Compare commits

..

14 Commits

Author SHA1 Message Date
Robert Hensing
e54227b0df Revert "nixosTests: Resolve alias kgx = gnome-console"
This reverts commit a486968a6e.
2023-05-11 15:07:45 +02:00
Robert Hensing
ad048019ad Revert "nixosTests: Resolve use of trivial aliases"
This reverts commit 7e2d8c4ace.
2023-05-11 15:07:42 +02:00
Robert Hensing
20ed39a036 Revert "linuxKernel.packages.linux_stable: init as reference"
This reverts commit 936309cb9b.
2023-05-11 15:07:37 +02:00
Robert Hensing
95e249772f Revert "nixos/release.nix: Pass a pkgs without aliases to tests"
We don't have a good way of adding `allowAliases = false` to an existing
`pkgs`, which means that we can't enable this on `nixosTests.*` because
that would break coherence between `pkgs` as in literally `pkgs.nixosTest`
and the `pkgs` module argument that is available there.

Having a discrepancy between the two means that neither OfBorg nor users
will catch the eval errors that makes tests effectively disappear from
Hydra. This is a Hydra UX issue, not a nixpkgs issue but a blocker
nonetheless.

This reverts commit 2d0a47236d.
2023-05-11 15:02:47 +02:00
Robert Hensing
936309cb9b linuxKernel.packages.linux_stable: init as reference
Or call it an alias, although that has the wrong connotation,
from aliases.nix. This alias is not deprecated.
2023-05-10 20:43:09 +02:00
Robert Hensing
7e2d8c4ace nixosTests: Resolve use of trivial aliases 2023-05-10 18:26:36 +02:00
Robert Hensing
a486968a6e nixosTests: Resolve alias kgx = gnome-console 2023-05-10 18:14:50 +02:00
Robert Hensing
9edbbf1633 nixos/all-tests: Enable readOnlyPkgs by default for runTest
Most tests are not affected by this because they use the `handleTest`
function instead.
2023-05-10 15:57:15 +02:00
Robert Hensing
5400041d4a nixos/testing/nodes.nix: Do not rely on disabledModules
It's just not necessary.
2023-05-10 15:55:10 +02:00
Robert Hensing
ae64e1b4cf nixos/testing: Add node.pkgsReadOnly escape hatch
By adding this option indirection, a test can declare all by itself
that it needs a custom nixpkgs. This is a more convenient way of
going about this when the caller of the test framework receives a
`node.pkgs` unconditionally.
2023-05-10 15:55:10 +02:00
Robert Hensing
7a32a2eb7d nixos/testing: Add node.pkgs option
By factoring out this logic, it's easier for other projects to make
use of it this optimization too (and do it correctly).
2023-05-10 15:55:10 +02:00
Robert Hensing
4f21de5214 nixosTests.acme: Use a read-only pkgs
This speeds up evaluation by a factor 2.

Ballpark figures from my machine:

```
$ time nix-build nixos/release.nix -A tests.acme
/nix/store/q4fxp55k64clcarsx8xc8f6s10szlfvz-vm-test-run-acme
/nix/store/lnfqg051sxx05hclva84bcbnjfc71c8x-vm-test-run-acme

real    1m28.142s
user    1m7.474s
sys     0m7.932s

$ time nix-build nixos/release.nix -A tests.acme
/nix/store/q4fxp55k64clcarsx8xc8f6s10szlfvz-vm-test-run-acme
/nix/store/lnfqg051sxx05hclva84bcbnjfc71c8x-vm-test-run-acme

real    0m38.235s
user    0m33.814s
sys     0m2.283s

```
2023-05-10 15:55:10 +02:00
Robert Hensing
35068dc47f nixos/all-tests.nix: Add readOnlyPkgs module 2023-05-10 15:55:09 +02:00
Robert Hensing
2d0a47236d nixos/release.nix: Pass a pkgs without aliases to tests
The tests currently only use it for support packages such as qemu, but
by changing this, the `pkgs` argument becomes suitable for use as the
`pkgs` argument in NixOS. Using a single Nixpkgs improves performance.
2023-05-10 15:55:09 +02:00
1882 changed files with 78545 additions and 86481 deletions

39
.github/CODEOWNERS vendored
View File

@@ -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

View File

@@ -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.

View File

@@ -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; };

View File

@@ -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=";
}
```

View File

@@ -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" />

View File

@@ -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
'';

View File

@@ -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
]);
# ...
}

View File

@@ -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";

View File

@@ -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)
);
}

View File

@@ -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.

View File

@@ -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";

View File

@@ -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";

View File

@@ -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

View File

@@ -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..."

View File

@@ -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

View File

@@ -151,7 +151,6 @@ with lib.maintainers; {
cuda = {
members = [
connorbaker
SomeoneSerge
];
scope = "Maintain CUDA-enabled packages";

View File

@@ -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.

View File

@@ -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;`.

View File

@@ -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}
'';

View File

@@ -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}

View File

@@ -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

View File

@@ -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:

View File

@@ -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" \
'{}

View File

@@ -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" \
'{}

View File

@@ -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;

View File

@@ -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 Sanitizers CombinedAllocator,
which aims at providing additional mitigations against heap based

View File

@@ -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': {

View File

@@ -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}
''}
'';

View File

@@ -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;

View File

@@ -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;
};

View File

@@ -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";

View File

@@ -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

View File

@@ -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;
};
};
}

View File

@@ -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 ];
}

View File

@@ -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.

View File

@@ -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));

View File

@@ -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:

View File

@@ -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 ];
}

View File

@@ -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 ];
}

View File

@@ -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" ];
};

View File

@@ -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,

View File

@@ -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

View File

@@ -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: ''

View File

@@ -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

View File

@@ -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 ];
}

View File

@@ -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"; };
};
};

View File

@@ -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;
};

View File

@@ -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;
};
};

View File

@@ -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;
};
}

View File

@@ -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";

View File

@@ -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
''}
'';
};

View File

@@ -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";
};
};

View File

@@ -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.";
};

View File

@@ -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";

View File

@@ -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 ""}

View File

@@ -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";

View File

@@ -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;

View File

@@ -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" ];

View File

@@ -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 ''

View File

@@ -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 ];
}

View File

@@ -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);
});
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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 = {

View File

@@ -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"

View File

@@ -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"
];
};
};
};
};
}

View File

@@ -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"
];
};
};
};
};
}

View File

@@ -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;
};
};
};
}

View File

@@ -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

View File

@@ -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}
'';
};

View File

@@ -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 ];
});
}

View File

@@ -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.
'';

View File

@@ -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";
};
};
}
];
};
};
}

View File

@@ -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}

View File

@@ -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" ];
})
];
};
}

View File

@@ -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";

View 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} = {

View File

@@ -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" ];})
];

View File

@@ -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 = {

View File

@@ -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};
'';
}
];
};
};
}

View File

@@ -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";

View File

@@ -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;
'';

View File

@@ -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";
};
};
};

View File

@@ -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 {

View File

@@ -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 = ''

View File

@@ -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)
'')

View File

@@ -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 ]";
};

View File

@@ -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";
};

View File

@@ -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;

View File

@@ -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;
};

View File

@@ -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,

View File

@@ -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";

View File

@@ -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"; }

View File

@@ -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";
})

View File

@@ -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]

View File

@@ -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"!'

View File

@@ -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 ];
}

View File

@@ -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 {

View File

@@ -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