mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-02-19 18:44:13 +00:00
Merge branch 'master' into xps-9310-kernel-config
This commit is contained in:
commit
13dc25bd67
10
.github/PULL_REQUEST_TEMPLATE.md
vendored
10
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -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
|
||||
|
2
.github/workflows/basic-eval.yml
vendored
2
.github/workflows/basic-eval.yml
vendored
@ -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" ]'
|
||||
|
2
.github/workflows/editorconfig.yml
vendored
2
.github/workflows/editorconfig.yml
vendored
@ -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
|
||||
|
2
.github/workflows/manual-nixos.yml
vendored
2
.github/workflows/manual-nixos.yml
vendored
@ -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
|
||||
|
2
.github/workflows/manual-nixpkgs.yml
vendored
2
.github/workflows/manual-nixpkgs.yml
vendored
@ -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
|
||||
|
2
.github/workflows/nixos-manual.yml
vendored
2
.github/workflows/nixos-manual.yml
vendored
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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 { };
|
||||
|
@ -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/).
|
||||
|
@ -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.
|
||||
|
@ -258,6 +258,12 @@ rec {
|
||||
platform = {};
|
||||
};
|
||||
|
||||
x86_64-darwin = {
|
||||
config = "x86_64-apple-darwin";
|
||||
xcodePlatform = "MacOSX";
|
||||
platform = {};
|
||||
};
|
||||
|
||||
#
|
||||
# Windows
|
||||
#
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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";
|
||||
|
@ -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 []
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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>>&2</literal>,
|
||||
to <literal>/dev/console</literal>,
|
||||
<literal>/dev/null</literal> or a file. Examples of detaching
|
||||
commands are <literal>sleep 365d &</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>
|
||||
|
@ -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("foo &")</literal> and
|
||||
<literal>succeed("foo | xclip -i")</literal> to
|
||||
close stdout. This can be done with a redirect such as
|
||||
<literal>succeed("foo >&2 &")</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.<name>.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>
|
||||
|
@ -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`.
|
||||
|
@ -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
|
||||
|
@ -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'
|
||||
)
|
||||
|
102
nixos/maintainers/scripts/lxd/lxd-image-inner.nix
Normal file
102
nixos/maintainers/scripts/lxd/lxd-image-inner.nix
Normal 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. It‘s 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;
|
||||
}
|
34
nixos/maintainers/scripts/lxd/lxd-image.nix
Normal file
34
nixos/maintainers/scripts/lxd/lxd-image.nix
Normal 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;
|
||||
}
|
9
nixos/maintainers/scripts/lxd/nix.tpl
Normal file
9
nixos/maintainers/scripts/lxd/nix.tpl
Normal file
@ -0,0 +1,9 @@
|
||||
{ lib, config, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
# WARNING: THIS CONFIGURATION IS AUTOGENERATED AND WILL BE OVERWRITTEN AUTOMATICALLY
|
||||
|
||||
{
|
||||
networking.hostName = "{{ container.name }}";
|
||||
}
|
@ -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}
|
||||
''}
|
||||
'';
|
||||
|
@ -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;
|
||||
|
@ -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";
|
||||
}
|
||||
|
@ -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
|
||||
]
|
||||
|
@ -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 "") + ''
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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/
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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;
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
|
@ -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 = [
|
||||
|
@ -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" ];
|
||||
|
@ -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 = {
|
||||
|
@ -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 = {
|
||||
|
@ -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"/>
|
||||
'';
|
||||
};
|
||||
|
||||
|
@ -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";
|
||||
|
240
nixos/modules/services/matrix/mjolnir.nix
Normal file
240
nixos/modules/services/matrix/mjolnir.nix
Normal 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 ];
|
||||
};
|
||||
}
|
134
nixos/modules/services/matrix/mjolnir.xml
Normal file
134
nixos/modules/services/matrix/mjolnir.xml
Normal 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>
|
70
nixos/modules/services/matrix/pantalaimon-options.nix
Normal file
70
nixos/modules/services/matrix/pantalaimon-options.nix
Normal 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.
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
70
nixos/modules/services/matrix/pantalaimon.nix
Normal file
70
nixos/modules/services/matrix/pantalaimon.nix
Normal 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 ];
|
||||
};
|
||||
}
|
107
nixos/modules/services/misc/ananicy.nix
Normal file
107
nixos/modules/services/misc/ananicy.nix
Normal 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 ];
|
||||
};
|
||||
}
|
71
nixos/modules/services/misc/xmrig.nix
Normal file
71
nixos/modules/services/misc/xmrig.nix
Normal 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 ];
|
||||
};
|
||||
}
|
@ -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
@ -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 {
|
||||
|
80
nixos/modules/services/networking/antennas.nix
Normal file
80
nixos/modules/services/networking/antennas.nix
Normal 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;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
@ -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 = {
|
||||
|
138
nixos/modules/services/networking/lxd-image-server.nix
Normal file
138
nixos/modules/services/networking/lxd-image-server.nix
Normal 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";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
102
nixos/modules/services/networking/mosquitto.md
Normal file
102
nixos/modules/services/networking/mosquitto.md
Normal 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.
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
147
nixos/modules/services/networking/mosquitto.xml
Normal file
147
nixos/modules/services/networking/mosquitto.xml
Normal 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 = [ "pattern readwrite #" ];
|
||||
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 = [ "read #" ];
|
||||
password = "monitor";
|
||||
};
|
||||
service = {
|
||||
acl = [ "write service/#" ];
|
||||
password = "service";
|
||||
};
|
||||
};
|
||||
} ];
|
||||
};
|
||||
</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 = "/path/to/mqtt.ca.pem";
|
||||
certfile = "/path/to/mqtt.pem";
|
||||
keyfile = "/path/to/mqtt.key";
|
||||
};
|
||||
} ];
|
||||
</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 = [ "pattern readwrite #" ]</literal>
|
||||
in the listener.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
</chapter>
|
@ -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.
|
||||
'';
|
||||
};
|
||||
|
||||
|
@ -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 ];
|
||||
}
|
||||
|
@ -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" ];
|
||||
|
@ -33,7 +33,7 @@ let
|
||||
fi
|
||||
'';
|
||||
|
||||
streamingConfig = builtins.fromJSON (builtins.readFile ./streaming.json);
|
||||
streamingConfig = lib.importJSON ./streaming.json;
|
||||
logConfig = {
|
||||
appenders.stdout.type = "stdout";
|
||||
categories = {
|
||||
|
139
nixos/modules/services/web-apps/code-server.nix
Normal file
139
nixos/modules/services/web-apps/code-server.nix
Normal 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 ];
|
||||
}
|
@ -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 [
|
||||
|
@ -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 ];
|
||||
};
|
||||
|
@ -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";
|
||||
|
33
nixos/modules/services/web-apps/openwebrx.nix
Normal file
33
nixos/modules/services/web-apps/openwebrx.nix
Normal 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" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
@ -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
|
||||
'';
|
||||
};
|
||||
})
|
||||
|
@ -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}';
|
||||
|
@ -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 = ''
|
||||
|
@ -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 ];
|
||||
|
@ -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 = {
|
||||
|
@ -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.
|
||||
'';
|
||||
|
@ -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 = ''
|
||||
|
@ -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 = {
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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}"
|
||||
|
@ -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" ];
|
||||
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
@ -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.
|
||||
|
169
nixos/modules/virtualisation/proxmox-image.nix
Normal file
169
nixos/modules/virtualisation/proxmox-image.nix
Normal 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;
|
||||
};
|
||||
}
|
@ -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.
|
||||
|
@ -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 [{
|
||||
|
@ -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";
|
||||
|
66
nixos/modules/virtualisation/waydroid.nix
Normal file
66
nixos/modules/virtualisation/waydroid.nix
Normal 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";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
}
|
@ -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"
|
||||
|
@ -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 {};
|
||||
|
@ -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")
|
||||
|
@ -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(
|
||||
|
@ -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")
|
||||
|
@ -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
|
||||
|
@ -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'"
|
||||
)
|
||||
'';
|
||||
|
@ -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}")
|
||||
'';
|
||||
}
|
||||
)
|
||||
|
26
nixos/tests/domination.nix
Normal file
26
nixos/tests/domination.nix
Normal 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")
|
||||
'';
|
||||
})
|
@ -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
Loading…
Reference in New Issue
Block a user