Project import generated by Copybara.
GitOrigin-RevId: 5aaed40d22f0d9376330b6fa413223435ad6fee5
This commit is contained in:
parent
f3d86dbf9e
commit
14910f5943
1370 changed files with 40878 additions and 19782 deletions
27
third_party/nixpkgs/.github/CODEOWNERS
vendored
27
third_party/nixpkgs/.github/CODEOWNERS
vendored
|
@ -141,6 +141,15 @@
|
|||
/pkgs/development/tools/build-managers/rebar3 @gleber
|
||||
/pkgs/development/tools/erlang @gleber
|
||||
|
||||
# Audio
|
||||
/nixos/modules/services/audio/botamusique.nix @mweinelt
|
||||
/nixos/modules/services/audio/snapserver.nix @mweinelt
|
||||
/nixos/tests/modules/services/audio/botamusique.nix @mweinelt
|
||||
/nixos/tests/snapcast.nix @mweinelt
|
||||
|
||||
# Browsers
|
||||
/pkgs/applications/networking/browsers/firefox @mweinelt
|
||||
|
||||
# Jetbrains
|
||||
/pkgs/applications/editors/jetbrains @edwtjo
|
||||
|
||||
|
@ -167,12 +176,30 @@
|
|||
/nixos/tests/hardened.nix @joachifm
|
||||
/pkgs/os-specific/linux/kernel/hardened-config.nix @joachifm
|
||||
|
||||
# Home Automation
|
||||
/nixos/modules/services/misc/home-assistant.nix @mweinelt
|
||||
/nixos/modules/services/misc/zigbee2mqtt.nix @mweinelt
|
||||
/nixos/tests/home-assistant.nix @mweinelt
|
||||
/nixos/tests/zigbee2mqtt.nix @mweinelt
|
||||
/pkgs/servers/home-assistant @mweinelt
|
||||
/pkgs/tools/misc/esphome @mweinelt
|
||||
|
||||
# Network Time Daemons
|
||||
/pkgs/tools/networking/chrony @thoughtpolice
|
||||
/pkgs/tools/networking/ntp @thoughtpolice
|
||||
/pkgs/tools/networking/openntpd @thoughtpolice
|
||||
/nixos/modules/services/networking/ntp @thoughtpolice
|
||||
|
||||
# Network
|
||||
/pkgs/tools/networking/kea/default.nix @mweinelt
|
||||
/pkgs/tools/networking/babeld/default.nix @mweinelt
|
||||
/nixos/modules/services/networking/babeld.nix @mweinelt
|
||||
/nixos/modules/services/networking/kea.nix @mweinelt
|
||||
/nixos/modules/services/networking/knot.nix @mweinelt
|
||||
/nixos/tests/babeld.nix @mweinelt
|
||||
/nixos/tests/kea.nix @mweinelt
|
||||
/nixos/tests/knot.nix @mweinelt
|
||||
|
||||
# Dhall
|
||||
/pkgs/development/dhall-modules @Gabriel439 @Profpatsch @ehmry
|
||||
/pkgs/development/interpreters/dhall @Gabriel439 @Profpatsch @ehmry
|
||||
|
|
6
third_party/nixpkgs/CONTRIBUTING.md
vendored
6
third_party/nixpkgs/CONTRIBUTING.md
vendored
|
@ -11,6 +11,10 @@ under the terms of [COPYING](COPYING), which is an MIT-like license.
|
|||
|
||||
## Submitting changes
|
||||
|
||||
Read the ["Submitting changes"](https://nixos.org/nixpkgs/manual/#chap-submitting-changes) section of the nixpkgs manual. It explains how to write, test, and iterate on your change, and which branch to base your pull request against.
|
||||
|
||||
Below is a short excerpt of some points in there:
|
||||
|
||||
* Format the commit messages in the following way:
|
||||
|
||||
```
|
||||
|
@ -40,7 +44,7 @@ under the terms of [COPYING](COPYING), which is an MIT-like license.
|
|||
* If there is no upstream license, `meta.license` should default to `lib.licenses.unfree`.
|
||||
* `meta.maintainers` must be set.
|
||||
|
||||
See the nixpkgs manual for more details on [standard meta-attributes](https://nixos.org/nixpkgs/manual/#sec-standard-meta-attributes) and on how to [submit changes to nixpkgs](https://nixos.org/nixpkgs/manual/#chap-submitting-changes).
|
||||
See the nixpkgs manual for more details on [standard meta-attributes](https://nixos.org/nixpkgs/manual/#sec-standard-meta-attributes).
|
||||
|
||||
## Writing good commit messages
|
||||
|
||||
|
|
2
third_party/nixpkgs/COPYING
vendored
2
third_party/nixpkgs/COPYING
vendored
|
@ -1,4 +1,4 @@
|
|||
Copyright (c) 2003-2021 Eelco Dolstra and the Nixpkgs/NixOS contributors
|
||||
Copyright (c) 2003-2022 Eelco Dolstra and the Nixpkgs/NixOS contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
|
|
@ -1,17 +1,37 @@
|
|||
# pkgs.mkShell {#sec-pkgs-mkShell}
|
||||
|
||||
`pkgs.mkShell` is a special kind of derivation that is only useful when using
|
||||
it combined with `nix-shell`. It will in fact fail to instantiate when invoked
|
||||
with `nix-build`.
|
||||
`pkgs.mkShell` is a specialized `stdenv.mkDerivation` that removes some
|
||||
repetition when using it with `nix-shell` (or `nix develop`).
|
||||
|
||||
## Usage {#sec-pkgs-mkShell-usage}
|
||||
|
||||
Here is a common usage example:
|
||||
|
||||
```nix
|
||||
{ pkgs ? import <nixpkgs> {} }:
|
||||
pkgs.mkShell {
|
||||
# specify which packages to add to the shell environment
|
||||
packages = [ pkgs.gnumake ];
|
||||
# add all the dependencies, of the given packages, to the shell environment
|
||||
inputsFrom = with pkgs; [ hello gnutar ];
|
||||
|
||||
inputsFrom = [ pkgs.hello pkgs.gnutar ];
|
||||
|
||||
shellHook = ''
|
||||
export DEBUG=1
|
||||
'';
|
||||
}
|
||||
```
|
||||
|
||||
## Attributes
|
||||
|
||||
* `name` (default: `nix-shell`). Set the name of the derivation.
|
||||
* `packages` (default: `[]`). Add executable packages to the `nix-shell` environment.
|
||||
* `inputsFrom` (default: `[]`). Add build dependencies of the listed derivations to the `nix-shell` environment.
|
||||
* `shellHook` (default: `""`). Bash statements that are executed by `nix-shell`.
|
||||
|
||||
... all the attributes of `stdenv.mkDerivation`.
|
||||
|
||||
## Building the shell
|
||||
|
||||
This derivation output will contain a text file that contains a reference to
|
||||
all the build inputs. This is useful in CI where we want to make sure that
|
||||
every derivation, and its dependencies, build properly. Or when creating a GC
|
||||
root so that the build dependencies don't get garbage-collected.
|
||||
|
|
|
@ -47,6 +47,88 @@ These functions write `text` to the Nix store. This is useful for creating scrip
|
|||
|
||||
Many more commands wrap `writeTextFile` including `writeText`, `writeTextDir`, `writeScript`, and `writeScriptBin`. These are convenience functions over `writeTextFile`.
|
||||
|
||||
Here are a few examples:
|
||||
```nix
|
||||
# Writes my-file to /nix/store/<store path>
|
||||
writeTextFile {
|
||||
name = "my-file";
|
||||
text = ''
|
||||
Contents of File
|
||||
'';
|
||||
}
|
||||
# See also the `writeText` helper function below.
|
||||
|
||||
# Writes executable my-file to /nix/store/<store path>/bin/my-file
|
||||
writeTextFile {
|
||||
name = "my-file";
|
||||
text = ''
|
||||
Contents of File
|
||||
'';
|
||||
executable = true;
|
||||
destination = "/bin/my-file";
|
||||
}
|
||||
# Writes contents of file to /nix/store/<store path>
|
||||
writeText "my-file"
|
||||
''
|
||||
Contents of File
|
||||
'';
|
||||
# Writes contents of file to /nix/store/<store path>/share/my-file
|
||||
writeTextDir "share/my-file"
|
||||
''
|
||||
Contents of File
|
||||
'';
|
||||
# Writes my-file to /nix/store/<store path> and makes executable
|
||||
writeScript "my-file"
|
||||
''
|
||||
Contents of File
|
||||
'';
|
||||
# Writes my-file to /nix/store/<store path>/bin/my-file and makes executable.
|
||||
writeScriptBin "my-file"
|
||||
''
|
||||
Contents of File
|
||||
'';
|
||||
# Writes my-file to /nix/store/<store path> and makes executable.
|
||||
writeShellScript "my-file"
|
||||
''
|
||||
Contents of File
|
||||
'';
|
||||
# Writes my-file to /nix/store/<store path>/bin/my-file and makes executable.
|
||||
writeShellScriptBin "my-file"
|
||||
''
|
||||
Contents of File
|
||||
'';
|
||||
|
||||
```
|
||||
|
||||
## `concatTextFile`, `concatText`, `concatScript` {#trivial-builder-concatText}
|
||||
|
||||
These functions concatenate `files` to the Nix store in a single file. This is useful for configuration files structured in lines of text. `concatTextFile` takes an attribute set and expects two arguments, `name` and `files`. `name` corresponds to the name used in the Nix store path. `files` will be the files to be concatenated. You can also set `executable` to true to make this file have the executable bit set.
|
||||
`concatText` and`concatScript` are simple wrappers over `concatTextFile`.
|
||||
|
||||
Here are a few examples:
|
||||
```nix
|
||||
|
||||
# Writes my-file to /nix/store/<store path>
|
||||
concatTextFile {
|
||||
name = "my-file";
|
||||
files = [ drv1 "${drv2}/path/to/file" ];
|
||||
}
|
||||
# See also the `concatText` helper function below.
|
||||
|
||||
# Writes executable my-file to /nix/store/<store path>/bin/my-file
|
||||
concatTextFile {
|
||||
name = "my-file";
|
||||
files = [ drv1 "${drv2}/path/to/file" ];
|
||||
executable = true;
|
||||
destination = "/bin/my-file";
|
||||
}
|
||||
# Writes contents of files to /nix/store/<store path>
|
||||
concatText "my-file" [ file1 file2 ]
|
||||
|
||||
# Writes contents of files to /nix/store/<store path>
|
||||
concatScript "my-file" [ file1 file2 ]
|
||||
```
|
||||
|
||||
## `writeShellApplication` {#trivial-builder-writeShellApplication}
|
||||
|
||||
This can be used to easily produce a shell script that has some dependencies (`runtimeInputs`). It automatically sets the `PATH` of the script to contain all of the listed inputs, sets some sanity shellopts (`errexit`, `nounset`, `pipefail`), and checks the resulting script with [`shellcheck`](https://github.com/koalaman/shellcheck).
|
||||
|
@ -72,6 +154,26 @@ validation.
|
|||
## `symlinkJoin` {#trivial-builder-symlinkJoin}
|
||||
|
||||
This can be used to put many derivations into the same directory structure. It works by creating a new derivation and adding symlinks to each of the paths listed. It expects two arguments, `name`, and `paths`. `name` is the name used in the Nix store path for the created derivation. `paths` is a list of paths that will be symlinked. These paths can be to Nix store derivations or any other subdirectory contained within.
|
||||
Here is an example:
|
||||
```nix
|
||||
# adds symlinks of hello and stack to current build and prints "links added"
|
||||
symlinkJoin { name = "myexample"; paths = [ pkgs.hello pkgs.stack ]; postBuild = "echo links added"; }
|
||||
```
|
||||
This creates a derivation with a directory structure like the following:
|
||||
```
|
||||
/nix/store/sglsr5g079a5235hy29da3mq3hv8sjmm-myexample
|
||||
|-- bin
|
||||
| |-- hello -> /nix/store/qy93dp4a3rqyn2mz63fbxjg228hffwyw-hello-2.10/bin/hello
|
||||
| `-- stack -> /nix/store/6lzdpxshx78281vy056lbk553ijsdr44-stack-2.1.3.1/bin/stack
|
||||
`-- share
|
||||
|-- bash-completion
|
||||
| `-- completions
|
||||
| `-- stack -> /nix/store/6lzdpxshx78281vy056lbk553ijsdr44-stack-2.1.3.1/share/bash-completion/completions/stack
|
||||
|-- fish
|
||||
| `-- vendor_completions.d
|
||||
| `-- stack.fish -> /nix/store/6lzdpxshx78281vy056lbk553ijsdr44-stack-2.1.3.1/share/fish/vendor_completions.d/stack.fish
|
||||
...
|
||||
```
|
||||
|
||||
## `writeReferencesToFile` {#trivial-builder-writeReferencesToFile}
|
||||
|
||||
|
|
32
third_party/nixpkgs/lib/attrsets.nix
vendored
32
third_party/nixpkgs/lib/attrsets.nix
vendored
|
@ -3,9 +3,9 @@
|
|||
|
||||
let
|
||||
inherit (builtins) head tail length;
|
||||
inherit (lib.trivial) and;
|
||||
inherit (lib.trivial) id;
|
||||
inherit (lib.strings) concatStringsSep sanitizeDerivationName;
|
||||
inherit (lib.lists) foldr foldl' concatMap concatLists elemAt;
|
||||
inherit (lib.lists) foldr foldl' concatMap concatLists elemAt all;
|
||||
in
|
||||
|
||||
rec {
|
||||
|
@ -73,9 +73,9 @@ rec {
|
|||
getAttrFromPath ["z" "z"] x
|
||||
=> error: cannot find attribute `z.z'
|
||||
*/
|
||||
getAttrFromPath = attrPath: set:
|
||||
getAttrFromPath = attrPath:
|
||||
let errorMsg = "cannot find attribute `" + concatStringsSep "." attrPath + "'";
|
||||
in attrByPath attrPath (abort errorMsg) set;
|
||||
in attrByPath attrPath (abort errorMsg);
|
||||
|
||||
|
||||
/* Return the specified attributes from a set.
|
||||
|
@ -154,12 +154,12 @@ rec {
|
|||
foldAttrs (n: a: [n] ++ a) [] [{ a = 2; } { a = 3; }]
|
||||
=> { a = [ 2 3 ]; }
|
||||
*/
|
||||
foldAttrs = op: nul: list_of_attrs:
|
||||
foldAttrs = op: nul:
|
||||
foldr (n: a:
|
||||
foldr (name: o:
|
||||
o // { ${name} = op n.${name} (a.${name} or nul); }
|
||||
) a (attrNames n)
|
||||
) {} list_of_attrs;
|
||||
) {};
|
||||
|
||||
|
||||
/* Recursively collect sets that verify a given predicate named `pred'
|
||||
|
@ -295,14 +295,14 @@ rec {
|
|||
*/
|
||||
mapAttrsRecursiveCond = cond: f: set:
|
||||
let
|
||||
recurse = path: set:
|
||||
recurse = path:
|
||||
let
|
||||
g =
|
||||
name: value:
|
||||
if isAttrs value && cond value
|
||||
then recurse (path ++ [name]) value
|
||||
else f (path ++ [name]) value;
|
||||
in mapAttrs g set;
|
||||
in mapAttrs g;
|
||||
in recurse [] set;
|
||||
|
||||
|
||||
|
@ -378,7 +378,8 @@ rec {
|
|||
zipAttrsWith (name: values: values) [{a = "x";} {a = "y"; b = "z";}]
|
||||
=> { a = ["x" "y"]; b = ["z"] }
|
||||
*/
|
||||
zipAttrsWith = f: sets: zipAttrsWithNames (concatMap attrNames sets) f sets;
|
||||
zipAttrsWith =
|
||||
builtins.zipAttrsWith or (f: sets: zipAttrsWithNames (concatMap attrNames sets) f sets);
|
||||
/* Like `zipAttrsWith' with `(name: values: values)' as the function.
|
||||
|
||||
Example:
|
||||
|
@ -419,8 +420,8 @@ rec {
|
|||
let f = attrPath:
|
||||
zipAttrsWith (n: values:
|
||||
let here = attrPath ++ [n]; in
|
||||
if tail values == []
|
||||
|| pred here (head (tail values)) (head values) then
|
||||
if length values == 1
|
||||
|| pred here (elemAt values 1) (head values) then
|
||||
head values
|
||||
else
|
||||
f here values
|
||||
|
@ -446,10 +447,7 @@ rec {
|
|||
}
|
||||
|
||||
*/
|
||||
recursiveUpdate = lhs: rhs:
|
||||
recursiveUpdateUntil (path: lhs: rhs:
|
||||
!(isAttrs lhs && isAttrs rhs)
|
||||
) lhs rhs;
|
||||
recursiveUpdate = recursiveUpdateUntil (path: lhs: rhs: !(isAttrs lhs && isAttrs rhs));
|
||||
|
||||
/* Returns true if the pattern is contained in the set. False otherwise.
|
||||
|
||||
|
@ -458,8 +456,8 @@ rec {
|
|||
=> true
|
||||
*/
|
||||
matchAttrs = pattern: attrs: assert isAttrs pattern;
|
||||
foldr and true (attrValues (zipAttrsWithNames (attrNames pattern) (n: values:
|
||||
let pat = head values; val = head (tail values); in
|
||||
all id (attrValues (zipAttrsWithNames (attrNames pattern) (n: values:
|
||||
let pat = head values; val = elemAt values 1; in
|
||||
if length values == 1 then false
|
||||
else if isAttrs pat then isAttrs val && matchAttrs pat val
|
||||
else pat == val
|
||||
|
|
2
third_party/nixpkgs/lib/default.nix
vendored
2
third_party/nixpkgs/lib/default.nix
vendored
|
@ -66,7 +66,7 @@ let
|
|||
stringLength sub substring tail trace;
|
||||
inherit (self.trivial) id const pipe concat or and bitAnd bitOr bitXor
|
||||
bitNot boolToString mergeAttrs flip mapNullable inNixShell isFloat min max
|
||||
importJSON importTOML warn warnIf throwIfNot
|
||||
importJSON importTOML warn warnIf throwIfNot checkListOfEnum
|
||||
info showWarnings nixpkgsVersion version
|
||||
mod compare splitByAndCompare functionArgs setFunctionArgs isFunction
|
||||
toHexString toBaseDigits;
|
||||
|
|
15
third_party/nixpkgs/lib/modules.nix
vendored
15
third_party/nixpkgs/lib/modules.nix
vendored
|
@ -37,6 +37,7 @@ let
|
|||
toList
|
||||
types
|
||||
warnIf
|
||||
zipAttrsWith
|
||||
;
|
||||
inherit (lib.options)
|
||||
isOption
|
||||
|
@ -442,10 +443,11 @@ rec {
|
|||
}
|
||||
*/
|
||||
byName = attr: f: modules:
|
||||
foldl' (acc: module:
|
||||
if !(builtins.isAttrs module.${attr}) then
|
||||
zipAttrsWith (n: concatLists)
|
||||
(map (module: let subtree = module.${attr}; in
|
||||
if !(builtins.isAttrs subtree) then
|
||||
throw ''
|
||||
You're trying to declare a value of type `${builtins.typeOf module.${attr}}'
|
||||
You're trying to declare a value of type `${builtins.typeOf subtree}'
|
||||
rather than an attribute-set for the option
|
||||
`${builtins.concatStringsSep "." prefix}'!
|
||||
|
||||
|
@ -454,11 +456,8 @@ rec {
|
|||
this option by e.g. referring to `man 5 configuration.nix'!
|
||||
''
|
||||
else
|
||||
acc // (mapAttrs (n: v:
|
||||
(acc.${n} or []) ++ f module v
|
||||
) module.${attr}
|
||||
)
|
||||
) {} modules;
|
||||
mapAttrs (n: f module) subtree
|
||||
) modules);
|
||||
# an attrset 'name' => list of submodules that declare ‘name’.
|
||||
declsByName = byName "options" (module: option:
|
||||
[{ inherit (module) _file; options = option; }]
|
||||
|
|
17
third_party/nixpkgs/lib/trivial.nix
vendored
17
third_party/nixpkgs/lib/trivial.nix
vendored
|
@ -347,6 +347,23 @@ rec {
|
|||
*/
|
||||
throwIfNot = cond: msg: if cond then x: x else throw msg;
|
||||
|
||||
/* Check if the elements in a list are valid values from a enum, returning the identity function, or throwing an error message otherwise.
|
||||
|
||||
Example:
|
||||
let colorVariants = ["bright" "dark" "black"]
|
||||
in checkListOfEnum "color variants" [ "standard" "light" "dark" ] colorVariants;
|
||||
=>
|
||||
error: color variants: bright, black unexpected; valid ones: standard, light, dark
|
||||
|
||||
Type: String -> List ComparableVal -> List ComparableVal -> a -> a
|
||||
*/
|
||||
checkListOfEnum = msg: valid: given:
|
||||
let
|
||||
unexpected = lib.subtractLists valid given;
|
||||
in
|
||||
lib.throwIfNot (unexpected == [])
|
||||
"${msg}: ${builtins.concatStringsSep ", " (builtins.map builtins.toString unexpected)} unexpected; valid ones: ${builtins.concatStringsSep ", " (builtins.map builtins.toString valid)}";
|
||||
|
||||
info = msg: builtins.trace "INFO: ${msg}";
|
||||
|
||||
showWarnings = warnings: res: lib.foldr (w: x: warn w x) res warnings;
|
||||
|
|
|
@ -3188,6 +3188,12 @@
|
|||
githubId = 24791219;
|
||||
name = "Jakob Neufeld";
|
||||
};
|
||||
dsalaza4 = {
|
||||
email = "podany270895@gmail.com";
|
||||
github = "dsalaza4";
|
||||
githubId = 11205987;
|
||||
name = "Daniel Salazar";
|
||||
};
|
||||
dschrempf = {
|
||||
name = "Dominik Schrempf";
|
||||
email = "dominik.schrempf@gmail.com";
|
||||
|
@ -3429,6 +3435,12 @@
|
|||
githubId = 4742;
|
||||
name = "Aaron Bull Schaefer";
|
||||
};
|
||||
elatov = {
|
||||
email = "elatov@gmail.com";
|
||||
github = "elatov";
|
||||
githubId = 7494394;
|
||||
name = "Karim Elatov";
|
||||
};
|
||||
eleanor = {
|
||||
email = "dejan@proteansec.com";
|
||||
github = "proteansec";
|
||||
|
@ -4110,12 +4122,6 @@
|
|||
githubId = 7551358;
|
||||
name = "Frede Emil";
|
||||
};
|
||||
freepotion = {
|
||||
email = "42352817+freepotion@users.noreply.github.com";
|
||||
github = "freepotion";
|
||||
githubId = 42352817;
|
||||
name = "Free Potion";
|
||||
};
|
||||
freezeboy = {
|
||||
email = "freezeboy@users.noreply.github.com";
|
||||
github = "freezeboy";
|
||||
|
@ -5951,6 +5957,12 @@
|
|||
githubId = 11947756;
|
||||
name = "Julien Dehos";
|
||||
};
|
||||
julienmalka = {
|
||||
email = "julien.malka@me.com";
|
||||
github = "JulienMalka";
|
||||
githubId = 1792886;
|
||||
name = "Julien Malka";
|
||||
};
|
||||
julm = {
|
||||
email = "julm+nixpkgs@sourcephile.fr";
|
||||
github = "ju1m";
|
||||
|
@ -6049,6 +6061,13 @@
|
|||
github = "k4leg";
|
||||
githubId = 39882583;
|
||||
};
|
||||
k900 = {
|
||||
name = "Ilya K.";
|
||||
email = "me@0upti.me";
|
||||
github = "K900";
|
||||
githubId = 386765;
|
||||
matrix = "@k900:0upti.me";
|
||||
};
|
||||
kaction = {
|
||||
name = "Dmitry Bogatov";
|
||||
email = "KAction@disroot.org";
|
||||
|
@ -6355,7 +6374,7 @@
|
|||
};
|
||||
|
||||
kmein = {
|
||||
email = "kieran.meinhardt@gmail.com";
|
||||
email = "kmein@posteo.de";
|
||||
name = "Kierán Meinhardt";
|
||||
github = "kmein";
|
||||
githubId = 10352507;
|
||||
|
@ -6597,6 +6616,12 @@
|
|||
githubId = 55911173;
|
||||
name = "Gwendolyn Quasebarth";
|
||||
};
|
||||
lammermann = {
|
||||
email = "k.o.b.e.r@web.de";
|
||||
github = "lammermann";
|
||||
githubId = 695526;
|
||||
name = "Benjamin Kober";
|
||||
};
|
||||
larsr = {
|
||||
email = "Lars.Rasmusson@gmail.com";
|
||||
github = "larsr";
|
||||
|
@ -8874,6 +8899,12 @@
|
|||
githubId = 72201;
|
||||
name = "Ole Jørgen Brønner";
|
||||
};
|
||||
ollieB = {
|
||||
email = "1237862+oliverbunting@users.noreply.github.com";
|
||||
github = "oliverbunting";
|
||||
githubId = 1237862;
|
||||
name = "Ollie Bunting";
|
||||
};
|
||||
olynch = {
|
||||
email = "owen@olynch.me";
|
||||
github = "olynch";
|
||||
|
@ -10020,6 +10051,13 @@
|
|||
githubId = 16779;
|
||||
name = "Rickard Nilsson";
|
||||
};
|
||||
ricochet = {
|
||||
email = "behayes2@gmail.com";
|
||||
github = "ricochet";
|
||||
githubId = 974323;
|
||||
matrix = "@ricochetcode:matrix.org";
|
||||
name = "Bailey Hayes";
|
||||
};
|
||||
riey = {
|
||||
email = "creeper844@gmail.com";
|
||||
github = "Riey";
|
||||
|
@ -10781,6 +10819,16 @@
|
|||
githubId = 6720672;
|
||||
name = "Shane Pearlman";
|
||||
};
|
||||
shanesveller = {
|
||||
email = "shane@sveller.dev";
|
||||
github = "shanesveller";
|
||||
githubId = 831;
|
||||
keys = [{
|
||||
longkeyid = "rsa4096/0x9210C218023C15CD";
|
||||
fingerprint = "F83C 407C ADC4 5A0F 1F2F 44E8 9210 C218 023C 15CD";
|
||||
}];
|
||||
name = "Shane Sveller";
|
||||
};
|
||||
shawndellysse = {
|
||||
email = "sdellysse@gmail.com";
|
||||
github = "shawndellysse";
|
||||
|
@ -13570,10 +13618,27 @@
|
|||
github = "jpagex";
|
||||
githubId = 635768;
|
||||
};
|
||||
portothree = {
|
||||
name = "Gustavo Porto";
|
||||
email = "gustavoporto@ya.ru";
|
||||
github = "portothree";
|
||||
githubId = 3718120;
|
||||
};
|
||||
pwoelfel = {
|
||||
name = "Philipp Woelfel";
|
||||
email = "philipp.woelfel@gmail.com";
|
||||
github = "PhilippWoelfel";
|
||||
githubId = 19400064;
|
||||
};
|
||||
qbit = {
|
||||
name = "Aaron Bieber";
|
||||
email = "aaron@bolddaemon.com";
|
||||
github = "qbit";
|
||||
githubId = 68368;
|
||||
matrix = "@qbit:tapenet.org";
|
||||
keys = [{
|
||||
longkeyid = "rsa4096/0x1F81112D62A9ADCE";
|
||||
fingerprint = "3586 3350 BFEA C101 DB1A 4AF0 1F81 112D 62A9 ADCE";
|
||||
}];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -305,7 +305,7 @@ class CleanEnvironment(object):
|
|||
|
||||
def get_current_plugins(editor: Editor) -> List[Plugin]:
|
||||
with CleanEnvironment():
|
||||
cmd = ["nix", "eval", "--impure", "--json", "--expr", editor.get_plugins]
|
||||
cmd = ["nix", "eval", "--extra-experimental-features", "nix-command", "--impure", "--json", "--expr", editor.get_plugins]
|
||||
log.debug("Running command %s", cmd)
|
||||
out = subprocess.check_output(cmd)
|
||||
data = json.loads(out)
|
||||
|
|
|
@ -214,7 +214,7 @@ in rec {
|
|||
|
||||
manualEpub = runCommand "nixos-manual-epub"
|
||||
{ inherit sources;
|
||||
buildInputs = [ libxml2.bin libxslt.bin zip ];
|
||||
nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin buildPackages.zip ];
|
||||
}
|
||||
''
|
||||
# Generate the epub manual.
|
||||
|
|
|
@ -4,19 +4,19 @@ The test itself can be run interactively. This is particularly useful
|
|||
when developing or debugging a test:
|
||||
|
||||
```ShellSession
|
||||
$ nix-build nixos/tests/login.nix -A driverInteractive
|
||||
$ nix-build . -A nixosTests.login.driverInteractive
|
||||
$ ./result/bin/nixos-test-driver --interactive
|
||||
starting VDE switch for network 1
|
||||
>
|
||||
[...]
|
||||
>>>
|
||||
```
|
||||
|
||||
You can then take any Python statement, e.g.
|
||||
|
||||
```py
|
||||
> start_all()
|
||||
> test_script()
|
||||
> machine.succeed("touch /tmp/foo")
|
||||
> print(machine.succeed("pwd")) # Show stdout of command
|
||||
>>> start_all()
|
||||
>>> test_script()
|
||||
>>> machine.succeed("touch /tmp/foo")
|
||||
>>> print(machine.succeed("pwd")) # Show stdout of command
|
||||
```
|
||||
|
||||
The function `test_script` executes the entire test script and drops you
|
||||
|
|
|
@ -88,6 +88,8 @@ starting them in parallel:
|
|||
start_all()
|
||||
```
|
||||
|
||||
## Machine objects {#ssec-machine-objects}
|
||||
|
||||
The following methods are available on machine objects:
|
||||
|
||||
`start`
|
||||
|
@ -313,3 +315,52 @@ repository):
|
|||
# fmt: on
|
||||
'';
|
||||
```
|
||||
|
||||
## Failing tests early {#ssec-failing-tests-early}
|
||||
|
||||
To fail tests early when certain invariables are no longer met (instead of waiting for the build to time out), the decorator `polling_condition` is provided. For example, if we are testing a program `foo` that should not quit after being started, we might write the following:
|
||||
|
||||
```py
|
||||
@polling_condition
|
||||
def foo_running():
|
||||
machine.succeed("pgrep -x foo")
|
||||
|
||||
|
||||
machine.succeed("foo --start")
|
||||
machine.wait_until_succeeds("pgrep -x foo")
|
||||
|
||||
with foo_running:
|
||||
... # Put `foo` through its paces
|
||||
```
|
||||
|
||||
|
||||
`polling_condition` takes the following (optional) arguments:
|
||||
|
||||
`seconds_interval`
|
||||
|
||||
:
|
||||
specifies how often the condition should be polled:
|
||||
|
||||
```py
|
||||
@polling_condition(seconds_interval=10)
|
||||
def foo_running():
|
||||
machine.succeed("pgrep -x foo")
|
||||
```
|
||||
|
||||
`description`
|
||||
|
||||
:
|
||||
is used in the log when the condition is checked. If this is not provided, the description is pulled from the docstring of the function. These two are therefore equivalent:
|
||||
|
||||
```py
|
||||
@polling_condition
|
||||
def foo_running():
|
||||
"check that foo is running"
|
||||
machine.succeed("pgrep -x foo")
|
||||
```
|
||||
|
||||
```py
|
||||
@polling_condition(description="check that foo is running")
|
||||
def foo_running():
|
||||
machine.succeed("pgrep -x foo")
|
||||
```
|
||||
|
|
|
@ -5,19 +5,19 @@
|
|||
useful when developing or debugging a test:
|
||||
</para>
|
||||
<programlisting>
|
||||
$ nix-build nixos/tests/login.nix -A driverInteractive
|
||||
$ nix-build . -A nixosTests.login.driverInteractive
|
||||
$ ./result/bin/nixos-test-driver --interactive
|
||||
starting VDE switch for network 1
|
||||
>
|
||||
[...]
|
||||
>>>
|
||||
</programlisting>
|
||||
<para>
|
||||
You can then take any Python statement, e.g.
|
||||
</para>
|
||||
<programlisting language="python">
|
||||
> start_all()
|
||||
> test_script()
|
||||
> machine.succeed("touch /tmp/foo")
|
||||
> print(machine.succeed("pwd")) # Show stdout of command
|
||||
>>> start_all()
|
||||
>>> test_script()
|
||||
>>> machine.succeed("touch /tmp/foo")
|
||||
>>> print(machine.succeed("pwd")) # Show stdout of command
|
||||
</programlisting>
|
||||
<para>
|
||||
The function <literal>test_script</literal> executes the entire test
|
||||
|
|
|
@ -117,6 +117,8 @@ if not "Linux" in machine.succeed("uname"):
|
|||
<programlisting language="python">
|
||||
start_all()
|
||||
</programlisting>
|
||||
<section xml:id="ssec-machine-objects">
|
||||
<title>Machine objects</title>
|
||||
<para>
|
||||
The following methods are available on machine objects:
|
||||
</para>
|
||||
|
@ -194,8 +196,8 @@ start_all()
|
|||
Return a list of different interpretations of what is
|
||||
currently visible on the machine's screen using optical
|
||||
character recognition. The number and order of the
|
||||
interpretations is not specified and is subject to change, but
|
||||
if no exception is raised at least one will be returned.
|
||||
interpretations is not specified and is subject to change,
|
||||
but if no exception is raised at least one will be returned.
|
||||
</para>
|
||||
<note>
|
||||
<para>
|
||||
|
@ -253,9 +255,9 @@ start_all()
|
|||
<para>
|
||||
Simulate typing a sequence of characters on the virtual
|
||||
keyboard, e.g.,
|
||||
<literal>send_chars("foobar\n")</literal> will type
|
||||
the string <literal>foobar</literal> followed by the Enter
|
||||
key.
|
||||
<literal>send_chars("foobar\n")</literal> will
|
||||
type the string <literal>foobar</literal> followed by the
|
||||
Enter key.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
@ -266,23 +268,24 @@ start_all()
|
|||
<listitem>
|
||||
<para>
|
||||
Execute a shell command, returning a list
|
||||
<literal>(status, stdout)</literal>. If the command detaches,
|
||||
it must close stdout, as <literal>execute</literal> will wait
|
||||
for this to consume all output reliably. This can be achieved
|
||||
by redirecting stdout to stderr <literal>>&2</literal>,
|
||||
to <literal>/dev/console</literal>,
|
||||
<literal>/dev/null</literal> or a file. Examples of detaching
|
||||
commands are <literal>sleep 365d &</literal>, where the
|
||||
shell forks a new process that can write to stdout and
|
||||
<literal>xclip -i</literal>, where the
|
||||
<literal>xclip</literal> command itself forks without closing
|
||||
stdout. Takes an optional parameter
|
||||
<literal>(status, stdout)</literal>. If the command
|
||||
detaches, it must close stdout, as
|
||||
<literal>execute</literal> will wait for this to consume all
|
||||
output reliably. This can be achieved by redirecting stdout
|
||||
to stderr <literal>>&2</literal>, to
|
||||
<literal>/dev/console</literal>,
|
||||
<literal>/dev/null</literal> or a file. Examples of
|
||||
detaching commands are <literal>sleep 365d &</literal>,
|
||||
where the shell forks a new process that can write to stdout
|
||||
and <literal>xclip -i</literal>, where the
|
||||
<literal>xclip</literal> command itself forks without
|
||||
closing stdout. Takes an optional parameter
|
||||
<literal>check_return</literal> that defaults to
|
||||
<literal>True</literal>. Setting this parameter to
|
||||
<literal>False</literal> will not check for the return code
|
||||
and return -1 instead. This can be used for commands that shut
|
||||
down the VM and would therefore break the pipe that would be
|
||||
used for retrieving the return code.
|
||||
and return -1 instead. This can be used for commands that
|
||||
shut down the VM and would therefore break the pipe that
|
||||
would be used for retrieving the return code.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
@ -300,8 +303,9 @@ start_all()
|
|||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
If several commands are separated by <literal>;</literal>
|
||||
and one fails, the command as a whole will fail.
|
||||
If several commands are separated by
|
||||
<literal>;</literal> and one fails, the command as a
|
||||
whole will fail.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
|
@ -353,7 +357,8 @@ start_all()
|
|||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Repeat a shell command with 1-second intervals until it fails.
|
||||
Repeat a shell command with 1-second intervals until it
|
||||
fails.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
@ -462,9 +467,9 @@ start_all()
|
|||
<literal>copy_from_host("myfile", "/etc/my/important/file")</literal>.
|
||||
</para>
|
||||
<para>
|
||||
The first argument is the file on the host. The file needs to
|
||||
be accessible while building the nix derivation. The second
|
||||
argument is the location of the file on the machine.
|
||||
The first argument is the file on the host. The file needs
|
||||
to be accessible while building the nix derivation. The
|
||||
second argument is the location of the file on the machine.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
@ -490,8 +495,8 @@ machine.systemctl("list-jobs --no-pager", "any-user") # spaw
|
|||
<listitem>
|
||||
<para>
|
||||
Allows you to directly interact with the guest shell. This
|
||||
should only be used during test development, not in production
|
||||
tests. Killing the interactive session with
|
||||
should only be used during test development, not in
|
||||
production tests. Killing the interactive session with
|
||||
<literal>Ctrl-d</literal> or <literal>Ctrl-c</literal> also
|
||||
ends the guest session.
|
||||
</para>
|
||||
|
@ -510,12 +515,13 @@ machine.wait_for_unit("xautolock.service", "x-session-user")
|
|||
</programlisting>
|
||||
<para>
|
||||
This applies to <literal>systemctl</literal>,
|
||||
<literal>get_unit_info</literal>, <literal>wait_for_unit</literal>,
|
||||
<literal>start_job</literal> and <literal>stop_job</literal>.
|
||||
<literal>get_unit_info</literal>,
|
||||
<literal>wait_for_unit</literal>, <literal>start_job</literal> and
|
||||
<literal>stop_job</literal>.
|
||||
</para>
|
||||
<para>
|
||||
For faster dev cycles it's also possible to disable the code-linters
|
||||
(this shouldn't be commited though):
|
||||
For faster dev cycles it's also possible to disable the
|
||||
code-linters (this shouldn't be commited though):
|
||||
</para>
|
||||
<programlisting language="bash">
|
||||
import ./make-test-python.nix {
|
||||
|
@ -532,10 +538,10 @@ import ./make-test-python.nix {
|
|||
}
|
||||
</programlisting>
|
||||
<para>
|
||||
This will produce a Nix warning at evaluation time. To fully disable
|
||||
the linter, wrap the test script in comment directives to disable
|
||||
the Black linter directly (again, don't commit this within the
|
||||
Nixpkgs repository):
|
||||
This will produce a Nix warning at evaluation time. To fully
|
||||
disable the linter, wrap the test script in comment directives to
|
||||
disable the Black linter directly (again, don't commit this within
|
||||
the Nixpkgs repository):
|
||||
</para>
|
||||
<programlisting language="bash">
|
||||
testScript =
|
||||
|
@ -545,4 +551,66 @@ import ./make-test-python.nix {
|
|||
# fmt: on
|
||||
'';
|
||||
</programlisting>
|
||||
</section>
|
||||
<section xml:id="ssec-failing-tests-early">
|
||||
<title>Failing tests early</title>
|
||||
<para>
|
||||
To fail tests early when certain invariables are no longer met
|
||||
(instead of waiting for the build to time out), the decorator
|
||||
<literal>polling_condition</literal> is provided. For example, if
|
||||
we are testing a program <literal>foo</literal> that should not
|
||||
quit after being started, we might write the following:
|
||||
</para>
|
||||
<programlisting language="python">
|
||||
@polling_condition
|
||||
def foo_running():
|
||||
machine.succeed("pgrep -x foo")
|
||||
|
||||
|
||||
machine.succeed("foo --start")
|
||||
machine.wait_until_succeeds("pgrep -x foo")
|
||||
|
||||
with foo_running:
|
||||
... # Put `foo` through its paces
|
||||
</programlisting>
|
||||
<para>
|
||||
<literal>polling_condition</literal> takes the following
|
||||
(optional) arguments:
|
||||
</para>
|
||||
<para>
|
||||
<literal>seconds_interval</literal>
|
||||
</para>
|
||||
<para>
|
||||
: specifies how often the condition should be polled:
|
||||
</para>
|
||||
<programlisting>
|
||||
```py
|
||||
@polling_condition(seconds_interval=10)
|
||||
def foo_running():
|
||||
machine.succeed("pgrep -x foo")
|
||||
```
|
||||
</programlisting>
|
||||
<para>
|
||||
<literal>description</literal>
|
||||
</para>
|
||||
<para>
|
||||
: is used in the log when the condition is checked. If this is not
|
||||
provided, the description is pulled from the docstring of the
|
||||
function. These two are therefore equivalent:
|
||||
</para>
|
||||
<programlisting>
|
||||
```py
|
||||
@polling_condition
|
||||
def foo_running():
|
||||
"check that foo is running"
|
||||
machine.succeed("pgrep -x foo")
|
||||
```
|
||||
|
||||
```py
|
||||
@polling_condition(description="check that foo is running")
|
||||
def foo_running():
|
||||
machine.succeed("pgrep -x foo")
|
||||
```
|
||||
</programlisting>
|
||||
</section>
|
||||
</section>
|
||||
|
|
|
@ -75,6 +75,14 @@
|
|||
<link linkend="opt-services.filebeat.enable">services.filebeat</link>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<link xlink:href="https://frrouting.org/">FRRouting</link>, a
|
||||
popular suite of Internet routing protocol daemons (BGP, BFD,
|
||||
OSPF, IS-IS, VVRP and others). Available as
|
||||
<link linkend="opt-services.ffr.babel.enable">services.frr</link>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<link xlink:href="https://github.com/hifi/heisenbridge">heisenbridge</link>,
|
||||
|
@ -96,6 +104,13 @@
|
|||
<link xlink:href="options.html#opt-services.maddy.enable">services.maddy</link>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<link xlink:href="https://github.com/mgumz/mtr-exporter">mtr-exporter</link>,
|
||||
a Prometheus exporter for mtr metrics. Available as
|
||||
<link xlink:href="options.html#opt-services.mtr-exporter.enable">services.mtr-exporter</link>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<link xlink:href="https://tetrd.app">tetrd</link>, share your
|
||||
|
@ -104,6 +119,37 @@
|
|||
<link linkend="opt-services.tetrd.enable">services.tetrd</link>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<link xlink:href="https://github.com/JustArchiNET/ArchiSteamFarm">ArchiSteamFarm</link>,
|
||||
a C# application with primary purpose of idling Steam cards
|
||||
from multiple accounts simultaneously. Available as
|
||||
<link xlink:href="options.html#opt-services.archisteamfarm.enable">services.archisteamfarm</link>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<link xlink:href="https://goteleport.com">teleport</link>,
|
||||
allows engineers and security professionals to unify access
|
||||
for SSH servers, Kubernetes clusters, web applications, and
|
||||
databases across all environments. Available at
|
||||
<link linkend="opt-services.teleport.enable">services.teleport</link>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<link xlink:href="https://loic-sharma.github.io/BaGet/">BaGet</link>,
|
||||
a lightweight NuGet and symbol server. Available at
|
||||
<link linkend="opt-services.baget.enable">services.baget</link>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<link xlink:href="https://github.com/ThomasLeister/prosody-filer">prosody-filer</link>,
|
||||
a server for handling XMPP HTTP Upload requests. Available at
|
||||
<link linkend="opt-services.prosody-filer.enable">services.prosody-filer</link>.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
<section xml:id="sec-release-22.05-incompatibilities">
|
||||
|
@ -191,6 +237,12 @@
|
|||
<literal>virtualisation.docker.daemon.settings</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
opensmtpd-extras is no longer build with python2 scripting
|
||||
support due to python2 deprecation in nixpkgs
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The <literal>autorestic</literal> package has been upgraded
|
||||
|
@ -228,6 +280,37 @@
|
|||
to your configuration.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Normal users (with <literal>isNormalUser = true</literal>)
|
||||
which have non-empty <literal>subUidRanges</literal> or
|
||||
<literal>subGidRanges</literal> set no longer have additional
|
||||
implicit ranges allocated. To enable automatic allocation back
|
||||
set <literal>autoSubUidGidRange = true</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>idris2</literal> now requires
|
||||
<literal>--package</literal> when using packages
|
||||
<literal>contrib</literal> and <literal>network</literal>,
|
||||
while previously these idris2 packages were automatically
|
||||
loaded.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>services.thelounge.private</literal> was removed in
|
||||
favor of <literal>services.thelounge.public</literal>, to
|
||||
follow with upstream changes.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>pkgs.docbookrx</literal> was removed since it’s
|
||||
unmaintained
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
<section xml:id="sec-release-22.05-notable-changes">
|
||||
|
@ -334,6 +417,30 @@
|
|||
<literal>true</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The option <literal>services.thelounge.plugins</literal> has
|
||||
been added to allow installing plugins for The Lounge. Plugins
|
||||
can be found in
|
||||
<literal>pkgs.theLoungePlugins.plugins</literal> and
|
||||
<literal>pkgs.theLoungePlugins.themes</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The <literal>firmwareLinuxNonfree</literal> package has been
|
||||
renamed to <literal>linux-firmware</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
A new module was added for the
|
||||
<link xlink:href="https://starship.rs/">Starship</link> shell
|
||||
prompt, providing the options
|
||||
<literal>programs.starship.enable</literal> and
|
||||
<literal>programs.starship.settings</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
</section>
|
||||
|
|
|
@ -19,20 +19,33 @@ In addition to numerous new and upgraded packages, this release has the followin
|
|||
## New Services {#sec-release-22.05-new-services}
|
||||
|
||||
- [aesmd](https://github.com/intel/linux-sgx#install-the-intelr-sgx-psw), the Intel SGX Architectural Enclave Service Manager. Available as [services.aesmd](#opt-services.aesmd.enable).
|
||||
|
||||
- [rootless Docker](https://docs.docker.com/engine/security/rootless/), a `systemd --user` Docker service which runs without root permissions. Available as [virtualisation.docker.rootless.enable](options.html#opt-virtualisation.docker.rootless.enable).
|
||||
|
||||
- [matrix-conduit](https://conduit.rs/), a simple, fast and reliable chat server powered by matrix. Available as [services.matrix-conduit](option.html#opt-services.matrix-conduit.enable).
|
||||
|
||||
- [filebeat](https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-overview.html), a lightweight shipper for forwarding and centralizing log data. Available as [services.filebeat](#opt-services.filebeat.enable).
|
||||
|
||||
- [FRRouting](https://frrouting.org/), a popular suite of Internet routing protocol daemons (BGP, BFD, OSPF, IS-IS, VVRP and others). Available as [services.frr](#opt-services.ffr.babel.enable)
|
||||
|
||||
- [heisenbridge](https://github.com/hifi/heisenbridge), a bouncer-style Matrix IRC bridge. Available as [services.heisenbridge](options.html#opt-services.heisenbridge.enable).
|
||||
|
||||
- [PowerDNS-Admin](https://github.com/ngoduykhanh/PowerDNS-Admin), a web interface for the PowerDNS server. Available at [services.powerdns-admin](options.html#opt-services.powerdns-admin.enable).
|
||||
|
||||
- [maddy](https://maddy.email), a composable all-in-one mail server. Available as [services.maddy](options.html#opt-services.maddy.enable).
|
||||
|
||||
- [mtr-exporter](https://github.com/mgumz/mtr-exporter), a Prometheus exporter for mtr metrics. Available as [services.mtr-exporter](options.html#opt-services.mtr-exporter.enable).
|
||||
|
||||
- [tetrd](https://tetrd.app), share your internet connection from your device to your PC and vice versa through a USB cable. Available at [services.tetrd](#opt-services.tetrd.enable).
|
||||
|
||||
- [ArchiSteamFarm](https://github.com/JustArchiNET/ArchiSteamFarm), a C# application with primary purpose of idling Steam cards from multiple accounts simultaneously. Available as [services.archisteamfarm](options.html#opt-services.archisteamfarm.enable).
|
||||
|
||||
- [teleport](https://goteleport.com), allows engineers and security professionals to unify access for SSH servers, Kubernetes clusters, web applications, and databases across all environments. Available at [services.teleport](#opt-services.teleport.enable).
|
||||
|
||||
- [BaGet](https://loic-sharma.github.io/BaGet/), a lightweight NuGet and symbol server. Available at [services.baget](#opt-services.baget.enable).
|
||||
|
||||
- [prosody-filer](https://github.com/ThomasLeister/prosody-filer), a server for handling XMPP HTTP Upload requests. Available at [services.prosody-filer](#opt-services.prosody-filer.enable).
|
||||
|
||||
## Backward Incompatibilities {#sec-release-22.05-incompatibilities}
|
||||
|
||||
- `pkgs.ghc` now refers to `pkgs.targetPackages.haskellPackages.ghc`.
|
||||
|
@ -66,6 +79,8 @@ In addition to numerous new and upgraded packages, this release has the followin
|
|||
|
||||
- If you previously used `/etc/docker/daemon.json`, you need to incorporate the changes into the new option `virtualisation.docker.daemon.settings`.
|
||||
|
||||
- opensmtpd-extras is no longer build with python2 scripting support due to python2 deprecation in nixpkgs
|
||||
|
||||
- The `autorestic` package has been upgraded from 1.3.0 to 1.5.0 which introduces breaking changes in config file, check [their migration guide](https://autorestic.vercel.app/migration/1.4_1.5) for more details.
|
||||
|
||||
- For `pkgs.python3.pkgs.ipython`, its direct dependency `pkgs.python3.pkgs.matplotlib-inline`
|
||||
|
@ -77,6 +92,14 @@ In addition to numerous new and upgraded packages, this release has the followin
|
|||
|
||||
- `documentation.man` has been refactored to support choosing a man implementation other than GNU's `man-db`. For this, `documentation.man.manualPages` has been renamed to `documentation.man.man-db.manualPages`. If you want to use the new alternative man implementation `mandoc`, add `documentation.man = { enable = true; man-db.enable = false; mandoc.enable = true; }` to your configuration.
|
||||
|
||||
- Normal users (with `isNormalUser = true`) which have non-empty `subUidRanges` or `subGidRanges` set no longer have additional implicit ranges allocated. To enable automatic allocation back set `autoSubUidGidRange = true`.
|
||||
|
||||
- `idris2` now requires `--package` when using packages `contrib` and `network`, while previously these idris2 packages were automatically loaded.
|
||||
|
||||
- `services.thelounge.private` was removed in favor of `services.thelounge.public`, to follow with upstream changes.
|
||||
|
||||
- `pkgs.docbookrx` was removed since it's unmaintained
|
||||
|
||||
## Other Notable Changes {#sec-release-22.05-notable-changes}
|
||||
|
||||
- The option [services.redis.servers](#opt-services.redis.servers) was added
|
||||
|
@ -124,3 +147,10 @@ In addition to numerous new and upgraded packages, this release has the followin
|
|||
- `fetchFromSourcehut` now allows fetching repositories recursively
|
||||
using `fetchgit` or `fetchhg` if the argument `fetchSubmodules`
|
||||
is set to `true`.
|
||||
|
||||
- The option `services.thelounge.plugins` has been added to allow installing plugins for The Lounge. Plugins can be found in `pkgs.theLoungePlugins.plugins` and `pkgs.theLoungePlugins.themes`.
|
||||
|
||||
- The `firmwareLinuxNonfree` package has been renamed to `linux-firmware`.
|
||||
|
||||
- A new module was added for the [Starship](https://starship.rs/) shell prompt,
|
||||
providing the options `programs.starship.enable` and `programs.starship.settings`.
|
||||
|
|
|
@ -17,7 +17,7 @@ rec {
|
|||
''-netdev vde,id=vlan${toString nic},sock="$QEMU_VDE_SOCKET_${toString net}"''
|
||||
];
|
||||
|
||||
qemuSerialDevice = if pkgs.stdenv.hostPlatform.isx86 then "ttyS0"
|
||||
qemuSerialDevice = if pkgs.stdenv.hostPlatform.isx86 || pkgs.stdenv.hostPlatform.isRiscV then "ttyS0"
|
||||
else if (with pkgs.stdenv.hostPlatform; isAarch32 || isAarch64 || isPower) then "ttyAMA0"
|
||||
else throw "Unknown QEMU serial device for system '${pkgs.stdenv.hostPlatform.system}'";
|
||||
|
||||
|
|
|
@ -228,9 +228,7 @@ in rec {
|
|||
mkdir -p $out/getty.target.wants/
|
||||
ln -s ../autovt@tty1.service $out/getty.target.wants/
|
||||
|
||||
ln -s ../local-fs.target ../remote-fs.target \
|
||||
../nss-lookup.target ../nss-user-lookup.target ../swap.target \
|
||||
$out/multi-user.target.wants/
|
||||
ln -s ../remote-fs.target $out/multi-user.target.wants/
|
||||
''}
|
||||
''; # */
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
python3Packages.buildPythonApplication rec {
|
||||
pname = "nixos-test-driver";
|
||||
version = "1.0";
|
||||
version = "1.1";
|
||||
src = ./.;
|
||||
|
||||
propagatedBuildInputs = [ coreutils netpbm python3Packages.colorama python3Packages.ptpython qemu_pkg socat vde2 ]
|
||||
|
@ -26,7 +26,7 @@ python3Packages.buildPythonApplication rec {
|
|||
mypy --disallow-untyped-defs \
|
||||
--no-implicit-optional \
|
||||
--ignore-missing-imports ${src}/test_driver
|
||||
pylint --errors-only ${src}/test_driver
|
||||
pylint --errors-only --enable=unused-import ${src}/test_driver
|
||||
black --check --diff ${src}/test_driver
|
||||
'';
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ from setuptools import setup, find_packages
|
|||
|
||||
setup(
|
||||
name="nixos-test-driver",
|
||||
version='1.0',
|
||||
version='1.1',
|
||||
packages=find_packages(),
|
||||
entry_points={
|
||||
"console_scripts": [
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
from contextlib import contextmanager
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, Iterator, List
|
||||
from typing import Any, Dict, Iterator, List, Union, Optional, Callable, ContextManager
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
from test_driver.logger import rootlog
|
||||
from test_driver.machine import Machine, NixStartScript, retry
|
||||
from test_driver.vlan import VLan
|
||||
from test_driver.polling_condition import PollingCondition
|
||||
|
||||
|
||||
class Driver:
|
||||
|
@ -16,6 +17,7 @@ class Driver:
|
|||
tests: str
|
||||
vlans: List[VLan]
|
||||
machines: List[Machine]
|
||||
polling_conditions: List[PollingCondition]
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
|
@ -36,12 +38,15 @@ class Driver:
|
|||
for s in scripts:
|
||||
yield NixStartScript(s)
|
||||
|
||||
self.polling_conditions = []
|
||||
|
||||
self.machines = [
|
||||
Machine(
|
||||
start_command=cmd,
|
||||
keep_vm_state=keep_vm_state,
|
||||
name=cmd.machine_name,
|
||||
tmp_dir=tmp_dir,
|
||||
callbacks=[self.check_polling_conditions],
|
||||
)
|
||||
for cmd in cmd(start_scripts)
|
||||
]
|
||||
|
@ -84,6 +89,7 @@ class Driver:
|
|||
retry=retry,
|
||||
serial_stdout_off=self.serial_stdout_off,
|
||||
serial_stdout_on=self.serial_stdout_on,
|
||||
polling_condition=self.polling_condition,
|
||||
Machine=Machine, # for typing
|
||||
)
|
||||
machine_symbols = {m.name: m for m in self.machines}
|
||||
|
@ -159,3 +165,36 @@ class Driver:
|
|||
|
||||
def serial_stdout_off(self) -> None:
|
||||
rootlog._print_serial_logs = False
|
||||
|
||||
def check_polling_conditions(self) -> None:
|
||||
for condition in self.polling_conditions:
|
||||
condition.maybe_raise()
|
||||
|
||||
def polling_condition(
|
||||
self,
|
||||
fun_: Optional[Callable] = None,
|
||||
*,
|
||||
seconds_interval: float = 2.0,
|
||||
description: Optional[str] = None,
|
||||
) -> Union[Callable[[Callable], ContextManager], ContextManager]:
|
||||
driver = self
|
||||
|
||||
class Poll:
|
||||
def __init__(self, fun: Callable):
|
||||
self.condition = PollingCondition(
|
||||
fun,
|
||||
seconds_interval,
|
||||
description,
|
||||
)
|
||||
|
||||
def __enter__(self) -> None:
|
||||
driver.polling_conditions.append(self.condition)
|
||||
|
||||
def __exit__(self, a, b, c) -> None: # type: ignore
|
||||
res = driver.polling_conditions.pop()
|
||||
assert res is self.condition
|
||||
|
||||
if fun_ is None:
|
||||
return Poll
|
||||
else:
|
||||
return Poll(fun_)
|
||||
|
|
|
@ -318,6 +318,7 @@ class Machine:
|
|||
# Store last serial console lines for use
|
||||
# of wait_for_console_text
|
||||
last_lines: Queue = Queue()
|
||||
callbacks: List[Callable]
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<Machine '{self.name}'>"
|
||||
|
@ -329,12 +330,14 @@ class Machine:
|
|||
name: str = "machine",
|
||||
keep_vm_state: bool = False,
|
||||
allow_reboot: bool = False,
|
||||
callbacks: Optional[List[Callable]] = None,
|
||||
) -> None:
|
||||
self.tmp_dir = tmp_dir
|
||||
self.keep_vm_state = keep_vm_state
|
||||
self.allow_reboot = allow_reboot
|
||||
self.name = name
|
||||
self.start_command = start_command
|
||||
self.callbacks = callbacks if callbacks is not None else []
|
||||
|
||||
# set up directories
|
||||
self.shared_dir = self.tmp_dir / "shared-xchg"
|
||||
|
@ -406,6 +409,7 @@ class Machine:
|
|||
return answer
|
||||
|
||||
def send_monitor_command(self, command: str) -> str:
|
||||
self.run_callbacks()
|
||||
with self.nested("sending monitor command: {}".format(command)):
|
||||
message = ("{}\n".format(command)).encode()
|
||||
assert self.monitor is not None
|
||||
|
@ -509,6 +513,7 @@ class Machine:
|
|||
def execute(
|
||||
self, command: str, check_return: bool = True, timeout: Optional[int] = 900
|
||||
) -> Tuple[int, str]:
|
||||
self.run_callbacks()
|
||||
self.connect()
|
||||
|
||||
if timeout is not None:
|
||||
|
@ -969,3 +974,7 @@ class Machine:
|
|||
self.shell.close()
|
||||
self.monitor.close()
|
||||
self.serial_thread.join()
|
||||
|
||||
def run_callbacks(self) -> None:
|
||||
for callback in self.callbacks:
|
||||
callback()
|
||||
|
|
77
third_party/nixpkgs/nixos/lib/test-driver/test_driver/polling_condition.py
vendored
Normal file
77
third_party/nixpkgs/nixos/lib/test-driver/test_driver/polling_condition.py
vendored
Normal file
|
@ -0,0 +1,77 @@
|
|||
from typing import Callable, Optional
|
||||
import time
|
||||
|
||||
from .logger import rootlog
|
||||
|
||||
|
||||
class PollingConditionFailed(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class PollingCondition:
|
||||
condition: Callable[[], bool]
|
||||
seconds_interval: float
|
||||
description: Optional[str]
|
||||
|
||||
last_called: float
|
||||
entered: bool
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
condition: Callable[[], Optional[bool]],
|
||||
seconds_interval: float = 2.0,
|
||||
description: Optional[str] = None,
|
||||
):
|
||||
self.condition = condition # type: ignore
|
||||
self.seconds_interval = seconds_interval
|
||||
|
||||
if description is None:
|
||||
if condition.__doc__:
|
||||
self.description = condition.__doc__
|
||||
else:
|
||||
self.description = condition.__name__
|
||||
else:
|
||||
self.description = str(description)
|
||||
|
||||
self.last_called = float("-inf")
|
||||
self.entered = False
|
||||
|
||||
def check(self) -> bool:
|
||||
if self.entered or not self.overdue:
|
||||
return True
|
||||
|
||||
with self, rootlog.nested(self.nested_message):
|
||||
rootlog.info(f"Time since last: {time.monotonic() - self.last_called:.2f}s")
|
||||
try:
|
||||
res = self.condition() # type: ignore
|
||||
except Exception:
|
||||
res = False
|
||||
res = res is None or res
|
||||
rootlog.info(self.status_message(res))
|
||||
return res
|
||||
|
||||
def maybe_raise(self) -> None:
|
||||
if not self.check():
|
||||
raise PollingConditionFailed(self.status_message(False))
|
||||
|
||||
def status_message(self, status: bool) -> str:
|
||||
return f"Polling condition {'succeeded' if status else 'failed'}: {self.description}"
|
||||
|
||||
@property
|
||||
def nested_message(self) -> str:
|
||||
nested_message = ["Checking polling condition"]
|
||||
if self.description is not None:
|
||||
nested_message.append(repr(self.description))
|
||||
|
||||
return " ".join(nested_message)
|
||||
|
||||
@property
|
||||
def overdue(self) -> bool:
|
||||
return self.last_called + self.seconds_interval < time.monotonic()
|
||||
|
||||
def __enter__(self) -> None:
|
||||
self.entered = True
|
||||
|
||||
def __exit__(self, exc_type, exc_value, traceback) -> None: # type: ignore
|
||||
self.entered = False
|
||||
self.last_called = time.monotonic()
|
|
@ -17,7 +17,7 @@ rec {
|
|||
inherit pkgs;
|
||||
|
||||
# Run an automated test suite in the given virtual network.
|
||||
runTests = { driver, pos }:
|
||||
runTests = { driver, driverInteractive, pos }:
|
||||
stdenv.mkDerivation {
|
||||
name = "vm-test-run-${driver.testName}";
|
||||
|
||||
|
@ -34,7 +34,7 @@ rec {
|
|||
'';
|
||||
|
||||
passthru = driver.passthru // {
|
||||
inherit driver;
|
||||
inherit driver driverInteractive;
|
||||
};
|
||||
|
||||
inherit pos; # for better debugging
|
||||
|
@ -224,7 +224,7 @@ rec {
|
|||
passMeta = drv: drv // lib.optionalAttrs (t ? meta) {
|
||||
meta = (drv.meta or { }) // t.meta;
|
||||
};
|
||||
in passMeta (runTests { inherit driver pos; });
|
||||
in passMeta (runTests { inherit driver pos driverInteractive; });
|
||||
|
||||
in
|
||||
test // {
|
||||
|
|
|
@ -196,9 +196,7 @@ in
|
|||
protocols.source = pkgs.iana-etc + "/etc/protocols";
|
||||
|
||||
# /etc/hosts: Hostname-to-IP mappings.
|
||||
hosts.source = pkgs.runCommand "hosts" {} ''
|
||||
cat ${escapeShellArgs cfg.hostFiles} > $out
|
||||
'';
|
||||
hosts.source = pkgs.concatText "hosts" cfg.hostFiles;
|
||||
|
||||
# /etc/netgroup: Network-wide groups.
|
||||
netgroup.text = mkDefault "";
|
||||
|
|
|
@ -351,7 +351,7 @@ foreach my $u (values %usersOut) {
|
|||
push @subGids, $value;
|
||||
}
|
||||
|
||||
if($u->{isNormalUser}) {
|
||||
if($u->{autoSubUidGidRange}) {
|
||||
my $subordinate = allocSubUid($name);
|
||||
$subUidMap->{$name} = $subordinate;
|
||||
my $value = join(":", ($name, $subordinate, 65536));
|
||||
|
|
|
@ -204,6 +204,16 @@ let
|
|||
'';
|
||||
};
|
||||
|
||||
autoSubUidGidRange = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
example = true;
|
||||
description = ''
|
||||
Automatically allocate subordinate user and group ids for this user.
|
||||
Allocated range is currently always of size 65536.
|
||||
'';
|
||||
};
|
||||
|
||||
createHome = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
|
@ -320,6 +330,9 @@ let
|
|||
(mkIf (!cfg.mutableUsers && config.initialHashedPassword != null) {
|
||||
hashedPassword = mkDefault config.initialHashedPassword;
|
||||
})
|
||||
(mkIf (config.isNormalUser && config.subUidRanges == [] && config.subGidRanges == []) {
|
||||
autoSubUidGidRange = mkDefault true;
|
||||
})
|
||||
];
|
||||
|
||||
};
|
||||
|
@ -419,7 +432,7 @@ let
|
|||
{ inherit (u)
|
||||
name uid group description home createHome isSystemUser
|
||||
password passwordFile hashedPassword
|
||||
isNormalUser subUidRanges subGidRanges
|
||||
autoSubUidGidRange subUidRanges subGidRanges
|
||||
initialPassword initialHashedPassword;
|
||||
shell = utils.toShellPath u.shell;
|
||||
}) cfg.users;
|
||||
|
|
|
@ -31,7 +31,6 @@ in {
|
|||
type = types.bool;
|
||||
description = ''
|
||||
Turn on this option if you want to enable all the firmware with a license allowing redistribution.
|
||||
(i.e. free firmware and <literal>firmware-linux-nonfree</literal>)
|
||||
'';
|
||||
};
|
||||
|
||||
|
@ -51,7 +50,7 @@ in {
|
|||
config = mkMerge [
|
||||
(mkIf (cfg.enableAllFirmware || cfg.enableRedistributableFirmware) {
|
||||
hardware.firmware = with pkgs; [
|
||||
firmwareLinuxNonfree
|
||||
linux-firmware
|
||||
intel2200BGFirmware
|
||||
rtl8192su-firmware
|
||||
rt5677-firmware
|
||||
|
|
|
@ -1,10 +1,24 @@
|
|||
{ config, lib, ... }:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.hardware.cpu.intel.sgx.provision;
|
||||
defaultGroup = "sgx_prv";
|
||||
cfg = config.hardware.cpu.intel.sgx;
|
||||
defaultPrvGroup = "sgx_prv";
|
||||
in
|
||||
{
|
||||
options.hardware.cpu.intel.sgx.enableDcapCompat = mkOption {
|
||||
description = ''
|
||||
Whether to enable backward compatibility for SGX software build for the
|
||||
out-of-tree Intel SGX DCAP driver.
|
||||
|
||||
Creates symbolic links for the SGX devices <literal>/dev/sgx_enclave</literal>
|
||||
and <literal>/dev/sgx_provision</literal> to make them available as
|
||||
<literal>/dev/sgx/enclave</literal> and <literal>/dev/sgx/provision</literal>,
|
||||
respectively.
|
||||
'';
|
||||
type = types.bool;
|
||||
default = true;
|
||||
};
|
||||
|
||||
options.hardware.cpu.intel.sgx.provision = {
|
||||
enable = mkEnableOption "access to the Intel SGX provisioning device";
|
||||
user = mkOption {
|
||||
|
@ -15,7 +29,7 @@ in
|
|||
group = mkOption {
|
||||
description = "Group to assign to the SGX provisioning device.";
|
||||
type = types.str;
|
||||
default = defaultGroup;
|
||||
default = defaultPrvGroup;
|
||||
};
|
||||
mode = mkOption {
|
||||
description = "Mode to set for the SGX provisioning device.";
|
||||
|
@ -24,24 +38,32 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = mkMerge [
|
||||
(mkIf cfg.provision.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = hasAttr cfg.user config.users.users;
|
||||
assertion = hasAttr cfg.provision.user config.users.users;
|
||||
message = "Given user does not exist";
|
||||
}
|
||||
{
|
||||
assertion = (cfg.group == defaultGroup) || (hasAttr cfg.group config.users.groups);
|
||||
assertion = (cfg.provision.group == defaultPrvGroup) || (hasAttr cfg.provision.group config.users.groups);
|
||||
message = "Given group does not exist";
|
||||
}
|
||||
];
|
||||
|
||||
users.groups = optionalAttrs (cfg.group == defaultGroup) {
|
||||
"${cfg.group}" = { };
|
||||
users.groups = optionalAttrs (cfg.provision.group == defaultPrvGroup) {
|
||||
"${cfg.provision.group}" = { };
|
||||
};
|
||||
|
||||
services.udev.extraRules = ''
|
||||
SUBSYSTEM=="misc", KERNEL=="sgx_provision", OWNER="${cfg.user}", GROUP="${cfg.group}", MODE="${cfg.mode}"
|
||||
services.udev.extraRules = with cfg.provision; ''
|
||||
SUBSYSTEM=="misc", KERNEL=="sgx_provision", OWNER="${user}", GROUP="${group}", MODE="${mode}"
|
||||
'';
|
||||
};
|
||||
})
|
||||
(mkIf cfg.enableDcapCompat {
|
||||
services.udev.extraRules = ''
|
||||
SUBSYSTEM=="misc", KERNEL=="sgx_enclave", SYMLINK+="sgx/enclave"
|
||||
SUBSYSTEM=="misc", KERNEL=="sgx_provision", SYMLINK+="sgx/provision"
|
||||
'';
|
||||
})
|
||||
];
|
||||
}
|
||||
|
|
23
third_party/nixpkgs/nixos/modules/hardware/hackrf.nix
vendored
Normal file
23
third_party/nixpkgs/nixos/modules/hardware/hackrf.nix
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
cfg = config.hardware.hackrf;
|
||||
|
||||
in
|
||||
{
|
||||
options.hardware.hackrf = {
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Enables hackrf udev rules and ensures 'plugdev' group exists.
|
||||
This is a prerequisite to using HackRF devices without being root, since HackRF USB descriptors will be owned by plugdev through udev.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.udev.packages = [ pkgs.hackrf ];
|
||||
users.groups.plugdev = { };
|
||||
};
|
||||
}
|
|
@ -5,11 +5,15 @@ let
|
|||
|
||||
in {
|
||||
options.hardware.rtl-sdr = {
|
||||
enable = lib.mkEnableOption ''
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Enables rtl-sdr udev rules, ensures 'plugdev' group exists, and blacklists DVB kernel modules.
|
||||
This is a prerequisite to using devices supported by rtl-sdr without being root, since rtl-sdr USB descriptors will be owned by plugdev through udev.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
boot.blacklistedKernelModules = [ "dvb_usb_rtl28xxu" "e4000" "rtl2832" ];
|
||||
|
|
|
@ -11,23 +11,17 @@ let
|
|||
enabled = elem "amdgpu-pro" drivers;
|
||||
|
||||
package = config.boot.kernelPackages.amdgpu-pro;
|
||||
package32 = pkgs.pkgsi686Linux.linuxPackages.amdgpu-pro.override { libsOnly = true; kernel = null; };
|
||||
package32 = pkgs.pkgsi686Linux.linuxPackages.amdgpu-pro.override { kernel = null; };
|
||||
|
||||
opengl = config.hardware.opengl;
|
||||
|
||||
kernel = pkgs.linux_4_9.override {
|
||||
extraConfig = ''
|
||||
KALLSYMS_ALL y
|
||||
'';
|
||||
};
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
|
||||
config = mkIf enabled {
|
||||
|
||||
nixpkgs.config.xorg.abiCompat = "1.19";
|
||||
nixpkgs.config.xorg.abiCompat = "1.20";
|
||||
|
||||
services.xserver.drivers = singleton
|
||||
{ name = "amdgpu"; modules = [ package ]; display = true; };
|
||||
|
@ -36,31 +30,39 @@ in
|
|||
hardware.opengl.package32 = package32;
|
||||
hardware.opengl.setLdLibraryPath = true;
|
||||
|
||||
boot.extraModulePackages = [ package ];
|
||||
boot.extraModulePackages = [ package.kmod ];
|
||||
|
||||
boot.kernelPackages =
|
||||
pkgs.recurseIntoAttrs (pkgs.linuxPackagesFor kernel);
|
||||
boot.kernelPackages = pkgs.linuxKernel.packagesFor
|
||||
(pkgs.linuxKernel.kernels.linux_5_10.override {
|
||||
structuredExtraConfig = {
|
||||
DEVICE_PRIVATE = kernel.yes;
|
||||
KALLSYMS_ALL = kernel.yes;
|
||||
};
|
||||
});
|
||||
|
||||
boot.blacklistedKernelModules = [ "radeon" ];
|
||||
|
||||
hardware.firmware = [ package ];
|
||||
hardware.firmware = [ package.fw ];
|
||||
|
||||
system.activationScripts.setup-amdgpu-pro = ''
|
||||
mkdir -p /run/lib
|
||||
ln -sfn ${package}/lib ${package.libCompatDir}
|
||||
ln -sfn ${package} /run/amdgpu-pro
|
||||
'' + optionalString opengl.driSupport32Bit ''
|
||||
ln -sfn ${package32}/lib ${package32.libCompatDir}
|
||||
ln -sfn ${package}/opt/amdgpu{,-pro} /run
|
||||
'';
|
||||
|
||||
system.requiredKernelConfig = with config.lib.kernelConfig; [
|
||||
(isYes "DEVICE_PRIVATE")
|
||||
(isYes "KALLSYMS_ALL")
|
||||
];
|
||||
|
||||
boot.initrd.extraUdevRulesCommands = ''
|
||||
cp -v ${package}/etc/udev/rules.d/*.rules $out/
|
||||
'';
|
||||
|
||||
environment.systemPackages =
|
||||
[ package.vulkan ] ++
|
||||
# this isn't really DRI, but we'll reuse this option for now
|
||||
optional config.hardware.opengl.driSupport32Bit package32.vulkan;
|
||||
|
||||
environment.etc = {
|
||||
"amd/amdrc".source = package + "/etc/amd/amdrc";
|
||||
"amd/amdapfxx.blb".source = package + "/etc/amd/amdapfxx.blb";
|
||||
"gbm/gbm.conf".source = package + "/etc/gbm/gbm.conf";
|
||||
"modprobe.d/blacklist-radeon.conf".source = package + "/etc/modprobe.d/blacklist-radeon.conf";
|
||||
amd.source = package + "/etc/amd";
|
||||
};
|
||||
|
||||
};
|
||||
|
|
32
third_party/nixpkgs/nixos/modules/installer/sd-card/sd-image-riscv64-qemu.nix
vendored
Normal file
32
third_party/nixpkgs/nixos/modules/installer/sd-card/sd-image-riscv64-qemu.nix
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
# To build, use:
|
||||
# nix-build nixos -I nixos-config=nixos/modules/installer/sd-card/sd-image-riscv64-qemu.nix -A config.system.build.sdImage
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
../../profiles/base.nix
|
||||
./sd-image.nix
|
||||
];
|
||||
|
||||
boot.loader = {
|
||||
grub.enable = false;
|
||||
generic-extlinux-compatible = {
|
||||
enable = true;
|
||||
|
||||
# Don't even specify FDTDIR - We do not have the correct DT
|
||||
# The DTB is generated by QEMU at runtime
|
||||
useGenerationDeviceTree = false;
|
||||
};
|
||||
};
|
||||
|
||||
boot.consoleLogLevel = lib.mkDefault 7;
|
||||
boot.kernelParams = [ "console=tty0" "console=ttyS0,115200n8" ];
|
||||
|
||||
sdImage = {
|
||||
populateFirmwareCommands = "";
|
||||
populateRootCommands = ''
|
||||
mkdir -p ./files/boot
|
||||
${config.boot.loader.generic-extlinux-compatible.populateCmd} -c ${config.system.build.toplevel} -d ./files/boot
|
||||
'';
|
||||
};
|
||||
}
|
27
third_party/nixpkgs/nixos/modules/installer/sd-card/sd-image-x86_64.nix
vendored
Normal file
27
third_party/nixpkgs/nixos/modules/installer/sd-card/sd-image-x86_64.nix
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
# To build, use:
|
||||
# nix-build nixos -I nixos-config=nixos/modules/installer/sd-card/sd-image-x86_64.nix -A config.system.build.sdImage
|
||||
|
||||
# This image is primarily used in NixOS tests (boot.nix) to test `boot.loader.generic-extlinux-compatible`.
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
../../profiles/base.nix
|
||||
./sd-image.nix
|
||||
];
|
||||
|
||||
boot.loader = {
|
||||
grub.enable = false;
|
||||
generic-extlinux-compatible.enable = true;
|
||||
};
|
||||
|
||||
boot.consoleLogLevel = lib.mkDefault 7;
|
||||
|
||||
sdImage = {
|
||||
populateFirmwareCommands = "";
|
||||
populateRootCommands = ''
|
||||
mkdir -p ./files/boot
|
||||
${config.boot.loader.generic-extlinux-compatible.populateCmd} -c ${config.system.build.toplevel} -d ./files/boot
|
||||
'';
|
||||
};
|
||||
}
|
|
@ -176,7 +176,7 @@ in
|
|||
|
||||
nativeBuildInputs = [ dosfstools e2fsprogs mtools libfaketime util-linux zstd ];
|
||||
|
||||
inherit (config.sdImage) compressImage;
|
||||
inherit (config.sdImage) imageName compressImage;
|
||||
|
||||
buildCommand = ''
|
||||
mkdir -p $out/nix-support $out/sd-image
|
||||
|
|
|
@ -104,4 +104,6 @@ chroot_add_resolv_conf "$mountPoint" || print "ERROR: failed to set up resolv.co
|
|||
chroot "$mountPoint" systemd-tmpfiles --create --remove --exclude-prefix=/dev 1>&2 || true
|
||||
)
|
||||
|
||||
unset TMPDIR
|
||||
|
||||
exec chroot "$mountPoint" "${command[@]}"
|
||||
|
|
|
@ -76,7 +76,7 @@ let
|
|||
} ''
|
||||
export NIX_STORE_DIR=$TMPDIR/store
|
||||
export NIX_STATE_DIR=$TMPDIR/state
|
||||
${pkgs.nix}/bin/nix-instantiate \
|
||||
${pkgs.buildPackages.nix}/bin/nix-instantiate \
|
||||
--show-trace \
|
||||
--eval --json --strict \
|
||||
--argstr libPath "$libPath" \
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
./hardware/flirc.nix
|
||||
./hardware/gpgsmartcards.nix
|
||||
./hardware/i2c.nix
|
||||
./hardware/hackrf.nix
|
||||
./hardware/sensor/hddtemp.nix
|
||||
./hardware/sensor/iio.nix
|
||||
./hardware/keyboard/teck.nix
|
||||
|
@ -197,6 +198,7 @@
|
|||
./programs/ssmtp.nix
|
||||
./programs/sysdig.nix
|
||||
./programs/systemtap.nix
|
||||
./programs/starship.nix
|
||||
./programs/steam.nix
|
||||
./programs/sway.nix
|
||||
./programs/system-config-printer.nix
|
||||
|
@ -226,7 +228,7 @@
|
|||
./programs/zsh/zsh-autosuggestions.nix
|
||||
./programs/zsh/zsh-syntax-highlighting.nix
|
||||
./rename.nix
|
||||
./security/acme.nix
|
||||
./security/acme
|
||||
./security/apparmor.nix
|
||||
./security/audit.nix
|
||||
./security/auditd.nix
|
||||
|
@ -364,6 +366,7 @@
|
|||
./services/desktops/malcontent.nix
|
||||
./services/desktops/pipewire/pipewire.nix
|
||||
./services/desktops/pipewire/pipewire-media-session.nix
|
||||
./services/desktops/pipewire/wireplumber.nix
|
||||
./services/desktops/gnome/at-spi2-core.nix
|
||||
./services/desktops/gnome/chrome-gnome-shell.nix
|
||||
./services/desktops/gnome/evolution-data-server.nix
|
||||
|
@ -396,6 +399,7 @@
|
|||
./services/editors/emacs.nix
|
||||
./services/editors/infinoted.nix
|
||||
./services/finance/odoo.nix
|
||||
./services/games/asf.nix
|
||||
./services/games/crossfire-server.nix
|
||||
./services/games/deliantra-server.nix
|
||||
./services/games/factorio.nix
|
||||
|
@ -540,6 +544,7 @@
|
|||
./services/misc/gollum.nix
|
||||
./services/misc/gpsd.nix
|
||||
./services/misc/headphones.nix
|
||||
./services/misc/heisenbridge.nix
|
||||
./services/misc/greenclip.nix
|
||||
./services/misc/home-assistant.nix
|
||||
./services/misc/ihaskell.nix
|
||||
|
@ -743,6 +748,7 @@
|
|||
./services/networking/flannel.nix
|
||||
./services/networking/freenet.nix
|
||||
./services/networking/freeradius.nix
|
||||
./services/networking/frr.nix
|
||||
./services/networking/gateone.nix
|
||||
./services/networking/gdomap.nix
|
||||
./services/networking/ghostunnel.nix
|
||||
|
@ -796,6 +802,7 @@
|
|||
./services/networking/miredo.nix
|
||||
./services/networking/mstpd.nix
|
||||
./services/networking/mtprotoproxy.nix
|
||||
./services/networking/mtr-exporter.nix
|
||||
./services/networking/mullvad-vpn.nix
|
||||
./services/networking/multipath.nix
|
||||
./services/networking/murmur.nix
|
||||
|
@ -888,6 +895,7 @@
|
|||
./services/networking/tcpcrypt.nix
|
||||
./services/networking/teamspeak3.nix
|
||||
./services/networking/tedicross.nix
|
||||
./services/networking/teleport.nix
|
||||
./services/networking/thelounge.nix
|
||||
./services/networking/tinc.nix
|
||||
./services/networking/tinydns.nix
|
||||
|
@ -988,6 +996,7 @@
|
|||
./services/web-apps/bookstack.nix
|
||||
./services/web-apps/calibre-web.nix
|
||||
./services/web-apps/code-server.nix
|
||||
./services/web-apps/baget.nix
|
||||
./services/web-apps/convos.nix
|
||||
./services/web-apps/cryptpad.nix
|
||||
./services/web-apps/dex.nix
|
||||
|
@ -1026,6 +1035,7 @@
|
|||
./services/web-apps/plausible.nix
|
||||
./services/web-apps/pgpkeyserver-lite.nix
|
||||
./services/web-apps/powerdns-admin.nix
|
||||
./services/web-apps/prosody-filer.nix
|
||||
./services/web-apps/matomo.nix
|
||||
./services/web-apps/openwebrx.nix
|
||||
./services/web-apps/restya-board.nix
|
||||
|
|
|
@ -44,12 +44,12 @@ in
|
|||
"ohci1394" "sbp2"
|
||||
|
||||
# Virtio (QEMU, KVM etc.) support.
|
||||
"virtio_net" "virtio_pci" "virtio_blk" "virtio_scsi" "virtio_balloon" "virtio_console"
|
||||
"virtio_net" "virtio_pci" "virtio_mmio" "virtio_blk" "virtio_scsi" "virtio_balloon" "virtio_console"
|
||||
|
||||
# VMware support.
|
||||
"mptspi" "vmxnet3" "vsock"
|
||||
] ++ lib.optional platform.isx86 "vmw_balloon"
|
||||
++ lib.optionals (!platform.isAarch64 && !platform.isAarch32) [ # not sure where else they're missing
|
||||
++ lib.optionals (pkgs.stdenv.isi686 || pkgs.stdenv.isx86_64) [
|
||||
"vmw_vmci" "vmwgfx" "vmw_vsock_vmci_transport"
|
||||
|
||||
# Hyper-V support.
|
||||
|
|
|
@ -25,6 +25,9 @@ let
|
|||
+ (if h.publicKey != null then h.publicKey else readFile h.publicKeyFile)
|
||||
)) + "\n";
|
||||
|
||||
knownHostsFiles = [ "/etc/ssh/ssh_known_hosts" "/etc/ssh/ssh_known_hosts2" ]
|
||||
++ map pkgs.copyPathToStore cfg.knownHostsFiles;
|
||||
|
||||
in
|
||||
{
|
||||
###### interface
|
||||
|
@ -177,7 +180,9 @@ in
|
|||
You can fetch a public key file from a running SSH server
|
||||
with the <command>ssh-keyscan</command> command. The content
|
||||
of the file should follow the same format as described for
|
||||
the <literal>publicKey</literal> option.
|
||||
the <literal>publicKey</literal> option. Only a single key
|
||||
is supported. If a host has multiple keys, use
|
||||
<option>programs.ssh.knownHostsFiles</option> instead.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
@ -202,6 +207,28 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
knownHostsFiles = mkOption {
|
||||
default = [];
|
||||
type = with types; listOf path;
|
||||
description = ''
|
||||
Files containing SSH host keys to set as global known hosts.
|
||||
<literal>/etc/ssh/ssh_known_hosts</literal> (which is
|
||||
generated by <option>programs.ssh.knownHosts</option>) and
|
||||
<literal>/etc/ssh/ssh_known_hosts2</literal> are always
|
||||
included.
|
||||
'';
|
||||
example = literalExpression ''
|
||||
[
|
||||
./known_hosts
|
||||
(writeText "github.keys" '''
|
||||
github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
|
||||
github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=
|
||||
github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl
|
||||
''')
|
||||
]
|
||||
'';
|
||||
};
|
||||
|
||||
kexAlgorithms = mkOption {
|
||||
type = types.nullOr (types.listOf types.str);
|
||||
default = null;
|
||||
|
@ -258,6 +285,7 @@ in
|
|||
# Generated options from other settings
|
||||
Host *
|
||||
AddressFamily ${if config.networking.enableIPv6 then "any" else "inet"}
|
||||
GlobalKnownHostsFile ${concatStringsSep " " knownHostsFiles}
|
||||
|
||||
${optionalString cfg.setXAuthLocation ''
|
||||
XAuthLocation ${pkgs.xorg.xauth}/bin/xauth
|
||||
|
|
51
third_party/nixpkgs/nixos/modules/programs/starship.nix
vendored
Normal file
51
third_party/nixpkgs/nixos/modules/programs/starship.nix
vendored
Normal file
|
@ -0,0 +1,51 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.programs.starship;
|
||||
|
||||
settingsFormat = pkgs.formats.toml { };
|
||||
|
||||
settingsFile = settingsFormat.generate "starship.toml" cfg.settings;
|
||||
|
||||
in {
|
||||
options.programs.starship = {
|
||||
enable = mkEnableOption "the Starship shell prompt";
|
||||
|
||||
settings = mkOption {
|
||||
inherit (settingsFormat) type;
|
||||
default = { };
|
||||
description = ''
|
||||
Configuration included in <literal>starship.toml</literal>.
|
||||
|
||||
See https://starship.rs/config/#prompt for documentation.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
programs.bash.promptInit = ''
|
||||
if [[ $TERM != "dumb" && (-z $INSIDE_EMACS || $INSIDE_EMACS == "vterm") ]]; then
|
||||
export STARSHIP_CONFIG=${settingsFile}
|
||||
eval "$(${pkgs.starship}/bin/starship init bash)"
|
||||
fi
|
||||
'';
|
||||
|
||||
programs.fish.promptInit = ''
|
||||
if test "$TERM" != "dumb" -a \( -z "$INSIDE_EMACS" -o "$INSIDE_EMACS" = "vterm" \)
|
||||
set -x STARSHIP_CONFIG ${settingsFile}
|
||||
eval (${pkgs.starship}/bin/starship init fish)
|
||||
end
|
||||
'';
|
||||
|
||||
programs.zsh.promptInit = ''
|
||||
if [[ $TERM != "dumb" && (-z $INSIDE_EMACS || $INSIDE_EMACS == "vterm") ]]; then
|
||||
export STARSHIP_CONFIG=${settingsFile}
|
||||
eval "$(${pkgs.starship}/bin/starship init zsh)"
|
||||
fi
|
||||
'';
|
||||
};
|
||||
|
||||
meta.maintainers = pkgs.starship.meta.maintainers;
|
||||
}
|
|
@ -916,6 +916,6 @@ in {
|
|||
|
||||
meta = {
|
||||
maintainers = lib.teams.acme.members;
|
||||
doc = ./acme.xml;
|
||||
doc = ./doc.xml;
|
||||
};
|
||||
}
|
4
third_party/nixpkgs/nixos/modules/security/acme/mk-cert-ownership-assertion.nix
vendored
Normal file
4
third_party/nixpkgs/nixos/modules/security/acme/mk-cert-ownership-assertion.nix
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
{ cert, group, groups, user }: {
|
||||
assertion = cert.group == group || builtins.any (u: u == user) groups.${cert.group}.members;
|
||||
message = "Group for certificate ${cert.domain} must be ${group}, or user ${user} must be a member of group ${cert.group}";
|
||||
}
|
|
@ -1072,8 +1072,8 @@ in
|
|||
security.apparmor.includes."abstractions/pam" = let
|
||||
isEnabled = test: fold or false (map test (attrValues config.security.pam.services));
|
||||
in
|
||||
lib.concatMapStringsSep "\n"
|
||||
(name: "r ${config.environment.etc."pam.d/${name}".source},")
|
||||
lib.concatMapStrings
|
||||
(name: "r ${config.environment.etc."pam.d/${name}".source},\n")
|
||||
(attrNames config.security.pam.services) +
|
||||
''
|
||||
mr ${getLib pkgs.pam}/lib/security/pam_filter/*,
|
||||
|
|
|
@ -209,62 +209,42 @@ in {
|
|||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
# install mpd units
|
||||
systemd.packages = [ pkgs.mpd ];
|
||||
|
||||
systemd.sockets.mpd = mkIf cfg.startWhenNeeded {
|
||||
description = "Music Player Daemon Socket";
|
||||
wantedBy = [ "sockets.target" ];
|
||||
listenStreams = [
|
||||
(if pkgs.lib.hasPrefix "/" cfg.network.listenAddress
|
||||
then cfg.network.listenAddress
|
||||
else "${optionalString (cfg.network.listenAddress != "any") "${cfg.network.listenAddress}:"}${toString cfg.network.port}")
|
||||
];
|
||||
socketConfig = {
|
||||
Backlog = 5;
|
||||
KeepAlive = true;
|
||||
PassCredentials = true;
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.mpd = {
|
||||
after = [ "network.target" "sound.target" ];
|
||||
description = "Music Player Daemon";
|
||||
wantedBy = optional (!cfg.startWhenNeeded) "multi-user.target";
|
||||
|
||||
serviceConfig = mkMerge [
|
||||
{
|
||||
User = "${cfg.user}";
|
||||
ExecStart = "${pkgs.mpd}/bin/mpd --no-daemon /run/mpd/mpd.conf";
|
||||
ExecStartPre = pkgs.writeShellScript "mpd-start-pre" (''
|
||||
preStart =
|
||||
''
|
||||
set -euo pipefail
|
||||
install -m 600 ${mpdConf} /run/mpd/mpd.conf
|
||||
'' + optionalString (cfg.credentials != [])
|
||||
(concatStringsSep "\n"
|
||||
(imap0
|
||||
(i: c: ''${pkgs.replace-secret}/bin/replace-secret '{{password-${toString i}}}' '${c.passwordFile}' /run/mpd/mpd.conf'')
|
||||
cfg.credentials))
|
||||
);
|
||||
cfg.credentials));
|
||||
|
||||
serviceConfig =
|
||||
{
|
||||
User = "${cfg.user}";
|
||||
# Note: the first "" overrides the ExecStart from the upstream unit
|
||||
ExecStart = [ "" "${pkgs.mpd}/bin/mpd --systemd /run/mpd/mpd.conf" ];
|
||||
RuntimeDirectory = "mpd";
|
||||
Type = "notify";
|
||||
LimitRTPRIO = 50;
|
||||
LimitRTTIME = "infinity";
|
||||
ProtectSystem = true;
|
||||
NoNewPrivileges = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectKernelModules = true;
|
||||
RestrictAddressFamilies = "AF_INET AF_INET6 AF_UNIX AF_NETLINK";
|
||||
RestrictNamespaces = true;
|
||||
Restart = "always";
|
||||
}
|
||||
(mkIf (cfg.dataDir == "/var/lib/${name}") {
|
||||
StateDirectory = [ name ];
|
||||
})
|
||||
(mkIf (cfg.playlistDirectory == "/var/lib/${name}/playlists") {
|
||||
StateDirectory = [ name "${name}/playlists" ];
|
||||
})
|
||||
(mkIf (cfg.musicDirectory == "/var/lib/${name}/music") {
|
||||
StateDirectory = [ name "${name}/music" ];
|
||||
})
|
||||
];
|
||||
StateDirectory = []
|
||||
++ optionals (cfg.dataDir == "/var/lib/${name}") [ name ]
|
||||
++ optionals (cfg.playlistDirectory == "/var/lib/${name}/playlists") [ name "${name}/playlists" ]
|
||||
++ optionals (cfg.musicDirectory == "/var/lib/${name}/music") [ name "${name}/music" ];
|
||||
};
|
||||
};
|
||||
|
||||
users.users = optionalAttrs (cfg.user == name) {
|
||||
|
|
|
@ -167,4 +167,5 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
meta.buildDocsInSandbox = false;
|
||||
}
|
||||
|
|
|
@ -363,4 +363,6 @@ in {
|
|||
|
||||
services.kubernetes.kubelet.clusterDns = mkDefault cfg.clusterIp;
|
||||
};
|
||||
|
||||
meta.buildDocsInSandbox = false;
|
||||
}
|
||||
|
|
|
@ -496,4 +496,5 @@ in
|
|||
|
||||
];
|
||||
|
||||
meta.buildDocsInSandbox = false;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ let
|
|||
top = config.services.kubernetes;
|
||||
otop = options.services.kubernetes;
|
||||
cfg = top.controllerManager;
|
||||
klib = options.services.kubernetes.lib.default;
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
|
@ -57,7 +56,7 @@ in
|
|||
type = int;
|
||||
};
|
||||
|
||||
kubeconfig = klib.mkKubeConfigOptions "Kubernetes controller manager";
|
||||
kubeconfig = top.lib.mkKubeConfigOptions "Kubernetes controller manager";
|
||||
|
||||
leaderElect = mkOption {
|
||||
description = "Whether to start leader election before executing main loop.";
|
||||
|
@ -130,7 +129,7 @@ in
|
|||
"--cluster-cidr=${cfg.clusterCidr}"} \
|
||||
${optionalString (cfg.featureGates != [])
|
||||
"--feature-gates=${concatMapStringsSep "," (feature: "${feature}=true") cfg.featureGates}"} \
|
||||
--kubeconfig=${klib.mkKubeConfig "kube-controller-manager" cfg.kubeconfig} \
|
||||
--kubeconfig=${top.lib.mkKubeConfig "kube-controller-manager" cfg.kubeconfig} \
|
||||
--leader-elect=${boolToString cfg.leaderElect} \
|
||||
${optionalString (cfg.rootCaFile!=null)
|
||||
"--root-ca-file=${cfg.rootCaFile}"} \
|
||||
|
@ -157,7 +156,7 @@ in
|
|||
path = top.path;
|
||||
};
|
||||
|
||||
services.kubernetes.pki.certs = with klib; {
|
||||
services.kubernetes.pki.certs = with top.lib; {
|
||||
controllerManager = mkCert {
|
||||
name = "kube-controller-manager";
|
||||
CN = "kube-controller-manager";
|
||||
|
@ -172,4 +171,6 @@ in
|
|||
|
||||
services.kubernetes.controllerManager.kubeconfig.server = mkDefault top.apiserverAddress;
|
||||
};
|
||||
|
||||
meta.buildDocsInSandbox = false;
|
||||
}
|
||||
|
|
|
@ -26,10 +26,7 @@ let
|
|||
|
||||
containerd.runtimes.runc = {
|
||||
runtime_type = "io.containerd.runc.v2";
|
||||
};
|
||||
|
||||
containerd.runtimes."io.containerd.runc.v2".options = {
|
||||
SystemdCgroup = true;
|
||||
options.SystemdCgroup = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -193,8 +190,6 @@ in {
|
|||
inherit mkKubeConfigOptions;
|
||||
};
|
||||
type = types.attrs;
|
||||
readOnly = true;
|
||||
internal = true;
|
||||
};
|
||||
|
||||
secretsPath = mkOption {
|
||||
|
@ -315,4 +310,6 @@ in {
|
|||
else "${cfg.masterAddress}:${toString cfg.apiserver.securePort}"}");
|
||||
})
|
||||
];
|
||||
|
||||
meta.buildDocsInSandbox = false;
|
||||
}
|
||||
|
|
|
@ -95,4 +95,6 @@ in
|
|||
|
||||
};
|
||||
};
|
||||
|
||||
meta.buildDocsInSandbox = false;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ let
|
|||
top = config.services.kubernetes;
|
||||
otop = options.services.kubernetes;
|
||||
cfg = top.kubelet;
|
||||
klib = options.services.kubernetes.lib.default;
|
||||
|
||||
cniConfig =
|
||||
if cfg.cni.config != [] && cfg.cni.configDir != null then
|
||||
|
@ -28,7 +27,7 @@ let
|
|||
config.Cmd = ["/bin/pause"];
|
||||
};
|
||||
|
||||
kubeconfig = klib.mkKubeConfig "kubelet" cfg.kubeconfig;
|
||||
kubeconfig = top.lib.mkKubeConfig "kubelet" cfg.kubeconfig;
|
||||
|
||||
manifestPath = "kubernetes/manifests";
|
||||
|
||||
|
@ -178,7 +177,7 @@ in
|
|||
type = str;
|
||||
};
|
||||
|
||||
kubeconfig = klib.mkKubeConfigOptions "Kubelet";
|
||||
kubeconfig = top.lib.mkKubeConfigOptions "Kubelet";
|
||||
|
||||
manifests = mkOption {
|
||||
description = "List of manifests to bootstrap with kubelet (only pods can be created as manifest entry)";
|
||||
|
@ -265,8 +264,6 @@ in
|
|||
"net.bridge.bridge-nf-call-ip6tables" = 1;
|
||||
};
|
||||
|
||||
systemd.enableUnifiedCgroupHierarchy = false; # true breaks node memory metrics
|
||||
|
||||
systemd.services.kubelet = {
|
||||
description = "Kubernetes Kubelet Service";
|
||||
wantedBy = [ "kubernetes.target" ];
|
||||
|
@ -359,7 +356,7 @@ in
|
|||
services.kubernetes.kubelet.hostname = with config.networking;
|
||||
mkDefault (hostName + optionalString (domain != null) ".${domain}");
|
||||
|
||||
services.kubernetes.pki.certs = with klib; {
|
||||
services.kubernetes.pki.certs = with top.lib; {
|
||||
kubelet = mkCert {
|
||||
name = "kubelet";
|
||||
CN = top.kubelet.hostname;
|
||||
|
@ -396,4 +393,6 @@ in
|
|||
})
|
||||
|
||||
];
|
||||
|
||||
meta.buildDocsInSandbox = false;
|
||||
}
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
{ config, options, lib, pkgs, ... }:
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
top = config.services.kubernetes;
|
||||
cfg = top.pki;
|
||||
klib = options.services.kubernetes.lib;
|
||||
|
||||
csrCA = pkgs.writeText "kube-pki-cacert-csr.json" (builtins.toJSON {
|
||||
key = {
|
||||
|
@ -30,7 +29,7 @@ let
|
|||
cfsslAPITokenLength = 32;
|
||||
|
||||
clusterAdminKubeconfig = with cfg.certs.clusterAdmin;
|
||||
klib.mkKubeConfig "cluster-admin" {
|
||||
top.lib.mkKubeConfig "cluster-admin" {
|
||||
server = top.apiserverAddress;
|
||||
certFile = cert;
|
||||
keyFile = key;
|
||||
|
@ -251,7 +250,7 @@ in
|
|||
# - it would be better with a more Nix-oriented way of managing addons
|
||||
systemd.services.kube-addon-manager = mkIf top.addonManager.enable (mkMerge [{
|
||||
environment.KUBECONFIG = with cfg.certs.addonManager;
|
||||
klib.mkKubeConfig "addon-manager" {
|
||||
top.lib.mkKubeConfig "addon-manager" {
|
||||
server = top.apiserverAddress;
|
||||
certFile = cert;
|
||||
keyFile = key;
|
||||
|
@ -344,7 +343,7 @@ in
|
|||
'';
|
||||
|
||||
services.flannel = with cfg.certs.flannelClient; {
|
||||
kubeconfig = klib.mkKubeConfig "flannel" {
|
||||
kubeconfig = top.lib.mkKubeConfig "flannel" {
|
||||
server = top.apiserverAddress;
|
||||
certFile = cert;
|
||||
keyFile = key;
|
||||
|
@ -402,4 +401,6 @@ in
|
|||
};
|
||||
};
|
||||
});
|
||||
|
||||
meta.buildDocsInSandbox = false;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ let
|
|||
top = config.services.kubernetes;
|
||||
otop = options.services.kubernetes;
|
||||
cfg = top.proxy;
|
||||
klib = options.services.kubernetes.lib.default;
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
|
@ -44,7 +43,7 @@ in
|
|||
type = str;
|
||||
};
|
||||
|
||||
kubeconfig = klib.mkKubeConfigOptions "Kubernetes proxy";
|
||||
kubeconfig = top.lib.mkKubeConfigOptions "Kubernetes proxy";
|
||||
|
||||
verbosity = mkOption {
|
||||
description = ''
|
||||
|
@ -73,7 +72,7 @@ in
|
|||
${optionalString (cfg.featureGates != [])
|
||||
"--feature-gates=${concatMapStringsSep "," (feature: "${feature}=true") cfg.featureGates}"} \
|
||||
--hostname-override=${cfg.hostname} \
|
||||
--kubeconfig=${klib.mkKubeConfig "kube-proxy" cfg.kubeconfig} \
|
||||
--kubeconfig=${top.lib.mkKubeConfig "kube-proxy" cfg.kubeconfig} \
|
||||
${optionalString (cfg.verbosity != null) "--v=${toString cfg.verbosity}"} \
|
||||
${cfg.extraOpts}
|
||||
'';
|
||||
|
@ -89,7 +88,7 @@ in
|
|||
services.kubernetes.proxy.hostname = with config.networking; mkDefault hostName;
|
||||
|
||||
services.kubernetes.pki.certs = {
|
||||
kubeProxyClient = klib.mkCert {
|
||||
kubeProxyClient = top.lib.mkCert {
|
||||
name = "kube-proxy-client";
|
||||
CN = "system:kube-proxy";
|
||||
action = "systemctl restart kube-proxy.service";
|
||||
|
@ -98,4 +97,6 @@ in
|
|||
|
||||
services.kubernetes.proxy.kubeconfig.server = mkDefault top.apiserverAddress;
|
||||
};
|
||||
|
||||
meta.buildDocsInSandbox = false;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ let
|
|||
top = config.services.kubernetes;
|
||||
otop = options.services.kubernetes;
|
||||
cfg = top.scheduler;
|
||||
klib = options.services.kubernetes.lib.default;
|
||||
in
|
||||
{
|
||||
###### interface
|
||||
|
@ -33,7 +32,7 @@ in
|
|||
type = listOf str;
|
||||
};
|
||||
|
||||
kubeconfig = klib.mkKubeConfigOptions "Kubernetes scheduler";
|
||||
kubeconfig = top.lib.mkKubeConfigOptions "Kubernetes scheduler";
|
||||
|
||||
leaderElect = mkOption {
|
||||
description = "Whether to start leader election before executing main loop.";
|
||||
|
@ -70,7 +69,7 @@ in
|
|||
--address=${cfg.address} \
|
||||
${optionalString (cfg.featureGates != [])
|
||||
"--feature-gates=${concatMapStringsSep "," (feature: "${feature}=true") cfg.featureGates}"} \
|
||||
--kubeconfig=${klib.mkKubeConfig "kube-scheduler" cfg.kubeconfig} \
|
||||
--kubeconfig=${top.lib.mkKubeConfig "kube-scheduler" cfg.kubeconfig} \
|
||||
--leader-elect=${boolToString cfg.leaderElect} \
|
||||
--port=${toString cfg.port} \
|
||||
${optionalString (cfg.verbosity != null) "--v=${toString cfg.verbosity}"} \
|
||||
|
@ -88,7 +87,7 @@ in
|
|||
};
|
||||
|
||||
services.kubernetes.pki.certs = {
|
||||
schedulerClient = klib.mkCert {
|
||||
schedulerClient = top.lib.mkCert {
|
||||
name = "kube-scheduler-client";
|
||||
CN = "system:kube-scheduler";
|
||||
action = "systemctl restart kube-scheduler.service";
|
||||
|
@ -97,4 +96,6 @@ in
|
|||
|
||||
services.kubernetes.scheduler.kubeconfig.server = mkDefault top.apiserverAddress;
|
||||
};
|
||||
|
||||
meta.buildDocsInSandbox = false;
|
||||
}
|
||||
|
|
|
@ -57,26 +57,12 @@ in
|
|||
pkgs.gnome.gnome-settings-daemon
|
||||
];
|
||||
|
||||
systemd.user.targets."gnome-session-initialized".wants = [
|
||||
"gsd-color.target"
|
||||
"gsd-datetime.target"
|
||||
"gsd-keyboard.target"
|
||||
"gsd-media-keys.target"
|
||||
"gsd-print-notifications.target"
|
||||
"gsd-rfkill.target"
|
||||
"gsd-screensaver-proxy.target"
|
||||
"gsd-sharing.target"
|
||||
"gsd-smartcard.target"
|
||||
"gsd-sound.target"
|
||||
"gsd-wacom.target"
|
||||
"gsd-wwan.target"
|
||||
"gsd-a11y-settings.target"
|
||||
"gsd-housekeeping.target"
|
||||
"gsd-power.target"
|
||||
systemd.user.targets."gnome-session-x11-services".wants = [
|
||||
"org.gnome.SettingsDaemon.XSettings.service"
|
||||
];
|
||||
|
||||
systemd.user.targets."gnome-session-x11-services".wants = [
|
||||
"gsd-xsettings.target"
|
||||
systemd.user.targets."gnome-session-x11-services-ready".wants = [
|
||||
"org.gnome.SettingsDaemon.XSettings.service"
|
||||
];
|
||||
|
||||
};
|
||||
|
|
|
@ -47,6 +47,8 @@ with lib;
|
|||
|
||||
systemd.packages = [ pkgs.tracker-miners ];
|
||||
|
||||
services.gnome.tracker.subcommandPackages = [ pkgs.tracker-miners ];
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -4,6 +4,9 @@
|
|||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.gnome.tracker;
|
||||
in
|
||||
{
|
||||
|
||||
meta = {
|
||||
|
@ -33,6 +36,15 @@ with lib;
|
|||
'';
|
||||
};
|
||||
|
||||
subcommandPackages = mkOption {
|
||||
type = types.listOf types.package;
|
||||
default = [ ];
|
||||
internal = true;
|
||||
description = ''
|
||||
List of packages containing tracker3 subcommands.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -40,7 +52,7 @@ with lib;
|
|||
|
||||
###### implementation
|
||||
|
||||
config = mkIf config.services.gnome.tracker.enable {
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
environment.systemPackages = [ pkgs.tracker ];
|
||||
|
||||
|
@ -48,6 +60,17 @@ with lib;
|
|||
|
||||
systemd.packages = [ pkgs.tracker ];
|
||||
|
||||
environment.variables = {
|
||||
TRACKER_CLI_SUBCOMMANDS_DIR =
|
||||
let
|
||||
subcommandPackagesTree = pkgs.symlinkJoin {
|
||||
name = "tracker-with-subcommands-${pkgs.tracker.version}";
|
||||
paths = [ pkgs.tracker ] ++ cfg.subcommandPackages;
|
||||
};
|
||||
in
|
||||
"${subcommandPackagesTree}/libexec/tracker3";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
41
third_party/nixpkgs/nixos/modules/services/desktops/pipewire/wireplumber.nix
vendored
Normal file
41
third_party/nixpkgs/nixos/modules/services/desktops/pipewire/wireplumber.nix
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
cfg = config.services.pipewire.wireplumber;
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.k900 ];
|
||||
|
||||
options = {
|
||||
services.pipewire.wireplumber = {
|
||||
enable = lib.mkEnableOption "A modular session / policy manager for PipeWire";
|
||||
|
||||
package = lib.mkOption {
|
||||
type = lib.types.package;
|
||||
default = pkgs.wireplumber;
|
||||
defaultText = lib.literalExpression "pkgs.wireplumber";
|
||||
description = ''
|
||||
The wireplumber derivation to use.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = !config.services.pipewire.media-session.enable;
|
||||
message = "WirePlumber and pipewire-media-session can't be enabled at the same time.";
|
||||
}
|
||||
];
|
||||
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
systemd.packages = [ cfg.package ];
|
||||
|
||||
systemd.services.wireplumber.enable = config.services.pipewire.systemWide;
|
||||
systemd.user.services.wireplumber.enable = !config.services.pipewire.systemWide;
|
||||
|
||||
systemd.services.wireplumber.wantedBy = [ "pipewire.service" ];
|
||||
systemd.user.services.wireplumber.wantedBy = [ "pipewire.service" ];
|
||||
};
|
||||
}
|
236
third_party/nixpkgs/nixos/modules/services/games/asf.nix
vendored
Normal file
236
third_party/nixpkgs/nixos/modules/services/games/asf.nix
vendored
Normal file
|
@ -0,0 +1,236 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.archisteamfarm;
|
||||
|
||||
format = pkgs.formats.json { };
|
||||
|
||||
asf-config = format.generate "ASF.json" (cfg.settings // {
|
||||
# we disable it because ASF cannot update itself anyways
|
||||
# and nixos takes care of restarting the service
|
||||
# is in theory not needed as this is already the default for default builds
|
||||
UpdateChannel = 0;
|
||||
Headless = true;
|
||||
});
|
||||
|
||||
ipc-config = format.generate "IPC.config" cfg.ipcSettings;
|
||||
|
||||
mkBot = n: c:
|
||||
format.generate "${n}.json" (c.settings // {
|
||||
SteamLogin = if c.username == "" then n else c.username;
|
||||
SteamPassword = c.passwordFile;
|
||||
# sets the password format to file (https://github.com/JustArchiNET/ArchiSteamFarm/wiki/Security#file)
|
||||
PasswordFormat = 4;
|
||||
Enabled = c.enabled;
|
||||
});
|
||||
in
|
||||
{
|
||||
options.services.archisteamfarm = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
description = ''
|
||||
If enabled, starts the ArchisSteamFarm service.
|
||||
For configuring the SteamGuard token you will need to use the web-ui, which is enabled by default over on 127.0.0.1:1242.
|
||||
You cannot configure ASF in any way outside of nix, since all the config files get wiped on restart and replaced with the programatically set ones by nix.
|
||||
'';
|
||||
default = false;
|
||||
};
|
||||
|
||||
web-ui = mkOption {
|
||||
type = types.submodule {
|
||||
options = {
|
||||
enable = mkEnableOption
|
||||
"Wheter to start the web-ui. This is the preferred way of configuring things such as the steam guard token";
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.ArchiSteamFarm.ui;
|
||||
description =
|
||||
"Web-UI package to use. Contents must be in lib/dist.";
|
||||
};
|
||||
};
|
||||
};
|
||||
default = {
|
||||
enable = true;
|
||||
package = pkgs.ArchiSteamFarm.ui;
|
||||
};
|
||||
example = {
|
||||
enable = false;
|
||||
};
|
||||
description = "The Web-UI hosted on 127.0.0.1:1242.";
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.ArchiSteamFarm;
|
||||
description =
|
||||
"Package to use. Should always be the latest version, for security reasons, since this module uses very new features and to not get out of sync with the Steam API.";
|
||||
};
|
||||
|
||||
dataDir = mkOption {
|
||||
type = types.path;
|
||||
default = "/var/lib/asf";
|
||||
description = ''
|
||||
The ASF home directory used to store all data.
|
||||
If left as the default value this directory will automatically be created before the ASF server starts, otherwise the sysadmin is responsible for ensuring the directory exists with appropriate ownership and permissions.'';
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
type = format.type;
|
||||
description = ''
|
||||
The ASF.json file, all the options are documented <link xlink:href="https://github.com/JustArchiNET/ArchiSteamFarm/wiki/Configuration#global-config">here</link>.
|
||||
Do note that `AutoRestart` and `UpdateChannel` is always to `false`
|
||||
respectively `0` because NixOS takes care of updating everything.
|
||||
`Headless` is also always set to `true` because there is no way to provide inputs via a systemd service.
|
||||
You should try to keep ASF up to date since upstream does not provide support for anything but the latest version and you're exposing yourself to all kinds of issues - as is outlined <link xlink:href="https://github.com/JustArchiNET/ArchiSteamFarm/wiki/Configuration#updateperiod">here</link>.
|
||||
'';
|
||||
example = {
|
||||
Statistics = false;
|
||||
};
|
||||
default = { };
|
||||
};
|
||||
|
||||
ipcSettings = mkOption {
|
||||
type = format.type;
|
||||
description = ''
|
||||
Settings to write to IPC.config.
|
||||
All options can be found <link xlink:href="https://github.com/JustArchiNET/ArchiSteamFarm/wiki/IPC#custom-configuration">here</link>.
|
||||
'';
|
||||
example = {
|
||||
Kestrel = {
|
||||
Endpoints = {
|
||||
HTTP = {
|
||||
Url = "http://*:1242";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
};
|
||||
|
||||
bots = mkOption {
|
||||
type = types.attrsOf (types.submodule {
|
||||
options = {
|
||||
username = mkOption {
|
||||
type = types.str;
|
||||
description =
|
||||
"Name of the user to log in. Default is attribute name.";
|
||||
default = "";
|
||||
};
|
||||
passwordFile = mkOption {
|
||||
type = types.path;
|
||||
description =
|
||||
"Path to a file containig the password. The file must be readable by the <literal>asf</literal> user/group.";
|
||||
};
|
||||
enabled = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Whether to enable the bot on startup.";
|
||||
};
|
||||
settings = mkOption {
|
||||
type = types.attrs;
|
||||
description =
|
||||
"Additional settings that are documented <link xlink:href=\"https://github.com/JustArchiNET/ArchiSteamFarm/wiki/Configuration#bot-config\">here</link>.";
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
});
|
||||
description = ''
|
||||
Bots name and configuration.
|
||||
'';
|
||||
example = {
|
||||
exampleBot = {
|
||||
username = "alice";
|
||||
passwordFile = "/var/lib/asf/secrets/password";
|
||||
settings = { SteamParentalCode = "1234"; };
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
users = {
|
||||
users.asf = {
|
||||
home = cfg.dataDir;
|
||||
isSystemUser = true;
|
||||
group = "asf";
|
||||
description = "Archis-Steam-Farm service user";
|
||||
};
|
||||
groups.asf = { };
|
||||
};
|
||||
|
||||
systemd.services = {
|
||||
asf = {
|
||||
description = "Archis-Steam-Farm Service";
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
serviceConfig = mkMerge [
|
||||
(mkIf (cfg.dataDir == "/var/lib/asf") { StateDirectory = "asf"; })
|
||||
{
|
||||
User = "asf";
|
||||
Group = "asf";
|
||||
WorkingDirectory = cfg.dataDir;
|
||||
Type = "simple";
|
||||
ExecStart =
|
||||
"${cfg.package}/bin/ArchiSteamFarm --path ${cfg.dataDir} --process-required --no-restart --service --no-config-migrate";
|
||||
|
||||
# mostly copied from the default systemd service
|
||||
PrivateTmp = true;
|
||||
LockPersonality = true;
|
||||
PrivateDevices = true;
|
||||
PrivateIPC = true;
|
||||
PrivateMounts = true;
|
||||
PrivateUsers = true;
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHostname = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectProc = "invisible";
|
||||
ProtectSystem = "full";
|
||||
RemoveIPC = true;
|
||||
RestrictAddressFamilies = "AF_INET AF_INET6";
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true;
|
||||
}
|
||||
];
|
||||
|
||||
preStart = ''
|
||||
mkdir -p config
|
||||
rm -f www
|
||||
rm -f config/{*.json,*.config}
|
||||
|
||||
ln -s ${asf-config} config/ASF.json
|
||||
|
||||
${strings.optionalString (cfg.ipcSettings != {}) ''
|
||||
ln -s ${ipc-config} config/IPC.config
|
||||
''}
|
||||
|
||||
ln -s ${pkgs.runCommandLocal "ASF-bots" {} ''
|
||||
mkdir -p $out/lib/asf/bots
|
||||
for i in ${strings.concatStringsSep " " (lists.map (x: "${getName x},${x}") (attrsets.mapAttrsToList mkBot cfg.bots))}; do IFS=",";
|
||||
set -- $i
|
||||
ln -s $2 $out/lib/asf/bots/$1
|
||||
done
|
||||
''}/lib/asf/bots/* config/
|
||||
|
||||
${strings.optionalString cfg.web-ui.enable ''
|
||||
ln -s ${cfg.web-ui.package}/lib/dist www
|
||||
''}
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
meta = {
|
||||
buildDocsInSandbox = false;
|
||||
maintainers = with maintainers; [ lom ];
|
||||
};
|
||||
}
|
|
@ -23,7 +23,7 @@ let
|
|||
in
|
||||
{
|
||||
options.services.heisenbridge = {
|
||||
enable = mkEnableOption "the Matrix<->IRC bridge";
|
||||
enable = mkEnableOption "A bouncer-style Matrix IRC bridge";
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
|
|
|
@ -19,8 +19,17 @@ let
|
|||
"${wrappedPlugins}/libexec/netdata/plugins.d"
|
||||
] ++ cfg.extraPluginPaths;
|
||||
|
||||
configDirectory = pkgs.runCommand "netdata-config-d" { } ''
|
||||
mkdir $out
|
||||
${concatStringsSep "\n" (mapAttrsToList (path: file: ''
|
||||
mkdir -p "$out/$(dirname ${path})"
|
||||
ln -s "${file}" "$out/${path}"
|
||||
'') cfg.configDir)}
|
||||
'';
|
||||
|
||||
localConfig = {
|
||||
global = {
|
||||
"config directory" = "/etc/netdata/conf.d";
|
||||
"plugins directory" = concatStringsSep " " plugins;
|
||||
};
|
||||
web = {
|
||||
|
@ -130,6 +139,26 @@ in {
|
|||
'';
|
||||
};
|
||||
|
||||
configDir = mkOption {
|
||||
type = types.attrsOf types.path;
|
||||
default = {};
|
||||
description = ''
|
||||
Complete netdata config directory except netdata.conf.
|
||||
The default configuration is merged with changes
|
||||
defined in this option.
|
||||
Each top-level attribute denotes a path in the configuration
|
||||
directory as in environment.etc.
|
||||
Its value is the absolute path and must be readable by netdata.
|
||||
Cannot be combined with configText.
|
||||
'';
|
||||
example = literalExpression ''
|
||||
"health_alarm_notify.conf" = pkgs.writeText "health_alarm_notify.conf" '''
|
||||
sendmail="/path/to/sendmail"
|
||||
''';
|
||||
"health.d" = "/run/secrets/netdata/health.d";
|
||||
'';
|
||||
};
|
||||
|
||||
enableAnalyticsReporting = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
|
@ -150,11 +179,14 @@ in {
|
|||
}
|
||||
];
|
||||
|
||||
environment.etc."netdata/netdata.conf".source = configFile;
|
||||
environment.etc."netdata/conf.d".source = configDirectory;
|
||||
|
||||
systemd.services.netdata = {
|
||||
description = "Real time performance monitoring";
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
path = (with pkgs; [ curl gawk iproute2 which ])
|
||||
path = (with pkgs; [ curl gawk iproute2 which procps ])
|
||||
++ lib.optional cfg.python.enable (pkgs.python3.withPackages cfg.python.extraPackages)
|
||||
++ lib.optional config.virtualisation.libvirtd.enable (config.virtualisation.libvirtd.package);
|
||||
environment = {
|
||||
|
@ -162,8 +194,12 @@ in {
|
|||
} // lib.optionalAttrs (!cfg.enableAnalyticsReporting) {
|
||||
DO_NOT_TRACK = "1";
|
||||
};
|
||||
restartTriggers = [
|
||||
config.environment.etc."netdata/netdata.conf".source
|
||||
config.environment.etc."netdata/conf.d".source
|
||||
];
|
||||
serviceConfig = {
|
||||
ExecStart = "${cfg.package}/bin/netdata -P /run/netdata/netdata.pid -D -c ${configFile}";
|
||||
ExecStart = "${cfg.package}/bin/netdata -P /run/netdata/netdata.pid -D -c /etc/netdata/netdata.conf";
|
||||
ExecReload = "${pkgs.util-linux}/bin/kill -s HUP -s USR1 -s USR2 $MAINPID";
|
||||
TimeoutStopSec = 60;
|
||||
Restart = "on-failure";
|
||||
|
|
|
@ -252,8 +252,8 @@ let
|
|||
promTypes.scrape_config = types.submodule {
|
||||
options = {
|
||||
authorization = mkOption {
|
||||
type = types.attrs;
|
||||
default = {};
|
||||
type = types.nullOr types.attrs;
|
||||
default = null;
|
||||
description = ''
|
||||
Sets the `Authorization` header on every scrape request with the configured credentials.
|
||||
'';
|
||||
|
|
|
@ -13,7 +13,7 @@ let
|
|||
foreground=YES
|
||||
use=${cfg.use}
|
||||
login=${cfg.username}
|
||||
password=
|
||||
password=${lib.optionalString (cfg.protocol == "nsupdate") "/run/${RuntimeDirectory}/ddclient.key"}
|
||||
protocol=${cfg.protocol}
|
||||
${lib.optionalString (cfg.script != "") "script=${cfg.script}"}
|
||||
${lib.optionalString (cfg.server != "") "server=${cfg.server}"}
|
||||
|
@ -29,8 +29,10 @@ let
|
|||
configFile = if (cfg.configFile != null) then cfg.configFile else configFile';
|
||||
|
||||
preStart = ''
|
||||
install ${configFile} /run/${RuntimeDirectory}/ddclient.conf
|
||||
${lib.optionalString (cfg.configFile == null) (if (cfg.passwordFile != null) then ''
|
||||
install --owner ddclient -m600 ${configFile} /run/${RuntimeDirectory}/ddclient.conf
|
||||
${lib.optionalString (cfg.configFile == null) (if (cfg.protocol == "nsupdate") then ''
|
||||
install --owner ddclient -m600 ${cfg.passwordFile} /run/${RuntimeDirectory}/ddclient.key
|
||||
'' else if (cfg.passwordFile != null) then ''
|
||||
password=$(printf "%q" "$(head -n 1 "${cfg.passwordFile}")")
|
||||
sed -i "s|^password=$|password=$password|" /run/${RuntimeDirectory}/ddclient.conf
|
||||
'' else ''
|
||||
|
@ -85,7 +87,9 @@ with lib;
|
|||
};
|
||||
|
||||
username = mkOption {
|
||||
default = "";
|
||||
# For `nsupdate` username contains the path to the nsupdate executable
|
||||
default = lib.optionalString (config.services.ddclient.protocol == "nsupdate") "${pkgs.bind.dnsutils}/bin/nsupdate";
|
||||
defaultText = "";
|
||||
type = str;
|
||||
description = ''
|
||||
User name.
|
||||
|
@ -96,7 +100,7 @@ with lib;
|
|||
default = null;
|
||||
type = nullOr str;
|
||||
description = ''
|
||||
A file containing the password.
|
||||
A file containing the password or a TSIG key in named format when using the nsupdate protocol.
|
||||
'';
|
||||
};
|
||||
|
||||
|
|
211
third_party/nixpkgs/nixos/modules/services/networking/frr.nix
vendored
Normal file
211
third_party/nixpkgs/nixos/modules/services/networking/frr.nix
vendored
Normal file
|
@ -0,0 +1,211 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.frr;
|
||||
|
||||
services = [
|
||||
"static"
|
||||
"bgp"
|
||||
"ospf"
|
||||
"ospf6"
|
||||
"rip"
|
||||
"ripng"
|
||||
"isis"
|
||||
"pim"
|
||||
"ldp"
|
||||
"nhrp"
|
||||
"eigrp"
|
||||
"babel"
|
||||
"sharp"
|
||||
"pbr"
|
||||
"bfd"
|
||||
"fabric"
|
||||
];
|
||||
|
||||
allServices = services ++ [ "zebra" ];
|
||||
|
||||
isEnabled = service: cfg.${service}.enable;
|
||||
|
||||
daemonName = service: if service == "zebra" then service else "${service}d";
|
||||
|
||||
configFile = service:
|
||||
let
|
||||
scfg = cfg.${service};
|
||||
in
|
||||
if scfg.configFile != null then scfg.configFile
|
||||
else pkgs.writeText "${daemonName service}.conf"
|
||||
''
|
||||
! FRR ${daemonName service} configuration
|
||||
!
|
||||
hostname ${config.networking.hostName}
|
||||
log syslog
|
||||
service password-encryption
|
||||
!
|
||||
${scfg.config}
|
||||
!
|
||||
end
|
||||
'';
|
||||
|
||||
serviceOptions = service:
|
||||
{
|
||||
enable = mkEnableOption "the FRR ${toUpper service} routing protocol";
|
||||
|
||||
configFile = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
example = "/etc/frr/${daemonName service}.conf";
|
||||
description = ''
|
||||
Configuration file to use for FRR ${daemonName service}.
|
||||
By default the NixOS generated files are used.
|
||||
'';
|
||||
};
|
||||
|
||||
config = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
example =
|
||||
let
|
||||
examples = {
|
||||
rip = ''
|
||||
router rip
|
||||
network 10.0.0.0/8
|
||||
'';
|
||||
|
||||
ospf = ''
|
||||
router ospf
|
||||
network 10.0.0.0/8 area 0
|
||||
'';
|
||||
|
||||
bgp = ''
|
||||
router bgp 65001
|
||||
neighbor 10.0.0.1 remote-as 65001
|
||||
'';
|
||||
};
|
||||
in
|
||||
examples.${service} or "";
|
||||
description = ''
|
||||
${daemonName service} configuration statements.
|
||||
'';
|
||||
};
|
||||
|
||||
vtyListenAddress = mkOption {
|
||||
type = types.str;
|
||||
default = "localhost";
|
||||
description = ''
|
||||
Address to bind to for the VTY interface.
|
||||
'';
|
||||
};
|
||||
|
||||
vtyListenPort = mkOption {
|
||||
type = types.nullOr types.int;
|
||||
default = null;
|
||||
description = ''
|
||||
TCP Port to bind to for the VTY interface.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
|
||||
###### interface
|
||||
imports = [
|
||||
{
|
||||
options.services.frr = {
|
||||
zebra = (serviceOptions "zebra") // {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = any isEnabled services;
|
||||
description = ''
|
||||
Whether to enable the Zebra routing manager.
|
||||
|
||||
The Zebra routing manager is automatically enabled
|
||||
if any routing protocols are configured.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
{ options.services.frr = (genAttrs services serviceOptions); }
|
||||
];
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf (any isEnabled allServices) {
|
||||
|
||||
environment.systemPackages = [
|
||||
pkgs.frr # for the vtysh tool
|
||||
];
|
||||
|
||||
users.users.frr = {
|
||||
description = "FRR daemon user";
|
||||
isSystemUser = true;
|
||||
group = "frr";
|
||||
};
|
||||
|
||||
users.groups = {
|
||||
frr = {};
|
||||
# Members of the frrvty group can use vtysh to inspect the FRR daemons
|
||||
frrvty = { members = [ "frr" ]; };
|
||||
};
|
||||
|
||||
environment.etc = let
|
||||
mkEtcLink = service: {
|
||||
name = "frr/${service}.conf";
|
||||
value.source = configFile service;
|
||||
};
|
||||
in
|
||||
(builtins.listToAttrs
|
||||
(map mkEtcLink (filter isEnabled allServices))) // {
|
||||
"frr/vtysh.conf".text = "";
|
||||
};
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"d /run/frr 0750 frr frr -"
|
||||
];
|
||||
|
||||
systemd.services =
|
||||
let
|
||||
frrService = service:
|
||||
let
|
||||
scfg = cfg.${service};
|
||||
daemon = daemonName service;
|
||||
in
|
||||
nameValuePair daemon ({
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network-pre.target" "systemd-sysctl.service" ] ++ lib.optionals (service != "zebra") [ "zebra.service" ];
|
||||
bindsTo = lib.optionals (service != "zebra") [ "zebra.service" ];
|
||||
wants = [ "network.target" ];
|
||||
|
||||
description = if service == "zebra" then "FRR Zebra routing manager"
|
||||
else "FRR ${toUpper service} routing daemon";
|
||||
|
||||
unitConfig.Documentation = if service == "zebra" then "man:zebra(8)"
|
||||
else "man:${daemon}(8) man:zebra(8)";
|
||||
|
||||
restartTriggers = [
|
||||
(configFile service)
|
||||
];
|
||||
reloadIfChanged = true;
|
||||
|
||||
serviceConfig = {
|
||||
PIDFile = "frr/${daemon}.pid";
|
||||
ExecStart = "${pkgs.frr}/libexec/frr/${daemon} -f /etc/frr/${service}.conf"
|
||||
+ optionalString (scfg.vtyListenAddress != "") " -A ${scfg.vtyListenAddress}"
|
||||
+ optionalString (scfg.vtyListenPort != null) " -P ${toString scfg.vtyListenPort}";
|
||||
ExecReload = "${pkgs.python3.interpreter} ${pkgs.frr}/libexec/frr/frr-reload.py --reload --daemon ${daemonName service} --bindir ${pkgs.frr}/bin --rundir /run/frr /etc/frr/${service}.conf";
|
||||
Restart = "on-abnormal";
|
||||
};
|
||||
});
|
||||
in
|
||||
listToAttrs (map frrService (filter isEnabled allServices));
|
||||
|
||||
};
|
||||
|
||||
meta.maintainers = with lib.maintainers; [ woffs ];
|
||||
|
||||
}
|
|
@ -7,15 +7,16 @@ let
|
|||
|
||||
# Convert systemd-style address specification to kresd config line(s).
|
||||
# On Nix level we don't attempt to precisely validate the address specifications.
|
||||
# The optional IPv6 scope spec comes *after* port, perhaps surprisingly.
|
||||
mkListen = kind: addr: let
|
||||
al_v4 = builtins.match "([0-9.]+):([0-9]+)" addr;
|
||||
al_v6 = builtins.match "\\[(.+)]:([0-9]+)" addr;
|
||||
al_v4 = builtins.match "([0-9.]+):([0-9]+)()" addr;
|
||||
al_v6 = builtins.match "\\[(.+)]:([0-9]+)(%.*|$)" addr;
|
||||
al_portOnly = builtins.match "([0-9]+)" addr;
|
||||
al = findFirst (a: a != null)
|
||||
(throw "services.kresd.*: incorrect address specification '${addr}'")
|
||||
[ al_v4 al_v6 al_portOnly ];
|
||||
port = last al;
|
||||
addrSpec = if al_portOnly == null then "'${head al}'" else "{'::', '0.0.0.0'}";
|
||||
port = elemAt al 1;
|
||||
addrSpec = if al_portOnly == null then "'${head al}${elemAt al 2}'" else "{'::', '0.0.0.0'}";
|
||||
in # freebind is set for compatibility with earlier kresd services;
|
||||
# it could be configurable, for example.
|
||||
''
|
||||
|
|
87
third_party/nixpkgs/nixos/modules/services/networking/mtr-exporter.nix
vendored
Normal file
87
third_party/nixpkgs/nixos/modules/services/networking/mtr-exporter.nix
vendored
Normal file
|
@ -0,0 +1,87 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
inherit (lib)
|
||||
maintainers types mkEnableOption mkOption mkIf
|
||||
literalExpression escapeShellArg escapeShellArgs;
|
||||
cfg = config.services.mtr-exporter;
|
||||
in {
|
||||
options = {
|
||||
services = {
|
||||
mtr-exporter = {
|
||||
enable = mkEnableOption "a Prometheus exporter for MTR";
|
||||
|
||||
target = mkOption {
|
||||
type = types.str;
|
||||
example = "example.org";
|
||||
description = "Target to check using MTR.";
|
||||
};
|
||||
|
||||
interval = mkOption {
|
||||
type = types.int;
|
||||
default = 60;
|
||||
description = "Interval between MTR checks in seconds.";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 8080;
|
||||
description = "Listen port for MTR exporter.";
|
||||
};
|
||||
|
||||
address = mkOption {
|
||||
type = types.str;
|
||||
default = "127.0.0.1";
|
||||
description = "Listen address for MTR exporter.";
|
||||
};
|
||||
|
||||
mtrFlags = mkOption {
|
||||
type = with types; listOf str;
|
||||
default = [];
|
||||
example = ["-G1"];
|
||||
description = "Additional flags to pass to MTR.";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
systemd.services.mtr-exporter = {
|
||||
script = ''
|
||||
exec ${pkgs.mtr-exporter}/bin/mtr-exporter \
|
||||
-mtr ${pkgs.mtr}/bin/mtr \
|
||||
-schedule '@every ${toString cfg.interval}s' \
|
||||
-bind ${escapeShellArg cfg.address}:${toString cfg.port} \
|
||||
-- \
|
||||
${escapeShellArgs (cfg.mtrFlags ++ [ cfg.target ])}
|
||||
'';
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
requires = [ "network.target" ];
|
||||
after = [ "network.target" ];
|
||||
serviceConfig = {
|
||||
Restart = "on-failure";
|
||||
# Hardening
|
||||
CapabilityBoundingSet = [ "" ];
|
||||
DynamicUser = true;
|
||||
LockPersonality = true;
|
||||
ProcSubset = "pid";
|
||||
PrivateDevices = true;
|
||||
PrivateUsers = true;
|
||||
PrivateTmp = true;
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHome = true;
|
||||
ProtectHostname = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectProc = "invisible";
|
||||
ProtectSystem = "strict";
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
meta.maintainers = with maintainers; [ jakubgs ];
|
||||
}
|
|
@ -14,6 +14,8 @@ let
|
|||
|
||||
in
|
||||
{
|
||||
imports = [ (mkRemovedOptionModule [ "services" "sniproxy" "logDir" ] "Now done by LogsDirectory=. Set to a custom path if you log to a different folder in your config.") ];
|
||||
|
||||
options = {
|
||||
services.sniproxy = {
|
||||
enable = mkEnableOption "sniproxy server";
|
||||
|
@ -50,13 +52,6 @@ in
|
|||
}
|
||||
'';
|
||||
};
|
||||
|
||||
logDir = mkOption {
|
||||
type = types.str;
|
||||
default = "/var/log/sniproxy/";
|
||||
description = "Location of the log directory for sniproxy.";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -66,18 +61,12 @@ in
|
|||
description = "sniproxy server";
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
preStart = ''
|
||||
test -d ${cfg.logDir} || {
|
||||
echo "Creating initial log directory for sniproxy in ${cfg.logDir}"
|
||||
mkdir -p ${cfg.logDir}
|
||||
chmod 640 ${cfg.logDir}
|
||||
}
|
||||
chown -R ${cfg.user}:${cfg.group} ${cfg.logDir}
|
||||
'';
|
||||
|
||||
serviceConfig = {
|
||||
Type = "forking";
|
||||
ExecStart = "${pkgs.sniproxy}/bin/sniproxy -c ${configFile}";
|
||||
LogsDirectory = "sniproxy";
|
||||
LogsDirectoryMode = "0640";
|
||||
Restart = "always";
|
||||
};
|
||||
};
|
||||
|
|
|
@ -480,6 +480,8 @@ in
|
|||
else
|
||||
cfg.ports;
|
||||
socketConfig.Accept = true;
|
||||
# Prevent brute-force attacks from shutting down socket
|
||||
socketConfig.TriggerLimitIntervalSec = 0;
|
||||
};
|
||||
|
||||
services."sshd@" = service;
|
||||
|
|
|
@ -25,8 +25,8 @@ let
|
|||
};
|
||||
|
||||
connect = mkOption {
|
||||
type = types.int;
|
||||
description = "To which port the decrypted connection should be forwarded.";
|
||||
type = types.either types.str types.int;
|
||||
description = "Port or IP:Port to which the decrypted connection should be forwarded.";
|
||||
};
|
||||
|
||||
cert = mkOption {
|
||||
|
|
99
third_party/nixpkgs/nixos/modules/services/networking/teleport.nix
vendored
Normal file
99
third_party/nixpkgs/nixos/modules/services/networking/teleport.nix
vendored
Normal file
|
@ -0,0 +1,99 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.teleport;
|
||||
settingsYaml = pkgs.formats.yaml { };
|
||||
in
|
||||
{
|
||||
options = {
|
||||
services.teleport = with lib.types; {
|
||||
enable = mkEnableOption "the Teleport service";
|
||||
|
||||
settings = mkOption {
|
||||
type = settingsYaml.type;
|
||||
default = { };
|
||||
example = literalExpression ''
|
||||
{
|
||||
teleport = {
|
||||
nodename = "client";
|
||||
advertise_ip = "192.168.1.2";
|
||||
auth_token = "60bdc117-8ff4-478d-95e4-9914597847eb";
|
||||
auth_servers = [ "192.168.1.1:3025" ];
|
||||
log.severity = "DEBUG";
|
||||
};
|
||||
ssh_service = {
|
||||
enabled = true;
|
||||
labels = {
|
||||
role = "client";
|
||||
};
|
||||
};
|
||||
proxy_service.enabled = false;
|
||||
auth_service.enabled = false;
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Contents of the <literal>teleport.yaml</literal> config file.
|
||||
The <literal>--config</literal> arguments will only be passed if this set is not empty.
|
||||
|
||||
See <link xlink:href="https://goteleport.com/docs/setup/reference/config/"/>.
|
||||
'';
|
||||
};
|
||||
|
||||
insecure.enable = mkEnableOption ''
|
||||
starting teleport in insecure mode.
|
||||
|
||||
This is dangerous!
|
||||
Sensitive information will be logged to console and certificates will not be verified.
|
||||
Proceed with caution!
|
||||
|
||||
Teleport starts with disabled certificate validation on Proxy Service, validation still occurs on Auth Service
|
||||
'';
|
||||
|
||||
diag = {
|
||||
enable = mkEnableOption ''
|
||||
endpoints for monitoring purposes.
|
||||
|
||||
See <link xlink:href="https://goteleport.com/docs/setup/admin/troubleshooting/#troubleshooting/"/>
|
||||
'';
|
||||
|
||||
addr = mkOption {
|
||||
type = str;
|
||||
default = "127.0.0.1";
|
||||
description = "Metrics and diagnostics address.";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = int;
|
||||
default = 3000;
|
||||
description = "Metrics and diagnostics port.";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf config.services.teleport.enable {
|
||||
environment.systemPackages = [ pkgs.teleport ];
|
||||
|
||||
systemd.services.teleport = {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
serviceConfig = {
|
||||
ExecStart = ''
|
||||
${pkgs.teleport}/bin/teleport start \
|
||||
${optionalString cfg.insecure.enable "--insecure"} \
|
||||
${optionalString cfg.diag.enable "--diag-addr=${cfg.diag.addr}:${toString cfg.diag.port}"} \
|
||||
${optionalString (cfg.settings != { }) "--config=${settingsYaml.generate "teleport.yaml" cfg.settings}"}
|
||||
'';
|
||||
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
|
||||
LimitNOFILE = 65536;
|
||||
Restart = "always";
|
||||
RestartSec = "5s";
|
||||
RuntimeDirectory = "teleport";
|
||||
Type = "simple";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -6,17 +6,31 @@ let
|
|||
cfg = config.services.thelounge;
|
||||
dataDir = "/var/lib/thelounge";
|
||||
configJsData = "module.exports = " + builtins.toJSON (
|
||||
{ private = cfg.private; port = cfg.port; } // cfg.extraConfig
|
||||
{ inherit (cfg) public port; } // cfg.extraConfig
|
||||
);
|
||||
in {
|
||||
pluginManifest = {
|
||||
dependencies = builtins.listToAttrs (builtins.map (pkg: { name = getName pkg; value = getVersion pkg; }) cfg.plugins);
|
||||
};
|
||||
plugins = pkgs.runCommandLocal "thelounge-plugins" { } ''
|
||||
mkdir -p $out/node_modules
|
||||
echo ${escapeShellArg (builtins.toJSON pluginManifest)} >> $out/package.json
|
||||
${concatMapStringsSep "\n" (pkg: ''
|
||||
ln -s ${pkg}/lib/node_modules/${getName pkg} $out/node_modules/${getName pkg}
|
||||
'') cfg.plugins}
|
||||
'';
|
||||
in
|
||||
{
|
||||
imports = [ (mkRemovedOptionModule [ "services" "thelounge" "private" ] "The option was renamed to `services.thelounge.public` to follow upstream changes.") ];
|
||||
|
||||
options.services.thelounge = {
|
||||
enable = mkEnableOption "The Lounge web IRC client";
|
||||
|
||||
private = mkOption {
|
||||
public = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Make your The Lounge instance private. You will need to configure user
|
||||
Make your The Lounge instance public.
|
||||
Setting this to <literal>false</literal> will require you to configure user
|
||||
accounts by using the (<command>thelounge</command>) command or by adding
|
||||
entries in <filename>${dataDir}/users</filename>. You might need to restart
|
||||
The Lounge after making changes to the state directory.
|
||||
|
@ -30,7 +44,7 @@ in {
|
|||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
default = {};
|
||||
default = { };
|
||||
type = types.attrs;
|
||||
example = literalExpression ''{
|
||||
reverseProxy = true;
|
||||
|
@ -50,19 +64,32 @@ in {
|
|||
Documentation: <link xlink:href="https://thelounge.chat/docs/server/configuration" />
|
||||
'';
|
||||
};
|
||||
|
||||
plugins = mkOption {
|
||||
default = [ ];
|
||||
type = types.listOf types.package;
|
||||
example = literalExpression "[ pkgs.theLoungePlugins.themes.solarized ]";
|
||||
description = ''
|
||||
The Lounge plugins to install. Plugins can be found in
|
||||
<literal>pkgs.theLoungePlugins.plugins</literal> and <literal>pkgs.theLoungePlugins.themes</literal>.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
users.users.thelounge = {
|
||||
description = "thelounge service user";
|
||||
description = "The Lounge service user";
|
||||
group = "thelounge";
|
||||
isSystemUser = true;
|
||||
};
|
||||
users.groups.thelounge = {};
|
||||
|
||||
users.groups.thelounge = { };
|
||||
|
||||
systemd.services.thelounge = {
|
||||
description = "The Lounge web IRC client";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
preStart = "ln -sf ${pkgs.writeText "config.js" configJsData} ${dataDir}/config.js";
|
||||
environment.THELOUNGE_PACKAGES = mkIf (cfg.plugins != [ ]) "${plugins}";
|
||||
serviceConfig = {
|
||||
User = "thelounge";
|
||||
StateDirectory = baseNameOf dataDir;
|
||||
|
@ -72,4 +99,8 @@ in {
|
|||
|
||||
environment.systemPackages = [ pkgs.thelounge ];
|
||||
};
|
||||
|
||||
meta = {
|
||||
maintainers = with lib.maintainers; [ winter ];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -204,7 +204,7 @@ in
|
|||
postStart = ''
|
||||
# Make sure elasticsearch is up and running before dependents
|
||||
# are started
|
||||
while ! ${pkgs.curl}/bin/curl -sS -f http://localhost:${toString cfg.port} 2>/dev/null; do
|
||||
while ! ${pkgs.curl}/bin/curl -sS -f http://${cfg.listenAddress}:${toString cfg.port} 2>/dev/null; do
|
||||
sleep 1
|
||||
done
|
||||
'';
|
||||
|
|
|
@ -73,6 +73,11 @@ in
|
|||
|
||||
hardware.cpu.intel.sgx.provision.enable = true;
|
||||
|
||||
# Make sure the AESM service can find the SGX devices until
|
||||
# https://github.com/intel/linux-sgx/issues/772 is resolved
|
||||
# and updated in nixpkgs.
|
||||
hardware.cpu.intel.sgx.enableDcapCompat = mkForce true;
|
||||
|
||||
systemd.services.aesmd =
|
||||
let
|
||||
storeAesmFolder = "${sgx-psw}/aesm";
|
||||
|
|
|
@ -50,7 +50,9 @@ in
|
|||
systemd.services.nscd =
|
||||
{ description = "Name Service Cache Daemon";
|
||||
|
||||
wantedBy = [ "nss-lookup.target" "nss-user-lookup.target" ];
|
||||
before = [ "nss-lookup.target" "nss-user-lookup.target" ];
|
||||
wants = [ "nss-lookup.target" "nss-user-lookup.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
environment = { LD_LIBRARY_PATH = nssModulesPath; };
|
||||
|
||||
|
|
170
third_party/nixpkgs/nixos/modules/services/web-apps/baget.nix
vendored
Normal file
170
third_party/nixpkgs/nixos/modules/services/web-apps/baget.nix
vendored
Normal file
|
@ -0,0 +1,170 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.baget;
|
||||
|
||||
defaultConfig = {
|
||||
"PackageDeletionBehavior" = "Unlist";
|
||||
"AllowPackageOverwrites" = false;
|
||||
|
||||
"Database" = {
|
||||
"Type" = "Sqlite";
|
||||
"ConnectionString" = "Data Source=baget.db";
|
||||
};
|
||||
|
||||
"Storage" = {
|
||||
"Type" = "FileSystem";
|
||||
"Path" = "";
|
||||
};
|
||||
|
||||
"Search" = {
|
||||
"Type" = "Database";
|
||||
};
|
||||
|
||||
"Mirror" = {
|
||||
"Enabled" = false;
|
||||
"PackageSource" = "https://api.nuget.org/v3/index.json";
|
||||
};
|
||||
|
||||
"Logging" = {
|
||||
"IncludeScopes" = false;
|
||||
"Debug" = {
|
||||
"LogLevel" = {
|
||||
"Default" = "Warning";
|
||||
};
|
||||
};
|
||||
"Console" = {
|
||||
"LogLevel" = {
|
||||
"Microsoft.Hosting.Lifetime" = "Information";
|
||||
"Default" = "Warning";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
configAttrs = recursiveUpdate defaultConfig cfg.extraConfig;
|
||||
|
||||
configFormat = pkgs.formats.json {};
|
||||
configFile = configFormat.generate "appsettings.json" configAttrs;
|
||||
|
||||
in
|
||||
{
|
||||
options.services.baget = {
|
||||
enable = mkEnableOption "BaGet NuGet-compatible server";
|
||||
|
||||
apiKeyFile = mkOption {
|
||||
type = types.path;
|
||||
example = "/root/baget.key";
|
||||
description = ''
|
||||
Private API key for BaGet.
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = configFormat.type;
|
||||
default = {};
|
||||
example = {
|
||||
"Database" = {
|
||||
"Type" = "PostgreSql";
|
||||
"ConnectionString" = "Server=/run/postgresql;Port=5432;";
|
||||
};
|
||||
};
|
||||
defaultText = literalExpression ''
|
||||
{
|
||||
"PackageDeletionBehavior" = "Unlist";
|
||||
"AllowPackageOverwrites" = false;
|
||||
|
||||
"Database" = {
|
||||
"Type" = "Sqlite";
|
||||
"ConnectionString" = "Data Source=baget.db";
|
||||
};
|
||||
|
||||
"Storage" = {
|
||||
"Type" = "FileSystem";
|
||||
"Path" = "";
|
||||
};
|
||||
|
||||
"Search" = {
|
||||
"Type" = "Database";
|
||||
};
|
||||
|
||||
"Mirror" = {
|
||||
"Enabled" = false;
|
||||
"PackageSource" = "https://api.nuget.org/v3/index.json";
|
||||
};
|
||||
|
||||
"Logging" = {
|
||||
"IncludeScopes" = false;
|
||||
"Debug" = {
|
||||
"LogLevel" = {
|
||||
"Default" = "Warning";
|
||||
};
|
||||
};
|
||||
"Console" = {
|
||||
"LogLevel" = {
|
||||
"Microsoft.Hosting.Lifetime" = "Information";
|
||||
"Default" = "Warning";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Extra configuration options for BaGet. Refer to <link xlink:href="https://loic-sharma.github.io/BaGet/configuration/"/> for details.
|
||||
Default value is merged with values from here.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
# implementation
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
systemd.services.baget = {
|
||||
description = "BaGet server";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
wants = [ "network-online.target" ];
|
||||
after = [ "network.target" "network-online.target" ];
|
||||
path = [ pkgs.jq ];
|
||||
serviceConfig = {
|
||||
WorkingDirectory = "/var/lib/baget";
|
||||
DynamicUser = true;
|
||||
StateDirectory = "baget";
|
||||
StateDirectoryMode = "0700";
|
||||
LoadCredential = "api_key:${cfg.apiKeyFile}";
|
||||
|
||||
CapabilityBoundingSet = "";
|
||||
NoNewPrivileges = true;
|
||||
PrivateDevices = true;
|
||||
PrivateTmp = true;
|
||||
PrivateUsers = true;
|
||||
PrivateMounts = true;
|
||||
ProtectHome = true;
|
||||
ProtectClock = true;
|
||||
ProtectProc = "noaccess";
|
||||
ProcSubset = "pid";
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHostname = true;
|
||||
RestrictSUIDSGID = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictNamespaces = true;
|
||||
LockPersonality = true;
|
||||
RemoveIPC = true;
|
||||
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
|
||||
SystemCallFilter = [ "@system-service" "~@privileged" ];
|
||||
};
|
||||
script = ''
|
||||
jq --slurpfile apiKeys <(jq -R . "$CREDENTIALS_DIRECTORY/api_key") '.ApiKey = $apiKeys[0]' ${configFile} > appsettings.json
|
||||
ln -snf ${pkgs.baget}/lib/BaGet/wwwroot wwwroot
|
||||
exec ${pkgs.baget}/bin/BaGet
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
}
|
88
third_party/nixpkgs/nixos/modules/services/web-apps/prosody-filer.nix
vendored
Normal file
88
third_party/nixpkgs/nixos/modules/services/web-apps/prosody-filer.nix
vendored
Normal file
|
@ -0,0 +1,88 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
|
||||
cfg = config.services.prosody-filer;
|
||||
|
||||
settingsFormat = pkgs.formats.toml { };
|
||||
configFile = settingsFormat.generate "prosody-filer.toml" cfg.settings;
|
||||
in {
|
||||
|
||||
options = {
|
||||
services.prosody-filer = {
|
||||
enable = mkEnableOption "Prosody Filer XMPP upload file server";
|
||||
|
||||
settings = mkOption {
|
||||
description = ''
|
||||
Configuration for Prosody Filer.
|
||||
Refer to <link xlink:href="https://github.com/ThomasLeister/prosody-filer#configure-prosody-filer"/> for details on supported values.
|
||||
'';
|
||||
|
||||
type = settingsFormat.type;
|
||||
|
||||
example = literalExample ''
|
||||
{
|
||||
secret = "mysecret";
|
||||
storeDir = "/srv/http/nginx/prosody-upload";
|
||||
}
|
||||
'';
|
||||
|
||||
defaultText = literalExpression ''
|
||||
{
|
||||
listenport = mkDefault "127.0.0.1:5050";
|
||||
uploadSubDir = mkDefault "upload/";
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.prosody-filer.settings = {
|
||||
listenport = mkDefault "127.0.0.1:5050";
|
||||
uploadSubDir = mkDefault "upload/";
|
||||
};
|
||||
|
||||
users.users.prosody-filer = {
|
||||
group = "prosody-filer";
|
||||
isSystemUser = true;
|
||||
};
|
||||
|
||||
users.groups.prosody-filer = { };
|
||||
|
||||
systemd.services.prosody-filer = {
|
||||
description = "Prosody file upload server";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
|
||||
serviceConfig = {
|
||||
User = "prosody-filer";
|
||||
Group = "prosody-filer";
|
||||
ExecStart = "${pkgs.prosody-filer}/bin/prosody-filer -config ${configFile}";
|
||||
Restart = "on-failure";
|
||||
CapabilityBoundingSet = "";
|
||||
NoNewPrivileges = true;
|
||||
PrivateDevices = true;
|
||||
PrivateTmp = true;
|
||||
PrivateMounts = true;
|
||||
ProtectHome = true;
|
||||
ProtectClock = true;
|
||||
ProtectProc = "noaccess";
|
||||
ProcSubset = "pid";
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHostname = true;
|
||||
RestrictSUIDSGID = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictNamespaces = true;
|
||||
LockPersonality = true;
|
||||
RemoveIPC = true;
|
||||
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
|
||||
SystemCallFilter = [ "@system-service" "~@privileged" "~@resources" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -301,11 +301,16 @@ in
|
|||
# implementation
|
||||
config = mkIf (eachSite != {}) (mkMerge [{
|
||||
|
||||
assertions = mapAttrsToList (hostName: cfg:
|
||||
assertions =
|
||||
(mapAttrsToList (hostName: cfg:
|
||||
{ assertion = cfg.database.createLocally -> cfg.database.user == user;
|
||||
message = ''services.wordpress.sites."${hostName}".database.user must be ${user} if the database is to be automatically provisioned'';
|
||||
}
|
||||
) eachSite;
|
||||
}) eachSite) ++
|
||||
(mapAttrsToList (hostName: cfg:
|
||||
{ assertion = cfg.database.createLocally -> cfg.database.passwordFile == null;
|
||||
message = ''services.wordpress.sites."${hostName}".database.passwordFile cannot be specified if services.wordpress.sites."${hostName}".database.createLocally is set to true.'';
|
||||
}) eachSite);
|
||||
|
||||
|
||||
warnings = mapAttrsToList (hostName: _: ''services.wordpress."${hostName}" is deprecated use services.wordpress.sites."${hostName}"'') (oldSites cfg);
|
||||
|
||||
|
|
|
@ -370,6 +370,8 @@ let
|
|||
cat ${php.phpIni} > $out
|
||||
echo "$options" >> $out
|
||||
'';
|
||||
|
||||
mkCertOwnershipAssertion = import ../../../security/acme/mk-cert-ownership-assertion.nix;
|
||||
in
|
||||
|
||||
|
||||
|
@ -657,7 +659,11 @@ in
|
|||
`services.httpd.virtualHosts.<name>.useACMEHost` are mutually exclusive.
|
||||
'';
|
||||
}
|
||||
];
|
||||
] ++ map (name: mkCertOwnershipAssertion {
|
||||
inherit (cfg) group user;
|
||||
cert = config.security.acme.certs.${name};
|
||||
groups = config.users.groups;
|
||||
}) dependentCertNames;
|
||||
|
||||
warnings =
|
||||
mapAttrsToList (name: hostOpts: ''
|
||||
|
|
|
@ -28,11 +28,7 @@ let
|
|||
let
|
||||
Caddyfile = pkgs.writeText "Caddyfile" ''
|
||||
{
|
||||
${optionalString (cfg.email != null) "email ${cfg.email}"}
|
||||
${optionalString (cfg.acmeCA != null) "acme_ca ${cfg.acmeCA}"}
|
||||
log {
|
||||
${cfg.logFormat}
|
||||
}
|
||||
${cfg.globalConfig}
|
||||
}
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
|
@ -42,6 +38,10 @@ let
|
|||
'';
|
||||
in
|
||||
if pkgs.stdenv.buildPlatform == pkgs.stdenv.hostPlatform then Caddyfile-formatted else Caddyfile;
|
||||
|
||||
acmeHosts = unique (catAttrs "useACMEHost" acmeVHosts);
|
||||
|
||||
mkCertOwnershipAssertion = import ../../../security/acme/mk-cert-ownership-assertion.nix;
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
|
@ -183,6 +183,26 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
globalConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
example = ''
|
||||
debug
|
||||
servers {
|
||||
protocol {
|
||||
experimental_http3
|
||||
}
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Additional lines of configuration appended to the global config section
|
||||
of the <literal>Caddyfile</literal>.
|
||||
|
||||
Refer to <link xlink:href="https://caddyserver.com/docs/caddyfile/options#global-options"/>
|
||||
for details on supported values.
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
|
@ -250,9 +270,20 @@ in
|
|||
{ assertion = cfg.adapter != "caddyfile" -> cfg.configFile != configFile;
|
||||
message = "Any value other than 'caddyfile' is only valid when providing your own `services.caddy.configFile`";
|
||||
}
|
||||
];
|
||||
] ++ map (name: mkCertOwnershipAssertion {
|
||||
inherit (cfg) group user;
|
||||
cert = config.security.acme.certs.${name};
|
||||
groups = config.users.groups;
|
||||
}) acmeHosts;
|
||||
|
||||
services.caddy.extraConfig = concatMapStringsSep "\n" mkVHostConf virtualHosts;
|
||||
services.caddy.globalConfig = ''
|
||||
${optionalString (cfg.email != null) "email ${cfg.email}"}
|
||||
${optionalString (cfg.acmeCA != null) "acme_ca ${cfg.acmeCA}"}
|
||||
log {
|
||||
${cfg.logFormat}
|
||||
}
|
||||
'';
|
||||
|
||||
systemd.packages = [ cfg.package ];
|
||||
systemd.services.caddy = {
|
||||
|
@ -300,8 +331,7 @@ in
|
|||
|
||||
security.acme.certs =
|
||||
let
|
||||
eachACMEHost = unique (catAttrs "useACMEHost" acmeVHosts);
|
||||
reloads = map (useACMEHost: nameValuePair useACMEHost { reloadServices = [ "caddy.service" ]; }) eachACMEHost;
|
||||
reloads = map (useACMEHost: nameValuePair useACMEHost { reloadServices = [ "caddy.service" ]; }) acmeHosts;
|
||||
in
|
||||
listToAttrs reloads;
|
||||
|
||||
|
|
|
@ -374,6 +374,8 @@ let
|
|||
${user}:{PLAIN}${password}
|
||||
'') authDef)
|
||||
);
|
||||
|
||||
mkCertOwnershipAssertion = import ../../../security/acme/mk-cert-ownership-assertion.nix;
|
||||
in
|
||||
|
||||
{
|
||||
|
@ -842,7 +844,11 @@ in
|
|||
services.nginx.virtualHosts.<name>.useACMEHost are mutually exclusive.
|
||||
'';
|
||||
}
|
||||
];
|
||||
] ++ map (name: mkCertOwnershipAssertion {
|
||||
inherit (cfg) group user;
|
||||
cert = config.security.acme.certs.${name};
|
||||
groups = config.users.groups;
|
||||
}) dependentCertNames;
|
||||
|
||||
systemd.services.nginx = {
|
||||
description = "Nginx Web Server";
|
||||
|
|
|
@ -20,10 +20,11 @@ let
|
|||
|
||||
buildCfg = name: c:
|
||||
let
|
||||
plugins =
|
||||
plugins' =
|
||||
if any (n: !any (m: m == n) cfg.plugins) (c.plugins or [])
|
||||
then throw "`plugins` attribute in uWSGI configuration contains plugins not in config.services.uwsgi.plugins"
|
||||
else c.plugins or cfg.plugins;
|
||||
plugins = unique plugins';
|
||||
|
||||
hasPython = v: filter (n: n == "python${v}") plugins != [];
|
||||
hasPython2 = hasPython "2";
|
||||
|
@ -48,13 +49,10 @@ let
|
|||
pyhome = "${pythonEnv}";
|
||||
env =
|
||||
# Argh, uwsgi expects list of key-values there instead of a dictionary.
|
||||
let env' = c.env or [];
|
||||
getPath =
|
||||
x: if hasPrefix "PATH=" x
|
||||
then substring (stringLength "PATH=") (stringLength x) x
|
||||
else null;
|
||||
oldPaths = filter (x: x != null) (map getPath env');
|
||||
in env' ++ [ "PATH=${optionalString (oldPaths != []) "${last oldPaths}:"}${pythonEnv}/bin" ];
|
||||
let envs = partition (hasPrefix "PATH=") (c.env or []);
|
||||
oldPaths = map (x: substring (stringLength "PATH=") (stringLength x) x) envs.right;
|
||||
paths = oldPaths ++ [ "${pythonEnv}/bin" ];
|
||||
in [ "PATH=${concatStringsSep ":" paths}" ] ++ envs.wrong;
|
||||
}
|
||||
else if isEmperor
|
||||
then {
|
||||
|
@ -225,7 +223,7 @@ in {
|
|||
};
|
||||
|
||||
services.uwsgi.package = pkgs.uwsgi.override {
|
||||
inherit (cfg) plugins;
|
||||
plugins = unique cfg.plugins;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -703,7 +703,7 @@ in
|
|||
|
||||
environment =
|
||||
optionalAttrs config.hardware.opengl.setLdLibraryPath
|
||||
{ LD_LIBRARY_PATH = pkgs.addOpenGLRunpath.driverLink; }
|
||||
{ LD_LIBRARY_PATH = lib.makeLibraryPath [ pkgs.addOpenGLRunpath.driverLink ]; }
|
||||
// cfg.displayManager.job.environment;
|
||||
|
||||
preStart =
|
||||
|
|
|
@ -30,6 +30,21 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
useGenerationDeviceTree = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to generate Device Tree-related directives in the
|
||||
extlinux configuration.
|
||||
|
||||
When enabled, the bootloader will attempt to load the device
|
||||
tree binaries from the generation's kernel.
|
||||
|
||||
Note that this affects all generations, regardless of the
|
||||
setting value used in their configurations.
|
||||
'';
|
||||
};
|
||||
|
||||
configurationLimit = mkOption {
|
||||
default = 20;
|
||||
example = 10;
|
||||
|
@ -54,7 +69,9 @@ in
|
|||
};
|
||||
|
||||
config = let
|
||||
builderArgs = "-g ${toString cfg.configurationLimit} -t ${timeoutStr}" + lib.optionalString (dtCfg.name != null) " -n ${dtCfg.name}";
|
||||
builderArgs = "-g ${toString cfg.configurationLimit} -t ${timeoutStr}"
|
||||
+ lib.optionalString (dtCfg.name != null) " -n ${dtCfg.name}"
|
||||
+ lib.optionalString (!cfg.useGenerationDeviceTree) " -r";
|
||||
in
|
||||
mkIf cfg.enable {
|
||||
system.build.installBootLoader = "${builder} ${builderArgs} -c";
|
||||
|
|
|
@ -6,7 +6,7 @@ export PATH=/empty
|
|||
for i in @path@; do PATH=$PATH:$i/bin; done
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 -t <timeout> -c <path-to-default-configuration> [-d <boot-dir>] [-g <num-generations>] [-n <dtbName>]" >&2
|
||||
echo "usage: $0 -t <timeout> -c <path-to-default-configuration> [-d <boot-dir>] [-g <num-generations>] [-n <dtbName>] [-r]" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ default= # Default configuration
|
|||
target=/boot # Target directory
|
||||
numGenerations=0 # Number of other generations to include in the menu
|
||||
|
||||
while getopts "t:c:d:g:n:" opt; do
|
||||
while getopts "t:c:d:g:n:r" opt; do
|
||||
case "$opt" in
|
||||
t) # U-Boot interprets '0' as infinite and negative as instant boot
|
||||
if [ "$OPTARG" -lt 0 ]; then
|
||||
|
@ -30,6 +30,7 @@ while getopts "t:c:d:g:n:" opt; do
|
|||
d) target="$OPTARG" ;;
|
||||
g) numGenerations="$OPTARG" ;;
|
||||
n) dtbName="$OPTARG" ;;
|
||||
r) noDeviceTree=1 ;;
|
||||
\?) usage ;;
|
||||
esac
|
||||
done
|
||||
|
@ -96,6 +97,12 @@ addEntry() {
|
|||
fi
|
||||
echo " LINUX ../nixos/$(basename $kernel)"
|
||||
echo " INITRD ../nixos/$(basename $initrd)"
|
||||
echo " APPEND init=$path/init $extraParams"
|
||||
|
||||
if [ -n "$noDeviceTree" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
if [ -d "$dtbDir" ]; then
|
||||
# if a dtbName was specified explicitly, use that, else use FDTDIR
|
||||
if [ -n "$dtbName" ]; then
|
||||
|
@ -109,7 +116,6 @@ addEntry() {
|
|||
exit 1
|
||||
fi
|
||||
fi
|
||||
echo " APPEND init=$path/init $extraParams"
|
||||
}
|
||||
|
||||
tmpFile="$target/extlinux/extlinux.conf.tmp.$$"
|
||||
|
|
|
@ -45,16 +45,6 @@ initrd {initrd}
|
|||
options {kernel_params}
|
||||
"""
|
||||
|
||||
# The boot loader entry for memtest86.
|
||||
#
|
||||
# TODO: This is hard-coded to use the 64-bit EFI app, but it could probably
|
||||
# be updated to use the 32-bit EFI app on 32-bit systems. The 32-bit EFI
|
||||
# app filename is BOOTIA32.efi.
|
||||
MEMTEST_BOOT_ENTRY = """title MemTest86
|
||||
efi /efi/memtest86/BOOTX64.efi
|
||||
"""
|
||||
|
||||
|
||||
def generation_conf_filename(profile: Optional[str], generation: int, specialisation: Optional[str]) -> str:
|
||||
pieces = [
|
||||
"nixos",
|
||||
|
@ -283,23 +273,24 @@ def main() -> None:
|
|||
except OSError as e:
|
||||
print("ignoring profile '{}' in the list of boot entries because of the following error:\n{}".format(profile, e), file=sys.stderr)
|
||||
|
||||
memtest_entry_file = "@efiSysMountPoint@/loader/entries/memtest86.conf"
|
||||
if os.path.exists(memtest_entry_file):
|
||||
os.unlink(memtest_entry_file)
|
||||
shutil.rmtree("@efiSysMountPoint@/efi/memtest86", ignore_errors=True)
|
||||
if "@memtest86@" != "":
|
||||
mkdir_p("@efiSysMountPoint@/efi/memtest86")
|
||||
for path in glob.iglob("@memtest86@/*"):
|
||||
if os.path.isdir(path):
|
||||
shutil.copytree(path, os.path.join("@efiSysMountPoint@/efi/memtest86", os.path.basename(path)))
|
||||
else:
|
||||
shutil.copy(path, "@efiSysMountPoint@/efi/memtest86/")
|
||||
for root, _, files in os.walk('@efiSysMountPoint@/efi/nixos/.extra-files', topdown=False):
|
||||
relative_root = root.removeprefix("@efiSysMountPoint@/efi/nixos/.extra-files").removeprefix("/")
|
||||
actual_root = os.path.join("@efiSysMountPoint@", relative_root)
|
||||
|
||||
memtest_entry_file = "@efiSysMountPoint@/loader/entries/memtest86.conf"
|
||||
memtest_entry_file_tmp_path = "%s.tmp" % memtest_entry_file
|
||||
with open(memtest_entry_file_tmp_path, 'w') as f:
|
||||
f.write(MEMTEST_BOOT_ENTRY)
|
||||
os.rename(memtest_entry_file_tmp_path, memtest_entry_file)
|
||||
for file in files:
|
||||
actual_file = os.path.join(actual_root, file)
|
||||
|
||||
if os.path.exists(actual_file):
|
||||
os.unlink(actual_file)
|
||||
os.unlink(os.path.join(root, file))
|
||||
|
||||
if not len(os.listdir(actual_root)):
|
||||
os.rmdir(actual_root)
|
||||
os.rmdir(root)
|
||||
|
||||
mkdir_p("@efiSysMountPoint@/efi/nixos/.extra-files")
|
||||
|
||||
subprocess.check_call("@copyExtraFiles@")
|
||||
|
||||
# Since fat32 provides little recovery facilities after a crash,
|
||||
# it can leave the system in an unbootable state, when a crash/outage
|
||||
|
|
|
@ -29,6 +29,22 @@ let
|
|||
inherit (efi) efiSysMountPoint canTouchEfiVariables;
|
||||
|
||||
memtest86 = if cfg.memtest86.enable then pkgs.memtest86-efi else "";
|
||||
|
||||
netbootxyz = if cfg.netbootxyz.enable then pkgs.netbootxyz-efi else "";
|
||||
|
||||
copyExtraFiles = pkgs.writeShellScript "copy-extra-files" ''
|
||||
empty_file=$(mktemp)
|
||||
|
||||
${concatStrings (mapAttrsToList (n: v: ''
|
||||
${pkgs.coreutils}/bin/install -Dp "${v}" "${efi.efiSysMountPoint}/"${escapeShellArg n}
|
||||
${pkgs.coreutils}/bin/install -D $empty_file "${efi.efiSysMountPoint}/efi/nixos/.extra-files/"${escapeShellArg n}
|
||||
'') cfg.extraFiles)}
|
||||
|
||||
${concatStrings (mapAttrsToList (n: v: ''
|
||||
${pkgs.coreutils}/bin/install -Dp "${pkgs.writeText n v}" "${efi.efiSysMountPoint}/loader/entries/"${escapeShellArg n}
|
||||
${pkgs.coreutils}/bin/install -D $empty_file "${efi.efiSysMountPoint}/efi/nixos/.extra-files/loader/entries/"${escapeShellArg n}
|
||||
'') cfg.extraEntries)}
|
||||
'';
|
||||
};
|
||||
|
||||
checkedSystemdBootBuilder = pkgs.runCommand "systemd-boot" {
|
||||
|
@ -125,6 +141,74 @@ in {
|
|||
<literal>true</literal>.
|
||||
'';
|
||||
};
|
||||
|
||||
entryFilename = mkOption {
|
||||
default = "memtest86.conf";
|
||||
type = types.str;
|
||||
description = ''
|
||||
<literal>systemd-boot</literal> orders the menu entries by the config file names,
|
||||
so if you want something to appear after all the NixOS entries,
|
||||
it should start with <filename>o</filename> or onwards.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
netbootxyz = {
|
||||
enable = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Make <literal>netboot.xyz</literal> available from the
|
||||
<literal>systemd-boot</literal> menu. <literal>netboot.xyz</literal>
|
||||
is a menu system that allows you to boot OS installers and
|
||||
utilities over the network.
|
||||
'';
|
||||
};
|
||||
|
||||
entryFilename = mkOption {
|
||||
default = "o_netbootxyz.conf";
|
||||
type = types.str;
|
||||
description = ''
|
||||
<literal>systemd-boot</literal> orders the menu entries by the config file names,
|
||||
so if you want something to appear after all the NixOS entries,
|
||||
it should start with <filename>o</filename> or onwards.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
extraEntries = mkOption {
|
||||
type = types.attrsOf types.lines;
|
||||
default = {};
|
||||
example = literalExpression ''
|
||||
{ "memtest86.conf" = '''
|
||||
title MemTest86
|
||||
efi /efi/memtest86/memtest86.efi
|
||||
'''; }
|
||||
'';
|
||||
description = ''
|
||||
Any additional entries you want added to the <literal>systemd-boot</literal> menu.
|
||||
These entries will be copied to <filename>/boot/loader/entries</filename>.
|
||||
Each attribute name denotes the destination file name,
|
||||
and the corresponding attribute value is the contents of the entry.
|
||||
|
||||
<literal>systemd-boot</literal> orders the menu entries by the config file names,
|
||||
so if you want something to appear after all the NixOS entries,
|
||||
it should start with <filename>o</filename> or onwards.
|
||||
'';
|
||||
};
|
||||
|
||||
extraFiles = mkOption {
|
||||
type = types.attrsOf types.path;
|
||||
default = {};
|
||||
example = literalExpression ''
|
||||
{ "efi/memtest86/memtest86.efi" = "''${pkgs.memtest86-efi}/BOOTX64.efi"; }
|
||||
'';
|
||||
description = ''
|
||||
A set of files to be copied to <filename>/boot</filename>.
|
||||
Each attribute name denotes the destination file name in
|
||||
<filename>/boot</filename>, while the corresponding
|
||||
attribute value specifies the source file.
|
||||
'';
|
||||
};
|
||||
|
||||
graceful = mkOption {
|
||||
|
@ -148,15 +232,64 @@ in {
|
|||
assertions = [
|
||||
{
|
||||
assertion = (config.boot.kernelPackages.kernel.features or { efiBootStub = true; }) ? efiBootStub;
|
||||
|
||||
message = "This kernel does not support the EFI boot stub";
|
||||
}
|
||||
];
|
||||
] ++ concatMap (filename: [
|
||||
{
|
||||
assertion = !(hasInfix "/" filename);
|
||||
message = "boot.loader.systemd-boot.extraEntries.${lib.strings.escapeNixIdentifier filename} is invalid: entries within folders are not supported";
|
||||
}
|
||||
{
|
||||
assertion = hasSuffix ".conf" filename;
|
||||
message = "boot.loader.systemd-boot.extraEntries.${lib.strings.escapeNixIdentifier filename} is invalid: entries must have a .conf file extension";
|
||||
}
|
||||
]) (builtins.attrNames cfg.extraEntries)
|
||||
++ concatMap (filename: [
|
||||
{
|
||||
assertion = !(hasPrefix "/" filename);
|
||||
message = "boot.loader.systemd-boot.extraFiles.${lib.strings.escapeNixIdentifier filename} is invalid: paths must not begin with a slash";
|
||||
}
|
||||
{
|
||||
assertion = !(hasInfix ".." filename);
|
||||
message = "boot.loader.systemd-boot.extraFiles.${lib.strings.escapeNixIdentifier filename} is invalid: paths must not reference the parent directory";
|
||||
}
|
||||
{
|
||||
assertion = !(hasInfix "nixos/.extra-files" (toLower filename));
|
||||
message = "boot.loader.systemd-boot.extraFiles.${lib.strings.escapeNixIdentifier filename} is invalid: files cannot be placed in the nixos/.extra-files directory";
|
||||
}
|
||||
]) (builtins.attrNames cfg.extraFiles);
|
||||
|
||||
boot.loader.grub.enable = mkDefault false;
|
||||
|
||||
boot.loader.supportsInitrdSecrets = true;
|
||||
|
||||
boot.loader.systemd-boot.extraFiles = mkMerge [
|
||||
# TODO: This is hard-coded to use the 64-bit EFI app, but it could probably
|
||||
# be updated to use the 32-bit EFI app on 32-bit systems. The 32-bit EFI
|
||||
# app filename is BOOTIA32.efi.
|
||||
(mkIf cfg.memtest86.enable {
|
||||
"efi/memtest86/BOOTX64.efi" = "${pkgs.memtest86-efi}/BOOTX64.efi";
|
||||
})
|
||||
(mkIf cfg.netbootxyz.enable {
|
||||
"efi/netbootxyz/netboot.xyz.efi" = "${pkgs.netbootxyz-efi}";
|
||||
})
|
||||
];
|
||||
|
||||
boot.loader.systemd-boot.extraEntries = mkMerge [
|
||||
(mkIf cfg.memtest86.enable {
|
||||
"${cfg.memtest86.entryFilename}" = ''
|
||||
title MemTest86
|
||||
efi /efi/memtest86/BOOTX64.efi
|
||||
'';
|
||||
})
|
||||
(mkIf cfg.netbootxyz.enable {
|
||||
"${cfg.netbootxyz.entryFilename}" = ''
|
||||
title netboot.xyz
|
||||
efi /efi/netbootxyz/netboot.xyz.efi
|
||||
'';
|
||||
})
|
||||
];
|
||||
|
||||
system = {
|
||||
build.installBootLoader = checkedSystemdBootBuilder;
|
||||
|
||||
|
|
|
@ -633,7 +633,7 @@ in
|
|||
|
||||
<itemizedlist>
|
||||
<listitem><para><literal>boot.consoleLogLevel = 0;</literal></para></listitem>
|
||||
<listitem><para><literal>boot.kernelParams = [ "quiet" "udev.log_priority=3" ];</literal></para></listitem>
|
||||
<listitem><para><literal>boot.kernelParams = [ "quiet" "udev.log_level=3" ];</literal></para></listitem>
|
||||
</itemizedlist>
|
||||
'';
|
||||
};
|
||||
|
|
|
@ -27,6 +27,7 @@ in
|
|||
message = "VMWare guest is not currently supported on ${pkgs.stdenv.hostPlatform.system}";
|
||||
} ];
|
||||
|
||||
boot.initrd.availableKernelModules = [ "mptspi" ];
|
||||
boot.initrd.kernelModules = [ "vmw_pvscsi" ];
|
||||
|
||||
environment.systemPackages = [ open-vm-tools ];
|
||||
|
|
12
third_party/nixpkgs/nixos/tests/acme.nix
vendored
12
third_party/nixpkgs/nixos/tests/acme.nix
vendored
|
@ -54,15 +54,15 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: let
|
|||
baseConfig = { nodes, config, specialConfig ? {} }: lib.mkMerge [
|
||||
{
|
||||
security.acme = {
|
||||
defaults = (dnsConfig nodes) // {
|
||||
inherit group;
|
||||
};
|
||||
defaults = (dnsConfig nodes);
|
||||
# One manual wildcard cert
|
||||
certs."example.test" = {
|
||||
domain = "*.example.test";
|
||||
};
|
||||
};
|
||||
|
||||
users.users."${config.services."${server}".user}".extraGroups = ["acme"];
|
||||
|
||||
services."${server}" = {
|
||||
enable = true;
|
||||
virtualHosts = {
|
||||
|
@ -252,15 +252,15 @@ in {
|
|||
} // (let
|
||||
baseCaddyConfig = { nodes, config, ... }: {
|
||||
security.acme = {
|
||||
defaults = (dnsConfig nodes) // {
|
||||
group = config.services.caddy.group;
|
||||
};
|
||||
defaults = (dnsConfig nodes);
|
||||
# One manual wildcard cert
|
||||
certs."example.test" = {
|
||||
domain = "*.example.test";
|
||||
};
|
||||
};
|
||||
|
||||
users.users."${config.services.caddy.user}".extraGroups = ["acme"];
|
||||
|
||||
services.caddy = {
|
||||
enable = true;
|
||||
virtualHosts."a.exmaple.test" = {
|
||||
|
|
|
@ -143,6 +143,7 @@ in
|
|||
fluidd = handleTest ./fluidd.nix {};
|
||||
fontconfig-default-fonts = handleTest ./fontconfig-default-fonts.nix {};
|
||||
freeswitch = handleTest ./freeswitch.nix {};
|
||||
frr = handleTest ./frr.nix {};
|
||||
fsck = handleTest ./fsck.nix {};
|
||||
ft2-clone = handleTest ./ft2-clone.nix {};
|
||||
gerrit = handleTest ./gerrit.nix {};
|
||||
|
@ -445,6 +446,7 @@ in
|
|||
sslh = handleTest ./sslh.nix {};
|
||||
sssd = handleTestOn ["x86_64-linux"] ./sssd.nix {};
|
||||
sssd-ldap = handleTestOn ["x86_64-linux"] ./sssd-ldap.nix {};
|
||||
starship = handleTest ./starship.nix {};
|
||||
step-ca = handleTestOn ["x86_64-linux"] ./step-ca.nix {};
|
||||
strongswan-swanctl = handleTest ./strongswan-swanctl.nix {};
|
||||
sudo = handleTest ./sudo.nix {};
|
||||
|
@ -471,6 +473,7 @@ in
|
|||
systemd-unit-path = handleTest ./systemd-unit-path.nix {};
|
||||
taskserver = handleTest ./taskserver.nix {};
|
||||
telegraf = handleTest ./telegraf.nix {};
|
||||
teleport = handleTest ./teleport.nix {};
|
||||
tiddlywiki = handleTest ./tiddlywiki.nix {};
|
||||
tigervnc = handleTest ./tigervnc.nix {};
|
||||
timezone = handleTest ./timezone.nix {};
|
||||
|
|
40
third_party/nixpkgs/nixos/tests/boot.nix
vendored
40
third_party/nixpkgs/nixos/tests/boot.nix
vendored
|
@ -12,12 +12,22 @@ let
|
|||
iso =
|
||||
(import ../lib/eval-config.nix {
|
||||
inherit system;
|
||||
modules =
|
||||
[ ../modules/installer/cd-dvd/installation-cd-minimal.nix
|
||||
modules = [
|
||||
../modules/installer/cd-dvd/installation-cd-minimal.nix
|
||||
../modules/testing/test-instrumentation.nix
|
||||
];
|
||||
}).config.system.build.isoImage;
|
||||
|
||||
sd =
|
||||
(import ../lib/eval-config.nix {
|
||||
inherit system;
|
||||
modules = [
|
||||
../modules/installer/sd-card/sd-image-x86_64.nix
|
||||
../modules/testing/test-instrumentation.nix
|
||||
{ sdImage.compressImage = false; }
|
||||
];
|
||||
}).config.system.build.sdImage;
|
||||
|
||||
pythonDict = params: "\n {\n ${concatStringsSep ",\n " (mapAttrsToList (name: param: "\"${name}\": \"${param}\"") params)},\n }\n";
|
||||
|
||||
makeBootTest = name: extraConfig:
|
||||
|
@ -110,4 +120,30 @@ in {
|
|||
};
|
||||
|
||||
biosNetboot = makeNetbootTest "bios" {};
|
||||
|
||||
ubootExtlinux = let
|
||||
sdImage = "${sd}/sd-image/${sd.imageName}";
|
||||
mutableImage = "/tmp/linked-image.qcow2";
|
||||
|
||||
machineConfig = pythonDict {
|
||||
bios = "${pkgs.ubootQemuX86}/u-boot.rom";
|
||||
qemuFlags = "-m 768 -machine type=pc,accel=tcg -drive file=${mutableImage},if=ide,format=qcow2";
|
||||
};
|
||||
in makeTest {
|
||||
name = "boot-uboot-extlinux";
|
||||
nodes = { };
|
||||
testScript = ''
|
||||
import os
|
||||
|
||||
# Create a mutable linked image backed by the read-only SD image
|
||||
if os.system("qemu-img create -f qcow2 -F raw -b ${sdImage} ${mutableImage}") != 0:
|
||||
raise RuntimeError("Could not create mutable linked image")
|
||||
|
||||
machine = create_machine(${machineConfig})
|
||||
machine.start()
|
||||
machine.wait_for_unit("multi-user.target")
|
||||
machine.succeed("nix store verify -r --no-trust --option experimental-features nix-command /run/current-system")
|
||||
machine.shutdown()
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
|
104
third_party/nixpkgs/nixos/tests/frr.nix
vendored
Normal file
104
third_party/nixpkgs/nixos/tests/frr.nix
vendored
Normal file
|
@ -0,0 +1,104 @@
|
|||
# This test runs FRR and checks if OSPF routing works.
|
||||
#
|
||||
# Network topology:
|
||||
# [ client ]--net1--[ router1 ]--net2--[ router2 ]--net3--[ server ]
|
||||
#
|
||||
# All interfaces are in OSPF Area 0.
|
||||
|
||||
import ./make-test-python.nix ({ pkgs, ... }:
|
||||
let
|
||||
|
||||
ifAddr = node: iface: (pkgs.lib.head node.config.networking.interfaces.${iface}.ipv4.addresses).address;
|
||||
|
||||
ospfConf1 = ''
|
||||
router ospf
|
||||
network 192.168.0.0/16 area 0
|
||||
'';
|
||||
|
||||
ospfConf2 = ''
|
||||
interface eth2
|
||||
ip ospf hello-interval 1
|
||||
ip ospf dead-interval 5
|
||||
!
|
||||
router ospf
|
||||
network 192.168.0.0/16 area 0
|
||||
'';
|
||||
|
||||
in
|
||||
{
|
||||
name = "frr";
|
||||
|
||||
meta = with pkgs.lib.maintainers; {
|
||||
maintainers = [ hexa ];
|
||||
};
|
||||
|
||||
nodes = {
|
||||
|
||||
client =
|
||||
{ nodes, ... }:
|
||||
{
|
||||
virtualisation.vlans = [ 1 ];
|
||||
networking.defaultGateway = ifAddr nodes.router1 "eth1";
|
||||
};
|
||||
|
||||
router1 =
|
||||
{ ... }:
|
||||
{
|
||||
virtualisation.vlans = [ 1 2 ];
|
||||
boot.kernel.sysctl."net.ipv4.ip_forward" = "1";
|
||||
networking.firewall.extraCommands = "iptables -A nixos-fw -i eth2 -p ospfigp -j ACCEPT";
|
||||
services.frr.ospf = {
|
||||
enable = true;
|
||||
config = ospfConf1;
|
||||
};
|
||||
|
||||
specialisation.ospf.configuration = {
|
||||
services.frr.ospf.config = ospfConf2;
|
||||
};
|
||||
};
|
||||
|
||||
router2 =
|
||||
{ ... }:
|
||||
{
|
||||
virtualisation.vlans = [ 3 2 ];
|
||||
boot.kernel.sysctl."net.ipv4.ip_forward" = "1";
|
||||
networking.firewall.extraCommands = "iptables -A nixos-fw -i eth2 -p ospfigp -j ACCEPT";
|
||||
services.frr.ospf = {
|
||||
enable = true;
|
||||
config = ospfConf2;
|
||||
};
|
||||
};
|
||||
|
||||
server =
|
||||
{ nodes, ... }:
|
||||
{
|
||||
virtualisation.vlans = [ 3 ];
|
||||
networking.defaultGateway = ifAddr nodes.router2 "eth1";
|
||||
};
|
||||
};
|
||||
|
||||
testScript =
|
||||
{ nodes, ... }:
|
||||
''
|
||||
start_all()
|
||||
|
||||
# Wait for the networking to start on all machines
|
||||
for machine in client, router1, router2, server:
|
||||
machine.wait_for_unit("network.target")
|
||||
|
||||
with subtest("Wait for Zebra and OSPFD"):
|
||||
for gw in router1, router2:
|
||||
gw.wait_for_unit("zebra")
|
||||
gw.wait_for_unit("ospfd")
|
||||
|
||||
router1.succeed("${nodes.router1.config.system.build.toplevel}/specialisation/ospf/bin/switch-to-configuration test >&2")
|
||||
|
||||
with subtest("Wait for OSPF to form adjacencies"):
|
||||
for gw in router1, router2:
|
||||
gw.wait_until_succeeds("vtysh -c 'show ip ospf neighbor' | grep Full")
|
||||
gw.wait_until_succeeds("vtysh -c 'show ip route' | grep '^O>'")
|
||||
|
||||
with subtest("Test ICMP"):
|
||||
client.wait_until_succeeds("ping -c 3 server >&2")
|
||||
'';
|
||||
})
|
10
third_party/nixpkgs/nixos/tests/installer.nix
vendored
10
third_party/nixpkgs/nixos/tests/installer.nix
vendored
|
@ -561,26 +561,16 @@ in {
|
|||
+ " mkpart primary 2048M -1s" # PV2
|
||||
+ " set 2 lvm on",
|
||||
"udevadm settle",
|
||||
"sleep 1",
|
||||
"pvcreate /dev/vda1 /dev/vda2",
|
||||
"sleep 1",
|
||||
"vgcreate MyVolGroup /dev/vda1 /dev/vda2",
|
||||
"sleep 1",
|
||||
"lvcreate --size 1G --name swap MyVolGroup",
|
||||
"sleep 1",
|
||||
"lvcreate --size 3G --name nixos MyVolGroup",
|
||||
"sleep 1",
|
||||
"mkswap -f /dev/MyVolGroup/swap -L swap",
|
||||
"swapon -L swap",
|
||||
"mkfs.xfs -L nixos /dev/MyVolGroup/nixos",
|
||||
"mount LABEL=nixos /mnt",
|
||||
)
|
||||
'';
|
||||
postBootCommands = ''
|
||||
assert "loaded active" in machine.succeed(
|
||||
"systemctl list-units 'lvm2-pvscan@*' -ql --no-legend | tee /dev/stderr"
|
||||
)
|
||||
'';
|
||||
};
|
||||
|
||||
# Boot off an encrypted root partition with the default LUKS header format
|
||||
|
|
|
@ -60,13 +60,6 @@ let
|
|||
advertiseAddress = master.ip;
|
||||
};
|
||||
masterAddress = "${masterName}.${config.networking.domain}";
|
||||
# workaround for:
|
||||
# https://github.com/kubernetes/kubernetes/issues/102676
|
||||
# (workaround from) https://github.com/kubernetes/kubernetes/issues/95488
|
||||
kubelet.extraOpts = ''\
|
||||
--cgroups-per-qos=false \
|
||||
--enforce-node-allocatable="" \
|
||||
'';
|
||||
};
|
||||
}
|
||||
(optionalAttrs (any (role: role == "master") machine.roles) {
|
||||
|
|
42
third_party/nixpkgs/nixos/tests/starship.nix
vendored
Normal file
42
third_party/nixpkgs/nixos/tests/starship.nix
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
import ./make-test-python.nix ({ pkgs, ... }: {
|
||||
name = "starship";
|
||||
meta.maintainers = pkgs.starship.meta.maintainers;
|
||||
|
||||
machine = {
|
||||
programs = {
|
||||
fish.enable = true;
|
||||
zsh.enable = true;
|
||||
|
||||
starship = {
|
||||
enable = true;
|
||||
settings.format = "<starship>";
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = map
|
||||
(shell: pkgs.writeScriptBin "expect-${shell}" ''
|
||||
#!${pkgs.expect}/bin/expect -f
|
||||
|
||||
spawn env TERM=xterm ${shell} -i
|
||||
|
||||
expect "<starship>" {
|
||||
send "exit\n"
|
||||
} timeout {
|
||||
send_user "\n${shell} failed to display Starship\n"
|
||||
exit 1
|
||||
}
|
||||
|
||||
expect eof
|
||||
'')
|
||||
[ "bash" "fish" "zsh" ];
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
start_all()
|
||||
machine.wait_for_unit("default.target")
|
||||
|
||||
machine.succeed("expect-bash")
|
||||
machine.succeed("expect-fish")
|
||||
machine.succeed("expect-zsh")
|
||||
'';
|
||||
})
|
141
third_party/nixpkgs/nixos/tests/systemd-boot.nix
vendored
141
third_party/nixpkgs/nixos/tests/systemd-boot.nix
vendored
|
@ -110,4 +110,145 @@ in
|
|||
assert "updating systemd-boot from (000.0-1-notnixos) to " in output
|
||||
'';
|
||||
};
|
||||
|
||||
memtest86 = makeTest {
|
||||
name = "systemd-boot-memtest86";
|
||||
meta.maintainers = with pkgs.lib.maintainers; [ Enzime ];
|
||||
|
||||
machine = { pkgs, lib, ... }: {
|
||||
imports = [ common ];
|
||||
boot.loader.systemd-boot.memtest86.enable = true;
|
||||
nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [
|
||||
"memtest86-efi"
|
||||
];
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
machine.succeed("test -e /boot/loader/entries/memtest86.conf")
|
||||
machine.succeed("test -e /boot/efi/memtest86/BOOTX64.efi")
|
||||
'';
|
||||
};
|
||||
|
||||
netbootxyz = makeTest {
|
||||
name = "systemd-boot-netbootxyz";
|
||||
meta.maintainers = with pkgs.lib.maintainers; [ Enzime ];
|
||||
|
||||
machine = { pkgs, lib, ... }: {
|
||||
imports = [ common ];
|
||||
boot.loader.systemd-boot.netbootxyz.enable = true;
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
machine.succeed("test -e /boot/loader/entries/o_netbootxyz.conf")
|
||||
machine.succeed("test -e /boot/efi/netbootxyz/netboot.xyz.efi")
|
||||
'';
|
||||
};
|
||||
|
||||
entryFilename = makeTest {
|
||||
name = "systemd-boot-entry-filename";
|
||||
meta.maintainers = with pkgs.lib.maintainers; [ Enzime ];
|
||||
|
||||
machine = { pkgs, lib, ... }: {
|
||||
imports = [ common ];
|
||||
boot.loader.systemd-boot.memtest86.enable = true;
|
||||
boot.loader.systemd-boot.memtest86.entryFilename = "apple.conf";
|
||||
nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [
|
||||
"memtest86-efi"
|
||||
];
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
machine.fail("test -e /boot/loader/entries/memtest86.conf")
|
||||
machine.succeed("test -e /boot/loader/entries/apple.conf")
|
||||
machine.succeed("test -e /boot/efi/memtest86/BOOTX64.efi")
|
||||
'';
|
||||
};
|
||||
|
||||
extraEntries = makeTest {
|
||||
name = "systemd-boot-extra-entries";
|
||||
meta.maintainers = with pkgs.lib.maintainers; [ Enzime ];
|
||||
|
||||
machine = { pkgs, lib, ... }: {
|
||||
imports = [ common ];
|
||||
boot.loader.systemd-boot.extraEntries = {
|
||||
"banana.conf" = ''
|
||||
title banana
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
machine.succeed("test -e /boot/loader/entries/banana.conf")
|
||||
machine.succeed("test -e /boot/efi/nixos/.extra-files/loader/entries/banana.conf")
|
||||
'';
|
||||
};
|
||||
|
||||
extraFiles = makeTest {
|
||||
name = "systemd-boot-extra-files";
|
||||
meta.maintainers = with pkgs.lib.maintainers; [ Enzime ];
|
||||
|
||||
machine = { pkgs, lib, ... }: {
|
||||
imports = [ common ];
|
||||
boot.loader.systemd-boot.extraFiles = {
|
||||
"efi/fruits/tomato.efi" = pkgs.netbootxyz-efi;
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
machine.succeed("test -e /boot/efi/fruits/tomato.efi")
|
||||
machine.succeed("test -e /boot/efi/nixos/.extra-files/efi/fruits/tomato.efi")
|
||||
'';
|
||||
};
|
||||
|
||||
switch-test = makeTest {
|
||||
name = "systemd-boot-switch-test";
|
||||
meta.maintainers = with pkgs.lib.maintainers; [ Enzime ];
|
||||
|
||||
nodes = {
|
||||
inherit common;
|
||||
|
||||
machine = { pkgs, ... }: {
|
||||
imports = [ common ];
|
||||
boot.loader.systemd-boot.extraFiles = {
|
||||
"efi/fruits/tomato.efi" = pkgs.netbootxyz-efi;
|
||||
};
|
||||
};
|
||||
|
||||
with_netbootxyz = { pkgs, ... }: {
|
||||
imports = [ common ];
|
||||
boot.loader.systemd-boot.netbootxyz.enable = true;
|
||||
};
|
||||
};
|
||||
|
||||
testScript = { nodes, ... }: let
|
||||
originalSystem = nodes.machine.config.system.build.toplevel;
|
||||
baseSystem = nodes.common.config.system.build.toplevel;
|
||||
finalSystem = nodes.with_netbootxyz.config.system.build.toplevel;
|
||||
in ''
|
||||
machine.succeed("test -e /boot/efi/fruits/tomato.efi")
|
||||
machine.succeed("test -e /boot/efi/nixos/.extra-files/efi/fruits/tomato.efi")
|
||||
|
||||
with subtest("remove files when no longer needed"):
|
||||
machine.succeed("${baseSystem}/bin/switch-to-configuration boot")
|
||||
machine.fail("test -e /boot/efi/fruits/tomato.efi")
|
||||
machine.fail("test -d /boot/efi/fruits")
|
||||
machine.succeed("test -d /boot/efi/nixos/.extra-files")
|
||||
machine.fail("test -e /boot/efi/nixos/.extra-files/efi/fruits/tomato.efi")
|
||||
machine.fail("test -d /boot/efi/nixos/.extra-files/efi/fruits")
|
||||
|
||||
with subtest("files are added back when needed again"):
|
||||
machine.succeed("${originalSystem}/bin/switch-to-configuration boot")
|
||||
machine.succeed("test -e /boot/efi/fruits/tomato.efi")
|
||||
machine.succeed("test -e /boot/efi/nixos/.extra-files/efi/fruits/tomato.efi")
|
||||
|
||||
with subtest("simultaneously removing and adding files works"):
|
||||
machine.succeed("${finalSystem}/bin/switch-to-configuration boot")
|
||||
machine.fail("test -e /boot/efi/fruits/tomato.efi")
|
||||
machine.fail("test -e /boot/efi/nixos/.extra-files/efi/fruits/tomato.efi")
|
||||
machine.succeed("test -e /boot/loader/entries/o_netbootxyz.conf")
|
||||
machine.succeed("test -e /boot/efi/netbootxyz/netboot.xyz.efi")
|
||||
machine.succeed("test -e /boot/efi/nixos/.extra-files/loader/entries/o_netbootxyz.conf")
|
||||
machine.succeed("test -e /boot/efi/nixos/.extra-files/efi/netbootxyz/netboot.xyz.efi")
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue