mirror of
https://github.com/CHN-beta/nixpkgs.git
synced 2026-01-12 19:00:19 +08:00
Compare commits
14 Commits
staging
...
python-tes
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e54227b0df | ||
|
|
ad048019ad | ||
|
|
20ed39a036 | ||
|
|
95e249772f | ||
|
|
936309cb9b | ||
|
|
7e2d8c4ace | ||
|
|
a486968a6e | ||
|
|
9edbbf1633 | ||
|
|
5400041d4a | ||
|
|
ae64e1b4cf | ||
|
|
7a32a2eb7d | ||
|
|
4f21de5214 | ||
|
|
35068dc47f | ||
|
|
2d0a47236d |
39
.github/CODEOWNERS
vendored
39
.github/CODEOWNERS
vendored
@@ -22,19 +22,19 @@
|
||||
/.editorconfig @Mic92 @zowoq
|
||||
|
||||
# Libraries
|
||||
/lib @edolstra @infinisil
|
||||
/lib/systems @alyssais @ericson2314 @matthewbauer
|
||||
/lib/generators.nix @edolstra @Profpatsch
|
||||
/lib/cli.nix @edolstra @Profpatsch
|
||||
/lib/debug.nix @edolstra @Profpatsch
|
||||
/lib/asserts.nix @edolstra @Profpatsch
|
||||
/lib @edolstra @nbp @infinisil
|
||||
/lib/systems @alyssais @nbp @ericson2314 @matthewbauer
|
||||
/lib/generators.nix @edolstra @nbp @Profpatsch
|
||||
/lib/cli.nix @edolstra @nbp @Profpatsch
|
||||
/lib/debug.nix @edolstra @nbp @Profpatsch
|
||||
/lib/asserts.nix @edolstra @nbp @Profpatsch
|
||||
/lib/path.* @infinisil @fricklerhandwerk
|
||||
|
||||
# Nixpkgs Internals
|
||||
/default.nix @Ericson2314
|
||||
/pkgs/top-level/default.nix @Ericson2314
|
||||
/pkgs/top-level/impure.nix @Ericson2314
|
||||
/pkgs/top-level/stage.nix @Ericson2314 @matthewbauer
|
||||
/default.nix @nbp
|
||||
/pkgs/top-level/default.nix @nbp @Ericson2314
|
||||
/pkgs/top-level/impure.nix @nbp @Ericson2314
|
||||
/pkgs/top-level/stage.nix @nbp @Ericson2314 @matthewbauer
|
||||
/pkgs/top-level/splice.nix @Ericson2314 @matthewbauer
|
||||
/pkgs/top-level/release-cross.nix @Ericson2314 @matthewbauer
|
||||
/pkgs/stdenv/generic @Ericson2314 @matthewbauer
|
||||
@@ -67,9 +67,22 @@
|
||||
/doc/using @fricklerhandwerk
|
||||
|
||||
# NixOS Internals
|
||||
/nixos/default.nix @infinisil
|
||||
/nixos/lib/from-env.nix @infinisil
|
||||
/nixos/lib/eval-config.nix @infinisil
|
||||
/nixos/default.nix @nbp @infinisil
|
||||
/nixos/lib/from-env.nix @nbp @infinisil
|
||||
/nixos/lib/eval-config.nix @nbp @infinisil
|
||||
/nixos/doc/manual/configuration/abstractions.xml @nbp
|
||||
/nixos/doc/manual/configuration/config-file.xml @nbp
|
||||
/nixos/doc/manual/configuration/config-syntax.xml @nbp
|
||||
/nixos/doc/manual/configuration/modularity.xml @nbp
|
||||
/nixos/doc/manual/development/assertions.xml @nbp
|
||||
/nixos/doc/manual/development/meta-attributes.xml @nbp
|
||||
/nixos/doc/manual/development/option-declarations.xml @nbp
|
||||
/nixos/doc/manual/development/option-def.xml @nbp
|
||||
/nixos/doc/manual/development/option-types.xml @nbp
|
||||
/nixos/doc/manual/development/replace-modules.xml @nbp
|
||||
/nixos/doc/manual/development/writing-modules.xml @nbp
|
||||
/nixos/doc/manual/man-nixos-option.xml @nbp
|
||||
/nixos/modules/installer/tools/nixos-option.sh @nbp
|
||||
/nixos/modules/system @dasJ
|
||||
/nixos/modules/system/activation/bootspec.nix @grahamc @cole-h @raitobezarius
|
||||
/nixos/modules/system/activation/bootspec.cue @grahamc @cole-h @raitobezarius
|
||||
|
||||
@@ -164,26 +164,6 @@ tests.fetchgit = testers.invalidateFetcherByDrvHash fetchgit {
|
||||
};
|
||||
```
|
||||
|
||||
## `runNixOSTest` {#tester-runNixOSTest}
|
||||
|
||||
A helper function that behaves exactly like the NixOS `runTest`, except it also assigns this Nixpkgs package set as the `pkgs` of the test and makes the `nixpkgs.*` options read-only.
|
||||
|
||||
If your test is part of the Nixpkgs repository, or if you need a more general entrypoint, see ["Calling a test" in the NixOS manual](https://nixos.org/manual/nixos/stable/index.html#sec-calling-nixos-tests).
|
||||
|
||||
Example:
|
||||
|
||||
```nix
|
||||
pkgs.testers.runNixOSTest ({ lib, ... }: {
|
||||
name = "hello";
|
||||
nodes.machine = { pkgs, ... }: {
|
||||
environment.systemPackages = [ pkgs.hello ];
|
||||
};
|
||||
testScript = ''
|
||||
machine.succeed("hello")
|
||||
'';
|
||||
})
|
||||
```
|
||||
|
||||
## `nixosTest` {#tester-nixosTest}
|
||||
|
||||
Run a NixOS VM network test using this evaluation of Nixpkgs.
|
||||
|
||||
@@ -27,7 +27,7 @@ package set to make it the default. This guarantees you get a consistent package
|
||||
set.
|
||||
```nix
|
||||
mypkg = let
|
||||
cudaPackages = cudaPackages_11_5.overrideScope' (final: prev: {
|
||||
cudaPackages = cudaPackages_11_5.overrideScope' (final: prev {
|
||||
cudnn = prev.cudnn_8_3_2;
|
||||
}});
|
||||
in callPackage { inherit cudaPackages; };
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
# Dart {#sec-language-dart}
|
||||
|
||||
## Dart applications {#ssec-dart-applications}
|
||||
|
||||
The function `buildDartApplication` builds Dart applications managed with pub.
|
||||
|
||||
It fetches its Dart dependencies automatically through `fetchDartDeps`, and (through a series of hooks) builds and installs the executables specified in the pubspec file. The hooks can be used in other derivations, if needed. The phases can also be overridden to do something different from installing binaries.
|
||||
|
||||
If you are packaging a Flutter desktop application, use [`buildFlutterApplication`](#ssec-dart-flutter) instead.
|
||||
|
||||
`vendorHash`: is the hash of the output of the dependency fetcher derivation. To obtain it, simply set it to `lib.fakeHash` (or omit it) and run the build ([more details here](#sec-source-hashes)).
|
||||
|
||||
If the upstream source is missing a `pubspec.lock` file, you'll have to vendor one and specify it using `pubspecLockFile`. If it is needed, one will be generated for you and printed when attempting to build the derivation.
|
||||
|
||||
The `dart` commands run can be overridden through `pubGetScript` and `dartCompileCommand`, you can also add flags using `dartCompileFlags` or `dartJitFlags`.
|
||||
|
||||
Dart supports multiple [outputs types](https://dart.dev/tools/dart-compile#types-of-output), you can choose between them using `dartOutputType` (defaults to `exe`). If you want to override the binaries path or the source path they come from, you can use `dartEntryPoints`. Outputs that require a runtime will automatically be wrapped with the relevant runtime (`dartaotruntime` for `aot-snapshot`, `dart run` for `jit-snapshot` and `kernel`, `node` for `js`), this can be overridden through `dartRuntimeCommand`.
|
||||
|
||||
```nix
|
||||
{ buildDartApplication, fetchFromGitHub }:
|
||||
|
||||
buildDartApplication rec {
|
||||
pname = "dart-sass";
|
||||
version = "1.62.1";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "sass";
|
||||
repo = pname;
|
||||
rev = version;
|
||||
hash = "sha256-U6enz8yJcc4Wf8m54eYIAnVg/jsGi247Wy8lp1r1wg4=";
|
||||
};
|
||||
|
||||
pubspecLockFile = ./pubspec.lock;
|
||||
vendorHash = "sha256-Atm7zfnDambN/BmmUf4BG0yUz/y6xWzf0reDw3Ad41s=";
|
||||
}
|
||||
```
|
||||
|
||||
## Flutter applications {#ssec-dart-flutter}
|
||||
|
||||
The function `buildFlutterApplication` builds Flutter applications.
|
||||
|
||||
The deps.json file must always be provided when packaging in Nixpkgs. It will be generated and printed if the derivation is attempted to be built without one. Alternatively, `autoDepsList` may be set to `true` when outside of Nixpkgs, as it relies on import-from-derivation.
|
||||
|
||||
A `pubspec.lock` file must be available. See the [Dart documentation](#ssec-dart-applications) for more details.
|
||||
|
||||
```nix
|
||||
{ flutter, fetchFromGitHub }:
|
||||
|
||||
flutter.buildFlutterApplication {
|
||||
pname = "firmware-updater";
|
||||
version = "unstable-2023-04-30";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "canonical";
|
||||
repo = "firmware-updater";
|
||||
rev = "6e7dbdb64e344633ea62874b54ff3990bd3b8440";
|
||||
sha256 = "sha256-s5mwtr5MSPqLMN+k851+pFIFFPa0N1hqz97ys050tFA=";
|
||||
fetchSubmodules = true;
|
||||
};
|
||||
|
||||
pubspecLockFile = ./pubspec.lock;
|
||||
depsListFile = ./deps.json;
|
||||
vendorHash = "sha256-cdMO+tr6kYiN5xKXa+uTMAcFf2C75F3wVPrn21G4QPQ=";
|
||||
}
|
||||
```
|
||||
@@ -14,7 +14,6 @@
|
||||
<xi:include href="crystal.section.xml" />
|
||||
<xi:include href="cuda.section.xml" />
|
||||
<xi:include href="cuelang.section.xml" />
|
||||
<xi:include href="dart.section.xml" />
|
||||
<xi:include href="dhall.section.xml" />
|
||||
<xi:include href="dotnet.section.xml" />
|
||||
<xi:include href="emscripten.section.xml" />
|
||||
|
||||
@@ -118,7 +118,7 @@ ImageExifTool = buildPerlPackage {
|
||||
hash = "sha256-vOhB/FwQMC8PPvdnjDvxRpU6jAZcC6GMQfc0AH4uwKg=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = lib.optional stdenv.isDarwin shortenPerlShebang;
|
||||
buildInputs = lib.optional stdenv.isDarwin shortenPerlShebang;
|
||||
postInstall = lib.optionalString stdenv.isDarwin ''
|
||||
shortenPerlShebang $out/bin/exiftool
|
||||
'';
|
||||
|
||||
@@ -535,9 +535,7 @@ directory of the `tokenizers` project's source archive, we use
|
||||
```nix
|
||||
{ fetchFromGitHub
|
||||
, buildPythonPackage
|
||||
, cargo
|
||||
, rustPlatform
|
||||
, rustc
|
||||
, setuptools-rust
|
||||
}:
|
||||
|
||||
@@ -560,12 +558,11 @@ buildPythonPackage rec {
|
||||
|
||||
sourceRoot = "source/bindings/python";
|
||||
|
||||
nativeBuildInputs = [
|
||||
cargo
|
||||
rustPlatform.cargoSetupHook
|
||||
rustc
|
||||
setuptools-rust
|
||||
];
|
||||
nativeBuildInputs = [ setuptools-rust ] ++ (with rustPlatform; [
|
||||
cargoSetupHook
|
||||
rust.cargo
|
||||
rust.rustc
|
||||
]);
|
||||
|
||||
# ...
|
||||
}
|
||||
|
||||
@@ -204,11 +204,6 @@ in mkLicense lset) ({
|
||||
free = false;
|
||||
};
|
||||
|
||||
caossl = {
|
||||
fullName = "Computer Associates Open Source Licence Version 1.0";
|
||||
url = "http://jxplorer.org/licence.html";
|
||||
};
|
||||
|
||||
cal10 = {
|
||||
fullName = "Cryptographic Autonomy License version 1.0 (CAL-1.0)";
|
||||
url = "https://opensource.org/licenses/CAL-1.0";
|
||||
@@ -235,12 +230,6 @@ in mkLicense lset) ({
|
||||
free = false;
|
||||
};
|
||||
|
||||
cc-by-nc-nd-40 = {
|
||||
spdxId = "CC-BY-NC-ND-4.0";
|
||||
fullName = "Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International";
|
||||
free = false;
|
||||
};
|
||||
|
||||
cc-by-nc-sa-20 = {
|
||||
spdxId = "CC-BY-NC-SA-2.0";
|
||||
fullName = "Creative Commons Attribution Non Commercial Share Alike 2.0";
|
||||
|
||||
@@ -261,7 +261,7 @@ rec {
|
||||
concatMap (opt:
|
||||
let
|
||||
name = showOption opt.loc;
|
||||
docOption = {
|
||||
docOption = rec {
|
||||
loc = opt.loc;
|
||||
inherit name;
|
||||
description = opt.description or null;
|
||||
@@ -280,9 +280,9 @@ rec {
|
||||
renderOptionValue opt.example
|
||||
);
|
||||
}
|
||||
// optionalAttrs (opt ? defaultText || opt ? default) {
|
||||
// optionalAttrs (opt ? default) {
|
||||
default =
|
||||
builtins.addErrorContext "while evaluating the ${if opt?defaultText then "defaultText" else "default value"} of option `${name}`" (
|
||||
builtins.addErrorContext "while evaluating the default value of option `${name}`" (
|
||||
renderOptionValue (opt.defaultText or opt.default)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -50,7 +50,6 @@ rec {
|
||||
else if final.isFreeBSD then "fblibc"
|
||||
else if final.isNetBSD then "nblibc"
|
||||
else if final.isAvr then "avrlibc"
|
||||
else if final.isGhcjs then null
|
||||
else if final.isNone then "newlib"
|
||||
# TODO(@Ericson2314) think more about other operating systems
|
||||
else "native/impure";
|
||||
@@ -121,7 +120,7 @@ rec {
|
||||
({
|
||||
linux-kernel = args.linux-kernel or {};
|
||||
gcc = args.gcc or {};
|
||||
rustc = args.rustc or {};
|
||||
rustc = args.rust or {};
|
||||
} // platforms.select final)
|
||||
linux-kernel gcc rustc;
|
||||
|
||||
@@ -145,7 +144,6 @@ rec {
|
||||
else if final.isS390 && !final.isS390x then null
|
||||
else if final.isx86_64 then "x86_64"
|
||||
else if final.isx86 then "i386"
|
||||
else if final.isMips64 then "mips64${lib.optionalString final.isLittleEndian "el"}"
|
||||
else final.uname.processor;
|
||||
|
||||
# Name used by UEFI for architectures.
|
||||
|
||||
@@ -579,12 +579,6 @@
|
||||
githubId = 20405311;
|
||||
name = "Aksh Gupta";
|
||||
};
|
||||
alanpearce = {
|
||||
email = "alan@alanpearce.eu";
|
||||
github = "alanpearce";
|
||||
githubId = 850317;
|
||||
name = "Alan Pearce";
|
||||
};
|
||||
alapshin = {
|
||||
email = "alapshin@fastmail.com";
|
||||
github = "alapshin";
|
||||
@@ -996,7 +990,7 @@
|
||||
name = "Stanislas Lange";
|
||||
};
|
||||
AngryAnt = {
|
||||
name = "Emil \"AngryAnt\" Johansen";
|
||||
name = "Emil Johansen";
|
||||
email = "git@eej.dk";
|
||||
matrix = "@angryant:envs.net";
|
||||
github = "AngryAnt";
|
||||
@@ -1526,12 +1520,6 @@
|
||||
githubId = 12958979;
|
||||
name = "Mika Naylor";
|
||||
};
|
||||
autrimpo = {
|
||||
email = "michal@koutensky.net";
|
||||
github = "autrimpo";
|
||||
githubId = 5968483;
|
||||
name = "Michal Koutenský";
|
||||
};
|
||||
autumnal = {
|
||||
name = "Sven Friedrich";
|
||||
email = "sven@autumnal.de";
|
||||
@@ -2108,12 +2096,6 @@
|
||||
githubId = 16330;
|
||||
name = "Mathijs Kwik";
|
||||
};
|
||||
blusk = {
|
||||
email = "bluskript@gmail.com";
|
||||
github = "Bluskript";
|
||||
githubId = 52386117;
|
||||
name = "Blusk";
|
||||
};
|
||||
bmilanov = {
|
||||
name = "Biser Milanov";
|
||||
email = "bmilanov11+nixpkgs@gmail.com";
|
||||
@@ -2418,12 +2400,6 @@
|
||||
githubId = 51231053;
|
||||
name = "Daniel";
|
||||
};
|
||||
cadkin = {
|
||||
email = "cva@siliconslumber.net";
|
||||
name = "Cameron Adkins";
|
||||
github = "cadkin";
|
||||
githubId = 34077838;
|
||||
};
|
||||
cafkafk = {
|
||||
email = "christina@cafkafk.com";
|
||||
matrix = "@cafkafk:matrix.cafkafk.com";
|
||||
@@ -3766,6 +3742,13 @@
|
||||
githubId = 62989;
|
||||
name = "Demyan Rogozhin";
|
||||
};
|
||||
dennajort = {
|
||||
email = "gosselinjb@gmail.com";
|
||||
matrix = "@dennajort:matrix.org";
|
||||
github = "dennajort";
|
||||
githubId = 1536838;
|
||||
name = "Jean-Baptiste Gosselin";
|
||||
};
|
||||
derchris = {
|
||||
email = "derchris@me.com";
|
||||
github = "derchrisuk";
|
||||
@@ -4957,12 +4940,6 @@
|
||||
githubId = 25955146;
|
||||
name = "eyJhb";
|
||||
};
|
||||
f2k1de = {
|
||||
name = "f2k1de";
|
||||
email = "hi@f2k1.de";
|
||||
github = "f2k1de";
|
||||
githubId = 11199213;
|
||||
};
|
||||
f4814n = {
|
||||
email = "me@f4814n.de";
|
||||
github = "f4814";
|
||||
@@ -6221,12 +6198,6 @@
|
||||
githubId = 982322;
|
||||
name = "Henrik Olsson";
|
||||
};
|
||||
henrirosten = {
|
||||
email = "henri.rosten@unikie.com";
|
||||
github = "henrirosten";
|
||||
githubId = 49935860;
|
||||
name = "Henri Rosten";
|
||||
};
|
||||
henrytill = {
|
||||
email = "henrytill@gmail.com";
|
||||
github = "henrytill";
|
||||
@@ -6297,14 +6268,6 @@
|
||||
github = "higebu";
|
||||
githubId = 733288;
|
||||
};
|
||||
|
||||
hikari = {
|
||||
email = "HikariNee@protonmail.com";
|
||||
github = "HikariNee";
|
||||
githubId = 72349937;
|
||||
name = "Hikari";
|
||||
};
|
||||
|
||||
hiljusti = {
|
||||
name = "J.R. Hill";
|
||||
email = "hiljusti@so.dang.cool";
|
||||
@@ -6317,7 +6280,6 @@
|
||||
githubId = 19825977;
|
||||
name = "Hiren Shah";
|
||||
};
|
||||
|
||||
hiro98 = {
|
||||
email = "hiro@protagon.space";
|
||||
github = "vale981";
|
||||
@@ -6806,15 +6768,6 @@
|
||||
githubId = 54999;
|
||||
name = "Ariel Nunez";
|
||||
};
|
||||
Intuinewin = {
|
||||
email = "antoinelabarussias@gmail.com";
|
||||
github = "Intuinewin";
|
||||
githubId = 13691729;
|
||||
name = "Antoine Labarussias";
|
||||
keys = [{
|
||||
fingerprint = "5CB5 9AA0 D180 1997 2FB3 E0EC 943A 1DE9 372E BE4E";
|
||||
}];
|
||||
};
|
||||
ionutnechita = {
|
||||
email = "ionut_n2001@yahoo.com";
|
||||
github = "ionutnechita";
|
||||
@@ -7116,13 +7069,6 @@
|
||||
githubId = 221929;
|
||||
name = "Jean-Baptiste Giraudeau";
|
||||
};
|
||||
jbgosselin = {
|
||||
email = "gosselinjb@gmail.com";
|
||||
matrix = "@dennajort:matrix.org";
|
||||
github = "jbgosselin";
|
||||
githubId = 1536838;
|
||||
name = "Jean-Baptiste Gosselin";
|
||||
};
|
||||
jboy = {
|
||||
email = "jboy+nixos@bius.moe";
|
||||
githubId = 2187261;
|
||||
@@ -7454,12 +7400,6 @@
|
||||
fingerprint = "B768 6CD7 451A 650D 9C54 4204 6710 CF0C 1CBD 7762";
|
||||
}];
|
||||
};
|
||||
jleightcap = {
|
||||
email = "jack@leightcap.com";
|
||||
github = "jleightcap";
|
||||
githubId = 30168080;
|
||||
name = "Jack Leightcap";
|
||||
};
|
||||
jlesquembre = {
|
||||
email = "jl@lafuente.me";
|
||||
github = "jlesquembre";
|
||||
@@ -7941,12 +7881,6 @@
|
||||
githubId = 2469618;
|
||||
name = "Junji Hashimoto";
|
||||
};
|
||||
jurraca = {
|
||||
email = "julienu@pm.me";
|
||||
github = "jurraca";
|
||||
githubId = 5124422;
|
||||
name = "Julien Urraca";
|
||||
};
|
||||
justinas = {
|
||||
email = "justinas@justinas.org";
|
||||
github = "justinas";
|
||||
@@ -8127,13 +8061,6 @@
|
||||
githubId = 524492;
|
||||
name = "Sergey Kazenyuk";
|
||||
};
|
||||
kbdharun = {
|
||||
email = "kbdharunkrishna@gmail.com";
|
||||
matrix = "@kbdk:matrix.org";
|
||||
github = "kbdharun";
|
||||
githubId = 26346867;
|
||||
name = "K.B.Dharun Krishna";
|
||||
};
|
||||
kcalvinalvin = {
|
||||
email = "calvin@kcalvinalvin.info";
|
||||
github = "kcalvinalvin";
|
||||
@@ -9075,12 +9002,6 @@
|
||||
fingerprint = "74F5 E5CC 19D3 B5CB 608F 6124 68FF 81E6 A785 0F49";
|
||||
}];
|
||||
};
|
||||
lizelive = {
|
||||
email = "nixpkgs@lize.live";
|
||||
github = "lizelive";
|
||||
githubId = 40217331;
|
||||
name = "LizeLive";
|
||||
};
|
||||
lluchs = {
|
||||
email = "lukas.werling@gmail.com";
|
||||
github = "lluchs";
|
||||
@@ -10251,15 +10172,6 @@
|
||||
github = "michaelgrahamevans";
|
||||
githubId = 5932424;
|
||||
};
|
||||
michaelpachec0 = {
|
||||
email = "michaelpacheco@protonmail.com";
|
||||
name = "Michael Pacheco";
|
||||
github = "MichaelPachec0";
|
||||
githubId = 48970112;
|
||||
keys = [ {
|
||||
fingerprint = "8D12 991F 5558 C501 70B2 779C 7811 46B0 B5F9 5F64";
|
||||
}];
|
||||
};
|
||||
michaelpj = {
|
||||
email = "michaelpj@gmail.com";
|
||||
github = "michaelpj";
|
||||
@@ -12662,9 +12574,9 @@
|
||||
githubId = 17690377;
|
||||
};
|
||||
ppom = {
|
||||
name = "ppom";
|
||||
email = "ppom@ecomail.fr";
|
||||
github = "ppom0";
|
||||
name = "Paco Pompeani";
|
||||
email = "paco@ecomail.io";
|
||||
github = "aopom";
|
||||
githubId = 38916722;
|
||||
};
|
||||
pradeepchhetri = {
|
||||
@@ -13020,12 +12932,6 @@
|
||||
githubId = 903072;
|
||||
name = "Raghav Sood";
|
||||
};
|
||||
ragingpastry = {
|
||||
email = "senior.crepe@gmail.com";
|
||||
github = "ragingpastry";
|
||||
githubId = 6778250;
|
||||
name = "Nick Wilburn";
|
||||
};
|
||||
raitobezarius = {
|
||||
email = "ryan@lahfa.xyz";
|
||||
matrix = "@raitobezarius:matrix.org";
|
||||
@@ -14356,12 +14262,6 @@
|
||||
githubId = 251028;
|
||||
name = "Shell Turner";
|
||||
};
|
||||
shhht = {
|
||||
name = "shhht";
|
||||
email = "stp.tjeerd@gmail.com";
|
||||
github = "shhht";
|
||||
githubId = 118352823;
|
||||
};
|
||||
shikanime = {
|
||||
name = "William Phetsinorath";
|
||||
email = "deva.shikanime@protonmail.com";
|
||||
@@ -14383,12 +14283,6 @@
|
||||
githubId = 487050;
|
||||
name = "Shea Levy";
|
||||
};
|
||||
shlok = {
|
||||
email = "sd-nix-maintainer@quant.is";
|
||||
github = "shlok";
|
||||
githubId = 3000933;
|
||||
name = "Shlok Datye";
|
||||
};
|
||||
shmish111 = {
|
||||
email = "shmish111@gmail.com";
|
||||
github = "shmish111";
|
||||
@@ -14877,7 +14771,7 @@
|
||||
name = "Christoph Honal";
|
||||
};
|
||||
star-szr = {
|
||||
email = "nixpkgs@szr.fastmail.com";
|
||||
email = "nixpkgs@scottr.mailworks.org";
|
||||
github = "star-szr";
|
||||
githubId = 327943;
|
||||
name = "Scott Zhu Reeves";
|
||||
@@ -15649,15 +15543,6 @@
|
||||
githubId = 57180880;
|
||||
name = "Ansh Tyagi";
|
||||
};
|
||||
therealr5 = {
|
||||
email = "rouven@rfive.de";
|
||||
github = "therealr5";
|
||||
githubId = 72568063;
|
||||
name = "Rouven Seifert";
|
||||
keys = [{
|
||||
fingerprint = "1169 87A8 DD3F 78FF 8601 BF4D B95E 8FE6 B11C 4D09";
|
||||
}];
|
||||
};
|
||||
therishidesai = {
|
||||
email = "desai.rishi1@gmail.com";
|
||||
github = "therishidesai";
|
||||
@@ -15956,12 +15841,6 @@
|
||||
githubId = 8577941;
|
||||
name = "Kevin Rauscher";
|
||||
};
|
||||
tomaskala = {
|
||||
email = "public+nixpkgs@tomaskala.com";
|
||||
github = "tomaskala";
|
||||
githubId = 7727887;
|
||||
name = "Tomas Kala";
|
||||
};
|
||||
tomberek = {
|
||||
email = "tomberek@gmail.com";
|
||||
matrix = "@tomberek:matrix.org";
|
||||
|
||||
@@ -50,22 +50,19 @@ while (@ARGV) {
|
||||
}
|
||||
}
|
||||
|
||||
my $bucket;
|
||||
|
||||
if (not defined $ENV{DEBUG}) {
|
||||
# S3 setup.
|
||||
my $aws_access_key_id = $ENV{'AWS_ACCESS_KEY_ID'} or die "AWS_ACCESS_KEY_ID not set\n";
|
||||
my $aws_secret_access_key = $ENV{'AWS_SECRET_ACCESS_KEY'} or die "AWS_SECRET_ACCESS_KEY not set\n";
|
||||
# S3 setup.
|
||||
my $aws_access_key_id = $ENV{'AWS_ACCESS_KEY_ID'} or die "AWS_ACCESS_KEY_ID not set\n";
|
||||
my $aws_secret_access_key = $ENV{'AWS_SECRET_ACCESS_KEY'} or die "AWS_SECRET_ACCESS_KEY not set\n";
|
||||
|
||||
my $s3 = Net::Amazon::S3->new(
|
||||
{ aws_access_key_id => $aws_access_key_id,
|
||||
aws_secret_access_key => $aws_secret_access_key,
|
||||
retry => 1,
|
||||
host => "s3-eu-west-1.amazonaws.com",
|
||||
});
|
||||
my $s3 = Net::Amazon::S3->new(
|
||||
{ aws_access_key_id => $aws_access_key_id,
|
||||
aws_secret_access_key => $aws_secret_access_key,
|
||||
retry => 1,
|
||||
host => "s3-eu-west-1.amazonaws.com",
|
||||
});
|
||||
|
||||
$bucket = $s3->bucket("nixpkgs-tarballs") or die;
|
||||
}
|
||||
my $bucket = $s3->bucket("nixpkgs-tarballs") or die;
|
||||
|
||||
my $doWrite = 0;
|
||||
my $cacheFile = ($ENV{"HOME"} or die "\$HOME is not set") . "/.cache/nix/copy-tarballs";
|
||||
@@ -162,18 +159,13 @@ elsif (defined $expr) {
|
||||
# Check every fetchurl call discovered by find-tarballs.nix.
|
||||
my $mirrored = 0;
|
||||
my $have = 0;
|
||||
foreach my $fetch (sort { $a->{urls}->[0] cmp $b->{urls}->[0] } @{$fetches}) {
|
||||
my $urls = $fetch->{urls};
|
||||
foreach my $fetch (sort { $a->{url} cmp $b->{url} } @{$fetches}) {
|
||||
my $url = $fetch->{url};
|
||||
my $algo = $fetch->{type};
|
||||
my $hash = $fetch->{hash};
|
||||
my $name = $fetch->{name};
|
||||
my $isPatch = $fetch->{isPatch};
|
||||
|
||||
if ($isPatch) {
|
||||
print STDERR "skipping $urls->[0] (support for patches is missing)\n";
|
||||
next;
|
||||
}
|
||||
|
||||
if ($hash =~ /^([a-z0-9]+)-([A-Za-z0-9+\/=]+)$/) {
|
||||
$algo = $1;
|
||||
$hash = `nix hash to-base16 $hash` or die;
|
||||
@@ -188,60 +180,62 @@ elsif (defined $expr) {
|
||||
chomp $hash;
|
||||
}
|
||||
|
||||
if (defined $ENV{DEBUG}) {
|
||||
print "$url $algo $hash\n";
|
||||
next;
|
||||
}
|
||||
|
||||
if ($url !~ /^http:/ && $url !~ /^https:/ && $url !~ /^ftp:/ && $url !~ /^mirror:/) {
|
||||
print STDERR "skipping $url (unsupported scheme)\n";
|
||||
next;
|
||||
}
|
||||
|
||||
if ($isPatch) {
|
||||
print STDERR "skipping $url (support for patches is missing)\n";
|
||||
next;
|
||||
}
|
||||
|
||||
next if defined $exclude && $url =~ /$exclude/;
|
||||
|
||||
if (alreadyMirrored($algo, $hash)) {
|
||||
$have++;
|
||||
next;
|
||||
}
|
||||
|
||||
my $storePath = makeFixedOutputPath(0, $algo, $hash, $name);
|
||||
|
||||
for my $url (@$urls) {
|
||||
if (defined $ENV{DEBUG}) {
|
||||
print "$url $algo $hash\n";
|
||||
next;
|
||||
}
|
||||
print STDERR "mirroring $url ($storePath, $algo, $hash)...\n";
|
||||
|
||||
if ($url !~ /^http:/ && $url !~ /^https:/ && $url !~ /^ftp:/ && $url !~ /^mirror:/) {
|
||||
print STDERR "skipping $url (unsupported scheme)\n";
|
||||
next;
|
||||
}
|
||||
|
||||
next if defined $exclude && $url =~ /$exclude/;
|
||||
|
||||
if (alreadyMirrored($algo, $hash)) {
|
||||
$have++;
|
||||
last;
|
||||
}
|
||||
|
||||
print STDERR "mirroring $url ($storePath, $algo, $hash)...\n";
|
||||
|
||||
if ($dryRun) {
|
||||
$mirrored++;
|
||||
last;
|
||||
}
|
||||
|
||||
# Substitute the output.
|
||||
if (!isValidPath($storePath)) {
|
||||
system("nix-store", "-r", $storePath);
|
||||
}
|
||||
|
||||
# Otherwise download the file using nix-prefetch-url.
|
||||
if (!isValidPath($storePath)) {
|
||||
$ENV{QUIET} = 1;
|
||||
$ENV{PRINT_PATH} = 1;
|
||||
my $fh;
|
||||
my $pid = open($fh, "-|", "nix-prefetch-url", "--type", $algo, $url, $hash) or die;
|
||||
waitpid($pid, 0) or die;
|
||||
if ($? != 0) {
|
||||
print STDERR "failed to fetch $url: $?\n";
|
||||
next;
|
||||
}
|
||||
<$fh>; my $storePath2 = <$fh>; chomp $storePath2;
|
||||
if ($storePath ne $storePath2) {
|
||||
warn "strange: $storePath != $storePath2\n";
|
||||
next;
|
||||
}
|
||||
}
|
||||
|
||||
uploadFile($storePath, $url);
|
||||
if ($dryRun) {
|
||||
$mirrored++;
|
||||
last;
|
||||
next;
|
||||
}
|
||||
|
||||
# Substitute the output.
|
||||
if (!isValidPath($storePath)) {
|
||||
system("nix-store", "-r", $storePath);
|
||||
}
|
||||
|
||||
# Otherwise download the file using nix-prefetch-url.
|
||||
if (!isValidPath($storePath)) {
|
||||
$ENV{QUIET} = 1;
|
||||
$ENV{PRINT_PATH} = 1;
|
||||
my $fh;
|
||||
my $pid = open($fh, "-|", "nix-prefetch-url", "--type", $algo, $url, $hash) or die;
|
||||
waitpid($pid, 0) or die;
|
||||
if ($? != 0) {
|
||||
print STDERR "failed to fetch $url: $?\n";
|
||||
next;
|
||||
}
|
||||
<$fh>; my $storePath2 = <$fh>; chomp $storePath2;
|
||||
if ($storePath ne $storePath2) {
|
||||
warn "strange: $storePath != $storePath2\n";
|
||||
next;
|
||||
}
|
||||
}
|
||||
|
||||
uploadFile($storePath, $url);
|
||||
$mirrored++;
|
||||
}
|
||||
|
||||
print STDERR "mirrored $mirrored files, already have $have files\n";
|
||||
|
||||
@@ -9,12 +9,12 @@ let
|
||||
|
||||
root = expr;
|
||||
|
||||
uniqueFiles = map (x: x.file) (genericClosure {
|
||||
startSet = map (file: { key = with file; (if type == null then "" else type + "+") + hash; inherit file; }) files;
|
||||
uniqueUrls = map (x: x.file) (genericClosure {
|
||||
startSet = map (file: { key = file.url; inherit file; }) urls;
|
||||
operator = const [ ];
|
||||
});
|
||||
|
||||
files = map (drv: { urls = drv.urls or [ drv.url ]; hash = drv.outputHash; isPatch = (drv?postFetch && drv.postFetch != ""); type = drv.outputHashAlgo; name = drv.name; }) fetchurlDependencies;
|
||||
urls = map (drv: { url = head (drv.urls or [ drv.url ]); hash = drv.outputHash; isPatch = (drv?postFetch && drv.postFetch != ""); type = drv.outputHashAlgo; name = drv.name; }) fetchurlDependencies;
|
||||
|
||||
fetchurlDependencies =
|
||||
filter
|
||||
@@ -47,4 +47,4 @@ let
|
||||
|
||||
canEval = val: (builtins.tryEval val).success;
|
||||
|
||||
in uniqueFiles
|
||||
in uniqueUrls
|
||||
|
||||
@@ -85,8 +85,7 @@ echo "Updating Stackage..."
|
||||
echo "Updating Hackage hashes..."
|
||||
./maintainers/scripts/haskell/update-hackage.sh --do-commit
|
||||
echo "Regenerating Hackage packages..."
|
||||
# Using fast here because after the hackage-update eval errors will likely break the transitive dependencies check.
|
||||
./maintainers/scripts/haskell/regenerate-hackage-packages.sh --fast --do-commit
|
||||
./maintainers/scripts/haskell/regenerate-hackage-packages.sh --do-commit
|
||||
|
||||
# Push these new commits to the haskell-updates branch
|
||||
echo "Pushing commits just created to the remote haskell-updates branch..."
|
||||
|
||||
@@ -1,18 +1,9 @@
|
||||
#! /usr/bin/env nix-shell
|
||||
#! nix-shell -i bash -p coreutils jq nix -I nixpkgs=.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
TMP_TEMPLATE=transitive-broken.XXXXXXX
|
||||
readonly TMP_TEMPLATE
|
||||
|
||||
tmpfile=$(mktemp "$TMP_TEMPLATE")
|
||||
|
||||
trap 'rm -f "${tmpfile}"' 0
|
||||
|
||||
config_file=pkgs/development/haskell-modules/configuration-hackage2nix/transitive-broken.yaml
|
||||
|
||||
cat > $tmpfile << EOF
|
||||
cat > $config_file << EOF
|
||||
# This file is automatically generated by
|
||||
# maintainers/scripts/haskell/regenerate-transitive-broken-packages.sh
|
||||
# It is supposed to list all haskellPackages that cannot evaluate because they
|
||||
@@ -20,6 +11,4 @@ cat > $tmpfile << EOF
|
||||
dont-distribute-packages:
|
||||
EOF
|
||||
|
||||
nix-instantiate --eval --option restrict-eval true -I . --strict --json maintainers/scripts/haskell/transitive-broken-packages.nix | jq -r . | LC_ALL=C.UTF-8 sort -i >> $tmpfile
|
||||
|
||||
mv $tmpfile $config_file
|
||||
nix-instantiate --eval --option restrict-eval true -I . --strict --json maintainers/scripts/haskell/transitive-broken-packages.nix | jq -r . | LC_ALL=C.UTF-8 sort -i >> $config_file
|
||||
|
||||
@@ -151,7 +151,6 @@ with lib.maintainers; {
|
||||
|
||||
cuda = {
|
||||
members = [
|
||||
connorbaker
|
||||
SomeoneSerge
|
||||
];
|
||||
scope = "Maintain CUDA-enabled packages";
|
||||
|
||||
@@ -4,7 +4,7 @@ This manual describes how to install, use and extend NixOS, a Linux distribution
|
||||
|
||||
Additional information regarding the Nix package manager and the Nixpkgs project can be found in respectively the [Nix manual](https://nixos.org/nix/manual) and the [Nixpkgs manual](https://nixos.org/nixpkgs/manual).
|
||||
|
||||
If you encounter problems, please report them on the [`Discourse`](https://discourse.nixos.org), the [Matrix room](https://matrix.to/#/%23nix:nixos.org), or on the [`#nixos` channel on Libera.Chat](irc://irc.libera.chat/#nixos). Alternatively, consider [contributing to this manual](#chap-contributing). Bugs should be reported in [NixOS’ GitHub issue tracker](https://github.com/NixOS/nixpkgs/issues).
|
||||
If you encounter problems, please report them on the [`Discourse`](https://discourse.nixos.org), the [Matrix room](https://matrix.to/#nix:nixos.org), or on the [`#nixos` channel on Libera.Chat](irc://irc.libera.chat/#nixos). Alternatively, consider [contributing to this manual](#chap-contributing). Bugs should be reported in [NixOS’ GitHub issue tracker](https://github.com/NixOS/nixpkgs/issues).
|
||||
|
||||
::: {.note}
|
||||
Commands prefixed with `#` have to be run as root, either requiring to login as root user or temporarily switching to it using `sudo` for example.
|
||||
|
||||
@@ -24,8 +24,6 @@ In addition to numerous new and upgraded packages, this release has the followin
|
||||
|
||||
- KDE Plasma has been updated to v5.27, see [the release notes](https://kde.org/announcements/plasma/5/5.27.0/) for what is changed.
|
||||
|
||||
- Python implements [PEP 668](https://peps.python.org/pep-0668/), providing better feedback to users that try to run `pip install` system-wide.
|
||||
|
||||
- `nixos-rebuild` now supports an extra `--specialisation` option that can be used to change specialisation for `switch` and `test` commands.
|
||||
|
||||
- `libxcrypt`, the library providing the `crypt(3)` password hashing function, is now built without support for algorithms not flagged [`strong`](https://github.com/besser82/libxcrypt/blob/v4.4.33/lib/hashes.conf#L48). This affects the availability of password hashing algorithms used for system login (`login(1)`, `passwd(1)`), but also Apache2 Basic-Auth, Samba, OpenLDAP, Dovecot, and [many other packages](https://github.com/search?q=repo%3ANixOS%2Fnixpkgs%20libxcrypt&type=code).
|
||||
@@ -38,8 +36,6 @@ In addition to numerous new and upgraded packages, this release has the followin
|
||||
|
||||
- [Akkoma](https://akkoma.social), an ActivityPub microblogging server. Available as [services.akkoma](options.html#opt-services.akkoma.enable).
|
||||
|
||||
- [Pixelfed](https://pixelfed.org/), an Instagram-like ActivityPub server. Available as [services.pixelfed](options.html#opt-services.pixelfed.enable).
|
||||
|
||||
- [blesh](https://github.com/akinomyoga/ble.sh), a line editor written in pure bash. Available as [programs.bash.blesh](#opt-programs.bash.blesh.enable).
|
||||
|
||||
- [webhook](https://github.com/adnanh/webhook), a lightweight webhook server. Available as [services.webhook](#opt-services.webhook.enable).
|
||||
@@ -60,12 +56,8 @@ In addition to numerous new and upgraded packages, this release has the followin
|
||||
|
||||
- [gemstash](https://github.com/rubygems/gemstash), a RubyGems.org cache and private gem server. Available as [services.gemstash](#opt-services.gemstash.enable).
|
||||
|
||||
- [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).
|
||||
|
||||
- [gmediarender](https://github.com/hzeller/gmrender-resurrect), a simple, headless UPnP/DLNA renderer. Available as [services.gmediarender](options.html#opt-services.gmediarender.enable).
|
||||
|
||||
- [harmonia](https://github.com/nix-community/harmonia/), Nix binary cache implemented in rust using libnix-store. Available as [services.harmonia](options.html#opt-services.harmonia.enable).
|
||||
|
||||
- [hyprland](https://github.com/hyprwm/hyprland), a dynamic tiling Wayland compositor that doesn't sacrifice on its looks. Available as [programs.hyprland](#opt-programs.hyprland.enable).
|
||||
|
||||
- [minipro](https://gitlab.com/DavidGriffith/minipro/), an open source program for controlling the MiniPRO TL866xx series of chip programmers. Available as [programs.minipro](options.html#opt-programs.minipro.enable).
|
||||
@@ -96,8 +88,6 @@ In addition to numerous new and upgraded packages, this release has the followin
|
||||
|
||||
- [networkd-dispatcher](https://gitlab.com/craftyguy/networkd-dispatcher), a dispatcher service for systemd-networkd connection status changes. Available as [services.networkd-dispatcher](#opt-services.networkd-dispatcher.enable).
|
||||
|
||||
- [gonic](https://github.com/sentriz/gonic), a Subsonic music streaming server. Available as [services.gonic](#opt-services.gonic.enable).
|
||||
|
||||
- [mmsd](https://gitlab.com/kop316/mmsd), a lower level daemon that transmits and recieves MMSes. Available as [services.mmsd](#opt-services.mmsd.enable).
|
||||
|
||||
- [QDMR](https://dm3mat.darc.de/qdmr/), a GUI application and command line tool for programming DMR radios [programs.qdmr](#opt-programs.qdmr.enable)
|
||||
@@ -108,12 +98,8 @@ In addition to numerous new and upgraded packages, this release has the followin
|
||||
|
||||
- [vault-agent](https://developer.hashicorp.com/vault/docs/agent), a template rendering and API auth proxy for HashiCorp Vault, similar to `consul-template`. Available as [services.vault-agent](#opt-services.vault-agent.instances).
|
||||
|
||||
- [trippy](https://github.com/fujiapple852/trippy), a network diagnostic tool. Available as [programs.trippy](#opt-programs.trippy.enable).
|
||||
|
||||
- [v2rayA](https://v2raya.org), a Linux web GUI client of Project V which supports V2Ray, Xray, SS, SSR, Trojan and Pingtunnel. Available as [services.v2raya](options.html#opt-services.v2raya.enable).
|
||||
|
||||
- [rshim](https://github.com/Mellanox/rshim-user-space), the user-space rshim driver for the BlueField SoC. Available as [services.rshim](options.html#opt-services.rshim.enable).
|
||||
|
||||
- [wstunnel](https://github.com/erebe/wstunnel), a proxy tunnelling arbitrary TCP or UDP traffic through a WebSocket connection. Instances may be configured via [services.wstunnel](options.html#opt-services.wstunnel.enable).
|
||||
|
||||
- [ulogd](https://www.netfilter.org/projects/ulogd/index.html), a userspace logging daemon for netfilter/iptables related logging. Available as [services.ulogd](options.html#opt-services.ulogd.enable).
|
||||
@@ -124,14 +110,8 @@ In addition to numerous new and upgraded packages, this release has the followin
|
||||
|
||||
- [stargazer](https://sr.ht/~zethra/stargazer/), a fast and easy to use Gemini server. Available as [services.stargazer](#opt-services.stargazer.enable).
|
||||
|
||||
- [sniffnet](https://github.com/GyulyVGC/sniffnet), an application to monitor your network traffic. Available as [programs.sniffnet](#opt-programs.sniffnet.enable).
|
||||
|
||||
- [photoprism](https://photoprism.app/), a AI-Powered Photos App for the Decentralized Web. Available as [services.photoprism](options.html#opt-services.photoprism.enable).
|
||||
|
||||
- [alice-lg](github.com/alice-lg/alice-lg), a looking-glass for BGP sessions. Available as [services.alice-lg](#opt-services.alice-lg.enable).
|
||||
|
||||
- [birdwatcher](github.com/alice-lg/birdwatcher), a small HTTP server meant to provide an API defined by Barry O'Donovan's birds-eye to the BIRD internet routing daemon. Available as [services.birdwatcher](#opt-services.birdwatcher.enable).
|
||||
|
||||
- [peroxide](https://github.com/ljanyst/peroxide), a fork of the official [ProtonMail bridge](https://github.com/ProtonMail/proton-bridge) that aims to be similar to [Hydroxide](https://github.com/emersion/hydroxide). Available as [services.peroxide](#opt-services.peroxide.enable).
|
||||
|
||||
- [autosuspend](https://github.com/languitar/autosuspend), a python daemon that suspends a system if certain conditions are met, or not met.
|
||||
@@ -182,8 +162,6 @@ In addition to numerous new and upgraded packages, this release has the followin
|
||||
|
||||
- `git-bug` has been updated to at least version 0.8.0, which includes backwards incompatible changes. The `git-bug-migration` package can be used to upgrade existing repositories.
|
||||
|
||||
- `graylog` has been updated to version 5, which can not be upgraded directly from the previously packaged version 3.3. If you had installed the previously packaged version 3.3, please follow the [upgrade path](https://go2docs.graylog.org/5-0/upgrading_graylog/upgrade_path.htm) from 3.3 to 4.0 to 4.3 to 5.0.
|
||||
|
||||
- `nushell` has been updated to at least version 0.77.0, which includes potential breaking changes in aliases. The old aliases are now available as `old-alias` but it is recommended you migrate to the new format. See [Reworked aliases](https://www.nushell.sh/blog/2023-03-14-nushell_0_77.html#reworked-aliases-breaking-changes-kubouch).
|
||||
|
||||
- `keepassx` and `keepassx2` have been removed, due to upstream [stopping development](https://www.keepassx.org/index.html%3Fp=636.html). Consider [KeePassXC](https://keepassxc.org) as a maintained alternative.
|
||||
@@ -199,26 +177,6 @@ In addition to numerous new and upgraded packages, this release has the followin
|
||||
|
||||
- `services.sourcehut.dispatch` and the corresponding package (`sourcehut.dispatchsrht`) have been removed due to [upstream deprecation](https://sourcehut.org/blog/2022-08-01-dispatch-deprecation-plans/).
|
||||
|
||||
- The attributes used by `services.snapper.configs.<name>` have changed. Migrate from this:
|
||||
|
||||
```nix
|
||||
services.snapper.configs.example = {
|
||||
subvolume = "/example";
|
||||
extraConfig = ''
|
||||
ALLOW_USERS="alice"
|
||||
'';
|
||||
};
|
||||
```
|
||||
|
||||
to this:
|
||||
|
||||
```nix
|
||||
services.snapper.configs.example = {
|
||||
SUBVOLUME = "/example";
|
||||
ALLOW_USERS = [ "alice" ];
|
||||
};
|
||||
```
|
||||
|
||||
- The [services.snapserver.openFirewall](#opt-services.snapserver.openFirewall) module option default value has been changed from `true` to `false`. You will need to explicitly set this option to `true`, or configure your firewall.
|
||||
|
||||
- The [services.tmate-ssh-server.openFirewall](#opt-services.tmate-ssh-server.openFirewall) module option default value has been changed from `true` to `false`. You will need to explicitly set this option to `true`, or configure your firewall.
|
||||
@@ -267,6 +225,7 @@ In addition to numerous new and upgraded packages, this release has the followin
|
||||
|
||||
- [`services.nextcloud.database.createLocally`](#opt-services.nextcloud.database.createLocally) now uses socket authentication and is no longer compatible with password authentication.
|
||||
- If you want the module to manage the database for you, unset [`services.nextcloud.config.dbpassFile`](#opt-services.nextcloud.config.dbpassFile) (and [`services.nextcloud.config.dbhost`](#opt-services.nextcloud.config.dbhost), if it's set).
|
||||
- If your database is external, simply set [`services.nextcloud.database.createLocally`](#opt-services.nextcloud.database.createLocally) to `false`.
|
||||
- If you want to use password authentication **and** create the database locally, you will have to use [`services.mysql`](#opt-services.mysql.enable) to set it up.
|
||||
|
||||
- `protonmail-bridge` package has been updated to major version 3.
|
||||
@@ -300,8 +259,6 @@ In addition to numerous new and upgraded packages, this release has the followin
|
||||
|
||||
- [services.xserver.videoDrivers](options.html#opt-services.xserver.videoDrivers) now defaults to the `modesetting` driver over device-specific ones. The `radeon`, `amdgpu` and `nouveau` drivers are still available, but effectively unmaintained and not recommended for use.
|
||||
|
||||
- [services.xserver.libinput.enable](options.html#opt-services.xserver.libinput.enable) is now set by default, enabling the more actively maintained and consistently behaved input device driver.
|
||||
|
||||
- To enable the HTTP3 (QUIC) protocol for a nginx virtual host, set the `quic` attribute on it to true, e.g. `services.nginx.virtualHosts.<name>.quic = true;`.
|
||||
|
||||
- In `services.fail2ban`, `bantime-increment.<name>` options now default to `null` (except `bantime-increment.enable`) and are used to set the corresponding option in `jail.local` only if not `null`. Also, enforce that `bantime-increment.formula` and `bantime-increment.multipliers` are not both specified.
|
||||
@@ -331,8 +288,6 @@ In addition to numerous new and upgraded packages, this release has the followin
|
||||
|
||||
- The `zplug` package changes its output path from `$out` to `$out/share/zplug`. Users should update their dependency on `${pkgs.zplug}/init.zsh` to `${pkgs.zplug}/share/zplug/init.zsh`.
|
||||
|
||||
- The `pict-rs` package was updated from an 0.3 alpha release to 0.3 stable, and related environment variables now require two underscores instead of one.
|
||||
|
||||
## Other Notable Changes {#sec-release-23.05-notable-changes}
|
||||
|
||||
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
|
||||
@@ -379,15 +334,13 @@ In addition to numerous new and upgraded packages, this release has the followin
|
||||
|
||||
- `services.maddy` got several updates:
|
||||
- Configuration of users and their credentials using `services.maddy.ensureCredentials`.
|
||||
- TLS configuration is now possible via `services.maddy.tls` with two loaders present: ACME and file based.
|
||||
- Configuration of TLS key and certificate files using `services.maddy.tls`.
|
||||
|
||||
- The `dnsmasq` service now takes configuration via the
|
||||
`services.dnsmasq.settings` attribute set. The option
|
||||
`services.dnsmasq.extraConfig` will be deprecated when NixOS 22.11 reaches
|
||||
end of life.
|
||||
|
||||
- `kube3d` has now been renamed to `k3d` since the 3d editor that originally took that name has been dropped from nixpkgs. `kube3d` will continue to work as an alias for now.
|
||||
|
||||
- The `dokuwiki` service is now configured via `services.dokuwiki.sites.<name>.settings` attribute set; `extraConfig` has been removed.
|
||||
The `{aclUse,superUser,disableActions}` attributes have been renamed accordingly. `pluginsConfig` now only accepts an attribute set of booleans.
|
||||
Passing plain PHP is no longer possible.
|
||||
@@ -414,28 +367,6 @@ In addition to numerous new and upgraded packages, this release has the followin
|
||||
|
||||
- `nextcloud` has an option to enable SSE-C in S3.
|
||||
|
||||
- NixOS swap partitions with random encryption can now control the sector size, cipher, and key size used to setup the plain encryption device over the
|
||||
underlying block device rather than allowing them to be determined by `cryptsetup(8)`. One can use these features like so:
|
||||
|
||||
```nix
|
||||
{
|
||||
swapDevices = [
|
||||
{
|
||||
device = "/dev/disk/by-partlabel/swapspace";
|
||||
|
||||
randomEncryption = {
|
||||
enable = true;
|
||||
cipher = "aes-xts-plain64";
|
||||
keySize = 512;
|
||||
sectorSize = 4096;
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
- New option `security.pam.zfs` to enable unlocking and mounting of encrypted ZFS home dataset at login.
|
||||
|
||||
- `services.peertube` now requires you to specify the secret file `secrets.secretsFile`. It can be generated by running `openssl rand -hex 32`.
|
||||
Before upgrading, read the release notes for PeerTube:
|
||||
- [Release v5.0.0](https://github.com/Chocobozzz/PeerTube/releases/tag/v5.0.0)
|
||||
@@ -454,8 +385,6 @@ In addition to numerous new and upgraded packages, this release has the followin
|
||||
}
|
||||
```
|
||||
|
||||
- `services.netdata` offers a `deadlineBeforeStopSec` option which enable users who have netdata instance that takes time to initialize to not have systemd kill them for no reason.
|
||||
|
||||
- `services.dhcpcd` service now don't solicit or accept IPv6 Router Advertisements on interfaces that use static IPv6 addresses.
|
||||
If network uses both IPv6 Unique local addresses (ULA) and global IPv6 address auto-configuration with SLAAC, must add the parameter `networking.dhcpcd.IPv6rs = true;`.
|
||||
|
||||
|
||||
@@ -511,7 +511,7 @@ let format' = format; in let
|
||||
${if format == "raw" then ''
|
||||
mv $diskImage $out/${filename}
|
||||
'' else ''
|
||||
${pkgs.qemu-utils}/bin/qemu-img convert -f raw -O ${format} ${compress} $diskImage $out/${filename}
|
||||
${pkgs.qemu}/bin/qemu-img convert -f raw -O ${format} ${compress} $diskImage $out/${filename}
|
||||
''}
|
||||
diskImage=$out/${filename}
|
||||
'';
|
||||
|
||||
@@ -261,8 +261,8 @@ let
|
||||
mv $bootDiskImage $out/${bootFilename}
|
||||
mv $rootDiskImage $out/${rootFilename}
|
||||
'' else ''
|
||||
${pkgs.qemu_kvm}/bin/qemu-img convert -f raw -O ${formatOpt} ${compress} $bootDiskImage $out/${bootFilename}
|
||||
${pkgs.qemu_kvm}/bin/qemu-img convert -f raw -O ${formatOpt} ${compress} $rootDiskImage $out/${rootFilename}
|
||||
${pkgs.qemu}/bin/qemu-img convert -f raw -O ${formatOpt} ${compress} $bootDiskImage $out/${bootFilename}
|
||||
${pkgs.qemu}/bin/qemu-img convert -f raw -O ${formatOpt} ${compress} $rootDiskImage $out/${rootFilename}
|
||||
''}
|
||||
bootDiskImage=$out/${bootFilename}
|
||||
rootDiskImage=$out/${rootFilename}
|
||||
|
||||
@@ -244,7 +244,7 @@ let
|
||||
${if formatOpt == "raw" then ''
|
||||
mv $rootDiskImage $out/${rootFilename}
|
||||
'' else ''
|
||||
${pkgs.qemu_kvm}/bin/qemu-img convert -f raw -O ${formatOpt} ${compress} $rootDiskImage $out/${rootFilename}
|
||||
${pkgs.qemu}/bin/qemu-img convert -f raw -O ${formatOpt} ${compress} $rootDiskImage $out/${rootFilename}
|
||||
''}
|
||||
rootDiskImage=$out/${rootFilename}
|
||||
set -x
|
||||
|
||||
@@ -7,7 +7,6 @@ import io
|
||||
import os
|
||||
import queue
|
||||
import re
|
||||
import select
|
||||
import shlex
|
||||
import shutil
|
||||
import socket
|
||||
@@ -100,7 +99,7 @@ def _perform_ocr_on_screenshot(
|
||||
+ "-blur 1x65535"
|
||||
)
|
||||
|
||||
tess_args = "-c debug_file=/dev/null --psm 11"
|
||||
tess_args = f"-c debug_file=/dev/null --psm 11"
|
||||
|
||||
cmd = f"convert {magick_args} '{screenshot_path}' 'tiff:{screenshot_path}.tiff'"
|
||||
ret = subprocess.run(cmd, shell=True, capture_output=True)
|
||||
@@ -155,7 +154,6 @@ class StartCommand:
|
||||
# qemu options
|
||||
qemu_opts = (
|
||||
" -device virtio-serial"
|
||||
# Note: virtconsole will map to /dev/hvc0 in Linux guests
|
||||
" -device virtconsole,chardev=shell"
|
||||
" -device virtio-rng-pci"
|
||||
" -serial stdio"
|
||||
@@ -526,10 +524,8 @@ class Machine:
|
||||
if timeout is not None:
|
||||
timeout_str = f"timeout {timeout}"
|
||||
|
||||
# While sh is bash on NixOS, this is not the case for every distro.
|
||||
# We explicitely 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} sh -c {shlex.quote(command)} | (base64 --wrap 0; echo)\n"
|
||||
)
|
||||
|
||||
assert self.shell
|
||||
@@ -723,15 +719,6 @@ class Machine:
|
||||
self.wait_for_unit(jobname)
|
||||
|
||||
def connect(self) -> None:
|
||||
def shell_ready(timeout_secs: int) -> bool:
|
||||
"""We sent some data from the backdoor service running on the guest
|
||||
to indicate that the backdoor shell is ready.
|
||||
As soon as we read some data from the socket here, we assume that
|
||||
our root shell is operational.
|
||||
"""
|
||||
(ready, _, _) = select.select([self.shell], [], [], timeout_secs)
|
||||
return bool(ready)
|
||||
|
||||
if self.connected:
|
||||
return
|
||||
|
||||
@@ -741,11 +728,8 @@ class Machine:
|
||||
assert self.shell
|
||||
|
||||
tic = time.time()
|
||||
# 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(self.shell.recv(1024).decode())
|
||||
self.shell.recv(1024)
|
||||
# TODO: Timeout
|
||||
toc = time.time()
|
||||
|
||||
self.log("connected to guest root shell")
|
||||
@@ -966,7 +950,7 @@ class Machine:
|
||||
Prepares the machine to be reconnected which is useful if the
|
||||
machine was started with `allow_reboot = True`
|
||||
"""
|
||||
self.send_key("ctrl-alt-delete")
|
||||
self.send_key(f"ctrl-alt-delete")
|
||||
self.connected = False
|
||||
|
||||
def wait_for_x(self) -> None:
|
||||
|
||||
@@ -102,8 +102,8 @@ in {
|
||||
${pkgs.jq}/bin/jq -n \
|
||||
--arg system_label ${lib.escapeShellArg config.system.nixos.label} \
|
||||
--arg system ${lib.escapeShellArg pkgs.stdenv.hostPlatform.system} \
|
||||
--arg root_logical_bytes "$(${pkgs.qemu_kvm}/bin/qemu-img info --output json "$rootDisk" | ${pkgs.jq}/bin/jq '."virtual-size"')" \
|
||||
--arg boot_logical_bytes "$(${pkgs.qemu_kvm}/bin/qemu-img info --output json "$bootDisk" | ${pkgs.jq}/bin/jq '."virtual-size"')" \
|
||||
--arg root_logical_bytes "$(${pkgs.qemu}/bin/qemu-img info --output json "$rootDisk" | ${pkgs.jq}/bin/jq '."virtual-size"')" \
|
||||
--arg boot_logical_bytes "$(${pkgs.qemu}/bin/qemu-img info --output json "$bootDisk" | ${pkgs.jq}/bin/jq '."virtual-size"')" \
|
||||
--arg boot_mode "${amiBootMode}" \
|
||||
--arg root "$rootDisk" \
|
||||
--arg boot "$bootDisk" \
|
||||
@@ -142,7 +142,7 @@ in {
|
||||
${pkgs.jq}/bin/jq -n \
|
||||
--arg system_label ${lib.escapeShellArg config.system.nixos.label} \
|
||||
--arg system ${lib.escapeShellArg pkgs.stdenv.hostPlatform.system} \
|
||||
--arg logical_bytes "$(${pkgs.qemu_kvm}/bin/qemu-img info --output json "$diskImage" | ${pkgs.jq}/bin/jq '."virtual-size"')" \
|
||||
--arg logical_bytes "$(${pkgs.qemu}/bin/qemu-img info --output json "$diskImage" | ${pkgs.jq}/bin/jq '."virtual-size"')" \
|
||||
--arg boot_mode "${amiBootMode}" \
|
||||
--arg file "$diskImage" \
|
||||
'{}
|
||||
|
||||
@@ -85,7 +85,7 @@ in
|
||||
${pkgs.jq}/bin/jq -n \
|
||||
--arg system_label ${lib.escapeShellArg config.system.nixos.label} \
|
||||
--arg system ${lib.escapeShellArg pkgs.stdenv.hostPlatform.system} \
|
||||
--arg root_logical_bytes "$(${pkgs.qemu_kvm}/bin/qemu-img info --output json "$rootDisk" | ${pkgs.jq}/bin/jq '."virtual-size"')" \
|
||||
--arg root_logical_bytes "$(${pkgs.qemu}/bin/qemu-img info --output json "$rootDisk" | ${pkgs.jq}/bin/jq '."virtual-size"')" \
|
||||
--arg boot_mode "${imageBootMode}" \
|
||||
--arg root "$rootDisk" \
|
||||
'{}
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
# GNU GRUB, where available.
|
||||
boot.loader.grub.enable = !pkgs.stdenv.isAarch32;
|
||||
boot.loader.grub.version = 2;
|
||||
|
||||
# GNU lsh.
|
||||
services.openssh.enable = false;
|
||||
|
||||
@@ -30,7 +30,7 @@ let
|
||||
|
||||
systemPlatform = platformMap.${pkgs.stdenv.hostPlatform.system} or (throw "scudo not supported on ${pkgs.stdenv.hostPlatform.system}");
|
||||
in {
|
||||
libPath = "${pkgs.llvmPackages_14.compiler-rt}/lib/linux/libclang_rt.scudo-${systemPlatform}.so";
|
||||
libPath = "${pkgs.llvmPackages_latest.compiler-rt}/lib/linux/libclang_rt.scudo-${systemPlatform}.so";
|
||||
description = ''
|
||||
A user-mode allocator based on LLVM Sanitizer’s CombinedAllocator,
|
||||
which aims at providing additional mitigations against heap based
|
||||
|
||||
@@ -47,7 +47,7 @@ with lib;
|
||||
libva = super.libva-minimal;
|
||||
limesuite = super.limesuite.override { withGui = false; };
|
||||
mc = super.mc.override { x11Support = false; };
|
||||
mpv-unwrapped = super.mpv-unwrapped.override { sdl2Support = false; x11Support = false; waylandSupport = false; };
|
||||
mpv-unwrapped = super.mpv-unwrapped.override { sdl2Support = false; x11Support = false; };
|
||||
msmtp = super.msmtp.override { withKeyring = false; };
|
||||
neofetch = super.neofetch.override { x11Support = false; };
|
||||
networkmanager-fortisslvpn = super.networkmanager-fortisslvpn.override { withGnome = false; };
|
||||
@@ -59,7 +59,6 @@ with lib;
|
||||
networkmanager-vpnc = super.networkmanager-vpnc.override { withGnome = false; };
|
||||
pango = super.pango.override { x11Support = false; };
|
||||
pinentry = super.pinentry.override { enabledFlavors = [ "curses" "tty" "emacs" ]; withLibsecret = false; };
|
||||
pipewire = super.pipewire.override { x11Support = false; };
|
||||
qemu = super.qemu.override { gtkSupport = false; spiceSupport = false; sdlSupport = false; };
|
||||
qrencode = super.qrencode.overrideAttrs (_: { doCheck = false; });
|
||||
qt5 = super.qt5.overrideScope (const (super': {
|
||||
|
||||
@@ -38,34 +38,6 @@ let
|
||||
'';
|
||||
};
|
||||
|
||||
keySize = mkOption {
|
||||
default = null;
|
||||
example = "512";
|
||||
type = types.nullOr types.int;
|
||||
description = lib.mdDoc ''
|
||||
Set the encryption key size for the plain device.
|
||||
|
||||
If not specified, the amount of data to read from `source` will be
|
||||
determined by cryptsetup.
|
||||
|
||||
See `cryptsetup-open(8)` for details.
|
||||
'';
|
||||
};
|
||||
|
||||
sectorSize = mkOption {
|
||||
default = null;
|
||||
example = "4096";
|
||||
type = types.nullOr types.int;
|
||||
description = lib.mdDoc ''
|
||||
Set the sector size for the plain encrypted device type.
|
||||
|
||||
If not specified, the default sector size is determined from the
|
||||
underlying block device.
|
||||
|
||||
See `cryptsetup-open(8)` for details.
|
||||
'';
|
||||
};
|
||||
|
||||
source = mkOption {
|
||||
default = "/dev/urandom";
|
||||
example = "/dev/random";
|
||||
@@ -185,11 +157,11 @@ let
|
||||
|
||||
};
|
||||
|
||||
config = {
|
||||
config = rec {
|
||||
device = mkIf options.label.isDefined
|
||||
"/dev/disk/by-label/${config.label}";
|
||||
deviceName = lib.replaceStrings ["\\"] [""] (escapeSystemdPath config.device);
|
||||
realDevice = if config.randomEncryption.enable then "/dev/mapper/${config.deviceName}" else config.device;
|
||||
realDevice = if config.randomEncryption.enable then "/dev/mapper/${deviceName}" else config.device;
|
||||
};
|
||||
|
||||
};
|
||||
@@ -275,12 +247,7 @@ in
|
||||
''}
|
||||
${optionalString sw.randomEncryption.enable ''
|
||||
cryptsetup plainOpen -c ${sw.randomEncryption.cipher} -d ${sw.randomEncryption.source} \
|
||||
'' + concatMapStrings (arg: arg + " \\\n") (flatten [
|
||||
(optional (sw.randomEncryption.sectorSize != null) "--sector-size=${toString sw.randomEncryption.sectorSize}")
|
||||
(optional (sw.randomEncryption.keySize != null) "--key-size=${toString sw.randomEncryption.keySize}")
|
||||
(optional sw.randomEncryption.allowDiscards "--allow-discards")
|
||||
]) + ''
|
||||
${sw.device} ${sw.deviceName}
|
||||
${optionalString sw.randomEncryption.allowDiscards "--allow-discards"} ${sw.device} ${sw.deviceName}
|
||||
mkswap ${sw.realDevice}
|
||||
''}
|
||||
'';
|
||||
|
||||
@@ -473,7 +473,7 @@ in
|
||||
};
|
||||
|
||||
isoImage.squashfsCompression = mkOption {
|
||||
default = with pkgs.stdenv.hostPlatform; "xz -Xdict-size 100% "
|
||||
default = with pkgs.stdenv.targetPlatform; "xz -Xdict-size 100% "
|
||||
+ lib.optionalString isx86 "-Xbcj x86"
|
||||
# Untested but should also reduce size for these platforms
|
||||
+ lib.optionalString isAarch "-Xbcj arm"
|
||||
@@ -483,7 +483,6 @@ in
|
||||
Compression settings to use for the squashfs nix store.
|
||||
'';
|
||||
example = "zstd -Xcompression-level 6";
|
||||
type = types.str;
|
||||
};
|
||||
|
||||
isoImage.edition = mkOption {
|
||||
@@ -694,6 +693,8 @@ in
|
||||
}
|
||||
];
|
||||
|
||||
boot.loader.grub.version = 2;
|
||||
|
||||
# Don't build the GRUB menu builder script, since we don't need it
|
||||
# here and it causes a cyclic dependency.
|
||||
boot.loader.grub.enable = false;
|
||||
|
||||
@@ -8,20 +8,6 @@ with lib;
|
||||
{
|
||||
options = {
|
||||
|
||||
netboot.squashfsCompression = mkOption {
|
||||
default = with pkgs.stdenv.hostPlatform; "xz -Xdict-size 100% "
|
||||
+ lib.optionalString isx86 "-Xbcj x86"
|
||||
# Untested but should also reduce size for these platforms
|
||||
+ lib.optionalString isAarch "-Xbcj arm"
|
||||
+ lib.optionalString (isPower && is32bit && isBigEndian) "-Xbcj powerpc"
|
||||
+ lib.optionalString (isSparc) "-Xbcj sparc";
|
||||
description = lib.mdDoc ''
|
||||
Compression settings to use for the squashfs nix store.
|
||||
'';
|
||||
example = "zstd -Xcompression-level 6";
|
||||
type = types.str;
|
||||
};
|
||||
|
||||
netboot.storeContents = mkOption {
|
||||
example = literalExpression "[ pkgs.stdenv ]";
|
||||
description = lib.mdDoc ''
|
||||
@@ -91,7 +77,6 @@ with lib;
|
||||
# Create the squashfs image that contains the Nix store.
|
||||
system.build.squashfsStore = pkgs.callPackage ../../../lib/make-squashfs.nix {
|
||||
storeContents = config.netboot.storeContents;
|
||||
comp = config.netboot.squashfsCompression;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -651,6 +651,7 @@ EOF
|
||||
$bootLoaderConfig = <<EOF;
|
||||
# Use the GRUB 2 boot loader.
|
||||
boot.loader.grub.enable = true;
|
||||
boot.loader.grub.version = 2;
|
||||
# boot.loader.grub.efiSupport = true;
|
||||
# boot.loader.grub.efiInstallAsRemovable = true;
|
||||
# boot.loader.efi.efiSysMountPoint = "/boot/efi";
|
||||
|
||||
@@ -153,7 +153,6 @@
|
||||
./programs/cnping.nix
|
||||
./programs/command-not-found/command-not-found.nix
|
||||
./programs/criu.nix
|
||||
./programs/darling.nix
|
||||
./programs/dconf.nix
|
||||
./programs/digitalbitbox/default.nix
|
||||
./programs/dmrconfig.nix
|
||||
@@ -235,7 +234,6 @@
|
||||
./programs/singularity.nix
|
||||
./programs/skim.nix
|
||||
./programs/slock.nix
|
||||
./programs/sniffnet.nix
|
||||
./programs/spacefm.nix
|
||||
./programs/ssh.nix
|
||||
./programs/starship.nix
|
||||
@@ -249,7 +247,6 @@
|
||||
./programs/thunar.nix
|
||||
./programs/tmux.nix
|
||||
./programs/traceroute.nix
|
||||
./programs/trippy.nix
|
||||
./programs/tsm-client.nix
|
||||
./programs/turbovnc.nix
|
||||
./programs/udevil.nix
|
||||
@@ -309,7 +306,6 @@
|
||||
./services/audio/alsa.nix
|
||||
./services/audio/botamusique.nix
|
||||
./services/audio/gmediarender.nix
|
||||
./services/audio/gonic.nix
|
||||
./services/audio/hqplayerd.nix
|
||||
./services/audio/icecast.nix
|
||||
./services/audio/jack.nix
|
||||
@@ -375,7 +371,6 @@
|
||||
./services/continuous-integration/buildbot/master.nix
|
||||
./services/continuous-integration/buildbot/worker.nix
|
||||
./services/continuous-integration/buildkite-agents.nix
|
||||
./services/continuous-integration/gitea-actions-runner.nix
|
||||
./services/continuous-integration/github-runner.nix
|
||||
./services/continuous-integration/github-runners.nix
|
||||
./services/continuous-integration/gitlab-runner.nix
|
||||
@@ -689,7 +684,6 @@
|
||||
./services/misc/ripple-data-api.nix
|
||||
./services/misc/rippled.nix
|
||||
./services/misc/rmfakecloud.nix
|
||||
./services/misc/rshim.nix
|
||||
./services/misc/safeeyes.nix
|
||||
./services/misc/sdrplay.nix
|
||||
./services/misc/serviio.nix
|
||||
@@ -807,7 +801,6 @@
|
||||
./services/network-filesystems/yandex-disk.nix
|
||||
./services/networking/3proxy.nix
|
||||
./services/networking/adguardhome.nix
|
||||
./services/networking/alice-lg.nix
|
||||
./services/networking/amuled.nix
|
||||
./services/networking/antennas.nix
|
||||
./services/networking/aria2.nix
|
||||
@@ -822,7 +815,6 @@
|
||||
./services/networking/bind.nix
|
||||
./services/networking/bird-lg.nix
|
||||
./services/networking/bird.nix
|
||||
./services/networking/birdwatcher.nix
|
||||
./services/networking/bitcoind.nix
|
||||
./services/networking/bitlbee.nix
|
||||
./services/networking/blockbook-frontend.nix
|
||||
@@ -881,7 +873,6 @@
|
||||
./services/networking/gobgpd.nix
|
||||
./services/networking/gvpe.nix
|
||||
./services/networking/hans.nix
|
||||
./services/networking/harmonia.nix
|
||||
./services/networking/haproxy.nix
|
||||
./services/networking/headscale.nix
|
||||
./services/networking/hostapd.nix
|
||||
@@ -1182,7 +1173,6 @@
|
||||
./services/web-apps/gerrit.nix
|
||||
./services/web-apps/gotify-server.nix
|
||||
./services/web-apps/grocy.nix
|
||||
./services/web-apps/pixelfed.nix
|
||||
./services/web-apps/healthchecks.nix
|
||||
./services/web-apps/hedgedoc.nix
|
||||
./services/web-apps/hledger-web.nix
|
||||
@@ -1199,7 +1189,6 @@
|
||||
./services/web-apps/komga.nix
|
||||
./services/web-apps/lemmy.nix
|
||||
./services/web-apps/limesurvey.nix
|
||||
./services/web-apps/mainsail.nix
|
||||
./services/web-apps/mastodon.nix
|
||||
./services/web-apps/matomo.nix
|
||||
./services/web-apps/mattermost.nix
|
||||
@@ -1378,7 +1367,6 @@
|
||||
./tasks/filesystems/cifs.nix
|
||||
./tasks/filesystems/ecryptfs.nix
|
||||
./tasks/filesystems/envfs.nix
|
||||
./tasks/filesystems/erofs.nix
|
||||
./tasks/filesystems/exfat.nix
|
||||
./tasks/filesystems/ext.nix
|
||||
./tasks/filesystems/f2fs.nix
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
cfg = config.programs.darling;
|
||||
in {
|
||||
options = {
|
||||
programs.darling = {
|
||||
enable = lib.mkEnableOption (lib.mdDoc "Darling, a Darwin/macOS compatibility layer for Linux");
|
||||
package = lib.mkPackageOptionMD pkgs "darling" {};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
security.wrappers.darling = {
|
||||
source = lib.getExe cfg.package;
|
||||
owner = "root";
|
||||
group = "root";
|
||||
setuid = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -26,7 +26,7 @@ in
|
||||
source ${pkgs.fzf}/share/fzf/key-bindings.zsh
|
||||
'');
|
||||
|
||||
programs.zsh.ohMyZsh.plugins = lib.mkIf (cfg.keybindings || cfg.fuzzyCompletion) [ "fzf" ];
|
||||
programs.zsh.ohMyZsh.plugins = optional (cfg.keybindings || cfg.fuzzyCompletion) [ "fzf" ];
|
||||
};
|
||||
meta.maintainers = with maintainers; [ laalsaas ];
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ in {
|
||||
Miriway, a Mir based Wayland compositor. You can manually launch Miriway by
|
||||
executing "exec miriway" on a TTY, or launch it from a display manager. Copy
|
||||
/etc/xdg/xdg-miriway/miriway-shell.config to ~/.config/miriway-shell.config
|
||||
to modify the system-wide configuration on a per-user basis. See <https://github.com/Miriway/Miriway>,
|
||||
to modify the default configuration. See <https://github.com/Miriway/Miriway>,
|
||||
and "miriway --help" for more information'');
|
||||
|
||||
config = lib.mkOption {
|
||||
@@ -19,15 +19,6 @@ in {
|
||||
ctrl-alt=t:miriway-terminal # Default "terminal emulator finder"
|
||||
|
||||
shell-component=dbus-update-activation-environment --systemd DISPLAY WAYLAND_DISPLAY
|
||||
|
||||
meta=Left:@dock-left
|
||||
meta=Right:@dock-right
|
||||
meta=Space:@toggle-maximized
|
||||
meta=Home:@workspace-begin
|
||||
meta=End:@workspace-end
|
||||
meta=Page_Up:@workspace-up
|
||||
meta=Page_Down:@workspace-down
|
||||
ctrl-alt=BackSpace:@exit
|
||||
'';
|
||||
example = ''
|
||||
idle-timeout=300
|
||||
@@ -40,15 +31,6 @@ in {
|
||||
shell-component=wbg Pictures/wallpaper
|
||||
|
||||
shell-meta=a:synapse
|
||||
|
||||
meta=Left:@dock-left
|
||||
meta=Right:@dock-right
|
||||
meta=Space:@toggle-maximized
|
||||
meta=Home:@workspace-begin
|
||||
meta=End:@workspace-end
|
||||
meta=Page_Up:@workspace-up
|
||||
meta=Page_Down:@workspace-down
|
||||
ctrl-alt=BackSpace:@exit
|
||||
'';
|
||||
description = lib.mdDoc ''
|
||||
Miriway's config. This will be installed system-wide.
|
||||
|
||||
@@ -138,8 +138,7 @@ in
|
||||
};
|
||||
|
||||
source = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.path;
|
||||
type = types.path;
|
||||
description = lib.mdDoc "Path of the source file.";
|
||||
};
|
||||
|
||||
@@ -161,11 +160,9 @@ in
|
||||
environment.etc = listToAttrs (attrValues (mapAttrs
|
||||
(name: value: {
|
||||
name = "xdg/nvim/${name}";
|
||||
value = removeAttrs
|
||||
(value // {
|
||||
target = "xdg/nvim/${value.target}";
|
||||
})
|
||||
(optionals (isNull value.source) [ "source" ]);
|
||||
value = value // {
|
||||
target = "xdg/nvim/${value.target}";
|
||||
};
|
||||
})
|
||||
cfg.runtime));
|
||||
|
||||
|
||||
@@ -41,8 +41,6 @@ let
|
||||
# This should be made configurable.
|
||||
#CHFN_RESTRICT frwh
|
||||
|
||||
# The default crypt() method, keep in sync with the PAM default
|
||||
ENCRYPT_METHOD YESCRYPT
|
||||
'';
|
||||
|
||||
mkSetuidRoot = source:
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
cfg = config.programs.sniffnet;
|
||||
in
|
||||
|
||||
{
|
||||
options = {
|
||||
programs.sniffnet = {
|
||||
enable = lib.mkEnableOption (lib.mdDoc "sniffnet");
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
security.wrappers.sniffnet = {
|
||||
owner = "root";
|
||||
group = "root";
|
||||
capabilities = "cap_net_raw,cap_net_admin=eip";
|
||||
source = "${pkgs.sniffnet}/bin/sniffnet";
|
||||
};
|
||||
};
|
||||
|
||||
meta.maintainers = with lib.maintainers; [ figsoda ];
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
{ lib, config, pkgs, ... }:
|
||||
|
||||
let
|
||||
cfg = config.programs.trippy;
|
||||
in
|
||||
|
||||
{
|
||||
options = {
|
||||
programs.trippy = {
|
||||
enable = lib.mkEnableOption (lib.mdDoc "trippy");
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
security.wrappers.trip = {
|
||||
owner = "root";
|
||||
group = "root";
|
||||
capabilities = "cap_net_raw+p";
|
||||
source = lib.getExe pkgs.trippy;
|
||||
};
|
||||
};
|
||||
|
||||
meta.maintainers = with lib.maintainers; [ figsoda ];
|
||||
}
|
||||
@@ -323,7 +323,7 @@ let
|
||||
}
|
||||
fi
|
||||
'');
|
||||
} // optionalAttrs (data.listenHTTP != null && toInt (last (splitString ":" data.listenHTTP)) < 1024) {
|
||||
} // optionalAttrs (data.listenHTTP != null && toInt (elemAt (splitString ":" data.listenHTTP) 1) < 1024) {
|
||||
CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ];
|
||||
AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ];
|
||||
};
|
||||
|
||||
@@ -22,7 +22,7 @@ in
|
||||
# some may even be completely useless.
|
||||
config.security.apparmor.includes = {
|
||||
# This one is included by <tunables/global>
|
||||
# which is usually included before any profile.
|
||||
# which is usualy included before any profile.
|
||||
"abstractions/tunables/alias" = ''
|
||||
alias /bin -> /run/current-system/sw/bin,
|
||||
alias /lib/modules -> /run/current-system/kernel/lib/modules,
|
||||
|
||||
@@ -446,15 +446,6 @@ let
|
||||
};
|
||||
};
|
||||
|
||||
zfs = mkOption {
|
||||
default = config.security.pam.zfs.enable;
|
||||
defaultText = literalExpression "config.security.pam.zfs.enable";
|
||||
type = types.bool;
|
||||
description = lib.mdDoc ''
|
||||
Enable unlocking and mounting of encrypted ZFS home dataset at login.
|
||||
'';
|
||||
};
|
||||
|
||||
text = mkOption {
|
||||
type = types.nullOr types.lines;
|
||||
description = lib.mdDoc "Contents of the PAM service file.";
|
||||
@@ -565,8 +556,7 @@ let
|
||||
|| cfg.googleAuthenticator.enable
|
||||
|| cfg.gnupg.enable
|
||||
|| cfg.failDelay.enable
|
||||
|| cfg.duoSecurity.enable
|
||||
|| cfg.zfs))
|
||||
|| cfg.duoSecurity.enable))
|
||||
(
|
||||
optionalString config.services.homed.enable ''
|
||||
auth optional ${config.systemd.package}/lib/security/pam_systemd_home.so
|
||||
@@ -580,9 +570,6 @@ let
|
||||
optionalString config.security.pam.enableFscrypt ''
|
||||
auth optional ${pkgs.fscrypt-experimental}/lib/security/pam_fscrypt.so
|
||||
'' +
|
||||
optionalString cfg.zfs ''
|
||||
auth optional ${config.boot.zfs.package}/lib/security/pam_zfs_key.so homes=${config.security.pam.zfs.homes}
|
||||
'' +
|
||||
optionalString cfg.pamMount ''
|
||||
auth optional ${pkgs.pam_mount}/lib/security/pam_mount.so disable_interactive
|
||||
'' +
|
||||
@@ -641,9 +628,6 @@ let
|
||||
optionalString config.security.pam.enableFscrypt ''
|
||||
password optional ${pkgs.fscrypt-experimental}/lib/security/pam_fscrypt.so
|
||||
'' +
|
||||
optionalString cfg.zfs ''
|
||||
password optional ${config.boot.zfs.package}/lib/security/pam_zfs_key.so homes=${config.security.pam.zfs.homes}
|
||||
'' +
|
||||
optionalString cfg.pamMount ''
|
||||
password optional ${pkgs.pam_mount}/lib/security/pam_mount.so
|
||||
'' +
|
||||
@@ -654,7 +638,7 @@ let
|
||||
password sufficient ${pkgs.pam_mysql}/lib/security/pam_mysql.so config_file=/etc/security/pam_mysql.conf
|
||||
'' +
|
||||
optionalString config.services.sssd.enable ''
|
||||
password sufficient ${pkgs.sssd}/lib/security/pam_sss.so
|
||||
password sufficient ${pkgs.sssd}/lib/security/pam_sss.so use_authtok
|
||||
'' +
|
||||
optionalString config.security.pam.krb5.enable ''
|
||||
password sufficient ${pam_krb5}/lib/security/pam_krb5.so use_first_pass
|
||||
@@ -701,10 +685,6 @@ let
|
||||
session [success=1 default=ignore] pam_succeed_if.so service = systemd-user
|
||||
session optional ${pkgs.fscrypt-experimental}/lib/security/pam_fscrypt.so
|
||||
'' +
|
||||
optionalString cfg.zfs ''
|
||||
session [success=1 default=ignore] pam_succeed_if.so service = systemd-user
|
||||
session optional ${config.boot.zfs.package}/lib/security/pam_zfs_key.so homes=${config.security.pam.zfs.homes} ${optionalString config.security.pam.zfs.noUnmount "nounmount"}
|
||||
'' +
|
||||
optionalString cfg.pamMount ''
|
||||
session optional ${pkgs.pam_mount}/lib/security/pam_mount.so disable_interactive
|
||||
'' +
|
||||
@@ -1222,34 +1202,6 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
security.pam.zfs = {
|
||||
enable = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = lib.mdDoc ''
|
||||
Enable unlocking and mounting of encrypted ZFS home dataset at login.
|
||||
'';
|
||||
};
|
||||
|
||||
homes = mkOption {
|
||||
example = "rpool/home";
|
||||
default = "rpool/home";
|
||||
type = types.str;
|
||||
description = lib.mdDoc ''
|
||||
Prefix of home datasets. This value will be concatenated with
|
||||
`"/" + <username>` in order to determine the home dataset to unlock.
|
||||
'';
|
||||
};
|
||||
|
||||
noUnmount = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = lib.mdDoc ''
|
||||
Do not unmount home dataset on logout.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
security.pam.enableEcryptfs = mkEnableOption (lib.mdDoc "eCryptfs PAM module (mounting ecryptfs home directory on login)");
|
||||
security.pam.enableFscrypt = mkEnableOption (lib.mdDoc ''
|
||||
Enables fscrypt to automatically unlock directories with the user's login password.
|
||||
@@ -1286,12 +1238,6 @@ in
|
||||
Only one of users.motd and users.motdFile can be set.
|
||||
'';
|
||||
}
|
||||
{
|
||||
assertion = config.security.pam.zfs.enable -> (config.boot.zfs.enabled || config.boot.zfs.enableUnstable);
|
||||
message = ''
|
||||
`security.pam.zfs.enable` requires enabling ZFS (`boot.zfs.enabled` or `boot.zfs.enableUnstable`).
|
||||
'';
|
||||
}
|
||||
];
|
||||
|
||||
environment.systemPackages =
|
||||
@@ -1432,10 +1378,7 @@ in
|
||||
mr ${pkgs.plasma5Packages.kwallet-pam}/lib/security/pam_kwallet5.so,
|
||||
'' +
|
||||
optionalString config.virtualisation.lxc.lxcfs.enable ''
|
||||
mr ${pkgs.lxc}/lib/security/pam_cgfs.so,
|
||||
'' +
|
||||
optionalString (isEnabled (cfg: cfg.zfs)) ''
|
||||
mr ${config.boot.zfs.package}/lib/security/pam_zfs_key.so,
|
||||
mr ${pkgs.lxc}/lib/security/pam_cgfs.so
|
||||
'' +
|
||||
optionalString config.services.homed.enable ''
|
||||
mr ${config.systemd.package}/lib/security/pam_systemd_home.so
|
||||
|
||||
@@ -3,7 +3,7 @@ let
|
||||
cfg = config.security.tpm2;
|
||||
|
||||
# This snippet is taken from tpm2-tss/dist/tpm-udev.rules, but modified to allow custom user/groups
|
||||
# The idea is that the tssUser is allowed to access the TPM and kernel TPM resource manager, while
|
||||
# The idea is that the tssUser is allowed to acess the TPM and kernel TPM resource manager, while
|
||||
# the tssGroup is only allowed to access the kernel resource manager
|
||||
# Therefore, if either of the two are null, the respective part isn't generated
|
||||
udevRules = tssUser: tssGroup: ''
|
||||
|
||||
@@ -283,7 +283,7 @@ in
|
||||
'';
|
||||
|
||||
###### wrappers consistency checks
|
||||
system.checks = lib.singleton (pkgs.runCommandLocal
|
||||
system.extraDependencies = lib.singleton (pkgs.runCommandLocal
|
||||
"ensure-all-wrappers-paths-exist" { }
|
||||
''
|
||||
# make sure we produce output
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.gonic;
|
||||
settingsFormat = pkgs.formats.keyValue {
|
||||
mkKeyValue = lib.generators.mkKeyValueDefault { } " ";
|
||||
listsAsDuplicateKeys = true;
|
||||
};
|
||||
in
|
||||
{
|
||||
options = {
|
||||
services.gonic = {
|
||||
|
||||
enable = mkEnableOption (lib.mdDoc "Gonic music server");
|
||||
|
||||
settings = mkOption rec {
|
||||
type = settingsFormat.type;
|
||||
apply = recursiveUpdate default;
|
||||
default = {
|
||||
listen-addr = "127.0.0.1:4747";
|
||||
cache-path = "/var/cache/gonic";
|
||||
tls-cert = null;
|
||||
tls-key = null;
|
||||
};
|
||||
example = {
|
||||
music-path = [ "/mnt/music" ];
|
||||
podcast-path = "/mnt/podcasts";
|
||||
};
|
||||
description = lib.mdDoc ''
|
||||
Configuration for Gonic, see <https://github.com/sentriz/gonic#configuration-options> for supported values.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
systemd.services.gonic = {
|
||||
description = "Gonic Media Server";
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
ExecStart =
|
||||
let
|
||||
# these values are null by default but should not appear in the final config
|
||||
filteredSettings = filterAttrs (n: v: !((n == "tls-cert" || n == "tls-key") && v == null)) cfg.settings;
|
||||
in
|
||||
"${pkgs.gonic}/bin/gonic -config-path ${settingsFormat.generate "gonic" filteredSettings}";
|
||||
DynamicUser = true;
|
||||
StateDirectory = "gonic";
|
||||
CacheDirectory = "gonic";
|
||||
WorkingDirectory = "/var/lib/gonic";
|
||||
RuntimeDirectory = "gonic";
|
||||
RootDirectory = "/run/gonic";
|
||||
ReadWritePaths = "";
|
||||
BindReadOnlyPaths = [
|
||||
# gonic can access scrobbling services
|
||||
"-/etc/ssl/certs/ca-certificates.crt"
|
||||
builtins.storeDir
|
||||
cfg.settings.podcast-path
|
||||
] ++ cfg.settings.music-path
|
||||
++ lib.optional (cfg.settings.tls-cert != null) cfg.settings.tls-cert
|
||||
++ lib.optional (cfg.settings.tls-key != null) cfg.settings.tls-key;
|
||||
CapabilityBoundingSet = "";
|
||||
RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ];
|
||||
RestrictNamespaces = true;
|
||||
PrivateDevices = true;
|
||||
PrivateUsers = true;
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHome = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
SystemCallArchitectures = "native";
|
||||
SystemCallFilter = [ "@system-service" "~@privileged" ];
|
||||
RestrictRealtime = true;
|
||||
LockPersonality = true;
|
||||
MemoryDenyWriteExecute = true;
|
||||
UMask = "0066";
|
||||
ProtectHostname = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
meta.maintainers = [ maintainers.autrimpo ];
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
let
|
||||
|
||||
inherit (lib) concatMapStringsSep concatStringsSep isInt isList literalExpression;
|
||||
inherit (lib) mapAttrs mapAttrsToList mkDefault mkEnableOption mkIf mkOption mkRenamedOptionModule optional types;
|
||||
inherit (lib) mapAttrs mapAttrsToList mkDefault mkEnableOption mkIf mkOption optional types;
|
||||
|
||||
cfg = config.services.automysqlbackup;
|
||||
pkg = pkgs.automysqlbackup;
|
||||
@@ -26,10 +26,6 @@ let
|
||||
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
(mkRenamedOptionModule [ "services" "automysqlbackup" "config" ] [ "services" "automysqlbackup" "settings" ])
|
||||
];
|
||||
|
||||
# interface
|
||||
options = {
|
||||
services.automysqlbackup = {
|
||||
@@ -44,7 +40,7 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
config = mkOption {
|
||||
type = with types; attrsOf (oneOf [ str int bool (listOf str) ]);
|
||||
default = {};
|
||||
description = lib.mdDoc ''
|
||||
@@ -116,18 +112,7 @@ in
|
||||
|
||||
services.mysql.ensureUsers = optional (config.services.mysql.enable && cfg.config.mysql_dump_host == "localhost") {
|
||||
name = user;
|
||||
ensurePermissions = {
|
||||
"*.*" = "SELECT, SHOW VIEW, TRIGGER, LOCK TABLES, EVENT";
|
||||
|
||||
# https://forums.mysql.com/read.php?10,668311,668315#msg-668315
|
||||
"function sys.extract_table_from_file_name" = "execute";
|
||||
"function sys.format_path" = "execute";
|
||||
"function sys.format_statement" = "execute";
|
||||
"function sys.extract_schema_from_file_name" = "execute";
|
||||
"function sys.ps_thread_account" = "execute";
|
||||
"function sys.format_time" = "execute";
|
||||
"function sys.format_bytes" = "execute";
|
||||
};
|
||||
ensurePermissions = { "*.*" = "SELECT, SHOW VIEW, TRIGGER, LOCK TABLES, EVENT"; };
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
@@ -109,7 +109,7 @@ let
|
||||
};
|
||||
environment = {
|
||||
BORG_REPO = cfg.repo;
|
||||
inherit (cfg) extraArgs extraInitArgs extraCreateArgs extraPruneArgs extraCompactArgs;
|
||||
inherit (cfg) extraArgs extraInitArgs extraCreateArgs extraPruneArgs;
|
||||
} // (mkPassEnv cfg) // cfg.environment;
|
||||
};
|
||||
|
||||
|
||||
@@ -145,7 +145,6 @@ in
|
||||
type = types.attrsOf unitOption;
|
||||
default = {
|
||||
OnCalendar = "daily";
|
||||
Persistent = true;
|
||||
};
|
||||
description = lib.mdDoc ''
|
||||
When to run the backup. See {manpage}`systemd.timer(5)` for details.
|
||||
@@ -153,7 +152,6 @@ in
|
||||
example = {
|
||||
OnCalendar = "00:05";
|
||||
RandomizedDelaySec = "5h";
|
||||
Persistent = true;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -1,237 +0,0 @@
|
||||
{ config
|
||||
, lib
|
||||
, pkgs
|
||||
, utils
|
||||
, ...
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib)
|
||||
any
|
||||
attrValues
|
||||
concatStringsSep
|
||||
escapeShellArg
|
||||
hasInfix
|
||||
hasSuffix
|
||||
optionalAttrs
|
||||
optionals
|
||||
literalExpression
|
||||
mapAttrs'
|
||||
mkEnableOption
|
||||
mkOption
|
||||
mkPackageOptionMD
|
||||
mkIf
|
||||
nameValuePair
|
||||
types
|
||||
;
|
||||
|
||||
inherit (utils)
|
||||
escapeSystemdPath
|
||||
;
|
||||
|
||||
cfg = config.services.gitea-actions-runner;
|
||||
|
||||
# Check whether any runner instance label requires a container runtime
|
||||
# Empty label strings result in the upstream defined defaultLabels, which require docker
|
||||
# https://gitea.com/gitea/act_runner/src/tag/v0.1.5/internal/app/cmd/register.go#L93-L98
|
||||
hasDockerScheme = instance:
|
||||
instance.labels == [] || any (label: hasInfix ":docker:" label) instance.labels;
|
||||
wantsContainerRuntime = any hasDockerScheme (attrValues cfg.instances);
|
||||
|
||||
hasHostScheme = instance: any (label: hasSuffix ":host" label) instance.labels;
|
||||
|
||||
# provide shorthands for whether container runtimes are enabled
|
||||
hasDocker = config.virtualisation.docker.enable;
|
||||
hasPodman = config.virtualisation.podman.enable;
|
||||
|
||||
tokenXorTokenFile = instance:
|
||||
(instance.token == null && instance.tokenFile != null) ||
|
||||
(instance.token != null && instance.tokenFile == null);
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [
|
||||
hexa
|
||||
];
|
||||
|
||||
options.services.gitea-actions-runner = with types; {
|
||||
package = mkPackageOptionMD pkgs "gitea-actions-runner" { };
|
||||
|
||||
instances = mkOption {
|
||||
default = {};
|
||||
description = lib.mdDoc ''
|
||||
Gitea Actions Runner instances.
|
||||
'';
|
||||
type = attrsOf (submodule {
|
||||
options = {
|
||||
enable = mkEnableOption (lib.mdDoc "Gitea Actions Runner instance");
|
||||
|
||||
name = mkOption {
|
||||
type = str;
|
||||
example = literalExpression "config.networking.hostName";
|
||||
description = lib.mdDoc ''
|
||||
The name identifying the runner instance towards the Gitea/Forgejo instance.
|
||||
'';
|
||||
};
|
||||
|
||||
url = mkOption {
|
||||
type = str;
|
||||
example = "https://forge.example.com";
|
||||
description = lib.mdDoc ''
|
||||
Base URL of your Gitea/Forgejo instance.
|
||||
'';
|
||||
};
|
||||
|
||||
token = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
description = lib.mdDoc ''
|
||||
Plain token to register at the configured Gitea/Forgejo instance.
|
||||
'';
|
||||
};
|
||||
|
||||
tokenFile = mkOption {
|
||||
type = nullOr (either str path);
|
||||
default = null;
|
||||
description = lib.mdDoc ''
|
||||
Path to an environment file, containing the `TOKEN` environment
|
||||
variable, that holds a token to register at the configured
|
||||
Gitea/Forgejo instance.
|
||||
'';
|
||||
};
|
||||
|
||||
labels = mkOption {
|
||||
type = listOf str;
|
||||
example = literalExpression ''
|
||||
[
|
||||
# provide a debian base with nodejs for actions
|
||||
"debian-latest:docker://node:18-bullseye"
|
||||
# fake the ubuntu name, because node provides no ubuntu builds
|
||||
"ubuntu-latest:docker://node:18-bullseye"
|
||||
# provide native execution on the host
|
||||
#"native:host"
|
||||
]
|
||||
'';
|
||||
description = lib.mdDoc ''
|
||||
Labels used to map jobs to their runtime environment. Changing these
|
||||
labels currently requires a new registration token.
|
||||
|
||||
Many common actions require bash, git and nodejs, as well as a filesystem
|
||||
that follows the filesystem hierarchy standard.
|
||||
'';
|
||||
};
|
||||
|
||||
hostPackages = mkOption {
|
||||
type = listOf package;
|
||||
default = with pkgs; [
|
||||
bash
|
||||
coreutils
|
||||
curl
|
||||
gawk
|
||||
gitMinimal
|
||||
gnused
|
||||
nodejs
|
||||
wget
|
||||
];
|
||||
defaultText = literalExpression ''
|
||||
with pkgs; [
|
||||
bash
|
||||
coreutils
|
||||
curl
|
||||
gawk
|
||||
gitMinimal
|
||||
gnused
|
||||
nodejs
|
||||
wget
|
||||
]
|
||||
'';
|
||||
description = lib.mdDoc ''
|
||||
List of packages, that are available to actions, when the runner is configured
|
||||
with a host execution label.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf (cfg.instances != {}) {
|
||||
assertions = [ {
|
||||
assertion = any tokenXorTokenFile (attrValues cfg.instances);
|
||||
message = "Instances of gitea-actions-runner can have `token` or `tokenFile`, not both.";
|
||||
} {
|
||||
assertion = wantsContainerRuntime -> hasDocker || hasPodman;
|
||||
message = "Label configuration on gitea-actions-runner instance requires either docker or podman.";
|
||||
} ];
|
||||
|
||||
systemd.services = let
|
||||
mkRunnerService = name: instance: let
|
||||
wantsContainerRuntime = hasDockerScheme instance;
|
||||
wantsHost = hasHostScheme instance;
|
||||
wantsDocker = wantsContainerRuntime && config.virtualisation.docker.enable;
|
||||
wantsPodman = wantsContainerRuntime && config.virtualisation.podman.enable;
|
||||
in
|
||||
nameValuePair "gitea-runner-${escapeSystemdPath name}" {
|
||||
inherit (instance) enable;
|
||||
description = "Gitea Actions Runner";
|
||||
after = [
|
||||
"network-online.target"
|
||||
] ++ optionals (wantsDocker) [
|
||||
"docker.service"
|
||||
] ++ optionals (wantsPodman) [
|
||||
"podman.service"
|
||||
];
|
||||
wantedBy = [
|
||||
"multi-user.target"
|
||||
];
|
||||
environment = optionalAttrs (instance.token != null) {
|
||||
TOKEN = "${instance.token}";
|
||||
} // optionalAttrs (wantsPodman) {
|
||||
DOCKER_HOST = "unix:///run/podman/podman.sock";
|
||||
};
|
||||
path = with pkgs; [
|
||||
coreutils
|
||||
] ++ lib.optionals wantsHost instance.hostPackages;
|
||||
serviceConfig = {
|
||||
DynamicUser = true;
|
||||
User = "gitea-runner";
|
||||
StateDirectory = "gitea-runner";
|
||||
WorkingDirectory = "-/var/lib/gitea-runner/${name}";
|
||||
ExecStartPre = pkgs.writeShellScript "gitea-register-runner-${name}" ''
|
||||
export INSTANCE_DIR="$STATE_DIRECTORY/${name}"
|
||||
mkdir -vp "$INSTANCE_DIR"
|
||||
cd "$INSTANCE_DIR"
|
||||
|
||||
# force reregistration on changed labels
|
||||
export LABELS_FILE="$INSTANCE_DIR/.labels"
|
||||
export LABELS_WANTED="$(echo ${escapeShellArg (concatStringsSep "\n" instance.labels)} | sort)"
|
||||
export LABELS_CURRENT="$(cat $LABELS_FILE 2>/dev/null || echo 0)"
|
||||
|
||||
if [ ! -e "$INSTANCE_DIR/.runner" ] || [ "$LABELS_WANTED" != "$LABELS_CURRENT" ]; then
|
||||
# remove existing registration file, so that changing the labels forces a re-registation
|
||||
rm -v "$INSTANCE_DIR/.runner" || true
|
||||
|
||||
# perform the registration
|
||||
${cfg.package}/bin/act_runner register --no-interactive \
|
||||
--instance ${escapeShellArg instance.url} \
|
||||
--token "$TOKEN" \
|
||||
--name ${escapeShellArg instance.name} \
|
||||
--labels ${escapeShellArg (concatStringsSep "," instance.labels)}
|
||||
|
||||
# and write back the configured labels
|
||||
echo "$LABELS_WANTED" > "$LABELS_FILE"
|
||||
fi
|
||||
|
||||
'';
|
||||
ExecStart = "${cfg.package}/bin/act_runner daemon";
|
||||
SupplementaryGroups = optionals (wantsDocker) [
|
||||
"docker"
|
||||
] ++ optionals (wantsPodman) [
|
||||
"podman"
|
||||
];
|
||||
} // optionalAttrs (instance.tokenFile != null) {
|
||||
EnvironmentFile = instance.tokenFile;
|
||||
};
|
||||
};
|
||||
in mapAttrs' mkRunnerService cfg.instances;
|
||||
};
|
||||
}
|
||||
@@ -489,7 +489,7 @@ in
|
||||
"/share/postgresql"
|
||||
];
|
||||
|
||||
system.checks = lib.optional (cfg.checkConfig && pkgs.stdenv.hostPlatform == pkgs.stdenv.buildPlatform) configFileCheck;
|
||||
system.extraDependencies = lib.optional (cfg.checkConfig && pkgs.stdenv.hostPlatform == pkgs.stdenv.buildPlatform) configFileCheck;
|
||||
|
||||
systemd.services.postgresql =
|
||||
{ description = "PostgreSQL Server";
|
||||
|
||||
@@ -245,7 +245,7 @@ in
|
||||
|
||||
rm -f www
|
||||
${optionalString cfg.web-ui.enable ''
|
||||
ln -s ${cfg.web-ui.package}/ www
|
||||
ln -s ${cfg.web-ui.package}/lib/dist www
|
||||
''}
|
||||
'';
|
||||
};
|
||||
|
||||
@@ -76,9 +76,7 @@ in
|
||||
ExecStart = "${pkgs.keyd}/bin/keyd";
|
||||
Restart = "always";
|
||||
|
||||
# TODO investigate why it doesn't work propeprly with DynamicUser
|
||||
# See issue: https://github.com/NixOS/nixpkgs/issues/226346
|
||||
# DynamicUser = true;
|
||||
DynamicUser = true;
|
||||
SupplementaryGroups = [
|
||||
config.users.groups.input.name
|
||||
config.users.groups.uinput.name
|
||||
@@ -98,7 +96,6 @@ in
|
||||
ProtectHostname = true;
|
||||
PrivateUsers = true;
|
||||
PrivateMounts = true;
|
||||
PrivateTmp = true;
|
||||
RestrictNamespaces = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
@@ -107,18 +104,7 @@ in
|
||||
MemoryDenyWriteExecute = true;
|
||||
RestrictRealtime = true;
|
||||
LockPersonality = true;
|
||||
ProtectProc = "invisible";
|
||||
SystemCallFilter = [
|
||||
"@system-service"
|
||||
"~@privileged"
|
||||
"~@resources"
|
||||
];
|
||||
RestrictAddressFamilies = [ "AF_UNIX" ];
|
||||
RestrictSUIDSGID = true;
|
||||
IPAddressDeny = [ "any" ];
|
||||
NoNewPrivileges = true;
|
||||
ProtectSystem = "strict";
|
||||
ProcSubset = "pid";
|
||||
ProtectProc = "noaccess";
|
||||
UMask = "0077";
|
||||
};
|
||||
};
|
||||
|
||||
@@ -37,8 +37,8 @@ in
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = if versionOlder config.system.stateVersion "23.05" then pkgs.graylog-3_3 else pkgs.graylog-5_0;
|
||||
defaultText = literalExpression (if versionOlder config.system.stateVersion "23.05" then "pkgs.graylog-3_3" else "pkgs.graylog-5_0");
|
||||
default = pkgs.graylog;
|
||||
defaultText = literalExpression "pkgs.graylog";
|
||||
description = lib.mdDoc "Graylog package to use.";
|
||||
};
|
||||
|
||||
|
||||
@@ -8,8 +8,6 @@ in
|
||||
options.services.vector = {
|
||||
enable = mkEnableOption (lib.mdDoc "Vector");
|
||||
|
||||
package = mkPackageOptionMD pkgs "vector" { };
|
||||
|
||||
journaldAccess = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
@@ -49,7 +47,7 @@ in
|
||||
'';
|
||||
in
|
||||
{
|
||||
ExecStart = "${getExe cfg.package} --config ${validateConfig conf}";
|
||||
ExecStart = "${pkgs.vector}/bin/vector --config ${validateConfig conf}";
|
||||
DynamicUser = true;
|
||||
Restart = "no";
|
||||
StateDirectory = "vector";
|
||||
|
||||
@@ -206,7 +206,7 @@ in {
|
||||
Server configuration, see
|
||||
[https://maddy.email](https://maddy.email) for
|
||||
more information. The default configuration of this module will setup
|
||||
minimal Maddy instance for mail transfer without TLS encryption.
|
||||
minimal maddy instance for mail transfer without TLS encryption.
|
||||
|
||||
::: {.note}
|
||||
This should not be used in a production environment.
|
||||
@@ -216,24 +216,13 @@ in {
|
||||
|
||||
tls = {
|
||||
loader = mkOption {
|
||||
type = with types; nullOr (enum [ "off" "file" "acme" ]);
|
||||
type = with types; nullOr (enum [ "file" "off" ]);
|
||||
default = "off";
|
||||
description = lib.mdDoc ''
|
||||
TLS certificates are obtained by modules called "certificate
|
||||
loaders".
|
||||
|
||||
The `file` loader module reads certificates from files specified by
|
||||
the `certificates` option.
|
||||
|
||||
Alternatively the `acme` module can be used to automatically obtain
|
||||
certificates using the ACME protocol.
|
||||
|
||||
Module configuration is done via the `tls.extraConfig` option.
|
||||
|
||||
Secrets such as API keys or passwords should not be supplied in
|
||||
plaintext. Instead the `secrets` option can be used to read secrets
|
||||
at runtime as environment variables. Secrets can be referenced with
|
||||
`{env:VAR}`.
|
||||
loaders". Currently only the file loader is supported which reads
|
||||
certificates from files specifying the options `keyPaths` and
|
||||
`certPaths`.
|
||||
'';
|
||||
};
|
||||
|
||||
@@ -272,13 +261,11 @@ in {
|
||||
extraConfig = mkOption {
|
||||
type = with types; nullOr lines;
|
||||
description = lib.mdDoc ''
|
||||
Arguments for the specified certificate loader.
|
||||
|
||||
In case the `tls` loader is set, the defaults are considered secure
|
||||
and there is no need to change anything in most cases.
|
||||
For available options see [upstream manual](https://maddy.email/reference/tls/).
|
||||
|
||||
For ACME configuration, see [following page](https://maddy.email/reference/tls-acme).
|
||||
Arguments for the specific certificate loader. Note that Maddy uses
|
||||
secure defaults for the TLS configuration so there is no need to
|
||||
change anything in most cases.
|
||||
See [upstream manual](https://maddy.email/reference/tls/) for
|
||||
available options.
|
||||
'';
|
||||
default = "";
|
||||
};
|
||||
@@ -334,41 +321,20 @@ in {
|
||||
});
|
||||
};
|
||||
|
||||
secrets = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
description = lib.mdDoc ''
|
||||
A file containing the various secrets. Should be in the format
|
||||
expected by systemd's `EnvironmentFile` directory. Secrets can be
|
||||
referenced in the format `{env:VAR}`.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
assertions = [
|
||||
{
|
||||
assertion = cfg.tls.loader == "file" -> cfg.tls.certificates != [];
|
||||
message = ''
|
||||
If Maddy is configured to use TLS, tls.certificates with attribute sets
|
||||
of certPath and keyPath must be provided.
|
||||
Read more about obtaining TLS certificates here:
|
||||
https://maddy.email/tutorials/setting-up/#tls-certificates
|
||||
'';
|
||||
}
|
||||
{
|
||||
assertion = cfg.tls.loader == "acme" -> cfg.tls.extraConfig != "";
|
||||
message = ''
|
||||
If Maddy is configured to obtain TLS certificates using the ACME
|
||||
loader, extra configuration options must be supplied via
|
||||
tls.extraConfig option.
|
||||
See upstream documentation for more details:
|
||||
https://maddy.email/reference/tls-acme
|
||||
'';
|
||||
}
|
||||
];
|
||||
assertions = [{
|
||||
assertion = cfg.tls.loader == "file" -> cfg.tls.certificates != [];
|
||||
message = ''
|
||||
If maddy is configured to use TLS, tls.certificates with attribute sets
|
||||
of certPath and keyPath must be provided.
|
||||
Read more about obtaining TLS certificates here:
|
||||
https://maddy.email/tutorials/setting-up/#tls-certificates
|
||||
'';
|
||||
}];
|
||||
|
||||
systemd = {
|
||||
|
||||
@@ -379,7 +345,6 @@ in {
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
StateDirectory = [ "maddy" ];
|
||||
EnvironmentFile = lib.mkIf (cfg.secrets != null) "${cfg.secrets}";
|
||||
};
|
||||
restartTriggers = [ config.environment.etc."maddy/maddy.conf".source ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
@@ -426,12 +391,6 @@ in {
|
||||
) cfg.tls.certificates)} ${optionalString (cfg.tls.extraConfig != "") ''
|
||||
{ ${cfg.tls.extraConfig} }
|
||||
''}
|
||||
'' else if (cfg.tls.loader == "acme") then ''
|
||||
tls {
|
||||
loader acme {
|
||||
${cfg.tls.extraConfig}
|
||||
}
|
||||
}
|
||||
'' else if (cfg.tls.loader == "off") then ''
|
||||
tls off
|
||||
'' else ""}
|
||||
|
||||
@@ -30,7 +30,7 @@ let
|
||||
|
||||
# these config files will be merged one after the other to build the final config
|
||||
configFiles = [
|
||||
"${pkgs.mjolnir}/libexec/mjolnir/deps/mjolnir/config/default.yaml"
|
||||
"${pkgs.mjolnir}/share/mjolnir/config/default.yaml"
|
||||
moduleConfigFile
|
||||
];
|
||||
|
||||
@@ -200,7 +200,7 @@ in
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = ''${pkgs.mjolnir}/bin/mjolnir --mjolnir-config ./config/default.yaml'';
|
||||
ExecStart = ''${pkgs.mjolnir}/bin/mjolnir'';
|
||||
ExecStartPre = [ generateConfig ];
|
||||
WorkingDirectory = cfg.dataPath;
|
||||
StateDirectory = "mjolnir";
|
||||
|
||||
@@ -167,11 +167,10 @@ in {
|
||||
ETCD_LISTEN_CLIENT_URLS = concatStringsSep "," cfg.listenClientUrls;
|
||||
ETCD_LISTEN_PEER_URLS = concatStringsSep "," cfg.listenPeerUrls;
|
||||
ETCD_INITIAL_ADVERTISE_PEER_URLS = concatStringsSep "," cfg.initialAdvertisePeerUrls;
|
||||
ETCD_PEER_CLIENT_CERT_AUTH = toString cfg.peerClientCertAuth;
|
||||
ETCD_PEER_TRUSTED_CA_FILE = cfg.peerTrustedCaFile;
|
||||
ETCD_PEER_CERT_FILE = cfg.peerCertFile;
|
||||
ETCD_PEER_KEY_FILE = cfg.peerKeyFile;
|
||||
ETCD_CLIENT_CERT_AUTH = toString cfg.clientCertAuth;
|
||||
ETCD_CLIENT_CERT_AUTH = toString cfg.peerClientCertAuth;
|
||||
ETCD_TRUSTED_CA_FILE = cfg.trustedCaFile;
|
||||
ETCD_CERT_FILE = cfg.certFile;
|
||||
ETCD_KEY_FILE = cfg.keyFile;
|
||||
|
||||
@@ -23,16 +23,6 @@ in
|
||||
description = lib.mdDoc "The Klipper package.";
|
||||
};
|
||||
|
||||
logFile = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
example = "/var/lib/klipper/klipper.log";
|
||||
description = lib.mdDoc ''
|
||||
Path of the file Klipper should log to.
|
||||
If `null`, it logs to stdout, which is not recommended by upstream.
|
||||
'';
|
||||
};
|
||||
|
||||
inputTTY = mkOption {
|
||||
type = types.path;
|
||||
default = "/run/klipper/tty";
|
||||
@@ -161,9 +151,7 @@ in
|
||||
systemd.services.klipper =
|
||||
let
|
||||
klippyArgs = "--input-tty=${cfg.inputTTY}"
|
||||
+ optionalString (cfg.apiSocket != null) " --api-server=${cfg.apiSocket}"
|
||||
+ optionalString (cfg.logFile != null) " --logfile=${cfg.logFile}"
|
||||
;
|
||||
+ optionalString (cfg.apiSocket != null) " --api-server=${cfg.apiSocket}";
|
||||
printerConfigPath =
|
||||
if cfg.mutableConfig
|
||||
then cfg.mutableConfigFolder + "/printer.cfg"
|
||||
@@ -189,7 +177,7 @@ in
|
||||
'';
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = "${cfg.package}/bin/klippy ${klippyArgs} ${printerConfigPath}";
|
||||
ExecStart = "${cfg.package}/lib/klipper/klippy.py ${klippyArgs} ${printerConfigPath}";
|
||||
RuntimeDirectory = "klipper";
|
||||
StateDirectory = "klipper";
|
||||
SupplementaryGroups = [ "dialout" ];
|
||||
|
||||
@@ -72,7 +72,7 @@ in {
|
||||
example = {
|
||||
authorization = {
|
||||
trusted_clients = [ "10.0.0.0/24" ];
|
||||
cors_domains = [ "https://app.fluidd.xyz" "https://my.mainsail.xyz" ];
|
||||
cors_domains = [ "https://app.fluidd.xyz" ];
|
||||
};
|
||||
};
|
||||
description = lib.mdDoc ''
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
cfg = config.services.rshim;
|
||||
|
||||
rshimCommand = [ "${cfg.package}/bin/rshim" ]
|
||||
++ lib.optionals (cfg.backend != null) [ "--backend ${cfg.backend}" ]
|
||||
++ lib.optionals (cfg.device != null) [ "--device ${cfg.device}" ]
|
||||
++ lib.optionals (cfg.index != null) [ "--index ${builtins.toString cfg.index}" ]
|
||||
++ [ "--log-level ${builtins.toString cfg.log-level}" ]
|
||||
;
|
||||
in
|
||||
{
|
||||
options.services.rshim = {
|
||||
enable = lib.mkEnableOption (lib.mdDoc "User-space rshim driver for the BlueField SoC");
|
||||
|
||||
package = lib.mkPackageOptionMD pkgs "rshim-user-space" { };
|
||||
|
||||
backend = lib.mkOption {
|
||||
type = with lib.types; nullOr (enum [ "usb" "pcie" "pcie_lf" ]);
|
||||
description = lib.mdDoc ''
|
||||
Specify the backend to attach. If not specified, the driver will scan
|
||||
all rshim backends unless the `device` option is given with a device
|
||||
name specified.
|
||||
'';
|
||||
default = null;
|
||||
example = "pcie";
|
||||
};
|
||||
|
||||
device = lib.mkOption {
|
||||
type = with lib.types; nullOr str;
|
||||
description = lib.mdDoc ''
|
||||
Specify the device name to attach. The backend driver can be deduced
|
||||
from the device name, thus the `backend` option is not needed.
|
||||
'';
|
||||
default = null;
|
||||
example = "pcie-04:00.2";
|
||||
};
|
||||
|
||||
index = lib.mkOption {
|
||||
type = with lib.types; nullOr int;
|
||||
description = lib.mdDoc ''
|
||||
Specify the index to create device path `/dev/rshim<index>`. It's also
|
||||
used to create network interface name `tmfifo_net<index>`. This option
|
||||
is needed when multiple rshim instances are running.
|
||||
'';
|
||||
default = null;
|
||||
example = 1;
|
||||
};
|
||||
|
||||
log-level = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
description = lib.mdDoc ''
|
||||
Specify the log level (0:none, 1:error, 2:warning, 3:notice, 4:debug).
|
||||
'';
|
||||
default = 2;
|
||||
example = 4;
|
||||
};
|
||||
|
||||
config = lib.mkOption {
|
||||
type = with lib.types; attrsOf (oneOf [ int str ]);
|
||||
description = lib.mdDoc ''
|
||||
Structural setting for the rshim configuration file
|
||||
(`/etc/rshim.conf`). It can be used to specify the static mapping
|
||||
between rshim devices and rshim names. It can also be used to ignore
|
||||
some rshim devices.
|
||||
'';
|
||||
default = { };
|
||||
example = {
|
||||
DISPLAY_LEVEL = 0;
|
||||
rshim0 = "usb-2-1.7";
|
||||
none = "usb-1-1.4";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
environment.etc = lib.mkIf (cfg.config != { }) {
|
||||
"rshim.conf".text = lib.generators.toKeyValue
|
||||
{ mkKeyValue = lib.generators.mkKeyValueDefault { } " "; }
|
||||
cfg.config;
|
||||
};
|
||||
|
||||
systemd.services.rshim = {
|
||||
after = [ "network.target" ];
|
||||
serviceConfig = {
|
||||
Restart = "always";
|
||||
Type = "forking";
|
||||
ExecStart = [
|
||||
(lib.concatStringsSep " \\\n" rshimCommand)
|
||||
];
|
||||
KillMode = "control-group";
|
||||
};
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
};
|
||||
};
|
||||
|
||||
meta.maintainers = with lib.maintainers; [ nikstur ];
|
||||
}
|
||||
@@ -4,81 +4,6 @@ with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.snapper;
|
||||
|
||||
mkValue = v:
|
||||
if isList v then "\"${concatMapStringsSep " " (escape [ "\\" " " ]) v}\""
|
||||
else if v == true then "yes"
|
||||
else if v == false then "no"
|
||||
else if isString v then "\"${v}\""
|
||||
else builtins.toJSON v;
|
||||
|
||||
mkKeyValue = k: v: "${k}=${mkValue v}";
|
||||
|
||||
# "it's recommended to always specify the filesystem type" -- man snapper-configs
|
||||
defaultOf = k: if k == "FSTYPE" then null else configOptions.${k}.default or null;
|
||||
|
||||
safeStr = types.strMatching "[^\n\"]*" // {
|
||||
description = "string without line breaks or quotes";
|
||||
descriptionClass = "conjunction";
|
||||
};
|
||||
|
||||
configOptions = {
|
||||
SUBVOLUME = mkOption {
|
||||
type = types.path;
|
||||
description = lib.mdDoc ''
|
||||
Path of the subvolume or mount point.
|
||||
This path is a subvolume and has to contain a subvolume named
|
||||
.snapshots.
|
||||
See also man:snapper(8) section PERMISSIONS.
|
||||
'';
|
||||
};
|
||||
|
||||
FSTYPE = mkOption {
|
||||
type = types.enum [ "btrfs" ];
|
||||
default = "btrfs";
|
||||
description = lib.mdDoc ''
|
||||
Filesystem type. Only btrfs is stable and tested.
|
||||
'';
|
||||
};
|
||||
|
||||
ALLOW_GROUPS = mkOption {
|
||||
type = types.listOf safeStr;
|
||||
default = [];
|
||||
description = lib.mdDoc ''
|
||||
List of groups allowed to operate with the config.
|
||||
|
||||
Also see the PERMISSIONS section in man:snapper(8).
|
||||
'';
|
||||
};
|
||||
|
||||
ALLOW_USERS = mkOption {
|
||||
type = types.listOf safeStr;
|
||||
default = [];
|
||||
example = [ "alice" ];
|
||||
description = lib.mdDoc ''
|
||||
List of users allowed to operate with the config. "root" is always
|
||||
implicitly included.
|
||||
|
||||
Also see the PERMISSIONS section in man:snapper(8).
|
||||
'';
|
||||
};
|
||||
|
||||
TIMELINE_CLEANUP = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = lib.mdDoc ''
|
||||
Defines whether the timeline cleanup algorithm should be run for the config.
|
||||
'';
|
||||
};
|
||||
|
||||
TIMELINE_CREATE = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = lib.mdDoc ''
|
||||
Defines whether hourly snapshots should be created.
|
||||
'';
|
||||
};
|
||||
};
|
||||
in
|
||||
|
||||
{
|
||||
@@ -127,23 +52,49 @@ in
|
||||
example = literalExpression ''
|
||||
{
|
||||
home = {
|
||||
SUBVOLUME = "/home";
|
||||
ALLOW_USERS = [ "alice" ];
|
||||
TIMELINE_CREATE = true;
|
||||
TIMELINE_CLEANUP = true;
|
||||
subvolume = "/home";
|
||||
extraConfig = '''
|
||||
ALLOW_USERS="alice"
|
||||
TIMELINE_CREATE=yes
|
||||
TIMELINE_CLEANUP=yes
|
||||
''';
|
||||
};
|
||||
}
|
||||
'';
|
||||
|
||||
description = lib.mdDoc ''
|
||||
Subvolume configuration. Any option mentioned in man:snapper-configs(5)
|
||||
is valid here, even if NixOS doesn't document it.
|
||||
Subvolume configuration
|
||||
'';
|
||||
|
||||
type = types.attrsOf (types.submodule {
|
||||
freeformType = types.attrsOf (types.oneOf [ (types.listOf safeStr) types.bool safeStr types.number ]);
|
||||
options = {
|
||||
subvolume = mkOption {
|
||||
type = types.path;
|
||||
description = lib.mdDoc ''
|
||||
Path of the subvolume or mount point.
|
||||
This path is a subvolume and has to contain a subvolume named
|
||||
.snapshots.
|
||||
See also man:snapper(8) section PERMISSIONS.
|
||||
'';
|
||||
};
|
||||
|
||||
options = configOptions;
|
||||
fstype = mkOption {
|
||||
type = types.enum [ "btrfs" ];
|
||||
default = "btrfs";
|
||||
description = lib.mdDoc ''
|
||||
Filesystem type. Only btrfs is stable and tested.
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = lib.mdDoc ''
|
||||
Additional configuration next to SUBVOLUME and FSTYPE.
|
||||
See man:snapper-configs(5).
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
};
|
||||
@@ -166,7 +117,11 @@ in
|
||||
|
||||
}
|
||||
// (mapAttrs' (name: subvolume: nameValuePair "snapper/configs/${name}" ({
|
||||
text = lib.generators.toKeyValue { inherit mkKeyValue; } (filterAttrs (k: v: v != defaultOf k) subvolume);
|
||||
text = ''
|
||||
${subvolume.extraConfig}
|
||||
FSTYPE="${subvolume.fstype}"
|
||||
SUBVOLUME="${subvolume.subvolume}"
|
||||
'';
|
||||
})) cfg.configs)
|
||||
// (lib.optionalAttrs (cfg.filters != null) {
|
||||
"snapper/filters/default.txt".text = cfg.filters;
|
||||
@@ -226,28 +181,5 @@ in
|
||||
unitConfig.ConditionPathExists = "/etc/snapper/configs/root";
|
||||
};
|
||||
|
||||
assertions =
|
||||
concatMap
|
||||
(name:
|
||||
let
|
||||
sub = cfg.configs.${name};
|
||||
in
|
||||
[ { assertion = !(sub ? extraConfig);
|
||||
message = ''
|
||||
The option definition `services.snapper.configs.${name}.extraConfig' no longer has any effect; please remove it.
|
||||
The contents of this option should be migrated to attributes on `services.snapper.configs.${name}'.
|
||||
'';
|
||||
}
|
||||
] ++
|
||||
map
|
||||
(attr: {
|
||||
assertion = !(hasAttr attr sub);
|
||||
message = ''
|
||||
The option definition `services.snapper.configs.${name}.${attr}' has been renamed to `services.snapper.configs.${name}.${toUpper attr}'.
|
||||
'';
|
||||
})
|
||||
[ "fstype" "subvolume" ]
|
||||
)
|
||||
(attrNames cfg.configs);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -169,20 +169,6 @@ in {
|
||||
See: <https://learn.netdata.cloud/docs/agent/anonymous-statistics>
|
||||
'';
|
||||
};
|
||||
|
||||
deadlineBeforeStopSec = mkOption {
|
||||
type = types.int;
|
||||
default = 120;
|
||||
description = lib.mdDoc ''
|
||||
In order to detect when netdata is misbehaving, we run a concurrent task pinging netdata (wait-for-netdata-up)
|
||||
in the systemd unit.
|
||||
|
||||
If after a while, this task does not succeed, we stop the unit and mark it as failed.
|
||||
|
||||
You can control this deadline in seconds with this option, it's useful to bump it
|
||||
if you have (1) a lot of data (2) doing upgrades (3) have low IOPS/throughput.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -219,7 +205,7 @@ in {
|
||||
while [ "$(${pkgs.netdata}/bin/netdatacli ping)" != pong ]; do sleep 0.5; done
|
||||
'';
|
||||
|
||||
TimeoutStopSec = cfg.deadlineBeforeStopSec;
|
||||
TimeoutStopSec = 60;
|
||||
Restart = "on-failure";
|
||||
# User and group
|
||||
User = cfg.user;
|
||||
|
||||
@@ -6,12 +6,10 @@ let
|
||||
cfg = config.services.prometheus.alertmanager;
|
||||
mkConfigFile = pkgs.writeText "alertmanager.yml" (builtins.toJSON cfg.configuration);
|
||||
|
||||
checkedConfig = file:
|
||||
if cfg.checkConfig then
|
||||
pkgs.runCommand "checked-config" { buildInputs = [ cfg.package ]; } ''
|
||||
ln -s ${file} $out
|
||||
amtool check-config $out
|
||||
'' else file;
|
||||
checkedConfig = file: pkgs.runCommand "checked-config" { buildInputs = [ cfg.package ]; } ''
|
||||
ln -s ${file} $out
|
||||
amtool check-config $out
|
||||
'';
|
||||
|
||||
alertmanagerYml = let
|
||||
yml = if cfg.configText != null then
|
||||
@@ -72,20 +70,6 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
checkConfig = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = lib.mdDoc ''
|
||||
Check configuration with `amtool check-config`. The call to `amtool` is
|
||||
subject to sandboxing by Nix.
|
||||
|
||||
If you use credentials stored in external files
|
||||
(`environmentFile`, etc),
|
||||
they will not be visible to `amtool`
|
||||
and it will report errors, despite a correct configuration.
|
||||
'';
|
||||
};
|
||||
|
||||
logFormat = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
|
||||
@@ -76,7 +76,7 @@ example:
|
||||
directory, which will be called postfix.nix and contains all exporter
|
||||
specific options and configuration:
|
||||
```
|
||||
# nixpkgs/nixos/modules/services/prometheus/exporters/postfix.nix
|
||||
# nixpgs/nixos/modules/services/prometheus/exporters/postfix.nix
|
||||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
@@ -43,8 +43,6 @@ in
|
||||
services.uptime-kuma.settings = {
|
||||
DATA_DIR = "/var/lib/uptime-kuma/";
|
||||
NODE_ENV = mkDefault "production";
|
||||
HOST = mkDefault "127.0.0.1";
|
||||
PORT = mkDefault "3001";
|
||||
};
|
||||
|
||||
systemd.services.uptime-kuma = {
|
||||
|
||||
@@ -28,12 +28,6 @@ in
|
||||
description = lib.mdDoc "Group to run under when setuid is not enabled.";
|
||||
};
|
||||
|
||||
debug = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = lib.mdDoc "Enable debug mode.";
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
type = format.type;
|
||||
default = { };
|
||||
@@ -117,7 +111,7 @@ in
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
ExecStart = "${pkgs.webdav-server-rs}/bin/webdav-server ${lib.optionalString cfg.debug "--debug"} -c ${cfg.configFile}";
|
||||
ExecStart = "${pkgs.webdav-server-rs}/bin/webdav-server -c ${cfg.configFile}";
|
||||
|
||||
CapabilityBoundingSet = [
|
||||
"CAP_SETUID"
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.alice-lg;
|
||||
settingsFormat = pkgs.formats.ini { };
|
||||
in
|
||||
{
|
||||
options = {
|
||||
services.alice-lg = {
|
||||
enable = mkEnableOption (lib.mdDoc "Alice Looking Glass");
|
||||
|
||||
package = mkPackageOptionMD pkgs "alice-lg" { };
|
||||
|
||||
settings = mkOption {
|
||||
type = settingsFormat.type;
|
||||
default = { };
|
||||
description = lib.mdDoc ''
|
||||
alice-lg configuration, for configuration options see the example on [github](https://github.com/alice-lg/alice-lg/blob/main/etc/alice-lg/alice.example.conf)
|
||||
'';
|
||||
example = literalExpression ''
|
||||
{
|
||||
server = {
|
||||
# configures the built-in webserver and provides global application settings
|
||||
listen_http = "127.0.0.1:7340";
|
||||
enable_prefix_lookup = true;
|
||||
asn = 9033;
|
||||
store_backend = postgres;
|
||||
routes_store_refresh_parallelism = 5;
|
||||
neighbors_store_refresh_parallelism = 10000;
|
||||
routes_store_refresh_interval = 5;
|
||||
neighbors_store_refresh_interval = 5;
|
||||
};
|
||||
postgres = {
|
||||
url = "postgres://postgres:postgres@localhost:5432/alice";
|
||||
min_connections = 2;
|
||||
max_connections = 128;
|
||||
};
|
||||
pagination = {
|
||||
routes_filtered_page_size = 250;
|
||||
routes_accepted_page_size = 250;
|
||||
routes_not_exported_page_size = 250;
|
||||
};
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
environment = {
|
||||
etc."alice-lg/alice.conf".source = settingsFormat.generate "alice-lg.conf" cfg.settings;
|
||||
};
|
||||
systemd.services = {
|
||||
alice-lg = {
|
||||
wants = [ "network.target" ];
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
description = "Alice Looking Glass";
|
||||
serviceConfig = {
|
||||
DynamicUser = true;
|
||||
Type = "simple";
|
||||
Restart = "on-failure";
|
||||
RestartSec = 15;
|
||||
ExecStart = "${cfg.package}/bin/alice-lg";
|
||||
StateDirectoryMode = "0700";
|
||||
UMask = "0007";
|
||||
CapabilityBoundingSet = "";
|
||||
NoNewPrivileges = true;
|
||||
ProtectSystem = "strict";
|
||||
PrivateTmp = true;
|
||||
PrivateDevices = true;
|
||||
PrivateUsers = true;
|
||||
ProtectHostname = true;
|
||||
ProtectClock = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectControlGroups = true;
|
||||
RestrictAddressFamilies = [ "AF_INET AF_INET6" ];
|
||||
LockPersonality = true;
|
||||
MemoryDenyWriteExecute = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true;
|
||||
PrivateMounts = true;
|
||||
SystemCallArchitectures = "native";
|
||||
SystemCallFilter = "~@clock @privileged @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @reboot @setuid @swap";
|
||||
BindReadOnlyPaths = [
|
||||
"-/etc/resolv.conf"
|
||||
"-/etc/nsswitch.conf"
|
||||
"-/etc/ssl/certs"
|
||||
"-/etc/static/ssl/certs"
|
||||
"-/etc/hosts"
|
||||
"-/etc/localtime"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,129 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.birdwatcher;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
services.birdwatcher = {
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.birdwatcher;
|
||||
defaultText = literalExpression "pkgs.birdwatcher";
|
||||
description = lib.mdDoc "The Birdwatcher package to use.";
|
||||
};
|
||||
enable = mkEnableOption (lib.mdDoc "Birdwatcher");
|
||||
flags = mkOption {
|
||||
default = [ ];
|
||||
type = types.listOf types.str;
|
||||
example = [ "-worker-pool-size 16" "-6" ];
|
||||
description = lib.mdDoc ''
|
||||
Flags to append to the program call
|
||||
'';
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
type = types.lines;
|
||||
default = { };
|
||||
description = lib.mdDoc ''
|
||||
birdwatcher configuration, for configuration options see the example on [github](https://github.com/alice-lg/birdwatcher/blob/master/etc/birdwatcher/birdwatcher.conf)
|
||||
'';
|
||||
example = literalExpression ''
|
||||
[server]
|
||||
allow_from = []
|
||||
allow_uncached = false
|
||||
modules_enabled = ["status",
|
||||
"protocols",
|
||||
"protocols_bgp",
|
||||
"protocols_short",
|
||||
"routes_protocol",
|
||||
"routes_peer",
|
||||
"routes_table",
|
||||
"routes_table_filtered",
|
||||
"routes_table_peer",
|
||||
"routes_filtered",
|
||||
"routes_prefixed",
|
||||
"routes_noexport",
|
||||
"routes_pipe_filtered_count",
|
||||
"routes_pipe_filtered"
|
||||
]
|
||||
|
||||
[status]
|
||||
reconfig_timestamp_source = "bird"
|
||||
reconfig_timestamp_match = "# created: (.*)"
|
||||
|
||||
filter_fields = []
|
||||
|
||||
[bird]
|
||||
listen = "0.0.0.0:29184"
|
||||
config = "/etc/bird/bird2.conf"
|
||||
birdc = "''${pkgs.bird}/bin/birdc"
|
||||
ttl = 5 # time to live (in minutes) for caching of cli output
|
||||
|
||||
[parser]
|
||||
filter_fields = []
|
||||
|
||||
[cache]
|
||||
use_redis = false # if not using redis cache, activate housekeeping to save memory!
|
||||
|
||||
[housekeeping]
|
||||
interval = 5
|
||||
force_release_memory = true
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config =
|
||||
let flagsStr = escapeShellArgs cfg.flags;
|
||||
in lib.mkIf cfg.enable {
|
||||
environment.etc."birdwatcher/birdwatcher.conf".source = pkgs.writeTextFile {
|
||||
name = "birdwatcher.conf";
|
||||
text = cfg.settings;
|
||||
};
|
||||
systemd.services = {
|
||||
birdwatcher = {
|
||||
wants = [ "network.target" ];
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
description = "Birdwatcher";
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
Restart = "on-failure";
|
||||
RestartSec = 15;
|
||||
ExecStart = "${cfg.package}/bin/birdwatcher";
|
||||
StateDirectoryMode = "0700";
|
||||
UMask = "0117";
|
||||
NoNewPrivileges = true;
|
||||
ProtectSystem = "strict";
|
||||
PrivateTmp = true;
|
||||
PrivateDevices = true;
|
||||
ProtectHostname = true;
|
||||
ProtectClock = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectControlGroups = true;
|
||||
RestrictAddressFamilies = [ "AF_UNIX AF_INET AF_INET6" ];
|
||||
LockPersonality = true;
|
||||
MemoryDenyWriteExecute = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true;
|
||||
PrivateMounts = true;
|
||||
SystemCallArchitectures = "native";
|
||||
SystemCallFilter = "~@clock @privileged @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @reboot @setuid @swap";
|
||||
BindReadOnlyPaths = [
|
||||
"-/etc/resolv.conf"
|
||||
"-/etc/nsswitch.conf"
|
||||
"-/etc/ssl/certs"
|
||||
"-/etc/static/ssl/certs"
|
||||
"-/etc/hosts"
|
||||
"-/etc/localtime"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
let
|
||||
cfg = config.services.harmonia;
|
||||
format = pkgs.formats.toml { };
|
||||
in
|
||||
{
|
||||
options = {
|
||||
services.harmonia = {
|
||||
enable = lib.mkEnableOption (lib.mdDoc "Harmonia: Nix binary cache written in Rust");
|
||||
|
||||
signKeyPath = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.path;
|
||||
default = null;
|
||||
description = lib.mdDoc "Path to the signing key that will be used for signing the cache";
|
||||
};
|
||||
|
||||
package = lib.mkPackageOptionMD pkgs "harmonia" { };
|
||||
|
||||
settings = lib.mkOption {
|
||||
inherit (format) type;
|
||||
default = { };
|
||||
description = lib.mdDoc ''
|
||||
Settings to merge with the default configuration.
|
||||
For the list of the default configuration, see <https://github.com/nix-community/harmonia/tree/master#configuration>.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.services.harmonia = {
|
||||
description = "harmonia binary cache service";
|
||||
|
||||
requires = [ "nix-daemon.socket" ];
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
environment = {
|
||||
CONFIG_FILE = format.generate "harmonia.toml" cfg.settings;
|
||||
SIGN_KEY_PATH = lib.mkIf (cfg.signKeyPath != null) "%d/sign-key";
|
||||
# Note: it's important to set this for nix-store, because it wants to use
|
||||
# $HOME in order to use a temporary cache dir. bizarre failures will occur
|
||||
# otherwise
|
||||
HOME = "/run/harmonia";
|
||||
};
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = lib.getExe cfg.package;
|
||||
User = "harmonia";
|
||||
Group = "harmonia";
|
||||
DynamicUser = true;
|
||||
PrivateUsers = true;
|
||||
DeviceAllow = [ "" ];
|
||||
UMask = "0066";
|
||||
RuntimeDirectory = "harmonia";
|
||||
LoadCredential = lib.mkIf (cfg.signKeyPath != null) [ "sign-key:${cfg.signKeyPath}" ];
|
||||
SystemCallFilter = [
|
||||
"@system-service"
|
||||
"~@privileged"
|
||||
"~@resources"
|
||||
];
|
||||
CapabilityBoundingSet = "";
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectHostname = true;
|
||||
ProtectClock = true;
|
||||
RestrictRealtime = true;
|
||||
MemoryDenyWriteExecute = true;
|
||||
ProcSubset = "pid";
|
||||
ProtectProc = "invisible";
|
||||
RestrictNamespaces = true;
|
||||
SystemCallArchitectures = "native";
|
||||
PrivateNetwork = false;
|
||||
PrivateTmp = true;
|
||||
PrivateDevices = true;
|
||||
PrivateMounts = true;
|
||||
NoNewPrivileges = true;
|
||||
ProtectSystem = "strict";
|
||||
ProtectHome = true;
|
||||
LockPersonality = true;
|
||||
RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6";
|
||||
LimitNOFILE = 65536;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -365,6 +365,9 @@ in
|
||||
"hmac-sha2-512-etm@openssh.com"
|
||||
"hmac-sha2-256-etm@openssh.com"
|
||||
"umac-128-etm@openssh.com"
|
||||
"hmac-sha2-512"
|
||||
"hmac-sha2-256"
|
||||
"umac-128@openssh.com"
|
||||
];
|
||||
description = lib.mdDoc ''
|
||||
Allowed MACs
|
||||
|
||||
@@ -8,8 +8,7 @@ let
|
||||
cmdArgs =
|
||||
[ "--port" cfg.port ]
|
||||
++ optionals (cfg.salt != null) [ "--salt" cfg.salt ]
|
||||
++ optionals (cfg.certDir != null) [ "--tls" cfg.certDir ]
|
||||
++ cfg.extraArgs;
|
||||
++ optionals (cfg.certDir != null) [ "--tls" cfg.certDir ];
|
||||
|
||||
in
|
||||
{
|
||||
@@ -34,22 +33,7 @@ in
|
||||
default = null;
|
||||
description = lib.mdDoc ''
|
||||
Salt to allow room operator passwords generated by this server
|
||||
instance to still work when the server is restarted. The salt will be
|
||||
readable in the nix store and the processlist. If this is not
|
||||
intended use `saltFile` instead. Mutually exclusive with
|
||||
<option>services.syncplay.saltFile</option>.
|
||||
'';
|
||||
};
|
||||
|
||||
saltFile = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
description = lib.mdDoc ''
|
||||
Path to the file that contains the server salt. This allows room
|
||||
operator passwords generated by this server instance to still work
|
||||
when the server is restarted. `null`, the server doesn't load the
|
||||
salt from a file. Mutually exclusive with
|
||||
<option>services.syncplay.salt</option>.
|
||||
instance to still work when the server is restarted.
|
||||
'';
|
||||
};
|
||||
|
||||
@@ -62,14 +46,6 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
extraArgs = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
description = lib.mdDoc ''
|
||||
Additional arguments to be passed to the service.
|
||||
'';
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
default = "nobody";
|
||||
@@ -98,31 +74,21 @@ in
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = cfg.salt == null || cfg.saltFile == null;
|
||||
message = "services.syncplay.salt and services.syncplay.saltFile are mutually exclusive.";
|
||||
}
|
||||
];
|
||||
systemd.services.syncplay = {
|
||||
description = "Syncplay Service";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network-online.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network-online.target" ];
|
||||
|
||||
serviceConfig = {
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
LoadCredential = lib.optional (cfg.passwordFile != null) "password:${cfg.passwordFile}"
|
||||
++ lib.optional (cfg.saltFile != null) "salt:${cfg.saltFile}";
|
||||
LoadCredential = lib.mkIf (cfg.passwordFile != null) "password:${cfg.passwordFile}";
|
||||
};
|
||||
|
||||
script = ''
|
||||
${lib.optionalString (cfg.passwordFile != null) ''
|
||||
export SYNCPLAY_PASSWORD=$(cat "''${CREDENTIALS_DIRECTORY}/password")
|
||||
''}
|
||||
${lib.optionalString (cfg.saltFile != null) ''
|
||||
export SYNCPLAY_SALT=$(cat "''${CREDENTIALS_DIRECTORY}/salt")
|
||||
''}
|
||||
exec ${pkgs.syncplay-nogui}/bin/syncplay-server ${escapeShellArgs cmdArgs}
|
||||
'';
|
||||
};
|
||||
|
||||
@@ -90,7 +90,7 @@ in
|
||||
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = {
|
||||
services.cloud-init.settings = {
|
||||
system_info = mkDefault {
|
||||
distro = "nixos";
|
||||
@@ -142,6 +142,7 @@ in
|
||||
"power-state-change"
|
||||
];
|
||||
};
|
||||
} // (mkIf cfg.enable {
|
||||
|
||||
environment.etc."cloud/cloud.cfg" =
|
||||
if cfg.config == "" then
|
||||
@@ -224,7 +225,5 @@ in
|
||||
description = "Cloud-config availability";
|
||||
requires = [ "cloud-init-local.service" "cloud-init.service" ];
|
||||
};
|
||||
};
|
||||
|
||||
meta.maintainers = [ maintainers.zimbatm ];
|
||||
});
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ in {
|
||||
`true`.
|
||||
|
||||
It does NOT apply to the daemon port nor the web UI port. To access those
|
||||
ports securely check the documentation
|
||||
ports secuerly check the documentation
|
||||
<https://dev.deluge-torrent.org/wiki/UserGuide/ThinClient#CreateSSHTunnel>
|
||||
or use a VPN or configure certificates for deluge.
|
||||
'';
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.services.mainsail;
|
||||
moonraker = config.services.moonraker;
|
||||
in
|
||||
{
|
||||
options.services.mainsail = {
|
||||
enable = mkEnableOption (lib.mdDoc "a modern and responsive user interface for Klipper");
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
description = lib.mdDoc "Mainsail package to be used in the module";
|
||||
default = pkgs.mainsail;
|
||||
defaultText = literalExpression "pkgs.mainsail";
|
||||
};
|
||||
|
||||
hostName = mkOption {
|
||||
type = types.str;
|
||||
default = "localhost";
|
||||
description = lib.mdDoc "Hostname to serve mainsail on";
|
||||
};
|
||||
|
||||
nginx = mkOption {
|
||||
type = types.submodule
|
||||
(import ../web-servers/nginx/vhost-options.nix { inherit config lib; });
|
||||
default = { };
|
||||
example = literalExpression ''
|
||||
{
|
||||
serverAliases = [ "mainsail.''${config.networking.domain}" ];
|
||||
}
|
||||
'';
|
||||
description = lib.mdDoc "Extra configuration for the nginx virtual host of mainsail.";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
upstreams.mainsail-apiserver.servers."${moonraker.address}:${toString moonraker.port}" = { };
|
||||
virtualHosts."${cfg.hostName}" = mkMerge [
|
||||
cfg.nginx
|
||||
{
|
||||
root = mkForce "${cfg.package}/share/mainsail";
|
||||
locations = {
|
||||
"/" = {
|
||||
index = "index.html";
|
||||
tryFiles = "$uri $uri/ /index.html";
|
||||
};
|
||||
"/index.html".extraConfig = ''
|
||||
add_header Cache-Control "no-store, no-cache, must-revalidate";
|
||||
'';
|
||||
"/websocket" = {
|
||||
proxyWebsockets = true;
|
||||
proxyPass = "http://mainsail-apiserver/websocket";
|
||||
};
|
||||
"~ ^/(printer|api|access|machine|server)/" = {
|
||||
proxyWebsockets = true;
|
||||
proxyPass = "http://mainsail-apiserver$request_uri";
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
Matomo is a real-time web analytics application. This module configures
|
||||
php-fpm as backend for Matomo, optionally configuring an nginx vhost as well.
|
||||
|
||||
An automatic setup is not supported by Matomo, so you need to configure Matomo
|
||||
An automatic setup is not suported by Matomo, so you need to configure Matomo
|
||||
itself in the browser-based Matomo setup.
|
||||
|
||||
## Database Setup {#module-services-matomo-database-setup}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
let
|
||||
cfg = config.services.nextcloud.notify_push;
|
||||
cfgN = config.services.nextcloud;
|
||||
in
|
||||
{
|
||||
options.services.nextcloud.notify_push = {
|
||||
@@ -26,16 +25,6 @@ in
|
||||
default = "error";
|
||||
description = lib.mdDoc "Log level";
|
||||
};
|
||||
|
||||
bendDomainToLocalhost = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = lib.mdDoc ''
|
||||
Wether to add an entry to `/etc/hosts` for the configured nextcloud domain to point to `localhost` and add `localhost `to nextcloud's `trusted_proxies` config option.
|
||||
|
||||
This is useful when nextcloud's domain is not a static IP address and when the reverse proxy cannot be bypassed because the backend connection is done via unix socket.
|
||||
'';
|
||||
};
|
||||
} // (
|
||||
lib.genAttrs [
|
||||
"dbtype"
|
||||
@@ -55,14 +44,11 @@ in
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.services.nextcloud-notify_push = let
|
||||
nextcloudUrl = "http${lib.optionalString cfgN.https "s"}://${cfgN.hostName}";
|
||||
nextcloudUrl = "http${lib.optionalString config.services.nextcloud.https "s"}://${config.services.nextcloud.hostName}";
|
||||
in {
|
||||
description = "Push daemon for Nextcloud clients";
|
||||
documentation = [ "https://github.com/nextcloud/notify_push" ];
|
||||
after = [
|
||||
"phpfpm-nextcloud.service"
|
||||
"redis-nextcloud.service"
|
||||
];
|
||||
after = [ "phpfpm-nextcloud.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
environment = {
|
||||
NEXTCLOUD_URL = nextcloudUrl;
|
||||
@@ -71,7 +57,7 @@ in
|
||||
LOG = cfg.logLevel;
|
||||
};
|
||||
postStart = ''
|
||||
${cfgN.occ}/bin/nextcloud-occ notify_push:setup ${nextcloudUrl}/push
|
||||
${config.services.nextcloud.occ}/bin/nextcloud-occ notify_push:setup ${nextcloudUrl}/push
|
||||
'';
|
||||
script = let
|
||||
dbType = if cfg.dbtype == "pgsql" then "postgresql" else cfg.dbtype;
|
||||
@@ -90,7 +76,7 @@ in
|
||||
export DATABASE_PASSWORD="$(<"${cfg.dbpassFile}")"
|
||||
'' + ''
|
||||
export DATABASE_URL="${dbUrl}"
|
||||
${cfg.package}/bin/notify_push '${cfgN.datadir}/config/config.php'
|
||||
${cfg.package}/bin/notify_push '${config.services.nextcloud.datadir}/config/config.php'
|
||||
'';
|
||||
serviceConfig = {
|
||||
User = "nextcloud";
|
||||
@@ -101,23 +87,10 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
networking.hosts = lib.mkIf cfg.bendDomainToLocalhost {
|
||||
"127.0.0.1" = [ cfgN.hostName ];
|
||||
"::1" = [ cfgN.hostName ];
|
||||
services.nginx.virtualHosts.${config.services.nextcloud.hostName}.locations."^~ /push/" = {
|
||||
proxyPass = "http://unix:${cfg.socketPath}";
|
||||
proxyWebsockets = true;
|
||||
recommendedProxySettings = true;
|
||||
};
|
||||
|
||||
services = lib.mkMerge [
|
||||
{
|
||||
nginx.virtualHosts.${cfgN.hostName}.locations."^~ /push/" = {
|
||||
proxyPass = "http://unix:${cfg.socketPath}";
|
||||
proxyWebsockets = true;
|
||||
recommendedProxySettings = true;
|
||||
};
|
||||
}
|
||||
|
||||
(lib.mkIf cfg.bendDomainToLocalhost {
|
||||
nextcloud.extraOptions.trusted_proxies = [ "127.0.0.1" "::1" ];
|
||||
})
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
@@ -17,12 +17,11 @@ and optionally supports
|
||||
|
||||
For the database, you can set
|
||||
[`services.nextcloud.config.dbtype`](#opt-services.nextcloud.config.dbtype) to
|
||||
either `sqlite` (the default), `mysql`, or `pgsql`. The simplest is `sqlite`,
|
||||
which will be automatically created and managed by the application. For the
|
||||
last two, you can easily create a local database by setting
|
||||
either `sqlite` (the default), `mysql`, or `pgsql`. For the last two, by
|
||||
default, a local database will be created and nextcloud will connect to it via
|
||||
socket; this can be disabled by setting
|
||||
[`services.nextcloud.database.createLocally`](#opt-services.nextcloud.database.createLocally)
|
||||
to `true`, Nextcloud will automatically be configured to connect to it through
|
||||
socket.
|
||||
to `false`.
|
||||
|
||||
A very basic configuration may look like this:
|
||||
```
|
||||
@@ -31,7 +30,6 @@ A very basic configuration may look like this:
|
||||
services.nextcloud = {
|
||||
enable = true;
|
||||
hostName = "nextcloud.tld";
|
||||
database.createLocally = true;
|
||||
config = {
|
||||
dbtype = "pgsql";
|
||||
adminpassFile = "/path/to/admin-pass-file";
|
||||
|
||||
@@ -317,7 +317,7 @@ in {
|
||||
|
||||
createLocally = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
default = true;
|
||||
description = lib.mdDoc ''
|
||||
Create the database and database user locally.
|
||||
'';
|
||||
@@ -551,19 +551,6 @@ in {
|
||||
default = true;
|
||||
};
|
||||
|
||||
configureRedis = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = config.services.nextcloud.notify_push.enable;
|
||||
defaultText = literalExpression "config.services.nextcloud.notify_push.enable";
|
||||
description = lib.mdDoc ''
|
||||
Wether to configure nextcloud to use the recommended redis settings for small instances.
|
||||
|
||||
::: {.note}
|
||||
The `notify_push` app requires redis to be configured. If this option is turned off, this must be configured manually.
|
||||
:::
|
||||
'';
|
||||
};
|
||||
|
||||
caching = {
|
||||
apcu = mkOption {
|
||||
type = types.bool;
|
||||
@@ -754,8 +741,9 @@ in {
|
||||
{ assertions = [
|
||||
{ assertion = cfg.database.createLocally -> cfg.config.dbpassFile == null;
|
||||
message = ''
|
||||
Using `services.nextcloud.database.createLocally` with database
|
||||
password authentication is no longer supported.
|
||||
Using `services.nextcloud.database.createLocally` (that now defaults
|
||||
to true) with database password authentication is no longer
|
||||
supported.
|
||||
|
||||
If you use an external database (or want to use password auth for any
|
||||
other reason), set `services.nextcloud.database.createLocally` to
|
||||
@@ -1056,25 +1044,6 @@ in {
|
||||
}];
|
||||
};
|
||||
|
||||
services.redis.servers.nextcloud = lib.mkIf cfg.configureRedis {
|
||||
enable = true;
|
||||
user = "nextcloud";
|
||||
};
|
||||
|
||||
services.nextcloud = lib.mkIf cfg.configureRedis {
|
||||
caching.redis = true;
|
||||
extraOptions = {
|
||||
memcache = {
|
||||
distributed = ''\OC\Memcache\Redis'';
|
||||
locking = ''\OC\Memcache\Redis'';
|
||||
};
|
||||
redis = {
|
||||
host = config.services.redis.servers.nextcloud.unixSocket;
|
||||
port = 0;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx.enable = mkDefault true;
|
||||
|
||||
services.nginx.virtualHosts.${cfg.hostName} = {
|
||||
|
||||
@@ -429,7 +429,7 @@ in {
|
||||
|
||||
environment = env;
|
||||
|
||||
path = with pkgs; [ bashInteractive ffmpeg nodejs_18 openssl yarn python3 ];
|
||||
path = with pkgs; [ bashInteractive ffmpeg nodejs_16 openssl yarn python3 ];
|
||||
|
||||
script = ''
|
||||
#!/bin/sh
|
||||
@@ -490,7 +490,7 @@ in {
|
||||
services.nginx = lib.mkIf cfg.configureNginx {
|
||||
enable = true;
|
||||
virtualHosts."${cfg.localDomain}" = {
|
||||
root = "/var/lib/peertube/www";
|
||||
root = "/var/lib/peertube";
|
||||
|
||||
# Application
|
||||
locations."/" = {
|
||||
@@ -593,7 +593,7 @@ in {
|
||||
|
||||
# Bypass PeerTube for performance reasons.
|
||||
locations."~ ^/client/(assets/images/(icons/icon-36x36\.png|icons/icon-48x48\.png|icons/icon-72x72\.png|icons/icon-96x96\.png|icons/icon-144x144\.png|icons/icon-192x192\.png|icons/icon-512x512\.png|logo\.svg|favicon\.png|default-playlist\.jpg|default-avatar-account\.png|default-avatar-account-48x48\.png|default-avatar-video-channel\.png|default-avatar-video-channel-48x48\.png))$" = {
|
||||
tryFiles = "/client-overrides/$1 /client/$1 $1";
|
||||
tryFiles = "/www/client-overrides/$1 /www/client/$1 $1";
|
||||
priority = 1310;
|
||||
};
|
||||
|
||||
@@ -859,7 +859,7 @@ in {
|
||||
home = cfg.package;
|
||||
};
|
||||
})
|
||||
(lib.attrsets.setAttrByPath [ cfg.user "packages" ] [ cfg.package peertubeEnv peertubeCli pkgs.ffmpeg pkgs.nodejs_18 pkgs.yarn ])
|
||||
(lib.attrsets.setAttrByPath [ cfg.user "packages" ] [ cfg.package peertubeEnv peertubeCli pkgs.ffmpeg pkgs.nodejs_16 pkgs.yarn ])
|
||||
(lib.mkIf cfg.redis.enableUnixSocket {${config.services.peertube.user}.extraGroups = [ "redis-peertube" ];})
|
||||
];
|
||||
|
||||
|
||||
@@ -34,8 +34,8 @@ in
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.services.pict-rs = {
|
||||
environment = {
|
||||
PICTRS__PATH = cfg.dataDir;
|
||||
PICTRS__ADDR = "${cfg.address}:${toString cfg.port}";
|
||||
PICTRS_PATH = cfg.dataDir;
|
||||
PICTRS_ADDR = "${cfg.address}:${toString cfg.port}";
|
||||
};
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
|
||||
@@ -1,478 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.pixelfed;
|
||||
user = cfg.user;
|
||||
group = cfg.group;
|
||||
pixelfed = cfg.package.override { inherit (cfg) dataDir runtimeDir; };
|
||||
# https://github.com/pixelfed/pixelfed/blob/dev/app/Console/Commands/Installer.php#L185-L190
|
||||
extraPrograms = with pkgs; [ jpegoptim optipng pngquant gifsicle ffmpeg ];
|
||||
# Ensure PHP extensions: https://github.com/pixelfed/pixelfed/blob/dev/app/Console/Commands/Installer.php#L135-L147
|
||||
phpPackage = cfg.phpPackage.buildEnv {
|
||||
extensions = { enabled, all }:
|
||||
enabled
|
||||
++ (with all; [ bcmath ctype curl mbstring gd intl zip redis imagick ]);
|
||||
};
|
||||
configFile =
|
||||
pkgs.writeText "pixelfed-env" (lib.generators.toKeyValue { } cfg.settings);
|
||||
# Management script
|
||||
pixelfed-manage = pkgs.writeShellScriptBin "pixelfed-manage" ''
|
||||
cd ${pixelfed}
|
||||
sudo=exec
|
||||
if [[ "$USER" != ${user} ]]; then
|
||||
sudo='exec /run/wrappers/bin/sudo -u ${user}'
|
||||
fi
|
||||
$sudo ${cfg.phpPackage}/bin/php artisan "$@"
|
||||
'';
|
||||
dbSocket = {
|
||||
"pgsql" = "/run/postgresql";
|
||||
"mysql" = "/run/mysqld/mysqld.sock";
|
||||
}.${cfg.database.type};
|
||||
dbService = {
|
||||
"pgsql" = "postgresql.service";
|
||||
"mysql" = "mysql.service";
|
||||
}.${cfg.database.type};
|
||||
redisService = "redis-pixelfed.service";
|
||||
in {
|
||||
options.services = {
|
||||
pixelfed = {
|
||||
enable = mkEnableOption (lib.mdDoc "a Pixelfed instance");
|
||||
package = mkPackageOptionMD pkgs "pixelfed" { };
|
||||
phpPackage = mkPackageOptionMD pkgs "php81" { };
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
default = "pixelfed";
|
||||
description = lib.mdDoc ''
|
||||
User account under which pixelfed runs.
|
||||
|
||||
::: {.note}
|
||||
If left as the default value this user will automatically be created
|
||||
on system activation, otherwise you are responsible for
|
||||
ensuring the user exists before the pixelfed application starts.
|
||||
:::
|
||||
'';
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
default = "pixelfed";
|
||||
description = lib.mdDoc ''
|
||||
Group account under which pixelfed runs.
|
||||
|
||||
::: {.note}
|
||||
If left as the default value this group will automatically be created
|
||||
on system activation, otherwise you are responsible for
|
||||
ensuring the group exists before the pixelfed application starts.
|
||||
:::
|
||||
'';
|
||||
};
|
||||
|
||||
domain = mkOption {
|
||||
type = types.str;
|
||||
description = lib.mdDoc ''
|
||||
FQDN for the Pixelfed instance.
|
||||
'';
|
||||
};
|
||||
|
||||
secretFile = mkOption {
|
||||
type = types.path;
|
||||
description = lib.mdDoc ''
|
||||
A secret file to be sourced for the .env settings.
|
||||
Place `APP_KEY` and other settings that should not end up in the Nix store here.
|
||||
'';
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
type = with types; (attrsOf (oneOf [ bool int str ]));
|
||||
description = lib.mdDoc ''
|
||||
.env settings for Pixelfed.
|
||||
Secrets should use `secretFile` option instead.
|
||||
'';
|
||||
};
|
||||
|
||||
nginx = mkOption {
|
||||
type = types.nullOr (types.submodule
|
||||
(import ../web-servers/nginx/vhost-options.nix {
|
||||
inherit config lib;
|
||||
}));
|
||||
default = null;
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
serverAliases = [
|
||||
"pics.''${config.networking.domain}"
|
||||
];
|
||||
enableACME = true;
|
||||
forceHttps = true;
|
||||
}
|
||||
'';
|
||||
description = lib.mdDoc ''
|
||||
With this option, you can customize an nginx virtual host which already has sensible defaults for Dolibarr.
|
||||
Set to {} if you do not need any customization to the virtual host.
|
||||
If enabled, then by default, the {option}`serverName` is
|
||||
`''${domain}`,
|
||||
If this is set to null (the default), no nginx virtualHost will be configured.
|
||||
'';
|
||||
};
|
||||
|
||||
redis.createLocally = mkEnableOption
|
||||
(lib.mdDoc "a local Redis database using UNIX socket authentication")
|
||||
// {
|
||||
default = true;
|
||||
};
|
||||
|
||||
database = {
|
||||
createLocally = mkEnableOption
|
||||
(lib.mdDoc "a local database using UNIX socket authentication") // {
|
||||
default = true;
|
||||
};
|
||||
automaticMigrations = mkEnableOption
|
||||
(lib.mdDoc "automatic migrations for database schema and data") // {
|
||||
default = true;
|
||||
};
|
||||
|
||||
type = mkOption {
|
||||
type = types.enum [ "mysql" "pgsql" ];
|
||||
example = "pgsql";
|
||||
default = "mysql";
|
||||
description = lib.mdDoc ''
|
||||
Database engine to use.
|
||||
Note that PGSQL is not well supported: https://github.com/pixelfed/pixelfed/issues/2727
|
||||
'';
|
||||
};
|
||||
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
default = "pixelfed";
|
||||
description = lib.mdDoc "Database name.";
|
||||
};
|
||||
};
|
||||
|
||||
maxUploadSize = mkOption {
|
||||
type = types.str;
|
||||
default = "8M";
|
||||
description = lib.mdDoc ''
|
||||
Max upload size with units.
|
||||
'';
|
||||
};
|
||||
|
||||
poolConfig = mkOption {
|
||||
type = with types; attrsOf (oneOf [ int str bool ]);
|
||||
default = { };
|
||||
|
||||
description = lib.mdDoc ''
|
||||
Options for Pixelfed's PHP-FPM pool.
|
||||
'';
|
||||
};
|
||||
|
||||
dataDir = mkOption {
|
||||
type = types.str;
|
||||
default = "/var/lib/pixelfed";
|
||||
description = lib.mdDoc ''
|
||||
State directory of the `pixelfed` user which holds
|
||||
the application's state and data.
|
||||
'';
|
||||
};
|
||||
|
||||
runtimeDir = mkOption {
|
||||
type = types.str;
|
||||
default = "/run/pixelfed";
|
||||
description = lib.mdDoc ''
|
||||
Ruutime directory of the `pixelfed` user which holds
|
||||
the application's caches and temporary files.
|
||||
'';
|
||||
};
|
||||
|
||||
schedulerInterval = mkOption {
|
||||
type = types.str;
|
||||
default = "1d";
|
||||
description = lib.mdDoc "How often the Pixelfed cron task should run";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
users.users.pixelfed = mkIf (cfg.user == "pixelfed") {
|
||||
isSystemUser = true;
|
||||
group = cfg.group;
|
||||
extraGroups = lib.optional cfg.redis.createLocally "redis-pixelfed";
|
||||
};
|
||||
users.groups.pixelfed = mkIf (cfg.group == "pixelfed") { };
|
||||
|
||||
services.redis.servers.pixelfed.enable = lib.mkIf cfg.redis.createLocally true;
|
||||
services.pixelfed.settings = mkMerge [
|
||||
({
|
||||
APP_ENV = mkDefault "production";
|
||||
APP_DEBUG = mkDefault false;
|
||||
# https://github.com/pixelfed/pixelfed/blob/dev/app/Console/Commands/Installer.php#L312-L316
|
||||
APP_URL = mkDefault "https://${cfg.domain}";
|
||||
ADMIN_DOMAIN = mkDefault cfg.domain;
|
||||
APP_DOMAIN = mkDefault cfg.domain;
|
||||
SESSION_DOMAIN = mkDefault cfg.domain;
|
||||
SESSION_SECURE_COOKIE = mkDefault true;
|
||||
OPEN_REGISTRATION = mkDefault false;
|
||||
# ActivityPub: https://github.com/pixelfed/pixelfed/blob/dev/app/Console/Commands/Installer.php#L360-L364
|
||||
ACTIVITY_PUB = mkDefault true;
|
||||
AP_REMOTE_FOLLOW = mkDefault true;
|
||||
AP_INBOX = mkDefault true;
|
||||
AP_OUTBOX = mkDefault true;
|
||||
AP_SHAREDINBOX = mkDefault true;
|
||||
# Image optimization: https://github.com/pixelfed/pixelfed/blob/dev/app/Console/Commands/Installer.php#L367-L404
|
||||
PF_OPTIMIZE_IMAGES = mkDefault true;
|
||||
IMAGE_DRIVER = mkDefault "imagick";
|
||||
# Mobile APIs
|
||||
OAUTH_ENABLED = mkDefault true;
|
||||
# https://github.com/pixelfed/pixelfed/blob/dev/app/Console/Commands/Installer.php#L351
|
||||
EXP_EMC = mkDefault true;
|
||||
# Defer to systemd
|
||||
LOG_CHANNEL = mkDefault "stderr";
|
||||
# TODO: find out the correct syntax?
|
||||
# TRUST_PROXIES = mkDefault "127.0.0.1/8, ::1/128";
|
||||
})
|
||||
(mkIf (cfg.redis.createLocally) {
|
||||
BROADCAST_DRIVER = mkDefault "redis";
|
||||
CACHE_DRIVER = mkDefault "redis";
|
||||
QUEUE_DRIVER = mkDefault "redis";
|
||||
SESSION_DRIVER = mkDefault "redis";
|
||||
WEBSOCKET_REPLICATION_MODE = mkDefault "redis";
|
||||
# Suppport phpredis and predis configuration-style.
|
||||
REDIS_SCHEME = "unix";
|
||||
REDIS_HOST = config.services.redis.servers.pixelfed.unixSocket;
|
||||
REDIS_PATH = config.services.redis.servers.pixelfed.unixSocket;
|
||||
})
|
||||
(mkIf (cfg.database.createLocally) {
|
||||
DB_CONNECTION = cfg.database.type;
|
||||
DB_SOCKET = dbSocket;
|
||||
DB_DATABASE = cfg.database.name;
|
||||
DB_USERNAME = user;
|
||||
# No TCP/IP connection.
|
||||
DB_PORT = 0;
|
||||
})
|
||||
];
|
||||
|
||||
environment.systemPackages = [ pixelfed-manage ];
|
||||
|
||||
services.mysql =
|
||||
mkIf (cfg.database.createLocally && cfg.database.type == "mysql") {
|
||||
enable = mkDefault true;
|
||||
package = mkDefault pkgs.mariadb;
|
||||
ensureDatabases = [ cfg.database.name ];
|
||||
ensureUsers = [{
|
||||
name = user;
|
||||
ensurePermissions = { "${cfg.database.name}.*" = "ALL PRIVILEGES"; };
|
||||
}];
|
||||
};
|
||||
|
||||
services.postgresql =
|
||||
mkIf (cfg.database.createLocally && cfg.database.type == "pgsql") {
|
||||
enable = mkDefault true;
|
||||
ensureDatabases = [ cfg.database.name ];
|
||||
ensureUsers = [{
|
||||
name = user;
|
||||
ensurePermissions = { };
|
||||
}];
|
||||
};
|
||||
|
||||
# Make each individual option overridable with lib.mkDefault.
|
||||
services.pixelfed.poolConfig = lib.mapAttrs' (n: v: lib.nameValuePair n (lib.mkDefault v)) {
|
||||
"pm" = "dynamic";
|
||||
"php_admin_value[error_log]" = "stderr";
|
||||
"php_admin_flag[log_errors]" = true;
|
||||
"catch_workers_output" = true;
|
||||
"pm.max_children" = "32";
|
||||
"pm.start_servers" = "2";
|
||||
"pm.min_spare_servers" = "2";
|
||||
"pm.max_spare_servers" = "4";
|
||||
"pm.max_requests" = "500";
|
||||
};
|
||||
|
||||
services.phpfpm.pools.pixelfed = {
|
||||
inherit user group;
|
||||
inherit phpPackage;
|
||||
|
||||
phpOptions = ''
|
||||
post_max_size = ${toString cfg.maxUploadSize}
|
||||
upload_max_filesize = ${toString cfg.maxUploadSize}
|
||||
max_execution_time = 600;
|
||||
'';
|
||||
|
||||
settings = {
|
||||
"listen.owner" = user;
|
||||
"listen.group" = group;
|
||||
"listen.mode" = "0660";
|
||||
"catch_workers_output" = "yes";
|
||||
} // cfg.poolConfig;
|
||||
};
|
||||
|
||||
systemd.services.phpfpm-pixelfed.after = [ "pixelfed-data-setup.service" ];
|
||||
systemd.services.phpfpm-pixelfed.requires =
|
||||
[ "pixelfed-horizon.service" "pixelfed-data-setup.service" ]
|
||||
++ lib.optional cfg.database.createLocally dbService
|
||||
++ lib.optional cfg.redis.createLocally redisService;
|
||||
# Ensure image optimizations programs are available.
|
||||
systemd.services.phpfpm-pixelfed.path = extraPrograms;
|
||||
|
||||
systemd.services.pixelfed-horizon = {
|
||||
description = "Pixelfed task queueing via Laravel Horizon framework";
|
||||
after = [ "network.target" "pixelfed-data-setup.service" ];
|
||||
requires = [ "pixelfed-data-setup.service" ]
|
||||
++ (lib.optional cfg.database.createLocally dbService)
|
||||
++ (lib.optional cfg.redis.createLocally redisService);
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
# Ensure image optimizations programs are available.
|
||||
path = extraPrograms;
|
||||
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
ExecStart = "${pixelfed-manage}/bin/pixelfed-manage horizon";
|
||||
StateDirectory =
|
||||
lib.mkIf (cfg.dataDir == "/var/lib/pixelfed") "pixelfed";
|
||||
User = user;
|
||||
Group = group;
|
||||
Restart = "on-failure";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.timers.pixelfed-cron = {
|
||||
description = "Pixelfed periodic tasks timer";
|
||||
after = [ "pixelfed-data-setup.service" ];
|
||||
requires = [ "phpfpm-pixelfed.service" ];
|
||||
wantedBy = [ "timers.target" ];
|
||||
|
||||
timerConfig = {
|
||||
OnBootSec = cfg.schedulerInterval;
|
||||
OnUnitActiveSec = cfg.schedulerInterval;
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.pixelfed-cron = {
|
||||
description = "Pixelfed periodic tasks";
|
||||
# Ensure image optimizations programs are available.
|
||||
path = extraPrograms;
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = "${pixelfed-manage}/bin/pixelfed-manage schedule:run";
|
||||
User = user;
|
||||
Group = group;
|
||||
StateDirectory = cfg.dataDir;
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.pixelfed-data-setup = {
|
||||
description =
|
||||
"Pixelfed setup: migrations, environment file update, cache reload, data changes";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = lib.optional cfg.database.createLocally dbService;
|
||||
requires = lib.optional cfg.database.createLocally dbService;
|
||||
path = with pkgs; [ bash pixelfed-manage rsync ] ++ extraPrograms;
|
||||
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
User = user;
|
||||
Group = group;
|
||||
StateDirectory =
|
||||
lib.mkIf (cfg.dataDir == "/var/lib/pixelfed") "pixelfed";
|
||||
LoadCredential = "env-secrets:${cfg.secretFile}";
|
||||
UMask = "077";
|
||||
};
|
||||
|
||||
script = ''
|
||||
# Concatenate non-secret .env and secret .env
|
||||
rm -f ${cfg.dataDir}/.env
|
||||
cp --no-preserve=all ${configFile} ${cfg.dataDir}/.env
|
||||
echo -e '\n' >> ${cfg.dataDir}/.env
|
||||
cat "$CREDENTIALS_DIRECTORY/env-secrets" >> ${cfg.dataDir}/.env
|
||||
|
||||
# Link the static storage (package provided) to the runtime storage
|
||||
# Necessary for cities.json and static images.
|
||||
mkdir -p ${cfg.dataDir}/storage
|
||||
rsync -av --no-perms ${pixelfed}/storage-static/ ${cfg.dataDir}/storage
|
||||
chmod -R +w ${cfg.dataDir}/storage
|
||||
|
||||
# Link the app.php in the runtime folder.
|
||||
# We cannot link the cache folder only because bootstrap folder needs to be writeable.
|
||||
ln -sf ${pixelfed}/bootstrap-static/app.php ${cfg.runtimeDir}/app.php
|
||||
|
||||
# https://laravel.com/docs/10.x/filesystem#the-public-disk
|
||||
# Creating the public/storage → storage/app/public link
|
||||
# is unnecessary as it's part of the installPhase of pixelfed.
|
||||
|
||||
# Install Horizon
|
||||
# FIXME: require write access to public/ — should be done as part of install — pixelfed-manage horizon:publish
|
||||
|
||||
# Before running any PHP program, cleanup the bootstrap.
|
||||
# It's necessary if you upgrade the application otherwise you might
|
||||
# try to import non-existent modules.
|
||||
rm -rf ${cfg.runtimeDir}/bootstrap/*
|
||||
|
||||
# Perform the first migration.
|
||||
[[ ! -f ${cfg.dataDir}/.initial-migration ]] && pixelfed-manage migrate --force && touch ${cfg.dataDir}/.initial-migration
|
||||
|
||||
${lib.optionalString cfg.database.automaticMigrations ''
|
||||
# Force migrate the database.
|
||||
pixelfed-manage migrate --force
|
||||
''}
|
||||
|
||||
# Import location data
|
||||
pixelfed-manage import:cities
|
||||
|
||||
${lib.optionalString cfg.settings.ACTIVITY_PUB ''
|
||||
# ActivityPub federation bookkeeping
|
||||
[[ ! -f ${cfg.dataDir}/.instance-actor-created ]] && pixelfed-manage instance:actor && touch ${cfg.dataDir}/.instance-actor-created
|
||||
''}
|
||||
|
||||
${lib.optionalString cfg.settings.OAUTH_ENABLED ''
|
||||
# Generate Passport encryption keys
|
||||
[[ ! -f ${cfg.dataDir}/.passport-keys-generated ]] && pixelfed-manage passport:keys && touch ${cfg.dataDir}/.passport-keys-generated
|
||||
''}
|
||||
|
||||
pixelfed-manage route:cache
|
||||
pixelfed-manage view:cache
|
||||
pixelfed-manage config:cache
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
# Cache must live across multiple systemd units runtimes.
|
||||
"d ${cfg.runtimeDir}/ 0700 ${user} ${group} - -"
|
||||
"d ${cfg.runtimeDir}/cache 0700 ${user} ${group} - -"
|
||||
];
|
||||
|
||||
# Enable NGINX to access our phpfpm-socket.
|
||||
users.users."${config.services.nginx.group}".extraGroups = [ cfg.group ];
|
||||
services.nginx = mkIf (cfg.nginx != null) {
|
||||
enable = true;
|
||||
virtualHosts."${cfg.domain}" = mkMerge [
|
||||
cfg.nginx
|
||||
{
|
||||
root = lib.mkForce "${pixelfed}/public/";
|
||||
locations."/".tryFiles = "$uri $uri/ /index.php?query_string";
|
||||
locations."/favicon.ico".extraConfig = ''
|
||||
access_log off; log_not_found off;
|
||||
'';
|
||||
locations."/robots.txt".extraConfig = ''
|
||||
access_log off; log_not_found off;
|
||||
'';
|
||||
locations."~ \\.php$".extraConfig = ''
|
||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||
fastcgi_pass unix:${config.services.phpfpm.pools.pixelfed.socket};
|
||||
fastcgi_index index.php;
|
||||
'';
|
||||
locations."~ /\\.(?!well-known).*".extraConfig = ''
|
||||
deny all;
|
||||
'';
|
||||
extraConfig = ''
|
||||
add_header X-Frame-Options "SAMEORIGIN";
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
add_header X-Content-Type-Options "nosniff";
|
||||
index index.html index.htm index.php;
|
||||
error_page 404 /index.php;
|
||||
client_max_body_size ${toString cfg.maxUploadSize};
|
||||
'';
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -534,7 +534,7 @@ let
|
||||
services.phpfpm.pools = mkIf (cfg.pool == "${poolName}") {
|
||||
${poolName} = {
|
||||
inherit (cfg) user;
|
||||
phpPackage = pkgs.php81;
|
||||
phpPackage = pkgs.php80;
|
||||
settings = mapAttrs (name: mkDefault) {
|
||||
"listen.owner" = "nginx";
|
||||
"listen.group" = "nginx";
|
||||
|
||||
@@ -56,11 +56,6 @@ in {
|
||||
type = types.str;
|
||||
description = lib.mdDoc "The Hostname under which the frontend is running.";
|
||||
};
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 3456;
|
||||
description = lib.mdDoc "The TCP port exposed by the API.";
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
type = format.type;
|
||||
@@ -106,7 +101,6 @@ in {
|
||||
inherit (cfg.database) type host user database path;
|
||||
};
|
||||
service = {
|
||||
interface = ":${toString cfg.port}";
|
||||
frontendurl = "${cfg.frontendScheme}://${cfg.frontendHostname}/";
|
||||
};
|
||||
files = {
|
||||
@@ -138,7 +132,7 @@ in {
|
||||
tryFiles = "try_files $uri $uri/ /";
|
||||
};
|
||||
"~* ^/(api|dav|\\.well-known)/" = {
|
||||
proxyPass = "http://localhost:${toString cfg.port}";
|
||||
proxyPass = "http://localhost:3456";
|
||||
extraConfig = ''
|
||||
client_max_body_size 20M;
|
||||
'';
|
||||
|
||||
@@ -133,7 +133,7 @@ in {
|
||||
WorkingDirectory = "/var/lib/${cfg.stateDirectoryName}";
|
||||
DynamicUser = true;
|
||||
PrivateTmp = true;
|
||||
ExecStart = "${pkgs.nodejs_18}/bin/node ${pkgs.wiki-js}/server";
|
||||
ExecStart = "${pkgs.nodejs_16}/bin/node ${pkgs.wiki-js}/server";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -113,15 +113,10 @@ let
|
||||
]};
|
||||
'') (filterAttrs (name: conf: conf.enable) cfg.proxyCachePath));
|
||||
|
||||
toUpstreamParameter = key: value:
|
||||
if builtins.isBool value
|
||||
then lib.optionalString value key
|
||||
else "${key}=${toString value}";
|
||||
|
||||
upstreamConfig = toString (flip mapAttrsToList cfg.upstreams (name: upstream: ''
|
||||
upstream ${name} {
|
||||
${toString (flip mapAttrsToList upstream.servers (name: server: ''
|
||||
server ${name} ${concatStringsSep " " (mapAttrsToList toUpstreamParameter server)};
|
||||
server ${name} ${optionalString server.backup "backup"};
|
||||
''))}
|
||||
${upstream.extraConfig}
|
||||
}
|
||||
@@ -927,7 +922,6 @@ in
|
||||
options = {
|
||||
servers = mkOption {
|
||||
type = types.attrsOf (types.submodule {
|
||||
freeformType = types.attrsOf (types.oneOf [ types.bool types.int types.str ]);
|
||||
options = {
|
||||
backup = mkOption {
|
||||
type = types.bool;
|
||||
@@ -941,11 +935,9 @@ in
|
||||
});
|
||||
description = lib.mdDoc ''
|
||||
Defines the address and other parameters of the upstream servers.
|
||||
See [the documentation](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#server)
|
||||
for the available parameters.
|
||||
'';
|
||||
default = {};
|
||||
example = lib.literalMD "see [](#opt-services.nginx.upstreams)";
|
||||
example = { "127.0.0.1:8000" = {}; };
|
||||
};
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
@@ -960,23 +952,14 @@ in
|
||||
Defines a group of servers to use as proxy target.
|
||||
'';
|
||||
default = {};
|
||||
example = {
|
||||
"backend" = {
|
||||
servers = {
|
||||
"backend1.example.com:8080" = { weight = 5; };
|
||||
"backend2.example.com" = { max_fails = 3; fail_timeout = "30s"; };
|
||||
"backend3.example.com" = {};
|
||||
"backup1.example.com" = { backup = true; };
|
||||
"backup2.example.com" = { backup = true; };
|
||||
};
|
||||
extraConfig = ''
|
||||
example = literalExpression ''
|
||||
"backend_server" = {
|
||||
servers = { "127.0.0.1:8000" = {}; };
|
||||
extraConfig = ''''
|
||||
keepalive 16;
|
||||
'';
|
||||
'''';
|
||||
};
|
||||
"memcached" = {
|
||||
servers."unix:/run//memcached/memcached.sock" = {};
|
||||
};
|
||||
};
|
||||
'';
|
||||
};
|
||||
|
||||
virtualHosts = mkOption {
|
||||
|
||||
@@ -104,7 +104,7 @@ in {
|
||||
PIDFile = "/run/unit/unit.pid";
|
||||
ExecStart = ''
|
||||
${cfg.package}/bin/unitd --control 'unix:/run/unit/control.unit.sock' --pid '/run/unit/unit.pid' \
|
||||
--log '${cfg.logDir}/unit.log' --statedir '${cfg.stateDir}' --tmpdir '/tmp' \
|
||||
--log '${cfg.logDir}/unit.log' --state '${cfg.stateDir}' --tmp '/tmp' \
|
||||
--user ${cfg.user} --group ${cfg.group}
|
||||
'';
|
||||
ExecStop = ''
|
||||
|
||||
@@ -99,7 +99,7 @@ in
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
|
||||
# check .vcl syntax at compile time (e.g. before nixops deployment)
|
||||
system.checks = mkIf cfg.enableConfigCheck [
|
||||
system.extraDependencies = mkIf cfg.enableConfigCheck [
|
||||
(pkgs.runCommand "check-varnish-syntax" {} ''
|
||||
${cfg.package}/bin/varnishd -C ${commandLine} 2> $out || (cat $out; exit 1)
|
||||
'')
|
||||
|
||||
@@ -45,15 +45,10 @@ in {
|
||||
enable = mkEnableOption (mdDoc "the Budgie desktop");
|
||||
|
||||
sessionPath = mkOption {
|
||||
description = lib.mdDoc ''
|
||||
Additional list of packages to be added to the session search path.
|
||||
Useful for GSettings-conditional autostart.
|
||||
|
||||
Note that this should be a last resort; patching the package is preferred (see GPaste).
|
||||
'';
|
||||
type = types.listOf types.package;
|
||||
description = mdDoc "Additional list of packages to be added to the session search path. Useful for GSettings-conditional autostart.";
|
||||
type = with types; listOf package;
|
||||
example = literalExpression "[ pkgs.budgie.budgie-desktop-view ]";
|
||||
default = [];
|
||||
example = literalExpression "[ pkgs.gnome.gpaste ]";
|
||||
};
|
||||
|
||||
extraGSettingsOverrides = mkOption {
|
||||
@@ -64,21 +59,20 @@ in {
|
||||
|
||||
extraGSettingsOverridePackages = mkOption {
|
||||
description = mdDoc "List of packages for which GSettings are overridden.";
|
||||
type = types.listOf types.path;
|
||||
type = with types; listOf path;
|
||||
default = [];
|
||||
};
|
||||
|
||||
extraPlugins = mkOption {
|
||||
description = mdDoc "Extra plugins for the Budgie desktop";
|
||||
type = types.listOf types.package;
|
||||
type = with types; listOf package;
|
||||
default = [];
|
||||
example = literalExpression "[ pkgs.budgiePlugins.budgie-analogue-clock-applet ]";
|
||||
};
|
||||
};
|
||||
|
||||
environment.budgie.excludePackages = mkOption {
|
||||
description = mdDoc "Which packages Budgie should exclude from the default environment.";
|
||||
type = types.listOf types.package;
|
||||
type = with types; listOf package;
|
||||
default = [];
|
||||
example = literalExpression "[ pkgs.mate-terminal ]";
|
||||
};
|
||||
|
||||
@@ -260,9 +260,7 @@ in {
|
||||
options = {
|
||||
|
||||
services.xserver.libinput = {
|
||||
enable = mkEnableOption (lib.mdDoc "libinput") // {
|
||||
default = true;
|
||||
};
|
||||
enable = mkEnableOption (lib.mdDoc "libinput");
|
||||
mouse = mkConfigForDevice "mouse";
|
||||
touchpad = mkConfigForDevice "touchpad";
|
||||
};
|
||||
|
||||
@@ -776,7 +776,7 @@ in
|
||||
xorg.xf86inputevdev.out
|
||||
];
|
||||
|
||||
system.checks = singleton (pkgs.runCommand "xkb-validated" {
|
||||
system.extraDependencies = singleton (pkgs.runCommand "xkb-validated" {
|
||||
inherit (cfg) xkbModel layout xkbVariant xkbOptions;
|
||||
nativeBuildInputs = with pkgs.buildPackages; [ xkbvalidate ];
|
||||
preferLocalBuild = true;
|
||||
|
||||
@@ -263,23 +263,8 @@ in
|
||||
default = [];
|
||||
description = lib.mdDoc ''
|
||||
A list of packages that should be included in the system
|
||||
closure but generally not visible to users.
|
||||
|
||||
This option has also been used for build-time checks, but the
|
||||
`system.checks` option is more appropriate for that purpose as checks
|
||||
should not leave a trace in the built system configuration.
|
||||
'';
|
||||
};
|
||||
|
||||
system.checks = mkOption {
|
||||
type = types.listOf types.package;
|
||||
default = [];
|
||||
description = lib.mdDoc ''
|
||||
Packages that are added as dependencies of the system's build, usually
|
||||
for the purpose of validating some part of the configuration.
|
||||
|
||||
Unlike `system.extraDependencies`, these store paths do not
|
||||
become part of the built system configuration.
|
||||
closure but not otherwise made available to users. This is
|
||||
primarily used by the installation tests.
|
||||
'';
|
||||
};
|
||||
|
||||
@@ -378,17 +363,7 @@ in
|
||||
fi
|
||||
'';
|
||||
|
||||
system.systemBuilderArgs = {
|
||||
# Not actually used in the builder. `passedChecks` is just here to create
|
||||
# the build dependencies. Checks are similar to build dependencies in the
|
||||
# sense that if they fail, the system build fails. However, checks do not
|
||||
# produce any output of value, so they are not used by the system builder.
|
||||
# In fact, using them runs the risk of accidentally adding unneeded paths
|
||||
# to the system closure, which defeats the purpose of the `system.checks`
|
||||
# option, as opposed to `system.extraDependencies`.
|
||||
passedChecks = concatStringsSep " " config.system.checks;
|
||||
}
|
||||
// lib.optionalAttrs (config.system.forbiddenDependenciesRegex != "") {
|
||||
system.systemBuilderArgs = lib.optionalAttrs (config.system.forbiddenDependenciesRegex != "") {
|
||||
inherit (config.system) forbiddenDependenciesRegex;
|
||||
closureInfo = pkgs.closureInfo { rootPaths = [
|
||||
# override to avoid infinite recursion (and to allow using extraDependencies to add forbidden dependencies)
|
||||
@@ -396,7 +371,6 @@ in
|
||||
]; };
|
||||
};
|
||||
|
||||
|
||||
system.build.toplevel = if config.system.includeBuildDependencies then systemWithBuildDeps else system;
|
||||
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{ config, options, lib, pkgs, ... }:
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
@@ -12,8 +12,13 @@ let
|
||||
# Package set of targeted architecture
|
||||
if cfg.forcei686 then pkgs.pkgsi686Linux else pkgs;
|
||||
|
||||
realGrub = if cfg.zfsSupport then grubPkgs.grub2.override { zfsSupport = true; }
|
||||
else grubPkgs.grub2;
|
||||
realGrub = if cfg.version == 1 then grubPkgs.grub
|
||||
else if cfg.zfsSupport then grubPkgs.grub2.override { zfsSupport = true; }
|
||||
else if cfg.trustedBoot.enable
|
||||
then if cfg.trustedBoot.isHPLaptop
|
||||
then grubPkgs.trustedGrub-for-HP
|
||||
else grubPkgs.trustedGrub
|
||||
else grubPkgs.grub2;
|
||||
|
||||
grub =
|
||||
# Don't include GRUB if we're only generating a GRUB menu (e.g.,
|
||||
@@ -23,7 +28,8 @@ let
|
||||
else realGrub;
|
||||
|
||||
grubEfi =
|
||||
if cfg.efiSupport
|
||||
# EFI version of Grub v2
|
||||
if cfg.efiSupport && (cfg.version == 2)
|
||||
then realGrub.override { efiSupport = cfg.efiSupport; }
|
||||
else null;
|
||||
|
||||
@@ -46,24 +52,24 @@ let
|
||||
fullName = lib.getName realGrub;
|
||||
fullVersion = lib.getVersion realGrub;
|
||||
grubEfi = f grubEfi;
|
||||
grubTargetEfi = optionalString cfg.efiSupport (f (grubEfi.grubTarget or ""));
|
||||
grubTargetEfi = optionalString (cfg.efiSupport && (cfg.version == 2)) (f (grubEfi.grubTarget or ""));
|
||||
bootPath = args.path;
|
||||
storePath = config.boot.loader.grub.storePath;
|
||||
bootloaderId = if args.efiBootloaderId == null then "${config.system.nixos.distroName}${efiSysMountPoint'}" else args.efiBootloaderId;
|
||||
timeout = if config.boot.loader.timeout == null then -1 else config.boot.loader.timeout;
|
||||
users = if cfg.users == {} || cfg.version != 1 then cfg.users else throw "GRUB version 1 does not support user accounts.";
|
||||
theme = f cfg.theme;
|
||||
inherit efiSysMountPoint;
|
||||
inherit (args) devices;
|
||||
inherit (efi) canTouchEfiVariables;
|
||||
inherit (cfg)
|
||||
extraConfig extraPerEntryConfig extraEntries forceInstall useOSProber
|
||||
version extraConfig extraPerEntryConfig extraEntries forceInstall useOSProber
|
||||
extraGrubInstallArgs
|
||||
extraEntriesBeforeNixOS extraPrepareConfig configurationLimit copyKernels
|
||||
default fsIdentifier efiSupport efiInstallAsRemovable gfxmodeEfi gfxmodeBios gfxpayloadEfi gfxpayloadBios
|
||||
users;
|
||||
default fsIdentifier efiSupport efiInstallAsRemovable gfxmodeEfi gfxmodeBios gfxpayloadEfi gfxpayloadBios;
|
||||
path = with pkgs; makeBinPath (
|
||||
[ coreutils gnused gnugrep findutils diffutils btrfs-progs util-linux mdadm ]
|
||||
++ optional cfg.efiSupport efibootmgr
|
||||
++ optional (cfg.efiSupport && (cfg.version == 2)) efibootmgr
|
||||
++ optionals cfg.useOSProber [ busybox os-prober ]);
|
||||
font = if cfg.font == null then ""
|
||||
else (if lib.last (lib.splitString "." cfg.font) == "pf2"
|
||||
@@ -103,8 +109,14 @@ in
|
||||
};
|
||||
|
||||
version = mkOption {
|
||||
visible = false;
|
||||
default = 2;
|
||||
example = 1;
|
||||
type = types.int;
|
||||
description = lib.mdDoc ''
|
||||
The version of GRUB to use: `1` for GRUB
|
||||
Legacy (versions 0.9x), or `2` (the
|
||||
default) for GRUB 2.
|
||||
'';
|
||||
};
|
||||
|
||||
device = mkOption {
|
||||
@@ -670,6 +682,39 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
trustedBoot = {
|
||||
|
||||
enable = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = lib.mdDoc ''
|
||||
Enable trusted boot. GRUB will measure all critical components during
|
||||
the boot process to offer TCG (TPM) support.
|
||||
'';
|
||||
};
|
||||
|
||||
systemHasTPM = mkOption {
|
||||
default = "";
|
||||
example = "YES_TPM_is_activated";
|
||||
type = types.str;
|
||||
description = lib.mdDoc ''
|
||||
Assertion that the target system has an activated TPM. It is a safety
|
||||
check before allowing the activation of 'trustedBoot.enable'. TrustedBoot
|
||||
WILL FAIL TO BOOT YOUR SYSTEM if no TPM is available.
|
||||
'';
|
||||
};
|
||||
|
||||
isHPLaptop = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = lib.mdDoc ''
|
||||
Use a special version of TrustedGRUB that is needed by some HP laptops
|
||||
and works only for the HP laptops.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
@@ -679,7 +724,14 @@ in
|
||||
|
||||
config = mkMerge [
|
||||
|
||||
{ boot.loader.grub.splashImage = mkDefault defaultSplash; }
|
||||
{ boot.loader.grub.splashImage = mkDefault (
|
||||
if cfg.version == 1 then pkgs.fetchurl {
|
||||
url = "http://www.gnome-look.org/CONTENT/content-files/36909-soft-tux.xpm.gz";
|
||||
sha256 = "14kqdx2lfqvh40h6fjjzqgff1mwk74dmbjvmqphi6azzra7z8d59";
|
||||
}
|
||||
# GRUB 1.97 doesn't support gzipped XPMs.
|
||||
else defaultSplash);
|
||||
}
|
||||
|
||||
(mkIf (cfg.splashImage == defaultSplash) {
|
||||
boot.loader.grub.backgroundColor = mkDefault "#2F302F";
|
||||
@@ -736,6 +788,10 @@ in
|
||||
'') config.boot.loader.grub.extraFiles);
|
||||
|
||||
assertions = [
|
||||
{
|
||||
assertion = !cfg.zfsSupport || cfg.version == 2;
|
||||
message = "Only GRUB version 2 provides ZFS support";
|
||||
}
|
||||
{
|
||||
assertion = cfg.mirroredBoots != [ ];
|
||||
message = "You must set the option ‘boot.loader.grub.devices’ or "
|
||||
@@ -745,6 +801,22 @@ in
|
||||
assertion = cfg.efiSupport || all (c: c < 2) (mapAttrsToList (n: c: if n == "nodev" then 0 else c) bootDeviceCounters);
|
||||
message = "You cannot have duplicated devices in mirroredBoots";
|
||||
}
|
||||
{
|
||||
assertion = !cfg.trustedBoot.enable || cfg.version == 2;
|
||||
message = "Trusted GRUB is only available for GRUB 2";
|
||||
}
|
||||
{
|
||||
assertion = !cfg.efiSupport || !cfg.trustedBoot.enable;
|
||||
message = "Trusted GRUB does not have EFI support";
|
||||
}
|
||||
{
|
||||
assertion = !cfg.zfsSupport || !cfg.trustedBoot.enable;
|
||||
message = "Trusted GRUB does not have ZFS support";
|
||||
}
|
||||
{
|
||||
assertion = !cfg.trustedBoot.enable || cfg.trustedBoot.systemHasTPM == "YES_TPM_is_activated";
|
||||
message = "Trusted GRUB can break the system! Confirm that the system has an activated TPM by setting 'systemHasTPM'.";
|
||||
}
|
||||
{
|
||||
assertion = cfg.efiInstallAsRemovable -> cfg.efiSupport;
|
||||
message = "If you wish to to use boot.loader.grub.efiInstallAsRemovable, then turn on boot.loader.grub.efiSupport";
|
||||
@@ -753,10 +825,6 @@ in
|
||||
assertion = cfg.efiInstallAsRemovable -> !config.boot.loader.efi.canTouchEfiVariables;
|
||||
message = "If you wish to to use boot.loader.grub.efiInstallAsRemovable, then turn off boot.loader.efi.canTouchEfiVariables";
|
||||
}
|
||||
{
|
||||
assertion = !(options.boot.loader.grub.version.isDefined && cfg.version == 1);
|
||||
message = "Support for version 0.9x of GRUB was removed after being unsupported upstream for around a decade";
|
||||
}
|
||||
] ++ flip concatMap cfg.mirroredBoots (args: [
|
||||
{
|
||||
assertion = args.devices != [ ];
|
||||
@@ -776,11 +844,6 @@ in
|
||||
}));
|
||||
})
|
||||
|
||||
(mkIf options.boot.loader.grub.version.isDefined {
|
||||
warnings = [ ''
|
||||
The boot.loader.grub.version option does not have any effect anymore, please remove it from your configuration.
|
||||
'' ];
|
||||
})
|
||||
];
|
||||
|
||||
|
||||
@@ -792,10 +855,6 @@ in
|
||||
(mkRenamedOptionModule [ "boot" "grubDevice" ] [ "boot" "loader" "grub" "device" ])
|
||||
(mkRenamedOptionModule [ "boot" "bootMount" ] [ "boot" "loader" "grub" "bootDevice" ])
|
||||
(mkRenamedOptionModule [ "boot" "grubSplashImage" ] [ "boot" "loader" "grub" "splashImage" ])
|
||||
(mkRemovedOptionModule [ "boot" "loader" "grub" "trustedBoot" ] ''
|
||||
Support for Trusted GRUB has been removed, because the project
|
||||
has been retired upstream.
|
||||
'')
|
||||
(mkRemovedOptionModule [ "boot" "loader" "grub" "extraInitrd" ] ''
|
||||
This option has been replaced with the bootloader agnostic
|
||||
boot.initrd.secrets option. To migrate to the initrd secrets system,
|
||||
|
||||
@@ -61,6 +61,7 @@ sub runCommand {
|
||||
}
|
||||
|
||||
my $grub = get("grub");
|
||||
my $grubVersion = int(get("version"));
|
||||
my $grubTarget = get("grubTarget");
|
||||
my $extraConfig = get("extraConfig");
|
||||
my $extraPrepareConfig = get("extraPrepareConfig");
|
||||
@@ -95,7 +96,9 @@ my $theme = get("theme");
|
||||
my $saveDefault = $defaultEntry eq "saved";
|
||||
$ENV{'PATH'} = get("path");
|
||||
|
||||
print STDERR "updating GRUB 2 menu...\n";
|
||||
die "unsupported GRUB version\n" if $grubVersion != 1 && $grubVersion != 2;
|
||||
|
||||
print STDERR "updating GRUB $grubVersion menu...\n";
|
||||
|
||||
mkpath("$bootPath/grub", 0, 0700);
|
||||
|
||||
@@ -173,74 +176,76 @@ sub GrubFs {
|
||||
}
|
||||
my $search = "";
|
||||
|
||||
# ZFS is completely separate logic as zpools are always identified by a label
|
||||
# or custom UUID
|
||||
if ($fs->type eq 'zfs') {
|
||||
my $sid = index($fs->device, '/');
|
||||
if ($grubVersion > 1) {
|
||||
# ZFS is completely separate logic as zpools are always identified by a label
|
||||
# or custom UUID
|
||||
if ($fs->type eq 'zfs') {
|
||||
my $sid = index($fs->device, '/');
|
||||
|
||||
if ($sid < 0) {
|
||||
$search = '--label ' . $fs->device;
|
||||
$path = '/@' . $path;
|
||||
} else {
|
||||
$search = '--label ' . substr($fs->device, 0, $sid);
|
||||
$path = '/' . substr($fs->device, $sid) . '/@' . $path;
|
||||
}
|
||||
} else {
|
||||
my %types = ('uuid' => '--fs-uuid', 'label' => '--label');
|
||||
|
||||
if ($fsIdentifier eq 'provided') {
|
||||
# If the provided dev is identifying the partition using a label or uuid,
|
||||
# we should get the label / uuid and do a proper search
|
||||
my @matches = $fs->device =~ m/\/dev\/disk\/by-(label|uuid)\/(.*)/;
|
||||
if ($#matches > 1) {
|
||||
die "Too many matched devices"
|
||||
} elsif ($#matches == 1) {
|
||||
$search = "$types{$matches[0]} $matches[1]"
|
||||
if ($sid < 0) {
|
||||
$search = '--label ' . $fs->device;
|
||||
$path = '/@' . $path;
|
||||
} else {
|
||||
$search = '--label ' . substr($fs->device, 0, $sid);
|
||||
$path = '/' . substr($fs->device, $sid) . '/@' . $path;
|
||||
}
|
||||
} else {
|
||||
# Determine the identifying type
|
||||
$search = $types{$fsIdentifier} . ' ';
|
||||
my %types = ('uuid' => '--fs-uuid', 'label' => '--label');
|
||||
|
||||
# Based on the type pull in the identifier from the system
|
||||
my ($status, @devInfo) = runCommand("@utillinux@/bin/blkid", "-o", "export", @{[$fs->device]});
|
||||
if ($status != 0) {
|
||||
die "Failed to get blkid info (returned $status) for @{[$fs->mount]} on @{[$fs->device]}";
|
||||
}
|
||||
my @matches = join("", @devInfo) =~ m/@{[uc $fsIdentifier]}=([^\n]*)/;
|
||||
if ($#matches != 0) {
|
||||
die "Couldn't find a $types{$fsIdentifier} for @{[$fs->device]}\n"
|
||||
}
|
||||
$search .= $matches[0];
|
||||
}
|
||||
if ($fsIdentifier eq 'provided') {
|
||||
# If the provided dev is identifying the partition using a label or uuid,
|
||||
# we should get the label / uuid and do a proper search
|
||||
my @matches = $fs->device =~ m/\/dev\/disk\/by-(label|uuid)\/(.*)/;
|
||||
if ($#matches > 1) {
|
||||
die "Too many matched devices"
|
||||
} elsif ($#matches == 1) {
|
||||
$search = "$types{$matches[0]} $matches[1]"
|
||||
}
|
||||
} else {
|
||||
# Determine the identifying type
|
||||
$search = $types{$fsIdentifier} . ' ';
|
||||
|
||||
# BTRFS is a special case in that we need to fix the referrenced path based on subvolumes
|
||||
if ($fs->type eq 'btrfs') {
|
||||
my ($status, @id_info) = runCommand("@btrfsprogs@/bin/btrfs", "subvol", "show", @{[$fs->mount]});
|
||||
if ($status != 0) {
|
||||
die "Failed to retrieve subvolume info for @{[$fs->mount]}\n";
|
||||
}
|
||||
my @ids = join("\n", @id_info) =~ m/^(?!\/\n).*Subvolume ID:[ \t\n]*([0-9]+)/s;
|
||||
if ($#ids > 0) {
|
||||
die "Btrfs subvol name for @{[$fs->device]} listed multiple times in mount\n"
|
||||
} elsif ($#ids == 0) {
|
||||
my ($status, @path_info) = runCommand("@btrfsprogs@/bin/btrfs", "subvol", "list", @{[$fs->mount]});
|
||||
# Based on the type pull in the identifier from the system
|
||||
my ($status, @devInfo) = runCommand("@utillinux@/bin/blkid", "-o", "export", @{[$fs->device]});
|
||||
if ($status != 0) {
|
||||
die "Failed to find @{[$fs->mount]} subvolume id from btrfs\n";
|
||||
die "Failed to get blkid info (returned $status) for @{[$fs->mount]} on @{[$fs->device]}";
|
||||
}
|
||||
my @paths = join("", @path_info) =~ m/ID $ids[0] [^\n]* path ([^\n]*)/;
|
||||
if ($#paths > 0) {
|
||||
die "Btrfs returned multiple paths for a single subvolume id, mountpoint @{[$fs->mount]}\n";
|
||||
} elsif ($#paths != 0) {
|
||||
die "Btrfs did not return a path for the subvolume at @{[$fs->mount]}\n";
|
||||
my @matches = join("", @devInfo) =~ m/@{[uc $fsIdentifier]}=([^\n]*)/;
|
||||
if ($#matches != 0) {
|
||||
die "Couldn't find a $types{$fsIdentifier} for @{[$fs->device]}\n"
|
||||
}
|
||||
$search .= $matches[0];
|
||||
}
|
||||
|
||||
# BTRFS is a special case in that we need to fix the referrenced path based on subvolumes
|
||||
if ($fs->type eq 'btrfs') {
|
||||
my ($status, @id_info) = runCommand("@btrfsprogs@/bin/btrfs", "subvol", "show", @{[$fs->mount]});
|
||||
if ($status != 0) {
|
||||
die "Failed to retrieve subvolume info for @{[$fs->mount]}\n";
|
||||
}
|
||||
my @ids = join("\n", @id_info) =~ m/^(?!\/\n).*Subvolume ID:[ \t\n]*([0-9]+)/s;
|
||||
if ($#ids > 0) {
|
||||
die "Btrfs subvol name for @{[$fs->device]} listed multiple times in mount\n"
|
||||
} elsif ($#ids == 0) {
|
||||
my ($status, @path_info) = runCommand("@btrfsprogs@/bin/btrfs", "subvol", "list", @{[$fs->mount]});
|
||||
if ($status != 0) {
|
||||
die "Failed to find @{[$fs->mount]} subvolume id from btrfs\n";
|
||||
}
|
||||
my @paths = join("", @path_info) =~ m/ID $ids[0] [^\n]* path ([^\n]*)/;
|
||||
if ($#paths > 0) {
|
||||
die "Btrfs returned multiple paths for a single subvolume id, mountpoint @{[$fs->mount]}\n";
|
||||
} elsif ($#paths != 0) {
|
||||
die "Btrfs did not return a path for the subvolume at @{[$fs->mount]}\n";
|
||||
}
|
||||
$path = "/$paths[0]$path";
|
||||
}
|
||||
$path = "/$paths[0]$path";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (not $search eq "") {
|
||||
$search = "search --set=drive$driveid " . $search;
|
||||
$path = "(\$drive$driveid)$path";
|
||||
$driveid += 1;
|
||||
if (not $search eq "") {
|
||||
$search = "search --set=drive$driveid " . $search;
|
||||
$path = "(\$drive$driveid)$path";
|
||||
$driveid += 1;
|
||||
}
|
||||
}
|
||||
return Grub->new(path => $path, search => $search);
|
||||
}
|
||||
@@ -253,151 +258,166 @@ if ($copyKernels == 0) {
|
||||
# Generate the header.
|
||||
my $conf .= "# Automatically generated. DO NOT EDIT THIS FILE!\n";
|
||||
|
||||
my @users = ();
|
||||
foreach my $user ($dom->findnodes('/expr/attrs/attr[@name = "users"]/attrs/attr')) {
|
||||
my $name = $user->findvalue('@name') or die;
|
||||
my $hashedPassword = $user->findvalue('./attrs/attr[@name = "hashedPassword"]/string/@value');
|
||||
my $hashedPasswordFile = $user->findvalue('./attrs/attr[@name = "hashedPasswordFile"]/string/@value');
|
||||
my $password = $user->findvalue('./attrs/attr[@name = "password"]/string/@value');
|
||||
my $passwordFile = $user->findvalue('./attrs/attr[@name = "passwordFile"]/string/@value');
|
||||
|
||||
if ($hashedPasswordFile) {
|
||||
open(my $f, '<', $hashedPasswordFile) or die "Can't read file '$hashedPasswordFile'!";
|
||||
$hashedPassword = <$f>;
|
||||
chomp $hashedPassword;
|
||||
}
|
||||
if ($passwordFile) {
|
||||
open(my $f, '<', $passwordFile) or die "Can't read file '$passwordFile'!";
|
||||
$password = <$f>;
|
||||
chomp $password;
|
||||
if ($grubVersion == 1) {
|
||||
# $defaultEntry might be "saved", indicating that we want to use the last selected configuration as default.
|
||||
# Incidentally this is already the correct value for the grub 1 config to achieve this behaviour.
|
||||
$conf .= "
|
||||
default $defaultEntry
|
||||
timeout $timeout
|
||||
";
|
||||
if ($splashImage) {
|
||||
copy $splashImage, "$bootPath/background.xpm.gz" or die "cannot copy $splashImage to $bootPath: $!\n";
|
||||
$conf .= "splashimage " . ($grubBoot->path eq "/" ? "" : $grubBoot->path) . "/background.xpm.gz\n";
|
||||
}
|
||||
}
|
||||
|
||||
if ($hashedPassword) {
|
||||
if (index($hashedPassword, "grub.pbkdf2.") == 0) {
|
||||
$conf .= "\npassword_pbkdf2 $name $hashedPassword";
|
||||
else {
|
||||
my @users = ();
|
||||
foreach my $user ($dom->findnodes('/expr/attrs/attr[@name = "users"]/attrs/attr')) {
|
||||
my $name = $user->findvalue('@name') or die;
|
||||
my $hashedPassword = $user->findvalue('./attrs/attr[@name = "hashedPassword"]/string/@value');
|
||||
my $hashedPasswordFile = $user->findvalue('./attrs/attr[@name = "hashedPasswordFile"]/string/@value');
|
||||
my $password = $user->findvalue('./attrs/attr[@name = "password"]/string/@value');
|
||||
my $passwordFile = $user->findvalue('./attrs/attr[@name = "passwordFile"]/string/@value');
|
||||
|
||||
if ($hashedPasswordFile) {
|
||||
open(my $f, '<', $hashedPasswordFile) or die "Can't read file '$hashedPasswordFile'!";
|
||||
$hashedPassword = <$f>;
|
||||
chomp $hashedPassword;
|
||||
}
|
||||
if ($passwordFile) {
|
||||
open(my $f, '<', $passwordFile) or die "Can't read file '$passwordFile'!";
|
||||
$password = <$f>;
|
||||
chomp $password;
|
||||
}
|
||||
|
||||
if ($hashedPassword) {
|
||||
if (index($hashedPassword, "grub.pbkdf2.") == 0) {
|
||||
$conf .= "\npassword_pbkdf2 $name $hashedPassword";
|
||||
}
|
||||
else {
|
||||
die "Password hash for GRUB user '$name' is not valid!";
|
||||
}
|
||||
}
|
||||
elsif ($password) {
|
||||
$conf .= "\npassword $name $password";
|
||||
}
|
||||
else {
|
||||
die "Password hash for GRUB user '$name' is not valid!";
|
||||
die "GRUB user '$name' has no password!";
|
||||
}
|
||||
push(@users, $name);
|
||||
}
|
||||
elsif ($password) {
|
||||
$conf .= "\npassword $name $password";
|
||||
if (@users) {
|
||||
$conf .= "\nset superusers=\"" . join(' ',@users) . "\"\n";
|
||||
}
|
||||
else {
|
||||
die "GRUB user '$name' has no password!";
|
||||
}
|
||||
push(@users, $name);
|
||||
}
|
||||
if (@users) {
|
||||
$conf .= "\nset superusers=\"" . join(' ',@users) . "\"\n";
|
||||
}
|
||||
|
||||
if ($copyKernels == 0) {
|
||||
if ($copyKernels == 0) {
|
||||
$conf .= "
|
||||
" . $grubStore->search;
|
||||
}
|
||||
# FIXME: should use grub-mkconfig.
|
||||
my $defaultEntryText = $defaultEntry;
|
||||
if ($saveDefault) {
|
||||
$defaultEntryText = "\"\${saved_entry}\"";
|
||||
}
|
||||
$conf .= "
|
||||
" . $grubStore->search;
|
||||
}
|
||||
# FIXME: should use grub-mkconfig.
|
||||
my $defaultEntryText = $defaultEntry;
|
||||
if ($saveDefault) {
|
||||
$defaultEntryText = "\"\${saved_entry}\"";
|
||||
}
|
||||
$conf .= "
|
||||
" . $grubBoot->search . "
|
||||
if [ -s \$prefix/grubenv ]; then
|
||||
load_env
|
||||
fi
|
||||
|
||||
# ‘grub-reboot’ sets a one-time saved entry, which we process here and
|
||||
# then delete.
|
||||
if [ \"\${next_entry}\" ]; then
|
||||
set default=\"\${next_entry}\"
|
||||
set next_entry=
|
||||
save_env next_entry
|
||||
set timeout=1
|
||||
set boot_once=true
|
||||
else
|
||||
set default=$defaultEntryText
|
||||
set timeout=$timeout
|
||||
fi
|
||||
|
||||
function savedefault {
|
||||
if [ -z \"\${boot_once}\"]; then
|
||||
saved_entry=\"\${chosen}\"
|
||||
save_env saved_entry
|
||||
" . $grubBoot->search . "
|
||||
if [ -s \$prefix/grubenv ]; then
|
||||
load_env
|
||||
fi
|
||||
}
|
||||
|
||||
# Setup the graphics stack for bios and efi systems
|
||||
if [ \"\${grub_platform}\" = \"efi\" ]; then
|
||||
insmod efi_gop
|
||||
insmod efi_uga
|
||||
else
|
||||
insmod vbe
|
||||
fi
|
||||
";
|
||||
# ‘grub-reboot’ sets a one-time saved entry, which we process here and
|
||||
# then delete.
|
||||
if [ \"\${next_entry}\" ]; then
|
||||
set default=\"\${next_entry}\"
|
||||
set next_entry=
|
||||
save_env next_entry
|
||||
set timeout=1
|
||||
set boot_once=true
|
||||
else
|
||||
set default=$defaultEntryText
|
||||
set timeout=$timeout
|
||||
fi
|
||||
|
||||
if ($font) {
|
||||
copy $font, "$bootPath/converted-font.pf2" or die "cannot copy $font to $bootPath: $!\n";
|
||||
$conf .= "
|
||||
insmod font
|
||||
if loadfont " . ($grubBoot->path eq "/" ? "" : $grubBoot->path) . "/converted-font.pf2; then
|
||||
insmod gfxterm
|
||||
if [ \"\${grub_platform}\" = \"efi\" ]; then
|
||||
set gfxmode=$gfxmodeEfi
|
||||
set gfxpayload=$gfxpayloadEfi
|
||||
else
|
||||
set gfxmode=$gfxmodeBios
|
||||
set gfxpayload=$gfxpayloadBios
|
||||
fi
|
||||
terminal_output gfxterm
|
||||
function savedefault {
|
||||
if [ -z \"\${boot_once}\"]; then
|
||||
saved_entry=\"\${chosen}\"
|
||||
save_env saved_entry
|
||||
fi
|
||||
}
|
||||
|
||||
# Setup the graphics stack for bios and efi systems
|
||||
if [ \"\${grub_platform}\" = \"efi\" ]; then
|
||||
insmod efi_gop
|
||||
insmod efi_uga
|
||||
else
|
||||
insmod vbe
|
||||
fi
|
||||
";
|
||||
}
|
||||
if ($splashImage) {
|
||||
# Keeps the image's extension.
|
||||
my ($filename, $dirs, $suffix) = fileparse($splashImage, qr"\..[^.]*$");
|
||||
# The module for jpg is jpeg.
|
||||
if ($suffix eq ".jpg") {
|
||||
$suffix = ".jpeg";
|
||||
}
|
||||
if ($backgroundColor) {
|
||||
|
||||
if ($font) {
|
||||
copy $font, "$bootPath/converted-font.pf2" or die "cannot copy $font to $bootPath: $!\n";
|
||||
$conf .= "
|
||||
background_color '$backgroundColor'
|
||||
insmod font
|
||||
if loadfont " . ($grubBoot->path eq "/" ? "" : $grubBoot->path) . "/converted-font.pf2; then
|
||||
insmod gfxterm
|
||||
if [ \"\${grub_platform}\" = \"efi\" ]; then
|
||||
set gfxmode=$gfxmodeEfi
|
||||
set gfxpayload=$gfxpayloadEfi
|
||||
else
|
||||
set gfxmode=$gfxmodeBios
|
||||
set gfxpayload=$gfxpayloadBios
|
||||
fi
|
||||
terminal_output gfxterm
|
||||
fi
|
||||
";
|
||||
}
|
||||
copy $splashImage, "$bootPath/background$suffix" or die "cannot copy $splashImage to $bootPath: $!\n";
|
||||
$conf .= "
|
||||
insmod " . substr($suffix, 1) . "
|
||||
if background_image --mode '$splashMode' " . ($grubBoot->path eq "/" ? "" : $grubBoot->path) . "/background$suffix; then
|
||||
set color_normal=white/black
|
||||
set color_highlight=black/white
|
||||
else
|
||||
set menu_color_normal=cyan/blue
|
||||
set menu_color_highlight=white/blue
|
||||
fi
|
||||
";
|
||||
}
|
||||
|
||||
rmtree("$bootPath/theme") or die "cannot clean up theme folder in $bootPath\n" if -e "$bootPath/theme";
|
||||
|
||||
if ($theme) {
|
||||
# Copy theme
|
||||
rcopy($theme, "$bootPath/theme") or die "cannot copy $theme to $bootPath\n";
|
||||
$conf .= "
|
||||
# Sets theme.
|
||||
set theme=" . ($grubBoot->path eq "/" ? "" : $grubBoot->path) . "/theme/theme.txt
|
||||
export theme
|
||||
# Load theme fonts, if any
|
||||
";
|
||||
|
||||
find( { wanted => sub {
|
||||
if ($_ =~ /\.pf2$/i) {
|
||||
$font = File::Spec->abs2rel($File::Find::name, $theme);
|
||||
if ($splashImage) {
|
||||
# Keeps the image's extension.
|
||||
my ($filename, $dirs, $suffix) = fileparse($splashImage, qr"\..[^.]*$");
|
||||
# The module for jpg is jpeg.
|
||||
if ($suffix eq ".jpg") {
|
||||
$suffix = ".jpeg";
|
||||
}
|
||||
if ($backgroundColor) {
|
||||
$conf .= "
|
||||
loadfont " . ($grubBoot->path eq "/" ? "" : $grubBoot->path) . "/theme/$font
|
||||
background_color '$backgroundColor'
|
||||
";
|
||||
}
|
||||
}, no_chdir => 1 }, $theme );
|
||||
copy $splashImage, "$bootPath/background$suffix" or die "cannot copy $splashImage to $bootPath: $!\n";
|
||||
$conf .= "
|
||||
insmod " . substr($suffix, 1) . "
|
||||
if background_image --mode '$splashMode' " . ($grubBoot->path eq "/" ? "" : $grubBoot->path) . "/background$suffix; then
|
||||
set color_normal=white/black
|
||||
set color_highlight=black/white
|
||||
else
|
||||
set menu_color_normal=cyan/blue
|
||||
set menu_color_highlight=white/blue
|
||||
fi
|
||||
";
|
||||
}
|
||||
|
||||
rmtree("$bootPath/theme") or die "cannot clean up theme folder in $bootPath\n" if -e "$bootPath/theme";
|
||||
|
||||
if ($theme) {
|
||||
# Copy theme
|
||||
rcopy($theme, "$bootPath/theme") or die "cannot copy $theme to $bootPath\n";
|
||||
$conf .= "
|
||||
# Sets theme.
|
||||
set theme=" . ($grubBoot->path eq "/" ? "" : $grubBoot->path) . "/theme/theme.txt
|
||||
export theme
|
||||
# Load theme fonts, if any
|
||||
";
|
||||
|
||||
find( { wanted => sub {
|
||||
if ($_ =~ /\.pf2$/i) {
|
||||
$font = File::Spec->abs2rel($File::Find::name, $theme);
|
||||
$conf .= "
|
||||
loadfont " . ($grubBoot->path eq "/" ? "" : $grubBoot->path) . "/theme/$font
|
||||
";
|
||||
}
|
||||
}, no_chdir => 1 }, $theme );
|
||||
}
|
||||
}
|
||||
|
||||
$conf .= "$extraConfig\n";
|
||||
@@ -474,19 +494,31 @@ sub addEntry {
|
||||
readFile("$path/kernel-params");
|
||||
my $xenParams = $xen && -e "$path/xen-params" ? readFile("$path/xen-params") : "";
|
||||
|
||||
$conf .= "menuentry \"$name\" " . $options . " {\n";
|
||||
if ($saveDefault) {
|
||||
$conf .= " savedefault\n";
|
||||
if ($grubVersion == 1) {
|
||||
$conf .= "title $name\n";
|
||||
$conf .= " $extraPerEntryConfig\n" if $extraPerEntryConfig;
|
||||
$conf .= " kernel $xen $xenParams\n" if $xen;
|
||||
$conf .= " " . ($xen ? "module" : "kernel") . " $kernel $kernelParams\n";
|
||||
$conf .= " " . ($xen ? "module" : "initrd") . " $initrd\n";
|
||||
if ($saveDefault) {
|
||||
$conf .= " savedefault\n";
|
||||
}
|
||||
$conf .= "\n";
|
||||
} else {
|
||||
$conf .= "menuentry \"$name\" " . $options . " {\n";
|
||||
if ($saveDefault) {
|
||||
$conf .= " savedefault\n";
|
||||
}
|
||||
$conf .= $grubBoot->search . "\n";
|
||||
if ($copyKernels == 0) {
|
||||
$conf .= $grubStore->search . "\n";
|
||||
}
|
||||
$conf .= " $extraPerEntryConfig\n" if $extraPerEntryConfig;
|
||||
$conf .= " multiboot $xen $xenParams\n" if $xen;
|
||||
$conf .= " " . ($xen ? "module" : "linux") . " $kernel $kernelParams\n";
|
||||
$conf .= " " . ($xen ? "module" : "initrd") . " $initrd\n";
|
||||
$conf .= "}\n\n";
|
||||
}
|
||||
$conf .= $grubBoot->search . "\n";
|
||||
if ($copyKernels == 0) {
|
||||
$conf .= $grubStore->search . "\n";
|
||||
}
|
||||
$conf .= " $extraPerEntryConfig\n" if $extraPerEntryConfig;
|
||||
$conf .= " multiboot $xen $xenParams\n" if $xen;
|
||||
$conf .= " " . ($xen ? "module" : "linux") . " $kernel $kernelParams\n";
|
||||
$conf .= " " . ($xen ? "module" : "initrd") . " $initrd\n";
|
||||
$conf .= "}\n\n";
|
||||
}
|
||||
|
||||
|
||||
@@ -530,7 +562,7 @@ sub addProfile {
|
||||
my ($profile, $description) = @_;
|
||||
|
||||
# Add entries for all generations of this profile.
|
||||
$conf .= "submenu \"$description\" --class submenu {\n";
|
||||
$conf .= "submenu \"$description\" --class submenu {\n" if $grubVersion == 2;
|
||||
|
||||
sub nrFromGen { my ($x) = @_; $x =~ /\/\w+-(\d+)-link/; return $1; }
|
||||
|
||||
@@ -553,15 +585,17 @@ sub addProfile {
|
||||
addEntry("@distroName@ - Configuration " . nrFromGen($link) . " ($date - $version)", $link, $subEntryOptions, 0);
|
||||
}
|
||||
|
||||
$conf .= "}\n";
|
||||
$conf .= "}\n" if $grubVersion == 2;
|
||||
}
|
||||
|
||||
addProfile "/nix/var/nix/profiles/system", "@distroName@ - All configurations";
|
||||
|
||||
for my $profile (glob "/nix/var/nix/profiles/system-profiles/*") {
|
||||
my $name = basename($profile);
|
||||
next unless $name =~ /^\w+$/;
|
||||
addProfile $profile, "@distroName@ - Profile '$name'";
|
||||
if ($grubVersion == 2) {
|
||||
for my $profile (glob "/nix/var/nix/profiles/system-profiles/*") {
|
||||
my $name = basename($profile);
|
||||
next unless $name =~ /^\w+$/;
|
||||
addProfile $profile, "@distroName@ - Profile '$name'";
|
||||
}
|
||||
}
|
||||
|
||||
# extraPrepareConfig could refer to @bootPath@, which we have to substitute
|
||||
@@ -573,14 +607,16 @@ if ($extraPrepareConfig ne "") {
|
||||
}
|
||||
|
||||
# write the GRUB config.
|
||||
my $confFile = "$bootPath/grub/grub.cfg";
|
||||
my $confFile = $grubVersion == 1 ? "$bootPath/grub/menu.lst" : "$bootPath/grub/grub.cfg";
|
||||
my $tmpFile = $confFile . ".tmp";
|
||||
writeFile($tmpFile, $conf);
|
||||
|
||||
|
||||
# check whether to install GRUB EFI or not
|
||||
sub getEfiTarget {
|
||||
if (($grub ne "") && ($grubEfi ne "")) {
|
||||
if ($grubVersion == 1) {
|
||||
return "no"
|
||||
} elsif (($grub ne "") && ($grubEfi ne "")) {
|
||||
# EFI can only be installed when target is set;
|
||||
# A target is also required then for non-EFI grub
|
||||
if (($grubTarget eq "") || ($grubTargetEfi eq "")) { die }
|
||||
@@ -705,7 +741,7 @@ symlink "$bootPath", "$tmpDir/boot" or die "Failed to symlink $tmpDir/boot: $!";
|
||||
if (($requireNewInstall != 0) && ($efiTarget eq "no" || $efiTarget eq "both")) {
|
||||
foreach my $dev (@deviceTargets) {
|
||||
next if $dev eq "nodev";
|
||||
print STDERR "installing the GRUB 2 boot loader on $dev...\n";
|
||||
print STDERR "installing the GRUB $grubVersion boot loader on $dev...\n";
|
||||
my @command = ("$grub/sbin/grub-install", "--recheck", "--root-directory=$tmpDir", Cwd::abs_path($dev), @extraGrubInstallArgs);
|
||||
if ($forceInstall eq "true") {
|
||||
push @command, "--force";
|
||||
@@ -720,7 +756,7 @@ if (($requireNewInstall != 0) && ($efiTarget eq "no" || $efiTarget eq "both")) {
|
||||
|
||||
# install EFI GRUB
|
||||
if (($requireNewInstall != 0) && ($efiTarget eq "only" || $efiTarget eq "both")) {
|
||||
print STDERR "installing the GRUB 2 boot loader into $efiSysMountPoint...\n";
|
||||
print STDERR "installing the GRUB $grubVersion EFI boot loader into $efiSysMountPoint...\n";
|
||||
my @command = ("$grubEfi/sbin/grub-install", "--recheck", "--target=$grubTargetEfi", "--boot-directory=$bootPath", "--efi-directory=$efiSysMountPoint", @extraGrubInstallArgs);
|
||||
if ($forceInstall eq "true") {
|
||||
push @command, "--force";
|
||||
|
||||
@@ -46,7 +46,11 @@ in
|
||||
|
||||
config = mkIf (builtins.length scripts != 0) {
|
||||
|
||||
boot.loader.grub.extraEntries = toString (map grubEntry scripts);
|
||||
boot.loader.grub.extraEntries =
|
||||
if config.boot.loader.grub.version == 2 then
|
||||
toString (map grubEntry scripts)
|
||||
else
|
||||
throw "iPXE is not supported with GRUB 1.";
|
||||
|
||||
boot.loader.grub.extraFiles =
|
||||
{ "ipxe.lkrn" = "${pkgs.ipxe}/ipxe.lkrn"; }
|
||||
|
||||
@@ -84,11 +84,15 @@ in
|
||||
})
|
||||
|
||||
(mkIf (cfg.enable && !efiSupport) {
|
||||
boot.loader.grub.extraEntries = ''
|
||||
menuentry "Memtest86+" {
|
||||
linux16 @bootRoot@/memtest.bin ${toString cfg.params}
|
||||
}
|
||||
'';
|
||||
boot.loader.grub.extraEntries =
|
||||
if config.boot.loader.grub.version == 2 then
|
||||
''
|
||||
menuentry "Memtest86+" {
|
||||
linux16 @bootRoot@/memtest.bin ${toString cfg.params}
|
||||
}
|
||||
''
|
||||
else
|
||||
throw "Memtest86+ is not supported with GRUB 1.";
|
||||
|
||||
boot.loader.grub.extraFiles."memtest.bin" = "${memtest86}/memtest.bin";
|
||||
})
|
||||
|
||||
@@ -70,9 +70,6 @@ let
|
||||
"CombinedChannels"
|
||||
"RxBufferSize"
|
||||
"TxBufferSize"
|
||||
"ReceiveQueues"
|
||||
"TransmitQueues"
|
||||
"TransmitQueueLength"
|
||||
])
|
||||
(assertValueOneOf "MACAddressPolicy" ["persistent" "random" "none"])
|
||||
(assertMacAddress "MACAddress")
|
||||
@@ -99,9 +96,6 @@ let
|
||||
(assertRange "CombinedChannels" 1 4294967295)
|
||||
(assertInt "RxBufferSize")
|
||||
(assertInt "TxBufferSize")
|
||||
(assertRange "ReceiveQueues" 1 4096)
|
||||
(assertRange "TransmitQueues" 1 4096)
|
||||
(assertRange "TransmitQueueLength" 1 4294967294)
|
||||
];
|
||||
};
|
||||
|
||||
@@ -2848,7 +2842,7 @@ let
|
||||
''
|
||||
+ optionalString (def.tokenBucketFilterConfig != { }) ''
|
||||
[TokenBucketFilter]
|
||||
${attrsToSection def.tokenBucketFilterConfig}
|
||||
${attrsToSection def.tockenBucketFilterConfig}
|
||||
''
|
||||
+ optionalString (def.pieConfig != { }) ''
|
||||
[PIE]
|
||||
|
||||
@@ -293,9 +293,6 @@ checkFS() {
|
||||
# Skip fsck for inherently readonly filesystems.
|
||||
if [ "$fsType" = squashfs ]; then return 0; fi
|
||||
|
||||
# Skip fsck.erofs because it is still experimental.
|
||||
if [ "$fsType" = erofs ]; then return 0; fi
|
||||
|
||||
# If we couldn't figure out the FS type, then skip fsck.
|
||||
if [ "$fsType" = auto ]; then
|
||||
echo 'cannot check filesystem with type "auto"!'
|
||||
|
||||
@@ -72,6 +72,11 @@ in
|
||||
};
|
||||
|
||||
config = lib.mkIf (cfg.enable || initrdCfg.enable) {
|
||||
# Always link the definitions into /etc so that they are also included in
|
||||
# the /nix/store of the sysroot during early userspace (i.e. while in the
|
||||
# initrd).
|
||||
environment.etc."repart.d".source = definitionsDirectory;
|
||||
|
||||
boot.initrd.systemd = lib.mkIf initrdCfg.enable {
|
||||
additionalUpstreamUnits = [
|
||||
"systemd-repart.service"
|
||||
@@ -81,40 +86,33 @@ in
|
||||
"${config.boot.initrd.systemd.package}/bin/systemd-repart"
|
||||
];
|
||||
|
||||
contents."/etc/repart.d".source = definitionsDirectory;
|
||||
|
||||
# Override defaults in upstream unit.
|
||||
services.systemd-repart = {
|
||||
# systemd-repart tries to create directories in /var/tmp by default to
|
||||
# store large temporary files that benefit from persistence on disk. In
|
||||
# the initrd, however, /var/tmp does not provide more persistence than
|
||||
# /tmp, so we re-use it here.
|
||||
environment."TMPDIR" = "/tmp";
|
||||
# Unset the conditions as they cannot be met before activation because
|
||||
# the definition files are not stored in the expected locations.
|
||||
unitConfig.ConditionDirectoryNotEmpty = [
|
||||
" " # required to unset the previous value.
|
||||
];
|
||||
serviceConfig = {
|
||||
# systemd-repart runs before the activation script. Thus we cannot
|
||||
# rely on them being linked in /etc already. Instead we have to
|
||||
# explicitly pass their location in the sysroot to the binary.
|
||||
ExecStart = [
|
||||
" " # required to unset the previous value.
|
||||
# When running in the initrd, systemd-repart by default searches
|
||||
# for definition files in /sysroot or /sysusr. We tell it to look
|
||||
# in the initrd itself.
|
||||
''${config.boot.initrd.systemd.package}/bin/systemd-repart \
|
||||
--definitions=/etc/repart.d \
|
||||
--definitions=/sysroot${definitionsDirectory} \
|
||||
--dry-run=no
|
||||
''
|
||||
];
|
||||
};
|
||||
# systemd-repart needs to run after /sysroot (or /sysuser, but we don't
|
||||
# have it) has been mounted because otherwise it cannot determine the
|
||||
# device (i.e disk) to operate on. If you want to run systemd-repart
|
||||
# without /sysroot, you have to explicitly tell it which device to
|
||||
# operate on.
|
||||
# Because the initrd does not have the `initrd-usr-fs.target` the
|
||||
# upestream unit runs too early in the boot process, before the sysroot
|
||||
# is available. However, systemd-repart needs access to the sysroot to
|
||||
# find the definition files.
|
||||
after = [ "sysroot.mount" ];
|
||||
};
|
||||
};
|
||||
|
||||
environment.etc = lib.mkIf cfg.enable {
|
||||
"repart.d".source = definitionsDirectory;
|
||||
};
|
||||
|
||||
systemd = lib.mkIf cfg.enable {
|
||||
additionalUpstreamSystemUnits = [
|
||||
"systemd-repart.service"
|
||||
@@ -122,5 +120,4 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
meta.maintainers = with lib.maintainers; [ nikstur ];
|
||||
}
|
||||
|
||||
@@ -12,13 +12,12 @@ let
|
||||
ln -s ${config.environment.usrbinenv} $out/env
|
||||
ln -s ${config.environment.binsh} $out/sh
|
||||
'' + cfg.extraFallbackPathCommands)}"
|
||||
"nofail"
|
||||
];
|
||||
};
|
||||
"/bin" = {
|
||||
device = "/usr/bin";
|
||||
fsType = "none";
|
||||
options = [ "bind" "nofail" ];
|
||||
options = [ "bind" ];
|
||||
};
|
||||
};
|
||||
in {
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
|
||||
inInitrd = lib.any (fs: fs == "erofs") config.boot.initrd.supportedFilesystems;
|
||||
inSystem = lib.any (fs: fs == "erofs") config.boot.supportedFilesystems;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
config = lib.mkIf (inInitrd || inSystem) {
|
||||
|
||||
system.fsPackages = [ pkgs.erofs-utils ];
|
||||
|
||||
boot.initrd.availableKernelModules = lib.mkIf inInitrd [ "erofs" ];
|
||||
|
||||
# fsck.erofs is currently experimental and should not be run as a
|
||||
# privileged user. Thus, it is not included in the initrd.
|
||||
|
||||
};
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user