Project import generated by Copybara.
GitOrigin-RevId: 18036c0be90f4e308ae3ebcab0e14aae0336fe42
This commit is contained in:
parent
670ffb4186
commit
5e9e1146e1
3799 changed files with 97519 additions and 123476 deletions
13
third_party/nixpkgs/.github/CODEOWNERS
vendored
13
third_party/nixpkgs/.github/CODEOWNERS
vendored
|
@ -196,6 +196,11 @@ pkgs/development/python-modules/buildcatrust/ @ajs124 @lukegb @mweinelt
|
|||
/nixos/tests/kea.nix @mweinelt
|
||||
/nixos/tests/knot.nix @mweinelt
|
||||
|
||||
# Web servers
|
||||
/doc/builders/packages/nginx.section.md @raitobezarius
|
||||
/pkgs/servers/http/nginx/ @raitobezarius
|
||||
/nixos/modules/services/web-servers/nginx/ @raitobezarius
|
||||
|
||||
# Dhall
|
||||
/pkgs/development/dhall-modules @Gabriella439 @Profpatsch @ehmry
|
||||
/pkgs/development/interpreters/dhall @Gabriella439 @Profpatsch @ehmry
|
||||
|
@ -226,11 +231,6 @@ pkgs/development/python-modules/buildcatrust/ @ajs124 @lukegb @mweinelt
|
|||
# VsCode Extensions
|
||||
/pkgs/applications/editors/vscode/extensions @jonringer
|
||||
|
||||
# Prometheus exporter modules and tests
|
||||
/nixos/modules/services/monitoring/prometheus/exporters.nix @WilliButz
|
||||
/nixos/modules/services/monitoring/prometheus/exporters.xml @WilliButz
|
||||
/nixos/tests/prometheus-exporters.nix @WilliButz
|
||||
|
||||
# PHP interpreter, packages, extensions, tests and documentation
|
||||
/doc/languages-frameworks/php.section.md @aanderse @drupol @etu @globin @ma27 @talyz
|
||||
/nixos/tests/php @aanderse @drupol @etu @globin @ma27 @talyz
|
||||
|
@ -308,3 +308,6 @@ nixos/lib/make-single-disk-zfs-image.nix @raitobezarius
|
|||
nixos/lib/make-multi-disk-zfs-image.nix @raitobezarius
|
||||
nixos/modules/tasks/filesystems/zfs.nix @raitobezarius
|
||||
nixos/tests/zfs.nix @raitobezarius
|
||||
|
||||
# Linux Kernel
|
||||
pkgs/os-specific/linux/kernel/manual-config.nix @amjoseph-nixpkgs
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
###### Description of changes
|
||||
## Description of changes
|
||||
|
||||
<!--
|
||||
For package updates please link to a changelog or describe changes, this helps your fellow maintainers discover breaking updates.
|
||||
For new packages please briefly describe the package or provide a link to its homepage.
|
||||
-->
|
||||
|
||||
###### Things done
|
||||
## Things done
|
||||
|
||||
<!-- Please check what applies. Note that these are not hard requirements but merely serve as information for reviewers. -->
|
||||
|
||||
|
|
1
third_party/nixpkgs/.gitignore
vendored
1
third_party/nixpkgs/.gitignore
vendored
|
@ -9,6 +9,7 @@
|
|||
outputs/
|
||||
result-*
|
||||
result
|
||||
repl-result-*
|
||||
!pkgs/development/python-modules/result
|
||||
/doc/NEWS.html
|
||||
/doc/NEWS.txt
|
||||
|
|
|
@ -34,5 +34,7 @@ The `ibus-engines.typing-booster` package contains a program named `emoji-picker
|
|||
On NixOS, it can be installed using the following expression:
|
||||
|
||||
```nix
|
||||
{ pkgs, ... }: { fonts.fonts = with pkgs; [ noto-fonts-emoji ]; }
|
||||
{ pkgs, ... }: {
|
||||
fonts.packages = with pkgs; [ noto-fonts-emoji ];
|
||||
}
|
||||
```
|
||||
|
|
4
third_party/nixpkgs/doc/common.nix
vendored
Normal file
4
third_party/nixpkgs/doc/common.nix
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
outputPath = "share/doc/nixpkgs";
|
||||
indexPath = "manual.html";
|
||||
}
|
|
@ -456,7 +456,7 @@ In the file `pkgs/top-level/all-packages.nix` you can find fetch helpers, these
|
|||
owner = "NixOS";
|
||||
repo = "nix";
|
||||
rev = "1f795f9f44607cc5bec70d1300150bfefcef2aae";
|
||||
hash = "ha256-7D4m+saJjbSFP5hOwpQq2FGR2rr+psQMTcyb1ZvtXsQ=";
|
||||
hash = "sha256-7D4m+saJjbSFP5hOwpQq2FGR2rr+psQMTcyb1ZvtXsQ=";
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -1,28 +1,24 @@
|
|||
# Contributing to this documentation {#chap-contributing}
|
||||
|
||||
The sources of the Nixpkgs manual are in the [doc](https://github.com/NixOS/nixpkgs/tree/master/doc) subdirectory of the Nixpkgs repository. The manual is still partially written in DocBook but it is progressively being converted to [Markdown](#sec-contributing-markup).
|
||||
The sources of the Nixpkgs manual are in the [doc](https://github.com/NixOS/nixpkgs/tree/master/doc) subdirectory of the Nixpkgs repository.
|
||||
|
||||
You can quickly check your edits with `make`:
|
||||
You can quickly check your edits with `nix-build`:
|
||||
|
||||
```ShellSession
|
||||
$ cd /path/to/nixpkgs/doc
|
||||
$ nix-shell
|
||||
[nix-shell]$ make
|
||||
```
|
||||
|
||||
If you experience problems, run `make debug` to help understand the docbook errors.
|
||||
|
||||
After making modifications to the manual, it's important to build it before committing. You can do that as follows:
|
||||
|
||||
```ShellSession
|
||||
$ cd /path/to/nixpkgs/doc
|
||||
$ nix-shell
|
||||
[nix-shell]$ make clean
|
||||
[nix-shell]$ nix-build .
|
||||
$ cd /path/to/nixpkgs
|
||||
$ nix-build doc
|
||||
```
|
||||
|
||||
If the build succeeds, the manual will be in `./result/share/doc/nixpkgs/manual.html`.
|
||||
|
||||
## devmode {#sec-contributing-devmode}
|
||||
|
||||
The shell in the manual source directory makes available a command, `devmode`.
|
||||
It is a daemon, that:
|
||||
1. watches the manual's source for changes and when they occur — rebuilds
|
||||
2. HTTP serves the manual, injecting a script that triggers reload on changes
|
||||
3. opens the manual in the default browser
|
||||
|
||||
## Syntax {#sec-contributing-markup}
|
||||
|
||||
As per [RFC 0072](https://github.com/NixOS/rfcs/pull/72), all new documentation content should be written in [CommonMark](https://commonmark.org/) Markdown dialect.
|
||||
|
@ -114,5 +110,3 @@ Additional syntax extensions are available, all of which can be used in NixOS op
|
|||
>
|
||||
> watermelon
|
||||
> : green fruit with red flesh
|
||||
|
||||
For contributing to the legacy parts, please see [DocBook: The Definitive Guide](https://tdg.docbook.org/) or the [DocBook rocks! primer](https://web.archive.org/web/20200816233747/https://docbook.rocks/).
|
||||
|
|
8
third_party/nixpkgs/doc/default.nix
vendored
8
third_party/nixpkgs/doc/default.nix
vendored
|
@ -3,6 +3,8 @@ let
|
|||
inherit (pkgs) lib;
|
||||
inherit (lib) hasPrefix removePrefix;
|
||||
|
||||
common = import ./common.nix;
|
||||
|
||||
lib-docs = import ./doc-support/lib-function-docs.nix {
|
||||
inherit pkgs nixpkgs;
|
||||
libsets = [
|
||||
|
@ -132,15 +134,15 @@ in pkgs.stdenv.mkDerivation {
|
|||
'';
|
||||
|
||||
installPhase = ''
|
||||
dest="$out/share/doc/nixpkgs"
|
||||
dest="$out/${common.outputPath}"
|
||||
mkdir -p "$(dirname "$dest")"
|
||||
mv out "$dest"
|
||||
mv "$dest/index.html" "$dest/manual.html"
|
||||
mv "$dest/index.html" "$dest/${common.indexPath}"
|
||||
|
||||
cp ${epub} "$dest/nixpkgs-manual.epub"
|
||||
|
||||
mkdir -p $out/nix-support/
|
||||
echo "doc manual $dest manual.html" >> $out/nix-support/hydra-build-products
|
||||
echo "doc manual $dest ${common.indexPath}" >> $out/nix-support/hydra-build-products
|
||||
echo "doc manual $dest nixpkgs-manual.epub" >> $out/nix-support/hydra-build-products
|
||||
'';
|
||||
}
|
||||
|
|
1
third_party/nixpkgs/doc/hooks/index.md
vendored
1
third_party/nixpkgs/doc/hooks/index.md
vendored
|
@ -29,5 +29,6 @@ tetex-tex-live.section.md
|
|||
unzip.section.md
|
||||
validatePkgConfig.section.md
|
||||
waf.section.md
|
||||
zig.section.md
|
||||
xcbuild.section.md
|
||||
```
|
||||
|
|
59
third_party/nixpkgs/doc/hooks/zig.section.md
vendored
Normal file
59
third_party/nixpkgs/doc/hooks/zig.section.md
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
# zigHook {#zighook}
|
||||
|
||||
[Zig](https://ziglang.org/) is a general-purpose programming language and toolchain for maintaining robust, optimal and reusable software.
|
||||
|
||||
In Nixpkgs, `zigHook` overrides the default build, check and install phases.
|
||||
|
||||
## Example code snippet {#example-code-snippet}
|
||||
|
||||
```nix
|
||||
{ lib
|
||||
, stdenv
|
||||
, zigHook
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation {
|
||||
# . . .
|
||||
|
||||
nativeBuildInputs = [
|
||||
zigHook
|
||||
];
|
||||
|
||||
zigBuildFlags = [ "-Dman-pages=true" ];
|
||||
|
||||
dontUseZigCheck = true;
|
||||
|
||||
# . . .
|
||||
}
|
||||
```
|
||||
|
||||
## Variables controlling zigHook {#variables-controlling-zighook}
|
||||
|
||||
### `dontUseZigBuild` {#dontUseZigBuild}
|
||||
|
||||
Disables using `zigBuildPhase`.
|
||||
|
||||
### `zigBuildFlags` {#zigBuildFlags}
|
||||
|
||||
Controls the flags passed to the build phase.
|
||||
|
||||
### `dontUseZigCheck` {#dontUseZigCheck}
|
||||
|
||||
Disables using `zigCheckPhase`.
|
||||
|
||||
### `zigCheckFlags` {#zigCheckFlags}
|
||||
|
||||
Controls the flags passed to the check phase.
|
||||
|
||||
### `dontUseZigInstall` {#dontUseZigInstall}
|
||||
|
||||
Disables using `zigInstallPhase`.
|
||||
|
||||
### `zigInstallFlags` {#zigInstallFlags}
|
||||
|
||||
Controls the flags passed to the install phase.
|
||||
|
||||
### Variables honored by zigHook {#variablesHonoredByZigHook}
|
||||
|
||||
- `prefixKey`
|
||||
- `dontAddPrefix`
|
|
@ -12,8 +12,11 @@ compatible are available as well. For example, there can be a
|
|||
|
||||
To use one or more CUDA packages in an expression, give the expression a `cudaPackages` parameter, and in case CUDA is optional
|
||||
```nix
|
||||
cudaSupport ? false
|
||||
cudaPackages ? {}
|
||||
{ config
|
||||
, cudaSupport ? config.cudaSupport
|
||||
, cudaPackages ? { }
|
||||
, ...
|
||||
}:
|
||||
```
|
||||
|
||||
When using `callPackage`, you can choose to pass in a different variant, e.g.
|
||||
|
|
|
@ -20,7 +20,7 @@ In the following is an example expression using `buildGoModule`, the following a
|
|||
|
||||
To obtain the actual hash, set `vendorHash = lib.fakeSha256;` and run the build ([more details here](#sec-source-hashes)).
|
||||
- `proxyVendor`: Fetches (go mod download) and proxies the vendor directory. This is useful if your code depends on c code and go mod tidy does not include the needed sources to build or if any dependency has case-insensitive conflicts which will produce platform-dependent `vendorHash` checksums.
|
||||
- `modPostBuild`: Shell commands to run after the build of the go-modules executes `go mod vendor`, and before calculating fixed output derivation's `vendorHash` (or `vendorSha256`). Note that if you change this attribute, you need to update `vendorHash` (or `vendorSha256`) attribute.
|
||||
- `modPostBuild`: Shell commands to run after the build of the goModules executes `go mod vendor`, and before calculating fixed output derivation's `vendorHash` (or `vendorSha256`). Note that if you change this attribute, you need to update `vendorHash` (or `vendorSha256`) attribute.
|
||||
|
||||
```nix
|
||||
pet = buildGoModule rec {
|
||||
|
@ -115,7 +115,7 @@ done
|
|||
|
||||
## Attributes used by the builders {#ssec-go-common-attributes}
|
||||
|
||||
Many attributes [controlling the build phase](#variables-controlling-the-build-phase) are respected by both `buildGoModule` and `buildGoPackage`. Note that `buildGoModule` reads the following attributes also when building the `vendor/` go-modules fixed output derivation as well:
|
||||
Many attributes [controlling the build phase](#variables-controlling-the-build-phase) are respected by both `buildGoModule` and `buildGoPackage`. Note that `buildGoModule` reads the following attributes also when building the `vendor/` goModules fixed output derivation as well:
|
||||
|
||||
- [`sourceRoot`](#var-stdenv-sourceRoot)
|
||||
- [`prePatch`](#var-stdenv-prePatch)
|
||||
|
|
|
@ -4,6 +4,87 @@ Maven is a well-known build tool for the Java ecosystem however it has some chal
|
|||
|
||||
The following provides a list of common patterns with how to package a Maven project (or any JVM language that can export to Maven) as a Nix package.
|
||||
|
||||
## Building a package using `maven.buildMavenPackage` {#maven-buildmavenpackage}
|
||||
|
||||
Consider the following package:
|
||||
|
||||
```nix
|
||||
{ lib, fetchFromGitHub, jre, makeWrapper, maven }:
|
||||
|
||||
maven.buildMavenPackage rec {
|
||||
pname = "jd-cli";
|
||||
version = "1.2.1";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "intoolswetrust";
|
||||
repo = pname;
|
||||
rev = "${pname}-${version}";
|
||||
hash = "sha256-rRttA5H0A0c44loBzbKH7Waoted3IsOgxGCD2VM0U/Q=";
|
||||
};
|
||||
|
||||
mvnHash = "sha256-kLpjMj05uC94/5vGMwMlFzLKNFOKeyNvq/vmB6pHTAo=";
|
||||
|
||||
nativeBuildInputs = [ makeWrapper ];
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out/bin $out/share/jd-cli
|
||||
install -Dm644 jd-cli/target/jd-cli.jar $out/share/jd-cli
|
||||
|
||||
makeWrapper ${jre}/bin/java $out/bin/jd-cli \
|
||||
--add-flags "-jar $out/share/jd-cli/jd-cli.jar"
|
||||
'';
|
||||
|
||||
meta = with lib; {
|
||||
description = "Simple command line wrapper around JD Core Java Decompiler project";
|
||||
homepage = "https://github.com/intoolswetrust/jd-cli";
|
||||
license = licenses.gpl3Plus;
|
||||
maintainers = with maintainers; [ majiir ];
|
||||
};
|
||||
}:
|
||||
```
|
||||
|
||||
This package calls `maven.buildMavenPackage` to do its work. The primary difference from `stdenv.mkDerivation` is the `mvnHash` variable, which is a hash of all of the Maven dependencies.
|
||||
|
||||
::: {.tip}
|
||||
After setting `maven.buildMavenPackage`, we then do standard Java `.jar` installation by saving the `.jar` to `$out/share/java` and then making a wrapper which allows executing that file; see [](#sec-language-java) for additional generic information about packaging Java applications.
|
||||
:::
|
||||
|
||||
### Stable Maven plugins {#stable-maven-plugins}
|
||||
|
||||
Maven defines default versions for its core plugins, e.g. `maven-compiler-plugin`. If your project does not override these versions, an upgrade of Maven will change the version of the used plugins, and therefore the derivation and hash.
|
||||
|
||||
When `maven` is upgraded, `mvnHash` for the derivation must be updated as well: otherwise, the project will simply be built on the derivation of old plugins, and fail because the requested plugins are missing.
|
||||
|
||||
This clearly prevents automatic upgrades of Maven: a manual effort must be made throughout nixpkgs by any maintainer wishing to push the upgrades.
|
||||
|
||||
To make sure that your package does not add extra manual effort when upgrading Maven, explicitly define versions for all plugins. You can check if this is the case by adding the following plugin to your (parent) POM:
|
||||
|
||||
```xml
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-enforcer-plugin</artifactId>
|
||||
<version>3.3.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>enforce-plugin-versions</id>
|
||||
<goals>
|
||||
<goal>enforce</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<rules>
|
||||
<requirePluginVersions />
|
||||
</rules>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
```
|
||||
|
||||
## Manually using `mvn2nix` {#maven-mvn2nix}
|
||||
::: {.warning}
|
||||
This way is no longer recommended; see [](#maven-buildmavenpackage) for the simpler and preferred way.
|
||||
:::
|
||||
|
||||
For the purposes of this example let's consider a very basic Maven project with the following `pom.xml` with a single dependency on [emoji-java](https://github.com/vdurmont/emoji-java).
|
||||
|
||||
```xml
|
||||
|
@ -41,14 +122,11 @@ public class Main {
|
|||
}
|
||||
```
|
||||
|
||||
You find this demo project at https://github.com/fzakaria/nixos-maven-example
|
||||
You find this demo project at [https://github.com/fzakaria/nixos-maven-example](https://github.com/fzakaria/nixos-maven-example).
|
||||
|
||||
## Solving for dependencies {#solving-for-dependencies}
|
||||
|
||||
### buildMaven with NixOS/mvn2nix-maven-plugin {#buildmaven-with-nixosmvn2nix-maven-plugin}
|
||||
|
||||
> ⚠️ Although `buildMaven` is the "blessed" way within nixpkgs, as of 2020, it hasn't seen much activity in quite a while.
|
||||
### Solving for dependencies {#solving-for-dependencies}
|
||||
|
||||
#### buildMaven with NixOS/mvn2nix-maven-plugin {#buildmaven-with-nixosmvn2nix-maven-plugin}
|
||||
`buildMaven` is an alternative method that tries to follow similar patterns of other programming languages by generating a lock file. It relies on the maven plugin [mvn2nix-maven-plugin](https://github.com/NixOS/mvn2nix-maven-plugin).
|
||||
|
||||
First you generate a `project-info.json` file using the maven plugin.
|
||||
|
@ -105,9 +183,10 @@ The benefit over the _double invocation_ as we will see below, is that the _/nix
|
|||
│ ├── avalon-framework-4.1.3.jar -> /nix/store/iv5fp3955w3nq28ff9xfz86wvxbiw6n9-avalon-framework-4.1.3.jar
|
||||
```
|
||||
|
||||
### Double Invocation {#double-invocation}
|
||||
|
||||
> ⚠️ This pattern is the simplest but may cause unnecessary rebuilds due to the output hash changing.
|
||||
#### Double Invocation {#double-invocation}
|
||||
::: {.note}
|
||||
This pattern is the simplest but may cause unnecessary rebuilds due to the output hash changing.
|
||||
:::
|
||||
|
||||
The double invocation is a _simple_ way to get around the problem that `nix-build` may be sandboxed and have no Internet connectivity.
|
||||
|
||||
|
@ -115,7 +194,9 @@ It treats the entire Maven repository as a single source to be downloaded, relyi
|
|||
|
||||
The first step will be to build the Maven project as a fixed-output derivation in order to collect the Maven repository -- below is an [example](https://github.com/fzakaria/nixos-maven-example/blob/main/double-invocation-repository.nix).
|
||||
|
||||
> Traditionally the Maven repository is at `~/.m2/repository`. We will override this to be the `$out` directory.
|
||||
::: {.note}
|
||||
Traditionally the Maven repository is at `~/.m2/repository`. We will override this to be the `$out` directory.
|
||||
:::
|
||||
|
||||
```nix
|
||||
{ lib, stdenv, maven }:
|
||||
|
@ -147,7 +228,9 @@ stdenv.mkDerivation {
|
|||
|
||||
The build will fail, and tell you the expected `outputHash` to place. When you've set the hash, the build will return with a `/nix/store` entry whose contents are the full Maven repository.
|
||||
|
||||
> Some additional files are deleted that would cause the output hash to change potentially on subsequent runs.
|
||||
::: {.warning}
|
||||
Some additional files are deleted that would cause the output hash to change potentially on subsequent runs.
|
||||
:::
|
||||
|
||||
```bash
|
||||
❯ tree $(nix-build --no-out-link double-invocation-repository.nix) | head
|
||||
|
@ -165,40 +248,7 @@ The build will fail, and tell you the expected `outputHash` to place. When you'v
|
|||
|
||||
If your package uses _SNAPSHOT_ dependencies or _version ranges_; there is a strong likelihood that over-time your output hash will change since the resolved dependencies may change. Hence this method is less recommended then using `buildMaven`.
|
||||
|
||||
#### Stable Maven plugins {#stable-maven-plugins}
|
||||
|
||||
Maven defines default versions for its core plugins, e.g. `maven-compiler-plugin`.
|
||||
If your project does not override these versions, an upgrade of Maven will change the version of the used plugins.
|
||||
This changes the output of the first invocation and the plugins required by the second invocation.
|
||||
However, since a hash is given for the output of the first invocation, the second invocation will simply fail
|
||||
because the requested plugins are missing.
|
||||
This will prevent automatic upgrades of Maven: the manual fix for this is to change the hash of the first invocation.
|
||||
|
||||
To make sure that your package does not add manual effort when upgrading Maven, explicitly define versions for all
|
||||
plugins. You can check if this is the case by adding the following plugin to your (parent) POM:
|
||||
|
||||
```xml
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-enforcer-plugin</artifactId>
|
||||
<version>3.3.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>enforce-plugin-versions</id>
|
||||
<goals>
|
||||
<goal>enforce</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<rules>
|
||||
<requirePluginVersions />
|
||||
</rules>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
```
|
||||
|
||||
## Building a JAR {#building-a-jar}
|
||||
### Building a JAR {#building-a-jar}
|
||||
|
||||
Regardless of which strategy is chosen above, the step to build the derivation is the same.
|
||||
|
||||
|
@ -224,7 +274,9 @@ in stdenv.mkDerivation rec {
|
|||
}
|
||||
```
|
||||
|
||||
> We place the library in `$out/share/java` since JDK package has a _stdenv setup hook_ that adds any JARs in the `share/java` directories of the build inputs to the CLASSPATH environment.
|
||||
::: {.tip}
|
||||
We place the library in `$out/share/java` since JDK package has a _stdenv setup hook_ that adds any JARs in the `share/java` directories of the build inputs to the CLASSPATH environment.
|
||||
:::
|
||||
|
||||
```bash
|
||||
❯ tree $(nix-build --no-out-link build-jar.nix)
|
||||
|
@ -236,7 +288,7 @@ in stdenv.mkDerivation rec {
|
|||
2 directories, 1 file
|
||||
```
|
||||
|
||||
## Runnable JAR {#runnable-jar}
|
||||
### Runnable JAR {#runnable-jar}
|
||||
|
||||
The previous example builds a `jar` file but that's not a file one can run.
|
||||
|
||||
|
@ -248,9 +300,9 @@ We will use the same repository we built above (either _double invocation_ or _b
|
|||
|
||||
The following two methods are more suited to Nix then building an [UberJar](https://imagej.net/Uber-JAR) which may be the more traditional approach.
|
||||
|
||||
### CLASSPATH {#classpath}
|
||||
#### CLASSPATH {#classpath}
|
||||
|
||||
> This is ideal if you are providing a derivation for _nixpkgs_ and don't want to patch the project's `pom.xml`.
|
||||
This method is ideal if you are providing a derivation for _nixpkgs_ and don't want to patch the project's `pom.xml`.
|
||||
|
||||
We will read the Maven repository and flatten it to a single list. This list will then be concatenated with the _CLASSPATH_ separator to create the full classpath.
|
||||
|
||||
|
@ -288,9 +340,9 @@ in stdenv.mkDerivation rec {
|
|||
}
|
||||
```
|
||||
|
||||
### MANIFEST file via Maven Plugin {#manifest-file-via-maven-plugin}
|
||||
#### MANIFEST file via Maven Plugin {#manifest-file-via-maven-plugin}
|
||||
|
||||
> This is ideal if you are the project owner and want to change your `pom.xml` to set the CLASSPATH within it.
|
||||
This method is ideal if you are the project owner and want to change your `pom.xml` to set the CLASSPATH within it.
|
||||
|
||||
Augment the `pom.xml` to create a JAR with the following manifest:
|
||||
|
||||
|
@ -366,8 +418,9 @@ in stdenv.mkDerivation rec {
|
|||
'';
|
||||
}
|
||||
```
|
||||
|
||||
> Our script produces a dependency on `jre` rather than `jdk` to restrict the runtime closure necessary to run the application.
|
||||
::: {.note}
|
||||
Our script produces a dependency on `jre` rather than `jdk` to restrict the runtime closure necessary to run the application.
|
||||
:::
|
||||
|
||||
This will give you an executable shell-script that launches your JAR with all the dependencies available.
|
||||
|
||||
|
|
|
@ -1514,11 +1514,11 @@ Note: There is a boolean value `lib.inNixShell` set to `true` if nix-shell is in
|
|||
|
||||
### Tools {#tools}
|
||||
|
||||
Packages inside nixpkgs are written by hand. However many tools exist in
|
||||
community to help save time. No tool is preferred at the moment.
|
||||
Packages inside nixpkgs must use the `buildPythonPackage` or `buildPythonApplication` function directly,
|
||||
because we can only provide security support for non-vendored dependencies.
|
||||
|
||||
- [nixpkgs-pytools](https://github.com/nix-community/nixpkgs-pytools)
|
||||
- [poetry2nix](https://github.com/nix-community/poetry2nix)
|
||||
We recommend [nix-init](https://github.com/nix-community/nix-init) for creating new python packages within nixpkgs,
|
||||
as it already prefetches the source, parses dependencies for common formats and prefills most things in `meta`.
|
||||
|
||||
### Deterministic builds {#deterministic-builds}
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ rustPlatform.buildRustPackage rec {
|
|||
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 ];
|
||||
maintainers = [];
|
||||
};
|
||||
}
|
||||
```
|
||||
|
@ -558,7 +558,7 @@ buildPythonPackage rec {
|
|||
hash = "sha256-miW//pnOmww2i6SOGbkrAIdc/JMDT4FJLqdMFojZeoY=";
|
||||
};
|
||||
|
||||
sourceRoot = "source/bindings/python";
|
||||
sourceRoot = "${src.name}/bindings/python";
|
||||
|
||||
nativeBuildInputs = [
|
||||
cargo
|
||||
|
@ -926,7 +926,7 @@ rustPlatform.buildRustPackage rec {
|
|||
description = "A fast line-oriented regex search tool, similar to ag and ack";
|
||||
homepage = "https://github.com/BurntSushi/ripgrep";
|
||||
license = with licenses; [ mit unlicense ];
|
||||
maintainers = with maintainers; [ tailhook ];
|
||||
maintainers = with maintainers; [];
|
||||
};
|
||||
}
|
||||
```
|
||||
|
|
20
third_party/nixpkgs/doc/shell.nix
vendored
Normal file
20
third_party/nixpkgs/doc/shell.nix
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
let
|
||||
pkgs = import ../. {
|
||||
config = {};
|
||||
overlays = [];
|
||||
};
|
||||
|
||||
common = import ./common.nix;
|
||||
inherit (common) outputPath indexPath;
|
||||
|
||||
web-devmode = import ../pkgs/tools/nix/web-devmode.nix {
|
||||
inherit pkgs;
|
||||
buildArgs = "./.";
|
||||
open = "/${outputPath}/${indexPath}";
|
||||
};
|
||||
in
|
||||
pkgs.mkShell {
|
||||
packages = [
|
||||
web-devmode
|
||||
];
|
||||
}
|
|
@ -70,7 +70,7 @@ A list of the maintainers of this Nix expression. Maintainers are defined in [`n
|
|||
|
||||
### `mainProgram` {#var-meta-mainProgram}
|
||||
|
||||
The name of the main binary for the package. This affects the binary `nix run` executes and falls back to the name of the package. Example: `"rg"`
|
||||
The name of the main binary for the package. This affects the binary `nix run` executes. Example: `"rg"`
|
||||
|
||||
### `priority` {#var-meta-priority}
|
||||
|
||||
|
|
|
@ -614,14 +614,19 @@ The list of source files or directories to be unpacked or copied. One of these m
|
|||
|
||||
##### `sourceRoot` {#var-stdenv-sourceRoot}
|
||||
|
||||
After running `unpackPhase`, the generic builder changes the current directory to the directory created by unpacking the sources. If there are multiple source directories, you should set `sourceRoot` to the name of the intended directory. Set `sourceRoot = ".";` if you use `srcs` and control the unpack phase yourself.
|
||||
After unpacking all of `src` and `srcs`, if neither of `sourceRoot` and `setSourceRoot` are set, `unpackPhase` of the generic builder checks that the unpacking produced a single directory and moves the current working directory into it.
|
||||
|
||||
By default the `sourceRoot` is set to `"source"`. If you want to point to a sub-directory inside your project, you therefore need to set `sourceRoot = "source/my-sub-directory"`.
|
||||
If `unpackPhase` produces multiple source directories, you should set `sourceRoot` to the name of the intended directory.
|
||||
You can also set `sourceRoot = ".";` if you want to control it yourself in a later phase.
|
||||
|
||||
For example, if your want your build to start in a sub-directory inside your sources, and you are using `fetchzip`-derived `src` (like `fetchFromGitHub` or similar), you need to set `sourceRoot = "${src.name}/my-sub-directory"`.
|
||||
|
||||
##### `setSourceRoot` {#var-stdenv-setSourceRoot}
|
||||
|
||||
Alternatively to setting `sourceRoot`, you can set `setSourceRoot` to a shell command to be evaluated by the unpack phase after the sources have been unpacked. This command must set `sourceRoot`.
|
||||
|
||||
For example, if you are using `fetchurl` on an archive file that gets unpacked into a single directory the name of which changes between package versions, and you want your build to start in its sub-directory, you need to set `setSourceRoot = "sourceRoot=$(echo */my-sub-directory)";`, or in the case of multiple sources, you could use something more specific, like `setSourceRoot = "sourceRoot=$(echo ${pname}-*/my-sub-directory)";`.
|
||||
|
||||
##### `preUnpack` {#var-stdenv-preUnpack}
|
||||
|
||||
Hook executed at the start of the unpack phase.
|
||||
|
|
73
third_party/nixpkgs/lib/README.md
vendored
Normal file
73
third_party/nixpkgs/lib/README.md
vendored
Normal file
|
@ -0,0 +1,73 @@
|
|||
# Nixpkgs lib
|
||||
|
||||
This directory contains the implementation, documentation and tests for the Nixpkgs `lib` library.
|
||||
|
||||
## Overview
|
||||
|
||||
The evaluation entry point for `lib` is [`default.nix`](default.nix).
|
||||
This file evaluates to an attribute set containing two separate kinds of attributes:
|
||||
- Sub-libraries:
|
||||
Attribute sets grouping together similar functionality.
|
||||
Each sub-library is defined in a separate file usually matching its attribute name.
|
||||
|
||||
Example: `lib.lists` is a sub-library containing list-related functionality such as `lib.lists.take` and `lib.lists.imap0`.
|
||||
These are defined in the file [`lists.nix`](lists.nix).
|
||||
|
||||
- Aliases:
|
||||
Attributes that point to an attribute of the same name in some sub-library.
|
||||
|
||||
Example: `lib.take` is an alias for `lib.lists.take`.
|
||||
|
||||
Most files in this directory are definitions of sub-libraries, but there are a few others:
|
||||
- [`minver.nix`](minver.nix): A string of the minimum version of Nix that is required to evaluate Nixpkgs.
|
||||
- [`tests`](tests): Tests, see [Running tests](#running-tests)
|
||||
- [`release.nix`](tests/release.nix): A derivation aggregating all tests
|
||||
- [`misc.nix`](tests/misc.nix): Evaluation unit tests for most sub-libraries
|
||||
- `*.sh`: Bash scripts that run tests for specific sub-libraries
|
||||
- All other files in this directory exist to support the tests
|
||||
- [`systems`](systems): The `lib.systems` sub-library, structured into a directory instead of a file due to its complexity
|
||||
- [`path`](path): The `lib.path` sub-library, which includes tests as well as a document describing the design goals of `lib.path`
|
||||
- All other files in this directory are sub-libraries
|
||||
|
||||
### Module system
|
||||
|
||||
The [module system](https://nixos.org/manual/nixpkgs/#module-system) spans multiple sub-libraries:
|
||||
- [`modules.nix`](modules.nix): `lib.modules` for the core functions and anything not relating to option definitions
|
||||
- [`options.nix`](options.nix): `lib.options` for anything relating to option definitions
|
||||
- [`types.nix`](types.nix): `lib.types` for module system types
|
||||
|
||||
## Reference documentation
|
||||
|
||||
Reference documentation for library functions is written above each function as a multi-line comment.
|
||||
These comments are processed using [nixdoc](https://github.com/nix-community/nixdoc) and [rendered in the Nixpkgs manual](https://nixos.org/manual/nixpkgs/stable/#chap-functions).
|
||||
The nixdoc README describes the [comment format](https://github.com/nix-community/nixdoc#comment-format).
|
||||
|
||||
See the [chapter on contributing to the Nixpkgs manual](https://nixos.org/manual/nixpkgs/#chap-contributing) for how to build the manual.
|
||||
|
||||
## Running tests
|
||||
|
||||
All library tests can be run by building the derivation in [`tests/release.nix`](tests/release.nix):
|
||||
|
||||
```bash
|
||||
nix-build tests/release.nix
|
||||
```
|
||||
|
||||
Some commands for quicker iteration over parts of the test suite are also available:
|
||||
|
||||
```bash
|
||||
# Run all evaluation unit tests in tests/misc.nix
|
||||
# if the resulting list is empty, all tests passed
|
||||
nix-instantiate --eval --strict tests/misc.nix
|
||||
|
||||
# Run the module system tests
|
||||
tests/modules.sh
|
||||
|
||||
# Run the lib.sources tests
|
||||
tests/sources.sh
|
||||
|
||||
# Run the lib.filesystem tests
|
||||
tests/filesystem.sh
|
||||
|
||||
# Run the lib.path property tests
|
||||
path/tests/prop.sh
|
||||
```
|
36
third_party/nixpkgs/lib/attrsets.nix
vendored
36
third_party/nixpkgs/lib/attrsets.nix
vendored
|
@ -738,6 +738,42 @@ rec {
|
|||
sets:
|
||||
zipAttrsWith (name: values: values) sets;
|
||||
|
||||
/*
|
||||
Merge a list of attribute sets together using the `//` operator.
|
||||
In case of duplicate attributes, values from later list elements take precedence over earlier ones.
|
||||
The result is the same as `foldl mergeAttrs { }`, but the performance is better for large inputs.
|
||||
For n list elements, each with an attribute set containing m unique attributes, the complexity of this operation is O(nm log n).
|
||||
|
||||
Type:
|
||||
mergeAttrsList :: [ Attrs ] -> Attrs
|
||||
|
||||
Example:
|
||||
mergeAttrsList [ { a = 0; b = 1; } { c = 2; d = 3; } ]
|
||||
=> { a = 0; b = 1; c = 2; d = 3; }
|
||||
mergeAttrsList [ { a = 0; } { a = 1; } ]
|
||||
=> { a = 1; }
|
||||
*/
|
||||
mergeAttrsList = list:
|
||||
let
|
||||
# `binaryMerge start end` merges the elements at indices `index` of `list` such that `start <= index < end`
|
||||
# Type: Int -> Int -> Attrs
|
||||
binaryMerge = start: end:
|
||||
# assert start < end; # Invariant
|
||||
if end - start >= 2 then
|
||||
# If there's at least 2 elements, split the range in two, recurse on each part and merge the result
|
||||
# The invariant is satisfied because each half will have at least 1 element
|
||||
binaryMerge start (start + (end - start) / 2)
|
||||
// binaryMerge (start + (end - start) / 2) end
|
||||
else
|
||||
# Otherwise there will be exactly 1 element due to the invariant, in which case we just return it directly
|
||||
elemAt list start;
|
||||
in
|
||||
if list == [ ] then
|
||||
# Calling binaryMerge as below would not satisfy its invariant
|
||||
{ }
|
||||
else
|
||||
binaryMerge 0 (length list);
|
||||
|
||||
|
||||
/* Does the same as the update operator '//' except that attributes are
|
||||
merged until the given predicate is verified. The predicate should
|
||||
|
|
5
third_party/nixpkgs/lib/generators.nix
vendored
5
third_party/nixpkgs/lib/generators.nix
vendored
|
@ -81,9 +81,10 @@ rec {
|
|||
*/
|
||||
toKeyValue = {
|
||||
mkKeyValue ? mkKeyValueDefault {} "=",
|
||||
listsAsDuplicateKeys ? false
|
||||
listsAsDuplicateKeys ? false,
|
||||
indent ? ""
|
||||
}:
|
||||
let mkLine = k: v: mkKeyValue k v + "\n";
|
||||
let mkLine = k: v: indent + mkKeyValue k v + "\n";
|
||||
mkLines = if listsAsDuplicateKeys
|
||||
then k: v: map (mkLine k) (if lib.isList v then v else [v])
|
||||
else k: v: [ (mkLine k v) ];
|
||||
|
|
7
third_party/nixpkgs/lib/licenses.nix
vendored
7
third_party/nixpkgs/lib/licenses.nix
vendored
|
@ -657,6 +657,13 @@ in mkLicense lset) ({
|
|||
redistributable = true;
|
||||
};
|
||||
|
||||
hl3 = {
|
||||
fullName = "Hippocratic License v3.0";
|
||||
url = "https://firstdonoharm.dev/version/3/0/core.txt";
|
||||
free = false;
|
||||
redistributable = true;
|
||||
};
|
||||
|
||||
issl = {
|
||||
fullName = "Intel Simplified Software License";
|
||||
url = "https://software.intel.com/en-us/license/intel-simplified-software-license";
|
||||
|
|
70
third_party/nixpkgs/lib/lists.nix
vendored
70
third_party/nixpkgs/lib/lists.nix
vendored
|
@ -3,7 +3,7 @@
|
|||
{ lib }:
|
||||
let
|
||||
inherit (lib.strings) toInt;
|
||||
inherit (lib.trivial) compare min;
|
||||
inherit (lib.trivial) compare min id;
|
||||
inherit (lib.attrsets) mapAttrs;
|
||||
in
|
||||
rec {
|
||||
|
@ -180,18 +180,18 @@ rec {
|
|||
else if len != 1 then multiple
|
||||
else head found;
|
||||
|
||||
/* Find the first element in the list matching the specified
|
||||
/* Find the first index in the list matching the specified
|
||||
predicate or return `default` if no such element exists.
|
||||
|
||||
Type: findFirst :: (a -> bool) -> a -> [a] -> a
|
||||
Type: findFirstIndex :: (a -> Bool) -> b -> [a] -> (Int | b)
|
||||
|
||||
Example:
|
||||
findFirst (x: x > 3) 7 [ 1 6 4 ]
|
||||
=> 6
|
||||
findFirst (x: x > 9) 7 [ 1 6 4 ]
|
||||
=> 7
|
||||
findFirstIndex (x: x > 3) null [ 0 6 4 ]
|
||||
=> 1
|
||||
findFirstIndex (x: x > 9) null [ 0 6 4 ]
|
||||
=> null
|
||||
*/
|
||||
findFirst =
|
||||
findFirstIndex =
|
||||
# Predicate
|
||||
pred:
|
||||
# Default value to return
|
||||
|
@ -229,7 +229,33 @@ rec {
|
|||
if resultIndex < 0 then
|
||||
default
|
||||
else
|
||||
elemAt list resultIndex;
|
||||
resultIndex;
|
||||
|
||||
/* Find the first element in the list matching the specified
|
||||
predicate or return `default` if no such element exists.
|
||||
|
||||
Type: findFirst :: (a -> bool) -> a -> [a] -> a
|
||||
|
||||
Example:
|
||||
findFirst (x: x > 3) 7 [ 1 6 4 ]
|
||||
=> 6
|
||||
findFirst (x: x > 9) 7 [ 1 6 4 ]
|
||||
=> 7
|
||||
*/
|
||||
findFirst =
|
||||
# Predicate
|
||||
pred:
|
||||
# Default value to return
|
||||
default:
|
||||
# Input list
|
||||
list:
|
||||
let
|
||||
index = findFirstIndex pred null list;
|
||||
in
|
||||
if index == null then
|
||||
default
|
||||
else
|
||||
elemAt list index;
|
||||
|
||||
/* Return true if function `pred` returns true for at least one
|
||||
element of `list`.
|
||||
|
@ -637,6 +663,32 @@ rec {
|
|||
else if start + count > len then len - start
|
||||
else count);
|
||||
|
||||
/* The common prefix of two lists.
|
||||
|
||||
Type: commonPrefix :: [a] -> [a] -> [a]
|
||||
|
||||
Example:
|
||||
commonPrefix [ 1 2 3 4 5 6 ] [ 1 2 4 8 ]
|
||||
=> [ 1 2 ]
|
||||
commonPrefix [ 1 2 3 ] [ 1 2 3 4 5 ]
|
||||
=> [ 1 2 3 ]
|
||||
commonPrefix [ 1 2 3 ] [ 4 5 6 ]
|
||||
=> [ ]
|
||||
*/
|
||||
commonPrefix =
|
||||
list1:
|
||||
list2:
|
||||
let
|
||||
# Zip the lists together into a list of booleans whether each element matches
|
||||
matchings = zipListsWith (fst: snd: fst != snd) list1 list2;
|
||||
# Find the first index where the elements don't match,
|
||||
# which will then also be the length of the common prefix.
|
||||
# If all elements match, we fall back to the length of the zipped list,
|
||||
# which is the same as the length of the smaller list.
|
||||
commonPrefixLength = findFirstIndex id (length matchings) matchings;
|
||||
in
|
||||
take commonPrefixLength list1;
|
||||
|
||||
/* Return the last element of a list.
|
||||
|
||||
This function throws an error if the list is empty.
|
||||
|
|
11
third_party/nixpkgs/lib/meta.nix
vendored
11
third_party/nixpkgs/lib/meta.nix
vendored
|
@ -132,10 +132,9 @@ rec {
|
|||
{ shortName = licstr; }
|
||||
);
|
||||
|
||||
/* Get the path to the main program of a derivation with either
|
||||
meta.mainProgram or pname or name
|
||||
/* Get the path to the main program of a package based on meta.mainProgram
|
||||
|
||||
Type: getExe :: derivation -> string
|
||||
Type: getExe :: package -> string
|
||||
|
||||
Example:
|
||||
getExe pkgs.hello
|
||||
|
@ -144,5 +143,9 @@ rec {
|
|||
=> "/nix/store/am9ml4f4ywvivxnkiaqwr0hyxka1xjsf-mustache-go-1.3.0/bin/mustache"
|
||||
*/
|
||||
getExe = x:
|
||||
"${lib.getBin x}/bin/${x.meta.mainProgram or (lib.getName x)}";
|
||||
"${lib.getBin x}/bin/${x.meta.mainProgram or (
|
||||
# This could be turned into an error when 23.05 is at end of life
|
||||
lib.warn "getExe: Package ${lib.strings.escapeNixIdentifier x.meta.name or x.pname or x.name} does not have the meta.mainProgram attribute. We'll assume that the main program has the same name for now, but this behavior is deprecated, because it leads to surprising errors when the assumption does not hold. If the package has a main program, please set `meta.mainProgram` in its definition to make this warning go away. Otherwise, if the package does not have a main program, or if you don't control its definition, specify the full path to the program, such as \"\${lib.getBin foo}/bin/bar\"."
|
||||
lib.getName x
|
||||
)}";
|
||||
}
|
||||
|
|
2
third_party/nixpkgs/lib/modules.nix
vendored
2
third_party/nixpkgs/lib/modules.nix
vendored
|
@ -639,7 +639,7 @@ let
|
|||
unmatchedDefns = [];
|
||||
}
|
||||
else if optionDecls != [] then
|
||||
if all (x: x.options.type.name == "submodule") optionDecls
|
||||
if all (x: x.options.type.name or null == "submodule") optionDecls
|
||||
# Raw options can only be merged into submodules. Merging into
|
||||
# attrsets might be nice, but ambiguous. Suppose we have
|
||||
# attrset as a `attrsOf submodule`. User declares option
|
||||
|
|
21
third_party/nixpkgs/lib/path/README.md
vendored
21
third_party/nixpkgs/lib/path/README.md
vendored
|
@ -187,6 +187,27 @@ Decision: All functions remove trailing slashes in their results.
|
|||
|
||||
</details>
|
||||
|
||||
### Prefer returning subpaths over components
|
||||
[subpath-preference]: #prefer-returning-subpaths-over-components
|
||||
|
||||
Observing: Functions could return subpaths or lists of path component strings.
|
||||
|
||||
Considering: Subpaths are used as inputs for some functions. Using them for outputs, too, makes the library more consistent and composable.
|
||||
|
||||
Decision: Subpaths should be preferred over list of path component strings.
|
||||
|
||||
<details>
|
||||
<summary>Arguments</summary>
|
||||
|
||||
- (+) It is consistent with functions accepting subpaths, making the library more composable
|
||||
- (-) It is less efficient when the components are needed, because after creating the normalised subpath string, it will have to be parsed into components again
|
||||
- (+) If necessary, we can still make it faster by adding builtins to Nix
|
||||
- (+) Alternatively if necessary, versions of these functions that return components could later still be introduced.
|
||||
- (+) It makes the path library simpler because there's only two types (paths and subpaths). Only `lib.path.subpath.components` can be used to get a list of components.
|
||||
And once we have a list of component strings, `lib.lists` and `lib.strings` can be used to operate on them.
|
||||
For completeness, `lib.path.subpath.join` allows converting the list of components back to a subpath.
|
||||
</details>
|
||||
|
||||
## Other implementations and references
|
||||
|
||||
- [Rust](https://doc.rust-lang.org/std/path/struct.Path.html)
|
||||
|
|
133
third_party/nixpkgs/lib/path/default.nix
vendored
133
third_party/nixpkgs/lib/path/default.nix
vendored
|
@ -20,6 +20,7 @@ let
|
|||
concatMap
|
||||
foldl'
|
||||
take
|
||||
drop
|
||||
;
|
||||
|
||||
inherit (lib.strings)
|
||||
|
@ -217,9 +218,110 @@ in /* No rec! Add dependencies on this file at the top. */ {
|
|||
second argument: "${toString path2}" with root "${toString path2Deconstructed.root}"'';
|
||||
take (length path1Deconstructed.components) path2Deconstructed.components == path1Deconstructed.components;
|
||||
|
||||
/*
|
||||
Remove the first path as a component-wise prefix from the second path.
|
||||
The result is a normalised subpath string, see `lib.path.subpath.normalise`.
|
||||
|
||||
Laws:
|
||||
|
||||
- Inverts `append` for normalised subpaths:
|
||||
|
||||
removePrefix p (append p s) == subpath.normalise s
|
||||
|
||||
Type:
|
||||
removePrefix :: Path -> Path -> String
|
||||
|
||||
Example:
|
||||
removePrefix /foo /foo/bar/baz
|
||||
=> "./bar/baz"
|
||||
removePrefix /foo /foo
|
||||
=> "./."
|
||||
removePrefix /foo/bar /foo
|
||||
=> <error>
|
||||
removePrefix /. /foo
|
||||
=> "./foo"
|
||||
*/
|
||||
removePrefix =
|
||||
path1:
|
||||
assert assertMsg
|
||||
(isPath path1)
|
||||
"lib.path.removePrefix: First argument is of type ${typeOf path1}, but a path was expected.";
|
||||
let
|
||||
path1Deconstructed = deconstructPath path1;
|
||||
path1Length = length path1Deconstructed.components;
|
||||
in
|
||||
path2:
|
||||
assert assertMsg
|
||||
(isPath path2)
|
||||
"lib.path.removePrefix: Second argument is of type ${typeOf path2}, but a path was expected.";
|
||||
let
|
||||
path2Deconstructed = deconstructPath path2;
|
||||
success = take path1Length path2Deconstructed.components == path1Deconstructed.components;
|
||||
components =
|
||||
if success then
|
||||
drop path1Length path2Deconstructed.components
|
||||
else
|
||||
throw ''
|
||||
lib.path.removePrefix: The first path argument "${toString path1}" is not a component-wise prefix of the second path argument "${toString path2}".'';
|
||||
in
|
||||
assert assertMsg
|
||||
(path1Deconstructed.root == path2Deconstructed.root) ''
|
||||
lib.path.removePrefix: Filesystem roots must be the same for both paths, but paths with different roots were given:
|
||||
first argument: "${toString path1}" with root "${toString path1Deconstructed.root}"
|
||||
second argument: "${toString path2}" with root "${toString path2Deconstructed.root}"'';
|
||||
joinRelPath components;
|
||||
|
||||
/*
|
||||
Split the filesystem root from a [path](https://nixos.org/manual/nix/stable/language/values.html#type-path).
|
||||
The result is an attribute set with these attributes:
|
||||
- `root`: The filesystem root of the path, meaning that this directory has no parent directory.
|
||||
- `subpath`: The [normalised subpath string](#function-library-lib.path.subpath.normalise) that when [appended](#function-library-lib.path.append) to `root` returns the original path.
|
||||
|
||||
Laws:
|
||||
- [Appending](#function-library-lib.path.append) the `root` and `subpath` gives the original path:
|
||||
|
||||
p ==
|
||||
append
|
||||
(splitRoot p).root
|
||||
(splitRoot p).subpath
|
||||
|
||||
- Trying to get the parent directory of `root` using [`readDir`](https://nixos.org/manual/nix/stable/language/builtins.html#builtins-readDir) returns `root` itself:
|
||||
|
||||
dirOf (splitRoot p).root == (splitRoot p).root
|
||||
|
||||
Type:
|
||||
splitRoot :: Path -> { root :: Path, subpath :: String }
|
||||
|
||||
Example:
|
||||
splitRoot /foo/bar
|
||||
=> { root = /.; subpath = "./foo/bar"; }
|
||||
|
||||
splitRoot /.
|
||||
=> { root = /.; subpath = "./."; }
|
||||
|
||||
# Nix neutralises `..` path components for all path values automatically
|
||||
splitRoot /foo/../bar
|
||||
=> { root = /.; subpath = "./bar"; }
|
||||
|
||||
splitRoot "/foo/bar"
|
||||
=> <error>
|
||||
*/
|
||||
splitRoot = path:
|
||||
assert assertMsg
|
||||
(isPath path)
|
||||
"lib.path.splitRoot: Argument is of type ${typeOf path}, but a path was expected";
|
||||
let
|
||||
deconstructed = deconstructPath path;
|
||||
in {
|
||||
root = deconstructed.root;
|
||||
subpath = joinRelPath deconstructed.components;
|
||||
};
|
||||
|
||||
/* Whether a value is a valid subpath string.
|
||||
|
||||
A subpath string points to a specific file or directory within an absolute base directory.
|
||||
It is a stricter form of a relative path that excludes `..` components, since those could escape the base directory.
|
||||
|
||||
- The value is a string
|
||||
|
||||
- The string is not empty
|
||||
|
@ -336,6 +438,37 @@ in /* No rec! Add dependencies on this file at the top. */ {
|
|||
${subpathInvalidReason path}''
|
||||
) 0 subpaths;
|
||||
|
||||
/*
|
||||
Split [a subpath](#function-library-lib.path.subpath.isValid) into its path component strings.
|
||||
Throw an error if the subpath isn't valid.
|
||||
Note that the returned path components are also valid subpath strings, though they are intentionally not [normalised](#function-library-lib.path.subpath.normalise).
|
||||
|
||||
Laws:
|
||||
|
||||
- Splitting a subpath into components and [joining](#function-library-lib.path.subpath.join) the components gives the same subpath but [normalised](#function-library-lib.path.subpath.normalise):
|
||||
|
||||
subpath.join (subpath.components s) == subpath.normalise s
|
||||
|
||||
Type:
|
||||
subpath.components :: String -> [ String ]
|
||||
|
||||
Example:
|
||||
subpath.components "."
|
||||
=> [ ]
|
||||
|
||||
subpath.components "./foo//bar/./baz/"
|
||||
=> [ "foo" "bar" "baz" ]
|
||||
|
||||
subpath.components "/foo"
|
||||
=> <error>
|
||||
*/
|
||||
subpath.components =
|
||||
subpath:
|
||||
assert assertMsg (isValid subpath) ''
|
||||
lib.path.subpath.components: Argument is not a valid subpath string:
|
||||
${subpathInvalidReason subpath}'';
|
||||
splitRelPath subpath;
|
||||
|
||||
/* Normalise a subpath. Throw an error if the subpath isn't valid, see
|
||||
`lib.path.subpath.isValid`
|
||||
|
||||
|
|
7
third_party/nixpkgs/lib/path/tests/prop.sh
vendored
7
third_party/nixpkgs/lib/path/tests/prop.sh
vendored
|
@ -1,9 +1,12 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Property tests for the `lib.path` library
|
||||
#
|
||||
# Property tests for lib/path/default.nix
|
||||
# It generates random path-like strings and runs the functions on
|
||||
# them, checking that the expected laws of the functions hold
|
||||
# Run:
|
||||
# [nixpkgs]$ lib/path/tests/prop.sh
|
||||
# or:
|
||||
# [nixpkgs]$ nix-build lib/tests/release.nix
|
||||
|
||||
set -euo pipefail
|
||||
shopt -s inherit_errexit
|
||||
|
|
49
third_party/nixpkgs/lib/path/tests/unit.nix
vendored
49
third_party/nixpkgs/lib/path/tests/unit.nix
vendored
|
@ -3,7 +3,7 @@
|
|||
{ libpath }:
|
||||
let
|
||||
lib = import libpath;
|
||||
inherit (lib.path) hasPrefix append subpath;
|
||||
inherit (lib.path) hasPrefix removePrefix append splitRoot subpath;
|
||||
|
||||
cases = lib.runTests {
|
||||
# Test examples from the lib.path.append documentation
|
||||
|
@ -57,6 +57,40 @@ let
|
|||
expected = true;
|
||||
};
|
||||
|
||||
testRemovePrefixExample1 = {
|
||||
expr = removePrefix /foo /foo/bar/baz;
|
||||
expected = "./bar/baz";
|
||||
};
|
||||
testRemovePrefixExample2 = {
|
||||
expr = removePrefix /foo /foo;
|
||||
expected = "./.";
|
||||
};
|
||||
testRemovePrefixExample3 = {
|
||||
expr = (builtins.tryEval (removePrefix /foo/bar /foo)).success;
|
||||
expected = false;
|
||||
};
|
||||
testRemovePrefixExample4 = {
|
||||
expr = removePrefix /. /foo;
|
||||
expected = "./foo";
|
||||
};
|
||||
|
||||
testSplitRootExample1 = {
|
||||
expr = splitRoot /foo/bar;
|
||||
expected = { root = /.; subpath = "./foo/bar"; };
|
||||
};
|
||||
testSplitRootExample2 = {
|
||||
expr = splitRoot /.;
|
||||
expected = { root = /.; subpath = "./."; };
|
||||
};
|
||||
testSplitRootExample3 = {
|
||||
expr = splitRoot /foo/../bar;
|
||||
expected = { root = /.; subpath = "./bar"; };
|
||||
};
|
||||
testSplitRootExample4 = {
|
||||
expr = (builtins.tryEval (splitRoot "/foo/bar")).success;
|
||||
expected = false;
|
||||
};
|
||||
|
||||
# Test examples from the lib.path.subpath.isValid documentation
|
||||
testSubpathIsValidExample1 = {
|
||||
expr = subpath.isValid null;
|
||||
|
@ -204,6 +238,19 @@ let
|
|||
expr = (builtins.tryEval (subpath.normalise "..")).success;
|
||||
expected = false;
|
||||
};
|
||||
|
||||
testSubpathComponentsExample1 = {
|
||||
expr = subpath.components ".";
|
||||
expected = [ ];
|
||||
};
|
||||
testSubpathComponentsExample2 = {
|
||||
expr = subpath.components "./foo//bar/./baz/";
|
||||
expected = [ "foo" "bar" "baz" ];
|
||||
};
|
||||
testSubpathComponentsExample3 = {
|
||||
expr = (builtins.tryEval (subpath.components "/foo")).success;
|
||||
expected = false;
|
||||
};
|
||||
};
|
||||
in
|
||||
if cases == [] then "Unit tests successful"
|
||||
|
|
11
third_party/nixpkgs/lib/systems/default.nix
vendored
11
third_party/nixpkgs/lib/systems/default.nix
vendored
|
@ -85,17 +85,18 @@ rec {
|
|||
# is why we use the more obscure "bfd" and not "binutils" for this
|
||||
# choice.
|
||||
else "bfd";
|
||||
extensions = rec {
|
||||
sharedLibrary = assert final.hasSharedLibraries;
|
||||
/**/ if final.isDarwin then ".dylib"
|
||||
extensions = lib.optionalAttrs final.hasSharedLibraries {
|
||||
sharedLibrary =
|
||||
if final.isDarwin then ".dylib"
|
||||
else if final.isWindows then ".dll"
|
||||
else ".so";
|
||||
} // {
|
||||
staticLibrary =
|
||||
/**/ if final.isWindows then ".lib"
|
||||
else ".a";
|
||||
library =
|
||||
/**/ if final.isStatic then staticLibrary
|
||||
else sharedLibrary;
|
||||
/**/ if final.isStatic then final.extensions.staticLibrary
|
||||
else final.extensions.sharedLibrary;
|
||||
executable =
|
||||
/**/ if final.isWindows then ".exe"
|
||||
else "";
|
||||
|
|
|
@ -213,7 +213,6 @@ rec {
|
|||
bluefield2 = {
|
||||
gcc = {
|
||||
arch = "armv8-a+fp+simd+crc+crypto";
|
||||
cpu = "cortex-a72";
|
||||
};
|
||||
};
|
||||
|
||||
|
|
126
third_party/nixpkgs/lib/tests/misc.nix
vendored
126
third_party/nixpkgs/lib/tests/misc.nix
vendored
|
@ -1,6 +1,18 @@
|
|||
# to run these tests:
|
||||
# nix-instantiate --eval --strict nixpkgs/lib/tests/misc.nix
|
||||
# if the resulting list is empty, all tests passed
|
||||
/*
|
||||
Nix evaluation tests for various lib functions.
|
||||
|
||||
Since these tests are implemented with Nix evaluation, error checking is limited to what `builtins.tryEval` can detect, which is `throw`'s and `abort`'s, without error messages.
|
||||
If you need to test error messages or more complex evaluations, see ./modules.sh, ./sources.sh or ./filesystem.sh as examples.
|
||||
|
||||
To run these tests:
|
||||
|
||||
[nixpkgs]$ nix-instantiate --eval --strict lib/tests/misc.nix
|
||||
|
||||
If the resulting list is empty, all tests passed.
|
||||
Alternatively, to run all `lib` tests:
|
||||
|
||||
[nixpkgs]$ nix-build lib/tests/release.nix
|
||||
*/
|
||||
with import ../default.nix;
|
||||
|
||||
let
|
||||
|
@ -488,6 +500,39 @@ runTests {
|
|||
expected = { a = [ 2 3 ]; b = [7]; c = [8];};
|
||||
};
|
||||
|
||||
testListCommonPrefixExample1 = {
|
||||
expr = lists.commonPrefix [ 1 2 3 4 5 6 ] [ 1 2 4 8 ];
|
||||
expected = [ 1 2 ];
|
||||
};
|
||||
testListCommonPrefixExample2 = {
|
||||
expr = lists.commonPrefix [ 1 2 3 ] [ 1 2 3 4 5 ];
|
||||
expected = [ 1 2 3 ];
|
||||
};
|
||||
testListCommonPrefixExample3 = {
|
||||
expr = lists.commonPrefix [ 1 2 3 ] [ 4 5 6 ];
|
||||
expected = [ ];
|
||||
};
|
||||
testListCommonPrefixEmpty = {
|
||||
expr = lists.commonPrefix [ ] [ 1 2 3 ];
|
||||
expected = [ ];
|
||||
};
|
||||
testListCommonPrefixSame = {
|
||||
expr = lists.commonPrefix [ 1 2 3 ] [ 1 2 3 ];
|
||||
expected = [ 1 2 3 ];
|
||||
};
|
||||
testListCommonPrefixLazy = {
|
||||
expr = lists.commonPrefix [ 1 ] [ 1 (abort "lib.lists.commonPrefix shouldn't evaluate this")];
|
||||
expected = [ 1 ];
|
||||
};
|
||||
# This would stack overflow if `commonPrefix` were implemented using recursion
|
||||
testListCommonPrefixLong =
|
||||
let
|
||||
longList = genList (n: n) 100000;
|
||||
in {
|
||||
expr = lists.commonPrefix longList longList;
|
||||
expected = longList;
|
||||
};
|
||||
|
||||
testSort = {
|
||||
expr = sort builtins.lessThan [ 40 2 30 42 ];
|
||||
expected = [2 30 40 42];
|
||||
|
@ -518,45 +563,55 @@ runTests {
|
|||
expected = false;
|
||||
};
|
||||
|
||||
testFindFirstExample1 = {
|
||||
expr = findFirst (x: x > 3) 7 [ 1 6 4 ];
|
||||
expected = 6;
|
||||
testFindFirstIndexExample1 = {
|
||||
expr = lists.findFirstIndex (x: x > 3) (abort "index found, so a default must not be evaluated") [ 1 6 4 ];
|
||||
expected = 1;
|
||||
};
|
||||
|
||||
testFindFirstExample2 = {
|
||||
expr = findFirst (x: x > 9) 7 [ 1 6 4 ];
|
||||
expected = 7;
|
||||
testFindFirstIndexExample2 = {
|
||||
expr = lists.findFirstIndex (x: x > 9) "a very specific default" [ 1 6 4 ];
|
||||
expected = "a very specific default";
|
||||
};
|
||||
|
||||
testFindFirstEmpty = {
|
||||
expr = findFirst (abort "when the list is empty, the predicate is not needed") null [];
|
||||
testFindFirstIndexEmpty = {
|
||||
expr = lists.findFirstIndex (abort "when the list is empty, the predicate is not needed") null [];
|
||||
expected = null;
|
||||
};
|
||||
|
||||
testFindFirstSingleMatch = {
|
||||
expr = findFirst (x: x == 5) null [ 5 ];
|
||||
expected = 5;
|
||||
testFindFirstIndexSingleMatch = {
|
||||
expr = lists.findFirstIndex (x: x == 5) null [ 5 ];
|
||||
expected = 0;
|
||||
};
|
||||
|
||||
testFindFirstSingleDefault = {
|
||||
expr = findFirst (x: false) null [ (abort "if the predicate doesn't access the value, it must not be evaluated") ];
|
||||
testFindFirstIndexSingleDefault = {
|
||||
expr = lists.findFirstIndex (x: false) null [ (abort "if the predicate doesn't access the value, it must not be evaluated") ];
|
||||
expected = null;
|
||||
};
|
||||
|
||||
testFindFirstNone = {
|
||||
expr = builtins.tryEval (findFirst (x: x == 2) null [ 1 (throw "the last element must be evaluated when there's no match") ]);
|
||||
testFindFirstIndexNone = {
|
||||
expr = builtins.tryEval (lists.findFirstIndex (x: x == 2) null [ 1 (throw "the last element must be evaluated when there's no match") ]);
|
||||
expected = { success = false; value = false; };
|
||||
};
|
||||
|
||||
# Makes sure that the implementation doesn't cause a stack overflow
|
||||
testFindFirstBig = {
|
||||
expr = findFirst (x: x == 1000000) null (range 0 1000000);
|
||||
testFindFirstIndexBig = {
|
||||
expr = lists.findFirstIndex (x: x == 1000000) null (range 0 1000000);
|
||||
expected = 1000000;
|
||||
};
|
||||
|
||||
testFindFirstLazy = {
|
||||
expr = findFirst (x: x == 1) 7 [ 1 (abort "list elements after the match must not be evaluated") ];
|
||||
expected = 1;
|
||||
testFindFirstIndexLazy = {
|
||||
expr = lists.findFirstIndex (x: x == 1) null [ 1 (abort "list elements after the match must not be evaluated") ];
|
||||
expected = 0;
|
||||
};
|
||||
|
||||
testFindFirstExample1 = {
|
||||
expr = lists.findFirst (x: x > 3) 7 [ 1 6 4 ];
|
||||
expected = 6;
|
||||
};
|
||||
|
||||
testFindFirstExample2 = {
|
||||
expr = lists.findFirst (x: x > 9) 7 [ 1 6 4 ];
|
||||
expected = 7;
|
||||
};
|
||||
|
||||
# ATTRSETS
|
||||
|
@ -609,6 +664,31 @@ runTests {
|
|||
};
|
||||
};
|
||||
|
||||
|
||||
testMergeAttrsListExample1 = {
|
||||
expr = attrsets.mergeAttrsList [ { a = 0; b = 1; } { c = 2; d = 3; } ];
|
||||
expected = { a = 0; b = 1; c = 2; d = 3; };
|
||||
};
|
||||
testMergeAttrsListExample2 = {
|
||||
expr = attrsets.mergeAttrsList [ { a = 0; } { a = 1; } ];
|
||||
expected = { a = 1; };
|
||||
};
|
||||
testMergeAttrsListExampleMany =
|
||||
let
|
||||
list = genList (n:
|
||||
listToAttrs (genList (m:
|
||||
let
|
||||
# Integer divide n by two to create duplicate attributes
|
||||
str = "halfn${toString (n / 2)}m${toString m}";
|
||||
in
|
||||
nameValuePair str str
|
||||
) 100)
|
||||
) 100;
|
||||
in {
|
||||
expr = attrsets.mergeAttrsList list;
|
||||
expected = foldl' mergeAttrs { } list;
|
||||
};
|
||||
|
||||
# code from the example
|
||||
testRecursiveUpdateUntil = {
|
||||
expr = recursiveUpdateUntil (path: l: r: path == ["foo"]) {
|
||||
|
|
33
third_party/nixpkgs/lib/tests/modules.sh
vendored
33
third_party/nixpkgs/lib/tests/modules.sh
vendored
|
@ -1,7 +1,13 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
|
||||
# This script is used to test that the module system is working as expected.
|
||||
# Executing it runs tests for `lib.modules`, `lib.options` and `lib.types`.
|
||||
# By default it test the version of nixpkgs which is defined in the NIX_PATH.
|
||||
#
|
||||
# Run:
|
||||
# [nixpkgs]$ lib/tests/modules.sh
|
||||
# or:
|
||||
# [nixpkgs]$ nix-build lib/tests/release.nix
|
||||
|
||||
set -o errexit -o noclobber -o nounset -o pipefail
|
||||
shopt -s failglob inherit_errexit
|
||||
|
@ -63,6 +69,28 @@ checkConfigOutput '^"one two"$' config.result ./shorthand-meta.nix
|
|||
|
||||
checkConfigOutput '^true$' config.result ./test-mergeAttrDefinitionsWithPrio.nix
|
||||
|
||||
# Check that a module argument is passed, also when a default is available
|
||||
# (but not needed)
|
||||
#
|
||||
# When the default is needed, we currently fail to do what the users expect, as
|
||||
# we pass our own argument anyway, even if it *turns out* not to exist.
|
||||
#
|
||||
# The reason for this is that we don't know at invocation time what is in the
|
||||
# _module.args option. That value is only available *after* all modules have been
|
||||
# invoked.
|
||||
#
|
||||
# Hypothetically, Nix could help support this by giving access to the default
|
||||
# values, through a new built-in function.
|
||||
# However the default values are allowed to depend on other arguments, so those
|
||||
# would have to be passed in somehow, making this not just a getter but
|
||||
# something more complicated.
|
||||
#
|
||||
# At that point we have to wonder whether the extra complexity is worth the cost.
|
||||
# Another - subjective - reason not to support it is that default values
|
||||
# contradict the notion that an option has a single value, where _module.args
|
||||
# is the option.
|
||||
checkConfigOutput '^true$' config.result ./module-argument-default.nix
|
||||
|
||||
# types.pathInStore
|
||||
checkConfigOutput '".*/store/0lz9p8xhf89kb1c1kk6jxrzskaiygnlh-bash-5.2-p15.drv"' config.pathInStore.ok1 ./types.nix
|
||||
checkConfigOutput '".*/store/0fb3ykw9r5hpayd05sr0cizwadzq1d8q-bash-5.2-p15"' config.pathInStore.ok2 ./types.nix
|
||||
|
@ -365,6 +393,9 @@ checkConfigError \
|
|||
config.set \
|
||||
./declare-set.nix ./declare-enable-nested.nix
|
||||
|
||||
# Check that that merging of option collisions doesn't depend on type being set
|
||||
checkConfigError 'The option .group..*would be a parent of the following options, but its type .<no description>. does not support nested options.\n\s*- option.s. with prefix .group.enable..*' config.group.enable ./merge-typeless-option.nix
|
||||
|
||||
# Test that types.optionType merges types correctly
|
||||
checkConfigOutput '^10$' config.theOption.int ./optionTypeMerging.nix
|
||||
checkConfigOutput '^"hello"$' config.theOption.str ./optionTypeMerging.nix
|
||||
|
|
25
third_party/nixpkgs/lib/tests/modules/merge-typeless-option.nix
vendored
Normal file
25
third_party/nixpkgs/lib/tests/modules/merge-typeless-option.nix
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
{ lib, ... }:
|
||||
|
||||
let
|
||||
typeless =
|
||||
{ lib, ... }:
|
||||
|
||||
{
|
||||
options.group = lib.mkOption { };
|
||||
};
|
||||
childOfTypeless =
|
||||
{ lib, ... }:
|
||||
|
||||
{
|
||||
options.group.enable = lib.mkEnableOption "nothing";
|
||||
};
|
||||
in
|
||||
|
||||
{
|
||||
imports = [
|
||||
typeless
|
||||
childOfTypeless
|
||||
];
|
||||
|
||||
config.group.enable = false;
|
||||
}
|
9
third_party/nixpkgs/lib/tests/modules/module-argument-default.nix
vendored
Normal file
9
third_party/nixpkgs/lib/tests/modules/module-argument-default.nix
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
{ a ? false, lib, ... }: {
|
||||
options = {
|
||||
result = lib.mkOption {};
|
||||
};
|
||||
config = {
|
||||
_module.args.a = true;
|
||||
result = a;
|
||||
};
|
||||
}
|
7
third_party/nixpkgs/lib/tests/sources.sh
vendored
7
third_party/nixpkgs/lib/tests/sources.sh
vendored
|
@ -1,4 +1,11 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Tests lib/sources.nix
|
||||
# Run:
|
||||
# [nixpkgs]$ lib/tests/sources.sh
|
||||
# or:
|
||||
# [nixpkgs]$ nix-build lib/tests/release.nix
|
||||
|
||||
set -euo pipefail
|
||||
shopt -s inherit_errexit
|
||||
|
||||
|
|
412
third_party/nixpkgs/maintainers/maintainer-list.nix
vendored
412
third_party/nixpkgs/maintainers/maintainer-list.nix
vendored
|
@ -418,6 +418,12 @@
|
|||
githubId = 1250775;
|
||||
name = "Adolfo E. García Castro";
|
||||
};
|
||||
adriandole = {
|
||||
email = "adrian@dole.tech";
|
||||
github = "adriandole";
|
||||
githubId = 25236206;
|
||||
name = "Adrian Dole";
|
||||
};
|
||||
AdsonCicilioti = {
|
||||
name = "Adson Cicilioti";
|
||||
email = "adson.cicilioti@live.com";
|
||||
|
@ -581,6 +587,12 @@
|
|||
githubId = 1318982;
|
||||
name = "Anders Claesson";
|
||||
};
|
||||
akechishiro = {
|
||||
email = "akechishiro-aur+nixpkgs@lahfa.xyz";
|
||||
github = "AkechiShiro";
|
||||
githubId = 14914796;
|
||||
name = "Samy Lahfa";
|
||||
};
|
||||
a-kenji = {
|
||||
email = "aks.kenji@protonmail.com";
|
||||
github = "a-kenji";
|
||||
|
@ -638,6 +650,13 @@
|
|||
githubId = 82811;
|
||||
name = "Aldo Borrero";
|
||||
};
|
||||
alejandrosame = {
|
||||
email = "alejandrosanchzmedina@gmail.com";
|
||||
matrix = "@alejandrosame:matrix.org";
|
||||
github = "alejandrosame";
|
||||
githubId = 1078000;
|
||||
name = "Alejandro Sánchez Medina";
|
||||
};
|
||||
aleksana = {
|
||||
email = "me@aleksana.moe";
|
||||
github = "Aleksanaa";
|
||||
|
@ -1148,6 +1167,9 @@
|
|||
githubId = 48802534;
|
||||
name = "Anselm Schüler";
|
||||
matrix = "@schuelermine:matrix.org";
|
||||
keys = [{
|
||||
fingerprint = "CDBF ECA8 36FE E340 1CEB 58FF BA34 EE1A BA3A 0955";
|
||||
}];
|
||||
};
|
||||
anthonyroussel = {
|
||||
email = "anthony@roussel.dev";
|
||||
|
@ -1237,6 +1259,12 @@
|
|||
githubId = 30842467;
|
||||
name = "April John";
|
||||
};
|
||||
aqrln = {
|
||||
email = "nix@aqrln.net";
|
||||
github = "aqrln";
|
||||
githubId = 4923335;
|
||||
name = "Alexey Orlenko";
|
||||
};
|
||||
ar1a = {
|
||||
email = "aria@ar1as.space";
|
||||
github = "ar1a";
|
||||
|
@ -1389,6 +1417,12 @@
|
|||
githubId = 37193992;
|
||||
name = "Arthur Teisseire";
|
||||
};
|
||||
arti5an = {
|
||||
email = "artis4n@outlook.com";
|
||||
github = "arti5an";
|
||||
githubId = 14922630;
|
||||
name = "Richard Smith";
|
||||
};
|
||||
artturin = {
|
||||
email = "artturin@artturin.com";
|
||||
matrix = "@artturin:matrix.org";
|
||||
|
@ -1499,6 +1533,13 @@
|
|||
fingerprint = "DD52 6BC7 767D BA28 16C0 95E5 6840 89CE 67EB B691";
|
||||
}];
|
||||
};
|
||||
atalii = {
|
||||
email = "taliauster@gmail.com";
|
||||
github = "atalii";
|
||||
githubId = 120901234;
|
||||
name = "tali auster";
|
||||
matrix = "@atalii:matrix.org";
|
||||
};
|
||||
ataraxiasjel = {
|
||||
email = "nix@ataraxiadev.com";
|
||||
github = "AtaraxiaSjel";
|
||||
|
@ -1691,6 +1732,13 @@
|
|||
fingerprint = "2688 0377 C31D 9E81 9BDF 83A8 C8C6 BDDB 3847 F72B";
|
||||
}];
|
||||
};
|
||||
azazak123 = {
|
||||
email = "azazaka2002@gmail.com";
|
||||
matrix = "@ne_dvoeshnik:matrix.org";
|
||||
name = "Volodymyr Antonov";
|
||||
github = "azazak123";
|
||||
githubId = 50211158;
|
||||
};
|
||||
azd325 = {
|
||||
email = "tim.kleinschmidt@gmail.com";
|
||||
github = "Azd325";
|
||||
|
@ -1730,6 +1778,12 @@
|
|||
fingerprint = "6FBC A462 4EAF C69C A7C4 98C1 F044 3098 48A0 7CAC";
|
||||
}];
|
||||
};
|
||||
babeuh = {
|
||||
name = "Raphael Le Goaller";
|
||||
email = "babeuh@rlglr.fr";
|
||||
github = "babeuh";
|
||||
githubId = 60193302;
|
||||
};
|
||||
bachp = {
|
||||
email = "pascal.bach@nextrem.ch";
|
||||
matrix = "@bachp:matrix.org";
|
||||
|
@ -2554,7 +2608,7 @@
|
|||
};
|
||||
cafkafk = {
|
||||
email = "christina@cafkafk.com";
|
||||
matrix = "@cafkafk:m.cafkafk.com";
|
||||
matrix = "@cafkafk:nixos.dev";
|
||||
name = "Christina Sørensen";
|
||||
github = "cafkafk";
|
||||
githubId = 89321978;
|
||||
|
@ -2563,7 +2617,7 @@
|
|||
fingerprint = "7B9E E848 D074 AE03 7A0C 651A 8ED4 DEF7 375A 30C8";
|
||||
}
|
||||
{
|
||||
fingerprint = "208A 2A66 8A2F CDE7 B5D3 8F64 CDDC 792F 6552 51ED";
|
||||
fingerprint = "208A 2A66 8A2F CDE7 B5D3 8F64 CDDC 792F 6552 51ED";
|
||||
}
|
||||
];
|
||||
};
|
||||
|
@ -2737,6 +2791,12 @@
|
|||
githubId = 3471749;
|
||||
name = "Claudio Bley";
|
||||
};
|
||||
cbourjau = {
|
||||
email = "christianb@posteo.de";
|
||||
github = "cbourjau";
|
||||
githubId = 3288058;
|
||||
name = "Christian Bourjau";
|
||||
};
|
||||
cbrewster = {
|
||||
email = "cbrewster@hey.com";
|
||||
github = "cbrewster";
|
||||
|
@ -2765,6 +2825,13 @@
|
|||
githubId = 64804;
|
||||
name = "Dennis Gosnell";
|
||||
};
|
||||
cdmistman = {
|
||||
name = "Colton Donnelly";
|
||||
email = "colton@donn.io";
|
||||
matrix = "@donnellycolton:matrix.org";
|
||||
github = "cdmistman";
|
||||
githubId = 23486351;
|
||||
};
|
||||
ceedubs = {
|
||||
email = "ceedubs@gmail.com";
|
||||
github = "ceedubs";
|
||||
|
@ -3864,6 +3931,12 @@
|
|||
githubId = 75067;
|
||||
name = "Daniel Duan";
|
||||
};
|
||||
de11n = {
|
||||
email = "nixpkgs-commits@deshaw.com";
|
||||
github = "de11n";
|
||||
githubId = 130508846;
|
||||
name = "Elliot Cameron";
|
||||
};
|
||||
dearrude = {
|
||||
name = "Ebrahim Nejati";
|
||||
email = "dearrude@tfwno.gf";
|
||||
|
@ -4108,6 +4181,12 @@
|
|||
fingerprint = "1C4E F4FE 7F8E D8B7 1E88 CCDF BAB1 D15F B7B4 D4CE";
|
||||
}];
|
||||
};
|
||||
dgollings = {
|
||||
email = "daniel.gollings+nixpkgs@gmail.com";
|
||||
github = "dgollings";
|
||||
githubId = 2032823;
|
||||
name = "Daniel Gollings";
|
||||
};
|
||||
dgonyeo = {
|
||||
email = "derek@gonyeo.com";
|
||||
github = "dgonyeo";
|
||||
|
@ -4309,6 +4388,12 @@
|
|||
githubId = 10998835;
|
||||
name = "Doron Behar";
|
||||
};
|
||||
dotemup = {
|
||||
email = "dotemup.designs+nixpkgs@gmail.com";
|
||||
github = "dotemup";
|
||||
githubId = 11077277;
|
||||
name = "Dote";
|
||||
};
|
||||
dotlambda = {
|
||||
email = "rschuetz17@gmail.com";
|
||||
matrix = "@robert:funklause.de";
|
||||
|
@ -4400,6 +4485,13 @@
|
|||
fingerprint = "7E38 89D9 B1A8 B381 C8DE A15F 95EB 6DFF 26D1 CEB0";
|
||||
}];
|
||||
};
|
||||
DrSensor = {
|
||||
name = "Fahmi Akbar Wildana";
|
||||
email = "sensorfied@gmail.com";
|
||||
matrix = "@drsensor:matrix.org";
|
||||
github = "DrSensor";
|
||||
githubId = 4953069;
|
||||
};
|
||||
drupol = {
|
||||
name = "Pol Dellaiera";
|
||||
email = "pol.dellaiera@protonmail.com";
|
||||
|
@ -5312,6 +5404,12 @@
|
|||
githubId = 4246921;
|
||||
name = "Florian Beeres";
|
||||
};
|
||||
fd = {
|
||||
email = "simon.menke@gmail.com";
|
||||
github = "fd";
|
||||
githubId = 591;
|
||||
name = "Simon Menke";
|
||||
};
|
||||
fdns = {
|
||||
email = "fdns02@gmail.com";
|
||||
github = "fdns";
|
||||
|
@ -5601,6 +5699,12 @@
|
|||
githubId = 84968;
|
||||
name = "Florian Paul Schmidt";
|
||||
};
|
||||
fptje = {
|
||||
email = "fpeijnenburg@gmail.com";
|
||||
github = "FPtje";
|
||||
githubId = 1202014;
|
||||
name = "Falco Peijnenburg";
|
||||
};
|
||||
fragamus = {
|
||||
email = "innovative.engineer@gmail.com";
|
||||
github = "fragamus";
|
||||
|
@ -5756,6 +5860,11 @@
|
|||
githubId = 17859309;
|
||||
name = "Fuzen";
|
||||
};
|
||||
fwc = {
|
||||
github = "fwc";
|
||||
githubId = 29337229;
|
||||
name = "mtths";
|
||||
};
|
||||
fxfactorial = {
|
||||
email = "edgar.factorial@gmail.com";
|
||||
github = "fxfactorial";
|
||||
|
@ -5961,6 +6070,12 @@
|
|||
fingerprint = "D0CF 440A A703 E0F9 73CB A078 82BB 70D5 41AE 2DB4";
|
||||
}];
|
||||
};
|
||||
gerg-l = {
|
||||
email = "gregleyda@proton.me";
|
||||
github = "Gerg-L";
|
||||
githubId = 88247690;
|
||||
name = "Greg Leyda";
|
||||
};
|
||||
geri1701 = {
|
||||
email = "geri@sdf.org";
|
||||
github = "geri1701";
|
||||
|
@ -6011,6 +6126,15 @@
|
|||
githubId = 127353;
|
||||
name = "Geoffrey Huntley";
|
||||
};
|
||||
gigglesquid = {
|
||||
email = "jack.connors@protonmail.com";
|
||||
github = "gigglesquid";
|
||||
githubId = 3685154;
|
||||
name = "Jack connors";
|
||||
keys = [{
|
||||
fingerprint = "21DF 8034 B212 EDFF 9F19 9C19 F65B 7583 7ABF D019";
|
||||
}];
|
||||
};
|
||||
gila = {
|
||||
email = "jeffry.molanus@gmail.com";
|
||||
github = "gila";
|
||||
|
@ -6583,6 +6707,12 @@
|
|||
githubId = 41522204;
|
||||
name = "hexchen";
|
||||
};
|
||||
hexclover = {
|
||||
email = "hexclover@outlook.com";
|
||||
github = "hexclover";
|
||||
githubId = 47456195;
|
||||
name = "hexclover";
|
||||
};
|
||||
heyimnova = {
|
||||
email = "git@heyimnova.dev";
|
||||
github = "heyimnova";
|
||||
|
@ -7076,12 +7206,6 @@
|
|||
fingerprint = "F5B2 BE1B 9AAD 98FE 2916 5597 3665 FFF7 9D38 7BAA";
|
||||
}];
|
||||
};
|
||||
imsofi = {
|
||||
email = "sofi+git@mailbox.org";
|
||||
github = "imsofi";
|
||||
githubId = 20756843;
|
||||
name = "Sofi";
|
||||
};
|
||||
imuli = {
|
||||
email = "i@imu.li";
|
||||
github = "imuli";
|
||||
|
@ -7147,6 +7271,12 @@
|
|||
fingerprint = "5CB5 9AA0 D180 1997 2FB3 E0EC 943A 1DE9 372E BE4E";
|
||||
}];
|
||||
};
|
||||
invokes-su = {
|
||||
email = "nixpkgs-commits@deshaw.com";
|
||||
github = "invokes-su";
|
||||
githubId = 88038050;
|
||||
name = "Souvik Sen";
|
||||
};
|
||||
ionutnechita = {
|
||||
email = "ionut_n2001@yahoo.com";
|
||||
github = "ionutnechita";
|
||||
|
@ -7622,6 +7752,13 @@
|
|||
githubId = 1608697;
|
||||
name = "Jens Binkert";
|
||||
};
|
||||
jeremiahs = {
|
||||
email = "jeremiah@secrist.xyz";
|
||||
github = "JeremiahSecrist";
|
||||
githubId = 26032621;
|
||||
matrix = "@jeremiahs:matrix.org";
|
||||
name = "Jeremiah Secrist";
|
||||
};
|
||||
jeremyschlatter = {
|
||||
email = "github@jeremyschlatter.com";
|
||||
github = "jeremyschlatter";
|
||||
|
@ -8247,6 +8384,12 @@
|
|||
name = "John Soo";
|
||||
githubId = 10039785;
|
||||
};
|
||||
jtbx = {
|
||||
email = "jtbx@duck.com";
|
||||
name = "Jeremy Baxter";
|
||||
github = "jtbx";
|
||||
githubId = 92071952;
|
||||
};
|
||||
jtcoolen = {
|
||||
email = "jtcoolen@pm.me";
|
||||
name = "Julien Coolen";
|
||||
|
@ -8349,6 +8492,12 @@
|
|||
githubId = 662666;
|
||||
name = "Justinas Stankevičius";
|
||||
};
|
||||
justinlime = {
|
||||
email = "justinlime1999@gmail.com";
|
||||
github = "justinlime";
|
||||
githubId = 119710965;
|
||||
name = "Justin Fields";
|
||||
};
|
||||
justinlovinger = {
|
||||
email = "git@justinlovinger.com";
|
||||
github = "JustinLovinger";
|
||||
|
@ -8593,6 +8742,11 @@
|
|||
githubId = 762421;
|
||||
name = "Pierre Thierry";
|
||||
};
|
||||
keto = {
|
||||
github = "TheRealKeto";
|
||||
githubId = 24854941;
|
||||
name = "Keto";
|
||||
};
|
||||
ketzacoatl = {
|
||||
email = "ketzacoatl@protonmail.com";
|
||||
github = "ketzacoatl";
|
||||
|
@ -8631,6 +8785,12 @@
|
|||
githubId = 546087;
|
||||
name = "Kristoffer K. Føllesdal";
|
||||
};
|
||||
khaneliman = {
|
||||
email = "khaneliman12@gmail.com";
|
||||
github = "khaneliman";
|
||||
githubId = 1778670;
|
||||
name = "Austin Horstman";
|
||||
};
|
||||
khaser = {
|
||||
email = "a-horohorin@mail.ru";
|
||||
github = "khaser";
|
||||
|
@ -8866,6 +9026,12 @@
|
|||
githubId = 3287933;
|
||||
name = "Josef Kemetmüller";
|
||||
};
|
||||
knightpp = {
|
||||
email = "knightpp@proton.me";
|
||||
github = "knightpp";
|
||||
githubId = 28928944;
|
||||
name = "Danylo Kondratiev";
|
||||
};
|
||||
knl = {
|
||||
email = "nikola@knezevic.co";
|
||||
github = "knl";
|
||||
|
@ -8921,6 +9087,12 @@
|
|||
githubId = 524268;
|
||||
name = "Koral";
|
||||
};
|
||||
koralowiec = {
|
||||
email = "qnlgzyrw@anonaddy.me";
|
||||
github = "koralowiec";
|
||||
githubId = 36413794;
|
||||
name = "Arek Kalandyk";
|
||||
};
|
||||
koslambrou = {
|
||||
email = "koslambrou@gmail.com";
|
||||
github = "koslambrou";
|
||||
|
@ -9017,6 +9189,12 @@
|
|||
githubId = 5759930;
|
||||
name = "Alexis Destrez";
|
||||
};
|
||||
krupkat = {
|
||||
github = "krupkat";
|
||||
githubId = 6817216;
|
||||
name = "Tomas Krupka";
|
||||
matrix = "@krupkat:matrix.org";
|
||||
};
|
||||
ktf = {
|
||||
email = "giulio.eulisse@cern.ch";
|
||||
github = "ktf";
|
||||
|
@ -9091,6 +9269,12 @@
|
|||
fingerprint = "5A9A 1C9B 2369 8049 3B48 CF5B 81A1 5409 4816 2372";
|
||||
}];
|
||||
};
|
||||
l0b0 = {
|
||||
email = "victor@engmark.name";
|
||||
github = "l0b0";
|
||||
githubId = 168301;
|
||||
name = "Victor Engmark";
|
||||
};
|
||||
l3af = {
|
||||
email = "L3afMeAlon3@gmail.com";
|
||||
matrix = "@L3afMe:matrix.org";
|
||||
|
@ -9547,6 +9731,12 @@
|
|||
fingerprint = "1763 9903 2D7C 5B82 5D5A 0EAD A2BC 3C6F 1435 1991";
|
||||
}];
|
||||
};
|
||||
locochoco = {
|
||||
email = "contact@locochoco.dev";
|
||||
github = "loco-choco";
|
||||
githubId = 58634087;
|
||||
name = "Ivan Pancheniak";
|
||||
};
|
||||
lodi = {
|
||||
email = "anthony.lodi@gmail.com";
|
||||
github = "lodi";
|
||||
|
@ -9743,6 +9933,15 @@
|
|||
githubId = 1168435;
|
||||
name = "Ludovic Courtès";
|
||||
};
|
||||
ludovicopiero = {
|
||||
email = "ludovicopiero@pm.me";
|
||||
github = "ludovicopiero";
|
||||
githubId = 44255157;
|
||||
name = "Ludovico Piero";
|
||||
keys = [{
|
||||
fingerprint = "72CA 4F61 46C6 0DAB 6193 4D35 3911 DD27 6CFE 779C";
|
||||
}];
|
||||
};
|
||||
lufia = {
|
||||
email = "lufia@lufia.org";
|
||||
github = "lufia";
|
||||
|
@ -9770,6 +9969,15 @@
|
|||
githubId = 22085373;
|
||||
name = "Luis Hebendanz";
|
||||
};
|
||||
luisdaranda = {
|
||||
email = "luisdomingoaranda@gmail.com";
|
||||
github = "propet";
|
||||
githubId = 8515861;
|
||||
name = "Luis D. Aranda Sánchez";
|
||||
keys = [{
|
||||
fingerprint = "AB7C 81F4 9E07 CC64 F3E7 BC25 DCAC C6F4 AAFC C04E";
|
||||
}];
|
||||
};
|
||||
luisnquin = {
|
||||
email = "lpaandres2020@gmail.com";
|
||||
matrix = "@luisnquin:matrix.org";
|
||||
|
@ -9865,6 +10073,12 @@
|
|||
githubId = 782440;
|
||||
name = "Luna Nova";
|
||||
};
|
||||
lurkki = {
|
||||
email = "jussi.kuokkanen@protonmail.com";
|
||||
github = "Lurkki14";
|
||||
githubId = 44469719;
|
||||
name = "Jussi Kuokkanen";
|
||||
};
|
||||
lux = {
|
||||
email = "lux@lux.name";
|
||||
github = "luxzeitlos";
|
||||
|
@ -9976,6 +10190,16 @@
|
|||
githubId = 93990818;
|
||||
name = "Madoura";
|
||||
};
|
||||
maeve = {
|
||||
email = "mrey@mailbox.org";
|
||||
matrix = "@maeve:catgirl.cloud";
|
||||
github = "m-rey";
|
||||
githubId = 42996147;
|
||||
name = "Mæve";
|
||||
keys = [{
|
||||
fingerprint = "96C9 D086 CC9D 7BD7 EF24 80E2 9168 796A 1CC3 AEA2";
|
||||
}];
|
||||
};
|
||||
mafo = {
|
||||
email = "Marc.Fontaine@gmx.de";
|
||||
github = "MarcFontaine";
|
||||
|
@ -10132,6 +10356,13 @@
|
|||
githubId = 105451387;
|
||||
name = "Maria";
|
||||
};
|
||||
marie = {
|
||||
email = "tabmeier12+nix@gmail.com";
|
||||
github = "nycodeghg";
|
||||
githubId = 37078297;
|
||||
matrix = "@marie:marie.cologne";
|
||||
name = "Marie Ramlow";
|
||||
};
|
||||
marijanp = {
|
||||
name = "Marijan Petričević";
|
||||
email = "marijan.petricevic94@gmail.com";
|
||||
|
@ -10366,6 +10597,12 @@
|
|||
fingerprint = "CAEC A12D CE23 37A6 6DFD 17B0 7AC7 631D 70D6 C898";
|
||||
}];
|
||||
};
|
||||
max-amb = {
|
||||
email = "maxpeterambaum@gmail.com";
|
||||
github = "max-amb";
|
||||
githubId = 137820334;
|
||||
name = "Max Ambaum";
|
||||
};
|
||||
maxbrunet = {
|
||||
email = "max@brnt.mx";
|
||||
github = "maxbrunet";
|
||||
|
@ -10509,12 +10746,6 @@
|
|||
githubId = 10420834;
|
||||
name = "Mihai-Drosi Caju";
|
||||
};
|
||||
mcbeth = {
|
||||
email = "mcbeth@broggs.org";
|
||||
github = "mcbeth";
|
||||
githubId = 683809;
|
||||
name = "Jeffrey Brent McBeth";
|
||||
};
|
||||
mccurdyc = {
|
||||
email = "mccurdyc22@gmail.com";
|
||||
github = "mccurdyc";
|
||||
|
@ -10718,6 +10949,16 @@
|
|||
fingerprint = "8CE3 2906 516F C4D8 D373 308A E189 648A 55F5 9A9F";
|
||||
}];
|
||||
};
|
||||
mib = {
|
||||
name = "mib";
|
||||
email = "mib@kanp.ai";
|
||||
matrix = "@mib:kanp.ai";
|
||||
github = "mibmo";
|
||||
githubId = 87388017;
|
||||
keys = [{
|
||||
fingerprint = "AB0D C647 B2F7 86EB 045C 7EFE CF6E 67DE D6DC 1E3F";
|
||||
}];
|
||||
};
|
||||
mic92 = {
|
||||
email = "joerg@thalheim.io";
|
||||
matrix = "@mic92:nixos.dev";
|
||||
|
@ -10814,6 +11055,12 @@
|
|||
fingerprint = "FEF0 AE2D 5449 3482 5F06 40AA 186A 1EDA C5C6 3F83";
|
||||
}];
|
||||
};
|
||||
mig4ng = {
|
||||
email = "mig4ng@gmail.com";
|
||||
github = "mig4ng";
|
||||
githubId = 5817039;
|
||||
name = "Miguel Carneiro";
|
||||
};
|
||||
mightyiam = {
|
||||
email = "mightyiampresence@gmail.com";
|
||||
github = "mightyiam";
|
||||
|
@ -11300,6 +11547,12 @@
|
|||
name = "Maxim Schuwalow";
|
||||
email = "maxim.schuwalow@gmail.com";
|
||||
};
|
||||
mschwaig = {
|
||||
name = "Martin Schwaighofer";
|
||||
github = "mschwaig";
|
||||
githubId = 3856390;
|
||||
email = "mschwaig+nixpkgs@eml.cc";
|
||||
};
|
||||
msfjarvis = {
|
||||
github = "msfjarvis";
|
||||
githubId = 13348378;
|
||||
|
@ -14179,6 +14432,12 @@
|
|||
githubId = 1069318;
|
||||
name = "Robin Lambertz";
|
||||
};
|
||||
robwalt = {
|
||||
email = "robwalter96@gmail.com";
|
||||
github = "robwalt";
|
||||
githubId = 26892280;
|
||||
name = "Robert Walter";
|
||||
};
|
||||
roconnor = {
|
||||
email = "roconnor@theorem.ca";
|
||||
github = "roconnor";
|
||||
|
@ -14303,6 +14562,15 @@
|
|||
}];
|
||||
name = "Rahul Butani";
|
||||
};
|
||||
rs0vere = {
|
||||
email = "rs0vere@outlook.com";
|
||||
github = "rs0vere";
|
||||
githubId = 140035635;
|
||||
keys = [{
|
||||
fingerprint = "C6D8 B5C2 FA79 901B DCCF 95E1 FEC4 5C5A ED00 C58D";
|
||||
}];
|
||||
name = "Red Star Over Earth";
|
||||
};
|
||||
rski = {
|
||||
name = "rski";
|
||||
email = "rom.skiad+nix@gmail.com";
|
||||
|
@ -14416,6 +14684,12 @@
|
|||
githubId = 889991;
|
||||
name = "Ryan Artecona";
|
||||
};
|
||||
ryanccn = {
|
||||
email = "hello@ryanccn.dev";
|
||||
github = "ryanccn";
|
||||
githubId = 70191398;
|
||||
name = "Ryan Cao";
|
||||
};
|
||||
ryane = {
|
||||
email = "ryanesc@gmail.com";
|
||||
github = "ryane";
|
||||
|
@ -14470,6 +14744,12 @@
|
|||
githubId = 3280280;
|
||||
name = "Ryne Everett";
|
||||
};
|
||||
ryota-ka = {
|
||||
email = "ok@ryota-ka.me";
|
||||
github = "ryota-ka";
|
||||
githubId = 7309170;
|
||||
name = "Ryota Kameoka";
|
||||
};
|
||||
rytone = {
|
||||
email = "max@ryt.one";
|
||||
github = "rastertail";
|
||||
|
@ -14875,6 +15155,16 @@
|
|||
githubId = 4805746;
|
||||
name = "Sebastian Jordan";
|
||||
};
|
||||
septem9er = {
|
||||
name = "Septem9er";
|
||||
email = "develop@septem9er.de";
|
||||
matrix = "@septem9er:fairydust.space";
|
||||
github = "septem9er";
|
||||
githubId = 33379902;
|
||||
keys = [{
|
||||
fingerprint = "C408 07F9 8677 3D98 EFF3 0980 355A 9AFB FD8E AD33";
|
||||
}];
|
||||
};
|
||||
seqizz = {
|
||||
email = "seqizz@gmail.com";
|
||||
github = "seqizz";
|
||||
|
@ -15279,6 +15569,12 @@
|
|||
githubId = 3789764;
|
||||
name = "skykanin";
|
||||
};
|
||||
slbtty = {
|
||||
email = "shenlebantongying@gmail.com";
|
||||
github = "shenlebantongying";
|
||||
githubId = 20123683;
|
||||
name = "Shenleban Tongying";
|
||||
};
|
||||
sleexyz = {
|
||||
email = "freshdried@gmail.com";
|
||||
github = "sleexyz";
|
||||
|
@ -15456,6 +15752,12 @@
|
|||
githubId = 6277322;
|
||||
name = "Wei Tang";
|
||||
};
|
||||
soupglasses = {
|
||||
email = "sofi+git@mailbox.org";
|
||||
github = "soupglasses";
|
||||
githubId = 20756843;
|
||||
name = "Sofi";
|
||||
};
|
||||
soywod = {
|
||||
name = "Clément DOUIN";
|
||||
email = "clement.douin@posteo.net";
|
||||
|
@ -15478,6 +15780,12 @@
|
|||
githubId = 7669898;
|
||||
name = "Katharina Fey";
|
||||
};
|
||||
spalf = {
|
||||
email = "tom@tombarrett.xyz";
|
||||
name = "tom barrett";
|
||||
github = "70m6";
|
||||
githubId = 105207964;
|
||||
};
|
||||
spease = {
|
||||
email = "peasteven@gmail.com";
|
||||
github = "spease";
|
||||
|
@ -15509,6 +15817,12 @@
|
|||
githubId = 6391601;
|
||||
name = "Roger Mason";
|
||||
};
|
||||
sputn1ck = {
|
||||
email = "kon@kon.ninja";
|
||||
github = "sputn1ck";
|
||||
githubId = 8904314;
|
||||
name = "Konstantin Nick";
|
||||
};
|
||||
squalus = {
|
||||
email = "squalus@squalus.net";
|
||||
github = "squalus";
|
||||
|
@ -15545,6 +15859,13 @@
|
|||
githubId = 219362;
|
||||
name = "Sarah Brofeldt";
|
||||
};
|
||||
srid = {
|
||||
email = "srid@srid.ca";
|
||||
matrix = "@srid:matrix.org";
|
||||
github = "srid";
|
||||
githubId = 3998;
|
||||
name = "Sridhar Ratnakumar";
|
||||
};
|
||||
srounce = {
|
||||
name = "Samuel Rounce";
|
||||
email = "me@samuelrounce.co.uk";
|
||||
|
@ -15813,6 +16134,12 @@
|
|||
githubId = 16734772;
|
||||
name = "Sumner Evans";
|
||||
};
|
||||
sund3RRR = {
|
||||
email = "evenquantity@gmail.com";
|
||||
github = "sund3RRR";
|
||||
githubId = 73298492;
|
||||
name = "Mikhail Kiselev";
|
||||
};
|
||||
suominen = {
|
||||
email = "kimmo@suominen.com";
|
||||
github = "suominen";
|
||||
|
@ -16714,6 +17041,14 @@
|
|||
githubId = 8577941;
|
||||
name = "Kevin Rauscher";
|
||||
};
|
||||
tomasajt = {
|
||||
github = "TomaSajt";
|
||||
githubId = 62384384;
|
||||
name = "TomaSajt";
|
||||
keys = [{
|
||||
fingerprint = "8CA9 8016 F44D B717 5B44 6032 F011 163C 0501 22A1";
|
||||
}];
|
||||
};
|
||||
tomaskala = {
|
||||
email = "public+nixpkgs@tomaskala.com";
|
||||
github = "tomaskala";
|
||||
|
@ -16990,6 +17325,12 @@
|
|||
matrix = "@ty:tjll.net";
|
||||
name = "Tyler Langlois";
|
||||
};
|
||||
tymscar = {
|
||||
email = "oscar@tymscar.com";
|
||||
github = "tymscar";
|
||||
githubId = 3742502;
|
||||
name = "Oscar Molnar";
|
||||
};
|
||||
typetetris = {
|
||||
email = "ericwolf42@mail.com";
|
||||
github = "typetetris";
|
||||
|
@ -17350,6 +17691,12 @@
|
|||
fingerprint = "AEF2 3487 66F3 71C6 89A7 3600 95A4 2FE8 3535 25F9";
|
||||
}];
|
||||
};
|
||||
vinetos = {
|
||||
name = "vinetos";
|
||||
email = "vinetosdev@gmail.com";
|
||||
github = "vinetos";
|
||||
githubId = 10145351;
|
||||
};
|
||||
vinnymeller = {
|
||||
email = "vinnymeller@proton.me";
|
||||
github = "vinnymeller";
|
||||
|
@ -17453,6 +17800,12 @@
|
|||
githubId = 3413119;
|
||||
name = "Vonfry";
|
||||
};
|
||||
votava = {
|
||||
email = "votava@gmail.com";
|
||||
github = "janvotava";
|
||||
githubId = 367185;
|
||||
name = "Jan Votava";
|
||||
};
|
||||
vq = {
|
||||
email = "vq@erq.se";
|
||||
github = "vq";
|
||||
|
@ -18036,6 +18389,12 @@
|
|||
githubId = 73759599;
|
||||
name = "Yaya";
|
||||
};
|
||||
yboettcher = {
|
||||
name = "Yannik Böttcher";
|
||||
github = "yboettcher";
|
||||
githubId = 39460066;
|
||||
email = "yannikboettcher@outlook.de";
|
||||
};
|
||||
ydlr = {
|
||||
name = "ydlr";
|
||||
email = "ydlr@ydlr.io";
|
||||
|
@ -18106,6 +18465,12 @@
|
|||
github = "ymeister";
|
||||
githubId = 47071325;
|
||||
};
|
||||
yoavlavi = {
|
||||
email = "yoav@yoavlavi.com";
|
||||
github = "yoav-lavi";
|
||||
githubId = 14347895;
|
||||
name = "Yoav Lavi";
|
||||
};
|
||||
yochai = {
|
||||
email = "yochai@titat.info";
|
||||
github = "yochai";
|
||||
|
@ -18355,12 +18720,6 @@
|
|||
github = "zfnmxt";
|
||||
githubId = 37446532;
|
||||
};
|
||||
zgrannan = {
|
||||
email = "zgrannan@gmail.com";
|
||||
github = "zgrannan";
|
||||
githubId = 1141948;
|
||||
name = "Zack Grannan";
|
||||
};
|
||||
zhaofengli = {
|
||||
email = "hello@zhaofeng.li";
|
||||
matrix = "@zhaofeng:zhaofeng.li";
|
||||
|
@ -18392,6 +18751,19 @@
|
|||
githubId = 1108325;
|
||||
name = "Théo Zimmermann";
|
||||
};
|
||||
zmitchell = {
|
||||
name = "Zach Mitchell";
|
||||
email = "zmitchell@fastmail.com";
|
||||
matrix = "@zmitchell:matrix.org";
|
||||
github = "zmitchell";
|
||||
githubId = 10246891;
|
||||
};
|
||||
znewman01 = {
|
||||
email = "znewman01@gmail.com";
|
||||
github = "znewman01";
|
||||
githubId = 873857;
|
||||
name = "Zack Newman";
|
||||
};
|
||||
zoedsoupe = {
|
||||
github = "zoedsoupe";
|
||||
githubId = 44469426;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#! /usr/bin/env nix-shell
|
||||
#! nix-shell -i bash -p nix curl jq nix-prefetch-github git gnused -I nixpkgs=.
|
||||
#! nix-shell -i bash -p nix curl jq git gnused -I nixpkgs=.
|
||||
|
||||
# See regenerate-hackage-packages.sh for details on the purpose of this script.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#! /usr/bin/env nix-shell
|
||||
#! nix-shell -i bash -p nix curl jq nix-prefetch-github git gnused gnugrep -I nixpkgs=.
|
||||
#! nix-shell -i bash -p nix curl jq git gnused gnugrep -I nixpkgs=.
|
||||
# shellcheck shell=bash
|
||||
|
||||
set -eu -o pipefail
|
||||
|
|
|
@ -86,6 +86,7 @@ luuid,,,,,,
|
|||
luv,,,,1.44.2-1,,
|
||||
lush.nvim,https://github.com/rktjmp/lush.nvim,,,,,teto
|
||||
lyaml,,,,,,lblasc
|
||||
magick,,,,,,donovanglover
|
||||
markdown,,,,,,
|
||||
mediator_lua,,,,,,
|
||||
mpack,,,,,,
|
||||
|
|
|
18
third_party/nixpkgs/maintainers/team-list.nix
vendored
18
third_party/nixpkgs/maintainers/team-list.nix
vendored
|
@ -193,10 +193,11 @@ with lib.maintainers; {
|
|||
deshaw = {
|
||||
# Verify additions to this team with at least one already existing member of the team.
|
||||
members = [
|
||||
limeytexan
|
||||
de11n
|
||||
invokes-su
|
||||
];
|
||||
scope = "Group registration for D. E. Shaw employees who collectively maintain packages.";
|
||||
shortName = "Shaw employees";
|
||||
shortName = "D. E. Shaw employees";
|
||||
};
|
||||
|
||||
determinatesystems = {
|
||||
|
@ -410,6 +411,14 @@ with lib.maintainers; {
|
|||
shortName = "Jitsi";
|
||||
};
|
||||
|
||||
jupyter = {
|
||||
members = [
|
||||
natsukium
|
||||
];
|
||||
scope = "Maintain Jupyter and related packages.";
|
||||
shortName = "Jupyter";
|
||||
};
|
||||
|
||||
kubernetes = {
|
||||
members = [
|
||||
johanot
|
||||
|
@ -570,6 +579,7 @@ with lib.maintainers; {
|
|||
ralith
|
||||
dandellion
|
||||
sumnerevans
|
||||
nickcao
|
||||
];
|
||||
scope = "Maintain the ecosystem around Matrix, a decentralized messenger.";
|
||||
shortName = "Matrix";
|
||||
|
@ -820,9 +830,7 @@ with lib.maintainers; {
|
|||
};
|
||||
|
||||
sphinx = {
|
||||
members = [
|
||||
SuperSandro2000
|
||||
];
|
||||
members = [ ];
|
||||
scope = "Maintain Sphinx related packages.";
|
||||
shortName = "Sphinx";
|
||||
};
|
||||
|
|
4
third_party/nixpkgs/nixos/doc/manual/common.nix
vendored
Normal file
4
third_party/nixpkgs/nixos/doc/manual/common.nix
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
outputPath = "share/doc/nixos";
|
||||
indexPath = "index.html";
|
||||
}
|
|
@ -11,6 +11,8 @@ $ nix-build nixos/release.nix -A manual.x86_64-linux
|
|||
|
||||
If the build succeeds, the manual will be in `./result/share/doc/nixos/index.html`.
|
||||
|
||||
There's also [a convenient development daemon](https://nixos.org/manual/nixpkgs/unstable/#sec-contributing-devmode).
|
||||
|
||||
**Contributing to the man pages**
|
||||
|
||||
The man pages are written in [DocBook] which is XML.
|
||||
|
|
21
third_party/nixpkgs/nixos/doc/manual/default.nix
vendored
21
third_party/nixpkgs/nixos/doc/manual/default.nix
vendored
|
@ -16,6 +16,8 @@ let
|
|||
|
||||
lib = pkgs.lib;
|
||||
|
||||
common = import ./common.nix;
|
||||
|
||||
manpageUrls = pkgs.path + "/doc/manpage-urls.json";
|
||||
|
||||
# We need to strip references to /nix/store/* from options,
|
||||
|
@ -63,6 +65,9 @@ let
|
|||
optionIdPrefix = "test-opt-";
|
||||
};
|
||||
|
||||
testDriverMachineDocstrings = pkgs.callPackage
|
||||
../../../nixos/lib/test-driver/nixos-test-driver-docstrings.nix {};
|
||||
|
||||
prepareManualFromMD = ''
|
||||
cp -r --no-preserve=all $inputs/* .
|
||||
|
||||
|
@ -75,11 +80,13 @@ let
|
|||
substituteInPlace ./nixos-options.md \
|
||||
--replace \
|
||||
'@NIXOS_OPTIONS_JSON@' \
|
||||
${optionsDoc.optionsJSON}/share/doc/nixos/options.json
|
||||
${optionsDoc.optionsJSON}/${common.outputPath}/options.json
|
||||
substituteInPlace ./development/writing-nixos-tests.section.md \
|
||||
--replace \
|
||||
'@NIXOS_TEST_OPTIONS_JSON@' \
|
||||
${testOptionsDoc.optionsJSON}/share/doc/nixos/options.json
|
||||
${testOptionsDoc.optionsJSON}/${common.outputPath}/options.json
|
||||
sed -e '/@PYTHON_MACHINE_METHODS@/ {' -e 'r ${testDriverMachineDocstrings}/machine-methods.md' -e 'd' -e '}' \
|
||||
-i ./development/writing-nixos-tests.section.md
|
||||
'';
|
||||
|
||||
in rec {
|
||||
|
@ -94,7 +101,7 @@ in rec {
|
|||
}
|
||||
''
|
||||
# Generate the HTML manual.
|
||||
dst=$out/share/doc/nixos
|
||||
dst=$out/${common.outputPath}
|
||||
mkdir -p $dst
|
||||
|
||||
cp ${../../../doc/style.css} $dst/style.css
|
||||
|
@ -115,7 +122,7 @@ in rec {
|
|||
--toc-depth 1 \
|
||||
--chunk-toc-depth 1 \
|
||||
./manual.md \
|
||||
$dst/index.html
|
||||
$dst/${common.indexPath}
|
||||
|
||||
mkdir -p $out/nix-support
|
||||
echo "nix-build out $out" >> $out/nix-support/hydra-build-products
|
||||
|
@ -126,7 +133,7 @@ in rec {
|
|||
manual = manualHTML;
|
||||
|
||||
# Index page of the NixOS manual.
|
||||
manualHTMLIndex = "${manualHTML}/share/doc/nixos/index.html";
|
||||
manualHTMLIndex = "${manualHTML}/${common.outputPath}/${common.indexPath}";
|
||||
|
||||
manualEpub = runCommand "nixos-manual-epub"
|
||||
{ nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin buildPackages.zip ];
|
||||
|
@ -157,7 +164,7 @@ in rec {
|
|||
}
|
||||
''
|
||||
# Generate the epub manual.
|
||||
dst=$out/share/doc/nixos
|
||||
dst=$out/${common.outputPath}
|
||||
|
||||
xsltproc \
|
||||
--param chapter.autolabel 0 \
|
||||
|
@ -192,7 +199,7 @@ in rec {
|
|||
mkdir -p $out/share/man/man5
|
||||
nixos-render-docs -j $NIX_BUILD_CORES options manpage \
|
||||
--revision ${lib.escapeShellArg revision} \
|
||||
${optionsJSON}/share/doc/nixos/options.json \
|
||||
${optionsJSON}/${common.outputPath}/options.json \
|
||||
$out/share/man/man5/configuration.nix.5
|
||||
'';
|
||||
|
||||
|
|
|
@ -139,210 +139,7 @@ to Python as `machine_a`.
|
|||
|
||||
The following methods are available on machine objects:
|
||||
|
||||
`start`
|
||||
|
||||
: Start the virtual machine. This method is asynchronous --- it does
|
||||
not wait for the machine to finish booting.
|
||||
|
||||
`shutdown`
|
||||
|
||||
: Shut down the machine, waiting for the VM to exit.
|
||||
|
||||
`crash`
|
||||
|
||||
: Simulate a sudden power failure, by telling the VM to exit
|
||||
immediately.
|
||||
|
||||
`block`
|
||||
|
||||
: Simulate unplugging the Ethernet cable that connects the machine to
|
||||
the other machines.
|
||||
|
||||
`unblock`
|
||||
|
||||
: Undo the effect of `block`.
|
||||
|
||||
`screenshot`
|
||||
|
||||
: Take a picture of the display of the virtual machine, in PNG format.
|
||||
The screenshot is linked from the HTML log.
|
||||
|
||||
`get_screen_text_variants`
|
||||
|
||||
: Return a list of different interpretations of what is currently
|
||||
visible on the machine's screen using optical character
|
||||
recognition. The number and order of the interpretations is not
|
||||
specified and is subject to change, but if no exception is raised at
|
||||
least one will be returned.
|
||||
|
||||
::: {.note}
|
||||
This requires [`enableOCR`](#test-opt-enableOCR) to be set to `true`.
|
||||
:::
|
||||
|
||||
`get_screen_text`
|
||||
|
||||
: Return a textual representation of what is currently visible on the
|
||||
machine's screen using optical character recognition.
|
||||
|
||||
::: {.note}
|
||||
This requires [`enableOCR`](#test-opt-enableOCR) to be set to `true`.
|
||||
:::
|
||||
|
||||
`send_monitor_command`
|
||||
|
||||
: Send a command to the QEMU monitor. This is rarely used, but allows
|
||||
doing stuff such as attaching virtual USB disks to a running
|
||||
machine.
|
||||
|
||||
`send_key`
|
||||
|
||||
: Simulate pressing keys on the virtual keyboard, e.g.,
|
||||
`send_key("ctrl-alt-delete")`.
|
||||
|
||||
`send_chars`
|
||||
|
||||
: Simulate typing a sequence of characters on the virtual keyboard,
|
||||
e.g., `send_chars("foobar\n")` will type the string `foobar`
|
||||
followed by the Enter key.
|
||||
|
||||
`send_console`
|
||||
|
||||
: Send keys to the kernel console. This allows interaction with the systemd
|
||||
emergency mode, for example. Takes a string that is sent, e.g.,
|
||||
`send_console("\n\nsystemctl default\n")`.
|
||||
|
||||
`execute`
|
||||
|
||||
: Execute a shell command, returning a list `(status, stdout)`.
|
||||
|
||||
Commands are run with `set -euo pipefail` set:
|
||||
|
||||
- If several commands are separated by `;` and one fails, the
|
||||
command as a whole will fail.
|
||||
|
||||
- For pipelines, the last non-zero exit status will be returned
|
||||
(if there is one; otherwise zero will be returned).
|
||||
|
||||
- Dereferencing unset variables fails the command.
|
||||
|
||||
- It will wait for stdout to be closed.
|
||||
|
||||
If the command detaches, it must close stdout, as `execute` will wait
|
||||
for this to consume all output reliably. This can be achieved by
|
||||
redirecting stdout to stderr `>&2`, to `/dev/console`, `/dev/null` or
|
||||
a file. Examples of detaching commands are `sleep 365d &`, where the
|
||||
shell forks a new process that can write to stdout and `xclip -i`, where
|
||||
the `xclip` command itself forks without closing stdout.
|
||||
|
||||
Takes an optional parameter `check_return` that defaults to `True`.
|
||||
Setting this parameter to `False` will not check for the return code
|
||||
and return -1 instead. This can be used for commands that shut down
|
||||
the VM and would therefore break the pipe that would be used for
|
||||
retrieving the return code.
|
||||
|
||||
A timeout for the command can be specified (in seconds) using the optional
|
||||
`timeout` parameter, e.g., `execute(cmd, timeout=10)` or
|
||||
`execute(cmd, timeout=None)`. The default is 900 seconds.
|
||||
|
||||
`succeed`
|
||||
|
||||
: Execute a shell command, raising an exception if the exit status is
|
||||
not zero, otherwise returning the standard output. Similar to `execute`,
|
||||
except that the timeout is `None` by default. See `execute` for details on
|
||||
command execution.
|
||||
|
||||
`fail`
|
||||
|
||||
: Like `succeed`, but raising an exception if the command returns a zero
|
||||
status.
|
||||
|
||||
`wait_until_succeeds`
|
||||
|
||||
: Repeat a shell command with 1-second intervals until it succeeds.
|
||||
Has a default timeout of 900 seconds which can be modified, e.g.
|
||||
`wait_until_succeeds(cmd, timeout=10)`. See `execute` for details on
|
||||
command execution.
|
||||
|
||||
`wait_until_fails`
|
||||
|
||||
: Like `wait_until_succeeds`, but repeating the command until it fails.
|
||||
|
||||
`wait_for_unit`
|
||||
|
||||
: Wait until the specified systemd unit has reached the "active"
|
||||
state.
|
||||
|
||||
`wait_for_file`
|
||||
|
||||
: Wait until the specified file exists.
|
||||
|
||||
`wait_for_open_port`
|
||||
|
||||
: Wait until a process is listening on the given TCP port and IP address
|
||||
(default `localhost`).
|
||||
|
||||
`wait_for_closed_port`
|
||||
|
||||
: Wait until nobody is listening on the given TCP port and IP address
|
||||
(default `localhost`).
|
||||
|
||||
`wait_for_x`
|
||||
|
||||
: Wait until the X11 server is accepting connections.
|
||||
|
||||
`wait_for_text`
|
||||
|
||||
: Wait until the supplied regular expressions matches the textual
|
||||
contents of the screen by using optical character recognition (see
|
||||
`get_screen_text` and `get_screen_text_variants`).
|
||||
|
||||
::: {.note}
|
||||
This requires [`enableOCR`](#test-opt-enableOCR) to be set to `true`.
|
||||
:::
|
||||
|
||||
`wait_for_console_text`
|
||||
|
||||
: Wait until the supplied regular expressions match a line of the
|
||||
serial console output. This method is useful when OCR is not
|
||||
possible or accurate enough.
|
||||
|
||||
`wait_for_window`
|
||||
|
||||
: Wait until an X11 window has appeared whose name matches the given
|
||||
regular expression, e.g., `wait_for_window("Terminal")`.
|
||||
|
||||
`copy_from_host`
|
||||
|
||||
: Copies a file from host to machine, e.g.,
|
||||
`copy_from_host("myfile", "/etc/my/important/file")`.
|
||||
|
||||
The first argument is the file on the host. The file needs to be
|
||||
accessible while building the nix derivation. The second argument is
|
||||
the location of the file on the machine.
|
||||
|
||||
`systemctl`
|
||||
|
||||
: Runs `systemctl` commands with optional support for
|
||||
`systemctl --user`
|
||||
|
||||
```py
|
||||
machine.systemctl("list-jobs --no-pager") # runs `systemctl list-jobs --no-pager`
|
||||
machine.systemctl("list-jobs --no-pager", "any-user") # spawns a shell for `any-user` and runs `systemctl --user list-jobs --no-pager`
|
||||
```
|
||||
|
||||
`shell_interact`
|
||||
|
||||
: Allows you to directly interact with the guest shell. This should
|
||||
only be used during test development, not in production tests.
|
||||
Killing the interactive session with `Ctrl-d` or `Ctrl-c` also ends
|
||||
the guest session.
|
||||
|
||||
`console_interact`
|
||||
|
||||
: Allows you to directly interact with QEMU's stdin. This should
|
||||
only be used during test development, not in production tests.
|
||||
Output from QEMU is only read line-wise. `Ctrl-c` kills QEMU and
|
||||
`Ctrl-d` closes console and returns to the test runner.
|
||||
@PYTHON_MACHINE_METHODS@
|
||||
|
||||
To test user units declared by `systemd.user.services` the optional
|
||||
`user` argument can be used:
|
||||
|
|
|
@ -249,14 +249,14 @@ update /etc/fstab.
|
|||
which will be used by the boot partition.
|
||||
|
||||
```ShellSession
|
||||
# parted /dev/sda -- mkpart primary 512MB -8GB
|
||||
# parted /dev/sda -- mkpart root ext4 512MB -8GB
|
||||
```
|
||||
|
||||
3. Next, add a *swap* partition. The size required will vary according
|
||||
to needs, here a 8GB one is created.
|
||||
|
||||
```ShellSession
|
||||
# parted /dev/sda -- mkpart primary linux-swap -8GB 100%
|
||||
# parted /dev/sda -- mkpart swap linux-swap -8GB 100%
|
||||
```
|
||||
|
||||
::: {.note}
|
||||
|
@ -550,8 +550,8 @@ corresponding configuration Nix expression.
|
|||
### Example partition schemes for NixOS on `/dev/sda` (UEFI)
|
||||
```ShellSession
|
||||
# parted /dev/sda -- mklabel gpt
|
||||
# parted /dev/sda -- mkpart primary 512MB -8GB
|
||||
# parted /dev/sda -- mkpart primary linux-swap -8GB 100%
|
||||
# parted /dev/sda -- mkpart root ext4 512MB -8GB
|
||||
# parted /dev/sda -- mkpart swap linux-swap -8GB 100%
|
||||
# parted /dev/sda -- mkpart ESP fat32 1MB 512MB
|
||||
# parted /dev/sda -- set 3 esp on
|
||||
```
|
||||
|
|
|
@ -83,6 +83,8 @@ In addition to numerous new and updated packages, this release has the following
|
|||
|
||||
- [gitea-actions-runner](https://gitea.com/gitea/act_runner), a CI runner for Gitea/Forgejo Actions. Available as [services.gitea-actions-runner](#opt-services.gitea-actions-runner.instances).
|
||||
|
||||
- [evdevremapkeys](https://github.com/philipl/evdevremapkeys), a daemon to remap key events. Available as [services.evdevremapkeys](#opt-services.evdevremapkeys.enable).
|
||||
|
||||
- [gmediarender](https://github.com/hzeller/gmrender-resurrect), a simple, headless UPnP/DLNA renderer. Available as [services.gmediarender](options.html#opt-services.gmediarender.enable).
|
||||
|
||||
- [go2rtc](https://github.com/AlexxIT/go2rtc), a camera streaming appliation with support for RTSP, WebRTC, HomeKit, FFMPEG, RTMP and other protocols. Available as [services.go2rtc](options.html#opt-services.go2rtc.enable).
|
||||
|
|
|
@ -16,16 +16,30 @@
|
|||
|
||||
- [river](https://github.com/riverwm/river), A dynamic tiling wayland compositor. Available as [programs.river](#opt-programs.river.enable).
|
||||
|
||||
- [wayfire](https://wayfire.org), A modular and extensible wayland compositor. Available as [programs.wayfire](#opt-programs.wayfire.enable).
|
||||
|
||||
- [GoToSocial](https://gotosocial.org/), an ActivityPub social network server, written in Golang. Available as [services.gotosocial](#opt-services.gotosocial.enable).
|
||||
|
||||
- [Typesense](https://github.com/typesense/typesense), a fast, typo-tolerant search engine for building delightful search experiences. Available as [services.typesense](#opt-services.typesense.enable).
|
||||
|
||||
* [NS-USBLoader](https://github.com/developersu/ns-usbloader/), an all-in-one tool for managing Nintendo Switch homebrew. Available as [programs.ns-usbloader](#opt-programs.ns-usbloader.enable).
|
||||
|
||||
- [Anuko Time Tracker](https://github.com/anuko/timetracker), a simple, easy to use, open source time tracking system. Available as [services.anuko-time-tracker](#opt-services.anuko-time-tracker.enable).
|
||||
|
||||
- [sitespeed-io](https://sitespeed.io), a tool that can generate metrics (timings, diagnostics) for websites. Available as [services.sitespeed-io](#opt-services.sitespeed-io.enable).
|
||||
|
||||
- [Apache Guacamole](https://guacamole.apache.org/), a cross-platform, clientless remote desktop gateway. Available as [services.guacamole-server](#opt-services.guacamole-server.enable) and [services.guacamole-client](#opt-services.guacamole-client.enable) services.
|
||||
|
||||
- [pgBouncer](https://www.pgbouncer.org), a PostgreSQL connection pooler. Available as [services.pgbouncer](#opt-services.pgbouncer.enable).
|
||||
|
||||
- [trust-dns](https://trust-dns.org/), a Rust based DNS server built to be safe and secure from the ground up. Available as [services.trust-dns](#opt-services.trust-dns.enable).
|
||||
|
||||
- [osquery](https://www.osquery.io/), a SQL powered operating system instrumentation, monitoring, and analytics.
|
||||
|
||||
- [ebusd](https://ebusd.eu), a daemon for handling communication with eBUS devices connected to a 2-wire bus system (“energy bus” used by numerous heating systems). Available as [services.ebusd](#opt-services.ebusd.enable).
|
||||
|
||||
- [systemd-sysupdate](https://www.freedesktop.org/software/systemd/man/systemd-sysupdate.html), atomically updates the host OS, container images, portable service images or other sources. Available as [systemd.sysupdate](opt-systemd.sysupdate).
|
||||
|
||||
## Backward Incompatibilities {#sec-release-23.11-incompatibilities}
|
||||
|
||||
- The `boot.loader.raspberryPi` options have been marked deprecated, with intent for removal for NixOS 24.11. They had a limited use-case, and do not work like people expect. They required either very old installs ([before mid-2019](https://github.com/NixOS/nixpkgs/pull/62462)) or customized builds out of scope of the standard and generic AArch64 support. That option set never supported the Raspberry Pi 4 family of devices.
|
||||
|
@ -62,6 +76,8 @@
|
|||
|
||||
- PHP now defaults to PHP 8.2, updated from 8.1.
|
||||
|
||||
- The ISC DHCP package and corresponding module have been removed, because they are end of life upstream. See https://www.isc.org/blogs/isc-dhcp-eol/ for details and switch to a different DHCP implementation like kea or dnsmasq.
|
||||
|
||||
- `util-linux` is now supported on Darwin and is no longer an alias to `unixtools`. Use the `unixtools.util-linux` package for access to the Apple variants of the utilities.
|
||||
|
||||
- `services.keyd` changed API. Now you can create multiple configuration files.
|
||||
|
@ -86,12 +102,20 @@
|
|||
|
||||
- `services.outline.sequelizeArguments` has been removed, as `outline` no longer executes database migrations via the `sequelize` cli.
|
||||
|
||||
- The binary of the package `cloud-sql-proxy` has changed from `cloud_sql_proxy` to `cloud-sql-proxy`.
|
||||
|
||||
- The `woodpecker-*` CI packages have been updated to 1.0.0. This release is wildly incompatible with the 0.15.X versions that were previously packaged. Please read [upstream's documentation](https://woodpecker-ci.org/docs/next/migrations#100) to learn how to update your CI configurations.
|
||||
|
||||
- The Caddy module gained a new option named `services.caddy.enableReload` which is enabled by default. It allows reloading the service instead of restarting it, if only a config file has changed. This option must be disabled if you have turned off the [Caddy admin API](https://caddyserver.com/docs/caddyfile/options#admin). If you keep this option enabled, you should consider setting [`grace_period`](https://caddyserver.com/docs/caddyfile/options#grace-period) to a non-infinite value to prevent Caddy from delaying the reload indefinitely.
|
||||
|
||||
- mdraid support is now optional. This reduces initramfs size and prevents the potentially undesired automatic detection and activation of software RAID pools. It is disabled by default in new configurations (determined by `stateVersion`), but the appropriate settings will be generated by `nixos-generate-config` when installing to a software RAID device, so the standard installation procedure should be unaffected. If you have custom configs relying on mdraid, ensure that you use `stateVersion` correctly or set `boot.swraid.enable` manually.
|
||||
|
||||
- The `go-ethereum` package has been updated to v1.12.0. This drops support for proof-of-work. Its GraphQL API now encodes all numeric values as hex strings and the GraphQL UI is updated to version 2.0. The default database has changed from `leveldb` to `pebble` but `leveldb` can be forced with the --db.engine=leveldb flag. The `checkpoint-admin` command was [removed along with trusted checkpoints](https://github.com/ethereum/go-ethereum/pull/27147).
|
||||
|
||||
- The default `kops` version is now 1.27.0 and support for 1.24 and older has been dropped.
|
||||
|
||||
- `pharo` has been updated to latest stable (PharoVM 10.0.5), which is compatible with the latest stable and oldstable images (Pharo 10 and 11). The VM in question is the 64bit Spur. The 32bit version has been dropped due to lack of maintenance. The Cog VM has been deleted because it is severily outdated. Finally, the `pharo-launcher` package has been deleted because it was not compatible with the newer VM, and due to lack of maintenance.
|
||||
|
||||
## Other Notable Changes {#sec-release-23.11-notable-changes}
|
||||
|
||||
- The Cinnamon module now enables XDG desktop integration by default. If you are experiencing collisions related to xdg-desktop-portal-gtk you can safely remove `xdg.portal.extraPortals = [ pkgs.xdg-desktop-portal-gtk ];` from your NixOS configuration.
|
||||
|
@ -110,6 +134,10 @@
|
|||
|
||||
- DocBook option documentation is no longer supported, all module documentation now uses markdown.
|
||||
|
||||
- `buildGoModule` `go-modules` attrs have been renamed to `goModules`.
|
||||
|
||||
- The `fonts.fonts` and `fonts.enableDefaultFonts` options have been renamed to `fonts.packages` and `fonts.enableDefaultPackages` respectively.
|
||||
|
||||
- `services.fail2ban.jails` can now be configured with attribute sets defining settings and filters instead of lines. The stringed options `daemonConfig` and `extraSettings` have respectively been replaced by `daemonSettings` and `jails.DEFAULT.settings` which use attribute sets.
|
||||
|
||||
- The module [services.ankisyncd](#opt-services.ankisyncd.package) has been switched to [anki-sync-server-rs](https://github.com/ankicommunity/anki-sync-server-rs) from the old python version, which was difficult to update, had not been updated in a while, and did not support recent versions of anki.
|
||||
|
@ -126,8 +154,16 @@ The module update takes care of the new config syntax and the data itself (user
|
|||
|
||||
- `programs.gnupg.agent.pinentryFlavor` is now set in `/etc/gnupg/gpg-agent.conf`, and will no longer take precedence over a `pinentry-program` set in `~/.gnupg/gpg-agent.conf`.
|
||||
|
||||
- `wrapHelm` now exposes `passthru.pluginsDir` which can be passed to `helmfile`. For convenience, a top-level package `helmfile-wrapped` has been added, which inherits `passthru.pluginsDir` from `kubernetes-helm-wrapped`. See [#217768](https://github.com/NixOS/nixpkgs/issues/217768) for details.
|
||||
|
||||
- `boot.initrd.network.udhcp.enable` allows control over dhcp during stage 1 regardless of what `networking.useDHCP` is set to.
|
||||
|
||||
- Suricata was upgraded from 6.0 to 7.0 and no longer considers HTTP/2 support as experimental, see [upstream release notes](https://forum.suricata.io/t/suricata-7-0-0-released/3715) for more details.
|
||||
|
||||
## Nixpkgs internals {#sec-release-23.11-nixpkgs-internals}
|
||||
|
||||
- The use of `sourceRoot = "source";`, `sourceRoot = "source/subdir";`, and similar lines in package derivations using the default `unpackPhase` is deprecated as it requires `unpackPhase` to always produce a directory named "source". Use `sourceRoot = src.name`, `sourceRoot = "${src.name}/subdir";`, or `setSourceRoot = "sourceRoot=$(echo */subdir)";` or similar instead.
|
||||
|
||||
- The `qemu-vm.nix` module by default now identifies block devices via
|
||||
persistent names available in `/dev/disk/by-*`. Because the rootDevice is
|
||||
identfied by its filesystem label, it needs to be formatted before the VM is
|
||||
|
|
20
third_party/nixpkgs/nixos/doc/manual/shell.nix
vendored
Normal file
20
third_party/nixpkgs/nixos/doc/manual/shell.nix
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
let
|
||||
pkgs = import ../../.. {
|
||||
config = {};
|
||||
overlays = [];
|
||||
};
|
||||
|
||||
common = import ./common.nix;
|
||||
inherit (common) outputPath indexPath;
|
||||
|
||||
web-devmode = import ../../../pkgs/tools/nix/web-devmode.nix {
|
||||
inherit pkgs;
|
||||
buildArgs = "../../release.nix -A manualHTML.${builtins.currentSystem}";
|
||||
open = "/${outputPath}/${indexPath}";
|
||||
};
|
||||
in
|
||||
pkgs.mkShell {
|
||||
packages = [
|
||||
web-devmode
|
||||
];
|
||||
}
|
10
third_party/nixpkgs/nixos/lib/eval-config.nix
vendored
10
third_party/nixpkgs/nixos/lib/eval-config.nix
vendored
|
@ -109,8 +109,10 @@ let
|
|||
|
||||
nixosWithUserModules = noUserModules.extendModules { modules = allUserModules; };
|
||||
|
||||
withExtraArgs = nixosSystem: nixosSystem // {
|
||||
inherit extraArgs;
|
||||
inherit (nixosSystem._module.args) pkgs;
|
||||
extendModules = args: withExtraArgs (nixosSystem.extendModules args);
|
||||
};
|
||||
in
|
||||
withWarnings nixosWithUserModules // {
|
||||
inherit extraArgs;
|
||||
inherit (nixosWithUserModules._module.args) pkgs;
|
||||
}
|
||||
withWarnings (withExtraArgs nixosWithUserModules)
|
||||
|
|
|
@ -572,7 +572,7 @@ let format' = format; in let
|
|||
${lib.optionalString installBootLoader ''
|
||||
# In this throwaway resource, we only have /dev/vda, but the actual VM may refer to another disk for bootloader, e.g. /dev/vdb
|
||||
# Use this option to create a symlink from vda to any arbitrary device you want.
|
||||
${optionalString (config.boot.loader.grub.device != "/dev/vda") ''
|
||||
${optionalString (config.boot.loader.grub.enable && config.boot.loader.grub.device != "/dev/vda") ''
|
||||
mkdir -p $(dirname ${config.boot.loader.grub.device})
|
||||
ln -s /dev/vda ${config.boot.loader.grub.device}
|
||||
''}
|
||||
|
|
24
third_party/nixpkgs/nixos/lib/systemd-lib.nix
vendored
24
third_party/nixpkgs/nixos/lib/systemd-lib.nix
vendored
|
@ -63,7 +63,12 @@ in rec {
|
|||
|
||||
assertMacAddress = name: group: attr:
|
||||
optional (attr ? ${name} && ! isMacAddress attr.${name})
|
||||
"Systemd ${group} field `${name}' must be a valid mac address.";
|
||||
"Systemd ${group} field `${name}' must be a valid MAC address.";
|
||||
|
||||
assertNetdevMacAddress = name: group: attr:
|
||||
optional (attr ? ${name} && (! isMacAddress attr.${name} && attr.${name} != "none"))
|
||||
"Systemd ${group} field `${name}` must be a valid MAC address or the special value `none`.";
|
||||
|
||||
|
||||
isPort = i: i >= 0 && i <= 65535;
|
||||
|
||||
|
@ -438,4 +443,21 @@ in rec {
|
|||
${attrsToSection def.sliceConfig}
|
||||
'';
|
||||
};
|
||||
|
||||
# Create a directory that contains systemd definition files from an attrset
|
||||
# that contains the file names as keys and the content as values. The values
|
||||
# in that attrset are determined by the supplied format.
|
||||
definitions = directoryName: format: definitionAttrs:
|
||||
let
|
||||
listOfDefinitions = lib.mapAttrsToList
|
||||
(name: format.generate "${name}.conf")
|
||||
definitionAttrs;
|
||||
in
|
||||
pkgs.runCommand directoryName { } ''
|
||||
mkdir -p $out
|
||||
${(lib.concatStringsSep "\n"
|
||||
(map (pkg: "cp ${pkg} $out/${pkg.name}") listOfDefinitions)
|
||||
)}
|
||||
'';
|
||||
|
||||
}
|
||||
|
|
66
third_party/nixpkgs/nixos/lib/test-driver/extract-docstrings.py
vendored
Normal file
66
third_party/nixpkgs/nixos/lib/test-driver/extract-docstrings.py
vendored
Normal file
|
@ -0,0 +1,66 @@
|
|||
import ast
|
||||
import sys
|
||||
|
||||
"""
|
||||
This program takes all the Machine class methods and prints its methods in
|
||||
markdown-style. These can then be included in the NixOS test driver
|
||||
markdown style, assuming the docstrings themselves are also in markdown.
|
||||
|
||||
These are included in the test driver documentation in the NixOS manual.
|
||||
See https://nixos.org/manual/nixos/stable/#ssec-machine-objects
|
||||
|
||||
The python input looks like this:
|
||||
|
||||
```py
|
||||
...
|
||||
|
||||
class Machine(...):
|
||||
...
|
||||
|
||||
def some_function(self, param1, param2):
|
||||
""
|
||||
documentation string of some_function.
|
||||
foo bar baz.
|
||||
""
|
||||
...
|
||||
```
|
||||
|
||||
Output will be:
|
||||
|
||||
```markdown
|
||||
...
|
||||
|
||||
some_function(param1, param2)
|
||||
|
||||
: documentation string of some_function.
|
||||
foo bar baz.
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
"""
|
||||
|
||||
assert len(sys.argv) == 2
|
||||
|
||||
with open(sys.argv[1], "r") as f:
|
||||
module = ast.parse(f.read())
|
||||
|
||||
class_definitions = (node for node in module.body if isinstance(node, ast.ClassDef))
|
||||
|
||||
machine_class = next(filter(lambda x: x.name == "Machine", class_definitions))
|
||||
assert machine_class is not None
|
||||
|
||||
function_definitions = [
|
||||
node for node in machine_class.body if isinstance(node, ast.FunctionDef)
|
||||
]
|
||||
function_definitions.sort(key=lambda x: x.name)
|
||||
|
||||
for f in function_definitions:
|
||||
docstr = ast.get_docstring(f)
|
||||
if docstr is not None:
|
||||
args = ", ".join((a.arg for a in f.args.args[1:]))
|
||||
args = f"({args})"
|
||||
|
||||
docstr = "\n".join((f" {l}" for l in docstr.strip().splitlines()))
|
||||
|
||||
print(f"{f.name}{args}\n\n:{docstr[1:]}\n")
|
13
third_party/nixpkgs/nixos/lib/test-driver/nixos-test-driver-docstrings.nix
vendored
Normal file
13
third_party/nixpkgs/nixos/lib/test-driver/nixos-test-driver-docstrings.nix
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
{ runCommand
|
||||
, python3
|
||||
}:
|
||||
|
||||
let
|
||||
env = { nativeBuildInputs = [ python3 ]; };
|
||||
in
|
||||
|
||||
runCommand "nixos-test-driver-docstrings" env ''
|
||||
mkdir $out
|
||||
python3 ${./extract-docstrings.py} ${./test_driver/machine.py} \
|
||||
> $out/machine-methods.md
|
||||
''
|
|
@ -416,6 +416,10 @@ class Machine:
|
|||
return answer
|
||||
|
||||
def send_monitor_command(self, command: str) -> str:
|
||||
"""
|
||||
Send a command to the QEMU monitor. This allows attaching
|
||||
virtual USB disks to a running machine, among other things.
|
||||
"""
|
||||
self.run_callbacks()
|
||||
message = f"{command}\n".encode()
|
||||
assert self.monitor is not None
|
||||
|
@ -425,9 +429,10 @@ class Machine:
|
|||
def wait_for_unit(
|
||||
self, unit: str, user: Optional[str] = None, timeout: int = 900
|
||||
) -> None:
|
||||
"""Wait for a systemd unit to get into "active" state.
|
||||
Throws exceptions on "failed" and "inactive" states as well as
|
||||
after timing out.
|
||||
"""
|
||||
Wait for a systemd unit to get into "active" state.
|
||||
Throws exceptions on "failed" and "inactive" states as well as after
|
||||
timing out.
|
||||
"""
|
||||
|
||||
def check_active(_: Any) -> bool:
|
||||
|
@ -476,6 +481,19 @@ class Machine:
|
|||
)
|
||||
|
||||
def systemctl(self, q: str, user: Optional[str] = None) -> Tuple[int, str]:
|
||||
"""
|
||||
Runs `systemctl` commands with optional support for
|
||||
`systemctl --user`
|
||||
|
||||
```py
|
||||
# run `systemctl list-jobs --no-pager`
|
||||
machine.systemctl("list-jobs --no-pager")
|
||||
|
||||
# spawn a shell for `any-user` and run
|
||||
# `systemctl --user list-jobs --no-pager`
|
||||
machine.systemctl("list-jobs --no-pager", "any-user")
|
||||
```
|
||||
"""
|
||||
if user is not None:
|
||||
q = q.replace("'", "\\'")
|
||||
return self.execute(
|
||||
|
@ -520,6 +538,38 @@ class Machine:
|
|||
check_output: bool = True,
|
||||
timeout: Optional[int] = 900,
|
||||
) -> Tuple[int, str]:
|
||||
"""
|
||||
Execute a shell command, returning a list `(status, stdout)`.
|
||||
|
||||
Commands are run with `set -euo pipefail` set:
|
||||
|
||||
- If several commands are separated by `;` and one fails, the
|
||||
command as a whole will fail.
|
||||
|
||||
- For pipelines, the last non-zero exit status will be returned
|
||||
(if there is one; otherwise zero will be returned).
|
||||
|
||||
- Dereferencing unset variables fails the command.
|
||||
|
||||
- It will wait for stdout to be closed.
|
||||
|
||||
If the command detaches, it must close stdout, as `execute` will wait
|
||||
for this to consume all output reliably. This can be achieved by
|
||||
redirecting stdout to stderr `>&2`, to `/dev/console`, `/dev/null` or
|
||||
a file. Examples of detaching commands are `sleep 365d &`, where the
|
||||
shell forks a new process that can write to stdout and `xclip -i`, where
|
||||
the `xclip` command itself forks without closing stdout.
|
||||
|
||||
Takes an optional parameter `check_return` that defaults to `True`.
|
||||
Setting this parameter to `False` will not check for the return code
|
||||
and return -1 instead. This can be used for commands that shut down
|
||||
the VM and would therefore break the pipe that would be used for
|
||||
retrieving the return code.
|
||||
|
||||
A timeout for the command can be specified (in seconds) using the optional
|
||||
`timeout` parameter, e.g., `execute(cmd, timeout=10)` or
|
||||
`execute(cmd, timeout=None)`. The default is 900 seconds.
|
||||
"""
|
||||
self.run_callbacks()
|
||||
self.connect()
|
||||
|
||||
|
@ -533,7 +583,7 @@ class Machine:
|
|||
# While sh is bash on NixOS, this is not the case for every distro.
|
||||
# We explicitly call bash here to allow for the driver to boot other distros as well.
|
||||
out_command = (
|
||||
f"{timeout_str} bash -c {shlex.quote(command)} | (base64 --wrap 0; echo)\n"
|
||||
f"{timeout_str} bash -c {shlex.quote(command)} | (base64 -w 0; echo)\n"
|
||||
)
|
||||
|
||||
assert self.shell
|
||||
|
@ -555,10 +605,11 @@ class Machine:
|
|||
return (rc, output.decode(errors="replace"))
|
||||
|
||||
def shell_interact(self, address: Optional[str] = None) -> None:
|
||||
"""Allows you to interact with the guest shell for debugging purposes.
|
||||
|
||||
@address string passed to socat that will be connected to the guest shell.
|
||||
Check the `Running Tests interactivly` chapter of NixOS manual for an example.
|
||||
"""
|
||||
Allows you to directly interact with the guest shell. This should
|
||||
only be used during test development, not in production tests.
|
||||
Killing the interactive session with `Ctrl-d` or `Ctrl-c` also ends
|
||||
the guest session.
|
||||
"""
|
||||
self.connect()
|
||||
|
||||
|
@ -577,12 +628,14 @@ class Machine:
|
|||
pass
|
||||
|
||||
def console_interact(self) -> None:
|
||||
"""Allows you to interact with QEMU's stdin
|
||||
|
||||
The shell can be exited with Ctrl+D. Note that Ctrl+C is not allowed to be used.
|
||||
QEMU's stdout is read line-wise.
|
||||
|
||||
Should only be used during test development, not in the production test."""
|
||||
"""
|
||||
Allows you to directly interact with QEMU's stdin, by forwarding
|
||||
terminal input to the QEMU process.
|
||||
This is for use with the interactive test driver, not for production
|
||||
tests, which run unattended.
|
||||
Output from QEMU is only read line-wise. `Ctrl-c` kills QEMU and
|
||||
`Ctrl-d` closes console and returns to the test runner.
|
||||
"""
|
||||
self.log("Terminal is ready (there is no prompt):")
|
||||
|
||||
assert self.process
|
||||
|
@ -599,7 +652,12 @@ class Machine:
|
|||
self.send_console(char.decode())
|
||||
|
||||
def succeed(self, *commands: str, timeout: Optional[int] = None) -> str:
|
||||
"""Execute each command and check that it succeeds."""
|
||||
"""
|
||||
Execute a shell command, raising an exception if the exit status is
|
||||
not zero, otherwise returning the standard output. Similar to `execute`,
|
||||
except that the timeout is `None` by default. See `execute` for details on
|
||||
command execution.
|
||||
"""
|
||||
output = ""
|
||||
for command in commands:
|
||||
with self.nested(f"must succeed: {command}"):
|
||||
|
@ -611,7 +669,10 @@ class Machine:
|
|||
return output
|
||||
|
||||
def fail(self, *commands: str, timeout: Optional[int] = None) -> str:
|
||||
"""Execute each command and check that it fails."""
|
||||
"""
|
||||
Like `succeed`, but raising an exception if the command returns a zero
|
||||
status.
|
||||
"""
|
||||
output = ""
|
||||
for command in commands:
|
||||
with self.nested(f"must fail: {command}"):
|
||||
|
@ -622,7 +683,11 @@ class Machine:
|
|||
return output
|
||||
|
||||
def wait_until_succeeds(self, command: str, timeout: int = 900) -> str:
|
||||
"""Wait until a command returns success and return its output.
|
||||
"""
|
||||
Repeat a shell command with 1-second intervals until it succeeds.
|
||||
Has a default timeout of 900 seconds which can be modified, e.g.
|
||||
`wait_until_succeeds(cmd, timeout=10)`. See `execute` for details on
|
||||
command execution.
|
||||
Throws an exception on timeout.
|
||||
"""
|
||||
output = ""
|
||||
|
@ -637,8 +702,8 @@ class Machine:
|
|||
return output
|
||||
|
||||
def wait_until_fails(self, command: str, timeout: int = 900) -> str:
|
||||
"""Wait until a command returns failure.
|
||||
Throws an exception on timeout.
|
||||
"""
|
||||
Like `wait_until_succeeds`, but repeating the command until it fails.
|
||||
"""
|
||||
output = ""
|
||||
|
||||
|
@ -690,12 +755,19 @@ class Machine:
|
|||
retry(tty_matches)
|
||||
|
||||
def send_chars(self, chars: str, delay: Optional[float] = 0.01) -> None:
|
||||
"""
|
||||
Simulate typing a sequence of characters on the virtual keyboard,
|
||||
e.g., `send_chars("foobar\n")` will type the string `foobar`
|
||||
followed by the Enter key.
|
||||
"""
|
||||
with self.nested(f"sending keys {repr(chars)}"):
|
||||
for char in chars:
|
||||
self.send_key(char, delay, log=False)
|
||||
|
||||
def wait_for_file(self, filename: str) -> None:
|
||||
"""Waits until the file exists in machine's file system."""
|
||||
"""
|
||||
Waits until the file exists in the machine's file system.
|
||||
"""
|
||||
|
||||
def check_file(_: Any) -> bool:
|
||||
status, _ = self.execute(f"test -e {filename}")
|
||||
|
@ -705,6 +777,11 @@ class Machine:
|
|||
retry(check_file)
|
||||
|
||||
def wait_for_open_port(self, port: int, addr: str = "localhost") -> None:
|
||||
"""
|
||||
Wait until a process is listening on the given TCP port and IP address
|
||||
(default `localhost`).
|
||||
"""
|
||||
|
||||
def port_is_open(_: Any) -> bool:
|
||||
status, _ = self.execute(f"nc -z {addr} {port}")
|
||||
return status == 0
|
||||
|
@ -713,6 +790,11 @@ class Machine:
|
|||
retry(port_is_open)
|
||||
|
||||
def wait_for_closed_port(self, port: int, addr: str = "localhost") -> None:
|
||||
"""
|
||||
Wait until nobody is listening on the given TCP port and IP address
|
||||
(default `localhost`).
|
||||
"""
|
||||
|
||||
def port_is_closed(_: Any) -> bool:
|
||||
status, _ = self.execute(f"nc -z {addr} {port}")
|
||||
return status != 0
|
||||
|
@ -751,6 +833,9 @@ class Machine:
|
|||
# TODO: do we want to bail after a set number of attempts?
|
||||
while not shell_ready(timeout_secs=30):
|
||||
self.log("Guest root shell did not produce any data yet...")
|
||||
self.log(
|
||||
" To debug, enter the VM and run 'systemctl status backdoor.service'."
|
||||
)
|
||||
|
||||
while True:
|
||||
chunk = self.shell.recv(1024)
|
||||
|
@ -766,6 +851,10 @@ class Machine:
|
|||
self.connected = True
|
||||
|
||||
def screenshot(self, filename: str) -> None:
|
||||
"""
|
||||
Take a picture of the display of the virtual machine, in PNG format.
|
||||
The screenshot will be available in the derivation output.
|
||||
"""
|
||||
if "." not in filename:
|
||||
filename += ".png"
|
||||
if "/" not in filename:
|
||||
|
@ -795,8 +884,21 @@ class Machine:
|
|||
)
|
||||
|
||||
def copy_from_host(self, source: str, target: str) -> None:
|
||||
"""Copy a file from the host into the guest via the `shared_dir` shared
|
||||
among all the VMs (using a temporary directory).
|
||||
"""
|
||||
Copies a file from host to machine, e.g.,
|
||||
`copy_from_host("myfile", "/etc/my/important/file")`.
|
||||
|
||||
The first argument is the file on the host. Note that the "host" refers
|
||||
to the environment in which the test driver runs, which is typically the
|
||||
Nix build sandbox.
|
||||
|
||||
The second argument is the location of the file on the machine that will
|
||||
be written to.
|
||||
|
||||
The file is copied via the `shared_dir` directory which is shared among
|
||||
all the VMs (using a temporary directory).
|
||||
The access rights bits will mimic the ones from the host file and
|
||||
user:group will be root:root.
|
||||
"""
|
||||
host_src = Path(source)
|
||||
vm_target = Path(target)
|
||||
|
@ -848,12 +950,41 @@ class Machine:
|
|||
return _perform_ocr_on_screenshot(screenshot_path, model_ids)
|
||||
|
||||
def get_screen_text_variants(self) -> List[str]:
|
||||
"""
|
||||
Return a list of different interpretations of what is currently
|
||||
visible on the machine's screen using optical character
|
||||
recognition. The number and order of the interpretations is not
|
||||
specified and is subject to change, but if no exception is raised at
|
||||
least one will be returned.
|
||||
|
||||
::: {.note}
|
||||
This requires [`enableOCR`](#test-opt-enableOCR) to be set to `true`.
|
||||
:::
|
||||
"""
|
||||
return self._get_screen_text_variants([0, 1, 2])
|
||||
|
||||
def get_screen_text(self) -> str:
|
||||
"""
|
||||
Return a textual representation of what is currently visible on the
|
||||
machine's screen using optical character recognition.
|
||||
|
||||
::: {.note}
|
||||
This requires [`enableOCR`](#test-opt-enableOCR) to be set to `true`.
|
||||
:::
|
||||
"""
|
||||
return self._get_screen_text_variants([2])[0]
|
||||
|
||||
def wait_for_text(self, regex: str) -> None:
|
||||
"""
|
||||
Wait until the supplied regular expressions matches the textual
|
||||
contents of the screen by using optical character recognition (see
|
||||
`get_screen_text` and `get_screen_text_variants`).
|
||||
|
||||
::: {.note}
|
||||
This requires [`enableOCR`](#test-opt-enableOCR) to be set to `true`.
|
||||
:::
|
||||
"""
|
||||
|
||||
def screen_matches(last: bool) -> bool:
|
||||
variants = self.get_screen_text_variants()
|
||||
for text in variants:
|
||||
|
@ -870,12 +1001,9 @@ class Machine:
|
|||
|
||||
def wait_for_console_text(self, regex: str, timeout: int | None = None) -> None:
|
||||
"""
|
||||
Wait for the provided regex to appear on console.
|
||||
For each reads,
|
||||
|
||||
If timeout is None, timeout is infinite.
|
||||
|
||||
`timeout` is in seconds.
|
||||
Wait until the supplied regular expressions match a line of the
|
||||
serial console output.
|
||||
This method is useful when OCR is not possible or inaccurate.
|
||||
"""
|
||||
# Buffer the console output, this is needed
|
||||
# to match multiline regexes.
|
||||
|
@ -903,6 +1031,13 @@ class Machine:
|
|||
def send_key(
|
||||
self, key: str, delay: Optional[float] = 0.01, log: Optional[bool] = True
|
||||
) -> None:
|
||||
"""
|
||||
Simulate pressing keys on the virtual keyboard, e.g.,
|
||||
`send_key("ctrl-alt-delete")`.
|
||||
|
||||
Please also refer to the QEMU documentation for more information on the
|
||||
input syntax: https://en.wikibooks.org/wiki/QEMU/Monitor#sendkey_keys
|
||||
"""
|
||||
key = CHAR_TO_KEY.get(key, key)
|
||||
context = self.nested(f"sending key {repr(key)}") if log else nullcontext()
|
||||
with context:
|
||||
|
@ -911,12 +1046,21 @@ class Machine:
|
|||
time.sleep(delay)
|
||||
|
||||
def send_console(self, chars: str) -> None:
|
||||
r"""
|
||||
Send keys to the kernel console. This allows interaction with the systemd
|
||||
emergency mode, for example. Takes a string that is sent, e.g.,
|
||||
`send_console("\n\nsystemctl default\n")`.
|
||||
"""
|
||||
assert self.process
|
||||
assert self.process.stdin
|
||||
self.process.stdin.write(chars.encode())
|
||||
self.process.stdin.flush()
|
||||
|
||||
def start(self, allow_reboot: bool = False) -> None:
|
||||
"""
|
||||
Start the virtual machine. This method is asynchronous --- it does
|
||||
not wait for the machine to finish booting.
|
||||
"""
|
||||
if self.booted:
|
||||
return
|
||||
|
||||
|
@ -974,6 +1118,9 @@ class Machine:
|
|||
rootlog.log("if you want to keep the VM state, pass --keep-vm-state")
|
||||
|
||||
def shutdown(self) -> None:
|
||||
"""
|
||||
Shut down the machine, waiting for the VM to exit.
|
||||
"""
|
||||
if not self.booted:
|
||||
return
|
||||
|
||||
|
@ -982,6 +1129,9 @@ class Machine:
|
|||
self.wait_for_shutdown()
|
||||
|
||||
def crash(self) -> None:
|
||||
"""
|
||||
Simulate a sudden power failure, by telling the VM to exit immediately.
|
||||
"""
|
||||
if not self.booted:
|
||||
return
|
||||
|
||||
|
@ -999,8 +1149,8 @@ class Machine:
|
|||
self.connected = False
|
||||
|
||||
def wait_for_x(self) -> None:
|
||||
"""Wait until it is possible to connect to the X server. Note that
|
||||
testing the existence of /tmp/.X11-unix/X0 is insufficient.
|
||||
"""
|
||||
Wait until it is possible to connect to the X server.
|
||||
"""
|
||||
|
||||
def check_x(_: Any) -> bool:
|
||||
|
@ -1023,6 +1173,10 @@ class Machine:
|
|||
).splitlines()
|
||||
|
||||
def wait_for_window(self, regexp: str) -> None:
|
||||
"""
|
||||
Wait until an X11 window has appeared whose name matches the given
|
||||
regular expression, e.g., `wait_for_window("Terminal")`.
|
||||
"""
|
||||
pattern = re.compile(regexp)
|
||||
|
||||
def window_is_visible(last_try: bool) -> bool:
|
||||
|
@ -1043,20 +1197,26 @@ class Machine:
|
|||
self.succeed(f"sleep {secs}")
|
||||
|
||||
def forward_port(self, host_port: int = 8080, guest_port: int = 80) -> None:
|
||||
"""Forward a TCP port on the host to a TCP port on the guest.
|
||||
"""
|
||||
Forward a TCP port on the host to a TCP port on the guest.
|
||||
Useful during interactive testing.
|
||||
"""
|
||||
self.send_monitor_command(f"hostfwd_add tcp::{host_port}-:{guest_port}")
|
||||
|
||||
def block(self) -> None:
|
||||
"""Make the machine unreachable by shutting down eth1 (the multicast
|
||||
interface used to talk to the other VMs). We keep eth0 up so that
|
||||
the test driver can continue to talk to the machine.
|
||||
"""
|
||||
Simulate unplugging the Ethernet cable that connects the machine to
|
||||
the other machines.
|
||||
This happens by shutting down eth1 (the multicast interface used to talk
|
||||
to the other VMs). eth0 is kept online to still enable the test driver
|
||||
to communicate with the machine.
|
||||
"""
|
||||
self.send_monitor_command("set_link virtio-net-pci.1 off")
|
||||
|
||||
def unblock(self) -> None:
|
||||
"""Make the machine reachable."""
|
||||
"""
|
||||
Undo the effect of `block`.
|
||||
"""
|
||||
self.send_monitor_command("set_link virtio-net-pci.1 on")
|
||||
|
||||
def release(self) -> None:
|
||||
|
|
|
@ -65,7 +65,8 @@ let
|
|||
echo "${builtins.toString vlanNames}" >> testScriptWithTypes
|
||||
echo -n "$testScript" >> testScriptWithTypes
|
||||
|
||||
cat -n testScriptWithTypes
|
||||
echo "Running type check (enable/disable: config.skipTypeCheck)"
|
||||
echo "See https://nixos.org/manual/nixos/stable/#test-opt-skipTypeCheck"
|
||||
|
||||
mypy --no-implicit-optional \
|
||||
--pretty \
|
||||
|
@ -79,6 +80,9 @@ let
|
|||
|
||||
${testDriver}/bin/generate-driver-symbols
|
||||
${lib.optionalString (!config.skipLint) ''
|
||||
echo "Linting test script (enable/disable: config.skipLint)"
|
||||
echo "See https://nixos.org/manual/nixos/stable/#test-opt-skipLint"
|
||||
|
||||
PYFLAKES_BUILTINS="$(
|
||||
echo -n ${lib.escapeShellArg (lib.concatStringsSep "," pythonizedNames)},
|
||||
< ${lib.escapeShellArg "driver-symbols"}
|
||||
|
|
|
@ -42,7 +42,7 @@ let
|
|||
# looking things up.
|
||||
makeCacheConf = { }:
|
||||
let
|
||||
makeCache = fontconfig: pkgs.makeFontsCache { inherit fontconfig; fontDirectories = config.fonts.fonts; };
|
||||
makeCache = fontconfig: pkgs.makeFontsCache { inherit fontconfig; fontDirectories = config.fonts.packages; };
|
||||
cache = makeCache pkgs.fontconfig;
|
||||
cache32 = makeCache pkgs.pkgsi686Linux.fontconfig;
|
||||
in
|
||||
|
@ -51,7 +51,7 @@ let
|
|||
<!DOCTYPE fontconfig SYSTEM 'urn:fontconfig:fonts.dtd'>
|
||||
<fontconfig>
|
||||
<!-- Font directories -->
|
||||
${concatStringsSep "\n" (map (font: "<dir>${font}</dir>") config.fonts.fonts)}
|
||||
${concatStringsSep "\n" (map (font: "<dir>${font}</dir>") config.fonts.packages)}
|
||||
${optionalString (pkgs.stdenv.hostPlatform == pkgs.stdenv.buildPlatform) ''
|
||||
<!-- Pre-generated font caches -->
|
||||
<cachedir>${cache}</cachedir>
|
||||
|
|
|
@ -9,7 +9,7 @@ let
|
|||
x11Fonts = pkgs.runCommand "X11-fonts" { preferLocalBuild = true; } ''
|
||||
mkdir -p "$out/share/X11/fonts"
|
||||
font_regexp='.*\.\(ttf\|ttc\|otb\|otf\|pcf\|pfa\|pfb\|bdf\)\(\.gz\)?'
|
||||
find ${toString config.fonts.fonts} -regex "$font_regexp" \
|
||||
find ${toString config.fonts.packages} -regex "$font_regexp" \
|
||||
-exec ln -sf -t "$out/share/X11/fonts" '{}' \;
|
||||
cd "$out/share/X11/fonts"
|
||||
${optionalString cfg.decompressFonts ''
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.fonts;
|
||||
|
||||
defaultFonts =
|
||||
[ pkgs.dejavu_fonts
|
||||
pkgs.freefont_ttf
|
||||
pkgs.gyre-fonts # TrueType substitutes for standard PostScript fonts
|
||||
pkgs.liberation_ttf
|
||||
pkgs.unifont
|
||||
pkgs.noto-fonts-emoji
|
||||
];
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
(mkRemovedOptionModule [ "fonts" "enableCoreFonts" ] "Use fonts.fonts = [ pkgs.corefonts ]; instead.")
|
||||
];
|
||||
|
||||
options = {
|
||||
|
||||
fonts = {
|
||||
|
||||
# TODO: find another name for it.
|
||||
fonts = mkOption {
|
||||
type = types.listOf types.path;
|
||||
default = [];
|
||||
example = literalExpression "[ pkgs.dejavu_fonts ]";
|
||||
description = lib.mdDoc "List of primary font paths.";
|
||||
};
|
||||
|
||||
enableDefaultFonts = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = lib.mdDoc ''
|
||||
Enable a basic set of fonts providing several font styles
|
||||
and families and reasonable coverage of Unicode.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
config = { fonts.fonts = mkIf cfg.enableDefaultFonts defaultFonts; };
|
||||
}
|
|
@ -3,31 +3,21 @@
|
|||
with lib;
|
||||
|
||||
{
|
||||
|
||||
options = {
|
||||
|
||||
fonts = {
|
||||
|
||||
enableGhostscriptFonts = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = lib.mdDoc ''
|
||||
Whether to add the fonts provided by Ghostscript (such as
|
||||
various URW fonts and the “Base-14” Postscript fonts) to the
|
||||
list of system fonts, making them available to X11
|
||||
applications.
|
||||
'';
|
||||
};
|
||||
|
||||
fonts.enableGhostscriptFonts = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = lib.mdDoc ''
|
||||
Whether to add the fonts provided by Ghostscript (such as
|
||||
various URW fonts and the “Base-14” Postscript fonts) to the
|
||||
list of system fonts, making them available to X11
|
||||
applications.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
config = mkIf config.fonts.enableGhostscriptFonts {
|
||||
|
||||
fonts.fonts = [ "${pkgs.ghostscript}/share/ghostscript/fonts" ];
|
||||
|
||||
fonts.packages = [ "${pkgs.ghostscript}/share/ghostscript/fonts" ];
|
||||
};
|
||||
|
||||
}
|
||||
|
|
43
third_party/nixpkgs/nixos/modules/config/fonts/packages.nix
vendored
Normal file
43
third_party/nixpkgs/nixos/modules/config/fonts/packages.nix
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
cfg = config.fonts;
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
(lib.mkRemovedOptionModule [ "fonts" "enableCoreFonts" ] "Use fonts.packages = [ pkgs.corefonts ]; instead.")
|
||||
(lib.mkRenamedOptionModule [ "fonts" "enableDefaultFonts" ] [ "fonts" "enableDefaultPackages" ])
|
||||
(lib.mkRenamedOptionModule [ "fonts" "fonts" ] [ "fonts" "packages" ])
|
||||
];
|
||||
|
||||
options = {
|
||||
fonts = {
|
||||
packages = lib.mkOption {
|
||||
type = with lib.types; listOf path;
|
||||
default = [];
|
||||
example = lib.literalExpression "[ pkgs.dejavu_fonts ]";
|
||||
description = lib.mdDoc "List of primary font packages.";
|
||||
};
|
||||
|
||||
enableDefaultPackages = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = lib.mdDoc ''
|
||||
Enable a basic set of fonts providing several styles
|
||||
and families and reasonable coverage of Unicode.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
fonts.packages = lib.mkIf cfg.enableDefaultPackages (with pkgs; [
|
||||
dejavu_fonts
|
||||
freefont_ttf
|
||||
gyre-fonts # TrueType substitutes for standard PostScript fonts
|
||||
liberation_ttf
|
||||
unifont
|
||||
noto-fonts-emoji
|
||||
]);
|
||||
};
|
||||
}
|
|
@ -3,12 +3,13 @@
|
|||
configuration to work.
|
||||
|
||||
See also
|
||||
- ./nix.nix
|
||||
- ./nix-flakes.nix
|
||||
- ./nix.nix
|
||||
- ./nix-flakes.nix
|
||||
*/
|
||||
{ config, lib, ... }:
|
||||
let
|
||||
inherit (lib)
|
||||
mkDefault
|
||||
mkIf
|
||||
mkOption
|
||||
stringAfter
|
||||
|
@ -21,13 +22,42 @@ in
|
|||
{
|
||||
options = {
|
||||
nix = {
|
||||
channel = {
|
||||
enable = mkOption {
|
||||
description = lib.mdDoc ''
|
||||
Whether the `nix-channel` command and state files are made available on the machine.
|
||||
|
||||
The following files are initialized when enabled:
|
||||
- `/nix/var/nix/profiles/per-user/root/channels`
|
||||
- `/root/.nix-channels`
|
||||
- `$HOME/.nix-defexpr/channels` (on login)
|
||||
|
||||
Disabling this option will not remove the state files from the system.
|
||||
'';
|
||||
type = types.bool;
|
||||
default = true;
|
||||
};
|
||||
};
|
||||
|
||||
nixPath = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [
|
||||
"nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos"
|
||||
"nixos-config=/etc/nixos/configuration.nix"
|
||||
"/nix/var/nix/profiles/per-user/root/channels"
|
||||
];
|
||||
default =
|
||||
if cfg.channel.enable
|
||||
then [
|
||||
"nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos"
|
||||
"nixos-config=/etc/nixos/configuration.nix"
|
||||
"/nix/var/nix/profiles/per-user/root/channels"
|
||||
]
|
||||
else [ ];
|
||||
defaultText = ''
|
||||
if nix.channel.enable
|
||||
then [
|
||||
"nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos"
|
||||
"nixos-config=/etc/nixos/configuration.nix"
|
||||
"/nix/var/nix/profiles/per-user/root/channels"
|
||||
]
|
||||
else [];
|
||||
'';
|
||||
description = lib.mdDoc ''
|
||||
The default Nix expression search path, used by the Nix
|
||||
evaluator to look up paths enclosed in angle brackets
|
||||
|
@ -49,22 +79,30 @@ in
|
|||
config = mkIf cfg.enable {
|
||||
|
||||
environment.extraInit =
|
||||
''
|
||||
mkIf cfg.channel.enable ''
|
||||
if [ -e "$HOME/.nix-defexpr/channels" ]; then
|
||||
export NIX_PATH="$HOME/.nix-defexpr/channels''${NIX_PATH:+:$NIX_PATH}"
|
||||
fi
|
||||
'';
|
||||
|
||||
environment.extraSetup = mkIf (!cfg.channel.enable) ''
|
||||
rm --force $out/bin/nix-channel
|
||||
'';
|
||||
|
||||
# NIX_PATH has a non-empty default according to Nix docs, so we don't unset
|
||||
# it when empty.
|
||||
environment.sessionVariables = {
|
||||
NIX_PATH = cfg.nixPath;
|
||||
};
|
||||
|
||||
system.activationScripts.nix-channel = stringAfter [ "etc" "users" ]
|
||||
''
|
||||
nix.settings.nix-path = mkIf (! cfg.channel.enable) (mkDefault "");
|
||||
|
||||
system.activationScripts.nix-channel = mkIf cfg.channel.enable
|
||||
(stringAfter [ "etc" "users" ] ''
|
||||
# Subscribe the root user to the NixOS channel by default.
|
||||
if [ ! -e "/root/.nix-channels" ]; then
|
||||
echo "${config.system.defaultChannel} nixos" > "/root/.nix-channels"
|
||||
fi
|
||||
'';
|
||||
'');
|
||||
};
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ let
|
|||
pkgs.qgnomeplatform-qt6
|
||||
pkgs.adwaita-qt6
|
||||
]
|
||||
else if isQtStyle then [ pkgs.libsForQt5.qtstyleplugins ]
|
||||
else if isQtStyle then [ pkgs.libsForQt5.qtstyleplugins pkgs.qt6Packages.qt6gtk2 ]
|
||||
else if isQt5ct then [ pkgs.libsForQt5.qt5ct pkgs.qt6Packages.qt6ct ]
|
||||
else if isLxqt then [ pkgs.lxqt.lxqt-qtplugin pkgs.lxqt.lxqt-config ]
|
||||
else if isKde then [ pkgs.libsForQt5.plasma-integration pkgs.libsForQt5.systemsettings ]
|
||||
|
@ -86,6 +86,7 @@ in
|
|||
"adwaita-qt"
|
||||
"adwaita-qt6"
|
||||
["libsForQt5" "qtstyleplugins"]
|
||||
["qt6Packages" "qt6gtk2"]
|
||||
];
|
||||
description = lib.mdDoc ''
|
||||
Selects the style to use for Qt applications.
|
||||
|
|
|
@ -7,12 +7,15 @@ with lib;
|
|||
|
||||
options = {
|
||||
|
||||
hardware.usbWwan = {
|
||||
hardware.usb-modeswitch = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = lib.mdDoc ''
|
||||
Enable this option to support USB WWAN adapters.
|
||||
Enable this option to support certain USB WLAN and WWAN adapters.
|
||||
|
||||
These network adapters initial present themselves as Flash Drives containing their drivers.
|
||||
This option enables automatic switching to the networking mode.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
@ -20,7 +23,11 @@ with lib;
|
|||
|
||||
###### implementation
|
||||
|
||||
config = mkIf config.hardware.usbWwan.enable {
|
||||
imports = [
|
||||
(mkRenamedOptionModule ["hardware" "usbWwan" ] ["hardware" "usb-modeswitch" ])
|
||||
];
|
||||
|
||||
config = mkIf config.hardware.usb-modeswitch.enable {
|
||||
# Attaches device specific handlers.
|
||||
services.udev.packages = with pkgs; [ usb-modeswitch-data ];
|
||||
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
with lib;
|
||||
{
|
||||
options.hardware.wooting.enable =
|
||||
mkEnableOption (lib.mdDoc "support for Wooting keyboards");
|
||||
options.hardware.wooting.enable = mkEnableOption (lib.mdDoc ''support for Wooting keyboards.
|
||||
Note that users must be in the "input" group for udev rules to apply'');
|
||||
|
||||
config = mkIf config.hardware.wooting.enable {
|
||||
environment.systemPackages = [ pkgs.wootility ];
|
||||
|
|
|
@ -12,12 +12,34 @@ in
|
|||
i18n.inputMethod.fcitx5 = {
|
||||
addons = mkOption {
|
||||
type = with types; listOf package;
|
||||
default = [];
|
||||
default = [ ];
|
||||
example = literalExpression "with pkgs; [ fcitx5-rime ]";
|
||||
description = lib.mdDoc ''
|
||||
Enabled Fcitx5 addons.
|
||||
'';
|
||||
};
|
||||
quickPhrase = mkOption {
|
||||
type = with types; attrsOf string;
|
||||
default = { };
|
||||
example = literalExpression ''
|
||||
{
|
||||
smile = "(・∀・)";
|
||||
angry = "( ̄ー ̄)";
|
||||
}
|
||||
'';
|
||||
description = lib.mdDoc "Quick phrases.";
|
||||
};
|
||||
quickPhraseFiles = mkOption {
|
||||
type = with types; attrsOf path;
|
||||
default = { };
|
||||
example = literalExpression ''
|
||||
{
|
||||
words = ./words.mb;
|
||||
numbers = ./numbers.mb;
|
||||
}
|
||||
'';
|
||||
description = lib.mdDoc "Quick phrase files.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -30,6 +52,16 @@ in
|
|||
config = mkIf (im.enabled == "fcitx5") {
|
||||
i18n.inputMethod.package = fcitx5Package;
|
||||
|
||||
i18n.inputMethod.fcitx5.addons = lib.optionals (cfg.quickPhrase != { }) [
|
||||
(pkgs.writeTextDir "share/fcitx5/data/QuickPhrase.mb"
|
||||
(lib.concatStringsSep "\n"
|
||||
(lib.mapAttrsToList (name: value: "${name} ${value}") cfg.quickPhrase)))
|
||||
] ++ lib.optionals (cfg.quickPhraseFiles != { }) [
|
||||
(pkgs.linkFarm "quickPhraseFiles" (lib.mapAttrs'
|
||||
(name: value: lib.nameValuePair ("share/fcitx5/data/quickphrase.d/${name}.mb") value)
|
||||
cfg.quickPhraseFiles))
|
||||
];
|
||||
|
||||
environment.variables = {
|
||||
GTK_IM_MODULE = "fcitx";
|
||||
QT_IM_MODULE = "fcitx";
|
||||
|
|
112
third_party/nixpkgs/nixos/modules/image/amend-repart-definitions.py
vendored
Normal file
112
third_party/nixpkgs/nixos/modules/image/amend-repart-definitions.py
vendored
Normal file
|
@ -0,0 +1,112 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
"""Amend systemd-repart definiton files.
|
||||
|
||||
In order to avoid Import-From-Derivation (IFD) when building images with
|
||||
systemd-repart, the definition files created by Nix need to be amended with the
|
||||
store paths from the closure.
|
||||
|
||||
This is achieved by adding CopyFiles= instructions to the definition files.
|
||||
|
||||
The arbitrary files configured via `contents` are also added to the definition
|
||||
files using the same mechanism.
|
||||
"""
|
||||
|
||||
import json
|
||||
import sys
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def add_contents_to_definition(
|
||||
definition: Path, contents: dict[str, dict[str, str]] | None
|
||||
) -> None:
|
||||
"""Add CopyFiles= instructions to a definition for all files in contents."""
|
||||
if not contents:
|
||||
return
|
||||
|
||||
copy_files_lines: list[str] = []
|
||||
for target, options in contents.items():
|
||||
source = options["source"]
|
||||
|
||||
copy_files_lines.append(f"CopyFiles={source}:{target}\n")
|
||||
|
||||
with open(definition, "a") as f:
|
||||
f.writelines(copy_files_lines)
|
||||
|
||||
|
||||
def add_closure_to_definition(
|
||||
definition: Path, closure: Path | None, strip_nix_store_prefix: bool | None
|
||||
) -> None:
|
||||
"""Add CopyFiles= instructions to a definition for all paths in the closure.
|
||||
|
||||
If strip_nix_store_prefix is True, `/nix/store` is stripped from the target path.
|
||||
"""
|
||||
if not closure:
|
||||
return
|
||||
|
||||
copy_files_lines: list[str] = []
|
||||
with open(closure, "r") as f:
|
||||
for line in f:
|
||||
if not isinstance(line, str):
|
||||
continue
|
||||
|
||||
source = Path(line.strip())
|
||||
target = str(source.relative_to("/nix/store/"))
|
||||
target = f":{target}" if strip_nix_store_prefix else ""
|
||||
|
||||
copy_files_lines.append(f"CopyFiles={source}{target}\n")
|
||||
|
||||
with open(definition, "a") as f:
|
||||
f.writelines(copy_files_lines)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
"""Amend the provided repart definitions by adding CopyFiles= instructions.
|
||||
|
||||
For each file specified in the `contents` field of a partition in the
|
||||
partiton config file, a `CopyFiles=` instruction is added to the
|
||||
corresponding definition file.
|
||||
|
||||
The same is done for every store path of the `closure` field.
|
||||
|
||||
Print the path to a directory that contains the amended repart
|
||||
definitions to stdout.
|
||||
"""
|
||||
partition_config_file = sys.argv[1]
|
||||
if not partition_config_file:
|
||||
print("No partition config file was supplied.")
|
||||
sys.exit(1)
|
||||
|
||||
repart_definitions = sys.argv[2]
|
||||
if not repart_definitions:
|
||||
print("No repart definitions were supplied.")
|
||||
sys.exit(1)
|
||||
|
||||
with open(partition_config_file, "rb") as f:
|
||||
partition_config = json.load(f)
|
||||
|
||||
if not partition_config:
|
||||
print("Partition config is empty.")
|
||||
sys.exit(1)
|
||||
|
||||
target_dir = Path("amended-repart.d")
|
||||
target_dir.mkdir()
|
||||
shutil.copytree(repart_definitions, target_dir, dirs_exist_ok=True)
|
||||
|
||||
for name, config in partition_config.items():
|
||||
definition = target_dir.joinpath(f"{name}.conf")
|
||||
definition.chmod(0o644)
|
||||
|
||||
contents = config.get("contents")
|
||||
add_contents_to_definition(definition, contents)
|
||||
|
||||
closure = config.get("closure")
|
||||
strip_nix_store_prefix = config.get("stripStorePaths")
|
||||
add_closure_to_definition(definition, closure, strip_nix_store_prefix)
|
||||
|
||||
print(target_dir.absolute())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
137
third_party/nixpkgs/nixos/modules/image/repart.md
vendored
Normal file
137
third_party/nixpkgs/nixos/modules/image/repart.md
vendored
Normal file
|
@ -0,0 +1,137 @@
|
|||
# Building Images via `systemd-repart` {#sec-image-repart}
|
||||
|
||||
You can build disk images in NixOS with the `image.repart` option provided by
|
||||
the module [image/repart.nix][]. This module uses `systemd-repart` to build the
|
||||
images and exposes it's entire interface via the `repartConfig` option.
|
||||
|
||||
[image/repart.nix]: https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/image/repart.nix
|
||||
|
||||
An example of how to build an image:
|
||||
|
||||
```nix
|
||||
{ config, modulesPath, ... }: {
|
||||
|
||||
imports = [ "${modulesPath}/image/repart.nix" ];
|
||||
|
||||
image.repart = {
|
||||
name = "image";
|
||||
partitions = {
|
||||
"esp" = {
|
||||
contents = {
|
||||
...
|
||||
};
|
||||
repartConfig = {
|
||||
Type = "esp";
|
||||
...
|
||||
};
|
||||
};
|
||||
"root" = {
|
||||
storePaths = [ config.system.build.toplevel ];
|
||||
repartConfig = {
|
||||
Type = "root";
|
||||
Label = "nixos";
|
||||
...
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## Nix Store Partition {#sec-image-repart-store-partition}
|
||||
|
||||
You can define a partition that only contains the Nix store and then mount it
|
||||
under `/nix/store`. Because the `/nix/store` part of the paths is already
|
||||
determined by the mount point, you have to set `stripNixStorePrefix = true;` so
|
||||
that the prefix is stripped from the paths before copying them into the image.
|
||||
|
||||
```nix
|
||||
fileSystems."/nix/store".device = "/dev/disk/by-partlabel/nix-store"
|
||||
|
||||
image.repart.partitions = {
|
||||
"store" = {
|
||||
storePaths = [ config.system.build.toplevel ];
|
||||
stripNixStorePrefix = true;
|
||||
repartConfig = {
|
||||
Type = "linux-generic";
|
||||
Label = "nix-store";
|
||||
...
|
||||
};
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
## Appliance Image {#sec-image-repart-appliance}
|
||||
|
||||
The `image/repart.nix` module can also be used to build self-contained [software
|
||||
appliances][].
|
||||
|
||||
[software appliances]: https://en.wikipedia.org/wiki/Software_appliance
|
||||
|
||||
The generation based update mechanism of NixOS is not suited for appliances.
|
||||
Updates of appliances are usually either performed by replacing the entire
|
||||
image with a new one or by updating partitions via an A/B scheme. See the
|
||||
[Chrome OS update process][chrome-os-update] for an example of how to achieve
|
||||
this. The appliance image built in the following example does not contain a
|
||||
`configuration.nix` and thus you will not be able to call `nixos-rebuild` from
|
||||
this system.
|
||||
|
||||
[chrome-os-update]: https://chromium.googlesource.com/aosp/platform/system/update_engine/+/HEAD/README.md
|
||||
|
||||
```nix
|
||||
let
|
||||
pkgs = import <nixpkgs> { };
|
||||
efiArch = pkgs.stdenv.hostPlatform.efiArch;
|
||||
in
|
||||
(pkgs.nixos [
|
||||
({ config, lib, pkgs, modulesPath, ... }: {
|
||||
|
||||
imports = [ "${modulesPath}/image/repart.nix" ];
|
||||
|
||||
boot.loader.grub.enable = false;
|
||||
|
||||
fileSystems."/".device = "/dev/disk/by-label/nixos";
|
||||
|
||||
image.repart = {
|
||||
name = "image";
|
||||
partitions = {
|
||||
"esp" = {
|
||||
contents = {
|
||||
"/EFI/BOOT/BOOT${lib.toUpper efiArch}.EFI".source =
|
||||
"${pkgs.systemd}/lib/systemd/boot/efi/systemd-boot${efiArch}.efi";
|
||||
|
||||
"/loader/entries/nixos.conf".source = pkgs.writeText "nixos.conf" ''
|
||||
title NixOS
|
||||
linux /EFI/nixos/kernel.efi
|
||||
initrd /EFI/nixos/initrd.efi
|
||||
options init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}
|
||||
'';
|
||||
|
||||
"/EFI/nixos/kernel.efi".source =
|
||||
"${config.boot.kernelPackages.kernel}/${config.system.boot.loader.kernelFile}";
|
||||
|
||||
"/EFI/nixos/initrd.efi".source =
|
||||
"${config.system.build.initialRamdisk}/${config.system.boot.loader.initrdFile}";
|
||||
};
|
||||
repartConfig = {
|
||||
Type = "esp";
|
||||
Format = "vfat";
|
||||
SizeMinBytes = "96M";
|
||||
};
|
||||
};
|
||||
"root" = {
|
||||
storePaths = [ config.system.build.toplevel ];
|
||||
repartConfig = {
|
||||
Type = "root";
|
||||
Format = "ext4";
|
||||
Label = "nixos";
|
||||
Minimize = "guess";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
})
|
||||
]).image
|
||||
```
|
209
third_party/nixpkgs/nixos/modules/image/repart.nix
vendored
Normal file
209
third_party/nixpkgs/nixos/modules/image/repart.nix
vendored
Normal file
|
@ -0,0 +1,209 @@
|
|||
# This module exposes options to build a disk image with a GUID Partition Table
|
||||
# (GPT). It uses systemd-repart to build the image.
|
||||
|
||||
{ config, pkgs, lib, utils, ... }:
|
||||
|
||||
let
|
||||
cfg = config.image.repart;
|
||||
|
||||
partitionOptions = {
|
||||
options = {
|
||||
storePaths = lib.mkOption {
|
||||
type = with lib.types; listOf path;
|
||||
default = [ ];
|
||||
description = lib.mdDoc "The store paths to include in the partition.";
|
||||
};
|
||||
|
||||
stripNixStorePrefix = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = lib.mdDoc ''
|
||||
Whether to strip `/nix/store/` from the store paths. This is useful
|
||||
when you want to build a partition that only contains store paths and
|
||||
is mounted under `/nix/store`.
|
||||
'';
|
||||
};
|
||||
|
||||
contents = lib.mkOption {
|
||||
type = with lib.types; attrsOf (submodule {
|
||||
options = {
|
||||
source = lib.mkOption {
|
||||
type = types.path;
|
||||
description = lib.mdDoc "Path of the source file.";
|
||||
};
|
||||
};
|
||||
});
|
||||
default = { };
|
||||
example = lib.literalExpression '' {
|
||||
"/EFI/BOOT/BOOTX64.EFI".source =
|
||||
"''${pkgs.systemd}/lib/systemd/boot/efi/systemd-bootx64.efi";
|
||||
|
||||
"/loader/entries/nixos.conf".source = systemdBootEntry;
|
||||
}
|
||||
'';
|
||||
description = lib.mdDoc "The contents to end up in the filesystem image.";
|
||||
};
|
||||
|
||||
repartConfig = lib.mkOption {
|
||||
type = with lib.types; attrsOf (oneOf [ str int bool ]);
|
||||
example = {
|
||||
Type = "home";
|
||||
SizeMinBytes = "512M";
|
||||
SizeMaxBytes = "2G";
|
||||
};
|
||||
description = lib.mdDoc ''
|
||||
Specify the repart options for a partiton as a structural setting.
|
||||
See <https://www.freedesktop.org/software/systemd/man/repart.d.html>
|
||||
for all available options.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
options.image.repart = {
|
||||
|
||||
name = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = lib.mdDoc "The name of the image.";
|
||||
};
|
||||
|
||||
seed = lib.mkOption {
|
||||
type = with lib.types; nullOr str;
|
||||
# Generated with `uuidgen`. Random but fixed to improve reproducibility.
|
||||
default = "0867da16-f251-457d-a9e8-c31f9a3c220b";
|
||||
description = lib.mdDoc ''
|
||||
A UUID to use as a seed. You can set this to `null` to explicitly
|
||||
randomize the partition UUIDs.
|
||||
'';
|
||||
};
|
||||
|
||||
split = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = lib.mdDoc ''
|
||||
Enables generation of split artifacts from partitions. If enabled, for
|
||||
each partition with SplitName= set, a separate output file containing
|
||||
just the contents of that partition is generated.
|
||||
'';
|
||||
};
|
||||
|
||||
partitions = lib.mkOption {
|
||||
type = with lib.types; attrsOf (submodule partitionOptions);
|
||||
default = { };
|
||||
example = lib.literalExpression '' {
|
||||
"10-esp" = {
|
||||
contents = {
|
||||
"/EFI/BOOT/BOOTX64.EFI".source =
|
||||
"''${pkgs.systemd}/lib/systemd/boot/efi/systemd-bootx64.efi";
|
||||
}
|
||||
repartConfig = {
|
||||
Type = "esp";
|
||||
Format = "fat";
|
||||
};
|
||||
};
|
||||
"20-root" = {
|
||||
storePaths = [ config.system.build.toplevel ];
|
||||
repartConfig = {
|
||||
Type = "root";
|
||||
Format = "ext4";
|
||||
Minimize = "guess";
|
||||
};
|
||||
};
|
||||
};
|
||||
'';
|
||||
description = lib.mdDoc ''
|
||||
Specify partitions as a set of the names of the partitions with their
|
||||
configuration as the key.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
config = {
|
||||
|
||||
system.build.image =
|
||||
let
|
||||
fileSystemToolMapping = with pkgs; {
|
||||
"vfat" = [ dosfstools mtools ];
|
||||
"ext4" = [ e2fsprogs.bin ];
|
||||
"squashfs" = [ squashfsTools ];
|
||||
"erofs" = [ erofs-utils ];
|
||||
"btrfs" = [ btrfs-progs ];
|
||||
"xfs" = [ xfsprogs ];
|
||||
};
|
||||
|
||||
fileSystems = lib.filter
|
||||
(f: f != null)
|
||||
(lib.mapAttrsToList (_n: v: v.repartConfig.Format or null) cfg.partitions);
|
||||
|
||||
fileSystemTools = builtins.concatMap (f: fileSystemToolMapping."${f}") fileSystems;
|
||||
|
||||
|
||||
makeClosure = paths: pkgs.closureInfo { rootPaths = paths; };
|
||||
|
||||
# Add the closure of the provided Nix store paths to cfg.partitions so
|
||||
# that amend-repart-definitions.py can read it.
|
||||
addClosure = _name: partitionConfig: partitionConfig // (
|
||||
lib.optionalAttrs
|
||||
(partitionConfig.storePaths or [ ] != [ ])
|
||||
{ closure = "${makeClosure partitionConfig.storePaths}/store-paths"; }
|
||||
);
|
||||
|
||||
|
||||
finalPartitions = lib.mapAttrs addClosure cfg.partitions;
|
||||
|
||||
|
||||
amendRepartDefinitions = pkgs.runCommand "amend-repart-definitions.py"
|
||||
{
|
||||
nativeBuildInputs = with pkgs; [ black ruff mypy ];
|
||||
buildInputs = [ pkgs.python3 ];
|
||||
} ''
|
||||
install ${./amend-repart-definitions.py} $out
|
||||
patchShebangs --host $out
|
||||
|
||||
black --check --diff $out
|
||||
ruff --line-length 88 $out
|
||||
mypy --strict $out
|
||||
'';
|
||||
|
||||
format = pkgs.formats.ini { };
|
||||
|
||||
definitionsDirectory = utils.systemdUtils.lib.definitions
|
||||
"repart.d"
|
||||
format
|
||||
(lib.mapAttrs (_n: v: { Partition = v.repartConfig; }) finalPartitions);
|
||||
|
||||
partitions = pkgs.writeText "partitions.json" (builtins.toJSON finalPartitions);
|
||||
in
|
||||
pkgs.runCommand cfg.name
|
||||
{
|
||||
nativeBuildInputs = with pkgs; [
|
||||
fakeroot
|
||||
systemd
|
||||
] ++ fileSystemTools;
|
||||
} ''
|
||||
amendedRepartDefinitions=$(${amendRepartDefinitions} ${partitions} ${definitionsDirectory})
|
||||
|
||||
mkdir -p $out
|
||||
cd $out
|
||||
|
||||
fakeroot systemd-repart \
|
||||
--dry-run=no \
|
||||
--empty=create \
|
||||
--size=auto \
|
||||
--seed="${cfg.seed}" \
|
||||
--definitions="$amendedRepartDefinitions" \
|
||||
--split="${lib.boolToString cfg.split}" \
|
||||
--json=pretty \
|
||||
image.raw \
|
||||
| tee repart-output.json
|
||||
'';
|
||||
|
||||
meta = {
|
||||
maintainers = with lib.maintainers; [ nikstur ];
|
||||
doc = ./repart.md;
|
||||
};
|
||||
|
||||
};
|
||||
}
|
|
@ -206,7 +206,7 @@ if [[ -z $noBootLoader ]]; then
|
|||
mount --rbind --mkdir / "$mountPoint"
|
||||
mount --make-rslave "$mountPoint"
|
||||
/run/current-system/bin/switch-to-configuration boot
|
||||
umount -R "$mountPoint" && rmdir "$mountPoint"
|
||||
umount -R "$mountPoint" && (rmdir "$mountPoint" 2>/dev/null || true)
|
||||
EOF
|
||||
)"
|
||||
fi
|
||||
|
|
|
@ -126,7 +126,7 @@ in
|
|||
# your system. Help is available in the configuration.nix(5) man page
|
||||
# and in the NixOS manual (accessible by running `nixos-help`).
|
||||
|
||||
{ config, pkgs, ... }:
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
imports =
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
./config/debug-info.nix
|
||||
./config/fonts/fontconfig.nix
|
||||
./config/fonts/fontdir.nix
|
||||
./config/fonts/fonts.nix
|
||||
./config/fonts/ghostscript.nix
|
||||
./config/fonts/packages.nix
|
||||
./config/gnu.nix
|
||||
./config/gtk/gtk-icon-cache.nix
|
||||
./config/i18n.nix
|
||||
|
@ -93,8 +93,8 @@
|
|||
./hardware/tuxedo-keyboard.nix
|
||||
./hardware/ubertooth.nix
|
||||
./hardware/uinput.nix
|
||||
./hardware/usb-modeswitch.nix
|
||||
./hardware/usb-storage.nix
|
||||
./hardware/usb-wwan.nix
|
||||
./hardware/video/amdgpu-pro.nix
|
||||
./hardware/video/bumblebee.nix
|
||||
./hardware/video/capture/mwprocapture.nix
|
||||
|
@ -221,7 +221,9 @@
|
|||
./programs/nncp.nix
|
||||
./programs/noisetorch.nix
|
||||
./programs/npm.nix
|
||||
./programs/ns-usbloader.nix
|
||||
./programs/oblogout.nix
|
||||
./programs/oddjobd.nix
|
||||
./programs/openvpn3.nix
|
||||
./programs/pantheon-tweaks.nix
|
||||
./programs/partition-manager.nix
|
||||
|
@ -263,6 +265,7 @@
|
|||
./programs/wayland/river.nix
|
||||
./programs/wayland/sway.nix
|
||||
./programs/wayland/waybar.nix
|
||||
./programs/wayland/wayfire.nix
|
||||
./programs/weylus.nix
|
||||
./programs/wireshark.nix
|
||||
./programs/xastir.nix
|
||||
|
@ -417,6 +420,7 @@
|
|||
./services/databases/neo4j.nix
|
||||
./services/databases/openldap.nix
|
||||
./services/databases/opentsdb.nix
|
||||
./services/databases/pgbouncer.nix
|
||||
./services/databases/pgmanage.nix
|
||||
./services/databases/postgresql.nix
|
||||
./services/databases/redis.nix
|
||||
|
@ -535,6 +539,7 @@
|
|||
./services/hardware/usbrelayd.nix
|
||||
./services/hardware/vdr.nix
|
||||
./services/hardware/keyd.nix
|
||||
./services/home-automation/ebusd.nix
|
||||
./services/home-automation/esphome.nix
|
||||
./services/home-automation/evcc.nix
|
||||
./services/home-automation/home-assistant.nix
|
||||
|
@ -598,6 +603,7 @@
|
|||
./services/matrix/mjolnir.nix
|
||||
./services/matrix/mx-puppet-discord.nix
|
||||
./services/matrix/pantalaimon.nix
|
||||
./services/matrix/matrix-sliding-sync.nix
|
||||
./services/matrix/synapse.nix
|
||||
./services/misc/airsonic.nix
|
||||
./services/misc/ananicy.nix
|
||||
|
@ -608,6 +614,7 @@
|
|||
./services/misc/autorandr.nix
|
||||
./services/misc/autosuspend.nix
|
||||
./services/misc/bazarr.nix
|
||||
./services/misc/bcg.nix
|
||||
./services/misc/beanstalkd.nix
|
||||
./services/misc/bees.nix
|
||||
./services/misc/bepasty.nix
|
||||
|
@ -631,6 +638,7 @@
|
|||
./services/misc/etcd.nix
|
||||
./services/misc/etebase-server.nix
|
||||
./services/misc/etesync-dav.nix
|
||||
./services/misc/evdevremapkeys.nix
|
||||
./services/misc/felix.nix
|
||||
./services/misc/freeswitch.nix
|
||||
./services/misc/fstrim.nix
|
||||
|
@ -665,6 +673,7 @@
|
|||
./services/misc/mediatomb.nix
|
||||
./services/misc/metabase.nix
|
||||
./services/misc/moonraker.nix
|
||||
./services/misc/mqtt2influxdb.nix
|
||||
./services/misc/n8n.nix
|
||||
./services/misc/nitter.nix
|
||||
./services/misc/nix-gc.nix
|
||||
|
@ -761,6 +770,7 @@
|
|||
./services/monitoring/nagios.nix
|
||||
./services/monitoring/netdata.nix
|
||||
./services/monitoring/opentelemetry-collector.nix
|
||||
./services/monitoring/osquery.nix
|
||||
./services/monitoring/parsedmarc.nix
|
||||
./services/monitoring/prometheus/alertmanager-irc-relay.nix
|
||||
./services/monitoring/prometheus/alertmanager.nix
|
||||
|
@ -855,7 +865,6 @@
|
|||
./services/networking/croc.nix
|
||||
./services/networking/dante.nix
|
||||
./services/networking/dhcpcd.nix
|
||||
./services/networking/dhcpd.nix
|
||||
./services/networking/dnscache.nix
|
||||
./services/networking/dnscrypt-proxy2.nix
|
||||
./services/networking/dnscrypt-wrapper.nix
|
||||
|
@ -1103,6 +1112,7 @@
|
|||
./services/search/meilisearch.nix
|
||||
./services/search/opensearch.nix
|
||||
./services/search/qdrant.nix
|
||||
./services/search/typesense.nix
|
||||
./services/security/aesmd.nix
|
||||
./services/security/authelia.nix
|
||||
./services/security/certmgr.nix
|
||||
|
@ -1142,6 +1152,7 @@
|
|||
./services/security/vaultwarden/default.nix
|
||||
./services/security/yubikey-agent.nix
|
||||
./services/system/automatic-timezoned.nix
|
||||
./services/system/bpftune.nix
|
||||
./services/system/cachix-agent/default.nix
|
||||
./services/system/cachix-watch-store.nix
|
||||
./services/system/cloud-init.nix
|
||||
|
@ -1255,6 +1266,7 @@
|
|||
./services/web-apps/rss-bridge.nix
|
||||
./services/web-apps/selfoss.nix
|
||||
./services/web-apps/shiori.nix
|
||||
./services/web-apps/slskd.nix
|
||||
./services/web-apps/snipe-it.nix
|
||||
./services/web-apps/sogo.nix
|
||||
./services/web-apps/trilium.nix
|
||||
|
@ -1387,6 +1399,7 @@
|
|||
./system/boot/systemd/oomd.nix
|
||||
./system/boot/systemd/repart.nix
|
||||
./system/boot/systemd/shutdown.nix
|
||||
./system/boot/systemd/sysupdate.nix
|
||||
./system/boot/systemd/tmpfiles.nix
|
||||
./system/boot/systemd/user.nix
|
||||
./system/boot/systemd/userdbd.nix
|
||||
|
|
|
@ -21,7 +21,8 @@ in
|
|||
../virtualisation/nixos-containers.nix
|
||||
../services/x11/desktop-managers/xterm.nix
|
||||
];
|
||||
config = { };
|
||||
# swraid's default depends on stateVersion
|
||||
config.boot.swraid.enable = false;
|
||||
options.boot.isContainer = lib.mkOption { default = false; internal = true; };
|
||||
}
|
||||
];
|
||||
|
|
|
@ -123,8 +123,8 @@ in
|
|||
boot.extraModulePackages = [ (lib.mkIf cfg.netatop.enable cfg.netatop.package) ];
|
||||
systemd =
|
||||
let
|
||||
mkSystemd = type: cond: name: restartTriggers: {
|
||||
${name} = lib.mkIf cond {
|
||||
mkSystemd = type: name: restartTriggers: {
|
||||
${name} = {
|
||||
inherit restartTriggers;
|
||||
wantedBy = [ (if type == "services" then "multi-user.target" else if type == "timers" then "timers.target" else null) ];
|
||||
};
|
||||
|
@ -134,42 +134,44 @@ in
|
|||
in
|
||||
{
|
||||
packages = [ atop (lib.mkIf cfg.netatop.enable cfg.netatop.package) ];
|
||||
services =
|
||||
mkService cfg.atopService.enable "atop" [ atop ]
|
||||
// lib.mkIf cfg.atopService.enable {
|
||||
# always convert logs to newer version first
|
||||
# XXX might trigger TimeoutStart but restarting atop.service will
|
||||
# convert remainings logs and start eventually
|
||||
atop.serviceConfig.ExecStartPre = pkgs.writeShellScript "atop-update-log-format" ''
|
||||
set -e -u
|
||||
shopt -s nullglob
|
||||
for logfile in "$LOGPATH"/atop_*
|
||||
do
|
||||
${atop}/bin/atopconvert "$logfile" "$logfile".new
|
||||
# only replace old file if version was upgraded to avoid
|
||||
# false positives for atop-rotate.service
|
||||
if ! ${pkgs.diffutils}/bin/cmp -s "$logfile" "$logfile".new
|
||||
then
|
||||
${pkgs.coreutils}/bin/mv -v -f "$logfile".new "$logfile"
|
||||
else
|
||||
${pkgs.coreutils}/bin/rm -f "$logfile".new
|
||||
fi
|
||||
done
|
||||
'';
|
||||
}
|
||||
// mkService cfg.atopacctService.enable "atopacct" [ atop ]
|
||||
// mkService cfg.netatop.enable "netatop" [ cfg.netatop.package ]
|
||||
// mkService cfg.atopgpu.enable "atopgpu" [ atop ];
|
||||
timers = mkTimer cfg.atopRotateTimer.enable "atop-rotate" [ atop ];
|
||||
services = lib.mkMerge [
|
||||
(lib.mkIf cfg.atopService.enable (lib.recursiveUpdate
|
||||
(mkService "atop" [ atop ])
|
||||
{
|
||||
# always convert logs to newer version first
|
||||
# XXX might trigger TimeoutStart but restarting atop.service will
|
||||
# convert remainings logs and start eventually
|
||||
atop.preStart = ''
|
||||
set -e -u
|
||||
shopt -s nullglob
|
||||
for logfile in "$LOGPATH"/atop_*
|
||||
do
|
||||
${atop}/bin/atopconvert "$logfile" "$logfile".new
|
||||
# only replace old file if version was upgraded to avoid
|
||||
# false positives for atop-rotate.service
|
||||
if ! ${pkgs.diffutils}/bin/cmp -s "$logfile" "$logfile".new
|
||||
then
|
||||
${pkgs.coreutils}/bin/mv -v -f "$logfile".new "$logfile"
|
||||
else
|
||||
${pkgs.coreutils}/bin/rm -f "$logfile".new
|
||||
fi
|
||||
done
|
||||
'';
|
||||
}))
|
||||
(lib.mkIf cfg.atopacctService.enable (mkService "atopacct" [ atop ]))
|
||||
(lib.mkIf cfg.netatop.enable (mkService "netatop" [ cfg.netatop.package ]))
|
||||
(lib.mkIf cfg.atopgpu.enable (mkService "atopgpu" [ atop ]))
|
||||
];
|
||||
timers = lib.mkIf cfg.atopRotateTimer.enable (mkTimer "atop-rotate" [ atop ]);
|
||||
};
|
||||
|
||||
security.wrappers = lib.mkIf cfg.setuidWrapper.enable {
|
||||
atop =
|
||||
{ setuid = true;
|
||||
owner = "root";
|
||||
group = "root";
|
||||
source = "${atop}/bin/atop";
|
||||
};
|
||||
atop = {
|
||||
setuid = true;
|
||||
owner = "root";
|
||||
group = "root";
|
||||
source = "${atop}/bin/atop";
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
|
|
|
@ -233,7 +233,6 @@ in
|
|||
nixpkgs.config.firefox = {
|
||||
enableBrowserpass = nmh.browserpass;
|
||||
enableBukubrow = nmh.bukubrow;
|
||||
enableEUWebID = nmh.euwebid;
|
||||
enableTridactylNative = nmh.tridactyl;
|
||||
enableUgetIntegrator = nmh.ugetIntegrator;
|
||||
enableFXCastBridge = nmh.fxCast;
|
||||
|
|
|
@ -37,7 +37,7 @@ let
|
|||
babelfishTranslate = path: name:
|
||||
pkgs.runCommandLocal "${name}.fish" {
|
||||
nativeBuildInputs = [ pkgs.babelfish ];
|
||||
} "${pkgs.babelfish}/bin/babelfish < ${path} > $out;";
|
||||
} "babelfish < ${path} > $out;";
|
||||
|
||||
in
|
||||
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
with lib; let
|
||||
cfg = config.programs.hyprland;
|
||||
|
||||
defaultHyprlandPackage = pkgs.hyprland.override {
|
||||
enableXWayland = cfg.xwayland.enable;
|
||||
hidpiXWayland = cfg.xwayland.hidpi;
|
||||
nvidiaPatches = cfg.nvidiaPatches;
|
||||
finalPortalPackage = cfg.portalPackage.override {
|
||||
hyprland-share-picker = pkgs.hyprland-share-picker.override {
|
||||
hyprland = cfg.finalPackage;
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
|
@ -25,24 +25,25 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
type = types.path;
|
||||
default = defaultHyprlandPackage;
|
||||
defaultText = literalExpression ''
|
||||
pkgs.hyprland.override {
|
||||
enableXWayland = config.programs.hyprland.xwayland.enable;
|
||||
hidpiXWayland = config.programs.hyprland.xwayland.hidpi;
|
||||
nvidiaPatches = config.programs.hyprland.nvidiaPatches;
|
||||
}
|
||||
'';
|
||||
example = literalExpression "<Hyprland flake>.packages.<system>.default";
|
||||
package = mkPackageOptionMD pkgs "hyprland" { };
|
||||
|
||||
finalPackage = mkOption {
|
||||
type = types.package;
|
||||
readOnly = true;
|
||||
default = cfg.package.override {
|
||||
enableXWayland = cfg.xwayland.enable;
|
||||
hidpiXWayland = cfg.xwayland.hidpi;
|
||||
nvidiaPatches = cfg.nvidiaPatches;
|
||||
};
|
||||
defaultText = literalExpression
|
||||
"`wayland.windowManager.hyprland.package` with applied configuration";
|
||||
description = mdDoc ''
|
||||
The Hyprland package to use.
|
||||
Setting this option will make {option}`programs.hyprland.xwayland` and
|
||||
{option}`programs.hyprland.nvidiaPatches` not work.
|
||||
The Hyprland package after applying configuration.
|
||||
'';
|
||||
};
|
||||
|
||||
portalPackage = mkPackageOptionMD pkgs "xdg-desktop-portal-hyprland" { };
|
||||
|
||||
xwayland = {
|
||||
enable = mkEnableOption (mdDoc "XWayland") // { default = true; };
|
||||
hidpi = mkEnableOption null // {
|
||||
|
@ -57,9 +58,9 @@ in
|
|||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
environment.systemPackages = [ cfg.finalPackage ];
|
||||
|
||||
fonts.enableDefaultFonts = mkDefault true;
|
||||
fonts.enableDefaultPackages = mkDefault true;
|
||||
hardware.opengl.enable = mkDefault true;
|
||||
|
||||
programs = {
|
||||
|
@ -69,13 +70,11 @@ in
|
|||
|
||||
security.polkit.enable = true;
|
||||
|
||||
services.xserver.displayManager.sessionPackages = [ cfg.package ];
|
||||
services.xserver.displayManager.sessionPackages = [ cfg.finalPackage ];
|
||||
|
||||
xdg.portal = {
|
||||
enable = mkDefault true;
|
||||
extraPortals = [
|
||||
pkgs.xdg-desktop-portal-hyprland
|
||||
];
|
||||
extraPortals = [ finalPortalPackage ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ in {
|
|||
};
|
||||
|
||||
hardware.opengl.enable = lib.mkDefault true;
|
||||
fonts.enableDefaultFonts = lib.mkDefault true;
|
||||
fonts.enableDefaultPackages = lib.mkDefault true;
|
||||
programs.dconf.enable = lib.mkDefault true;
|
||||
programs.xwayland.enable = lib.mkDefault true;
|
||||
|
||||
|
|
18
third_party/nixpkgs/nixos/modules/programs/ns-usbloader.nix
vendored
Normal file
18
third_party/nixpkgs/nixos/modules/programs/ns-usbloader.nix
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.programs.ns-usbloader;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
programs.ns-usbloader = {
|
||||
enable = lib.mkEnableOption (lib.mdDoc "ns-usbloader application with udev rules applied");
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
environment.systemPackages = [ pkgs.ns-usbloader ];
|
||||
services.udev.packages = [ pkgs.ns-usbloader ];
|
||||
};
|
||||
|
||||
meta.maintainers = pkgs.ns-usbloader.meta.maintainers;
|
||||
}
|
33
third_party/nixpkgs/nixos/modules/programs/oddjobd.nix
vendored
Normal file
33
third_party/nixpkgs/nixos/modules/programs/oddjobd.nix
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
|
||||
let
|
||||
cfg = config.programs.oddjobd;
|
||||
in
|
||||
{
|
||||
options.programs.oddjobd = {
|
||||
enable = lib.mkEnableOption "oddjob";
|
||||
package = lib.mkPackageOption pkgs "oddjob" {};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions = [
|
||||
{ assertion = false;
|
||||
message = "The oddjob service was found to be broken without NixOS test or maintainer. Please take ownership of this service.";
|
||||
}
|
||||
];
|
||||
systemd.packages = [ cfg.package ];
|
||||
|
||||
systemd.services.oddjobd = {
|
||||
wantedBy = [ "multi-user.target"];
|
||||
after = [ "network.target"];
|
||||
description = "DBUS Odd-job Daemon";
|
||||
enable = true;
|
||||
documentation = [ "man:oddjobd(8)" "man:oddjobd.conf(5)" ];
|
||||
serviceConfig = {
|
||||
Type = "dbus";
|
||||
BusName = "org.freedesktop.oddjob";
|
||||
ExecStart = "${lib.getBin cfg.package}/bin/oddjobd";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
48
third_party/nixpkgs/nixos/modules/programs/wayland/wayfire.nix
vendored
Normal file
48
third_party/nixpkgs/nixos/modules/programs/wayland/wayfire.nix
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
{ config, lib, pkgs, ...}:
|
||||
let
|
||||
cfg = config.programs.wayfire;
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [ rewine ];
|
||||
|
||||
options.programs.wayfire = {
|
||||
enable = lib.mkEnableOption (lib.mdDoc "Wayfire, a wayland compositor based on wlroots.");
|
||||
|
||||
package = lib.mkPackageOptionMD pkgs "wayfire" { };
|
||||
|
||||
plugins = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.package;
|
||||
default = with pkgs.wayfirePlugins; [ wcm wf-shell ];
|
||||
defaultText = lib.literalExpression "with pkgs.wayfirePlugins; [ wcm wf-shell ]";
|
||||
example = lib.literalExpression ''
|
||||
with pkgs.wayfirePlugins; [
|
||||
wcm
|
||||
wf-shell
|
||||
wayfire-plugins-extra
|
||||
];
|
||||
'';
|
||||
description = lib.mdDoc ''
|
||||
Additional plugins to use with the wayfire window manager.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = let
|
||||
finalPackage = pkgs.wayfire-with-plugins.override {
|
||||
wayfire = cfg.package;
|
||||
plugins = cfg.plugins;
|
||||
};
|
||||
in
|
||||
lib.mkIf cfg.enable {
|
||||
environment.systemPackages = [
|
||||
finalPackage
|
||||
];
|
||||
|
||||
services.xserver.displayManager.sessionPackages = [ finalPackage ];
|
||||
|
||||
xdg.portal = {
|
||||
enable = lib.mkDefault true;
|
||||
wlr.enable = lib.mkDefault true;
|
||||
};
|
||||
};
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
};
|
||||
|
||||
hardware.opengl.enable = mkDefault true;
|
||||
fonts.enableDefaultFonts = mkDefault true;
|
||||
fonts.enableDefaultPackages = mkDefault true;
|
||||
|
||||
programs = {
|
||||
dconf.enable = mkDefault true;
|
||||
|
|
11
third_party/nixpkgs/nixos/modules/rename.nix
vendored
11
third_party/nixpkgs/nixos/modules/rename.nix
vendored
|
@ -72,7 +72,6 @@ in
|
|||
(mkRemovedOptionModule [ "services" "mesos" ] "The corresponding package was removed from nixpkgs.")
|
||||
(mkRemovedOptionModule [ "services" "moinmoin" ] "The corresponding package was removed from nixpkgs.")
|
||||
(mkRemovedOptionModule [ "services" "mwlib" ] "The corresponding package was removed from nixpkgs.")
|
||||
(mkRemovedOptionModule [ "services" "osquery" ] "The osquery module has been removed")
|
||||
(mkRemovedOptionModule [ "services" "pantheon" "files" ] ''
|
||||
This module was removed, please add pkgs.pantheon.elementary-files to environment.systemPackages directly.
|
||||
'')
|
||||
|
@ -115,6 +114,16 @@ in
|
|||
(mkRemovedOptionModule [ "services" "rtsp-simple-server" ] "Package has been completely rebranded by upstream as mediamtx, and thus the service and the package were renamed in NixOS as well.")
|
||||
|
||||
(mkRemovedOptionModule [ "i18n" "inputMethod" "fcitx" ] "The fcitx module has been removed. Please use fcitx5 instead")
|
||||
(mkRemovedOptionModule [ "services" "dhcpd4" ] ''
|
||||
The dhcpd4 module has been removed because ISC DHCP reached its end of life.
|
||||
See https://www.isc.org/blogs/isc-dhcp-eol/ for details.
|
||||
Please switch to a different implementation like kea or dnsmasq.
|
||||
'')
|
||||
(mkRemovedOptionModule [ "services" "dhcpd6" ] ''
|
||||
The dhcpd6 module has been removed because ISC DHCP reached its end of life.
|
||||
See https://www.isc.org/blogs/isc-dhcp-eol/ for details.
|
||||
Please switch to a different implementation like kea or dnsmasq.
|
||||
'')
|
||||
|
||||
# Do NOT add any option renames here, see top of the file
|
||||
];
|
||||
|
|
|
@ -62,7 +62,7 @@ config.security.apparmor.includes = {
|
|||
include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/base"
|
||||
r ${pkgs.stdenv.cc.libc}/share/locale/**,
|
||||
r ${pkgs.stdenv.cc.libc}/share/locale.alias,
|
||||
${lib.optionalString (pkgs.glibcLocales != null) "r ${pkgs.glibcLocales}/lib/locale/locale-archive,"}
|
||||
r ${config.i18n.glibcLocales}/lib/locale/locale-archive,
|
||||
${etcRule "localtime"}
|
||||
r ${pkgs.tzdata}/share/zoneinfo/**,
|
||||
r ${pkgs.stdenv.cc.libc}/share/i18n/**,
|
||||
|
@ -72,7 +72,7 @@ config.security.apparmor.includes = {
|
|||
|
||||
# bash inspects filesystems at startup
|
||||
# and /etc/mtab is linked to /proc/mounts
|
||||
@{PROC}/mounts
|
||||
r @{PROC}/mounts,
|
||||
|
||||
# system-wide bash configuration
|
||||
'' + lib.concatMapStringsSep "\n" etcRule [
|
||||
|
@ -211,6 +211,9 @@ config.security.apparmor.includes = {
|
|||
"abstractions/nis" = ''
|
||||
include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/nis"
|
||||
'';
|
||||
"abstractions/nss-systemd" = ''
|
||||
include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/nss-systemd"
|
||||
'';
|
||||
"abstractions/nvidia" = ''
|
||||
include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/nvidia"
|
||||
${etcRule "vdpau_wrapper.cfg"}
|
||||
|
@ -279,6 +282,8 @@ config.security.apparmor.includes = {
|
|||
r /var/lib/acme/*/chain.pem,
|
||||
r /var/lib/acme/*/fullchain.pem,
|
||||
|
||||
r /etc/pki/tls/certs/,
|
||||
|
||||
'' + lib.concatMapStringsSep "\n" etcRule [
|
||||
"ssl/certs/ca-certificates.crt"
|
||||
"ssl/certs/ca-bundle.crt"
|
||||
|
|
|
@ -44,5 +44,5 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
meta.maintainers = with maintainers; [ SuperSandro2000 ];
|
||||
meta.maintainers = with maintainers; [ ];
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ let
|
|||
}
|
||||
trap on_exit EXIT
|
||||
|
||||
archiveName="${if cfg.archiveBaseName == null then "" else cfg.archiveBaseName + "-"}$(date ${cfg.dateFormat})"
|
||||
archiveName="${optionalString (cfg.archiveBaseName != null) (cfg.archiveBaseName + "-")}$(date ${cfg.dateFormat})"
|
||||
archiveSuffix="${optionalString cfg.appendFailedSuffix ".failed"}"
|
||||
${cfg.preHook}
|
||||
'' + optionalString cfg.doInit ''
|
||||
|
|
|
@ -32,6 +32,8 @@ in
|
|||
services.tarsnap = {
|
||||
enable = mkEnableOption (lib.mdDoc "periodic tarsnap backups");
|
||||
|
||||
package = mkPackageOption pkgs "tarsnap" { };
|
||||
|
||||
keyfile = mkOption {
|
||||
type = types.str;
|
||||
default = "/root/tarsnap.key";
|
||||
|
@ -307,7 +309,7 @@ in
|
|||
requires = [ "network-online.target" ];
|
||||
after = [ "network-online.target" ];
|
||||
|
||||
path = with pkgs; [ iputils tarsnap util-linux ];
|
||||
path = with pkgs; [ iputils gcfg.package util-linux ];
|
||||
|
||||
# In order for the persistent tarsnap timer to work reliably, we have to
|
||||
# make sure that the tarsnap server is reachable after systemd starts up
|
||||
|
@ -318,7 +320,7 @@ in
|
|||
'';
|
||||
|
||||
script = let
|
||||
tarsnap = ''tarsnap --configfile "/etc/tarsnap/${name}.conf"'';
|
||||
tarsnap = ''${lib.getExe gcfg.package} --configfile "/etc/tarsnap/${name}.conf"'';
|
||||
run = ''${tarsnap} -c -f "${name}-$(date +"%Y%m%d%H%M%S")" \
|
||||
${optionalString cfg.verbose "-v"} \
|
||||
${optionalString cfg.explicitSymlinks "-H"} \
|
||||
|
@ -355,10 +357,10 @@ in
|
|||
description = "Tarsnap restore '${name}'";
|
||||
requires = [ "network-online.target" ];
|
||||
|
||||
path = with pkgs; [ iputils tarsnap util-linux ];
|
||||
path = with pkgs; [ iputils gcfg.package util-linux ];
|
||||
|
||||
script = let
|
||||
tarsnap = ''tarsnap --configfile "/etc/tarsnap/${name}.conf"'';
|
||||
tarsnap = ''${lib.getExe gcfg.package} --configfile "/etc/tarsnap/${name}.conf"'';
|
||||
lastArchive = "$(${tarsnap} --list-archives | sort | tail -1)";
|
||||
run = ''${tarsnap} -x -f "${lastArchive}" ${optionalString cfg.verbose "-v"}'';
|
||||
cachedir = escapeShellArg cfg.cachedir;
|
||||
|
@ -402,6 +404,6 @@ in
|
|||
{ text = configFile name cfg;
|
||||
}) gcfg.archives;
|
||||
|
||||
environment.systemPackages = [ pkgs.tarsnap ];
|
||||
environment.systemPackages = [ gcfg.package ];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -6,9 +6,6 @@ let
|
|||
defaultGroup = "patroni";
|
||||
format = pkgs.formats.yaml { };
|
||||
|
||||
#boto doesn't support python 3.10 yet
|
||||
patroni = pkgs.patroni.override { pythonPackages = pkgs.python39Packages; };
|
||||
|
||||
configFileName = "patroni-${cfg.scope}-${cfg.name}.yaml";
|
||||
configFile = format.generate configFileName cfg.settings;
|
||||
in
|
||||
|
@ -224,7 +221,7 @@ in
|
|||
|
||||
script = ''
|
||||
${concatStringsSep "\n" (attrValues (mapAttrs (name: path: ''export ${name}="$(< ${escapeShellArg path})"'') cfg.environmentFiles))}
|
||||
exec ${patroni}/bin/patroni ${configFile}
|
||||
exec ${pkgs.patroni}/bin/patroni ${configFile}
|
||||
'';
|
||||
|
||||
serviceConfig = mkMerge [
|
||||
|
@ -252,7 +249,7 @@ in
|
|||
'';
|
||||
|
||||
environment.systemPackages = [
|
||||
patroni
|
||||
pkgs.patroni
|
||||
cfg.postgresqlPackage
|
||||
(mkIf cfg.raft pkgs.python310Packages.pysyncobj)
|
||||
];
|
||||
|
|
|
@ -31,6 +31,7 @@ in
|
|||
type = types.package;
|
||||
default = pkgs.boinc;
|
||||
defaultText = literalExpression "pkgs.boinc";
|
||||
example = literalExpression "pkgs.boinc-headless";
|
||||
description = lib.mdDoc ''
|
||||
Which BOINC package to use.
|
||||
'';
|
||||
|
|
|
@ -1,64 +1,49 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.buildkite-agents;
|
||||
|
||||
mkHookOption = { name, description, example ? null }: {
|
||||
inherit name;
|
||||
value = mkOption {
|
||||
default = null;
|
||||
description = lib.mdDoc description;
|
||||
type = types.nullOr types.lines;
|
||||
} // (lib.optionalAttrs (example != null) { inherit example; });
|
||||
};
|
||||
mkHookOptions = hooks: listToAttrs (map mkHookOption hooks);
|
||||
|
||||
hooksDir = cfg: let
|
||||
mkHookEntry = name: value: ''
|
||||
cat > $out/${name} <<'EOF'
|
||||
#! ${pkgs.runtimeShell}
|
||||
set -e
|
||||
${value}
|
||||
EOF
|
||||
chmod 755 $out/${name}
|
||||
hooksDir = hooks:
|
||||
let
|
||||
mkHookEntry = name: text: ''
|
||||
ln --symbolic ${pkgs.writeShellApplication { inherit name text; }}/bin/${name} $out/${name}
|
||||
'';
|
||||
in
|
||||
pkgs.runCommandLocal "buildkite-agent-hooks" { } ''
|
||||
mkdir $out
|
||||
${lib.concatStringsSep "\n" (lib.mapAttrsToList mkHookEntry hooks)}
|
||||
'';
|
||||
in pkgs.runCommand "buildkite-agent-hooks" { preferLocalBuild = true; } ''
|
||||
mkdir $out
|
||||
${concatStringsSep "\n" (mapAttrsToList mkHookEntry (filterAttrs (n: v: v != null) cfg.hooks))}
|
||||
'';
|
||||
|
||||
buildkiteOptions = { name ? "", config, ... }: {
|
||||
options = {
|
||||
enable = mkOption {
|
||||
enable = lib.mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
type = lib.types.bool;
|
||||
description = lib.mdDoc "Whether to enable this buildkite agent";
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
package = lib.mkOption {
|
||||
default = pkgs.buildkite-agent;
|
||||
defaultText = literalExpression "pkgs.buildkite-agent";
|
||||
defaultText = lib.literalExpression "pkgs.buildkite-agent";
|
||||
description = lib.mdDoc "Which buildkite-agent derivation to use";
|
||||
type = types.package;
|
||||
type = lib.types.package;
|
||||
};
|
||||
|
||||
dataDir = mkOption {
|
||||
dataDir = lib.mkOption {
|
||||
default = "/var/lib/buildkite-agent-${name}";
|
||||
description = lib.mdDoc "The workdir for the agent";
|
||||
type = types.str;
|
||||
type = lib.types.str;
|
||||
};
|
||||
|
||||
runtimePackages = mkOption {
|
||||
runtimePackages = lib.mkOption {
|
||||
default = [ pkgs.bash pkgs.gnutar pkgs.gzip pkgs.git pkgs.nix ];
|
||||
defaultText = literalExpression "[ pkgs.bash pkgs.gnutar pkgs.gzip pkgs.git pkgs.nix ]";
|
||||
defaultText = lib.literalExpression "[ pkgs.bash pkgs.gnutar pkgs.gzip pkgs.git pkgs.nix ]";
|
||||
description = lib.mdDoc "Add programs to the buildkite-agent environment";
|
||||
type = types.listOf types.package;
|
||||
type = lib.types.listOf lib.types.package;
|
||||
};
|
||||
|
||||
tokenPath = mkOption {
|
||||
type = types.path;
|
||||
tokenPath = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
description = lib.mdDoc ''
|
||||
The token from your Buildkite "Agents" page.
|
||||
|
||||
|
@ -67,25 +52,25 @@ let
|
|||
'';
|
||||
};
|
||||
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
name = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "%hostname-${name}-%n";
|
||||
description = lib.mdDoc ''
|
||||
The name of the agent as seen in the buildkite dashboard.
|
||||
'';
|
||||
};
|
||||
|
||||
tags = mkOption {
|
||||
type = types.attrsOf (types.either types.str (types.listOf types.str));
|
||||
default = {};
|
||||
example = { queue = "default"; docker = "true"; ruby2 ="true"; };
|
||||
tags = lib.mkOption {
|
||||
type = lib.types.attrsOf (lib.types.either lib.types.str (lib.types.listOf lib.types.str));
|
||||
default = { };
|
||||
example = { queue = "default"; docker = "true"; ruby2 = "true"; };
|
||||
description = lib.mdDoc ''
|
||||
Tags for the agent.
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
extraConfig = lib.mkOption {
|
||||
type = lib.types.lines;
|
||||
default = "";
|
||||
example = "debug=true";
|
||||
description = lib.mdDoc ''
|
||||
|
@ -93,8 +78,8 @@ let
|
|||
'';
|
||||
};
|
||||
|
||||
privateSshKeyPath = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
privateSshKeyPath = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.path;
|
||||
default = null;
|
||||
## maximum care is taken so that secrets (ssh keys and the CI token)
|
||||
## don't end up in the Nix store.
|
||||
|
@ -108,67 +93,25 @@ let
|
|||
'';
|
||||
};
|
||||
|
||||
hooks = mkHookOptions [
|
||||
{ name = "checkout";
|
||||
description = ''
|
||||
The `checkout` hook script will replace the default checkout routine of the
|
||||
bootstrap.sh script. You can use this hook to do your own SCM checkout
|
||||
behaviour
|
||||
''; }
|
||||
{ name = "command";
|
||||
description = ''
|
||||
The `command` hook script will replace the default implementation of running
|
||||
the build command.
|
||||
''; }
|
||||
{ name = "environment";
|
||||
description = ''
|
||||
The `environment` hook will run before all other commands, and can be used
|
||||
to set up secrets, data, etc. Anything exported in hooks will be available
|
||||
to the build script.
|
||||
hooks = lib.mkOption {
|
||||
type = lib.types.attrsOf lib.types.lines;
|
||||
default = { };
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
environment = '''
|
||||
export SECRET_VAR=`head -1 /run/keys/secret`
|
||||
''';
|
||||
}'';
|
||||
description = lib.mdDoc ''
|
||||
"Agent" hooks to install.
|
||||
See <https://buildkite.com/docs/agent/v3/hooks> for possible options.
|
||||
'';
|
||||
};
|
||||
|
||||
Note: the contents of this file will be copied to the world-readable
|
||||
Nix store.
|
||||
'';
|
||||
example = ''
|
||||
export SECRET_VAR=`head -1 /run/keys/secret`
|
||||
''; }
|
||||
{ name = "post-artifact";
|
||||
description = ''
|
||||
The `post-artifact` hook will run just after artifacts are uploaded
|
||||
''; }
|
||||
{ name = "post-checkout";
|
||||
description = ''
|
||||
The `post-checkout` hook will run after the bootstrap script has checked out
|
||||
your projects source code.
|
||||
''; }
|
||||
{ name = "post-command";
|
||||
description = ''
|
||||
The `post-command` hook will run after the bootstrap script has run your
|
||||
build commands
|
||||
''; }
|
||||
{ name = "pre-artifact";
|
||||
description = ''
|
||||
The `pre-artifact` hook will run just before artifacts are uploaded
|
||||
''; }
|
||||
{ name = "pre-checkout";
|
||||
description = ''
|
||||
The `pre-checkout` hook will run just before your projects source code is
|
||||
checked out from your SCM provider
|
||||
''; }
|
||||
{ name = "pre-command";
|
||||
description = ''
|
||||
The `pre-command` hook will run just before your build command runs
|
||||
''; }
|
||||
{ name = "pre-exit";
|
||||
description = ''
|
||||
The `pre-exit` hook will run just before your build job finishes
|
||||
''; }
|
||||
];
|
||||
|
||||
hooksPath = mkOption {
|
||||
type = types.path;
|
||||
default = hooksDir config;
|
||||
defaultText = literalMD "generated from {option}`services.buildkite-agents.<name>.hooks`";
|
||||
hooksPath = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = hooksDir config.hooks;
|
||||
defaultText = lib.literalMD "generated from {option}`services.buildkite-agents.<name>.hooks`";
|
||||
description = lib.mdDoc ''
|
||||
Path to the directory storing the hooks.
|
||||
Consider using {option}`services.buildkite-agents.<name>.hooks.<name>`
|
||||
|
@ -176,10 +119,10 @@ let
|
|||
'';
|
||||
};
|
||||
|
||||
shell = mkOption {
|
||||
type = types.str;
|
||||
shell = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "${pkgs.bash}/bin/bash -e -c";
|
||||
defaultText = literalExpression ''"''${pkgs.bash}/bin/bash -e -c"'';
|
||||
defaultText = lib.literalExpression ''"''${pkgs.bash}/bin/bash -e -c"'';
|
||||
description = lib.mdDoc ''
|
||||
Command that buildkite-agent 3 will execute when it spawns a shell.
|
||||
'';
|
||||
|
@ -190,9 +133,9 @@ let
|
|||
mapAgents = function: lib.mkMerge (lib.mapAttrsToList function enabledAgents);
|
||||
in
|
||||
{
|
||||
options.services.buildkite-agents = mkOption {
|
||||
type = types.attrsOf (types.submodule buildkiteOptions);
|
||||
default = {};
|
||||
options.services.buildkite-agents = lib.mkOption {
|
||||
type = lib.types.attrsOf (lib.types.submodule buildkiteOptions);
|
||||
default = { };
|
||||
description = lib.mdDoc ''
|
||||
Attribute set of buildkite agents.
|
||||
The attribute key is combined with the hostname and a unique integer to
|
||||
|
@ -213,23 +156,24 @@ in
|
|||
};
|
||||
});
|
||||
config.users.groups = mapAgents (name: cfg: {
|
||||
"buildkite-agent-${name}" = {};
|
||||
"buildkite-agent-${name}" = { };
|
||||
});
|
||||
|
||||
config.systemd.services = mapAgents (name: cfg: {
|
||||
"buildkite-agent-${name}" =
|
||||
{ description = "Buildkite Agent";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
path = cfg.runtimePackages ++ [ cfg.package pkgs.coreutils ];
|
||||
environment = config.networking.proxy.envVars // {
|
||||
HOME = cfg.dataDir;
|
||||
NIX_REMOTE = "daemon";
|
||||
};
|
||||
"buildkite-agent-${name}" = {
|
||||
description = "Buildkite Agent";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
path = cfg.runtimePackages ++ [ cfg.package pkgs.coreutils ];
|
||||
environment = config.networking.proxy.envVars // {
|
||||
HOME = cfg.dataDir;
|
||||
NIX_REMOTE = "daemon";
|
||||
};
|
||||
|
||||
## NB: maximum care is taken so that secrets (ssh keys and the CI token)
|
||||
## don't end up in the Nix store.
|
||||
preStart = let
|
||||
## NB: maximum care is taken so that secrets (ssh keys and the CI token)
|
||||
## don't end up in the Nix store.
|
||||
preStart =
|
||||
let
|
||||
sshDir = "${cfg.dataDir}/.ssh";
|
||||
tagStr = name: value:
|
||||
if lib.isList value
|
||||
|
@ -237,44 +181,39 @@ in
|
|||
else "${name}=${value}";
|
||||
tagsStr = lib.concatStringsSep "," (lib.mapAttrsToList tagStr cfg.tags);
|
||||
in
|
||||
optionalString (cfg.privateSshKeyPath != null) ''
|
||||
mkdir -m 0700 -p "${sshDir}"
|
||||
install -m600 "${toString cfg.privateSshKeyPath}" "${sshDir}/id_rsa"
|
||||
'' + ''
|
||||
cat > "${cfg.dataDir}/buildkite-agent.cfg" <<EOF
|
||||
token="$(cat ${toString cfg.tokenPath})"
|
||||
name="${cfg.name}"
|
||||
shell="${cfg.shell}"
|
||||
tags="${tagsStr}"
|
||||
build-path="${cfg.dataDir}/builds"
|
||||
hooks-path="${cfg.hooksPath}"
|
||||
${cfg.extraConfig}
|
||||
EOF
|
||||
'';
|
||||
lib.optionalString (cfg.privateSshKeyPath != null) ''
|
||||
mkdir -m 0700 -p "${sshDir}"
|
||||
install -m600 "${toString cfg.privateSshKeyPath}" "${sshDir}/id_rsa"
|
||||
'' + ''
|
||||
cat > "${cfg.dataDir}/buildkite-agent.cfg" <<EOF
|
||||
token="$(cat ${toString cfg.tokenPath})"
|
||||
name="${cfg.name}"
|
||||
shell="${cfg.shell}"
|
||||
tags="${tagsStr}"
|
||||
build-path="${cfg.dataDir}/builds"
|
||||
hooks-path="${cfg.hooksPath}"
|
||||
${cfg.extraConfig}
|
||||
EOF
|
||||
'';
|
||||
|
||||
serviceConfig =
|
||||
{ ExecStart = "${cfg.package}/bin/buildkite-agent start --config ${cfg.dataDir}/buildkite-agent.cfg";
|
||||
User = "buildkite-agent-${name}";
|
||||
RestartSec = 5;
|
||||
Restart = "on-failure";
|
||||
TimeoutSec = 10;
|
||||
# set a long timeout to give buildkite-agent a chance to finish current builds
|
||||
TimeoutStopSec = "2 min";
|
||||
KillMode = "mixed";
|
||||
};
|
||||
serviceConfig = {
|
||||
ExecStart = "${cfg.package}/bin/buildkite-agent start --config ${cfg.dataDir}/buildkite-agent.cfg";
|
||||
User = "buildkite-agent-${name}";
|
||||
RestartSec = 5;
|
||||
Restart = "on-failure";
|
||||
TimeoutSec = 10;
|
||||
# set a long timeout to give buildkite-agent a chance to finish current builds
|
||||
TimeoutStopSec = "2 min";
|
||||
KillMode = "mixed";
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
config.assertions = mapAgents (name: cfg: [
|
||||
{ assertion = cfg.hooksPath == (hooksDir cfg) || all (v: v == null) (attrValues cfg.hooks);
|
||||
message = ''
|
||||
Options `services.buildkite-agents.${name}.hooksPath' and
|
||||
`services.buildkite-agents.${name}.hooks.<name>' are mutually exclusive.
|
||||
'';
|
||||
}
|
||||
]);
|
||||
|
||||
imports = [
|
||||
(mkRemovedOptionModule [ "services" "buildkite-agent"] "services.buildkite-agent has been upgraded from version 2 to version 3 and moved to an attribute set at services.buildkite-agents. Please consult the 20.03 release notes for more information.")
|
||||
];
|
||||
config.assertions = mapAgents (name: cfg: [{
|
||||
assertion = cfg.hooksPath != hooksDir cfg.hooks -> cfg.hooks == { };
|
||||
message = ''
|
||||
Options `services.buildkite-agents.${name}.hooksPath' and
|
||||
`services.buildkite-agents.${name}.hooks.<name>' are mutually exclusive.
|
||||
'';
|
||||
}]);
|
||||
}
|
||||
|
|
|
@ -210,9 +210,7 @@ in {
|
|||
|
||||
preStart =
|
||||
let replacePlugins =
|
||||
if cfg.plugins == null
|
||||
then ""
|
||||
else
|
||||
optionalString (cfg.plugins != null) (
|
||||
let pluginCmds = lib.attrsets.mapAttrsToList
|
||||
(n: v: "cp ${v} ${cfg.home}/plugins/${n}.jpi")
|
||||
cfg.plugins;
|
||||
|
@ -220,7 +218,7 @@ in {
|
|||
rm -r ${cfg.home}/plugins || true
|
||||
mkdir -p ${cfg.home}/plugins
|
||||
${lib.strings.concatStringsSep "\n" pluginCmds}
|
||||
'';
|
||||
'');
|
||||
in ''
|
||||
rm -rf ${cfg.home}/war
|
||||
${replacePlugins}
|
||||
|
|
632
third_party/nixpkgs/nixos/modules/services/databases/pgbouncer.nix
vendored
Normal file
632
third_party/nixpkgs/nixos/modules/services/databases/pgbouncer.nix
vendored
Normal file
|
@ -0,0 +1,632 @@
|
|||
{ lib, pkgs, config, ... } :
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.pgbouncer;
|
||||
|
||||
confFile = pkgs.writeTextFile {
|
||||
name = "pgbouncer.ini";
|
||||
text = ''
|
||||
[databases]
|
||||
${concatStringsSep "\n"
|
||||
(mapAttrsToList (dbname : settings : "${dbname} = ${settings}") cfg.databases)}
|
||||
|
||||
[users]
|
||||
${concatStringsSep "\n"
|
||||
(mapAttrsToList (username : settings : "${username} = ${settings}") cfg.users)}
|
||||
|
||||
[peers]
|
||||
${concatStringsSep "\n"
|
||||
(mapAttrsToList (peerid : settings : "${peerid} = ${settings}") cfg.peers)}
|
||||
|
||||
[pgbouncer]
|
||||
# general
|
||||
${optionalString (cfg.ignoreStartupParameters != null) "ignore_startup_parameters = ${cfg.ignoreStartupParameters}"}
|
||||
listen_port = ${toString cfg.listenPort}
|
||||
${optionalString (cfg.listenAddress != null) "listen_addr = ${cfg.listenAddress}"}
|
||||
pool_mode = ${cfg.poolMode}
|
||||
max_client_conn = ${toString cfg.maxClientConn}
|
||||
default_pool_size = ${toString cfg.defaultPoolSize}
|
||||
max_user_connections = ${toString cfg.maxUserConnections}
|
||||
max_db_connections = ${toString cfg.maxDbConnections}
|
||||
|
||||
#auth
|
||||
auth_type = ${cfg.authType}
|
||||
${optionalString (cfg.authHbaFile != null) "auth_hba_file = ${cfg.authHbaFile}"}
|
||||
${optionalString (cfg.authFile != null) "auth_file = ${cfg.authFile}"}
|
||||
${optionalString (cfg.authUser != null) "auth_user = ${cfg.authUser}"}
|
||||
${optionalString (cfg.authQuery != null) "auth_query = ${cfg.authQuery}"}
|
||||
${optionalString (cfg.authDbname != null) "auth_dbname = ${cfg.authDbname}"}
|
||||
|
||||
# TLS
|
||||
${optionalString (cfg.tls.client != null) ''
|
||||
client_tls_sslmode = ${cfg.tls.client.sslmode}
|
||||
client_tls_key_file = ${cfg.tls.client.keyFile}
|
||||
client_tls_cert_file = ${cfg.tls.client.certFile}
|
||||
client_tls_ca_file = ${cfg.tls.client.caFile}
|
||||
''}
|
||||
${optionalString (cfg.tls.server != null) ''
|
||||
server_tls_sslmode = ${cfg.tls.server.sslmode}
|
||||
server_tls_key_file = ${cfg.tls.server.keyFile}
|
||||
server_tls_cert_file = ${cfg.tls.server.certFile}
|
||||
server_tls_ca_file = ${cfg.tls.server.caFile}
|
||||
''}
|
||||
|
||||
# log
|
||||
${optionalString (cfg.logFile != null) "logfile = ${cfg.homeDir}/${cfg.logFile}"}
|
||||
${optionalString (cfg.syslog != null) ''
|
||||
syslog = ${if cfg.syslog.enable then "1" else "0"}
|
||||
syslog_ident = ${cfg.syslog.syslogIdent}
|
||||
syslog_facility = ${cfg.syslog.syslogFacility}
|
||||
''}
|
||||
${optionalString (cfg.verbose != null) "verbose = ${toString cfg.verbose}"}
|
||||
|
||||
# console access
|
||||
${optionalString (cfg.adminUsers != null) "admin_users = ${cfg.adminUsers}"}
|
||||
${optionalString (cfg.statsUsers != null) "stats_users = ${cfg.statsUsers}"}
|
||||
|
||||
# linux
|
||||
pidfile = /run/pgbouncer/pgbouncer.pid
|
||||
|
||||
# extra
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
};
|
||||
|
||||
in {
|
||||
|
||||
options.services.pgbouncer = {
|
||||
|
||||
# NixOS settings
|
||||
|
||||
enable = mkEnableOption (lib.mdDoc "PostgreSQL connection pooler");
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.pgbouncer;
|
||||
defaultText = literalExpression "pkgs.pgbouncer";
|
||||
description = lib.mdDoc ''
|
||||
The pgbouncer package to use.
|
||||
'';
|
||||
};
|
||||
|
||||
openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = lib.mdDoc ''
|
||||
Whether to automatically open the specified TCP port in the firewall.
|
||||
'';
|
||||
};
|
||||
|
||||
# Generic settings
|
||||
|
||||
logFile = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = "pgbouncer.log";
|
||||
description = lib.mdDoc ''
|
||||
Specifies the log file.
|
||||
Either this or syslog has to be specified.
|
||||
'';
|
||||
};
|
||||
|
||||
listenAddress = mkOption {
|
||||
type = types.nullOr types.commas;
|
||||
example = "*";
|
||||
default = null;
|
||||
description = lib.mdDoc ''
|
||||
Specifies a list (comma-separated) of addresses where to listen for TCP connections.
|
||||
You may also use * meaning “listen on all addresses”.
|
||||
When not set, only Unix socket connections are accepted.
|
||||
|
||||
Addresses can be specified numerically (IPv4/IPv6) or by name.
|
||||
'';
|
||||
};
|
||||
|
||||
listenPort = mkOption {
|
||||
type = types.port;
|
||||
default = 6432;
|
||||
description = lib.mdDoc ''
|
||||
Which port to listen on. Applies to both TCP and Unix sockets.
|
||||
'';
|
||||
};
|
||||
|
||||
poolMode = mkOption {
|
||||
type = types.enum [ "session" "transaction" "statement" ];
|
||||
default = "session";
|
||||
description = lib.mdDoc ''
|
||||
Specifies when a server connection can be reused by other clients.
|
||||
|
||||
session
|
||||
Server is released back to pool after client disconnects. Default.
|
||||
transaction
|
||||
Server is released back to pool after transaction finishes.
|
||||
statement
|
||||
Server is released back to pool after query finishes.
|
||||
Transactions spanning multiple statements are disallowed in this mode.
|
||||
'';
|
||||
};
|
||||
|
||||
maxClientConn = mkOption {
|
||||
type = types.int;
|
||||
default = 100;
|
||||
description = lib.mdDoc ''
|
||||
Maximum number of client connections allowed.
|
||||
|
||||
When this setting is increased, then the file descriptor limits in the operating system
|
||||
might also have to be increased. Note that the number of file descriptors potentially
|
||||
used is more than maxClientConn. If each user connects under its own user name to the server,
|
||||
the theoretical maximum used is:
|
||||
maxClientConn + (max pool_size * total databases * total users)
|
||||
|
||||
If a database user is specified in the connection string (all users connect under the same user name),
|
||||
the theoretical maximum is:
|
||||
maxClientConn + (max pool_size * total databases)
|
||||
|
||||
The theoretical maximum should never be reached, unless somebody deliberately crafts a special load for it.
|
||||
Still, it means you should set the number of file descriptors to a safely high number.
|
||||
'';
|
||||
};
|
||||
|
||||
defaultPoolSize = mkOption {
|
||||
type = types.int;
|
||||
default = 20;
|
||||
description = lib.mdDoc ''
|
||||
How many server connections to allow per user/database pair.
|
||||
Can be overridden in the per-database configuration.
|
||||
'';
|
||||
};
|
||||
|
||||
maxDbConnections = mkOption {
|
||||
type = types.int;
|
||||
default = 0;
|
||||
description = lib.mdDoc ''
|
||||
Do not allow more than this many server connections per database (regardless of user).
|
||||
This considers the PgBouncer database that the client has connected to,
|
||||
not the PostgreSQL database of the outgoing connection.
|
||||
|
||||
This can also be set per database in the [databases] section.
|
||||
|
||||
Note that when you hit the limit, closing a client connection to one pool will
|
||||
not immediately allow a server connection to be established for another pool,
|
||||
because the server connection for the first pool is still open.
|
||||
Once the server connection closes (due to idle timeout),
|
||||
a new server connection will immediately be opened for the waiting pool.
|
||||
|
||||
0 = unlimited
|
||||
'';
|
||||
};
|
||||
|
||||
maxUserConnections = mkOption {
|
||||
type = types.int;
|
||||
default = 0;
|
||||
description = lib.mdDoc ''
|
||||
Do not allow more than this many server connections per user (regardless of database).
|
||||
This considers the PgBouncer user that is associated with a pool,
|
||||
which is either the user specified for the server connection
|
||||
or in absence of that the user the client has connected as.
|
||||
|
||||
This can also be set per user in the [users] section.
|
||||
|
||||
Note that when you hit the limit, closing a client connection to one pool
|
||||
will not immediately allow a server connection to be established for another pool,
|
||||
because the server connection for the first pool is still open.
|
||||
Once the server connection closes (due to idle timeout), a new server connection
|
||||
will immediately be opened for the waiting pool.
|
||||
|
||||
0 = unlimited
|
||||
'';
|
||||
};
|
||||
|
||||
ignoreStartupParameters = mkOption {
|
||||
type = types.nullOr types.commas;
|
||||
example = "extra_float_digits";
|
||||
default = null;
|
||||
description = lib.mdDoc ''
|
||||
By default, PgBouncer allows only parameters it can keep track of in startup packets:
|
||||
client_encoding, datestyle, timezone and standard_conforming_strings.
|
||||
|
||||
All others parameters will raise an error.
|
||||
To allow others parameters, they can be specified here, so that PgBouncer knows that
|
||||
they are handled by the admin and it can ignore them.
|
||||
|
||||
If you need to specify multiple values, use a comma-separated list.
|
||||
|
||||
IMPORTANT: When using prometheus-pgbouncer-exporter, you need:
|
||||
extra_float_digits
|
||||
<https://github.com/prometheus-community/pgbouncer_exporter#pgbouncer-configuration>
|
||||
'';
|
||||
};
|
||||
|
||||
# Section [databases]
|
||||
databases = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = {};
|
||||
example = {
|
||||
exampledb = "host=/run/postgresql/ port=5432 auth_user=exampleuser dbname=exampledb sslmode=require";
|
||||
bardb = "host=localhost dbname=bazdb";
|
||||
foodb = "host=host1.example.com port=5432";
|
||||
};
|
||||
description = lib.mdDoc ''
|
||||
Detailed information about PostgreSQL database definitions:
|
||||
<https://www.pgbouncer.org/config.html#section-databases>
|
||||
'';
|
||||
};
|
||||
|
||||
# Section [users]
|
||||
users = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = {};
|
||||
example = {
|
||||
user1 = "pool_mode=session";
|
||||
};
|
||||
description = lib.mdDoc ''
|
||||
Optional.
|
||||
|
||||
Detailed information about PostgreSQL user definitions:
|
||||
<https://www.pgbouncer.org/config.html#section-users>
|
||||
'';
|
||||
};
|
||||
|
||||
# Section [peers]
|
||||
peers = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = {};
|
||||
example = {
|
||||
"1" = "host=host1.example.com";
|
||||
"2" = "host=/tmp/pgbouncer-2 port=5555";
|
||||
};
|
||||
description = lib.mdDoc ''
|
||||
Optional.
|
||||
|
||||
Detailed information about PostgreSQL database definitions:
|
||||
<https://www.pgbouncer.org/config.html#section-peers>
|
||||
'';
|
||||
};
|
||||
|
||||
# Authentication settings
|
||||
authType = mkOption {
|
||||
type = types.enum [ "cert" "md5" "scram-sha-256" "plain" "trust" "any" "hba" "pam" ];
|
||||
default = "md5";
|
||||
description = lib.mdDoc ''
|
||||
How to authenticate users.
|
||||
|
||||
cert
|
||||
Client must connect over TLS connection with a valid client certificate.
|
||||
The user name is then taken from the CommonName field from the certificate.
|
||||
md5
|
||||
Use MD5-based password check. This is the default authentication method.
|
||||
authFile may contain both MD5-encrypted and plain-text passwords.
|
||||
If md5 is configured and a user has a SCRAM secret, then SCRAM authentication is used automatically instead.
|
||||
scram-sha-256
|
||||
Use password check with SCRAM-SHA-256. authFile has to contain SCRAM secrets or plain-text passwords.
|
||||
plain
|
||||
The clear-text password is sent over the wire. Deprecated.
|
||||
trust
|
||||
No authentication is done. The user name must still exist in authFile.
|
||||
any
|
||||
Like the trust method, but the user name given is ignored.
|
||||
Requires that all databases are configured to log in as a specific user.
|
||||
Additionally, the console database allows any user to log in as admin.
|
||||
hba
|
||||
The actual authentication type is loaded from authHbaFile.
|
||||
This allows different authentication methods for different access paths,
|
||||
for example: connections over Unix socket use the peer auth method, connections over TCP must use TLS.
|
||||
pam
|
||||
PAM is used to authenticate users, authFile is ignored.
|
||||
This method is not compatible with databases using the authUser option.
|
||||
The service name reported to PAM is “pgbouncer”. pam is not supported in the HBA configuration file.
|
||||
'';
|
||||
};
|
||||
|
||||
authHbaFile = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
example = "/secrets/pgbouncer_hba";
|
||||
description = lib.mdDoc ''
|
||||
HBA configuration file to use when authType is hba.
|
||||
|
||||
See HBA file format details:
|
||||
<https://www.pgbouncer.org/config.html#hba-file-format>
|
||||
'';
|
||||
};
|
||||
|
||||
authFile = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
example = "/secrets/pgbouncer_authfile";
|
||||
description = lib.mdDoc ''
|
||||
The name of the file to load user names and passwords from.
|
||||
|
||||
See section Authentication file format details:
|
||||
<https://www.pgbouncer.org/config.html#authentication-file-format>
|
||||
|
||||
Most authentication types require that either authFile or authUser be set;
|
||||
otherwise there would be no users defined.
|
||||
'';
|
||||
};
|
||||
|
||||
authUser = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "pgbouncer";
|
||||
description = lib.mdDoc ''
|
||||
If authUser is set, then any user not specified in authFile will be queried
|
||||
through the authQuery query from pg_shadow in the database, using authUser.
|
||||
The password of authUser will be taken from authFile.
|
||||
(If the authUser does not require a password then it does not need to be defined in authFile.)
|
||||
|
||||
Direct access to pg_shadow requires admin rights.
|
||||
It's preferable to use a non-superuser that calls a SECURITY DEFINER function instead.
|
||||
'';
|
||||
};
|
||||
|
||||
authQuery = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "SELECT usename, passwd FROM pg_shadow WHERE usename=$1";
|
||||
description = lib.mdDoc ''
|
||||
Query to load user's password from database.
|
||||
|
||||
Direct access to pg_shadow requires admin rights.
|
||||
It's preferable to use a non-superuser that calls a SECURITY DEFINER function instead.
|
||||
|
||||
Note that the query is run inside the target database.
|
||||
So if a function is used, it needs to be installed into each database.
|
||||
'';
|
||||
};
|
||||
|
||||
authDbname = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "authdb";
|
||||
description = lib.mdDoc ''
|
||||
Database name in the [database] section to be used for authentication purposes.
|
||||
This option can be either global or overriden in the connection string if this parameter is specified.
|
||||
'';
|
||||
};
|
||||
|
||||
# TLS settings
|
||||
tls.client = mkOption {
|
||||
type = types.nullOr (types.submodule {
|
||||
options = {
|
||||
sslmode = mkOption {
|
||||
type = types.enum [ "disable" "allow" "prefer" "require" "verify-ca" "verify-full" ];
|
||||
default = "disable";
|
||||
description = lib.mdDoc ''
|
||||
TLS mode to use for connections from clients.
|
||||
TLS connections are disabled by default.
|
||||
|
||||
When enabled, tls.client.keyFile and tls.client.certFile
|
||||
must be also configured to set up the key and certificate
|
||||
PgBouncer uses to accept client connections.
|
||||
|
||||
disable
|
||||
Plain TCP. If client requests TLS, it's ignored. Default.
|
||||
allow
|
||||
If client requests TLS, it is used. If not, plain TCP is used.
|
||||
If the client presents a client certificate, it is not validated.
|
||||
prefer
|
||||
Same as allow.
|
||||
require
|
||||
Client must use TLS. If not, the client connection is rejected.
|
||||
If the client presents a client certificate, it is not validated.
|
||||
verify-ca
|
||||
Client must use TLS with valid client certificate.
|
||||
verify-full
|
||||
Same as verify-ca
|
||||
'';
|
||||
};
|
||||
certFile = mkOption {
|
||||
type = types.path;
|
||||
example = "/secrets/pgbouncer.key";
|
||||
description = lib.mdDoc "Path to certificate for private key. Clients can validate it";
|
||||
};
|
||||
keyFile = mkOption {
|
||||
type = types.path;
|
||||
example = "/secrets/pgbouncer.crt";
|
||||
description = lib.mdDoc "Path to private key for PgBouncer to accept client connections";
|
||||
};
|
||||
caFile = mkOption {
|
||||
type = types.path;
|
||||
example = "/secrets/pgbouncer.crt";
|
||||
description = lib.mdDoc "Path to root certificate file to validate client certificates";
|
||||
};
|
||||
};
|
||||
});
|
||||
default = null;
|
||||
description = lib.mdDoc ''
|
||||
<https://www.pgbouncer.org/config.html#tls-settings>
|
||||
'';
|
||||
};
|
||||
|
||||
tls.server = mkOption {
|
||||
type = types.nullOr (types.submodule {
|
||||
options = {
|
||||
sslmode = mkOption {
|
||||
type = types.enum [ "disable" "allow" "prefer" "require" "verify-ca" "verify-full" ];
|
||||
default = "disable";
|
||||
description = lib.mdDoc ''
|
||||
TLS mode to use for connections to PostgreSQL servers.
|
||||
TLS connections are disabled by default.
|
||||
|
||||
disable
|
||||
Plain TCP. TLS is not even requested from the server. Default.
|
||||
allow
|
||||
FIXME: if server rejects plain, try TLS?
|
||||
prefer
|
||||
TLS connection is always requested first from PostgreSQL.
|
||||
If refused, the connection will be established over plain TCP.
|
||||
Server certificate is not validated.
|
||||
require
|
||||
Connection must go over TLS. If server rejects it, plain TCP is not attempted.
|
||||
Server certificate is not validated.
|
||||
verify-ca
|
||||
Connection must go over TLS and server certificate must be valid according to tls.server.caFile.
|
||||
Server host name is not checked against certificate.
|
||||
verify-full
|
||||
Connection must go over TLS and server certificate must be valid according to tls.server.caFile.
|
||||
Server host name must match certificate information.
|
||||
'';
|
||||
};
|
||||
certFile = mkOption {
|
||||
type = types.path;
|
||||
example = "/secrets/pgbouncer_server.key";
|
||||
description = lib.mdDoc "Certificate for private key. PostgreSQL server can validate it.";
|
||||
};
|
||||
keyFile = mkOption {
|
||||
type = types.path;
|
||||
example = "/secrets/pgbouncer_server.crt";
|
||||
description = lib.mdDoc "Private key for PgBouncer to authenticate against PostgreSQL server.";
|
||||
};
|
||||
caFile = mkOption {
|
||||
type = types.path;
|
||||
example = "/secrets/pgbouncer_server.crt";
|
||||
description = lib.mdDoc "Root certificate file to validate PostgreSQL server certificates.";
|
||||
};
|
||||
};
|
||||
});
|
||||
default = null;
|
||||
description = lib.mdDoc ''
|
||||
<https://www.pgbouncer.org/config.html#tls-settings>
|
||||
'';
|
||||
};
|
||||
|
||||
# Log settings
|
||||
syslog = mkOption {
|
||||
type = types.nullOr (types.submodule {
|
||||
options = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = lib.mdDoc ''
|
||||
Toggles syslog on/off.
|
||||
'';
|
||||
};
|
||||
syslogIdent = mkOption {
|
||||
type = types.str;
|
||||
default = "pgbouncer";
|
||||
description = lib.mdDoc ''
|
||||
Under what name to send logs to syslog.
|
||||
'';
|
||||
};
|
||||
syslogFacility = mkOption {
|
||||
type = types.enum [ "auth" "authpriv" "daemon" "user" "local0" "local1" "local2" "local3" "local4" "local5" "local6" "local7" ];
|
||||
default = "daemon";
|
||||
description = lib.mdDoc ''
|
||||
Under what facility to send logs to syslog.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
default = null;
|
||||
description = lib.mdDoc ''
|
||||
<https://www.pgbouncer.org/config.html#log-settings>
|
||||
'';
|
||||
};
|
||||
|
||||
verbose = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 0;
|
||||
description = lib.mdDoc ''
|
||||
Increase verbosity. Mirrors the “-v” switch on the command line.
|
||||
'';
|
||||
};
|
||||
|
||||
# Console access control
|
||||
adminUsers = mkOption {
|
||||
type = types.nullOr types.commas;
|
||||
default = null;
|
||||
description = lib.mdDoc ''
|
||||
Comma-separated list of database users that are allowed to connect and run all commands on the console.
|
||||
Ignored when authType is any, in which case any user name is allowed in as admin.
|
||||
'';
|
||||
};
|
||||
|
||||
statsUsers = mkOption {
|
||||
type = types.nullOr types.commas;
|
||||
default = null;
|
||||
description = lib.mdDoc ''
|
||||
Comma-separated list of database users that are allowed to connect and run read-only queries on the console.
|
||||
That means all SHOW commands except SHOW FDS.
|
||||
'';
|
||||
};
|
||||
|
||||
# Linux settings
|
||||
openFilesLimit = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 65536;
|
||||
description = lib.mdDoc ''
|
||||
Maximum number of open files.
|
||||
'';
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
default = "pgbouncer";
|
||||
description = lib.mdDoc ''
|
||||
The user pgbouncer is run as.
|
||||
'';
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
default = "pgbouncer";
|
||||
description = lib.mdDoc ''
|
||||
The group pgbouncer is run as.
|
||||
'';
|
||||
};
|
||||
|
||||
homeDir = mkOption {
|
||||
type = types.path;
|
||||
default = "/var/lib/pgbouncer";
|
||||
description = lib.mdDoc ''
|
||||
Specifies the home directory.
|
||||
'';
|
||||
};
|
||||
|
||||
# Extra settings
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
description = lib.mdDoc ''
|
||||
Any additional text to be appended to config.ini
|
||||
<https://www.pgbouncer.org/config.html>.
|
||||
'';
|
||||
default = "";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
users.groups.${cfg.group} = { };
|
||||
users.users.${cfg.user} = {
|
||||
description = "PgBouncer service user";
|
||||
group = cfg.group;
|
||||
home = cfg.homeDir;
|
||||
createHome = true;
|
||||
isSystemUser = true;
|
||||
};
|
||||
|
||||
systemd.services.pgbouncer = {
|
||||
description = "PgBouncer - PostgreSQL connection pooler";
|
||||
wants = [ "postgresql.service" ];
|
||||
after = [ "postgresql.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "forking";
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
ExecStart = "${pkgs.pgbouncer}/bin/pgbouncer -d ${confFile}";
|
||||
ExecReload = "${pkgs.coreutils}/bin/kill -SIGHUP $MAINPID";
|
||||
RuntimeDirectory = "pgbouncer";
|
||||
PIDFile = "/run/pgbouncer/pgbouncer.pid";
|
||||
LimitNOFILE = cfg.openFilesLimit;
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.port;
|
||||
|
||||
};
|
||||
|
||||
meta.maintainers = [ maintainers._1000101 ];
|
||||
|
||||
}
|
|
@ -404,8 +404,8 @@ in
|
|||
{
|
||||
log_connections = true;
|
||||
log_statement = "all";
|
||||
logging_collector = true
|
||||
log_disconnections = true
|
||||
logging_collector = true;
|
||||
log_disconnections = true;
|
||||
log_destination = lib.mkForce "syslog";
|
||||
}
|
||||
'';
|
||||
|
|
|
@ -96,7 +96,7 @@ in
|
|||
|
||||
environment.systemPackages = [ cfg.package editorScript desktopApplicationFile ];
|
||||
|
||||
environment.variables.EDITOR = mkIf cfg.defaultEditor (mkOverride 900 "${editorScript}/bin/emacseditor");
|
||||
environment.variables.EDITOR = mkIf cfg.defaultEditor (mkOverride 900 "emacseditor");
|
||||
};
|
||||
|
||||
meta.doc = ./emacs.md;
|
||||
|
|
|
@ -71,12 +71,16 @@ in
|
|||
|
||||
environment.systemPackages = [ pkgs.udisks2 ];
|
||||
|
||||
environment.etc = (mapAttrs' (name: value: nameValuePair "udisks2/${name}" { source = value; } ) configFiles) // {
|
||||
# We need to make sure /etc/libblockdev/conf.d is populated to avoid
|
||||
environment.etc = (mapAttrs' (name: value: nameValuePair "udisks2/${name}" { source = value; } ) configFiles) // (
|
||||
let
|
||||
libblockdev = pkgs.udisks2.libblockdev;
|
||||
majorVer = versions.major libblockdev.version;
|
||||
in {
|
||||
# We need to make sure /etc/libblockdev/@major_ver@/conf.d is populated to avoid
|
||||
# warnings
|
||||
"libblockdev/conf.d/00-default.cfg".source = "${pkgs.libblockdev}/etc/libblockdev/conf.d/00-default.cfg";
|
||||
"libblockdev/conf.d/10-lvm-dbus.cfg".source = "${pkgs.libblockdev}/etc/libblockdev/conf.d/10-lvm-dbus.cfg";
|
||||
};
|
||||
"libblockdev/${majorVer}/conf.d/00-default.cfg".source = "${libblockdev}/etc/libblockdev/${majorVer}/conf.d/00-default.cfg";
|
||||
"libblockdev/${majorVer}/conf.d/10-lvm-dbus.cfg".source = "${libblockdev}/etc/libblockdev/${majorVer}/conf.d/10-lvm-dbus.cfg";
|
||||
});
|
||||
|
||||
security.polkit.enable = true;
|
||||
|
||||
|
|
270
third_party/nixpkgs/nixos/modules/services/home-automation/ebusd.nix
vendored
Normal file
270
third_party/nixpkgs/nixos/modules/services/home-automation/ebusd.nix
vendored
Normal file
|
@ -0,0 +1,270 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.ebusd;
|
||||
|
||||
package = pkgs.ebusd;
|
||||
|
||||
arguments = [
|
||||
"${package}/bin/ebusd"
|
||||
"--foreground"
|
||||
"--updatecheck=off"
|
||||
"--device=${cfg.device}"
|
||||
"--port=${toString cfg.port}"
|
||||
"--configpath=${cfg.configpath}"
|
||||
"--scanconfig=${cfg.scanconfig}"
|
||||
"--log=main:${cfg.logs.main}"
|
||||
"--log=network:${cfg.logs.network}"
|
||||
"--log=bus:${cfg.logs.bus}"
|
||||
"--log=update:${cfg.logs.update}"
|
||||
"--log=other:${cfg.logs.other}"
|
||||
"--log=all:${cfg.logs.all}"
|
||||
] ++ lib.optionals cfg.readonly [
|
||||
"--readonly"
|
||||
] ++ lib.optionals cfg.mqtt.enable [
|
||||
"--mqtthost=${cfg.mqtt.host}"
|
||||
"--mqttport=${toString cfg.mqtt.port}"
|
||||
"--mqttuser=${cfg.mqtt.user}"
|
||||
"--mqttpass=${cfg.mqtt.password}"
|
||||
] ++ lib.optionals cfg.mqtt.home-assistant [
|
||||
"--mqttint=${package}/etc/ebusd/mqtt-hassio.cfg"
|
||||
"--mqttjson"
|
||||
] ++ lib.optionals cfg.mqtt.retain [
|
||||
"--mqttretain"
|
||||
] ++ cfg.extraArguments;
|
||||
|
||||
usesDev = hasPrefix "/" cfg.device;
|
||||
|
||||
command = concatStringsSep " " arguments;
|
||||
|
||||
in
|
||||
{
|
||||
meta.maintainers = with maintainers; [ nathan-gs ];
|
||||
|
||||
options.services.ebusd = {
|
||||
enable = mkEnableOption (lib.mdDoc "ebusd service");
|
||||
|
||||
device = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
example = "IP:PORT";
|
||||
description = lib.mdDoc ''
|
||||
Use DEV as eBUS device [/dev/ttyUSB0].
|
||||
This can be either:
|
||||
enh:DEVICE or enh:IP:PORT for enhanced device (only adapter v3 and newer),
|
||||
ens:DEVICE for enhanced high speed serial device (only adapter v3 and newer with firmware since 20220731),
|
||||
DEVICE for serial device (normal speed, for all other serial adapters like adapter v2 as well as adapter v3 in non-enhanced mode), or
|
||||
[udp:]IP:PORT for network device.
|
||||
https://github.com/john30/ebusd/wiki/2.-Run#device-options
|
||||
'';
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
default = 8888;
|
||||
type = types.port;
|
||||
description = lib.mdDoc ''
|
||||
The port on which to listen on
|
||||
'';
|
||||
};
|
||||
|
||||
readonly = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = lib.mdDoc ''
|
||||
Only read from device, never write to it
|
||||
'';
|
||||
};
|
||||
|
||||
configpath = mkOption {
|
||||
type = types.str;
|
||||
default = "https://cfg.ebusd.eu/";
|
||||
description = lib.mdDoc ''
|
||||
Read CSV config files from PATH (local folder or HTTPS URL) [https://cfg.ebusd.eu/]
|
||||
'';
|
||||
};
|
||||
|
||||
scanconfig = mkOption {
|
||||
type = types.str;
|
||||
default = "full";
|
||||
description = lib.mdDoc ''
|
||||
Pick CSV config files matching initial scan ("none" or empty for no initial scan message, "full" for full scan, or a single hex address to scan, default is to send a broadcast ident message).
|
||||
If combined with --checkconfig, you can add scan message data as arguments for checking a particular scan configuration, e.g. "FF08070400/0AB5454850303003277201". For further details on this option,
|
||||
see [Automatic configuration](https://github.com/john30/ebusd/wiki/4.7.-Automatic-configuration).
|
||||
'';
|
||||
};
|
||||
|
||||
logs = {
|
||||
main = mkOption {
|
||||
type = types.enum [ "error" "notice" "info" "debug"];
|
||||
default = "info";
|
||||
description = lib.mdDoc ''
|
||||
Only write log for matching AREAs (main|network|bus|update|other|all) below or equal to LEVEL (error|notice|info|debug) [all:notice].
|
||||
'';
|
||||
};
|
||||
|
||||
network = mkOption {
|
||||
type = types.enum [ "error" "notice" "info" "debug"];
|
||||
default = "info";
|
||||
description = lib.mdDoc ''
|
||||
Only write log for matching AREAs (main|network|bus|update|other|all) below or equal to LEVEL (error|notice|info|debug) [all:notice].
|
||||
'';
|
||||
};
|
||||
|
||||
bus = mkOption {
|
||||
type = types.enum [ "error" "notice" "info" "debug"];
|
||||
default = "info";
|
||||
description = lib.mdDoc ''
|
||||
Only write log for matching AREAs (main|network|bus|update|other|all) below or equal to LEVEL (error|notice|info|debug) [all:notice].
|
||||
'';
|
||||
};
|
||||
|
||||
update = mkOption {
|
||||
type = types.enum [ "error" "notice" "info" "debug"];
|
||||
default = "info";
|
||||
description = lib.mdDoc ''
|
||||
Only write log for matching AREAs (main|network|bus|update|other|all) below or equal to LEVEL (error|notice|info|debug) [all:notice].
|
||||
'';
|
||||
};
|
||||
|
||||
other = mkOption {
|
||||
type = types.enum [ "error" "notice" "info" "debug"];
|
||||
default = "info";
|
||||
description = lib.mdDoc ''
|
||||
Only write log for matching AREAs (main|network|bus|update|other|all) below or equal to LEVEL (error|notice|info|debug) [all:notice].
|
||||
'';
|
||||
};
|
||||
|
||||
all = mkOption {
|
||||
type = types.enum [ "error" "notice" "info" "debug"];
|
||||
default = "info";
|
||||
description = lib.mdDoc ''
|
||||
Only write log for matching AREAs (main|network|bus|update|other|all) below or equal to LEVEL (error|notice|info|debug) [all:notice].
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
mqtt = {
|
||||
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = lib.mdDoc ''
|
||||
Adds support for MQTT
|
||||
'';
|
||||
};
|
||||
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
default = "localhost";
|
||||
description = lib.mdDoc ''
|
||||
Connect to MQTT broker on HOST.
|
||||
'';
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
default = 1883;
|
||||
type = types.port;
|
||||
description = lib.mdDoc ''
|
||||
The port on which to connect to MQTT
|
||||
'';
|
||||
};
|
||||
|
||||
home-assistant = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = lib.mdDoc ''
|
||||
Adds the Home Assistant topics to MQTT, read more at [MQTT Integration](https://github.com/john30/ebusd/wiki/MQTT-integration)
|
||||
'';
|
||||
};
|
||||
|
||||
retain = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = lib.mdDoc ''
|
||||
Set the retain flag on all topics instead of only selected global ones
|
||||
'';
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
description = lib.mdDoc ''
|
||||
The MQTT user to use
|
||||
'';
|
||||
};
|
||||
|
||||
password = mkOption {
|
||||
type = types.str;
|
||||
description = lib.mdDoc ''
|
||||
The MQTT password.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
extraArguments = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
description = lib.mdDoc ''
|
||||
Extra arguments to the ebus daemon
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
config = mkIf (cfg.enable) {
|
||||
|
||||
systemd.services.ebusd = {
|
||||
description = "EBUSd Service";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
serviceConfig = {
|
||||
ExecStart = command;
|
||||
DynamicUser = true;
|
||||
Restart = "on-failure";
|
||||
|
||||
# Hardening
|
||||
CapabilityBoundingSet = "";
|
||||
DeviceAllow = lib.optionals usesDev [
|
||||
cfg.device
|
||||
] ;
|
||||
DevicePolicy = "closed";
|
||||
LockPersonality = true;
|
||||
MemoryDenyWriteExecute = false;
|
||||
NoNewPrivileges = true;
|
||||
PrivateDevices = usesDev;
|
||||
PrivateUsers = true;
|
||||
PrivateTmp = true;
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHome = true;
|
||||
ProtectHostname = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectProc = "invisible";
|
||||
ProcSubset = "pid";
|
||||
ProtectSystem = "strict";
|
||||
RemoveIPC = true;
|
||||
RestrictAddressFamilies = [
|
||||
"AF_INET"
|
||||
"AF_INET6"
|
||||
];
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true;
|
||||
SupplementaryGroups = [
|
||||
"dialout"
|
||||
];
|
||||
SystemCallArchitectures = "native";
|
||||
SystemCallFilter = [
|
||||
"@system-service @pkey"
|
||||
"~@privileged @resources"
|
||||
];
|
||||
UMask = "0077";
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
}
|
|
@ -451,6 +451,7 @@ in {
|
|||
"eufylife_ble"
|
||||
"esphome"
|
||||
"fjaraskupan"
|
||||
"gardena_bluetooth"
|
||||
"govee_ble"
|
||||
"homekit_controller"
|
||||
"inkbird"
|
||||
|
|
|
@ -12,16 +12,14 @@ let
|
|||
|
||||
configFile = pkgs.runCommand "matrix-appservice-irc.yml" {
|
||||
# Because this program will be run at build time, we need `nativeBuildInputs`
|
||||
nativeBuildInputs = [ (pkgs.python3.withPackages (ps: [ ps.pyyaml ps.jsonschema ])) ];
|
||||
nativeBuildInputs = [ (pkgs.python3.withPackages (ps: [ ps.jsonschema ])) pkgs.remarshal ];
|
||||
preferLocalBuild = true;
|
||||
|
||||
config = builtins.toJSON cfg.settings;
|
||||
passAsFile = [ "config" ];
|
||||
} ''
|
||||
# The schema is given as yaml, we need to convert it to json
|
||||
python -c 'import json; import yaml; import sys; json.dump(yaml.safe_load(sys.stdin), sys.stdout)' \
|
||||
< ${pkg}/lib/node_modules/matrix-appservice-irc/config.schema.yml \
|
||||
> config.schema.json
|
||||
remarshal --if yaml --of json -i ${pkg}/config.schema.yml -o config.schema.json
|
||||
python -m jsonschema config.schema.json -i $configPath
|
||||
cp "$configPath" "$out"
|
||||
'';
|
||||
|
@ -215,7 +213,10 @@ in {
|
|||
LockPersonality = true;
|
||||
RestrictRealtime = true;
|
||||
PrivateMounts = true;
|
||||
SystemCallFilter = "~@aio @clock @cpu-emulation @debug @keyring @memlock @module @mount @obsolete @raw-io @setuid @swap";
|
||||
SystemCallFilter = [
|
||||
"@system-service @pkey"
|
||||
"~@privileged @resources"
|
||||
];
|
||||
SystemCallArchitectures = "native";
|
||||
# AF_UNIX is required to connect to a postgres socket.
|
||||
RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6";
|
||||
|
|
|
@ -138,10 +138,12 @@ in
|
|||
"~@privileged"
|
||||
];
|
||||
StateDirectory = "matrix-conduit";
|
||||
StateDirectoryMode = "0700";
|
||||
ExecStart = "${cfg.package}/bin/conduit";
|
||||
Restart = "on-failure";
|
||||
RestartSec = 10;
|
||||
StartLimitBurst = 5;
|
||||
UMask = "077";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
96
third_party/nixpkgs/nixos/modules/services/matrix/matrix-sliding-sync.nix
vendored
Normal file
96
third_party/nixpkgs/nixos/modules/services/matrix/matrix-sliding-sync.nix
vendored
Normal file
|
@ -0,0 +1,96 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
cfg = config.services.matrix-synapse.sliding-sync;
|
||||
in
|
||||
{
|
||||
options.services.matrix-synapse.sliding-sync = {
|
||||
enable = lib.mkEnableOption (lib.mdDoc "sliding sync");
|
||||
|
||||
package = lib.mkPackageOption pkgs "matrix-sliding-sync" { };
|
||||
|
||||
settings = lib.mkOption {
|
||||
type = lib.types.submodule {
|
||||
freeformType = with lib.types; attrsOf str;
|
||||
options = {
|
||||
SYNCV3_SERVER = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = lib.mdDoc ''
|
||||
The destination homeserver to talk to not including `/_matrix/` e.g `https://matrix.example.org`.
|
||||
'';
|
||||
};
|
||||
|
||||
SYNCV3_DB = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "postgresql:///matrix-sliding-sync?host=/run/postgresql";
|
||||
description = lib.mdDoc ''
|
||||
The postgres connection string.
|
||||
Refer to <https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING>.
|
||||
'';
|
||||
};
|
||||
|
||||
SYNCV3_BINDADDR = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "127.0.0.1:8009";
|
||||
example = "[::]:8008";
|
||||
description = lib.mdDoc "The interface and port to listen on.";
|
||||
};
|
||||
|
||||
SYNCV3_LOG_LEVEL = lib.mkOption {
|
||||
type = lib.types.enum [ "trace" "debug" "info" "warn" "error" "fatal" ];
|
||||
default = "info";
|
||||
description = lib.mdDoc "The level of verbosity for messages logged.";
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
description = ''
|
||||
Freeform environment variables passed to the sliding sync proxy.
|
||||
Refer to <https://github.com/matrix-org/sliding-sync#setup> for all supported values.
|
||||
'';
|
||||
};
|
||||
|
||||
createDatabase = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = lib.mdDoc ''
|
||||
Whether to enable and configure `services.postgres` to ensure that the database user `matrix-sliding-sync`
|
||||
and the database `matrix-sliding-sync` exist.
|
||||
'';
|
||||
};
|
||||
|
||||
environmentFile = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = lib.mdDoc ''
|
||||
Environment file as defined in {manpage}`systemd.exec(5)`.
|
||||
|
||||
This must contain the {env}`SYNCV3_SECRET` variable which should
|
||||
be generated with {command}`openssl rand -hex 32`.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.postgresql = lib.optionalAttrs cfg.createDatabase {
|
||||
enable = true;
|
||||
ensureDatabases = [ "matrix-sliding-sync" ];
|
||||
ensureUsers = [ rec {
|
||||
name = "matrix-sliding-sync";
|
||||
ensurePermissions."DATABASE \"${name}\"" = "ALL PRIVILEGES";
|
||||
} ];
|
||||
};
|
||||
|
||||
systemd.services.matrix-sliding-sync = {
|
||||
after = lib.optional cfg.createDatabase "postgresql.service";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
environment = cfg.settings;
|
||||
serviceConfig = {
|
||||
DynamicUser = true;
|
||||
EnvironmentFile = cfg.environmentFile;
|
||||
ExecStart = lib.getExe cfg.package;
|
||||
StateDirectory = "matrix-sliding-sync";
|
||||
WorkingDirectory = "%S/matrix-sliding-sync";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue