Merge branch 'master' into xps-9310-kernel-config

This commit is contained in:
Jörg Thalheim 2021-11-14 11:33:38 +00:00 committed by GitHub
commit 13dc25bd67
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2271 changed files with 153794 additions and 42637 deletions

View File

@ -21,9 +21,13 @@ Reviewing guidelines: https://nixos.org/manual/nixpkgs/unstable/#chap-reviewing-
- [ ] x86_64-darwin
- [ ] aarch64-darwin
- [ ] For non-Linux: Is `sandbox = true` set in `nix.conf`? (See [Nix manual](https://nixos.org/manual/nix/stable/#sec-conf-file))
- [ ] Tested via one or more NixOS test(s) if existing and applicable for the change (look inside [nixos/tests](https://github.com/NixOS/nixpkgs/blob/master/nixos/tests))
- [ ] Tested compilation of all packages that depend on this change using `nix-shell -p nixpkgs-review --run "nixpkgs-review wip"`
- [ ] Tested execution of all binary files (usually in `./result/bin/`)
- [ ] Tested, as applicable:
- [NixOS test(s)](https://nixos.org/manual/nixos/unstable/index.html#sec-nixos-tests) (look inside [nixos/tests](https://github.com/NixOS/nixpkgs/blob/master/nixos/tests))
- and/or [package tests](https://nixos.org/manual/nixpkgs/unstable/#sec-package-tests)
- or, for functions and "core" functionality, tests in [lib/tests](https://github.com/NixOS/nixpkgs/blob/master/lib/tests) or [pkgs/test](https://github.com/NixOS/nixpkgs/blob/master/pkgs/test)
- made sure NixOS tests are [linked](https://nixos.org/manual/nixpkgs/unstable/#ssec-nixos-tests-linking) to the relevant packages
- [ ] Tested compilation of all packages that depend on this change using `nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD"`. Note: all changes have to be committed, also see [nixpkgs-review usage](https://github.com/Mic92/nixpkgs-review#usage)
- [ ] Tested basic functionality of all binary files (usually in `./result/bin/`)
- [21.11 Release Notes (or backporting 21.05 Release notes)](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md#generating-2111-release-notes)
- [ ] (Package updates) Added a release notes entry if the change is major or breaking
- [ ] (Module updates) Added a release notes entry if the change is significant

View File

@ -15,6 +15,6 @@ jobs:
# 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@v14
- uses: cachix/install-nix-action@v15
# 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

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

View File

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

View File

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

View File

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

View File

@ -53,7 +53,7 @@ system, [Hydra](https://hydra.nixos.org/).
Artifacts successfully built with Hydra are published to cache at
https://cache.nixos.org/. When successful build and test criteria are
met, the Nixpkgs expressions are distributed via [Nix
channels](https://nixos.org/nix/manual/#sec-channels).
channels](https://nixos.org/manual/nix/stable/package-management/channels.html).
# Contributing

View File

@ -47,6 +47,28 @@ These functions write `text` to the Nix store. This is useful for creating scrip
Many more commands wrap `writeTextFile` including `writeText`, `writeTextDir`, `writeScript`, and `writeScriptBin`. These are convenience functions over `writeTextFile`.
## `writeShellApplication` {#trivial-builder-writeShellApplication}
This can be used to easily produce a shell script that has some dependencies (`runtimeInputs`). It automatically sets the `PATH` of the script to contain all of the listed inputs, sets some sanity shellopts (`errexit`, `nounset`, `pipefail`), and checks the resulting script with [`shellcheck`](https://github.com/koalaman/shellcheck).
For example, look at the following code:
```nix
writeShellApplication {
name = "show-nixos-org";
runtimeInputs = [ curl w3m ];
text = ''
curl -s 'https://nixos.org' | w3m -dump -T text/html
'';
}
```
Unlike with normal `writeShellScriptBin`, there is no need to manually write out `${curl}/bin/curl`, setting the PATH
was handled by `writeShellApplication`. Moreover, the script is being checked with `shellcheck` for more strict
validation.
## `symlinkJoin` {#trivial-builder-symlinkJoin}
This can be used to put many derivations into the same directory structure. It works by creating a new derivation and adding symlinks to each of the paths listed. It expects two arguments, `name`, and `paths`. `name` is the name used in the Nix store path for the created derivation. `paths` is a list of paths that will be symlinked. These paths can be to Nix store derivations or any other subdirectory contained within.

View File

@ -50,7 +50,7 @@ expression does not protect the Prelude import with a semantic integrity
check, so the first step is to freeze the expression using `dhall freeze`,
like this:
```bash
```ShellSession
$ dhall freeze --inplace ./true.dhall
```
@ -113,7 +113,7 @@ in
… which we can then build using this command:
```bash
```ShellSession
$ nix build --file ./example.nix dhallPackages.true
```
@ -121,7 +121,7 @@ $ nix build --file ./example.nix dhallPackages.true
The above package produces the following directory tree:
```bash
```ShellSession
$ tree -a ./result
result
├── .cache
@ -135,7 +135,7 @@ result
* `source.dhall` contains the result of interpreting our Dhall package:
```bash
```ShellSession
$ cat ./result/source.dhall
True
```
@ -143,7 +143,7 @@ result
* The `.cache` subdirectory contains one binary cache product encoding the
same result as `source.dhall`:
```bash
```ShellSession
$ dhall decode < ./result/.cache/dhall/122027abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70
True
```
@ -151,7 +151,7 @@ result
* `binary.dhall` contains a Dhall expression which handles fetching and decoding
the same cache product:
```bash
```ShellSession
$ cat ./result/binary.dhall
missing sha256:27abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70
$ cp -r ./result/.cache .cache
@ -168,7 +168,7 @@ to conserve disk space when they are used exclusively as dependencies. For
example, if we build the Prelude package it will only contain the binary
encoding of the expression:
```bash
```ShellSession
$ nix build --file ./example.nix dhallPackages.Prelude
$ tree -a result
@ -199,7 +199,7 @@ Dhall overlay like this:
… and now the Prelude will contain the fully decoded result of interpreting
the Prelude:
```bash
```ShellSession
$ nix build --file ./example.nix dhallPackages.Prelude
$ tree -a result
@ -302,7 +302,7 @@ Additionally, `buildDhallGitHubPackage` accepts the same arguments as
You can use the `dhall-to-nixpkgs` command-line utility to automate
packaging Dhall code. For example:
```bash
```ShellSession
$ nix-env --install --attr haskellPackages.dhall-nixpkgs
$ nix-env --install --attr nix-prefetch-git # Used by dhall-to-nixpkgs
@ -329,12 +329,12 @@ The utility takes care of automatically detecting remote imports and converting
them to package dependencies. You can also use the utility on local
Dhall directories, too:
```bash
```ShellSession
$ dhall-to-nixpkgs directory ~/proj/dhall-semver
{ buildDhallDirectoryPackage, Prelude }:
buildDhallDirectoryPackage {
name = "proj";
src = /Users/gabriel/proj/dhall-semver;
src = ~/proj/dhall-semver;
file = "package.dhall";
source = false;
document = false;
@ -342,6 +342,37 @@ $ dhall-to-nixpkgs directory ~/proj/dhall-semver
}
```
### Remote imports as fixed-output derivations {#ssec-dhall-remote-imports-as-fod}
`dhall-to-nixpkgs` has the ability to fetch and build remote imports as
fixed-output derivations by using their Dhall integrity check. This is
sometimes easier than manually packaging all remote imports.
This can be used like the following:
```ShellSession
$ dhall-to-nixpkgs directory --fixed-output-derivations ~/proj/dhall-semver
{ buildDhallDirectoryPackage, buildDhallUrl }:
buildDhallDirectoryPackage {
name = "proj";
src = ~/proj/dhall-semver;
file = "package.dhall";
source = false;
document = false;
dependencies = [
(buildDhallUrl {
url = "https://prelude.dhall-lang.org/v17.0.0/package.dhall";
hash = "sha256-ENs8kZwl6QRoM9+Jeo/+JwHcOQ+giT2VjDQwUkvlpD4=";
dhallHash = "sha256:10db3c919c25e9046833df897a8ffe2701dc390fa0893d958c3430524be5a43e";
})
];
}
```
Here, `dhall-semver`'s `Prelude` dependency is fetched and built with the
`buildDhallUrl` helper function, instead of being passed in as a function
argument.
## Overriding dependency versions {#ssec-dhall-overriding-dependency-versions}
Suppose that we change our `true.dhall` example expression to depend on an older
@ -359,7 +390,7 @@ in Prelude.Bool.not False
If we try to rebuild that expression the build will fail:
```
```ShellSession
$ nix build --file ./example.nix dhallPackages.true
builder for '/nix/store/0f1hla7ff1wiaqyk1r2ky4wnhnw114fi-true.drv' failed with exit code 1; last 10 log lines:
@ -385,7 +416,7 @@ importing the URL.
However, we can override the default Prelude version by using `dhall-to-nixpkgs`
to create a Dhall package for our desired Prelude:
```bash
```ShellSession
$ dhall-to-nixpkgs github https://github.com/dhall-lang/dhall-lang.git \
--name Prelude \
--directory Prelude \
@ -396,7 +427,7 @@ $ dhall-to-nixpkgs github https://github.com/dhall-lang/dhall-lang.git \
… and then referencing that package in our Dhall overlay, by either overriding
the Prelude globally for all packages, like this:
```bash
```nix
dhallOverrides = self: super: {
true = self.callPackage ./true.nix { };
@ -407,7 +438,7 @@ the Prelude globally for all packages, like this:
… or selectively overriding the Prelude dependency for just the `true` package,
like this:
```bash
```nix
dhallOverrides = self: super: {
true = self.callPackage ./true.nix {
Prelude = self.callPackage ./Prelude.nix { };

View File

@ -13,7 +13,7 @@ into your `configuration.nix` or bring them into scope with `nix-shell -p rustc
For other versions such as daily builds (beta and nightly),
use either `rustup` from nixpkgs (which will manage the rust installation in your home directory),
or use Mozilla's [Rust nightlies overlay](#using-the-rust-nightlies-overlay).
or use a community maintained [Rust overlay](#using-community-rust-overlays).
## Compiling Rust applications with Cargo {#compiling-rust-applications-with-cargo}
@ -411,7 +411,7 @@ you of the correct hash.
`rustPlatform` provides the following hooks to automate Cargo builds:
* `cargoSetupHook`: configure Cargo to use depenencies vendored
* `cargoSetupHook`: configure Cargo to use dependencies vendored
through `fetchCargoTarball`. This hook uses the `cargoDeps`
environment variable to find the vendored dependencies. If a project
already vendors its dependencies, the variable `cargoVendorDir` can
@ -426,7 +426,7 @@ you of the correct hash.
* `maturinBuildHook`: use [Maturin](https://github.com/PyO3/maturin)
to build a Python wheel. Similar to `cargoBuildHook`, the optional
variable `buildAndTestSubdir` can be used to build a crate in a
Cargo workspace. Additional maturin flags can be passed through
Cargo workspace. Additional Maturin flags can be passed through
`maturinBuildFlags`.
* `cargoCheckHook`: run tests using Cargo. The build type for checks
can be set using `cargoCheckType`. Additional flags can be passed to
@ -447,7 +447,7 @@ dependencies. The build itself is then performed by
The following example outlines how the `tokenizers` Python package is
built. Since the Python package is in the `source/bindings/python`
directory of the *tokenizers* project's source archive, we use
directory of the `tokenizers` project's source archive, we use
`sourceRoot` to point the tooling to this directory:
```nix
@ -672,7 +672,7 @@ Some crates require external libraries. For crates from
`defaultCrateOverrides` package in nixpkgs itself.
Starting from that file, one can add more overrides, to add features
or build inputs by overriding the hello crate in a seperate file.
or build inputs by overriding the hello crate in a separate file.
```nix
with import <nixpkgs> {};
@ -729,7 +729,7 @@ with import <nixpkgs> {};
Actually, the overrides introduced in the previous section are more
general. A number of other parameters can be overridden:
- The version of rustc used to compile the crate:
- The version of `rustc` used to compile the crate:
```nix
(hello {}).override { rust = pkgs.rust; };
@ -742,7 +742,7 @@ general. A number of other parameters can be overridden:
(hello {}).override { release = false; };
```
- Whether to print the commands sent to rustc when building
- Whether to print the commands sent to `rustc` when building
(equivalent to `--verbose` in cargo:
```nix
@ -871,11 +871,87 @@ rustc 1.26.0-nightly (188e693b3 2018-03-26)
To see that you are using nightly.
## Using the Rust nightlies overlay {#using-the-rust-nightlies-overlay}
## Using community Rust overlays {#using-community-rust-overlays}
Mozilla provides an overlay for nixpkgs to bring a nightly version of Rust into scope.
This overlay can _also_ be used to install recent unstable or stable versions
of Rust, if desired.
There are two community maintained approaches to Rust toolchain management:
- [oxalica's Rust overlay](https://github.com/oxalica/rust-overlay)
- [fenix](https://github.com/nix-community/fenix)
Oxalica's overlay allows you to select a particular Rust version and components.
See [their documentation](https://github.com/oxalica/rust-overlay#rust-overlay) for more
detailed usage.
Fenix is an alternative to `rustup` and can also be used as an overlay.
Both oxalica's overlay and fenix better integrate with nix and cache optimizations.
Because of this and ergonomics, either of those community projects
should be preferred to the Mozilla's Rust overlay (`nixpkgs-mozilla`).
### How to select a specific `rustc` and toolchain version {#how-to-select-a-specific-rustc-and-toolchain-version}
You can consume the oxalica overlay and use it to grab a specific Rust toolchain version.
Here is an example `shell.nix` showing how to grab the current stable toolchain:
```nix
{ pkgs ? import <nixpkgs> {
overlays = [
(import (fetchTarball "https://github.com/oxalica/rust-overlay/archive/master.tar.gz"))
];
}
}:
pkgs.mkShell {
nativeBuildInputs = with pkgs; [
pkg-config
rust-bin.stable.latest.minimal
];
}
```
You can try this out by:
1. Saving that to `shell.nix`
2. Executing `nix-shell --pure --command 'rustc --version'`
As of writing, this prints out `rustc 1.56.0 (09c42c458 2021-10-18)`.
### How to use an overlay toolchain in a derivation {#how-to-use-an-overlay-toolchain-in-a-derivation}
You can also use an overlay's Rust toolchain with `buildRustPackage`.
The below snippet demonstrates invoking `buildRustPackage` with an oxalica overlay selected Rust toolchain:
```nix
with import <nixpkgs> {
overlays = [
(import (fetchTarball "https://github.com/oxalica/rust-overlay/archive/master.tar.gz"))
];
};
rustPlatform.buildRustPackage rec {
pname = "ripgrep";
version = "12.1.1";
nativeBuildInputs = [
rust-bin.stable.latest.minimal
];
src = fetchFromGitHub {
owner = "BurntSushi";
repo = "ripgrep";
rev = version;
sha256 = "1hqps7l5qrjh9f914r5i6kmcz6f1yb951nv4lby0cjnp5l253kps";
};
cargoSha256 = "03wf9r2csi6jpa7v5sw5lpxkrk4wfzwmzx7k3991q3bdjzcwnnwp";
meta = with lib; {
description = "A fast line-oriented regex search tool, similar to ag and ack";
homepage = "https://github.com/BurntSushi/ripgrep";
license = licenses.unlicense;
maintainers = [ maintainers.tailhook ];
};
}
```
Follow the below steps to try that snippet.
1. create a new directory
1. save the above snippet as `default.nix` in that directory
1. cd into that directory and run `nix-build`
### Rust overlay installation {#rust-overlay-installation}
@ -883,27 +959,15 @@ You can use this overlay by either changing your local nixpkgs configuration,
or by adding the overlay declaratively in a nix expression, e.g. in `configuration.nix`.
For more information see [the manual on installing overlays](#sec-overlays-install).
#### Imperative rust overlay installation {#imperative-rust-overlay-installation}
Clone [nixpkgs-mozilla](https://github.com/mozilla/nixpkgs-mozilla),
and create a symbolic link to the file
[rust-overlay.nix](https://github.com/mozilla/nixpkgs-mozilla/blob/master/rust-overlay.nix)
in the `~/.config/nixpkgs/overlays` directory.
```ShellSession
$ git clone https://github.com/mozilla/nixpkgs-mozilla.git
$ mkdir -p ~/.config/nixpkgs/overlays
$ ln -s $(pwd)/nixpkgs-mozilla/rust-overlay.nix ~/.config/nixpkgs/overlays/rust-overlay.nix
```
### Declarative rust overlay installation {#declarative-rust-overlay-installation}
### Declarative Rust overlay installation {#declarative-rust-overlay-installation}
This snippet shows how to use oxalica's Rust overlay.
Add the following to your `configuration.nix`, `home-configuration.nix`, `shell.nix`, or similar:
```nix
{ pkgs ? import <nixpkgs> {
overlays = [
(import (builtins.fetchTarball https://github.com/mozilla/nixpkgs-mozilla/archive/master.tar.gz))
(import (builtins.fetchTarball "https://github.com/oxalica/rust-overlay/archive/master.tar.gz"))
# Further overlays go here
];
};
@ -911,36 +975,3 @@ Add the following to your `configuration.nix`, `home-configuration.nix`, `shell.
```
Note that this will fetch the latest overlay version when rebuilding your system.
### Rust overlay usage {#rust-overlay-usage}
The overlay contains attribute sets corresponding to different versions of the rust toolchain, such as:
* `latest.rustChannels.stable`
* `latest.rustChannels.nightly`
* a function `rustChannelOf`, called as `(rustChannelOf { date = "2018-04-11"; channel = "nightly"; })`, or...
* `(nixpkgs.rustChannelOf { rustToolchain = ./rust-toolchain; })` if you have a local `rust-toolchain` file (see https://github.com/mozilla/nixpkgs-mozilla#using-in-nix-expressions for an example)
Each of these contain packages such as `rust`, which contains your usual rust development tools with the respective toolchain chosen.
For example, you might want to add `latest.rustChannels.stable.rust` to the list of packages in your configuration.
Imperatively, the latest stable version can be installed with the following command:
```ShellSession
$ nix-env -Ai nixpkgs.latest.rustChannels.stable.rust
```
Or using the attribute with nix-shell:
```ShellSession
$ nix-shell -p nixpkgs.latest.rustChannels.stable.rust
```
Substitute the `nixpkgs` prefix with `nixos` on NixOS.
To install the beta or nightly channel, "stable" should be substituted by
"nightly" or "beta", or
use the function provided by this overlay to pull a version based on a
build date.
The overlay automatically updates itself as it uses the same source as
[rustup](https://www.rustup.rs/).

View File

@ -112,7 +112,7 @@ self: super:
This overlay uses Intel's MKL library for both BLAS and LAPACK interfaces. Note that the same can be accomplished at runtime using `LD_LIBRARY_PATH` of `libblas.so.3` and `liblapack.so.3`. For instance:
```ShellSession
$ LD_LIBRARY_PATH=$(nix-build -A mkl)/lib:$LD_LIBRARY_PATH nix-shell -p octave --run octave
$ LD_LIBRARY_PATH=$(nix-build -A mkl)/lib${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH nix-shell -p octave --run octave
```
Intel MKL requires an `openmp` implementation when running with multiple processors. By default, `mkl` will use Intel's `iomp` implementation if no other is specified, but this is a runtime-only dependency and binary compatible with the LLVM implementation. To use that one instead, Intel recommends users set it with `LD_PRELOAD`. Note that `mkl` is only available on `x86_64-linux` and `x86_64-darwin`. Moreover, Hydra is not building and distributing pre-compiled binaries using it.

View File

@ -258,6 +258,12 @@ rec {
platform = {};
};
x86_64-darwin = {
config = "x86_64-apple-darwin";
xcodePlatform = "MacOSX";
platform = {};
};
#
# Windows
#

View File

@ -62,17 +62,17 @@ checkConfigError() {
# Check boolean option.
checkConfigOutput "false" config.enable ./declare-enable.nix
checkConfigError 'The option .* does not exist. Definition values:\n- In .*: true' config.enable ./define-enable.nix
checkConfigError 'The option .* does not exist. Definition values:\n\s*- In .*: true' config.enable ./define-enable.nix
# Check integer types.
# unsigned
checkConfigOutput "42" config.value ./declare-int-unsigned-value.nix ./define-value-int-positive.nix
checkConfigError 'A definition for option .* is not of type.*unsigned integer.*. Definition values:\n- In .*: -23' config.value ./declare-int-unsigned-value.nix ./define-value-int-negative.nix
checkConfigError 'A definition for option .* is not of type.*unsigned integer.*. Definition values:\n\s*- In .*: -23' config.value ./declare-int-unsigned-value.nix ./define-value-int-negative.nix
# positive
checkConfigError 'A definition for option .* is not of type.*positive integer.*. Definition values:\n- In .*: 0' config.value ./declare-int-positive-value.nix ./define-value-int-zero.nix
checkConfigError 'A definition for option .* is not of type.*positive integer.*. Definition values:\n\s*- In .*: 0' config.value ./declare-int-positive-value.nix ./define-value-int-zero.nix
# between
checkConfigOutput "42" config.value ./declare-int-between-value.nix ./define-value-int-positive.nix
checkConfigError 'A definition for option .* is not of type.*between.*-21 and 43.*inclusive.*. Definition values:\n- In .*: -23' config.value ./declare-int-between-value.nix ./define-value-int-negative.nix
checkConfigError 'A definition for option .* is not of type.*between.*-21 and 43.*inclusive.*. Definition values:\n\s*- In .*: -23' config.value ./declare-int-between-value.nix ./define-value-int-negative.nix
# Check either types
# types.either
@ -125,7 +125,7 @@ checkConfigOutput 'true' "$@" ./define-enable.nix ./define-attrsOfSub-foo-enable
set -- config.enable ./define-enable.nix ./declare-enable.nix
checkConfigOutput "true" "$@"
checkConfigOutput "false" "$@" ./disable-define-enable.nix
checkConfigError "The option .*enable.* does not exist. Definition values:\n- In .*: true" "$@" ./disable-declare-enable.nix
checkConfigError "The option .*enable.* does not exist. Definition values:\n\s*- In .*: true" "$@" ./disable-declare-enable.nix
checkConfigError "attribute .*enable.* in selection path .*config.enable.* not found" "$@" ./disable-define-enable.nix ./disable-declare-enable.nix
checkConfigError "attribute .*enable.* in selection path .*config.enable.* not found" "$@" ./disable-enable-modules.nix
@ -142,18 +142,18 @@ checkConfigError 'infinite recursion encountered' "$@"
# Check _module.check.
set -- config.enable ./declare-enable.nix ./define-enable.nix ./define-attrsOfSub-foo.nix
checkConfigError 'The option .* does not exist. Definition values:\n- In .*' "$@"
checkConfigError 'The option .* does not exist. Definition values:\n\s*- In .*' "$@"
checkConfigOutput "true" "$@" ./define-module-check.nix
# Check coerced value.
checkConfigOutput "\"42\"" config.value ./declare-coerced-value.nix
checkConfigOutput "\"24\"" config.value ./declare-coerced-value.nix ./define-value-string.nix
checkConfigError 'A definition for option .* is not.*string or signed integer convertible to it.*. Definition values:\n- In .*: \[ \]' config.value ./declare-coerced-value.nix ./define-value-list.nix
checkConfigError 'A definition for option .* is not.*string or signed integer convertible to it.*. Definition values:\n\s*- In .*: \[ \]' config.value ./declare-coerced-value.nix ./define-value-list.nix
# Check coerced value with unsound coercion
checkConfigOutput "12" config.value ./declare-coerced-value-unsound.nix
checkConfigError 'A definition for option .* is not of type .*. Definition values:\n- In .*: "1000"' config.value ./declare-coerced-value-unsound.nix ./define-value-string-bigint.nix
checkConfigError 'unrecognised JSON value' config.value ./declare-coerced-value-unsound.nix ./define-value-string-arbitrary.nix
checkConfigError 'A definition for option .* is not of type .*. Definition values:\n\s*- In .*: "1000"' config.value ./declare-coerced-value-unsound.nix ./define-value-string-bigint.nix
checkConfigError 'json.exception.parse_error' config.value ./declare-coerced-value-unsound.nix ./define-value-string-arbitrary.nix
# Check mkAliasOptionModule.
checkConfigOutput "true" config.enable ./alias-with-priority.nix
@ -169,7 +169,7 @@ checkConfigOutput "foo" config.submodule.foo ./declare-submoduleWith-special.nix
## shorthandOnlyDefines config behaves as expected
checkConfigOutput "true" config.submodule.config ./declare-submoduleWith-shorthand.nix ./define-submoduleWith-shorthand.nix
checkConfigError 'is not of type `boolean' config.submodule.config ./declare-submoduleWith-shorthand.nix ./define-submoduleWith-noshorthand.nix
checkConfigError "You're trying to declare a value of type \`bool'\nrather than an attribute-set for the option" config.submodule.config ./declare-submoduleWith-noshorthand.nix ./define-submoduleWith-shorthand.nix
checkConfigError "You're trying to declare a value of type \`bool'\n\s*rather than an attribute-set for the option" config.submodule.config ./declare-submoduleWith-noshorthand.nix ./define-submoduleWith-shorthand.nix
checkConfigOutput "true" config.submodule.config ./declare-submoduleWith-noshorthand.nix ./define-submoduleWith-noshorthand.nix
## submoduleWith should merge all modules in one swoop
@ -193,7 +193,7 @@ checkConfigOutput "true" config.submodule.enable ./declare-submoduleWith-path.ni
checkConfigOutput "true" config.enable ./disable-recursive/main.nix
checkConfigOutput "true" config.enable ./disable-recursive/{main.nix,disable-foo.nix}
checkConfigOutput "true" config.enable ./disable-recursive/{main.nix,disable-bar.nix}
checkConfigError 'The option .* does not exist. Definition values:\n- In .*: true' config.enable ./disable-recursive/{main.nix,disable-foo.nix,disable-bar.nix}
checkConfigError 'The option .* does not exist. Definition values:\n\s*- In .*: true' config.enable ./disable-recursive/{main.nix,disable-foo.nix,disable-bar.nix}
# Check that imports can depend on derivations
checkConfigOutput "true" config.enable ./import-from-store.nix
@ -277,7 +277,7 @@ checkConfigOutput baz config.value.nested.bar.baz ./types-anything/mk-mods.nix
## types.functionTo
checkConfigOutput "input is input" config.result ./functionTo/trivial.nix
checkConfigOutput "a b" config.result ./functionTo/merging-list.nix
checkConfigError 'A definition for option .fun.\[function body\]. is not of type .string.. Definition values:\n- In .*wrong-type.nix' config.result ./functionTo/wrong-type.nix
checkConfigError 'A definition for option .fun.\[function body\]. is not of type .string.. Definition values:\n\s*- In .*wrong-type.nix' config.result ./functionTo/wrong-type.nix
checkConfigOutput "b a" config.result ./functionTo/list-order.nix
checkConfigOutput "a c" config.result ./functionTo/merging-attrs.nix

View File

@ -23,6 +23,10 @@ pkgs.runCommand "nixpkgs-lib-tests" {
export NIX_STORE_DIR=$TEST_ROOT/store
export PAGER=cat
cacheDir=$TEST_ROOT/binary-cache
mkdir -p $NIX_CONF_DIR
echo "experimental-features = nix-command" >> $NIX_CONF_DIR/nix.conf
nix-store --init
cp -r ${../.} lib

View File

@ -26,7 +26,7 @@ touch {README.md,module.o,foo.bar}
# nix-instantiate doesn't write out the source, only computing the hash, so
# this uses the experimental nix command instead.
dir="$(nix eval --raw '(with import <nixpkgs/lib>; "${
dir="$(nix eval --impure --raw --expr '(with import <nixpkgs/lib>; "${
cleanSource ./.
}")')"
(cd $dir; find) | sort -f | diff -U10 - <(cat <<EOF
@ -37,7 +37,7 @@ EOF
) || die "cleanSource 1"
dir="$(nix eval --raw '(with import <nixpkgs/lib>; "${
dir="$(nix eval --impure --raw --expr '(with import <nixpkgs/lib>; "${
cleanSourceWith { src = '"$work"'; filter = path: type: ! hasSuffix ".bar" path; }
}")')"
(cd $dir; find) | sort -f | diff -U10 - <(cat <<EOF
@ -47,7 +47,7 @@ dir="$(nix eval --raw '(with import <nixpkgs/lib>; "${
EOF
) || die "cleanSourceWith 1"
dir="$(nix eval --raw '(with import <nixpkgs/lib>; "${
dir="$(nix eval --impure --raw --expr '(with import <nixpkgs/lib>; "${
cleanSourceWith { src = cleanSource '"$work"'; filter = path: type: ! hasSuffix ".bar" path; }
}")')"
(cd $dir; find) | sort -f | diff -U10 - <(cat <<EOF

View File

@ -159,6 +159,7 @@
};
abbe = {
email = "ashish.is@lostca.se";
matrix = "@abbe:badti.me";
github = "wahjava";
githubId = 2255192;
name = "Ashish SHUKLA";
@ -1663,6 +1664,7 @@
};
bryanasdev000 = {
email = "bryanasdev000@gmail.com";
matrix = "@bryanasdev000:matrix.org";
github = "bryanasdev000";
githubId = 53131727;
name = "Bryan Albuquerque";
@ -2535,6 +2537,13 @@
githubId = 86075850;
name = "Danil Danevich";
};
darkonion0 = {
name = "Alexandre Peruggia";
email = "darkgenius1@protonmail.com";
matrix = "@alexoo:matrix.org";
github = "DarkOnion0";
githubId = 68606322;
};
das-g = {
email = "nixpkgs@raphael.dasgupta.ch";
github = "das-g";
@ -2593,6 +2602,12 @@
githubId = 91113;
name = "David Kleuker";
};
davidarmstronglewis = {
email = "davidlewis@mac.com";
github = "davidarmstronglewis";
githubId = 6754950;
name = "David Armstrong Lewis";
};
davidrusu = {
email = "davidrusu.me@gmail.com";
github = "davidrusu";
@ -2795,6 +2810,12 @@
githubId = 2439413;
name = "Derek Gonyeo";
};
dguenther = {
email = "dguenther9@gmail.com";
github = "dguenther";
githubId = 767083;
name = "Derek Guenther";
};
dhkl = {
email = "david@davidslab.com";
github = "dhl";
@ -3652,6 +3673,10 @@
github = "expipiplus1";
githubId = 857308;
name = "Ellie Hermaszewska";
keys = [{
longkeyid = "rsa4096/0xC8116E3A0C1CA76A";
fingerprint = "FC1D 3E4F CBCA 80DF E870 6397 C811 6E3A 0C1C A76A";
}];
};
extends = {
email = "sharosari@gmail.com";
@ -4104,6 +4129,12 @@
githubId = 20208;
name = "Rok Garbas";
};
gardspirito = {
name = "gardspirito";
email = "nyxoroso@gmail.com";
github = "gardspirito";
githubId = 29687558;
};
garrison = {
email = "jim@garrison.cc";
github = "garrison";
@ -4193,6 +4224,12 @@
githubId = 1713676;
name = "Luis G. Torres";
};
GKasparov = {
email = "mizozahr@gmail.com";
github = "GKasparov";
githubId = 60962839;
name = "Mazen Zahr";
};
gleber = {
email = "gleber.p@gmail.com";
github = "gleber";
@ -4536,6 +4573,13 @@
githubId = 2405974;
name = "Sébastian Méric de Bellefon";
};
henkkalkwater = {
email = "chris+nixpkgs@netsoj.nl";
github = "HenkKalkwater";
githubId = 4262067;
matrix = "@chris:netsoj.nl";
name = "Chris Josten";
};
henrikolsson = {
email = "henrik@fixme.se";
github = "henrikolsson";
@ -5783,6 +5827,16 @@
githubId = 20658981;
name = "Jarosław Wygoda";
};
jyooru = {
email = "joel@joel.tokyo";
github = "jyooru";
githubId = 63786778;
name = "Joel";
keys = [{
longkeyid = "rsa4096/18550BD205E9EF64";
fingerprint = "9148 DC9E F4D5 3EB6 A30E 8EF0 1855 0BD2 05E9 EF64";
}];
};
jyp = {
email = "jeanphilippe.bernardy@gmail.com";
github = "jyp";
@ -6244,6 +6298,12 @@
githubId = 278013;
name = "Tomasz Kontusz";
};
kubukoz = {
email = "kubukoz@gmail.com";
github = "kubukoz";
githubId = 894884;
name = "Jakub Kozłowski";
};
kurnevsky = {
email = "kurnevsky@gmail.com";
github = "kurnevsky";
@ -6453,6 +6513,10 @@
github = "legendofmiracles";
githubId = 30902201;
name = "legendofmiracles";
keys = [{
longkeyid = "rsa4096/0x19B082B3DEFE5451";
fingerprint = "CC50 F82C 985D 2679 0703 AF15 19B0 82B3 DEFE 5451";
}];
};
lejonet = {
email = "daniel@kuehn.se";
@ -6629,6 +6693,12 @@
fingerprint = "5B93 9CFA E8FC 4D8F E07A 3AEA DFE1 D4A0 1733 7E2A";
}];
};
lorenzleutgeb = {
email = "lorenz@leutgeb.xyz";
github = "lorenzleutgeb";
githubId = 542154;
name = "Lorenz Leutgeb";
};
luis = {
email = "luis.nixos@gmail.com";
github = "Luis-Hebendanz";
@ -6718,6 +6788,12 @@
githubId = 10626;
name = "Andreas Wagner";
};
lrewega = {
email = "lrewega@c32.ca";
github = "lrewega";
githubId = 639066;
name = "Luke Rewega";
};
lromor = {
email = "leonardo.romor@gmail.com";
github = "lromor";
@ -7147,6 +7223,16 @@
githubId = 95194;
name = "Mauricio Scheffer";
};
max-niederman = {
email = "max@maxniederman.com";
github = "max-niederman";
githubId = 19580458;
name = "Max Niederman";
keys = [{
longkeyid = "rsa3072/0x9AED881481D8444E";
fingerprint = "1DE4 424D BF77 1192 5DC4 CF5E 9AED 8814 81D8 444E";
}];
};
maxdamantus = {
email = "maxdamantus@gmail.com";
github = "Maxdamantus";
@ -7693,6 +7779,7 @@
mohe2015 = {
name = "Moritz Hedtke";
email = "Moritz.Hedtke@t-online.de";
matrix = "@moritz.hedtke:matrix.org";
github = "mohe2015";
githubId = 13287984;
keys = [{
@ -8680,6 +8767,7 @@
};
pamplemousse = {
email = "xav.maso@gmail.com";
matrix = "@pamplemouss_:matrix.org";
github = "Pamplemousse";
githubId = 2647236;
name = "Xavier Maso";
@ -8894,6 +8982,12 @@
githubId = 421510;
name = "Noé Rubinstein";
};
photex = {
email = "photex@gmail.com";
github = "photex";
githubId = 301903;
name = "Chip Collier";
};
phreedom = {
email = "phreedom@yandex.ru";
github = "phreedom";
@ -9362,6 +9456,12 @@
githubId = 52847440;
name = "Ryan Burns";
};
r3dl3g = {
email = "redleg@rothfuss-web.de";
github = "r3dl3g";
githubId = 35229674;
name = "Armin Rothfuss";
};
raboof = {
email = "arnout@bzzt.net";
matrix = "@raboof:matrix.org";
@ -9554,12 +9654,28 @@
githubId = 500703;
name = "Tadas Barzdžius";
};
revol-xut = {
email = "revol-xut@protonmail.com";
name = "Tassilo Tanneberger";
github = "revol-xut";
githubId = 32239737;
keys = [{
longkeyid = "rsa4096/B966009D57E69CC6";
fingerprint = "91EB E870 1639 1323 642A 6803 B966 009D 57E6 9CC6";
}];
};
rexim = {
email = "reximkut@gmail.com";
github = "rexim";
githubId = 165283;
name = "Alexey Kutepov";
};
rewine = {
email = "lhongxu@outlook.com";
github = "wineee";
githubId = 22803888;
name = "Lu Hongxu";
};
rgrunbla = {
email = "remy@grunblatt.org";
github = "rgrunbla";
@ -10005,6 +10121,17 @@
github = "s1341";
githubId = 5682183;
};
sagikazarmark = {
name = "Mark Sagi-Kazar";
email = "mark.sagikazar@gmail.com";
matrix = "@mark.sagikazar:matrix.org";
github = "sagikazarmark";
githubId = 1226384;
keys = [{
longkeyid = "rsa4096/0xF251ADDC9D041C7E";
fingerprint = "E628 C811 6FB8 1657 F706 4EA4 F251 ADDC 9D04 1C7E";
}];
};
samalws = {
email = "sam@samalws.com";
name = "Sam Alws";
@ -10122,6 +10249,12 @@
githubId = 720864;
name = "Sébastien Bourdeauducq";
};
sbellem = {
email = "sbellem@gmail.com";
github = "sbellem";
githubId = 125458;
name = "Sylvain Bellemare";
};
sbond75 = {
name = "sbond75";
email = "43617712+sbond75@users.noreply.github.com";
@ -10774,6 +10907,12 @@
github = "staccato";
githubId = 86573128;
};
stackshadow = {
email = "stackshadow@evilbrain.de";
github = "stackshadow";
githubId = 7512804;
name = "Martin Langlotz";
};
steell = {
email = "steve@steellworks.com";
github = "Steell";
@ -11629,6 +11768,12 @@
githubId = 1568873;
name = "Torsten Scholak";
};
tshaynik = {
email = "tshaynik@protonmail.com";
github = "tshaynik";
githubId = 15064765;
name = "tshaynik";
};
tstrobel = {
email = "4ZKTUB6TEP74PYJOPWIR013S2AV29YUBW5F9ZH2F4D5UMJUJ6S@hash.domains";
name = "Thomas Strobel";

View File

@ -37,7 +37,7 @@ let
keyDrv = drv: if canEval drv.drvPath then { key = drv.drvPath; value = drv; } else { };
immediateDependenciesOf = drv:
concatLists (mapAttrsToList (n: v: derivationsIn v) (removeAttrs drv ["meta" "passthru"]));
concatLists (mapAttrsToList (n: v: derivationsIn v) (removeAttrs drv (["meta" "passthru"] ++ optionals (drv?passthru) (attrNames drv.passthru))));
derivationsIn = x:
if !canEval x then []

View File

@ -305,7 +305,7 @@ class CleanEnvironment(object):
def get_current_plugins(editor: Editor) -> List[Plugin]:
with CleanEnvironment():
cmd = ["nix", "eval", "--json", editor.get_plugins]
cmd = ["nix", "eval", "--impure", "--json", "--expr", editor.get_plugins]
log.debug("Running command %s", cmd)
out = subprocess.check_output(cmd)
data = json.loads(out)

View File

@ -58,5 +58,5 @@ a while to finish.
## NixOS Boot Entries {#sect-nixos-gc-boot-entries}
If your `/boot` partition runs out of space, after clearing old profiles
you must rebuild your system with `nixos-rebuild` to update the `/boot`
partition and clear space.
you must rebuild your system with `nixos-rebuild boot` or `nixos-rebuild
switch` to update the `/boot` partition and clear space.

View File

@ -159,6 +159,12 @@ The following methods are available on machine objects:
`execute`
: Execute a shell command, returning a list `(status, stdout)`.
If the command detaches, it must close stdout, as `execute` will wait
for this to consume all output reliably. This can be achieved by
redirecting stdout to stderr `>&2`, to `/dev/console`, `/dev/null` or
a file. Examples of detaching commands are `sleep 365d &`, where the
shell forks a new process that can write to stdout and `xclip -i`, where
the `xclip` command itself forks without closing stdout.
Takes an optional parameter `check_return` that defaults to `True`.
Setting this parameter to `False` will not check for the return code
and return -1 instead. This can be used for commands that shut down
@ -179,6 +185,9 @@ The following methods are available on machine objects:
- Dereferencing unset variables fail the command.
- It will wait for stdout to be closed. See `execute` for the
implications.
`fail`
: Like `succeed`, but raising an exception if the command returns a zero

View File

@ -64,7 +64,8 @@ $ nix-store --optimise
<para>
If your <literal>/boot</literal> partition runs out of space,
after clearing old profiles you must rebuild your system with
<literal>nixos-rebuild</literal> to update the
<literal>nixos-rebuild boot</literal> or
<literal>nixos-rebuild switch</literal> to update the
<literal>/boot</literal> partition and clear space.
</para>
</section>

View File

@ -266,8 +266,18 @@ start_all()
<listitem>
<para>
Execute a shell command, returning a list
<literal>(status, stdout)</literal>. Takes an optional
parameter <literal>check_return</literal> that defaults to
<literal>(status, stdout)</literal>. If the command detaches,
it must close stdout, as <literal>execute</literal> will wait
for this to consume all output reliably. This can be achieved
by redirecting stdout to stderr <literal>&gt;&amp;2</literal>,
to <literal>/dev/console</literal>,
<literal>/dev/null</literal> or a file. Examples of detaching
commands are <literal>sleep 365d &amp;</literal>, where the
shell forks a new process that can write to stdout and
<literal>xclip -i</literal>, where the
<literal>xclip</literal> command itself forks without closing
stdout. Takes an optional parameter
<literal>check_return</literal> that defaults to
<literal>True</literal>. Setting this parameter to
<literal>False</literal> will not check for the return code
and return -1 instead. This can be used for commands that shut
@ -306,6 +316,12 @@ start_all()
Dereferencing unset variables fail the command.
</para>
</listitem>
<listitem>
<para>
It will wait for stdout to be closed. See
<literal>execute</literal> for the implications.
</para>
</listitem>
</itemizedlist>
</listitem>
</varlistentry>

View File

@ -15,6 +15,15 @@
<section xml:id="sec-release-21.11-highlights">
<title>Highlights</title>
<itemizedlist>
<listitem>
<para>
Nix has been updated to version 2.4, reference its
<link xlink:href="https://discourse.nixos.org/t/nix-2-4-released/15822">release
notes</link> for more information on what has changed. The
previous version of Nix, 2.3.16, remains available for the
time being in the <literal>nix_2_3</literal> package.
</para>
</listitem>
<listitem>
<para>
<literal>iptables</literal> now uses
@ -50,6 +59,29 @@
guide</link> is available.
</para>
</listitem>
<listitem>
<para>
Improvements have been made to the Hadoop module and package:
</para>
<itemizedlist spacing="compact">
<listitem>
<para>
HDFS and YARN now support production-ready highly
available deployments with automatic failover.
</para>
</listitem>
<listitem>
<para>
Hadoop now defaults to Hadoop 3, updated from 2.
</para>
</listitem>
<listitem>
<para>
JournalNode, ZKFS and HTTPFS services have been added.
</para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para>
Activation scripts can now opt int to be run when running
@ -100,6 +132,46 @@
Notes</link> for details.
</para>
</listitem>
<listitem>
<para>
LXD support was greatly improved:
</para>
<itemizedlist spacing="compact">
<listitem>
<para>
building LXD images from configurations is now directly
possible with just nixpkgs
</para>
</listitem>
<listitem>
<para>
hydra is now building nixOS LXD images that can be used
standalone with full nixos-rebuild support
</para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para>
OpenSSH was updated to version 8.8p1
</para>
<itemizedlist spacing="compact">
<listitem>
<para>
This breaks connections to old SSH daemons as ssh-rsa host
keys and ssh-rsa public keys that were signed with SHA-1
are disabled by default now
</para>
</listitem>
<listitem>
<para>
These can be re-enabled, see the
<link xlink:href="https://www.openssh.com/txt/release-8.8">OpenSSH
changelog</link> for details
</para>
</listitem>
</itemizedlist>
</listitem>
</itemizedlist>
</section>
<section xml:id="sec-release-21.11-new-services">
@ -394,11 +466,52 @@
<link linkend="opt-hardware.rasdaemon.enable">hardware.rasdaemon</link>.
</para>
</listitem>
<listitem>
<para>
<literal>code-server</literal>-module now available
</para>
</listitem>
<listitem>
<para>
<link xlink:href="https://github.com/xmrig/xmrig">xmrig</link>,
a high performance, open source, cross platform RandomX,
KawPow, CryptoNight and AstroBWT unified CPU/GPU miner and
RandomX benchmark.
</para>
</listitem>
<listitem>
<para>
Auto nice daemons
<link xlink:href="https://github.com/Nefelim4ag/Ananicy">ananicy</link>
and
<link xlink:href="https://gitlab.com/ananicy-cpp/ananicy-cpp/">ananicy-cpp</link>.
Available as
<link linkend="opt-services.ananicy.enable">services.ananicy</link>.
</para>
</listitem>
</itemizedlist>
</section>
<section xml:id="sec-release-21.11-incompatibilities">
<title>Backward Incompatibilities</title>
<itemizedlist>
<listitem>
<para>
The NixOS VM test framework,
<literal>pkgs.nixosTest</literal>/<literal>make-test-python.nix</literal>,
now requires detaching commands such as
<literal>succeed(&quot;foo &amp;&quot;)</literal> and
<literal>succeed(&quot;foo | xclip -i&quot;)</literal> to
close stdout. This can be done with a redirect such as
<literal>succeed(&quot;foo &gt;&amp;2 &amp;&quot;)</literal>.
This breaking change was necessitated by a race condition
causing tests to fail or hang. It applies to all methods that
invoke commands on the nodes, including
<literal>execute</literal>, <literal>succeed</literal>,
<literal>fail</literal>,
<literal>wait_until_succeeds</literal>,
<literal>wait_until_fails</literal>.
</para>
</listitem>
<listitem>
<para>
The <literal>services.wakeonlan</literal> option was removed,
@ -511,7 +624,7 @@ Superuser created successfully.
<listitem>
<para>
The <literal>staticjinja</literal> package has been upgraded
from 1.0.4 to 4.1.0
from 1.0.4 to 4.1.1
</para>
</listitem>
<listitem>
@ -1722,6 +1835,25 @@ Superuser created successfully.
better user experience and benefit from this change.
</para>
</listitem>
<listitem>
<para>
A new option
<literal>services.prometheus.enableReload</literal> has been
added which can be enabled to reload the prometheus service
when its config file changes instead of restarting.
</para>
</listitem>
<listitem>
<para>
The option
<literal>services.prometheus.environmentFile</literal> has
been removed since it was causing
<link xlink:href="https://github.com/NixOS/nixpkgs/issues/126083">issues</link>
and Prometheus now has native support for secret files, i.e.
<literal>basic_auth.password_file</literal> and
<literal>authorization.credentials_file</literal>.
</para>
</listitem>
<listitem>
<para>
Dokuwiki now supports caddy! However
@ -1745,6 +1877,65 @@ Superuser created successfully.
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para>
The
<link xlink:href="options.html#opt-services.unifi.enable">services.unifi</link>
module has been reworked, solving a number of issues. This
leads to several user facing changes:
</para>
<itemizedlist spacing="compact">
<listitem>
<para>
The <literal>services.unifi.dataDir</literal> option is
removed and the data is now always located under
<literal>/var/lib/unifi/data</literal>. This is done to
make better use of systemd state direcotiry and thus
making the service restart more reliable.
</para>
</listitem>
<listitem>
<para>
The unifi logs can now be found under:
<literal>/var/log/unifi</literal> instead of
<literal>/var/lib/unifi/logs</literal>.
</para>
</listitem>
<listitem>
<para>
The unifi run directory can now be found under:
<literal>/run/unifi</literal> instead of
<literal>/var/lib/unifi/run</literal>.
</para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para>
<literal>security.pam.services.&lt;name&gt;.makeHomeDir</literal>
now uses <literal>umask=0077</literal> instead of
<literal>umask=0022</literal> when creating the home
directory.
</para>
</listitem>
<listitem>
<para>
Loki has had another release. Some default values have been
changed for the configuration and some configuration options
have been renamed. For more details, please check
<link xlink:href="https://grafana.com/docs/loki/latest/upgrading/#240">the
upgrade guide</link>.
</para>
</listitem>
<listitem>
<para>
<literal>julia</literal> now refers to
<literal>julia-stable</literal> instead of
<literal>julia-lts</literal>. In practice this means it has
been upgraded from <literal>1.0.4</literal> to
<literal>1.5.4</literal>.
</para>
</listitem>
</itemizedlist>
</section>
</section>

View File

@ -6,6 +6,8 @@ In addition to numerous new and upgraded packages, this release has the followin
## Highlights {#sec-release-21.11-highlights}
- Nix has been updated to version 2.4, reference its [release notes](https://discourse.nixos.org/t/nix-2-4-released/15822) for more information on what has changed. The previous version of Nix, 2.3.16, remains available for the time being in the `nix_2_3` package.
- `iptables` now uses `nf_tables` backend.
- PHP now defaults to PHP 8.0, updated from 7.4.
@ -18,6 +20,11 @@ In addition to numerous new and upgraded packages, this release has the followin
- spark now defaults to spark 3, updated from 2. A [migration guide](https://spark.apache.org/docs/latest/core-migration-guide.html#upgrading-from-core-24-to-30) is available.
- Improvements have been made to the Hadoop module and package:
- HDFS and YARN now support production-ready highly available deployments with automatic failover.
- Hadoop now defaults to Hadoop 3, updated from 2.
- JournalNode, ZKFS and HTTPFS services have been added.
- Activation scripts can now opt int to be run when running `nixos-rebuild dry-activate` and detect the dry activation by reading `$NIXOS_ACTION`.
This allows activation scripts to output what they would change if the activation was really run.
The users/modules activation script supports this and outputs some of is actions.
@ -35,6 +42,14 @@ In addition to numerous new and upgraded packages, this release has the followin
- GNOME has been upgraded to 41. Please take a look at their [Release Notes](https://help.gnome.org/misc/release-notes/41.0/) for details.
- LXD support was greatly improved:
- building LXD images from configurations is now directly possible with just nixpkgs
- hydra is now building nixOS LXD images that can be used standalone with full nixos-rebuild support
- OpenSSH was updated to version 8.8p1
- This breaks connections to old SSH daemons as ssh-rsa host keys and ssh-rsa public keys that were signed with SHA-1 are disabled by default now
- These can be re-enabled, see the [OpenSSH changelog](https://www.openssh.com/txt/release-8.8) for details
## 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).
@ -120,8 +135,18 @@ In addition to numerous new and upgraded packages, this release has the followin
- [rasdaemon](https://github.com/mchehab/rasdaemon), a hardware error logging daemon. Available as [hardware.rasdaemon](#opt-hardware.rasdaemon.enable).
- `code-server`-module now available
- [xmrig](https://github.com/xmrig/xmrig), a high performance, open source, cross platform RandomX, KawPow, CryptoNight and AstroBWT unified CPU/GPU miner and RandomX benchmark.
- Auto nice daemons [ananicy](https://github.com/Nefelim4ag/Ananicy) and [ananicy-cpp](https://gitlab.com/ananicy-cpp/ananicy-cpp/). Available as [services.ananicy](#opt-services.ananicy.enable).
## Backward Incompatibilities {#sec-release-21.11-incompatibilities}
- The NixOS VM test framework, `pkgs.nixosTest`/`make-test-python.nix`, now requires detaching commands such as `succeed("foo &")` and `succeed("foo | xclip -i")` to close stdout.
This can be done with a redirect such as `succeed("foo >&2 &")`. This breaking change was necessitated by a race condition causing tests to fail or hang.
It applies to all methods that invoke commands on the nodes, including `execute`, `succeed`, `fail`, `wait_until_succeeds`, `wait_until_fails`.
- The `services.wakeonlan` option was removed, and replaced with `networking.interfaces.<name>.wakeOnLan`.
- The `security.wrappers` option now requires to always specify an owner, group and whether the setuid/setgid bit should be set.
@ -179,7 +204,7 @@ In addition to numerous new and upgraded packages, this release has the followin
Superuser created successfully.
```
- The `staticjinja` package has been upgraded from 1.0.4 to 4.1.0
- The `staticjinja` package has been upgraded from 1.0.4 to 4.1.1
- Firefox v91 does not support addons with invalid signature anymore. Firefox ESR needs to be used for nix addon support.
@ -489,6 +514,21 @@ In addition to numerous new and upgraded packages, this release has the followin
- The `cawbird` Twitter client now uses its own API keys to count as different application than upstream builds. This is done to evade application-level rate limiting. While existing accounts continue to work, users may want to remove and re-register their account in the client to enjoy a better user experience and benefit from this change.
- A new option `services.prometheus.enableReload` has been added which can be enabled to reload the prometheus service when its config file changes instead of restarting.
- The option `services.prometheus.environmentFile` has been removed since it was causing [issues](https://github.com/NixOS/nixpkgs/issues/126083) and Prometheus now has native support for secret files, i.e. `basic_auth.password_file` and `authorization.credentials_file`.
- Dokuwiki now supports caddy! However
- the nginx option has been removed, in the new configuration, please use the `dokuwiki.webserver = "nginx"` instead.
- The "${hostname}" option has been deprecated, please use `dokuwiki.sites = [ "${hostname}" ]` instead
- The [services.unifi](options.html#opt-services.unifi.enable) module has been reworked, solving a number of issues. This leads to several user facing changes:
- The `services.unifi.dataDir` option is removed and the data is now always located under `/var/lib/unifi/data`. This is done to make better use of systemd state direcotiry and thus making the service restart more reliable.
- The unifi logs can now be found under: `/var/log/unifi` instead of `/var/lib/unifi/logs`.
- The unifi run directory can now be found under: `/run/unifi` instead of `/var/lib/unifi/run`.
- `security.pam.services.<name>.makeHomeDir` now uses `umask=0077` instead of `umask=0022` when creating the home directory.
- Loki has had another release. Some default values have been changed for the configuration and some configuration options have been renamed. For more details, please check [the upgrade guide](https://grafana.com/docs/loki/latest/upgrading/#240).
- `julia` now refers to `julia-stable` instead of `julia-lts`. In practice this means it has been upgraded from `1.0.4` to `1.5.4`.

View File

@ -4,6 +4,7 @@ with lib;
let
cfg = config.amazonImage;
amiBootMode = if config.ec2.efi then "uefi" else "legacy-bios";
in {
@ -106,10 +107,12 @@ in {
--arg system ${lib.escapeShellArg pkgs.stdenv.hostPlatform.system} \
--arg root_logical_bytes "$(${pkgs.qemu}/bin/qemu-img info --output json "$rootDisk" | ${pkgs.jq}/bin/jq '."virtual-size"')" \
--arg boot_logical_bytes "$(${pkgs.qemu}/bin/qemu-img info --output json "$bootDisk" | ${pkgs.jq}/bin/jq '."virtual-size"')" \
--arg boot_mode "${amiBootMode}" \
--arg root "$rootDisk" \
--arg boot "$bootDisk" \
'{}
| .label = $system_label
| .boot_mode = $boot_mode
| .system = $system
| .disks.boot.logical_bytes = $boot_logical_bytes
| .disks.boot.file = $boot
@ -145,9 +148,11 @@ in {
--arg system_label ${lib.escapeShellArg config.system.nixos.label} \
--arg system ${lib.escapeShellArg pkgs.stdenv.hostPlatform.system} \
--arg logical_bytes "$(${pkgs.qemu}/bin/qemu-img info --output json "$diskImage" | ${pkgs.jq}/bin/jq '."virtual-size"')" \
--arg boot_mode "${amiBootMode}" \
--arg file "$diskImage" \
'{}
| .label = $system_label
| .boot_mode = $boot_mode
| .system = $system
| .logical_bytes = $logical_bytes
| .file = $file

View File

@ -1,6 +1,9 @@
#!/usr/bin/env nix-shell
#!nix-shell -p awscli -p jq -p qemu -i bash
# shellcheck shell=bash
#
# Future Deprecation?
# This entire thing should probably be replaced with a generic terraform config
# Uploads and registers NixOS images built from the
# <nixos/release.nix> amazonImage attribute. Images are uploaded and
@ -65,13 +68,18 @@ read_image_info() {
# We handle a single image per invocation, store all attributes in
# globals for convenience.
zfs_disks=$(read_image_info .disks)
image_label="$(read_image_info .label)${zfs_disks:+-ZFS}"
is_zfs_image=
if jq -e .boot <<< "$zfs_disks"; then
is_zfs_image=1
zfs_boot=".disks.boot"
fi
image_label="$(read_image_info .label)${is_zfs_image:+-ZFS}"
image_system=$(read_image_info .system)
image_files=( $(read_image_info "${zfs_disks:+.disks.root}.file") )
image_files=( $(read_image_info ".disks.root.file") )
image_logical_bytes=$(read_image_info "${zfs_disks:+.disks.boot}.logical_bytes")
image_logical_bytes=$(read_image_info "${zfs_boot:-.disks.root}.logical_bytes")
if [[ -n "$zfs_disks" ]]; then
if [[ -n "$is_zfs_image" ]]; then
image_files+=( $(read_image_info .disks.boot.file) )
fi
@ -192,7 +200,7 @@ upload_image() {
for image_file in "${image_files[@]}"; do
local aws_path=${image_file#/}
if [[ -n "$zfs_disks" ]]; then
if [[ -n "$is_zfs_image" ]]; then
local suffix=${image_file%.*}
suffix=${suffix##*.}
fi
@ -239,7 +247,7 @@ upload_image() {
"DeviceName=/dev/xvda,Ebs={SnapshotId=$snapshot_id,VolumeSize=$image_logical_gigabytes,DeleteOnTermination=true,VolumeType=gp3}"
)
if [[ -n "$zfs_disks" ]]; then
if [[ -n "$is_zfs_image" ]]; then
local root_snapshot_id=$(read_state "$region.$image_label.root.$image_system" snapshot_id)
local root_image_logical_bytes=$(read_image_info ".disks.root.logical_bytes")
@ -270,6 +278,7 @@ upload_image() {
--region "$region" \
--architecture $amazon_arch \
--block-device-mappings "${block_device_mappings[@]}" \
--boot-mode $(read_image_info .boot_mode) \
"${extra_flags[@]}" \
| jq -r '.ImageId'
)

View File

@ -0,0 +1,102 @@
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running nixos-help).
{ config, pkgs, lib, ... }:
with lib;
{
imports =
[ # Include the default lxd configuration.
../../../modules/virtualisation/lxc-container.nix
# Include the container-specific autogenerated configuration.
./lxd.nix
];
# networking.hostName = mkForce "nixos"; # Overwrite the hostname.
# networking.wireless.enable = true; # Enables wireless support via wpa_supplicant.
# Set your time zone.
# time.timeZone = "Europe/Amsterdam";
# The global useDHCP flag is deprecated, therefore explicitly set to false here.
# Per-interface useDHCP will be mandatory in the future, so this generated config
# replicates the default behaviour.
networking.useDHCP = false;
networking.interfaces.eth0.useDHCP = true;
# Configure network proxy if necessary
# networking.proxy.default = "http://user:password@proxy:port/";
# networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";
# Select internationalisation properties.
# i18n.defaultLocale = "en_US.UTF-8";
# console = {
# font = "Lat2-Terminus16";
# keyMap = "us";
# };
# Enable the X11 windowing system.
# services.xserver.enable = true;
# Configure keymap in X11
# services.xserver.layout = "us";
# services.xserver.xkbOptions = "eurosign:e";
# Enable CUPS to print documents.
# services.printing.enable = true;
# Enable sound.
# sound.enable = true;
# hardware.pulseaudio.enable = true;
# Enable touchpad support (enabled default in most desktopManager).
# services.xserver.libinput.enable = true;
# Define a user account. Don't forget to set a password with passwd.
# users.users.jane = {
# isNormalUser = true;
# extraGroups = [ "wheel" ]; # Enable sudo for the user.
# };
# List packages installed in system profile. To search, run:
# $ nix search wget
# environment.systemPackages = with pkgs; [
# vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default.
# wget
# firefox
# ];
# Some programs need SUID wrappers, can be configured further or are
# started in user sessions.
# programs.mtr.enable = true;
# programs.gnupg.agent = {
# enable = true;
# enableSSHSupport = true;
# };
# List services that you want to enable:
# Enable the OpenSSH daemon.
# services.openssh.enable = true;
# Open ports in the firewall.
# networking.firewall.allowedTCPPorts = [ ... ];
# networking.firewall.allowedUDPPorts = [ ... ];
# Or disable the firewall altogether.
# networking.firewall.enable = false;
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions
# on your system were taken. Its perfectly fine and recommended to leave
# this value at the release version of the first install of this system.
# Before changing this value read the documentation for this option
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "21.05"; # Did you read the comment?
# As this is intended as a stadalone image, undo some of the minimal profile stuff
documentation.enable = true;
documentation.nixos.enable = true;
environment.noXlibs = false;
}

View File

@ -0,0 +1,34 @@
{ lib, config, pkgs, ... }:
with lib;
{
imports = [
../../../modules/virtualisation/lxc-container.nix
];
virtualisation.lxc.templates.nix = {
enable = true;
target = "/etc/nixos/lxd.nix";
template = ./nix.tpl;
when = [ "create" "copy" ];
};
# copy the config for nixos-rebuild
system.activationScripts.config = ''
if [ ! -e /etc/nixos/configuration.nix ]; then
mkdir -p /etc/nixos
cat ${./lxd-image-inner.nix} > /etc/nixos/configuration.nix
sed 's|../../../modules/virtualisation/lxc-container.nix|<nixpkgs/nixos/modules/virtualisation/lxc-container.nix>|g' -i /etc/nixos/configuration.nix
fi
'';
# Network
networking.useDHCP = false;
networking.interfaces.eth0.useDHCP = true;
# As this is intended as a stadalone image, undo some of the minimal profile stuff
documentation.enable = true;
documentation.nixos.enable = true;
environment.noXlibs = false;
}

View File

@ -0,0 +1,9 @@
{ lib, config, pkgs, ... }:
with lib;
# WARNING: THIS CONFIGURATION IS AUTOGENERATED AND WILL BE OVERWRITTEN AUTOMATICALLY
{
networking.hostName = "{{ container.name }}";
}

View File

@ -47,6 +47,15 @@ let
'';
};
allowDiscards = mkOption {
default = false;
type = types.bool;
description = ''
Whether to allow TRIM requests to the underlying device. This option
has security implications; please read the LUKS documentation before
activating it.
'';
};
};
};
@ -224,7 +233,8 @@ in
fi
''}
${optionalString sw.randomEncryption.enable ''
cryptsetup plainOpen -c ${sw.randomEncryption.cipher} -d ${sw.randomEncryption.source} ${optionalString (sw.discardPolicy != null) "--allow-discards"} ${sw.device} ${sw.deviceName}
cryptsetup plainOpen -c ${sw.randomEncryption.cipher} -d ${sw.randomEncryption.source} \
${optionalString sw.randomEncryption.allowDiscards "--allow-discards"} ${sw.device} ${sw.deviceName}
mkswap ${sw.realDevice}
''}
'';

View File

@ -284,6 +284,10 @@ in
source = "${nvidia_x11.bin}/share/nvidia/nvidia-application-profiles-rc";
};
# 'nvidia_x11' installs it's files to /run/opengl-driver/...
environment.etc."egl/egl_external_platform.d".source =
"/run/opengl-driver/share/egl/egl_external_platform.d/";
hardware.opengl.package = mkIf (!offloadCfg.enable) nvidia_x11.out;
hardware.opengl.package32 = mkIf (!offloadCfg.enable) nvidia_x11.lib32;
hardware.opengl.extraPackages = optional offloadCfg.enable nvidia_x11.out;

View File

@ -1,7 +1,7 @@
{
x86_64-linux = "/nix/store/nzp4m3cmm7wawk031byh8jg4cdzjq212-nix-2.3.16";
i686-linux = "/nix/store/zsaza9pwim617ak15fsc31lv65b9w3in-nix-2.3.16";
aarch64-linux = "/nix/store/7f6z40gyd405yd50qkyzwilnqw106bx8-nix-2.3.16";
x86_64-darwin = "/nix/store/c43kyri67ia8mibs0id5ara7gqwlkybf-nix-2.3.16";
aarch64-darwin = "/nix/store/6jwhak3cvsgnbqs540n27g8pxnk427fr-nix-2.3.16";
x86_64-linux = "/nix/store/hapw7q1fkjxvprnkcgw9ppczavg4daj2-nix-2.4";
i686-linux = "/nix/store/8qlvh8pp5j8wgrzj3is2jlbhgrwgsiy9-nix-2.4";
aarch64-linux = "/nix/store/h48lkygcqj4hdibbdnpl67q7ks6vkrd6-nix-2.4";
x86_64-darwin = "/nix/store/c3mvzszvyzakvcp9spnjvsb8m2bpjk7m-nix-2.4";
aarch64-darwin = "/nix/store/hbfqs62r0hga2yr4zi5kc7fzhf71bq9n-nix-2.4";
}

View File

@ -485,6 +485,9 @@
./services/mail/roundcube.nix
./services/mail/sympa.nix
./services/mail/nullmailer.nix
./services/matrix/mjolnir.nix
./services/matrix/pantalaimon.nix
./services/misc/ananicy.nix
./services/misc/airsonic.nix
./services/misc/ankisyncd.nix
./services/misc/apache-kafka.nix
@ -685,6 +688,7 @@
./services/networking/3proxy.nix
./services/networking/adguardhome.nix
./services/networking/amuled.nix
./services/networking/antennas.nix
./services/networking/aria2.nix
./services/networking/asterisk.nix
./services/networking/atftpd.nix
@ -772,6 +776,7 @@
./services/networking/libreswan.nix
./services/networking/lldpd.nix
./services/networking/logmein-hamachi.nix
./services/networking/lxd-image-server.nix
./services/networking/mailpile.nix
./services/networking/magic-wormhole-mailbox-server.nix
./services/networking/matterbridge.nix
@ -973,6 +978,7 @@
./services/web-apps/atlassian/jira.nix
./services/web-apps/bookstack.nix
./services/web-apps/calibre-web.nix
./services/web-apps/code-server.nix
./services/web-apps/convos.nix
./services/web-apps/cryptpad.nix
./services/web-apps/dex.nix
@ -1012,6 +1018,7 @@
./services/web-apps/pgpkeyserver-lite.nix
./services/web-apps/matomo.nix
./services/web-apps/moinmoin.nix
./services/web-apps/openwebrx.nix
./services/web-apps/restya-board.nix
./services/web-apps/sogo.nix
./services/web-apps/rss-bridge.nix
@ -1187,6 +1194,7 @@
./virtualisation/virtualbox-guest.nix
./virtualisation/virtualbox-host.nix
./virtualisation/vmware-guest.nix
./virtualisation/waydroid.nix
./virtualisation/xen-dom0.nix
./virtualisation/xe-guest-utilities.nix
]

View File

@ -41,7 +41,19 @@ in {
withRuby = mkOption {
type = types.bool;
default = true;
description = "Enable ruby provider.";
description = "Enable Ruby provider.";
};
withPython3 = mkOption {
type = types.bool;
default = true;
description = "Enable Python 3 provider.";
};
withNodeJs = mkOption {
type = types.bool;
default = false;
description = "Enable Node provider.";
};
configure = mkOption {
@ -142,7 +154,7 @@ in {
environment.variables.EDITOR = mkIf cfg.defaultEditor (mkOverride 900 "nvim");
programs.neovim.finalPackage = pkgs.wrapNeovim cfg.package {
inherit (cfg) viAlias vimAlias;
inherit (cfg) viAlias vimAlias withPython3 withNodeJs withRuby;
configure = cfg.configure // {
customRC = (cfg.configure.customRC or "") + ''

View File

@ -15,7 +15,7 @@ let
(optionalString rule.noLog "nolog")
(optionalString rule.persist "persist")
(optionalString rule.keepEnv "keepenv")
"setenv { SSH_AUTH_SOCK ${concatStringsSep " " rule.setEnv} }"
"setenv { SSH_AUTH_SOCK TERMINFO TERMINFO_DIRS ${concatStringsSep " " rule.setEnv} }"
];
mkArgs = rule:

View File

@ -483,7 +483,7 @@ let
if config.boot.isContainer then "optional" else "required"
} pam_loginuid.so"}
${optionalString cfg.makeHomeDir
"session required ${pkgs.pam}/lib/security/pam_mkhomedir.so silent skel=${config.security.pam.makeHomeDir.skelDirectory} umask=0022"}
"session required ${pkgs.pam}/lib/security/pam_mkhomedir.so silent skel=${config.security.pam.makeHomeDir.skelDirectory} umask=0077"}
${optionalString cfg.updateWtmp
"session required ${pkgs.pam}/lib/security/pam_lastlog.so silent"}
${optionalString config.security.pam.enableEcryptfs

View File

@ -42,7 +42,7 @@ in {
environment.ROON_DATAROOT = "/var/lib/${name}";
serviceConfig = {
ExecStart = "${pkgs.roon-server}/start.sh";
ExecStart = "${pkgs.roon-server}/bin/RoonServer";
LimitNOFILE = 8192;
User = cfg.user;
Group = cfg.group;

View File

@ -35,6 +35,7 @@ pkgs.runCommand "hadoop-conf" {} ''
cp ${siteXml "hdfs-site.xml" cfg.hdfsSite}/* $out/
cp ${siteXml "mapred-site.xml" cfg.mapredSite}/* $out/
cp ${siteXml "yarn-site.xml" cfg.yarnSite}/* $out/
cp ${siteXml "httpfs-site.xml" cfg.httpfsSite}/* $out/
cp ${cfgFile "container-executor.cfg" cfg.containerExecutorCfg}/* $out/
cp ${pkgs.writeTextDir "hadoop-user-functions.sh" userFunctions}/* $out/
cp ${pkgs.writeTextDir "hadoop-env.sh" hadoopEnv}/* $out/

View File

@ -15,7 +15,10 @@ with lib;
"fs.defaultFS" = "hdfs://localhost";
}
'';
description = "Hadoop core-site.xml definition";
description = ''
Hadoop core-site.xml definition
<link xlink:href="https://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-common/core-default.xml"/>
'';
};
hdfsSite = mkOption {
@ -28,7 +31,10 @@ with lib;
"dfs.nameservices" = "namenode1";
}
'';
description = "Hadoop hdfs-site.xml definition";
description = ''
Hadoop hdfs-site.xml definition
<link xlink:href="https://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-hdfs/hdfs-default.xml"/>
'';
};
mapredSite = mkOption {
@ -44,7 +50,10 @@ with lib;
"mapreduce.map.java.opts" = "-Xmx900m -XX:+UseParallelGC";
}
'';
description = "Hadoop mapred-site.xml definition";
description = ''
Hadoop mapred-site.xml definition
<link xlink:href="https://hadoop.apache.org/docs/current/hadoop-mapreduce-client/hadoop-mapreduce-client-core/mapred-default.xml"/>
'';
};
yarnSite = mkOption {
@ -67,7 +76,24 @@ with lib;
"yarn.resourcemanager.hostname" = "''${config.networking.hostName}";
}
'';
description = "Hadoop yarn-site.xml definition";
description = ''
Hadoop yarn-site.xml definition
<link xlink:href="https://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-common/yarn-default.xml"/>
'';
};
httpfsSite = mkOption {
default = { };
type = types.attrsOf types.anything;
example = literalExpression ''
{
"hadoop.http.max.threads" = 500;
}
'';
description = ''
Hadoop httpfs-site.xml definition
<link xlink:href="https://hadoop.apache.org/docs/current/hadoop-hdfs-httpfs/httpfs-default.html"/>
'';
};
log4jProperties = mkOption {
@ -92,7 +118,10 @@ with lib;
"feature.terminal.enabled" = 0;
}
'';
description = "Yarn container-executor.cfg definition";
description = ''
Yarn container-executor.cfg definition
<link xlink:href="https://hadoop.apache.org/docs/r2.7.2/hadoop-yarn/hadoop-yarn-site/SecureContainer.html"/>
'';
};
extraConfDirs = mkOption {
@ -118,7 +147,8 @@ with lib;
config = mkMerge [
(mkIf (builtins.hasAttr "yarn" config.users.users ||
builtins.hasAttr "hdfs" config.users.users) {
builtins.hasAttr "hdfs" config.users.users ||
builtins.hasAttr "httpfs" config.users.users) {
users.groups.hadoop = {
gid = config.ids.gids.hadoop;
};

View File

@ -17,11 +17,14 @@ in
{
options.services.hadoop.hdfs = {
namenode = {
enabled = mkOption {
enable = mkEnableOption "Whether to run the HDFS NameNode";
formatOnInit = mkOption {
type = types.bool;
default = false;
description = ''
Whether to run the HDFS NameNode
Format HDFS namenode on first start. This is useful for quickly spinning up ephemeral HDFS clusters with a single namenode.
For HA clusters, initialization involves multiple steps across multiple nodes. Follow [this guide](https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/HDFSHighAvailabilityWithQJM.html)
to initialize an HA cluster manually.
'';
};
inherit restartIfChanged;
@ -34,13 +37,7 @@ in
};
};
datanode = {
enabled = mkOption {
type = types.bool;
default = false;
description = ''
Whether to run the HDFS DataNode
'';
};
enable = mkEnableOption "Whether to run the HDFS DataNode";
inherit restartIfChanged;
openFirewall = mkOption {
type = types.bool;
@ -50,18 +47,51 @@ in
'';
};
};
journalnode = {
enable = mkEnableOption "Whether to run the HDFS JournalNode";
inherit restartIfChanged;
openFirewall = mkOption {
type = types.bool;
default = true;
description = ''
Open firewall ports for journalnode
'';
};
};
zkfc = {
enable = mkEnableOption "Whether to run the HDFS ZooKeeper failover controller";
inherit restartIfChanged;
};
httpfs = {
enable = mkEnableOption "Whether to run the HDFS HTTPfs server";
tempPath = mkOption {
type = types.path;
default = "/tmp/hadoop/httpfs";
description = ''
HTTPFS_TEMP path used by HTTPFS
'';
};
inherit restartIfChanged;
openFirewall = mkOption {
type = types.bool;
default = true;
description = ''
Open firewall ports for HTTPFS
'';
};
};
};
config = mkMerge [
(mkIf cfg.hdfs.namenode.enabled {
(mkIf cfg.hdfs.namenode.enable {
systemd.services.hdfs-namenode = {
description = "Hadoop HDFS NameNode";
wantedBy = [ "multi-user.target" ];
inherit (cfg.hdfs.namenode) restartIfChanged;
preStart = ''
preStart = (mkIf cfg.hdfs.namenode.formatOnInit ''
${cfg.package}/bin/hdfs --config ${hadoopConf} namenode -format -nonInteractive || true
'';
'');
serviceConfig = {
User = "hdfs";
@ -74,9 +104,10 @@ in
networking.firewall.allowedTCPPorts = (mkIf cfg.hdfs.namenode.openFirewall [
9870 # namenode.http-address
8020 # namenode.rpc-address
8022 # namenode. servicerpc-address
]);
})
(mkIf cfg.hdfs.datanode.enabled {
(mkIf cfg.hdfs.datanode.enable {
systemd.services.hdfs-datanode = {
description = "Hadoop HDFS DataNode";
wantedBy = [ "multi-user.target" ];
@ -96,8 +127,64 @@ in
9867 # datanode.ipc.address
]);
})
(mkIf cfg.hdfs.journalnode.enable {
systemd.services.hdfs-journalnode = {
description = "Hadoop HDFS JournalNode";
wantedBy = [ "multi-user.target" ];
inherit (cfg.hdfs.journalnode) restartIfChanged;
serviceConfig = {
User = "hdfs";
SyslogIdentifier = "hdfs-journalnode";
ExecStart = "${cfg.package}/bin/hdfs --config ${hadoopConf} journalnode";
Restart = "always";
};
};
networking.firewall.allowedTCPPorts = (mkIf cfg.hdfs.journalnode.openFirewall [
8480 # dfs.journalnode.http-address
8485 # dfs.journalnode.rpc-address
]);
})
(mkIf cfg.hdfs.zkfc.enable {
systemd.services.hdfs-zkfc = {
description = "Hadoop HDFS ZooKeeper failover controller";
wantedBy = [ "multi-user.target" ];
inherit (cfg.hdfs.zkfc) restartIfChanged;
serviceConfig = {
User = "hdfs";
SyslogIdentifier = "hdfs-zkfc";
ExecStart = "${cfg.package}/bin/hdfs --config ${hadoopConf} zkfc";
Restart = "always";
};
};
})
(mkIf cfg.hdfs.httpfs.enable {
systemd.services.hdfs-httpfs = {
description = "Hadoop httpfs";
wantedBy = [ "multi-user.target" ];
inherit (cfg.hdfs.httpfs) restartIfChanged;
environment.HTTPFS_TEMP = cfg.hdfs.httpfs.tempPath;
preStart = ''
mkdir -p $HTTPFS_TEMP
'';
serviceConfig = {
User = "httpfs";
SyslogIdentifier = "hdfs-httpfs";
ExecStart = "${cfg.package}/bin/hdfs --config ${hadoopConf} httpfs";
Restart = "always";
};
};
networking.firewall.allowedTCPPorts = (mkIf cfg.hdfs.httpfs.openFirewall [
14000 # httpfs.http.port
]);
})
(mkIf (
cfg.hdfs.namenode.enabled || cfg.hdfs.datanode.enabled
cfg.hdfs.namenode.enable || cfg.hdfs.datanode.enable || cfg.hdfs.journalnode.enable || cfg.hdfs.zkfc.enable
) {
users.users.hdfs = {
description = "Hadoop HDFS user";
@ -105,6 +192,12 @@ in
uid = config.ids.uids.hdfs;
};
})
(mkIf cfg.hdfs.httpfs.enable {
users.users.httpfs = {
description = "Hadoop HTTPFS user";
group = "hadoop";
isSystemUser = true;
};
})
];
}

View File

@ -17,13 +17,7 @@ in
{
options.services.hadoop.yarn = {
resourcemanager = {
enabled = mkOption {
type = types.bool;
default = false;
description = ''
Whether to run the Hadoop YARN ResourceManager
'';
};
enable = mkEnableOption "Whether to run the Hadoop YARN ResourceManager";
inherit restartIfChanged;
openFirewall = mkOption {
type = types.bool;
@ -34,13 +28,7 @@ in
};
};
nodemanager = {
enabled = mkOption {
type = types.bool;
default = false;
description = ''
Whether to run the Hadoop YARN NodeManager
'';
};
enable = mkEnableOption "Whether to run the Hadoop YARN NodeManager";
inherit restartIfChanged;
addBinBash = mkOption {
type = types.bool;
@ -62,7 +50,7 @@ in
config = mkMerge [
(mkIf (
cfg.yarn.resourcemanager.enabled || cfg.yarn.nodemanager.enabled
cfg.yarn.resourcemanager.enable || cfg.yarn.nodemanager.enable
) {
users.users.yarn = {
@ -72,7 +60,7 @@ in
};
})
(mkIf cfg.yarn.resourcemanager.enabled {
(mkIf cfg.yarn.resourcemanager.enable {
systemd.services.yarn-resourcemanager = {
description = "Hadoop YARN ResourceManager";
wantedBy = [ "multi-user.target" ];
@ -91,10 +79,11 @@ in
8030 # resourcemanager.scheduler.address
8031 # resourcemanager.resource-tracker.address
8032 # resourcemanager.address
8033 # resourcemanager.admin.address
]);
})
(mkIf cfg.yarn.nodemanager.enabled {
(mkIf cfg.yarn.nodemanager.enable {
# Needed because yarn hardcodes /bin/bash in container start scripts
# These scripts can't be patched, they are generated at runtime
systemd.tmpfiles.rules = [

View File

@ -258,6 +258,8 @@ in
"net.bridge.bridge-nf-call-ip6tables" = 1;
};
systemd.enableUnifiedCgroupHierarchy = false; # true breaks node memory metrics
systemd.services.kubelet = {
description = "Kubernetes Kubelet Service";
wantedBy = [ "kubernetes.target" ];

View File

@ -13,10 +13,10 @@ let
# Use upstream config files passed through spa-json-dump as the base
# Patched here as necessary for them to work with this module
defaults = {
alsa-monitor = (builtins.fromJSON (builtins.readFile ./media-session/alsa-monitor.conf.json));
bluez-monitor = (builtins.fromJSON (builtins.readFile ./media-session/bluez-monitor.conf.json));
media-session = (builtins.fromJSON (builtins.readFile ./media-session/media-session.conf.json));
v4l2-monitor = (builtins.fromJSON (builtins.readFile ./media-session/v4l2-monitor.conf.json));
alsa-monitor = lib.importJSON ./media-session/alsa-monitor.conf.json;
bluez-monitor = lib.importJSON ./media-session/bluez-monitor.conf.json;
media-session = lib.importJSON ./media-session/media-session.conf.json;
v4l2-monitor = lib.importJSON ./media-session/v4l2-monitor.conf.json;
};
configs = {

View File

@ -22,11 +22,11 @@ let
# Use upstream config files passed through spa-json-dump as the base
# Patched here as necessary for them to work with this module
defaults = {
client = builtins.fromJSON (builtins.readFile ./daemon/client.conf.json);
client-rt = builtins.fromJSON (builtins.readFile ./daemon/client-rt.conf.json);
jack = builtins.fromJSON (builtins.readFile ./daemon/jack.conf.json);
pipewire = builtins.fromJSON (builtins.readFile ./daemon/pipewire.conf.json);
pipewire-pulse = builtins.fromJSON (builtins.readFile ./daemon/pipewire-pulse.conf.json);
client = lib.importJSON ./daemon/client.conf.json;
client-rt = lib.importJSON ./daemon/client-rt.conf.json;
jack = lib.importJSON ./daemon/jack.conf.json;
pipewire = lib.importJSON ./daemon/pipewire.conf.json;
pipewire-pulse = lib.importJSON ./daemon/pipewire-pulse.conf.json;
};
configs = {

View File

@ -22,14 +22,14 @@ in
type = with types; listOf package;
default = [];
example = literalExpression "[ pkgs.odoo_enterprise ]";
description = "Odoo addons";
description = "Odoo addons.";
};
settings = mkOption {
type = format.type;
default = {};
description = ''
Odoo configuration settings. For more details see https://www.odoo.com/documentation/15.0/administration/install/deploy.html
Odoo configuration settings. For more details see <link xlink:href="https://www.odoo.com/documentation/15.0/administration/install/deploy.html"/>
'';
};

View File

@ -294,7 +294,7 @@ in
};
submissionOptions = mkOption {
type = types.attrs;
type = with types; attrsOf str;
default = {
smtpd_tls_security_level = "encrypt";
smtpd_sasl_auth_enable = "yes";
@ -312,7 +312,7 @@ in
};
submissionsOptions = mkOption {
type = types.attrs;
type = with types; attrsOf str;
default = {
smtpd_sasl_auth_enable = "yes";
smtpd_client_restrictions = "permit_sasl_authenticated,reject";

View File

@ -0,0 +1,240 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.mjolnir;
yamlConfig = {
inherit (cfg) dataPath managementRoom protectedRooms;
accessToken = "@ACCESS_TOKEN@"; # will be replaced in "generateConfig"
homeserverUrl =
if cfg.pantalaimon.enable then
"http://${cfg.pantalaimon.options.listenAddress}:${toString cfg.pantalaimon.options.listenPort}"
else
cfg.homeserverUrl;
pantalaimon = {
inherit (cfg.pantalaimon) username;
use = cfg.pantalaimon.enable;
password = "@PANTALAIMON_PASSWORD@"; # will be replaced in "generateConfig"
};
};
moduleConfigFile = pkgs.writeText "module-config.yaml" (
generators.toYAML { } (filterAttrs (_: v: v != null)
(fold recursiveUpdate { } [ yamlConfig cfg.settings ])));
# these config files will be merged one after the other to build the final config
configFiles = [
"${pkgs.mjolnir}/share/mjolnir/config/default.yaml"
moduleConfigFile
];
# this will generate the default.yaml file with all configFiles as inputs and
# replace all secret strings using replace-secret
generateConfig = pkgs.writeShellScript "mjolnir-generate-config" (
let
yqEvalStr = concatImapStringsSep " * " (pos: _: "select(fileIndex == ${toString (pos - 1)})") configFiles;
yqEvalArgs = concatStringsSep " " configFiles;
in
''
set -euo pipefail
umask 077
# mjolnir will try to load a config from "./config/default.yaml" in the working directory
# -> let's place the generated config there
mkdir -p ${cfg.dataPath}/config
# merge all config files into one, overriding settings of the previous one with the next config
# e.g. "eval-all 'select(fileIndex == 0) * select(fileIndex == 1)' filea.yaml fileb.yaml" will merge filea.yaml with fileb.yaml
${pkgs.yq-go}/bin/yq eval-all -P '${yqEvalStr}' ${yqEvalArgs} > ${cfg.dataPath}/config/default.yaml
${optionalString (cfg.accessTokenFile != null) ''
${pkgs.replace-secret}/bin/replace-secret '@ACCESS_TOKEN@' '${cfg.accessTokenFile}' ${cfg.dataPath}/config/default.yaml
''}
${optionalString (cfg.pantalaimon.passwordFile != null) ''
${pkgs.replace-secret}/bin/replace-secret '@PANTALAIMON_PASSWORD@' '${cfg.pantalaimon.passwordFile}' ${cfg.dataPath}/config/default.yaml
''}
''
);
in
{
options.services.mjolnir = {
enable = mkEnableOption "Mjolnir, a moderation tool for Matrix";
homeserverUrl = mkOption {
type = types.str;
default = "https://matrix.org";
description = ''
Where the homeserver is located (client-server URL).
If <literal>pantalaimon.enable</literal> is <literal>true</literal>, this option will become the homeserver to which <literal>pantalaimon</literal> connects.
The listen address of <literal>pantalaimon</literal> will then become the <literal>homeserverUrl</literal> of <literal>mjolnir</literal>.
'';
};
accessTokenFile = mkOption {
type = with types; nullOr path;
default = null;
description = ''
File containing the matrix access token for the <literal>mjolnir</literal> user.
'';
};
pantalaimon = mkOption {
description = ''
<literal>pantalaimon</literal> options (enables E2E Encryption support).
This will create a <literal>pantalaimon</literal> instance with the name "mjolnir".
'';
default = { };
type = types.submodule {
options = {
enable = mkEnableOption ''
If true, accessToken is ignored and the username/password below will be
used instead. The access token of the bot will be stored in the dataPath.
'';
username = mkOption {
type = types.str;
description = "The username to login with.";
};
passwordFile = mkOption {
type = with types; nullOr path;
default = null;
description = ''
File containing the matrix password for the <literal>mjolnir</literal> user.
'';
};
options = mkOption {
type = types.submodule (import ./pantalaimon-options.nix);
default = { };
description = ''
passthrough additional options to the <literal>pantalaimon</literal> service.
'';
};
};
};
};
dataPath = mkOption {
type = types.path;
default = "/var/lib/mjolnir";
description = ''
The directory the bot should store various bits of information in.
'';
};
managementRoom = mkOption {
type = types.str;
default = "#moderators:example.org";
description = ''
The room ID where people can use the bot. The bot has no access controls, so
anyone in this room can use the bot - secure your room!
This should be a room alias or room ID - not a matrix.to URL.
Note: <literal>mjolnir</literal> is fairly verbose - expect a lot of messages from it.
'';
};
protectedRooms = mkOption {
type = types.listOf types.str;
default = [ ];
example = literalExpression ''
[
"https://matrix.to/#/#yourroom:example.org"
"https://matrix.to/#/#anotherroom:example.org"
]
'';
description = ''
A list of rooms to protect (matrix.to URLs).
'';
};
settings = mkOption {
default = { };
type = (pkgs.formats.yaml { }).type;
example = literalExpression ''
{
autojoinOnlyIfManager = true;
automaticallyRedactForReasons = [ "spam" "advertising" ];
}
'';
description = ''
Additional settings (see <link xlink:href="https://github.com/matrix-org/mjolnir/blob/main/config/default.yaml">mjolnir default config</link> for available settings). These settings will override settings made by the module config.
'';
};
};
config = mkIf config.services.mjolnir.enable {
assertions = [
{
assertion = !(cfg.pantalaimon.enable && cfg.pantalaimon.passwordFile == null);
message = "Specify pantalaimon.passwordFile";
}
{
assertion = !(cfg.pantalaimon.enable && cfg.accessTokenFile != null);
message = "Do not specify accessTokenFile when using pantalaimon";
}
{
assertion = !(!cfg.pantalaimon.enable && cfg.accessTokenFile == null);
message = "Specify accessTokenFile when not using pantalaimon";
}
];
services.pantalaimon-headless.instances."mjolnir" = mkIf cfg.pantalaimon.enable
{
homeserver = cfg.homeserverUrl;
} // cfg.pantalaimon.options;
systemd.services.mjolnir = {
description = "mjolnir - a moderation tool for Matrix";
wants = [ "network-online.target" ] ++ optionals (cfg.pantalaimon.enable) [ "pantalaimon-mjolnir.service" ];
after = [ "network-online.target" ] ++ optionals (cfg.pantalaimon.enable) [ "pantalaimon-mjolnir.service" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
ExecStart = ''${pkgs.mjolnir}/bin/mjolnir'';
ExecStartPre = [ generateConfig ];
WorkingDirectory = cfg.dataPath;
StateDirectory = "mjolnir";
StateDirectoryMode = "0700";
ProtectSystem = "strict";
ProtectHome = true;
PrivateTmp = true;
NoNewPrivileges = true;
PrivateDevices = true;
User = "mjolnir";
Restart = "on-failure";
/* TODO: wait for #102397 to be resolved. Then load secrets from $CREDENTIALS_DIRECTORY+"/NAME"
DynamicUser = true;
LoadCredential = [] ++
optionals (cfg.accessTokenFile != null) [
"access_token:${cfg.accessTokenFile}"
] ++
optionals (cfg.pantalaimon.passwordFile != null) [
"pantalaimon_password:${cfg.pantalaimon.passwordFile}"
];
*/
};
};
users = {
users.mjolnir = {
group = "mjolnir";
isSystemUser = true;
};
groups.mjolnir = { };
};
};
meta = {
doc = ./mjolnir.xml;
maintainers = with maintainers; [ jojosch ];
};
}

View File

@ -0,0 +1,134 @@
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
version="5.0"
xml:id="module-services-mjolnir">
<title>Mjolnir (Matrix Moderation Tool)</title>
<para>
This chapter will show you how to set up your own, self-hosted
<link xlink:href="https://github.com/matrix-org/mjolnir">Mjolnir</link>
instance.
</para>
<para>
As an all-in-one moderation tool, it can protect your server from
malicious invites, spam messages, and whatever else you don't want.
In addition to server-level protection, Mjolnir is great for communities
wanting to protect their rooms without having to use their personal
accounts for moderation.
</para>
<para>
The bot by default includes support for bans, redactions, anti-spam,
server ACLs, room directory changes, room alias transfers, account
deactivation, room shutdown, and more.
</para>
<para>
See the <link xlink:href="https://github.com/matrix-org/mjolnir#readme">README</link>
page and the <link xlink:href="https://github.com/matrix-org/mjolnir/blob/main/docs/moderators.md">Moderator's guide</link>
for additional instructions on how to setup and use Mjolnir.
</para>
<para>
For <link linkend="opt-services.mjolnir.settings">additional settings</link>
see <link xlink:href="https://github.com/matrix-org/mjolnir/blob/main/config/default.yaml">the default configuration</link>.
</para>
<section xml:id="module-services-mjolnir-setup">
<title>Mjolnir Setup</title>
<para>
First create a new Room which will be used as a management room for Mjolnir. In
this room, Mjolnir will log possible errors and debugging information. You'll
need to set this Room-ID in <link linkend="opt-services.mjolnir.managementRoom">services.mjolnir.managementRoom</link>.
</para>
<para>
Next, create a new user for Mjolnir on your homeserver, if not present already.
</para>
<para>
The Mjolnir Matrix user expects to be free of any rate limiting.
See <link xlink:href="https://github.com/matrix-org/synapse/issues/6286">Synapse #6286</link>
for an example on how to achieve this.
</para>
<para>
If you want Mjolnir to be able to deactivate users, move room aliases, shutdown rooms, etc.
you'll need to make the Mjolnir user a Matrix server admin.
</para>
<para>
Now invite the Mjolnir user to the management room.
</para>
<para>
It is recommended to use <link xlink:href="https://github.com/matrix-org/pantalaimon">Pantalaimon</link>,
so your management room can be encrypted. This also applies if you are looking to moderate an encrypted room.
</para>
<para>
To enable the Pantalaimon E2E Proxy for mjolnir, enable
<link linkend="opt-services.mjolnir.pantalaimon.enable">services.mjolnir.pantalaimon</link>. This will
autoconfigure a new Pantalaimon instance, which will connect to the homeserver
set in <link linkend="opt-services.mjolnir.homeserverUrl">services.mjolnir.homeserverUrl</link> and Mjolnir itself
will be configured to connect to the new Pantalaimon instance.
</para>
<programlisting>
{
services.mjolnir = {
enable = true;
<link linkend="opt-services.mjolnir.homeserverUrl">homeserverUrl</link> = "https://matrix.domain.tld";
<link linkend="opt-services.mjolnir.pantalaimon">pantalaimon</link> = {
<link linkend="opt-services.mjolnir.pantalaimon.enable">enable</link> = true;
<link linkend="opt-services.mjolnir.pantalaimon.username">username</link> = "mjolnir";
<link linkend="opt-services.mjolnir.pantalaimon.passwordFile">passwordFile</link> = "/run/secrets/mjolnir-password";
};
<link linkend="opt-services.mjolnir.protectedRooms">protectedRooms</link> = [
"https://matrix.to/#/!xxx:domain.tld"
];
<link linkend="opt-services.mjolnir.managementRoom">managementRoom</link> = "!yyy:domain.tld";
};
}
</programlisting>
<section xml:id="module-services-mjolnir-setup-ems">
<title>Element Matrix Services (EMS)</title>
<para>
If you are using a managed <link xlink:href="https://ems.element.io/">"Element Matrix Services (EMS)"</link>
server, you will need to consent to the terms and conditions. Upon startup, an error
log entry with a URL to the consent page will be generated.
</para>
</section>
</section>
<section xml:id="module-services-mjolnir-matrix-synapse-antispam">
<title>Synapse Antispam Module</title>
<para>
A Synapse module is also available to apply the same rulesets the bot
uses across an entire homeserver.
</para>
<para>
To use the Antispam Module, add <package>matrix-synapse-plugins.matrix-synapse-mjolnir-antispam</package>
to the Synapse plugin list and enable the <literal>mjolnir.AntiSpam</literal> module.
</para>
<programlisting>
{
services.matrix-synapse = {
plugins = with pkgs; [
matrix-synapse-plugins.matrix-synapse-mjolnir-antispam
];
extraConfig = ''
modules:
- module: mjolnir.AntiSpam
config:
# Prevent servers/users in the ban lists from inviting users on this
# server to rooms. Default true.
block_invites: true
# Flag messages sent by servers/users in the ban lists as spam. Currently
# this means that spammy messages will appear as empty to users. Default
# false.
block_messages: false
# Remove users from the user directory search by filtering matrix IDs and
# display names by the entries in the user ban list. Default false.
block_usernames: false
# The room IDs of the ban lists to honour. Unlike other parts of Mjolnir,
# this list cannot be room aliases or permalinks. This server is expected
# to already be joined to the room - Mjolnir will not automatically join
# these rooms.
ban_lists:
- "!roomid:example.org"
'';
};
}
</programlisting>
</section>
</chapter>

View File

@ -0,0 +1,70 @@
{ config, lib, name, ... }:
with lib;
{
options = {
dataPath = mkOption {
type = types.path;
default = "/var/lib/pantalaimon-${name}";
description = ''
The directory where <literal>pantalaimon</literal> should store its state such as the database file.
'';
};
logLevel = mkOption {
type = types.enum [ "info" "warning" "error" "debug" ];
default = "warning";
description = ''
Set the log level of the daemon.
'';
};
homeserver = mkOption {
type = types.str;
example = "https://matrix.org";
description = ''
The URI of the homeserver that the <literal>pantalaimon</literal> proxy should
forward requests to, without the matrix API path but including
the http(s) schema.
'';
};
ssl = mkOption {
type = types.bool;
default = true;
description = ''
Whether or not SSL verification should be enabled for outgoing
connections to the homeserver.
'';
};
listenAddress = mkOption {
type = types.str;
default = "localhost";
description = ''
The address where the daemon will listen to client connections
for this homeserver.
'';
};
listenPort = mkOption {
type = types.port;
default = 8009;
description = ''
The port where the daemon will listen to client connections for
this homeserver. Note that the listen address/port combination
needs to be unique between different homeservers.
'';
};
extraSettings = mkOption {
type = types.attrs;
default = { };
description = ''
Extra configuration options. See
<link xlink:href="https://github.com/matrix-org/pantalaimon/blob/master/docs/man/pantalaimon.5.md">pantalaimon(5)</link>
for available options.
'';
};
};
}

View File

@ -0,0 +1,70 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.pantalaimon-headless;
iniFmt = pkgs.formats.ini { };
mkConfigFile = name: instanceConfig: iniFmt.generate "pantalaimon.conf" {
Default = {
LogLevel = instanceConfig.logLevel;
Notifications = false;
};
${name} = (recursiveUpdate
{
Homeserver = instanceConfig.homeserver;
ListenAddress = instanceConfig.listenAddress;
ListenPort = instanceConfig.listenPort;
SSL = instanceConfig.ssl;
# Set some settings to prevent user interaction for headless operation
IgnoreVerification = true;
UseKeyring = false;
}
instanceConfig.extraSettings
);
};
mkPantalaimonService = name: instanceConfig:
nameValuePair "pantalaimon-${name}" {
description = "pantalaimon instance ${name} - E2EE aware proxy daemon for matrix clients";
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
ExecStart = ''${pkgs.pantalaimon-headless}/bin/pantalaimon --config ${mkConfigFile name instanceConfig} --data-path ${instanceConfig.dataPath}'';
Restart = "on-failure";
DynamicUser = true;
NoNewPrivileges = true;
PrivateDevices = true;
PrivateTmp = true;
ProtectHome = true;
ProtectSystem = "strict";
StateDirectory = "pantalaimon-${name}";
};
};
in
{
options.services.pantalaimon-headless.instances = mkOption {
default = { };
type = types.attrsOf (types.submodule (import ./pantalaimon-options.nix));
description = ''
Declarative instance config.
Note: to use pantalaimon interactively, e.g. for a Matrix client which does not
support End-to-end encryption (like <literal>fractal</literal>), refer to the home-manager module.
'';
};
config = mkIf (config.services.pantalaimon-headless.instances != { })
{
systemd.services = mapAttrs' mkPantalaimonService config.services.pantalaimon-headless.instances;
};
meta = {
maintainers = with maintainers; [ jojosch ];
};
}

View File

@ -0,0 +1,107 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.ananicy;
configFile = pkgs.writeText "ananicy.conf" (generators.toKeyValue { } cfg.settings);
extraRules = pkgs.writeText "extraRules" cfg.extraRules;
servicename = if ((lib.getName cfg.package) == (lib.getName pkgs.ananicy-cpp)) then "ananicy-cpp" else "ananicy";
in
{
options = {
services.ananicy = {
enable = mkEnableOption "Ananicy, an auto nice daemon";
package = mkOption {
type = types.package;
default = pkgs.ananicy;
defaultText = literalExpression "pkgs.ananicy";
example = literalExpression "pkgs.ananicy-cpp";
description = ''
Which ananicy package to use.
'';
};
settings = mkOption {
type = with types; attrsOf (oneOf [ int bool str ]);
default = { };
example = {
apply_nice = false;
};
description = ''
See <link xlink:href="https://github.com/Nefelim4ag/Ananicy/blob/master/ananicy.d/ananicy.conf"/>
'';
};
extraRules = mkOption {
type = types.str;
default = "";
description = ''
Extra rules in json format on separate lines. See:
<link xlink:href="https://github.com/Nefelim4ag/Ananicy#configuration"/>
<link xlink:href="https://gitlab.com/ananicy-cpp/ananicy-cpp/#global-configuration"/>
'';
example = literalExpression ''
'''
{ "name": "eog", "type": "Image-View" }
{ "name": "fdupes", "type": "BG_CPUIO" }
'''
'';
};
};
};
config = mkIf cfg.enable {
environment = {
systemPackages = [ cfg.package ];
etc."ananicy.d".source = pkgs.runCommandLocal "ananicyfiles" { } ''
mkdir -p $out
# ananicy-cpp does not include rules or settings on purpose
cp -r ${pkgs.ananicy}/etc/ananicy.d/* $out
rm $out/ananicy.conf
cp ${configFile} $out/ananicy.conf
${optionalString (cfg.extraRules != "") "cp ${extraRules} $out/nixRules.rules"}
'';
};
# ananicy and ananicy-cpp have different default settings
services.ananicy.settings =
let
mkOD = mkOptionDefault;
in
{
cgroup_load = mkOD true;
type_load = mkOD true;
rule_load = mkOD true;
apply_nice = mkOD true;
apply_ioclass = mkOD true;
apply_ionice = mkOD true;
apply_sched = mkOD true;
apply_oom_score_adj = mkOD true;
apply_cgroup = mkOD true;
} // (if ((lib.getName cfg.package) == (lib.getName pkgs.ananicy-cpp)) then {
# https://gitlab.com/ananicy-cpp/ananicy-cpp/-/blob/master/src/config.cpp#L12
loglevel = mkOD "warn"; # default is info but its spammy
cgroup_realtime_workaround = mkOD true;
} else {
# https://github.com/Nefelim4ag/Ananicy/blob/master/ananicy.d/ananicy.conf
check_disks_schedulers = mkOD true;
check_freq = mkOD 5;
});
systemd = {
# https://gitlab.com/ananicy-cpp/ananicy-cpp/#cgroups applies to both ananicy and -cpp
enableUnifiedCgroupHierarchy = mkDefault false;
packages = [ cfg.package ];
services."${servicename}" = {
wantedBy = [ "default.target" ];
};
};
};
meta = {
maintainers = with maintainers; [ artturin ];
};
}

View File

@ -0,0 +1,71 @@
{ config, pkgs, lib, ... }:
let
cfg = config.services.xmrig;
json = pkgs.formats.json { };
configFile = json.generate "config.json" cfg.settings;
in
with lib;
{
options = {
services.xmrig = {
enable = mkEnableOption "XMRig Mining Software";
package = mkOption {
type = types.package;
default = pkgs.xmrig;
example = literalExpression "pkgs.xmrig-mo";
description = "XMRig package to use.";
};
settings = mkOption {
default = { };
type = json.type;
example = literalExpression ''
{
autosave = true;
cpu = true;
opencl = false;
cuda = false;
pools = [
{
url = "pool.supportxmr.com:443";
user = "your-wallet";
keepalive = true;
tls = true;
}
]
}
'';
description = ''
XMRig configuration. Refer to
<link xlink:href="https://xmrig.com/docs/miner/config"/>
for details on supported values.
'';
};
};
};
config = mkIf cfg.enable {
systemd.services.xmrig = {
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
description = "XMRig Mining Software Service";
serviceConfig = {
ExecStartPre = "${cfg.package}/bin/xmrig --config=${configFile} --dry-run";
ExecStart = "${cfg.package}/bin/xmrig --config=${configFile}";
DynamicUser = true;
};
};
};
meta = with lib; {
description = "XMRig Mining Software Service";
license = licenses.gpl3Only;
maintainers = with maintainers; [ ratsclub ];
};
}

View File

@ -57,7 +57,7 @@ in {
description = ''
Build a minimal collectd package with only the configured `services.collectd.plugins`
'';
type = types.bool;
type = bool;
};
user = mkOption {
@ -98,7 +98,7 @@ in {
description = ''
Attribute set of plugin names to plugin config segments
'';
type = types.attrsOf types.str;
type = attrsOf lines;
};
extraConfig = mkOption {

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,7 @@ let
cfg = config.services.unifi-poller;
configFile = pkgs.writeText "unifi-poller.json" (generators.toJSON {} {
inherit (cfg) poller influxdb prometheus unifi;
inherit (cfg) poller influxdb loki prometheus unifi;
});
in {
@ -118,6 +118,61 @@ in {
};
};
loki = {
url = mkOption {
type = types.str;
default = "";
description = ''
URL of the Loki host.
'';
};
user = mkOption {
type = types.str;
default = "";
description = ''
Username for Loki.
'';
};
pass = mkOption {
type = types.path;
default = pkgs.writeText "unifi-poller-loki-default.password" "";
defaultText = "unifi-poller-influxdb-default.password";
description = ''
Path of a file containing the password for Loki.
This file needs to be readable by the unifi-poller user.
'';
apply = v: "file://${v}";
};
verify_ssl = mkOption {
type = types.bool;
default = false;
description = ''
Verify Loki's certificate.
'';
};
tenant_id = mkOption {
type = types.str;
default = "";
description = ''
Tenant ID to use in Loki.
'';
};
interval = mkOption {
type = types.str;
default = "2m";
description = ''
How often the events are polled and pushed to Loki.
'';
};
timeout = mkOption {
type = types.str;
default = "10s";
description = ''
Should be increased in case of timeout errors.
'';
};
};
unifi = let
controllerOptions = {
user = mkOption {
@ -157,7 +212,28 @@ in {
type = types.bool;
default = false;
description = ''
Collect and save data from the intrusion detection system to influxdb.
Collect and save data from the intrusion detection system to influxdb and Loki.
'';
};
save_events = mkOption {
type = types.bool;
default = false;
description = ''
Collect and save data from UniFi events to influxdb and Loki.
'';
};
save_alarms = mkOption {
type = types.bool;
default = false;
description = ''
Collect and save data from UniFi alarms to influxdb and Loki.
'';
};
save_anomalies = mkOption {
type = types.bool;
default = false;
description = ''
Collect and save data from UniFi anomalies to influxdb and Loki.
'';
};
save_dpi = mkOption {

View File

@ -0,0 +1,80 @@
{ config, lib, pkgs, ... }:
with lib;
let cfg = config.services.antennas;
in
{
options = {
services.antennas = {
enable = mkEnableOption "Antennas";
tvheadendUrl = mkOption {
type = types.str;
default = "http://localhost:9981";
description = "URL of Tvheadend.";
};
antennasUrl = mkOption {
type = types.str;
default = "http://127.0.0.1:5004";
description = "URL of Antennas.";
};
tunerCount = mkOption {
type = types.int;
default = 6;
description = "Numbers of tuners in tvheadend.";
};
deviceUUID = mkOption {
type = types.str;
default = "2f70c0d7-90a3-4429-8275-cbeeee9cd605";
description = "Device tuner UUID. Change this if you are running multiple instances.";
};
};
};
config = mkIf cfg.enable {
systemd.services.antennas = {
description = "Antennas HDHomeRun emulator for Tvheadend. ";
wantedBy = [ "multi-user.target" ];
# Config
environment = {
TVHEADEND_URL = cfg.tvheadendUrl;
ANTENNAS_URL = cfg.antennasUrl;
TUNER_COUNT = toString cfg.tunerCount;
DEVICE_UUID = cfg.deviceUUID;
};
serviceConfig = {
ExecStart = "${pkgs.antennas}/bin/antennas";
# Antennas expects all resources like html and config to be relative to it's working directory
WorkingDirectory = "${pkgs.antennas}/libexec/antennas/deps/antennas/";
# Hardening
CapabilityBoundingSet = [ "" ];
DynamicUser = true;
LockPersonality = true;
ProcSubset = "pid";
PrivateDevices = true;
PrivateUsers = true;
PrivateTmp = true;
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectProc = "invisible";
ProtectSystem = "strict";
RestrictNamespaces = true;
RestrictRealtime = true;
};
};
};
}

View File

@ -28,6 +28,16 @@ let
'';
configFile = if (cfg.configFile != null) then cfg.configFile else configFile';
preStart = ''
install ${configFile} /run/${RuntimeDirectory}/ddclient.conf
${lib.optionalString (cfg.configFile == null) (if (cfg.passwordFile != null) then ''
password=$(head -n 1 ${cfg.passwordFile})
sed -i "s/^password=$/password=$password/" /run/${RuntimeDirectory}/ddclient.conf
'' else ''
sed -i '/^password=$/d' /run/${RuntimeDirectory}/ddclient.conf
'')}
'';
in
with lib;
@ -57,6 +67,15 @@ with lib;
'';
};
package = mkOption {
type = package;
default = pkgs.ddclient;
defaultText = "pkgs.ddclient";
description = ''
The ddclient executable package run by the service.
'';
};
domains = mkOption {
default = [ "" ];
type = listOf str;
@ -195,20 +214,13 @@ with lib;
serviceConfig = {
DynamicUser = true;
RuntimeDirectoryMode = "0700";
inherit RuntimeDirectory;
inherit StateDirectory;
Type = "oneshot";
ExecStart = "${lib.getBin pkgs.ddclient}/bin/ddclient -file /run/${RuntimeDirectory}/ddclient.conf";
ExecStartPre = "!${pkgs.writeShellScript "ddclient-prestart" preStart}";
ExecStart = "${lib.getBin cfg.package}/bin/ddclient -file /run/${RuntimeDirectory}/ddclient.conf";
};
preStart = ''
install -m 600 ${configFile} /run/${RuntimeDirectory}/ddclient.conf
${optionalString (cfg.configFile == null) (if (cfg.passwordFile != null) then ''
password=$(head -n 1 ${cfg.passwordFile})
sed -i "s/^password=$/password=$password/" /run/${RuntimeDirectory}/ddclient.conf
'' else ''
sed -i '/^password=$/d' /run/${RuntimeDirectory}/ddclient.conf
'')}
'';
};
systemd.timers.ddclient = {

View File

@ -0,0 +1,138 @@
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.services.lxd-image-server;
format = pkgs.formats.toml {};
location = "/var/www/simplestreams";
in
{
options = {
services.lxd-image-server = {
enable = mkEnableOption "lxd-image-server";
group = mkOption {
type = types.str;
description = "Group assigned to the user and the webroot directory.";
default = "nginx";
example = "www-data";
};
settings = mkOption {
type = format.type;
description = ''
Configuration for lxd-image-server.
Example see <link xlink:href="https://github.com/Avature/lxd-image-server/blob/master/config.toml"/>.
'';
default = {};
};
nginx = {
enable = mkEnableOption "nginx";
domain = mkOption {
type = types.str;
description = "Domain to use for nginx virtual host.";
example = "images.example.org";
};
};
};
};
config = mkMerge [
(mkIf (cfg.enable) {
users.users.lxd-image-server = {
isSystemUser = true;
group = cfg.group;
};
users.groups.${cfg.group} = {};
environment.etc."lxd-image-server/config.toml".source = format.generate "config.toml" cfg.settings;
services.logrotate.paths.lxd-image-server = {
path = "/var/log/lxd-image-server/lxd-image-server.log";
frequency = "daily";
keep = 21;
user = "lxd-image-server";
group = cfg.group;
extraConfig = ''
missingok
compress
delaycompress
copytruncate
notifempty
'';
};
systemd.tmpfiles.rules = [
"d /var/www/simplestreams 0755 lxd-image-server ${cfg.group}"
];
systemd.services.lxd-image-server = {
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
description = "LXD Image Server";
script = ''
${pkgs.lxd-image-server}/bin/lxd-image-server init
${pkgs.lxd-image-server}/bin/lxd-image-server watch
'';
serviceConfig = {
User = "lxd-image-server";
Group = cfg.group;
DynamicUser = true;
LogsDirectory = "lxd-image-server";
RuntimeDirectory = "lxd-image-server";
ExecReload = "${pkgs.lxd-image-server}/bin/lxd-image-server reload";
ReadWritePaths = [ location ];
};
};
})
# this is seperate so it can be enabled on mirrored hosts
(mkIf (cfg.nginx.enable) {
# https://github.com/Avature/lxd-image-server/blob/master/resources/nginx/includes/lxd-image-server.pkg.conf
services.nginx.virtualHosts = {
"${cfg.nginx.domain}" = {
forceSSL = true;
enableACME = mkDefault true;
root = location;
locations = {
"/streams/v1/" = {
index = "index.json";
};
# Serve json files with content type header application/json
"~ \.json$" = {
extraConfig = ''
add_header Content-Type application/json;
'';
};
"~ \.tar.xz$" = {
extraConfig = ''
add_header Content-Type application/octet-stream;
'';
};
"~ \.tar.gz$" = {
extraConfig = ''
add_header Content-Type application/octet-stream;
'';
};
# Deny access to document root and the images folder
"~ ^/(images/)?$" = {
return = "403";
};
};
};
};
})
];
}

View File

@ -0,0 +1,102 @@
# Mosquitto {#module-services-mosquitto}
Mosquitto is a MQTT broker often used for IoT or home automation data transport.
## Quickstart {#module-services-mosquitto-quickstart}
A minimal configuration for Mosquitto is
```nix
services.mosquitto = {
enable = true;
listeners = [ {
acl = [ "pattern readwrite #" ];
omitPasswordAuth = true;
settings.allow_anonymous = true;
} ];
};
```
This will start a broker on port 1883, listening on all interfaces of the machine, allowing
read/write access to all topics to any user without password requirements.
User authentication can be configured with the `users` key of listeners. A config that gives
full read access to a user `monitor` and restricted write access to a user `service` could look
like
```nix
services.mosquitto = {
enable = true;
listeners = [ {
users = {
monitor = {
acl = [ "read #" ];
password = "monitor";
};
service = {
acl = [ "write service/#" ];
password = "service";
};
};
} ];
};
```
TLS authentication is configured by setting TLS-related options of the listener:
```nix
services.mosquitto = {
enable = true;
listeners = [ {
port = 8883; # port change is not required, but helpful to avoid mistakes
# ...
settings = {
cafile = "/path/to/mqtt.ca.pem";
certfile = "/path/to/mqtt.pem";
keyfile = "/path/to/mqtt.key";
};
} ];
```
## Configuration {#module-services-mosquitto-config}
The Mosquitto configuration has four distinct types of settings:
the global settings of the daemon, listeners, plugins, and bridges.
Bridges and listeners are part of the global configuration, plugins are part of listeners.
Users of the broker are configured as parts of listeners rather than globally, allowing
configurations in which a given user is only allowed to log in to the broker using specific
listeners (eg to configure an admin user with full access to all topics, but restricted to
localhost).
Almost all options of Mosquitto are available for configuration at their appropriate levels, some
as NixOS options written in camel case, the remainders under `settings` with their exact names in
the Mosquitto config file. The exceptions are `acl_file` (which is always set according to the
`acl` attributes of a listener and its users) and `per_listener_settings` (which is always set to
`true`).
### Password authentication {#module-services-mosquitto-config-passwords}
Mosquitto can be run in two modes, with a password file or without. Each listener has its own
password file, and different listeners may use different password files. Password file generation
can be disabled by setting `omitPasswordAuth = true` for a listener; in this case it is necessary
to either set `settings.allow_anonymous = true` to allow all logins, or to configure other
authentication methods like TLS client certificates with `settings.use_identity_as_username = true`.
The default is to generate a password file for each listener from the users configured to that
listener. Users with no configured password will not be added to the password file and thus
will not be able to use the broker.
### ACL format {#module-services-mosquitto-config-acl}
Every listener has a Mosquitto `acl_file` attached to it. This ACL is configured via two
attributes of the config:
* the `acl` attribute of the listener configures pattern ACL entries and topic ACL entries
for anonymous users. Each entry must be prefixed with `pattern` or `topic` to distinguish
between these two cases.
* the `acl` attribute of every user configures in the listener configured the ACL for that
given user. Only topic ACLs are supported by Mosquitto in this setting, so no prefix is
required or allowed.
The default ACL for a listener is empty, disallowing all accesses from all clients. To configure
a completely open ACL, set `acl = [ "pattern readwrite #" ]` in the listener.

View File

@ -257,18 +257,28 @@ let
users = mkOption {
type = attrsOf userOptions;
example = { john = { password = "123456"; acl = [ "topic readwrite john/#" ]; }; };
example = { john = { password = "123456"; acl = [ "readwrite john/#" ]; }; };
description = ''
A set of users and their passwords and ACLs.
'';
default = {};
};
omitPasswordAuth = mkOption {
type = bool;
description = ''
Omits password checking, allowing anyone to log in with any user name unless
other mandatory authentication methods (eg TLS client certificates) are configured.
'';
default = false;
};
acl = mkOption {
type = listOf str;
description = ''
Additional ACL items to prepend to the generated ACL file.
'';
example = [ "pattern read #" "topic readwrite anon/report/#" ];
default = [];
};
@ -294,9 +304,9 @@ let
formatListener = idx: listener:
[
"listener ${toString listener.port} ${toString listener.address}"
"password_file ${cfg.dataDir}/passwd-${toString idx}"
"acl_file ${makeACLFile idx listener.users listener.acl}"
]
++ optional (! listener.omitPasswordAuth) "password_file ${cfg.dataDir}/passwd-${toString idx}"
++ formatFreeform {} listener.settings
++ concatMap formatAuthPlugin listener.authPlugins;
@ -645,5 +655,10 @@ in
};
meta.maintainers = with lib.maintainers; [ pennae ];
meta = {
maintainers = with lib.maintainers; [ pennae ];
# Don't edit the docbook xml directly, edit the md and generate it:
# `pandoc mosquitto.md -t docbook --top-level-division=chapter --extract-media=media -f markdown+smart > mosquitto.xml`
doc = ./mosquitto.xml;
};
}

View File

@ -0,0 +1,147 @@
<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-mosquitto">
<title>Mosquitto</title>
<para>
Mosquitto is a MQTT broker often used for IoT or home automation
data transport.
</para>
<section xml:id="module-services-mosquitto-quickstart">
<title>Quickstart</title>
<para>
A minimal configuration for Mosquitto is
</para>
<programlisting language="bash">
services.mosquitto = {
enable = true;
listeners = [ {
acl = [ &quot;pattern readwrite #&quot; ];
omitPasswordAuth = true;
settings.allow_anonymous = true;
} ];
};
</programlisting>
<para>
This will start a broker on port 1883, listening on all interfaces
of the machine, allowing read/write access to all topics to any
user without password requirements.
</para>
<para>
User authentication can be configured with the
<literal>users</literal> key of listeners. A config that gives
full read access to a user <literal>monitor</literal> and
restricted write access to a user <literal>service</literal> could
look like
</para>
<programlisting language="bash">
services.mosquitto = {
enable = true;
listeners = [ {
users = {
monitor = {
acl = [ &quot;read #&quot; ];
password = &quot;monitor&quot;;
};
service = {
acl = [ &quot;write service/#&quot; ];
password = &quot;service&quot;;
};
};
} ];
};
</programlisting>
<para>
TLS authentication is configured by setting TLS-related options of
the listener:
</para>
<programlisting language="bash">
services.mosquitto = {
enable = true;
listeners = [ {
port = 8883; # port change is not required, but helpful to avoid mistakes
# ...
settings = {
cafile = &quot;/path/to/mqtt.ca.pem&quot;;
certfile = &quot;/path/to/mqtt.pem&quot;;
keyfile = &quot;/path/to/mqtt.key&quot;;
};
} ];
</programlisting>
</section>
<section xml:id="module-services-mosquitto-config">
<title>Configuration</title>
<para>
The Mosquitto configuration has four distinct types of settings:
the global settings of the daemon, listeners, plugins, and
bridges. Bridges and listeners are part of the global
configuration, plugins are part of listeners. Users of the broker
are configured as parts of listeners rather than globally,
allowing configurations in which a given user is only allowed to
log in to the broker using specific listeners (eg to configure an
admin user with full access to all topics, but restricted to
localhost).
</para>
<para>
Almost all options of Mosquitto are available for configuration at
their appropriate levels, some as NixOS options written in camel
case, the remainders under <literal>settings</literal> with their
exact names in the Mosquitto config file. The exceptions are
<literal>acl_file</literal> (which is always set according to the
<literal>acl</literal> attributes of a listener and its users) and
<literal>per_listener_settings</literal> (which is always set to
<literal>true</literal>).
</para>
<section xml:id="module-services-mosquitto-config-passwords">
<title>Password authentication</title>
<para>
Mosquitto can be run in two modes, with a password file or
without. Each listener has its own password file, and different
listeners may use different password files. Password file
generation can be disabled by setting
<literal>omitPasswordAuth = true</literal> for a listener; in
this case it is necessary to either set
<literal>settings.allow_anonymous = true</literal> to allow all
logins, or to configure other authentication methods like TLS
client certificates with
<literal>settings.use_identity_as_username = true</literal>.
</para>
<para>
The default is to generate a password file for each listener
from the users configured to that listener. Users with no
configured password will not be added to the password file and
thus will not be able to use the broker.
</para>
</section>
<section xml:id="module-services-mosquitto-config-acl">
<title>ACL format</title>
<para>
Every listener has a Mosquitto <literal>acl_file</literal>
attached to it. This ACL is configured via two attributes of the
config:
</para>
<itemizedlist spacing="compact">
<listitem>
<para>
the <literal>acl</literal> attribute of the listener
configures pattern ACL entries and topic ACL entries for
anonymous users. Each entry must be prefixed with
<literal>pattern</literal> or <literal>topic</literal> to
distinguish between these two cases.
</para>
</listitem>
<listitem>
<para>
the <literal>acl</literal> attribute of every user
configures in the listener configured the ACL for that given
user. Only topic ACLs are supported by Mosquitto in this
setting, so no prefix is required or allowed.
</para>
</listitem>
</itemizedlist>
<para>
The default ACL for a listener is empty, disallowing all
accesses from all clients. To configure a completely open ACL,
set <literal>acl = [ &quot;pattern readwrite #&quot; ]</literal>
in the listener.
</para>
</section>
</section>
</chapter>

View File

@ -289,13 +289,13 @@ in
};
chroot = mkOption {
default = true;
default = false;
type = types.bool;
description = ''
Change process root directory to the directory where the config file is located (/etc/tinc/netname/), for added security.
The chroot is performed after all the initialization is done, after writing pid files and opening network sockets.
Note that tinc can't run scripts anymore (such as tinc-down or host-up), unless it is setup to be runnable inside chroot environment.
Note that this currently breaks dns resolution and tinc can't run scripts anymore (such as tinc-down or host-up), unless it is setup to be runnable inside chroot environment.
'';
};

View File

@ -9,25 +9,6 @@ let
${optionalString (cfg.maximumJavaHeapSize != null) "-Xmx${(toString cfg.maximumJavaHeapSize)}m"} \
-jar ${stateDir}/lib/ace.jar
'';
mountPoints = [
{
what = "${cfg.unifiPackage}/dl";
where = "${stateDir}/dl";
}
{
what = "${cfg.unifiPackage}/lib";
where = "${stateDir}/lib";
}
{
what = "${cfg.mongodbPackage}/bin";
where = "${stateDir}/bin";
}
{
what = "${cfg.dataDir}";
where = "${stateDir}/data";
}
];
systemdMountPoints = map (m: "${utils.escapeSystemdPath m.where}.mount") mountPoints;
in
{
@ -68,16 +49,6 @@ in
'';
};
services.unifi.dataDir = mkOption {
type = types.str;
default = "${stateDir}/data";
description = ''
Where to store the database and other data.
This directory will be bind-mounted to ${stateDir}/data as part of the service startup.
'';
};
services.unifi.openPorts = mkOption {
type = types.bool;
default = true;
@ -136,32 +107,11 @@ in
];
};
# We must create the binary directories as bind mounts instead of symlinks
# This is because the controller resolves all symlinks to absolute paths
# to be used as the working directory.
systemd.mounts = map ({ what, where }: {
bindsTo = [ "unifi.service" ];
partOf = [ "unifi.service" ];
unitConfig.RequiresMountsFor = stateDir;
options = "bind";
what = what;
where = where;
}) mountPoints;
systemd.tmpfiles.rules = [
"d '${stateDir}' 0700 unifi - - -"
"d '${stateDir}/data' 0700 unifi - - -"
"d '${stateDir}/webapps' 0700 unifi - - -"
"L+ '${stateDir}/webapps/ROOT' - - - - ${cfg.unifiPackage}/webapps/ROOT"
];
systemd.services.unifi = {
description = "UniFi controller daemon";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ] ++ systemdMountPoints;
partOf = systemdMountPoints;
bindsTo = systemdMountPoints;
unitConfig.RequiresMountsFor = stateDir;
after = [ "network.target" ];
# This a HACK to fix missing dependencies of dynamic libs extracted from jars
environment.LD_LIBRARY_PATH = with pkgs.stdenv; "${cc.cc.lib}/lib";
# Make sure package upgrades trigger a service restart
@ -209,8 +159,27 @@ in
SystemCallErrorNumber = "EPERM";
SystemCallFilter = [ "@system-service" ];
# Required for ProtectSystem=strict
BindPaths = [ stateDir ];
StateDirectory = "unifi";
RuntimeDirectory = "unifi";
LogsDirectory = "unifi";
CacheDirectory= "unifi";
TemporaryFileSystem = [
# required as we want to create bind mounts below
"${stateDir}/webapps:rw"
];
# We must create the binary directories as bind mounts instead of symlinks
# This is because the controller resolves all symlinks to absolute paths
# to be used as the working directory.
BindPaths = [
"/var/log/unifi:${stateDir}/logs"
"/run/unifi:${stateDir}/run"
"${cfg.unifiPackage}/dl:${stateDir}/dl"
"${cfg.unifiPackage}/lib:${stateDir}/lib"
"${cfg.mongodbPackage}/bin:${stateDir}/bin"
"${cfg.unifiPackage}/webapps/ROOT:${stateDir}/webapps/ROOT"
];
# Needs network access
PrivateNetwork = false;
@ -220,6 +189,9 @@ in
};
};
imports = [
(mkRemovedOptionModule [ "services" "unifi" "dataDir" ] "You should move contents of dataDir to /var/lib/unifi/data" )
];
meta.maintainers = with lib.maintainers; [ erictapen pennae ];
}

View File

@ -1012,6 +1012,7 @@ in
# Tor cannot currently bind privileged port when PrivateUsers=true,
# see https://gitlab.torproject.org/legacy/trac/-/issues/20930
PrivateUsers = !bindsPrivilegedPort;
ProcSubset = "pid";
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
@ -1019,6 +1020,7 @@ in
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectProc = "invisible";
ProtectSystem = "strict";
RemoveIPC = true;
RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" "AF_NETLINK" ];

View File

@ -33,7 +33,7 @@ let
fi
'';
streamingConfig = builtins.fromJSON (builtins.readFile ./streaming.json);
streamingConfig = lib.importJSON ./streaming.json;
logConfig = {
appenders.stdout.type = "stdout";
categories = {

View File

@ -0,0 +1,139 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.code-server;
defaultUser = "code-server";
defaultGroup = defaultUser;
in {
###### interface
options = {
services.code-server = {
enable = mkEnableOption "code-server";
package = mkOption {
default = pkgs.code-server;
defaultText = "pkgs.code-server";
description = "Which code-server derivation to use.";
type = types.package;
};
extraPackages = mkOption {
default = [ ];
description = "Packages that are available in the PATH of code-server.";
example = "[ pkgs.go ]";
type = types.listOf types.package;
};
extraEnvironment = mkOption {
type = types.attrsOf types.str;
description =
"Additional environment variables to passed to code-server.";
default = { };
example = { PKG_CONFIG_PATH = "/run/current-system/sw/lib/pkgconfig"; };
};
extraArguments = mkOption {
default = [ "--disable-telemetry" ];
description = "Additional arguments that passed to code-server";
example = ''[ "--verbose" ]'';
type = types.listOf types.str;
};
host = mkOption {
default = "127.0.0.1";
description = "The host-ip to bind to.";
type = types.str;
};
port = mkOption {
default = 4444;
description = "The port where code-server runs.";
type = types.port;
};
auth = mkOption {
default = "password";
description = "The type of authentication to use.";
type = types.enum [ "none" "password" ];
};
hashedPassword = mkOption {
default = "";
description =
"Create the password with: 'echo -n 'thisismypassword' | npx argon2-cli -e'.";
type = types.str;
};
user = mkOption {
default = defaultUser;
example = "yourUser";
description = ''
The user to run code-server as.
By default, a user named <literal>${defaultUser}</literal> will be created.
'';
type = types.str;
};
group = mkOption {
default = defaultGroup;
example = "yourGroup";
description = ''
The group to run code-server under.
By default, a group named <literal>${defaultGroup}</literal> will be created.
'';
type = types.str;
};
extraGroups = mkOption {
default = [ ];
description =
"An array of additional groups for the <literal>${defaultUser}</literal> user.";
example = [ "docker" ];
type = types.listOf types.str;
};
};
};
###### implementation
config = mkIf cfg.enable {
systemd.services.code-server = {
description = "VSCode server";
wantedBy = [ "multi-user.target" ];
after = [ "network-online.target" ];
path = cfg.extraPackages;
environment = {
HASHED_PASSWORD = cfg.hashedPassword;
} // cfg.extraEnvironment;
serviceConfig = {
ExecStart = "${cfg.package}/bin/code-server --bind-addr ${cfg.host}:${toString cfg.port} --auth ${cfg.auth} " + builtins.concatStringsSep " " cfg.extraArguments;
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
RuntimeDirectory = cfg.user;
User = cfg.user;
Group = cfg.group;
Restart = "on-failure";
};
};
users.users."${cfg.user}" = mkMerge [
(mkIf (cfg.user == defaultUser) {
isNormalUser = true;
description = "code-server user";
inherit (cfg) group;
})
{
packages = cfg.extraPackages;
inherit (cfg) extraGroups;
}
];
users.groups."${defaultGroup}" = mkIf (cfg.group == defaultGroup) { };
};
meta.maintainers = with maintainers; [ stackshadow ];
}

View File

@ -118,7 +118,7 @@ in {
++ extraOptions);
in {
description = "hledger-web - web-app for the hledger accounting tool.";
documentation = [ https://hledger.org/hledger-web.html ];
documentation = [ "https://hledger.org/hledger-web.html" ];
wantedBy = [ "multi-user.target" ];
after = [ "networking.target" ];
serviceConfig = mkMerge [

View File

@ -38,7 +38,7 @@ let
// (if cfg.smtp.authenticate then { SMTP_LOGIN = cfg.smtp.user; } else {})
// cfg.extraConfig;
systemCallsList = [ "@clock" "@cpu-emulation" "@debug" "@keyring" "@module" "@mount" "@obsolete" "@raw-io" "@reboot" "@setuid" "@swap" ];
systemCallsList = [ "@cpu-emulation" "@debug" "@keyring" "@ipc" "@mount" "@obsolete" "@privileged" "@setuid" ];
cfgService = {
# User and group
@ -50,6 +50,9 @@ let
# Logs directory and mode
LogsDirectory = "mastodon";
LogsDirectoryMode = "0750";
# Proc filesystem
ProcSubset = "pid";
ProtectProc = "invisible";
# Access write directories
UMask = "0027";
# Capabilities
@ -74,6 +77,7 @@ let
MemoryDenyWriteExecute = false;
RestrictRealtime = true;
RestrictSUIDSGID = true;
RemoveIPC = true;
PrivateMounts = true;
# System Call Filtering
SystemCallArchitectures = "native";
@ -464,7 +468,7 @@ in {
Type = "oneshot";
WorkingDirectory = cfg.package;
# System Call Filtering
SystemCallFilter = "~" + lib.concatStringsSep " " (systemCallsList ++ [ "@resources" ]);
SystemCallFilter = [ ("~" + lib.concatStringsSep " " (systemCallsList ++ [ "@resources" ])) "@chown" "pipe" "pipe2" ];
} // cfgService;
after = [ "network.target" ];
@ -491,7 +495,7 @@ in {
EnvironmentFile = "/var/lib/mastodon/.secrets_env";
WorkingDirectory = cfg.package;
# System Call Filtering
SystemCallFilter = "~" + lib.concatStringsSep " " (systemCallsList ++ [ "@resources" ]);
SystemCallFilter = [ ("~" + lib.concatStringsSep " " (systemCallsList ++ [ "@resources" ])) "@chown" "pipe" "pipe2" ];
} // cfgService;
after = [ "mastodon-init-dirs.service" "network.target" ] ++ (if databaseActuallyCreateLocally then [ "postgresql.service" ] else []);
wantedBy = [ "multi-user.target" ];
@ -517,7 +521,7 @@ in {
RuntimeDirectory = "mastodon-streaming";
RuntimeDirectoryMode = "0750";
# System Call Filtering
SystemCallFilter = "~" + lib.concatStringsSep " " (systemCallsList ++ [ "@privileged" "@resources" ]);
SystemCallFilter = [ ("~" + lib.concatStringsSep " " (systemCallsList ++ [ "@memlock" "@resources" ])) "pipe" "pipe2" ];
} // cfgService;
};
@ -541,7 +545,7 @@ in {
RuntimeDirectory = "mastodon-web";
RuntimeDirectoryMode = "0750";
# System Call Filtering
SystemCallFilter = "~" + lib.concatStringsSep " " (systemCallsList ++ [ "@resources" ]);
SystemCallFilter = [ ("~" + lib.concatStringsSep " " systemCallsList) "@chown" "pipe" "pipe2" ];
} // cfgService;
path = with pkgs; [ file imagemagick ffmpeg ];
};
@ -563,7 +567,7 @@ in {
EnvironmentFile = "/var/lib/mastodon/.secrets_env";
WorkingDirectory = cfg.package;
# System Call Filtering
SystemCallFilter = "~" + lib.concatStringsSep " " systemCallsList;
SystemCallFilter = [ ("~" + lib.concatStringsSep " " systemCallsList) "@chown" "pipe" "pipe2" ];
} // cfgService;
path = with pkgs; [ file imagemagick ffmpeg ];
};

View File

@ -24,6 +24,7 @@ in {
(mkRemovedOptionModule [ "services" "piwik" "phpfpmProcessManagerConfig" ] "Use services.phpfpm.pools.<name>.settings")
(mkRemovedOptionModule [ "services" "matomo" "phpfpmProcessManagerConfig" ] "Use services.phpfpm.pools.<name>.settings")
(mkRenamedOptionModule [ "services" "piwik" "nginx" ] [ "services" "matomo" "nginx" ])
(mkRenamedOptionModule [ "services" "matomo" "periodicArchiveProcessingUrl" ] [ "services" "matomo" "hostname" ])
];
options = {
@ -77,7 +78,7 @@ in {
'';
};
periodicArchiveProcessingUrl = mkOption {
hostname = mkOption {
type = types.str;
default = "${user}.${fqdn}";
example = "matomo.yourdomain.org";
@ -170,6 +171,19 @@ in {
fi
chown -R ${user}:${user} ${dataDir}
chmod -R ug+rwX,o-rwx ${dataDir}
if [ -e ${dataDir}/current-package ]; then
CURRENT_PACKAGE=$(readlink ${dataDir}/current-package)
NEW_PACKAGE=${cfg.package}
if [ "$CURRENT_PACKAGE" != "$NEW_PACKAGE" ]; then
# keeping tmp arround between upgrades seems to bork stuff, so delete it
rm -rf ${dataDir}/tmp
fi
elif [ -e ${dataDir}/tmp ]; then
# upgrade from 4.4.1
rm -rf ${dataDir}/tmp
fi
ln -sfT ${cfg.package} ${dataDir}/current-package
'';
script = ''
# Use User-Private Group scheme to protect Matomo data, but allow administration / backup via 'matomo' group
@ -202,7 +216,7 @@ in {
UMask = "0007";
CPUSchedulingPolicy = "idle";
IOSchedulingClass = "idle";
ExecStart = "${cfg.package}/bin/matomo-console core:archive --url=https://${cfg.periodicArchiveProcessingUrl}";
ExecStart = "${cfg.package}/bin/matomo-console core:archive --url=https://${cfg.hostname}";
};
};
@ -258,7 +272,7 @@ in {
# References:
# https://fralef.me/piwik-hardening-with-nginx-and-php-fpm.html
# https://github.com/perusio/piwik-nginx
"${user}.${fqdn}" = mkMerge [ cfg.nginx {
"${cfg.hostname}" = mkMerge [ cfg.nginx {
# don't allow to override the root easily, as it will almost certainly break Matomo.
# disadvantage: not shown as default in docs.
root = mkForce "${cfg.package}/share";

View File

@ -0,0 +1,33 @@
{ config, lib, pkgs, ... }:
let
cfg = config.services.openwebrx;
in
{
options.services.openwebrx = with lib; {
enable = mkEnableOption "OpenWebRX Web interface for Software-Defined Radios on http://localhost:8073";
package = mkOption {
type = types.package;
default = pkgs.openwebrx;
description = "OpenWebRX package to use for the service";
};
};
config = lib.mkIf cfg.enable {
systemd.services.openwebrx = {
wantedBy = [ "multi-user.target" ];
path = with pkgs; [
csdr
alsaUtils
netcat
];
serviceConfig = {
ExecStart = "${cfg.package}/bin/openwebrx";
Restart = "always";
DynamicUser = true;
# openwebrx uses /var/lib/openwebrx by default
StateDirectory = [ "openwebrx" ];
};
};
};
}

View File

@ -5,23 +5,18 @@ with lib;
let
cfg = config.services.plausible;
# FIXME consider using LoadCredential as soon as it actually works.
envSecrets = ''
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) ''
SMTP_USER_PWD="$(<${cfg.mail.smtp.passwordFile})"
export SMTP_USER_PWD # separate export to make `set -e` work
''}
'';
in {
options.services.plausible = {
enable = mkEnableOption "plausible";
releaseCookiePath = mkOption {
default = null;
type = with types; nullOr (either str path);
description = ''
The path to the file with release cookie. (used for remote connection to the running node).
'';
};
adminUser = {
name = mkOption {
default = "admin";
@ -184,13 +179,17 @@ in {
enable = true;
};
services.epmd.enable = true;
environment.systemPackages = [ pkgs.plausible ];
systemd.services = mkMerge [
{
plausible = {
inherit (pkgs.plausible.meta) description;
documentation = [ "https://plausible.io/docs/self-hosting" ];
wantedBy = [ "multi-user.target" ];
after = optional cfg.database.postgres.setup "plausible-postgres.service";
after = optionals cfg.database.postgres.setup [ "postgresql.service" "plausible-postgres.service" ];
requires = optional cfg.database.clickhouse.setup "clickhouse.service"
++ optionals cfg.database.postgres.setup [
"postgresql.service"
@ -200,7 +199,7 @@ in {
environment = {
# NixOS specific option to avoid that it's trying to write into its store-path.
# See also https://github.com/lau/tzdata#data-directory-and-releases
TZDATA_DIR = "/var/lib/plausible/elixir_tzdata";
STORAGE_DIR = "/var/lib/plausible/elixir_tzdata";
# Configuration options from
# https://plausible.io/docs/self-hosting-configuration
@ -208,6 +207,8 @@ in {
DISABLE_REGISTRATION = boolToString cfg.server.disableRegistration;
RELEASE_TMP = "/var/lib/plausible/tmp";
# Home is needed to connect to the node with iex
HOME = "/var/lib/plausible";
ADMIN_USER_NAME = cfg.adminUser.name;
ADMIN_USER_EMAIL = cfg.adminUser.email;
@ -231,28 +232,33 @@ in {
path = [ pkgs.plausible ]
++ optional cfg.database.postgres.setup config.services.postgresql.package;
script = ''
export CONFIG_DIR=$CREDENTIALS_DIRECTORY
# setup
${pkgs.plausible}/createdb.sh
${pkgs.plausible}/migrate.sh
${optionalString cfg.adminUser.activate ''
if ! ${pkgs.plausible}/init-admin.sh | grep 'already exists'; then
psql -d plausible <<< "UPDATE users SET email_verified=true;"
fi
''}
${optionalString (cfg.releaseCookiePath != null) ''
export RELEASE_COOKIE="$(< $CREDENTIALS_DIRECTORY/RELEASE_COOKIE )"
''}
plausible start
'';
serviceConfig = {
DynamicUser = true;
PrivateTmp = true;
WorkingDirectory = "/var/lib/plausible";
StateDirectory = "plausible";
ExecStartPre = "@${pkgs.writeShellScript "plausible-setup" ''
set -eu -o pipefail
${envSecrets}
${pkgs.plausible}/createdb.sh
${pkgs.plausible}/migrate.sh
${optionalString cfg.adminUser.activate ''
if ! ${pkgs.plausible}/init-admin.sh | grep 'already exists'; then
psql -d plausible <<< "UPDATE users SET email_verified=true;"
fi
''}
''} plausible-setup";
ExecStart = "@${pkgs.writeShellScript "plausible" ''
set -eu -o pipefail
${envSecrets}
plausible start
''} plausible";
LoadCredential = [
"ADMIN_USER_PWD:${cfg.adminUser.passwordFile}"
"SECRET_KEY_BASE:${cfg.server.secretKeybaseFile}"
] ++ lib.optionals (cfg.mail.smtp.passwordFile != null) [ "SMTP_USER_PWD:${cfg.mail.smtp.passwordFile}"]
++ lib.optionals (cfg.releaseCookiePath != null) [ "RELEASE_COOKIE:${cfg.releaseCookiePath}"];
};
};
}
@ -260,20 +266,22 @@ in {
# `plausible' requires the `citext'-extension.
plausible-postgres = {
after = [ "postgresql.service" ];
bindsTo = [ "postgresql.service" ];
requiredBy = [ "plausible.service" ];
partOf = [ "plausible.service" ];
serviceConfig.Type = "oneshot";
unitConfig.ConditionPathExists = "!/var/lib/plausible/.db-setup";
script = ''
mkdir -p /var/lib/plausible/
serviceConfig = {
Type = "oneshot";
User = config.services.postgresql.superUser;
RemainAfterExit = true;
};
script = with cfg.database.postgres; ''
PSQL() {
/run/wrappers/bin/sudo -Hu postgres ${config.services.postgresql.package}/bin/psql --port=5432 "$@"
${config.services.postgresql.package}/bin/psql --port=5432 "$@"
}
PSQL -tAc "CREATE ROLE plausible WITH LOGIN;"
PSQL -tAc "CREATE DATABASE plausible WITH OWNER plausible;"
PSQL -d plausible -tAc "CREATE EXTENSION IF NOT EXISTS citext;"
touch /var/lib/plausible/.db-setup
# check if the database already exists
if ! PSQL -lqt | ${pkgs.coreutils}/bin/cut -d \| -f 1 | ${pkgs.gnugrep}/bin/grep -qw ${dbname} ; then
PSQL -tAc "CREATE ROLE plausible WITH LOGIN;"
PSQL -tAc "CREATE DATABASE ${dbname} WITH OWNER plausible;"
PSQL -d ${dbname} -tAc "CREATE EXTENSION IF NOT EXISTS citext;"
fi
'';
};
})

View File

@ -21,7 +21,8 @@ let
$DB['PORT'] = '${toString cfg.database.port}';
$DB['DATABASE'] = '${cfg.database.name}';
$DB['USER'] = '${cfg.database.user}';
$DB['PASSWORD'] = ${if cfg.database.passwordFile != null then "file_get_contents('${cfg.database.passwordFile}')" else "''"};
# NOTE: file_get_contents adds newline at the end of returned string
$DB['PASSWORD'] = ${if cfg.database.passwordFile != null then "trim(file_get_contents('${cfg.database.passwordFile}'), \"\\r\\n\")" else "''"};
// Schema name. Used for IBM DB2 and PostgreSQL.
$DB['SCHEMA'] = ''';
$ZBX_SERVER = '${cfg.server.address}';

View File

@ -61,7 +61,7 @@ in
ipAllow = mkOption {
type = types.nullOr yaml.type;
default = builtins.fromJSON (builtins.readFile ./ip_allow.json);
default = lib.importJSON ./ip_allow.json;
defaultText = literalDocBook "upstream defaults";
example = literalExpression ''
{
@ -84,7 +84,7 @@ in
logging = mkOption {
type = types.nullOr yaml.type;
default = builtins.fromJSON (builtins.readFile ./logging.json);
default = lib.importJSON ./logging.json;
defaultText = literalDocBook "upstream defaults";
example = { };
description = ''

View File

@ -71,6 +71,14 @@ in {
};
config = mkIf cfg.enable {
assertions = let
inRange = v: l: r: v >= l && v <= r;
in [
{ assertion = config.location.provider == "manual" ->
inRange config.location.latitude (-90) 90 && inRange config.location.longitude (-180) 180;
message = "You must specify a valid latitude and longitude if manually providing location"; }
];
boot.kernelModules = [ "i2c_dev" ];
environment.systemPackages = with pkgs; [ clight clightd ];
services.dbus.packages = with pkgs; [ clight clightd ];

View File

@ -189,6 +189,10 @@ in
];
services.xserver.displayManager.sessionPackages = [ pkgs.libsForQt5.plasma5.plasma-workspace ];
# Default to be `plasma` (X11) instead of `plasmawayland`, since plasma wayland currently has
# many tiny bugs.
# See: https://github.com/NixOS/nixpkgs/issues/143272
services.xserver.displayManager.defaultSession = mkDefault "plasma";
security.wrappers = {
kcheckpass = {

View File

@ -280,7 +280,7 @@ in
null;
example = "gnome";
description = ''
Graphical session to pre-select in the session chooser (only effective for GDM and LightDM).
Graphical session to pre-select in the session chooser (only effective for GDM, LightDM and SDDM).
On GDM, LightDM and SDDM, it will also be used as a session for auto-login.
'';

View File

@ -146,7 +146,7 @@ in
};
background = mkOption {
type = types.path;
type = types.either types.path (types.strMatching "^#[0-9]\{6\}$");
# Manual cannot depend on packages, we are actually setting the default in config below.
defaultText = literalExpression "pkgs.nixos-artwork.wallpapers.simple-dark-gray-bottom.gnomeFilePath";
description = ''

View File

@ -30,6 +30,9 @@ let
HaltCommand = "/run/current-system/systemd/bin/systemctl poweroff";
RebootCommand = "/run/current-system/systemd/bin/systemctl reboot";
Numlock = if cfg.autoNumlock then "on" else "none"; # on, off none
# Implementation is done via pkgs/applications/display-managers/sddm/sddm-default-session.patch
DefaultSession = optionalString (dmcfg.defaultSession != null) "${dmcfg.defaultSession}.desktop";
};
Theme = {

View File

@ -248,6 +248,7 @@ in {
description = ''
List of systems to emulate. Will also configure Nix to
support your new systems.
Warning: the builder can execute all emulated systems within the same build, which introduces impurities in the case of cross compilation.
'';
type = types.listOf types.str;
};

View File

@ -42,7 +42,7 @@ let
"systemd-udevd-kernel.socket"
"systemd-udevd.service"
"systemd-udev-settle.service"
"systemd-udev-trigger.service"
] ++ (optional (!config.boot.isContainer) "systemd-udev-trigger.service") ++ [
# hwdb.bin is managed by NixOS
# "systemd-hwdb-update.service"

View File

@ -138,3 +138,9 @@ foreach my $fn (@oldCopied) {
# Rewrite /etc/.clean.
close CLEAN;
write_file("/etc/.clean", map { "$_\n" } @copied);
# Create /etc/NIXOS tag if not exists.
# When /etc is not on a persistent filesystem, it will be wiped after reboot,
# so we need to check and re-create it during activation.
open TAG, ">>/etc/NIXOS";
close TAG;

View File

@ -561,7 +561,8 @@ in
then cfgZfs.requestEncryptionCredentials
else cfgZfs.requestEncryptionCredentials != []) ''
${cfgZfs.package}/sbin/zfs list -rHo name,keylocation ${pool} | while IFS=$'\t' read ds kl; do
(${optionalString (!isBool cfgZfs.requestEncryptionCredentials) ''
{
${optionalString (!isBool cfgZfs.requestEncryptionCredentials) ''
if ! echo '${concatStringsSep "\n" cfgZfs.requestEncryptionCredentials}' | grep -qFx "$ds"; then
continue
fi
@ -575,7 +576,8 @@ in
* )
${cfgZfs.package}/sbin/zfs load-key "$ds"
;;
esac) < /dev/null # To protect while read ds kl in case anything reads stdin
esac
} < /dev/null # To protect while read ds kl in case anything reads stdin
done
''}
echo "Successfully imported ${pool}"

View File

@ -254,7 +254,7 @@ in
"allow ${e}")
cfg.allowedBridges;
systemPackages = with pkgs; [ libressl.nc iptables cfg.package cfg.qemu.package ];
etc.ethertypes.source = "${pkgs.ebtables}/etc/ethertypes";
etc.ethertypes.source = "${pkgs.iptables}/etc/ethertypes";
};
boot.kernelModules = [ "tun" ];

View File

@ -1,26 +1,174 @@
{ lib, ... }:
{ lib, config, pkgs, ... }:
with lib;
let
templateSubmodule = { ... }: {
options = {
enable = mkEnableOption "this template";
target = mkOption {
description = "Path in the container";
type = types.path;
};
template = mkOption {
description = ".tpl file for rendering the target";
type = types.path;
};
when = mkOption {
description = "Events which trigger a rewrite (create, copy)";
type = types.listOf (types.str);
};
properties = mkOption {
description = "Additional properties";
type = types.attrs;
default = {};
};
};
};
toYAML = name: data: pkgs.writeText name (generators.toYAML {} data);
cfg = config.virtualisation.lxc;
templates = if cfg.templates != {} then let
list = mapAttrsToList (name: value: { inherit name; } // value)
(filterAttrs (name: value: value.enable) cfg.templates);
in
{
files = map (tpl: {
source = tpl.template;
target = "/templates/${tpl.name}.tpl";
}) list;
properties = listToAttrs (map (tpl: nameValuePair tpl.target {
when = tpl.when;
template = "${tpl.name}.tpl";
properties = tpl.properties;
}) list);
}
else { files = []; properties = {}; };
in
{
imports = [
../profiles/docker-container.nix # FIXME, shouldn't include something from profiles/
../installer/cd-dvd/channel.nix
../profiles/minimal.nix
../profiles/clone-config.nix
];
# Allow the user to login as root without password.
users.users.root.initialHashedPassword = mkOverride 150 "";
options = {
virtualisation.lxc = {
templates = mkOption {
description = "Templates for LXD";
type = types.attrsOf (types.submodule (templateSubmodule));
default = {};
example = literalExpression ''
{
# create /etc/hostname on container creation
"hostname" = {
enable = true;
target = "/etc/hostname";
template = builtins.writeFile "hostname.tpl" "{{ container.name }}";
when = [ "create" ];
};
# create /etc/nixos/hostname.nix with a configuration for keeping the hostname applied
"hostname-nix" = {
enable = true;
target = "/etc/nixos/hostname.nix";
template = builtins.writeFile "hostname-nix.tpl" "{ ... }: { networking.hostName = "{{ container.name }}"; }";
# copy keeps the file updated when the container is changed
when = [ "create" "copy" ];
};
# copy allow the user to specify a custom configuration.nix
"configuration-nix" = {
enable = true;
target = "/etc/nixos/configuration.nix";
template = builtins.writeFile "configuration-nix" "{{ config_get(\"user.user-data\", properties.default) }}";
when = [ "create" ];
};
};
'';
};
};
};
# Some more help text.
services.getty.helpLine =
''
config = {
boot.isContainer = true;
boot.postBootCommands =
''
# After booting, register the contents of the Nix store in the Nix
# database.
if [ -f /nix-path-registration ]; then
${config.nix.package.out}/bin/nix-store --load-db < /nix-path-registration &&
rm /nix-path-registration
fi
Log in as "root" with an empty password.
# nixos-rebuild also requires a "system" profile
${config.nix.package.out}/bin/nix-env -p /nix/var/nix/profiles/system --set /run/current-system
'';
system.build.metadata = pkgs.callPackage ../../lib/make-system-tarball.nix {
contents = [
{
source = toYAML "metadata.yaml" {
architecture = builtins.elemAt (builtins.match "^([a-z0-9_]+).+" (toString pkgs.system)) 0;
creation_date = 1;
properties = {
description = "NixOS ${config.system.nixos.codeName} ${config.system.nixos.label} ${pkgs.system}";
os = "nixos";
release = "${config.system.nixos.codeName}";
};
templates = templates.properties;
};
target = "/metadata.yaml";
}
] ++ templates.files;
};
# TODO: build rootfs as squashfs for faster unpack
system.build.tarball = pkgs.callPackage ../../lib/make-system-tarball.nix {
extraArgs = "--owner=0";
storeContents = [
{
object = config.system.build.toplevel;
symlink = "none";
}
];
contents = [
{
source = config.system.build.toplevel + "/init";
target = "/sbin/init";
}
];
extraCommands = "mkdir -p proc sys dev";
};
# Add the overrides from lxd distrobuilder
systemd.extraConfig = ''
[Service]
ProtectProc=default
ProtectControlGroups=no
ProtectKernelTunables=no
'';
# Containers should be light-weight, so start sshd on demand.
services.openssh.enable = mkDefault true;
services.openssh.startWhenNeeded = mkDefault true;
# Allow the user to login as root without password.
users.users.root.initialHashedPassword = mkOverride 150 "";
# Allow ssh connections
networking.firewall.allowedTCPPorts = [ 22 ];
system.activationScripts.installInitScript = mkForce ''
ln -fs $systemConfig/init /sbin/init
'';
# Some more help text.
services.getty.helpLine =
''
Log in as "root" with an empty password.
'';
# Containers should be light-weight, so start sshd on demand.
services.openssh.enable = mkDefault true;
services.openssh.startWhenNeeded = mkDefault true;
};
}

View File

@ -34,7 +34,7 @@ in {
package = mkOption {
type = types.package;
default = pkgs.lxd.override { nftablesSupport = config.networking.nftables.enable; };
default = pkgs.lxd;
defaultText = literalExpression "pkgs.lxd";
description = ''
The LXD package to use.

View File

@ -0,0 +1,169 @@
{ config, pkgs, lib, ... }:
with lib;
{
options.proxmox = {
qemuConf = {
# essential configs
boot = mkOption {
type = types.str;
default = "";
example = "order=scsi0;net0";
description = ''
Default boot device. PVE will try all devices in its default order if this value is empty.
'';
};
scsihw = mkOption {
type = types.str;
default = "virtio-scsi-pci";
example = "lsi";
description = ''
SCSI controller type. Must be one of the supported values given in
<link xlink:href="https://pve.proxmox.com/wiki/Qemu/KVM_Virtual_Machines"/>
'';
};
virtio0 = mkOption {
type = types.str;
default = "local-lvm:vm-9999-disk-0";
example = "ceph:vm-123-disk-0";
description = ''
Configuration for the default virtio disk. It can be used as a cue for PVE to autodetect the target sotrage.
This parameter is required by PVE even if it isn't used.
'';
};
ostype = mkOption {
type = types.str;
default = "l26";
description = ''
Guest OS type
'';
};
cores = mkOption {
type = types.ints.positive;
default = 1;
description = ''
Guest core count
'';
};
memory = mkOption {
type = types.ints.positive;
default = 1024;
description = ''
Guest memory in MB
'';
};
# optional configs
name = mkOption {
type = types.str;
default = "nixos-${config.system.nixos.label}";
description = ''
VM name
'';
};
net0 = mkOption {
type = types.commas;
default = "virtio=00:00:00:00:00:00,bridge=vmbr0,firewall=1";
description = ''
Configuration for the default interface. When restoring from VMA, check the
"unique" box to ensure device mac is randomized.
'';
};
serial0 = mkOption {
type = types.str;
default = "socket";
example = "/dev/ttyS0";
description = ''
Create a serial device inside the VM (n is 0 to 3), and pass through a host serial device (i.e. /dev/ttyS0),
or create a unix socket on the host side (use qm terminal to open a terminal connection).
'';
};
agent = mkOption {
type = types.bool;
apply = x: if x then "1" else "0";
default = true;
description = ''
Expect guest to have qemu agent running
'';
};
};
qemuExtraConf = mkOption {
type = with types; attrsOf (oneOf [ str int ]);
default = {};
example = literalExpression ''{
cpu = "host";
onboot = 1;
}'';
description = ''
Additional options appended to qemu-server.conf
'';
};
filenameSuffix = mkOption {
type = types.str;
default = config.proxmox.qemuConf.name;
example = "999-nixos_template";
description = ''
Filename of the image will be vzdump-qemu-''${filenameSuffix}.vma.zstd.
This will also determine the default name of the VM on restoring the VMA.
Start this value with a number if you want the VMA to be detected as a backup of
any specific VMID.
'';
};
};
config = let
cfg = config.proxmox;
cfgLine = name: value: ''
${name}: ${builtins.toString value}
'';
cfgFile = fileName: properties: pkgs.writeTextDir fileName ''
# generated by NixOS
${lib.concatStrings (lib.mapAttrsToList cfgLine properties)}
#qmdump#map:virtio0:drive-virtio0:local-lvm:raw:
'';
in {
system.build.VMA = import ../../lib/make-disk-image.nix {
name = "proxmox-${cfg.filenameSuffix}";
postVM = let
# Build qemu with PVE's patch that adds support for the VMA format
vma = pkgs.qemu_kvm.overrideAttrs ( super: {
patches = let
rev = "cc707c362ea5c8d832aac270d1ffa7ac66a8908f";
path = "debian/patches/pve/0025-PVE-Backup-add-vma-backup-format-code.patch";
vma-patch = pkgs.fetchpatch {
url = "https://git.proxmox.com/?p=pve-qemu.git;a=blob_plain;hb=${rev};f=${path}";
sha256 = "1z467xnmfmry3pjy7p34psd5xdil9x0apnbvfz8qbj0bf9fgc8zf";
};
in super.patches ++ [ vma-patch ];
buildInputs = super.buildInputs ++ [ pkgs.libuuid ];
});
in
''
${vma}/bin/vma create "vzdump-qemu-${cfg.filenameSuffix}.vma" \
-c ${cfgFile "qemu-server.conf" (cfg.qemuConf // cfg.qemuExtraConf)}/qemu-server.conf drive-virtio0=$diskImage
rm $diskImage
${pkgs.zstd}/bin/zstd "vzdump-qemu-${cfg.filenameSuffix}.vma"
mv "vzdump-qemu-${cfg.filenameSuffix}.vma.zst" $out/
'';
format = "raw";
inherit config lib pkgs;
};
boot = {
growPartition = true;
kernelParams = [ "console=ttyS0" ];
loader.grub.device = lib.mkDefault "/dev/vda";
loader.timeout = 0;
initrd.availableKernelModules = [ "uas" "virtio_blk" "virtio_pci" ];
};
fileSystems."/" = {
device = "/dev/disk/by-label/nixos";
autoResize = true;
fsType = "ext4";
};
services.qemuGuest.enable = lib.mkDefault true;
};
}

View File

@ -318,7 +318,7 @@ in
virtualisation.diskSize =
mkOption {
type = types.nullOr types.ints.positive;
default = 512;
default = 1024;
description =
''
The disk size in megabytes of the virtual machine.

View File

@ -6,7 +6,7 @@ let
cfg = config.virtualisation.virtualbox.host;
virtualbox = cfg.package.override {
inherit (cfg) enableHardening headless;
inherit (cfg) enableHardening headless enableWebService;
extensionPack = if cfg.enableExtensionPack then pkgs.virtualboxExtpack else null;
};
@ -80,6 +80,14 @@ in
and when virtual machines are controlled only via SSH.
'';
};
enableWebService = mkOption {
type = types.bool;
default = false;
description = ''
Build VirtualBox web service tool (vboxwebsrv) to allow managing VMs via other webpage frontend tools. Useful for headless servers.
'';
};
};
config = mkIf cfg.enable (mkMerge [{

View File

@ -38,7 +38,7 @@ in
};
# Mount the vmblock for drag-and-drop and copy-and-paste.
systemd.mounts = [
systemd.mounts = mkIf (!cfg.headless) [
{
description = "VMware vmblock fuse mount";
documentation = [ "https://github.com/vmware/open-vm-tools/blob/master/open-vm-tools/vmblock-fuse/design.txt" ];
@ -52,8 +52,8 @@ in
}
];
security.wrappers.vmware-user-suid-wrapper =
{ setuid = true;
security.wrappers.vmware-user-suid-wrapper = mkIf (!cfg.headless) {
setuid = true;
owner = "root";
group = "root";
source = "${open-vm-tools}/bin/vmware-user-suid-wrapper";

View File

@ -0,0 +1,66 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.virtualisation.waydroid;
kernelPackages = config.boot.kernelPackages;
waydroidGbinderConf = pkgs.writeText "waydroid.conf" ''
[Protocol]
/dev/binder = aidl2
/dev/vndbinder = aidl2
/dev/hwbinder = hidl
[ServiceManager]
/dev/binder = aidl2
/dev/vndbinder = aidl2
/dev/hwbinder = hidl
'';
in {
options.virtualisation.waydroid = {
enable = mkEnableOption "Waydroid";
};
config = mkIf cfg.enable {
assertions = singleton {
assertion = versionAtLeast (getVersion config.boot.kernelPackages.kernel) "4.18";
message = "Waydroid needs user namespace support to work properly";
};
system.requiredKernelConfig = with config.lib.kernelConfig; [
(isEnabled "ANDROID_BINDER_IPC")
(isEnabled "ANDROID_BINDERFS")
(isEnabled "ASHMEM")
];
environment.etc."gbinder.d/waydroid.conf".source = waydroidGbinderConf;
environment.systemPackages = with pkgs; [ waydroid ];
networking.firewall.trustedInterfaces = [ "waydroid0" ];
virtualisation.lxc.enable = true;
systemd.services.waydroid-container = {
description = "Waydroid Container";
wantedBy = [ "multi-user.target" ];
path = with pkgs; [ getent iptables iproute kmod nftables util-linux which ];
unitConfig = {
ConditionPathExists = "/var/lib/waydroid/lxc/waydroid";
};
serviceConfig = {
ExecStart = "${pkgs.waydroid}/bin/waydroid container start";
ExecStop = "${pkgs.waydroid}/bin/waydroid container stop";
ExecStopPost = "${pkgs.waydroid}/bin/waydroid session stop";
};
};
};
}

View File

@ -251,6 +251,37 @@ in rec {
);
# An image that can be imported into lxd and used for container creation
lxdImage = forMatchingSystems [ "x86_64-linux" "aarch64-linux" ] (system:
with import ./.. { inherit system; };
hydraJob ((import lib/eval-config.nix {
inherit system;
modules =
[ configuration
versionModule
./maintainers/scripts/lxd/lxd-image.nix
];
}).config.system.build.tarball)
);
# Metadata for the lxd image
lxdMeta = forMatchingSystems [ "x86_64-linux" "aarch64-linux" ] (system:
with import ./.. { inherit system; };
hydraJob ((import lib/eval-config.nix {
inherit system;
modules =
[ configuration
versionModule
./maintainers/scripts/lxd/lxd-image.nix
];
}).config.system.build.metadata)
);
# Ensure that all packages used by the minimal NixOS config end up in the channel.
dummy = forAllSystems (system: pkgs.runCommand "dummy"

View File

@ -33,7 +33,7 @@ in
avahi-with-resolved = handleTest ./avahi.nix { networkd = true; };
babeld = handleTest ./babeld.nix {};
bazarr = handleTest ./bazarr.nix {};
bcachefs = handleTestOn ["x86_64-linux"] ./bcachefs.nix {}; # linux-4.18.2018.10.12 is unsupported on aarch64
bcachefs = handleTestOn ["x86_64-linux" "aarch64-linux"] ./bcachefs.nix {};
beanstalkd = handleTest ./beanstalkd.nix {};
bees = handleTest ./bees.nix {};
bind = handleTest ./bind.nix {};
@ -109,6 +109,7 @@ in
docker-tools-overlay = handleTestOn ["x86_64-linux"] ./docker-tools-overlay.nix {};
documize = handleTest ./documize.nix {};
dokuwiki = handleTest ./dokuwiki.nix {};
domination = handleTest ./domination.nix {};
dovecot = handleTest ./dovecot.nix {};
ec2-config = (handleTestOn ["x86_64-linux"] ./ec2.nix {}).boot-ec2-config or {};
ec2-nixops = (handleTestOn ["x86_64-linux"] ./ec2.nix {}).boot-ec2-nixops or {};
@ -236,7 +237,9 @@ in
login = handleTest ./login.nix {};
loki = handleTest ./loki.nix {};
lxd = handleTest ./lxd.nix {};
lxd-image = handleTest ./lxd-image.nix {};
lxd-nftables = handleTest ./lxd-nftables.nix {};
lxd-image-server = handleTest ./lxd-image-server.nix {};
#logstash = handleTest ./logstash.nix {};
lorri = handleTest ./lorri/default.nix {};
magic-wormhole-mailbox-server = handleTest ./magic-wormhole-mailbox-server.nix {};
@ -258,6 +261,7 @@ in
miniflux = handleTest ./miniflux.nix {};
minio = handleTest ./minio.nix {};
misc = handleTest ./misc.nix {};
mjolnir = handleTest ./matrix/mjolnir.nix {};
mod_perl = handleTest ./mod_perl.nix {};
moinmoin = handleTest ./moinmoin.nix {};
mongodb = handleTest ./mongodb.nix {};
@ -338,6 +342,7 @@ in
packagekit = handleTest ./packagekit.nix {};
pam-oath-login = handleTest ./pam-oath-login.nix {};
pam-u2f = handleTest ./pam-u2f.nix {};
pantalaimon = handleTest ./matrix/pantalaimon.nix {};
pantheon = handleTest ./pantheon.nix {};
paperless-ng = handleTest ./paperless-ng.nix {};
parsedmarc = handleTest ./parsedmarc {};
@ -401,6 +406,7 @@ in
samba-wsdd = handleTest ./samba-wsdd.nix {};
sanoid = handleTest ./sanoid.nix {};
sddm = handleTest ./sddm.nix {};
seafile = handleTest ./seafile.nix {};
searx = handleTest ./searx.nix {};
service-runner = handleTest ./service-runner.nix {};
shadow = handleTest ./shadow.nix {};

View File

@ -36,7 +36,7 @@ let
machine = create_machine(${machineConfig})
machine.start()
machine.wait_for_unit("multi-user.target")
machine.succeed("nix verify -r --no-trust /run/current-system")
machine.succeed("nix store verify --no-trust -r --option experimental-features nix-command /run/current-system")
with subtest("Check whether the channel got installed correctly"):
machine.succeed("nix-instantiate --dry-run '<nixpkgs>' -A hello")

View File

@ -86,7 +86,7 @@ mapAttrs (channel: chromiumPkg: makeTest rec {
options.append("--use-gl=swiftshader")
# Launch the process:
options.append("file://${startupHTML}")
machine.succeed(ru(f'ulimit -c unlimited; {binary} {shlex.join(options)} & disown'))
machine.succeed(ru(f'ulimit -c unlimited; {binary} {shlex.join(options)} >&2 & disown'))
if binary.startswith("google-chrome"):
# Need to click away the first window:
machine.wait_for_text("Make Google Chrome the default browser")
@ -215,7 +215,7 @@ mapAttrs (channel: chromiumPkg: makeTest rec {
clipboard = machine.succeed(
ru(
"echo void | ${pkgs.xclip}/bin/xclip -i"
"echo void | ${pkgs.xclip}/bin/xclip -i >&2"
)
)
machine.succeed(

View File

@ -119,7 +119,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: {
with subtest("Stop a container early"):
machine.succeed(f"nixos-container stop {id1}")
machine.succeed(f"nixos-container start {id1} &")
machine.succeed(f"nixos-container start {id1} >&2 &")
machine.wait_for_console_text("Stage 2")
machine.succeed(f"nixos-container stop {id1}")
machine.wait_for_console_text(f"Container {id1} exited successfully")

View File

@ -38,7 +38,7 @@ in {
sender.execute("echo Hello World > testfile01.txt")
sender.execute("echo Hello Earth > testfile02.txt")
sender.execute(
"croc --pass ${pass} --relay relay send --code topSecret testfile01.txt testfile02.txt &"
"croc --pass ${pass} --relay relay send --code topSecret testfile01.txt testfile02.txt >&2 &"
)
# receive the testfiles and check them

View File

@ -5,7 +5,7 @@ import ./make-test-python.nix ({ pkgs, ...} : {
};
nodes = {
simple2 = {
simple = {
services.deluge = {
enable = true;
package = pkgs.deluge-2_x;
@ -16,7 +16,7 @@ import ./make-test-python.nix ({ pkgs, ...} : {
};
};
declarative2 = {
declarative = {
services.deluge = {
enable = true;
package = pkgs.deluge-2_x;
@ -45,27 +45,16 @@ import ./make-test-python.nix ({ pkgs, ...} : {
testScript = ''
start_all()
simple1.wait_for_unit("deluged")
simple2.wait_for_unit("deluged")
simple1.wait_for_unit("delugeweb")
simple2.wait_for_unit("delugeweb")
simple1.wait_for_open_port("8112")
simple2.wait_for_open_port("8112")
declarative1.wait_for_unit("network.target")
declarative2.wait_for_unit("network.target")
declarative1.wait_until_succeeds("curl --fail http://simple1:8112")
declarative2.wait_until_succeeds("curl --fail http://simple2:8112")
simple.wait_for_unit("deluged")
simple.wait_for_unit("delugeweb")
simple.wait_for_open_port("8112")
declarative.wait_for_unit("network.target")
declarative.wait_until_succeeds("curl --fail http://simple:8112")
declarative1.wait_for_unit("deluged")
declarative2.wait_for_unit("deluged")
declarative1.wait_for_unit("delugeweb")
declarative2.wait_for_unit("delugeweb")
declarative1.wait_until_succeeds("curl --fail http://declarative1:3142")
declarative2.wait_until_succeeds("curl --fail http://declarative2:3142")
declarative1.succeed(
"deluge-console 'connect 127.0.0.1:58846 andrew password; help' | grep -q 'rm.*Remove a torrent'"
)
declarative2.succeed(
declarative.wait_for_unit("deluged")
declarative.wait_for_unit("delugeweb")
declarative.wait_until_succeeds("curl --fail http://declarative:3142")
declarative.succeed(
"deluge-console 'connect 127.0.0.1:58846 andrew password; help' | grep -q 'rm.*Remove a torrent'"
)
'';

View File

@ -85,6 +85,14 @@ import ./make-test-python.nix (
# ../../pkgs/tools/security/doas/0001-add-NixOS-specific-dirs-to-safe-PATH.patch
with subtest("recursive calls to doas from subprocesses should succeed"):
machine.succeed('doas -u test0 sh -c "doas -u test0 true"')
with subtest("test0 should inherit TERMINFO_DIRS from the user environment"):
dirs = machine.succeed(
"su - test0 -c 'doas -u root $SHELL -c \"echo \$TERMINFO_DIRS\"'"
)
if not "test0" in dirs:
raise Exception(f"user profile TERMINFO_DIRS is not preserved: {dirs}")
'';
}
)

View File

@ -0,0 +1,26 @@
import ./make-test-python.nix ({ pkgs, ... }: {
name = "domination";
meta = with pkgs.lib.maintainers; {
maintainers = [ fgaz ];
};
machine = { config, pkgs, ... }: {
imports = [
./common/x11.nix
];
services.xserver.enable = true;
environment.systemPackages = [ pkgs.domination ];
};
enableOCR = true;
testScript =
''
machine.wait_for_x()
machine.execute("domination >&2 &")
machine.wait_for_window("Menu")
machine.wait_for_text("New Game")
machine.screenshot("screen")
'';
})

View File

@ -1,12 +1,15 @@
# To run the test on the unfree ELK use the folllowing command:
# cd path/to/nixpkgs
# NIXPKGS_ALLOW_UNFREE=1 nix-build -A nixosTests.elk.unfree.ELK-6
{ system ? builtins.currentSystem,
config ? {},
pkgs ? import ../.. { inherit system config; },
enableUnfree ? false
# To run the test on the unfree ELK use the folllowing command:
# NIXPKGS_ALLOW_UNFREE=1 nix-build nixos/tests/elk.nix -A ELK-6 --arg enableUnfree true
}:
let
inherit (pkgs) lib;
esUrl = "http://localhost:9200";
mkElkTest = name : elk :
@ -215,38 +218,40 @@ let
'! curl --silent --show-error "${esUrl}/_cat/indices" | grep logstash | grep ^'
)
'';
}) {};
in pkgs.lib.mapAttrs mkElkTest {
ELK-6 =
if enableUnfree
then {
}) { inherit pkgs system; };
in {
ELK-6 = mkElkTest "elk-6-oss" {
name = "elk-6-oss";
elasticsearch = pkgs.elasticsearch6-oss;
logstash = pkgs.logstash6-oss;
kibana = pkgs.kibana6-oss;
journalbeat = pkgs.journalbeat6;
metricbeat = pkgs.metricbeat6;
};
# We currently only package upstream binaries.
# Feel free to package an SSPL licensed source-based package!
# ELK-7 = mkElkTest "elk-7-oss" {
# name = "elk-7";
# elasticsearch = pkgs.elasticsearch7-oss;
# logstash = pkgs.logstash7-oss;
# kibana = pkgs.kibana7-oss;
# journalbeat = pkgs.journalbeat7;
# metricbeat = pkgs.metricbeat7;
# };
unfree = lib.dontRecurseIntoAttrs {
ELK-6 = mkElkTest "elk-6" {
elasticsearch = pkgs.elasticsearch6;
logstash = pkgs.logstash6;
kibana = pkgs.kibana6;
journalbeat = pkgs.journalbeat6;
metricbeat = pkgs.metricbeat6;
}
else {
elasticsearch = pkgs.elasticsearch6-oss;
logstash = pkgs.logstash6-oss;
kibana = pkgs.kibana6-oss;
journalbeat = pkgs.journalbeat6;
metricbeat = pkgs.metricbeat6;
};
ELK-7 =
if enableUnfree
then {
ELK-7 = mkElkTest "elk-7" {
elasticsearch = pkgs.elasticsearch7;
logstash = pkgs.logstash7;
kibana = pkgs.kibana7;
journalbeat = pkgs.journalbeat7;
metricbeat = pkgs.metricbeat7;
}
else {
elasticsearch = pkgs.elasticsearch7-oss;
logstash = pkgs.logstash7-oss;
kibana = pkgs.kibana7-oss;
journalbeat = pkgs.journalbeat7;
metricbeat = pkgs.metricbeat7;
};
};
}

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