mirror of
https://github.com/NixOS/nixpkgs.git
synced 2024-10-30 06:01:19 +00:00
Merge remote-tracking branch 'upstream/master' into tests-restrict-arguments
This commit is contained in:
commit
6c469679f6
4
.github/labeler.yml
vendored
4
.github/labeler.yml
vendored
@ -5,10 +5,6 @@
|
||||
- pkgs/development/libraries/agda/**/*
|
||||
- pkgs/top-level/agda-packages.nix
|
||||
|
||||
"6.topic: bsd":
|
||||
- pkgs/os-specific/bsd/**/*
|
||||
- pkgs/stdenv/freebsd/**/*
|
||||
|
||||
"6.topic: cinnamon":
|
||||
- pkgs/desktops/cinnamon/**/*
|
||||
|
||||
|
6
.github/workflows/backport.yml
vendored
6
.github/workflows/backport.yml
vendored
@ -2,6 +2,12 @@ name: Backport
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [closed, labeled]
|
||||
|
||||
# WARNING:
|
||||
# When extending this action, be aware that $GITHUB_TOKEN allows write access to
|
||||
# the GitHub repository. This means that it should not evaluate user input in a
|
||||
# way that allows code injection.
|
||||
|
||||
jobs:
|
||||
backport:
|
||||
name: Backport Pull Request
|
||||
|
5
.github/workflows/labels.yml
vendored
5
.github/workflows/labels.yml
vendored
@ -4,6 +4,11 @@ on:
|
||||
pull_request_target:
|
||||
types: [edited, opened, synchronize, reopened]
|
||||
|
||||
# WARNING:
|
||||
# When extending this action, be aware that $GITHUB_TOKEN allows some write
|
||||
# access to the GitHub API. This means that it should not evaluate user input in
|
||||
# a way that allows code injection.
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
5
.github/workflows/pending-set.yml
vendored
5
.github/workflows/pending-set.yml
vendored
@ -3,6 +3,11 @@ name: "set pending status"
|
||||
on:
|
||||
pull_request_target:
|
||||
|
||||
# WARNING:
|
||||
# When extending this action, be aware that $GITHUB_TOKEN allows write access to
|
||||
# the GitHub repository. This means that it should not evaluate user input in a
|
||||
# way that allows code injection.
|
||||
|
||||
jobs:
|
||||
action:
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -125,7 +125,7 @@ Reviewing process:
|
||||
- Type should be appropriate (string related types differs in their merging capabilities, `optionSet` and `string` types are deprecated).
|
||||
- Description, default and example should be provided.
|
||||
- Ensure that option changes are backward compatible.
|
||||
- `mkRenamedOptionModule` and `mkAliasOptionModule` functions provide way to make option changes backward compatible.
|
||||
- `mkRenamedOptionModuleWith` provides a way to make option changes backward compatible.
|
||||
- Ensure that removed options are declared with `mkRemovedOptionModule`
|
||||
- Ensure that changes that are not backward compatible are mentioned in release notes.
|
||||
- Ensure that documentations affected by the change is updated.
|
||||
|
@ -85,7 +85,7 @@ you will still need to commit the modified version of the lock files, but at lea
|
||||
|
||||
each tool has an abstraction to just build the node_modules (dependencies) directory. you can always use the stdenv.mkDerivation with the node_modules to build the package (symlink the node_modules directory and then use the package build command). the node_modules abstraction can be also used to build some web framework frontends. For an example of this see how [plausible](https://github.com/NixOS/nixpkgs/blob/master/pkgs/servers/web-apps/plausible/default.nix) is built. mkYarnModules to make the derivation containing node_modules. Then when building the frontend you can just symlink the node_modules directory
|
||||
|
||||
## javascript packages inside nixpkgs {#javascript-packages-nixpkgs}
|
||||
## Javascript packages inside nixpkgs {#javascript-packages-nixpkgs}
|
||||
|
||||
The `pkgs/development/node-packages` folder contains a generated collection of
|
||||
[NPM packages](https://npmjs.com/) that can be installed with the Nix package
|
||||
@ -121,12 +121,14 @@ requires `node-gyp-build`, so [we override](https://github.com/NixOS/nixpkgs/blo
|
||||
};
|
||||
```
|
||||
|
||||
### Adding and Updating Javascript packages in nixpkgs
|
||||
|
||||
To add a package from NPM to nixpkgs:
|
||||
|
||||
1. Modify `pkgs/development/node-packages/node-packages.json` to add, update
|
||||
or remove package entries to have it included in `nodePackages` and
|
||||
`nodePackages_latest`.
|
||||
2. Run the script: `cd pkgs/development/node-packages && ./generate.sh`.
|
||||
2. Run the script: `./pkgs/development/node-packages/generate.sh`.
|
||||
3. Build your new package to test your changes:
|
||||
`cd /path/to/nixpkgs && nix-build -A nodePackages.<new-or-updated-package>`.
|
||||
To build against the latest stable Current Node.js version (e.g. 14.x):
|
||||
@ -137,6 +139,26 @@ For more information about the generation process, consult the
|
||||
[README.md](https://github.com/svanderburg/node2nix) file of the `node2nix`
|
||||
tool.
|
||||
|
||||
To update NPM packages in nixpkgs, run the same `generate.sh` script:
|
||||
|
||||
```sh
|
||||
./pkgs/development/node-packages/generate.sh
|
||||
```
|
||||
|
||||
#### Git protocol error
|
||||
|
||||
Some packages may have Git dependencies from GitHub specified with `git://`.
|
||||
GitHub has
|
||||
[disabled unecrypted Git connections](https://github.blog/2021-09-01-improving-git-protocol-security-github/#no-more-unauthenticated-git),
|
||||
so you may see the following error when running the generate script:
|
||||
`The unauthenticated git protocol on port 9418 is no longer supported`.
|
||||
|
||||
Use the following Git configuration to resolve the issue:
|
||||
|
||||
```sh
|
||||
git config --global url."https://github.com/".insteadOf git://github.com/
|
||||
```
|
||||
|
||||
## Tool specific instructions {#javascript-tool-specific}
|
||||
|
||||
### node2nix {#javascript-node2nix}
|
||||
|
115
lib/attrsets.nix
115
lib/attrsets.nix
@ -4,8 +4,8 @@
|
||||
let
|
||||
inherit (builtins) head tail length;
|
||||
inherit (lib.trivial) id;
|
||||
inherit (lib.strings) concatStringsSep sanitizeDerivationName;
|
||||
inherit (lib.lists) foldr foldl' concatMap concatLists elemAt all;
|
||||
inherit (lib.strings) concatStringsSep concatMapStringsSep escapeNixIdentifier sanitizeDerivationName;
|
||||
inherit (lib.lists) foldr foldl' concatMap concatLists elemAt all partition groupBy take foldl;
|
||||
in
|
||||
|
||||
rec {
|
||||
@ -78,6 +78,103 @@ rec {
|
||||
in attrByPath attrPath (abort errorMsg);
|
||||
|
||||
|
||||
/* Update or set specific paths of an attribute set.
|
||||
|
||||
Takes a list of updates to apply and an attribute set to apply them to,
|
||||
and returns the attribute set with the updates applied. Updates are
|
||||
represented as { path = ...; update = ...; } values, where `path` is a
|
||||
list of strings representing the attribute path that should be updated,
|
||||
and `update` is a function that takes the old value at that attribute path
|
||||
as an argument and returns the new
|
||||
value it should be.
|
||||
|
||||
Properties:
|
||||
- Updates to deeper attribute paths are applied before updates to more
|
||||
shallow attribute paths
|
||||
- Multiple updates to the same attribute path are applied in the order
|
||||
they appear in the update list
|
||||
- If any but the last `path` element leads into a value that is not an
|
||||
attribute set, an error is thrown
|
||||
- If there is an update for an attribute path that doesn't exist,
|
||||
accessing the argument in the update function causes an error, but
|
||||
intermediate attribute sets are implicitly created as needed
|
||||
|
||||
Example:
|
||||
updateManyAttrsByPath [
|
||||
{
|
||||
path = [ "a" "b" ];
|
||||
update = old: { d = old.c; };
|
||||
}
|
||||
{
|
||||
path = [ "a" "b" "c" ];
|
||||
update = old: old + 1;
|
||||
}
|
||||
{
|
||||
path = [ "x" "y" ];
|
||||
update = old: "xy";
|
||||
}
|
||||
] { a.b.c = 0; }
|
||||
=> { a = { b = { d = 1; }; }; x = { y = "xy"; }; }
|
||||
*/
|
||||
updateManyAttrsByPath = let
|
||||
# When recursing into attributes, instead of updating the `path` of each
|
||||
# update using `tail`, which needs to allocate an entirely new list,
|
||||
# we just pass a prefix length to use and make sure to only look at the
|
||||
# path without the prefix length, so that we can reuse the original list
|
||||
# entries.
|
||||
go = prefixLength: hasValue: value: updates:
|
||||
let
|
||||
# Splits updates into ones on this level (split.right)
|
||||
# And ones on levels further down (split.wrong)
|
||||
split = partition (el: length el.path == prefixLength) updates;
|
||||
|
||||
# Groups updates on further down levels into the attributes they modify
|
||||
nested = groupBy (el: elemAt el.path prefixLength) split.wrong;
|
||||
|
||||
# Applies only nested modification to the input value
|
||||
withNestedMods =
|
||||
# Return the value directly if we don't have any nested modifications
|
||||
if split.wrong == [] then
|
||||
if hasValue then value
|
||||
else
|
||||
# Throw an error if there is no value. This `head` call here is
|
||||
# safe, but only in this branch since `go` could only be called
|
||||
# with `hasValue == false` for nested updates, in which case
|
||||
# it's also always called with at least one update
|
||||
let updatePath = (head split.right).path; in
|
||||
throw
|
||||
( "updateManyAttrsByPath: Path '${showAttrPath updatePath}' does "
|
||||
+ "not exist in the given value, but the first update to this "
|
||||
+ "path tries to access the existing value.")
|
||||
else
|
||||
# If there are nested modifications, try to apply them to the value
|
||||
if ! hasValue then
|
||||
# But if we don't have a value, just use an empty attribute set
|
||||
# as the value, but simplify the code a bit
|
||||
mapAttrs (name: go (prefixLength + 1) false null) nested
|
||||
else if isAttrs value then
|
||||
# If we do have a value and it's an attribute set, override it
|
||||
# with the nested modifications
|
||||
value //
|
||||
mapAttrs (name: go (prefixLength + 1) (value ? ${name}) value.${name}) nested
|
||||
else
|
||||
# However if it's not an attribute set, we can't apply the nested
|
||||
# modifications, throw an error
|
||||
let updatePath = (head split.wrong).path; in
|
||||
throw
|
||||
( "updateManyAttrsByPath: Path '${showAttrPath updatePath}' needs to "
|
||||
+ "be updated, but path '${showAttrPath (take prefixLength updatePath)}' "
|
||||
+ "of the given value is not an attribute set, so we can't "
|
||||
+ "update an attribute inside of it.");
|
||||
|
||||
# We get the final result by applying all the updates on this level
|
||||
# after having applied all the nested updates
|
||||
# We use foldl instead of foldl' so that in case of multiple updates,
|
||||
# intermediate values aren't evaluated if not needed
|
||||
in foldl (acc: el: el.update acc) withNestedMods split.right;
|
||||
|
||||
in updates: value: go 0 true value updates;
|
||||
|
||||
/* Return the specified attributes from a set.
|
||||
|
||||
Example:
|
||||
@ -477,6 +574,20 @@ rec {
|
||||
overrideExisting = old: new:
|
||||
mapAttrs (name: value: new.${name} or value) old;
|
||||
|
||||
/* Turns a list of strings into a human-readable description of those
|
||||
strings represented as an attribute path. The result of this function is
|
||||
not intended to be machine-readable.
|
||||
|
||||
Example:
|
||||
showAttrPath [ "foo" "10" "bar" ]
|
||||
=> "foo.\"10\".bar"
|
||||
showAttrPath []
|
||||
=> "<root attribute path>"
|
||||
*/
|
||||
showAttrPath = path:
|
||||
if path == [] then "<root attribute path>"
|
||||
else concatMapStringsSep "." escapeNixIdentifier path;
|
||||
|
||||
/* Get a package output.
|
||||
If no output is found, fallback to `.out` and then to the default.
|
||||
|
||||
|
@ -67,7 +67,7 @@ let
|
||||
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 checkListOfEnum
|
||||
info showWarnings nixpkgsVersion version
|
||||
info showWarnings nixpkgsVersion version isInOldestRelease
|
||||
mod compare splitByAndCompare
|
||||
functionArgs setFunctionArgs isFunction toFunction
|
||||
toHexString toBaseDigits;
|
||||
@ -79,9 +79,10 @@ let
|
||||
mapAttrs' mapAttrsToList mapAttrsRecursive mapAttrsRecursiveCond
|
||||
genAttrs isDerivation toDerivation optionalAttrs
|
||||
zipAttrsWithNames zipAttrsWith zipAttrs recursiveUpdateUntil
|
||||
recursiveUpdate matchAttrs overrideExisting getOutput getBin
|
||||
recursiveUpdate matchAttrs overrideExisting showAttrPath getOutput getBin
|
||||
getLib getDev getMan chooseDevOutputs zipWithNames zip
|
||||
recurseIntoAttrs dontRecurseIntoAttrs cartesianProductOfSets;
|
||||
recurseIntoAttrs dontRecurseIntoAttrs cartesianProductOfSets
|
||||
updateManyAttrsByPath;
|
||||
inherit (self.lists) singleton forEach foldr fold foldl foldl' imap0 imap1
|
||||
concatMap flatten remove findSingle findFirst any all count
|
||||
optional optionals toList range partition zipListsWith zipLists
|
||||
@ -120,7 +121,8 @@ let
|
||||
mkOptionDefault mkDefault mkImageMediaOverride mkForce mkVMOverride
|
||||
mkFixStrictness mkOrder mkBefore mkAfter mkAliasDefinitions
|
||||
mkAliasAndWrapDefinitions fixMergeModules mkRemovedOptionModule
|
||||
mkRenamedOptionModule mkMergedOptionModule mkChangedOptionModule
|
||||
mkRenamedOptionModule mkRenamedOptionModuleWith
|
||||
mkMergedOptionModule mkChangedOptionModule
|
||||
mkAliasOptionModule mkDerivedConfig doRename;
|
||||
inherit (self.options) isOption mkEnableOption mkSinkUndeclaredOptions
|
||||
mergeDefaultOption mergeOneOption mergeEqualOption mergeUniqueOption
|
||||
|
@ -4,6 +4,7 @@
|
||||
let
|
||||
inherit (lib.strings) toInt;
|
||||
inherit (lib.trivial) compare min;
|
||||
inherit (lib.attrsets) mapAttrs;
|
||||
in
|
||||
rec {
|
||||
|
||||
@ -340,15 +341,15 @@ rec {
|
||||
groupBy' builtins.add 0 (x: boolToString (x > 2)) [ 5 1 2 3 4 ]
|
||||
=> { true = 12; false = 3; }
|
||||
*/
|
||||
groupBy' = op: nul: pred: lst:
|
||||
foldl' (r: e:
|
||||
let
|
||||
key = pred e;
|
||||
in
|
||||
r // { ${key} = op (r.${key} or nul) e; }
|
||||
) {} lst;
|
||||
groupBy' = op: nul: pred: lst: mapAttrs (name: foldl op nul) (groupBy pred lst);
|
||||
|
||||
groupBy = groupBy' (sum: e: sum ++ [e]) [];
|
||||
groupBy = builtins.groupBy or (
|
||||
pred: foldl' (r: e:
|
||||
let
|
||||
key = pred e;
|
||||
in
|
||||
r // { ${key} = (r.${key} or []) ++ [e]; }
|
||||
) {});
|
||||
|
||||
/* Merges two lists of the same size together. If the sizes aren't the same
|
||||
the merging stops at the shortest. How both lists are merged is defined
|
||||
|
@ -9,7 +9,7 @@ let
|
||||
catAttrs
|
||||
concatLists
|
||||
concatMap
|
||||
count
|
||||
concatStringsSep
|
||||
elem
|
||||
filter
|
||||
findFirst
|
||||
@ -47,6 +47,20 @@ let
|
||||
showOption
|
||||
unknownModule
|
||||
;
|
||||
|
||||
showDeclPrefix = loc: decl: prefix:
|
||||
" - option(s) with prefix `${showOption (loc ++ [prefix])}' in module `${decl._file}'";
|
||||
showRawDecls = loc: decls:
|
||||
concatStringsSep "\n"
|
||||
(sort (a: b: a < b)
|
||||
(concatMap
|
||||
(decl: map
|
||||
(showDeclPrefix loc decl)
|
||||
(attrNames decl.options)
|
||||
)
|
||||
decls
|
||||
));
|
||||
|
||||
in
|
||||
|
||||
rec {
|
||||
@ -474,26 +488,61 @@ rec {
|
||||
[{ inherit (module) file; inherit value; }]
|
||||
) configs;
|
||||
|
||||
# Convert an option tree decl to a submodule option decl
|
||||
optionTreeToOption = decl:
|
||||
if isOption decl.options
|
||||
then decl
|
||||
else decl // {
|
||||
options = mkOption {
|
||||
type = types.submoduleWith {
|
||||
modules = [ { options = decl.options; } ];
|
||||
# `null` is not intended for use by modules. It is an internal
|
||||
# value that means "whatever the user has declared elsewhere".
|
||||
# This might become obsolete with https://github.com/NixOS/nixpkgs/issues/162398
|
||||
shorthandOnlyDefinesConfig = null;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
resultsByName = mapAttrs (name: decls:
|
||||
# We're descending into attribute ‘name’.
|
||||
let
|
||||
loc = prefix ++ [name];
|
||||
defns = defnsByName.${name} or [];
|
||||
defns' = defnsByName'.${name} or [];
|
||||
nrOptions = count (m: isOption m.options) decls;
|
||||
optionDecls = filter (m: isOption m.options) decls;
|
||||
in
|
||||
if nrOptions == length decls then
|
||||
if length optionDecls == length decls then
|
||||
let opt = fixupOptionType loc (mergeOptionDecls loc decls);
|
||||
in {
|
||||
matchedOptions = evalOptionValue loc opt defns';
|
||||
unmatchedDefns = [];
|
||||
}
|
||||
else if nrOptions != 0 then
|
||||
let
|
||||
firstOption = findFirst (m: isOption m.options) "" decls;
|
||||
firstNonOption = findFirst (m: !isOption m.options) "" decls;
|
||||
in
|
||||
throw "The option `${showOption loc}' in `${firstOption._file}' is a prefix of options in `${firstNonOption._file}'."
|
||||
else if optionDecls != [] then
|
||||
if all (x: x.options.type.name == "submodule") optionDecls
|
||||
# Raw options can only be merged into submodules. Merging into
|
||||
# attrsets might be nice, but ambiguous. Suppose we have
|
||||
# attrset as a `attrsOf submodule`. User declares option
|
||||
# attrset.foo.bar, this could mean:
|
||||
# a. option `bar` is only available in `attrset.foo`
|
||||
# b. option `foo.bar` is available in all `attrset.*`
|
||||
# c. reject and require "<name>" as a reminder that it behaves like (b).
|
||||
# d. magically combine (a) and (c).
|
||||
# All of the above are merely syntax sugar though.
|
||||
then
|
||||
let opt = fixupOptionType loc (mergeOptionDecls loc (map optionTreeToOption decls));
|
||||
in {
|
||||
matchedOptions = evalOptionValue loc opt defns';
|
||||
unmatchedDefns = [];
|
||||
}
|
||||
else
|
||||
let
|
||||
firstNonOption = findFirst (m: !isOption m.options) "" decls;
|
||||
nonOptions = filter (m: !isOption m.options) decls;
|
||||
in
|
||||
throw "The option `${showOption loc}' in module `${(lib.head optionDecls)._file}' would be a parent of the following options, but its type `${(lib.head optionDecls).options.type.description or "<no description>"}' does not support nested options.\n${
|
||||
showRawDecls loc nonOptions
|
||||
}"
|
||||
else
|
||||
mergeModules' loc decls defns) declsByName;
|
||||
|
||||
@ -753,13 +802,14 @@ rec {
|
||||
compare = a: b: (a.priority or 1000) < (b.priority or 1000);
|
||||
in sort compare defs';
|
||||
|
||||
/* Hack for backward compatibility: convert options of type
|
||||
optionSet to options of type submodule. FIXME: remove
|
||||
eventually. */
|
||||
fixupOptionType = loc: opt:
|
||||
let
|
||||
options = opt.options or
|
||||
(throw "Option `${showOption loc}' has type optionSet but has no option attribute, in ${showFiles opt.declarations}.");
|
||||
|
||||
# Hack for backward compatibility: convert options of type
|
||||
# optionSet to options of type submodule. FIXME: remove
|
||||
# eventually.
|
||||
f = tp:
|
||||
if tp.name == "option set" || tp.name == "submodule" then
|
||||
throw "The option ${showOption loc} uses submodules without a wrapping type, in ${showFiles opt.declarations}."
|
||||
@ -904,6 +954,26 @@ rec {
|
||||
use = builtins.trace "Obsolete option `${showOption from}' is used. It was renamed to `${showOption to}'.";
|
||||
};
|
||||
|
||||
mkRenamedOptionModuleWith = {
|
||||
/* Old option path as list of strings. */
|
||||
from,
|
||||
/* New option path as list of strings. */
|
||||
to,
|
||||
|
||||
/*
|
||||
Release number of the first release that contains the rename, ignoring backports.
|
||||
Set it to the upcoming release, matching the nixpkgs/.version file.
|
||||
*/
|
||||
sinceRelease,
|
||||
|
||||
}: doRename {
|
||||
inherit from to;
|
||||
visible = false;
|
||||
warn = lib.isInOldestRelease sinceRelease;
|
||||
use = lib.warnIf (lib.isInOldestRelease sinceRelease)
|
||||
"Obsolete option `${showOption from}' is used. It was renamed to `${showOption to}'.";
|
||||
};
|
||||
|
||||
/* Return a module that causes a warning to be shown if any of the "from"
|
||||
option is defined; the defined values can be used in the "mergeFn" to set
|
||||
the "to" value.
|
||||
|
@ -231,7 +231,7 @@ rec {
|
||||
then true
|
||||
else opt.visible or true;
|
||||
readOnly = opt.readOnly or false;
|
||||
type = opt.type.description or null;
|
||||
type = opt.type.description or "unspecified";
|
||||
}
|
||||
// optionalAttrs (opt ? example) { example = scrubOptionValue opt.example; }
|
||||
// optionalAttrs (opt ? default) { default = scrubOptionValue opt.default; }
|
||||
|
@ -105,7 +105,8 @@ rec {
|
||||
else if final.isAarch64 then "arm64"
|
||||
else if final.isx86_32 then "i386"
|
||||
else if final.isx86_64 then "x86_64"
|
||||
else if final.isMips then "mips"
|
||||
else if final.isMips32 then "mips"
|
||||
else if final.isMips64 then "mips" # linux kernel does not distinguish mips32/mips64
|
||||
else if final.isPower then "powerpc"
|
||||
else if final.isRiscV then "riscv"
|
||||
else if final.isS390 then "s390"
|
||||
|
@ -26,7 +26,7 @@ let
|
||||
|
||||
# Linux
|
||||
"aarch64-linux" "armv5tel-linux" "armv6l-linux" "armv7a-linux"
|
||||
"armv7l-linux" "i686-linux" "m68k-linux" "mipsel-linux"
|
||||
"armv7l-linux" "i686-linux" "m68k-linux" "mipsel-linux" "mips64el-linux"
|
||||
"powerpc64-linux" "powerpc64le-linux" "riscv32-linux"
|
||||
"riscv64-linux" "s390-linux" "s390x-linux" "x86_64-linux"
|
||||
|
||||
@ -87,7 +87,11 @@ in {
|
||||
darwin = filterDoubles predicates.isDarwin;
|
||||
freebsd = filterDoubles predicates.isFreeBSD;
|
||||
# Should be better, but MinGW is unclear.
|
||||
gnu = filterDoubles (matchAttrs { kernel = parse.kernels.linux; abi = parse.abis.gnu; }) ++ filterDoubles (matchAttrs { kernel = parse.kernels.linux; abi = parse.abis.gnueabi; }) ++ filterDoubles (matchAttrs { kernel = parse.kernels.linux; abi = parse.abis.gnueabihf; });
|
||||
gnu = filterDoubles (matchAttrs { kernel = parse.kernels.linux; abi = parse.abis.gnu; })
|
||||
++ filterDoubles (matchAttrs { kernel = parse.kernels.linux; abi = parse.abis.gnueabi; })
|
||||
++ filterDoubles (matchAttrs { kernel = parse.kernels.linux; abi = parse.abis.gnueabihf; })
|
||||
++ filterDoubles (matchAttrs { kernel = parse.kernels.linux; abi = parse.abis.gnuabin32; })
|
||||
++ filterDoubles (matchAttrs { kernel = parse.kernels.linux; abi = parse.abis.gnuabi64; });
|
||||
illumos = filterDoubles predicates.isSunOS;
|
||||
linux = filterDoubles predicates.isLinux;
|
||||
netbsd = filterDoubles predicates.isNetBSD;
|
||||
|
@ -93,6 +93,26 @@ rec {
|
||||
config = "mipsel-unknown-linux-gnu";
|
||||
} // platforms.fuloong2f_n32;
|
||||
|
||||
# MIPS ABI table transcribed from here: https://wiki.debian.org/Multiarch/Tuples
|
||||
|
||||
# can execute on 32bit chip
|
||||
mips-linux-gnu = { config = "mips-linux-gnu"; } // platforms.gcc_mips32r2_o32;
|
||||
mipsel-linux-gnu = { config = "mipsel-linux-gnu"; } // platforms.gcc_mips32r2_o32;
|
||||
mipsisa32r6-linux-gnu = { config = "mipsisa32r6-linux-gnu"; } // platforms.gcc_mips32r6_o32;
|
||||
mipsisa32r6el-linux-gnu = { config = "mipsisa32r6el-linux-gnu"; } // platforms.gcc_mips32r6_o32;
|
||||
|
||||
# require 64bit chip (for more registers, 64-bit floating point, 64-bit "long long") but use 32bit pointers
|
||||
mips64-linux-gnuabin32 = { config = "mips64-linux-gnuabin32"; } // platforms.gcc_mips64r2_n32;
|
||||
mips64el-linux-gnuabin32 = { config = "mips64el-linux-gnuabin32"; } // platforms.gcc_mips64r2_n32;
|
||||
mipsisa64r6-linux-gnuabin32 = { config = "mipsisa64r6-linux-gnuabin32"; } // platforms.gcc_mips64r6_n32;
|
||||
mipsisa64r6el-linux-gnuabin32 = { config = "mipsisa64r6el-linux-gnuabin32"; } // platforms.gcc_mips64r6_n32;
|
||||
|
||||
# 64bit pointers
|
||||
mips64-linux-gnuabi64 = { config = "mips64-linux-gnuabi64"; } // platforms.gcc_mips64r2_64;
|
||||
mips64el-linux-gnuabi64 = { config = "mips64el-linux-gnuabi64"; } // platforms.gcc_mips64r2_64;
|
||||
mipsisa64r6-linux-gnuabi64 = { config = "mipsisa64r6-linux-gnuabi64"; } // platforms.gcc_mips64r6_64;
|
||||
mipsisa64r6el-linux-gnuabi64 = { config = "mipsisa64r6el-linux-gnuabi64"; } // platforms.gcc_mips64r6_64;
|
||||
|
||||
muslpi = raspberryPi // {
|
||||
config = "armv6l-unknown-linux-musleabihf";
|
||||
};
|
||||
|
@ -17,6 +17,10 @@ rec {
|
||||
isAarch32 = { cpu = { family = "arm"; bits = 32; }; };
|
||||
isAarch64 = { cpu = { family = "arm"; bits = 64; }; };
|
||||
isMips = { cpu = { family = "mips"; }; };
|
||||
isMips32 = { cpu = { family = "mips"; bits = 32; }; };
|
||||
isMips64 = { cpu = { family = "mips"; bits = 64; }; };
|
||||
isMips64n32 = { cpu = { family = "mips"; bits = 64; }; abi = { abi = "n32"; }; };
|
||||
isMips64n64 = { cpu = { family = "mips"; bits = 64; }; abi = { abi = "64"; }; };
|
||||
isMmix = { cpu = { family = "mmix"; }; };
|
||||
isRiscV = { cpu = { family = "riscv"; }; };
|
||||
isSparc = { cpu = { family = "sparc"; }; };
|
||||
@ -57,7 +61,7 @@ rec {
|
||||
|
||||
isAndroid = [ { abi = abis.android; } { abi = abis.androideabi; } ];
|
||||
isGnu = with abis; map (a: { abi = a; }) [ gnuabi64 gnu gnueabi gnueabihf ];
|
||||
isMusl = with abis; map (a: { abi = a; }) [ musl musleabi musleabihf ];
|
||||
isMusl = with abis; map (a: { abi = a; }) [ musl musleabi musleabihf muslabin32 muslabi64 ];
|
||||
isUClibc = with abis; map (a: { abi = a; }) [ uclibc uclibceabi uclibceabihf ];
|
||||
|
||||
isEfi = map (family: { cpu.family = family; })
|
||||
|
@ -359,6 +359,13 @@ rec {
|
||||
];
|
||||
};
|
||||
gnuabi64 = { abi = "64"; };
|
||||
muslabi64 = { abi = "64"; };
|
||||
|
||||
# NOTE: abi=n32 requires a 64-bit MIPS chip! That is not a typo.
|
||||
# It is basically the 64-bit abi with 32-bit pointers. Details:
|
||||
# https://www.linux-mips.org/pub/linux/mips/doc/ABI/MIPS-N32-ABI-Handbook.pdf
|
||||
gnuabin32 = { abi = "n32"; };
|
||||
muslabin32 = { abi = "n32"; };
|
||||
|
||||
musleabi = { float = "soft"; };
|
||||
musleabihf = { float = "hard"; };
|
||||
|
@ -1,3 +1,10 @@
|
||||
# Note: lib/systems/default.nix takes care of producing valid,
|
||||
# fully-formed "platform" values (e.g. hostPlatform, buildPlatform,
|
||||
# targetPlatform, etc) containing at least the minimal set of attrs
|
||||
# required (see types.parsedPlatform in lib/systems/parse.nix). This
|
||||
# file takes an already-valid platform and further elaborates it with
|
||||
# optional fields such as linux-kernel, gcc, etc.
|
||||
|
||||
{ lib }:
|
||||
rec {
|
||||
pc = {
|
||||
@ -482,6 +489,43 @@ rec {
|
||||
};
|
||||
};
|
||||
|
||||
# can execute on 32bit chip
|
||||
gcc_mips32r2_o32 = { gcc = { arch = "mips32r2"; abi = "o32"; }; };
|
||||
gcc_mips32r6_o32 = { gcc = { arch = "mips32r6"; abi = "o32"; }; };
|
||||
gcc_mips64r2_n32 = { gcc = { arch = "mips64r2"; abi = "n32"; }; };
|
||||
gcc_mips64r6_n32 = { gcc = { arch = "mips64r6"; abi = "n32"; }; };
|
||||
gcc_mips64r2_64 = { gcc = { arch = "mips64r2"; abi = "64"; }; };
|
||||
gcc_mips64r6_64 = { gcc = { arch = "mips64r6"; abi = "64"; }; };
|
||||
|
||||
# based on:
|
||||
# https://www.mail-archive.com/qemu-discuss@nongnu.org/msg05179.html
|
||||
# https://gmplib.org/~tege/qemu.html#mips64-debian
|
||||
mips64el-qemu-linux-gnuabi64 = (import ./examples).mips64el-linux-gnuabi64 // {
|
||||
linux-kernel = {
|
||||
name = "mips64el";
|
||||
baseConfig = "64r2el_defconfig";
|
||||
target = "vmlinuz";
|
||||
autoModules = false;
|
||||
DTB = true;
|
||||
# for qemu 9p passthrough filesystem
|
||||
extraConfig = ''
|
||||
MIPS_MALTA y
|
||||
PAGE_SIZE_4KB y
|
||||
CPU_LITTLE_ENDIAN y
|
||||
CPU_MIPS64_R2 y
|
||||
64BIT y
|
||||
CPU_MIPS64_R2 y
|
||||
|
||||
NET_9P y
|
||||
NET_9P_VIRTIO y
|
||||
9P_FS y
|
||||
9P_FS_POSIX_ACL y
|
||||
PCI y
|
||||
VIRTIO_PCI y
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
##
|
||||
## Other
|
||||
##
|
||||
@ -499,6 +543,9 @@ rec {
|
||||
};
|
||||
};
|
||||
|
||||
# This function takes a minimally-valid "platform" and returns an
|
||||
# attrset containing zero or more additional attrs which should be
|
||||
# included in the platform in order to further elaborate it.
|
||||
select = platform:
|
||||
# x86
|
||||
/**/ if platform.isx86 then pc
|
||||
|
@ -761,4 +761,156 @@ runTests {
|
||||
{ a = 3; b = 30; c = 300; }
|
||||
];
|
||||
};
|
||||
|
||||
# The example from the showAttrPath documentation
|
||||
testShowAttrPathExample = {
|
||||
expr = showAttrPath [ "foo" "10" "bar" ];
|
||||
expected = "foo.\"10\".bar";
|
||||
};
|
||||
|
||||
testShowAttrPathEmpty = {
|
||||
expr = showAttrPath [];
|
||||
expected = "<root attribute path>";
|
||||
};
|
||||
|
||||
testShowAttrPathVarious = {
|
||||
expr = showAttrPath [
|
||||
"."
|
||||
"foo"
|
||||
"2"
|
||||
"a2-b"
|
||||
"_bc'de"
|
||||
];
|
||||
expected = ''".".foo."2".a2-b._bc'de'';
|
||||
};
|
||||
|
||||
testGroupBy = {
|
||||
expr = groupBy (n: toString (mod n 5)) (range 0 16);
|
||||
expected = {
|
||||
"0" = [ 0 5 10 15 ];
|
||||
"1" = [ 1 6 11 16 ];
|
||||
"2" = [ 2 7 12 ];
|
||||
"3" = [ 3 8 13 ];
|
||||
"4" = [ 4 9 14 ];
|
||||
};
|
||||
};
|
||||
|
||||
testGroupBy' = {
|
||||
expr = groupBy' builtins.add 0 (x: boolToString (x > 2)) [ 5 1 2 3 4 ];
|
||||
expected = { false = 3; true = 12; };
|
||||
};
|
||||
|
||||
# The example from the updateManyAttrsByPath documentation
|
||||
testUpdateManyAttrsByPathExample = {
|
||||
expr = updateManyAttrsByPath [
|
||||
{
|
||||
path = [ "a" "b" ];
|
||||
update = old: { d = old.c; };
|
||||
}
|
||||
{
|
||||
path = [ "a" "b" "c" ];
|
||||
update = old: old + 1;
|
||||
}
|
||||
{
|
||||
path = [ "x" "y" ];
|
||||
update = old: "xy";
|
||||
}
|
||||
] { a.b.c = 0; };
|
||||
expected = { a = { b = { d = 1; }; }; x = { y = "xy"; }; };
|
||||
};
|
||||
|
||||
# If there are no updates, the value is passed through
|
||||
testUpdateManyAttrsByPathNone = {
|
||||
expr = updateManyAttrsByPath [] "something";
|
||||
expected = "something";
|
||||
};
|
||||
|
||||
# A single update to the root path is just like applying the function directly
|
||||
testUpdateManyAttrsByPathSingleIncrement = {
|
||||
expr = updateManyAttrsByPath [
|
||||
{
|
||||
path = [ ];
|
||||
update = old: old + 1;
|
||||
}
|
||||
] 0;
|
||||
expected = 1;
|
||||
};
|
||||
|
||||
# Multiple updates can be applied are done in order
|
||||
testUpdateManyAttrsByPathMultipleIncrements = {
|
||||
expr = updateManyAttrsByPath [
|
||||
{
|
||||
path = [ ];
|
||||
update = old: old + "a";
|
||||
}
|
||||
{
|
||||
path = [ ];
|
||||
update = old: old + "b";
|
||||
}
|
||||
{
|
||||
path = [ ];
|
||||
update = old: old + "c";
|
||||
}
|
||||
] "";
|
||||
expected = "abc";
|
||||
};
|
||||
|
||||
# If an update doesn't use the value, all previous updates are not evaluated
|
||||
testUpdateManyAttrsByPathLazy = {
|
||||
expr = updateManyAttrsByPath [
|
||||
{
|
||||
path = [ ];
|
||||
update = old: old + throw "nope";
|
||||
}
|
||||
{
|
||||
path = [ ];
|
||||
update = old: "untainted";
|
||||
}
|
||||
] (throw "start");
|
||||
expected = "untainted";
|
||||
};
|
||||
|
||||
# Deeply nested attributes can be updated without affecting others
|
||||
testUpdateManyAttrsByPathDeep = {
|
||||
expr = updateManyAttrsByPath [
|
||||
{
|
||||
path = [ "a" "b" "c" ];
|
||||
update = old: old + 1;
|
||||
}
|
||||
] {
|
||||
a.b.c = 0;
|
||||
|
||||
a.b.z = 0;
|
||||
a.y.z = 0;
|
||||
x.y.z = 0;
|
||||
};
|
||||
expected = {
|
||||
a.b.c = 1;
|
||||
|
||||
a.b.z = 0;
|
||||
a.y.z = 0;
|
||||
x.y.z = 0;
|
||||
};
|
||||
};
|
||||
|
||||
# Nested attributes are updated first
|
||||
testUpdateManyAttrsByPathNestedBeforehand = {
|
||||
expr = updateManyAttrsByPath [
|
||||
{
|
||||
path = [ "a" ];
|
||||
update = old: old // { x = old.b; };
|
||||
}
|
||||
{
|
||||
path = [ "a" "b" ];
|
||||
update = old: old + 1;
|
||||
}
|
||||
] {
|
||||
a.b = 0;
|
||||
};
|
||||
expected = {
|
||||
a.b = 1;
|
||||
a.x = 1;
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -62,6 +62,13 @@ checkConfigError() {
|
||||
checkConfigOutput '^false$' config.enable ./declare-enable.nix
|
||||
checkConfigError 'The option .* does not exist. Definition values:\n\s*- In .*: true' config.enable ./define-enable.nix
|
||||
|
||||
checkConfigOutput '^1$' config.bare-submodule.nested ./declare-bare-submodule.nix ./declare-bare-submodule-nested-option.nix
|
||||
checkConfigOutput '^2$' config.bare-submodule.deep ./declare-bare-submodule.nix ./declare-bare-submodule-deep-option.nix
|
||||
checkConfigOutput '^42$' config.bare-submodule.nested ./declare-bare-submodule.nix ./declare-bare-submodule-nested-option.nix ./declare-bare-submodule-deep-option.nix ./define-bare-submodule-values.nix
|
||||
checkConfigOutput '^420$' config.bare-submodule.deep ./declare-bare-submodule.nix ./declare-bare-submodule-nested-option.nix ./declare-bare-submodule-deep-option.nix ./define-bare-submodule-values.nix
|
||||
checkConfigOutput '^2$' config.bare-submodule.deep ./declare-bare-submodule.nix ./declare-bare-submodule-deep-option.nix ./define-shorthandOnlyDefinesConfig-true.nix
|
||||
checkConfigError 'The option .bare-submodule.deep. in .*/declare-bare-submodule-deep-option.nix. is already declared in .*/declare-bare-submodule-deep-option-duplicate.nix' config.bare-submodule.deep ./declare-bare-submodule.nix ./declare-bare-submodule-deep-option.nix ./declare-bare-submodule-deep-option-duplicate.nix
|
||||
|
||||
# Check integer types.
|
||||
# unsigned
|
||||
checkConfigOutput '^42$' config.value ./declare-int-unsigned-value.nix ./define-value-int-positive.nix
|
||||
@ -304,6 +311,12 @@ checkConfigOutput "10" config.processedToplevel ./raw.nix
|
||||
checkConfigError "The option .multiple. is defined multiple times" config.multiple ./raw.nix
|
||||
checkConfigOutput "bar" config.priorities ./raw.nix
|
||||
|
||||
## Option collision
|
||||
checkConfigError \
|
||||
'The option .set. in module .*/declare-set.nix. would be a parent of the following options, but its type .attribute set of signed integers. does not support nested options.\n\s*- option[(]s[)] with prefix .set.enable. in module .*/declare-enable-nested.nix.' \
|
||||
config.set \
|
||||
./declare-set.nix ./declare-enable-nested.nix
|
||||
|
||||
# Test that types.optionType merges types correctly
|
||||
checkConfigOutput '^10$' config.theOption.int ./optionTypeMerging.nix
|
||||
checkConfigOutput '^"hello"$' config.theOption.str ./optionTypeMerging.nix
|
||||
|
@ -0,0 +1,10 @@
|
||||
{ lib, ... }:
|
||||
let
|
||||
inherit (lib) mkOption types;
|
||||
in
|
||||
{
|
||||
options.bare-submodule.deep = mkOption {
|
||||
type = types.int;
|
||||
default = 2;
|
||||
};
|
||||
}
|
10
lib/tests/modules/declare-bare-submodule-deep-option.nix
Normal file
10
lib/tests/modules/declare-bare-submodule-deep-option.nix
Normal file
@ -0,0 +1,10 @@
|
||||
{ lib, ... }:
|
||||
let
|
||||
inherit (lib) mkOption types;
|
||||
in
|
||||
{
|
||||
options.bare-submodule.deep = mkOption {
|
||||
type = types.int;
|
||||
default = 2;
|
||||
};
|
||||
}
|
19
lib/tests/modules/declare-bare-submodule-nested-option.nix
Normal file
19
lib/tests/modules/declare-bare-submodule-nested-option.nix
Normal file
@ -0,0 +1,19 @@
|
||||
{ config, lib, ... }:
|
||||
let
|
||||
inherit (lib) mkOption types;
|
||||
in
|
||||
{
|
||||
options.bare-submodule = mkOption {
|
||||
type = types.submoduleWith {
|
||||
shorthandOnlyDefinesConfig = config.shorthandOnlyDefinesConfig;
|
||||
modules = [
|
||||
{
|
||||
options.nested = mkOption {
|
||||
type = types.int;
|
||||
default = 1;
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
18
lib/tests/modules/declare-bare-submodule.nix
Normal file
18
lib/tests/modules/declare-bare-submodule.nix
Normal file
@ -0,0 +1,18 @@
|
||||
{ config, lib, ... }:
|
||||
let
|
||||
inherit (lib) mkOption types;
|
||||
in
|
||||
{
|
||||
options.bare-submodule = mkOption {
|
||||
type = types.submoduleWith {
|
||||
modules = [ ];
|
||||
shorthandOnlyDefinesConfig = config.shorthandOnlyDefinesConfig;
|
||||
};
|
||||
default = {};
|
||||
};
|
||||
|
||||
# config-dependent options: won't recommend, but useful for making this test parameterized
|
||||
options.shorthandOnlyDefinesConfig = mkOption {
|
||||
default = false;
|
||||
};
|
||||
}
|
12
lib/tests/modules/declare-set.nix
Normal file
12
lib/tests/modules/declare-set.nix
Normal file
@ -0,0 +1,12 @@
|
||||
{ lib, ... }:
|
||||
|
||||
{
|
||||
options.set = lib.mkOption {
|
||||
default = { };
|
||||
example = { a = 1; };
|
||||
type = lib.types.attrsOf lib.types.int;
|
||||
description = ''
|
||||
Some descriptive text
|
||||
'';
|
||||
};
|
||||
}
|
4
lib/tests/modules/define-bare-submodule-values.nix
Normal file
4
lib/tests/modules/define-bare-submodule-values.nix
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
bare-submodule.nested = 42;
|
||||
bare-submodule.deep = 420;
|
||||
}
|
@ -0,0 +1 @@
|
||||
{ shorthandOnlyDefinesConfig = true; }
|
@ -17,7 +17,7 @@ with lib.systems.doubles; lib.runTests {
|
||||
|
||||
testarm = mseteq arm [ "armv5tel-linux" "armv6l-linux" "armv6l-netbsd" "armv6l-none" "armv7a-linux" "armv7a-netbsd" "armv7l-linux" "armv7l-netbsd" "arm-none" "armv7a-darwin" ];
|
||||
testi686 = mseteq i686 [ "i686-linux" "i686-freebsd" "i686-genode" "i686-netbsd" "i686-openbsd" "i686-cygwin" "i686-windows" "i686-none" "i686-darwin" ];
|
||||
testmips = mseteq mips [ "mipsel-linux" "mipsel-netbsd" ];
|
||||
testmips = mseteq mips [ "mips64el-linux" "mipsel-linux" "mipsel-netbsd" ];
|
||||
testmmix = mseteq mmix [ "mmix-mmixware" ];
|
||||
testx86_64 = mseteq x86_64 [ "x86_64-linux" "x86_64-darwin" "x86_64-freebsd" "x86_64-genode" "x86_64-redox" "x86_64-openbsd" "x86_64-netbsd" "x86_64-cygwin" "x86_64-solaris" "x86_64-windows" "x86_64-none" ];
|
||||
|
||||
@ -28,7 +28,7 @@ with lib.systems.doubles; lib.runTests {
|
||||
testredox = mseteq redox [ "x86_64-redox" ];
|
||||
testgnu = mseteq gnu (linux /* ++ kfreebsd ++ ... */);
|
||||
testillumos = mseteq illumos [ "x86_64-solaris" ];
|
||||
testlinux = mseteq linux [ "aarch64-linux" "armv5tel-linux" "armv6l-linux" "armv7a-linux" "armv7l-linux" "i686-linux" "mipsel-linux" "riscv32-linux" "riscv64-linux" "x86_64-linux" "powerpc64-linux" "powerpc64le-linux" "m68k-linux" "s390-linux" "s390x-linux" ];
|
||||
testlinux = mseteq linux [ "aarch64-linux" "armv5tel-linux" "armv6l-linux" "armv7a-linux" "armv7l-linux" "i686-linux" "mips64el-linux" "mipsel-linux" "riscv32-linux" "riscv64-linux" "x86_64-linux" "powerpc64-linux" "powerpc64le-linux" "m68k-linux" "s390-linux" "s390x-linux" ];
|
||||
testnetbsd = mseteq netbsd [ "aarch64-netbsd" "armv6l-netbsd" "armv7a-netbsd" "armv7l-netbsd" "i686-netbsd" "m68k-netbsd" "mipsel-netbsd" "powerpc-netbsd" "riscv32-netbsd" "riscv64-netbsd" "x86_64-netbsd" ];
|
||||
testopenbsd = mseteq openbsd [ "i686-openbsd" "x86_64-openbsd" ];
|
||||
testwindows = mseteq windows [ "i686-cygwin" "x86_64-cygwin" "i686-windows" "x86_64-windows" ];
|
||||
|
@ -166,6 +166,30 @@ rec {
|
||||
/* Returns the current nixpkgs release number as string. */
|
||||
release = lib.strings.fileContents ../.version;
|
||||
|
||||
/* The latest release that is supported, at the time of release branch-off,
|
||||
if applicable.
|
||||
|
||||
Ideally, out-of-tree modules should be able to evaluate cleanly with all
|
||||
supported Nixpkgs versions (master, release and old release until EOL).
|
||||
So if possible, deprecation warnings should take effect only when all
|
||||
out-of-tree expressions/libs/modules can upgrade to the new way without
|
||||
losing support for supported Nixpkgs versions.
|
||||
|
||||
This release number allows deprecation warnings to be implemented such that
|
||||
they take effect as soon as the oldest release reaches end of life. */
|
||||
oldestSupportedRelease =
|
||||
# Update on master only. Do not backport.
|
||||
2111;
|
||||
|
||||
/* Whether a feature is supported in all supported releases (at the time of
|
||||
release branch-off, if applicable). See `oldestSupportedRelease`. */
|
||||
isInOldestRelease =
|
||||
/* Release number of feature introduction as an integer, e.g. 2111 for 21.11.
|
||||
Set it to the upcoming release, matching the nixpkgs/.version file.
|
||||
*/
|
||||
release:
|
||||
release <= lib.trivial.oldestSupportedRelease;
|
||||
|
||||
/* Returns the current nixpkgs release code name.
|
||||
|
||||
On each release the first letter is bumped and a new animal is chosen
|
||||
|
@ -572,14 +572,18 @@ rec {
|
||||
let
|
||||
inherit (lib.modules) evalModules;
|
||||
|
||||
coerce = unify: value: if isFunction value
|
||||
then setFunctionArgs (args: unify (value args)) (functionArgs value)
|
||||
else unify (if shorthandOnlyDefinesConfig then { config = value; } else value);
|
||||
shorthandToModule = if shorthandOnlyDefinesConfig == false
|
||||
then value: value
|
||||
else value: { config = value; };
|
||||
|
||||
allModules = defs: imap1 (n: { value, file }:
|
||||
if isAttrs value || isFunction value then
|
||||
# Annotate the value with the location of its definition for better error messages
|
||||
coerce (lib.modules.unifyModuleSyntax file "${toString file}-${toString n}") value
|
||||
if isFunction value
|
||||
then setFunctionArgs
|
||||
(args: lib.modules.unifyModuleSyntax file "${toString file}-${toString n}" (value args))
|
||||
(functionArgs value)
|
||||
else if isAttrs value
|
||||
then
|
||||
lib.modules.unifyModuleSyntax file "${toString file}-${toString n}" (shorthandToModule value)
|
||||
else value
|
||||
) defs;
|
||||
|
||||
@ -647,7 +651,11 @@ rec {
|
||||
then lhs.specialArgs // rhs.specialArgs
|
||||
else throw "A submoduleWith option is declared multiple times with the same specialArgs \"${toString (attrNames intersecting)}\"";
|
||||
shorthandOnlyDefinesConfig =
|
||||
if lhs.shorthandOnlyDefinesConfig == rhs.shorthandOnlyDefinesConfig
|
||||
if lhs.shorthandOnlyDefinesConfig == null
|
||||
then rhs.shorthandOnlyDefinesConfig
|
||||
else if rhs.shorthandOnlyDefinesConfig == null
|
||||
then lhs.shorthandOnlyDefinesConfig
|
||||
else if lhs.shorthandOnlyDefinesConfig == rhs.shorthandOnlyDefinesConfig
|
||||
then lhs.shorthandOnlyDefinesConfig
|
||||
else throw "A submoduleWith option is declared multiple times with conflicting shorthandOnlyDefinesConfig values";
|
||||
};
|
||||
|
@ -1901,6 +1901,12 @@
|
||||
githubId = 82591;
|
||||
name = "Carl Sverre";
|
||||
};
|
||||
carpinchomug = {
|
||||
email = "aki.suda@protonmail.com";
|
||||
github = "carpinchomug";
|
||||
githubId = 101536256;
|
||||
name = "Akiyoshi Suda";
|
||||
};
|
||||
cartr = {
|
||||
email = "carter.sande@duodecima.technology";
|
||||
github = "cartr";
|
||||
@ -8716,6 +8722,12 @@
|
||||
fingerprint = "4BFF 0614 03A2 47F0 AA0B 4BC4 916D 8B67 2418 92AE";
|
||||
}];
|
||||
};
|
||||
nbr = {
|
||||
email = "nbr@users.noreply.github.com";
|
||||
github = "nbr";
|
||||
githubId = 3819225;
|
||||
name = "Nick Braga";
|
||||
};
|
||||
nbren12 = {
|
||||
email = "nbren12@gmail.com";
|
||||
github = "nbren12";
|
||||
@ -10380,6 +10392,12 @@
|
||||
githubId = 22803888;
|
||||
name = "Lu Hongxu";
|
||||
};
|
||||
rgnns = {
|
||||
email = "jglievano@gmail.com";
|
||||
github = "rgnns";
|
||||
githubId = 811827;
|
||||
name = "Gabriel Lievano";
|
||||
};
|
||||
rgrunbla = {
|
||||
email = "remy@grunblatt.org";
|
||||
github = "rgrunbla";
|
||||
|
@ -27,9 +27,10 @@ The function `mkOption` accepts the following arguments.
|
||||
|
||||
`type`
|
||||
|
||||
: The type of the option (see [](#sec-option-types)). It may be
|
||||
omitted, but that's not advisable since it may lead to errors that
|
||||
are hard to diagnose.
|
||||
: The type of the option (see [](#sec-option-types)). This
|
||||
argument is mandatory for nixpkgs modules. Setting this is highly
|
||||
recommended for the sake of documentation and type checking. In case it is
|
||||
not set, a fallback type with unspecified behavior is used.
|
||||
|
||||
`default`
|
||||
|
||||
|
@ -38,9 +38,11 @@ options = {
|
||||
<listitem>
|
||||
<para>
|
||||
The type of the option (see
|
||||
<xref linkend="sec-option-types" />). It may be omitted, but
|
||||
that’s not advisable since it may lead to errors that are hard
|
||||
to diagnose.
|
||||
<xref linkend="sec-option-types" />). This argument is
|
||||
mandatory for nixpkgs modules. Setting this is highly
|
||||
recommended for the sake of documentation and type checking.
|
||||
In case it is not set, a fallback type with unspecified
|
||||
behavior is used.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
@ -62,6 +62,14 @@
|
||||
notes</link> for details.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Module authors can use
|
||||
<literal>mkRenamedOptionModuleWith</literal> to automate the
|
||||
deprecation cycle without annoying out-of-tree module authors
|
||||
and their users.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
<section xml:id="sec-release-22.05-new-services">
|
||||
@ -274,6 +282,13 @@
|
||||
<link xlink:href="options.html#opt-services.nbd.server.enable">services.nbd</link>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<link xlink:href="https://github.com/Mic92/nix-ld">nix-ld</link>,
|
||||
Run unpatched dynamic binaries on NixOS. Available as
|
||||
<link xlink:href="options.html#opt-programs.nix-ld.enable">programs.nix-ld</link>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<link xlink:href="https://timetagger.app">timetagger</link>,
|
||||
@ -467,6 +482,12 @@
|
||||
still supported, because you can set arbitrary values in this
|
||||
freeform type.
|
||||
</para>
|
||||
<para>
|
||||
The <literal>listeners.*.bind_address</literal> option was
|
||||
renamed to <literal>bind_addresses</literal> in order to match
|
||||
the upstream <literal>homeserver.yaml</literal> option name.
|
||||
It is now also a list of strings instead of a string.
|
||||
</para>
|
||||
<para>
|
||||
An example to make the required migration clearer:
|
||||
</para>
|
||||
@ -528,7 +549,7 @@
|
||||
|
||||
listeners = [ {
|
||||
port = 8448;
|
||||
bind_address = [
|
||||
bind_addresses = [
|
||||
"::"
|
||||
"0.0.0.0"
|
||||
];
|
||||
@ -559,7 +580,14 @@
|
||||
Additionally a few option defaults have been synced up with
|
||||
upstream default values, for example the
|
||||
<literal>max_upload_size</literal> grew from
|
||||
<literal>10M</literal> to <literal>50M</literal>.
|
||||
<literal>10M</literal> to <literal>50M</literal>. For the same
|
||||
reason, the default <literal>media_store_path</literal> was
|
||||
changed from <literal>${dataDir}/media</literal> to
|
||||
<literal>${dataDir}/media_store</literal> if
|
||||
<literal>system.stateVersion</literal> is at least
|
||||
<literal>22.05</literal>. Files will need to be manually moved
|
||||
to the new location if the <literal>stateVersion</literal> is
|
||||
updated.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
@ -760,6 +788,12 @@
|
||||
unmaintained
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>pkgs._7zz</literal> is now correctly licensed as
|
||||
LGPL3+ and BSD3 with optional unfree unRAR licensed code
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>tilp2</literal> was removed together with its module
|
||||
@ -817,6 +851,16 @@
|
||||
<literal>systemd.nspawn.<name>.execConfig.PrivateUsers = false</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The Tor SOCKS proxy is now actually disabled if
|
||||
<literal>services.tor.client.enable</literal> is set to
|
||||
<literal>false</literal> (the default). If you are using this
|
||||
functionality but didn’t change the setting or set it to
|
||||
<literal>false</literal>, you now need to set it to
|
||||
<literal>true</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The terraform 0.12 compatibility has been removed and the
|
||||
@ -1171,7 +1215,8 @@
|
||||
Legacy options have been mapped to the corresponding
|
||||
options under under
|
||||
<link xlink:href="options.html#opt-nix.settings">nix.settings</link>
|
||||
but may be deprecated in the future.
|
||||
and will be deprecated when NixOS 21.11 reaches end of
|
||||
life.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
@ -1242,6 +1287,14 @@
|
||||
compatibilty, but will be removed at a later date.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The <literal>unifi</literal> package was switched from
|
||||
<literal>unifi6</literal> to <literal>unifi7</literal>. Direct
|
||||
downgrades from Unifi 7 to Unifi 6 are not possible and
|
||||
require restoring from a backup made by Unifi 6.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>programs.zsh.autosuggestions.strategy</literal> now
|
||||
@ -1319,10 +1372,10 @@
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
A new option
|
||||
<literal>boot.initrd.extraModprobeConfig</literal> has been
|
||||
added which can be used to configure kernel modules that are
|
||||
loaded in the initrd.
|
||||
The options <literal>boot.extraModprobeConfig</literal> and
|
||||
<literal>boot.blacklistedKernelModules</literal> now also take
|
||||
effect in the initrd by copying the file
|
||||
<literal>/etc/modprobe.d/nixos.conf</literal> into the initrd.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
@ -1332,6 +1385,52 @@
|
||||
instead of <literal>configuration.nix</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
ORY Kratos was updated to version 0.8.3-alpha.1.pre.0, which
|
||||
introduces some breaking changes:
|
||||
</para>
|
||||
<itemizedlist spacing="compact">
|
||||
<listitem>
|
||||
<para>
|
||||
If you are relying on the SQLite images, update your
|
||||
Docker Pull commands as follows:
|
||||
</para>
|
||||
<itemizedlist spacing="compact">
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>docker pull oryd/kratos:{version}</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Additionally, all passwords now have to be at least 8
|
||||
characters long.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
For more details, see:
|
||||
</para>
|
||||
<itemizedlist spacing="compact">
|
||||
<listitem>
|
||||
<para>
|
||||
<link xlink:href="https://github.com/ory/kratos/releases/tag/v0.8.1-alpha.1">Release
|
||||
Notes for v0.8.1-alpha-1</link>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<link xlink:href="https://github.com/ory/kratos/releases/tag/v0.8.2-alpha.1">Release
|
||||
Notes for v0.8.2-alpha-1</link>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>fetchFromSourcehut</literal> now allows fetching
|
||||
|
@ -21,6 +21,8 @@ In addition to numerous new and upgraded packages, this release has the followin
|
||||
|
||||
- [`kops`](https://kops.sigs.k8s.io) defaults to 1.22.4, which will enable [Instance Metadata Service Version 2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html) and require tokens on new clusters with Kubernetes 1.22. This will increase security by default, but may break some types of workloads. See the [release notes](https://kops.sigs.k8s.io/releases/1.22-notes/) for details.
|
||||
|
||||
- Module authors can use `mkRenamedOptionModuleWith` to automate the deprecation cycle without annoying out-of-tree module authors and their users.
|
||||
|
||||
## 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).
|
||||
@ -79,6 +81,8 @@ In addition to numerous new and upgraded packages, this release has the followin
|
||||
|
||||
- [nbd](https://nbd.sourceforge.io/), a Network Block Device server. Available as [services.nbd](options.html#opt-services.nbd.server.enable).
|
||||
|
||||
- [nix-ld](https://github.com/Mic92/nix-ld), Run unpatched dynamic binaries on NixOS. Available as [programs.nix-ld](options.html#opt-programs.nix-ld.enable).
|
||||
|
||||
- [timetagger](https://timetagger.app), an open source time-tracker with an intuitive user experience and powerful reporting. [services.timetagger](options.html#opt-services.timetagger.enable).
|
||||
|
||||
- [rstudio-server](https://www.rstudio.com/products/rstudio/#rstudio-server), a browser-based version of the RStudio IDE for the R programming language. Available as [services.rstudio-server](options.html#opt-services.rstudio-server.enable).
|
||||
@ -158,6 +162,9 @@ In addition to numerous new and upgraded packages, this release has the followin
|
||||
module (`services.matrix-synapse`) now need to be moved into `services.matrix-synapse.settings`. And while not all options you
|
||||
may use are defined in there, they are still supported, because you can set arbitrary values in this freeform type.
|
||||
|
||||
The `listeners.*.bind_address` option was renamed to `bind_addresses` in order to match the upstream `homeserver.yaml` option
|
||||
name. It is now also a list of strings instead of a string.
|
||||
|
||||
An example to make the required migration clearer:
|
||||
|
||||
Before:
|
||||
@ -215,7 +222,7 @@ In addition to numerous new and upgraded packages, this release has the followin
|
||||
|
||||
listeners = [ {
|
||||
port = 8448;
|
||||
bind_address = [
|
||||
bind_addresses = [
|
||||
"::"
|
||||
"0.0.0.0"
|
||||
];
|
||||
@ -240,7 +247,9 @@ In addition to numerous new and upgraded packages, this release has the followin
|
||||
|
||||
The secrets in your original config should be migrated into a YAML file that is included via `extraConfigFiles`.
|
||||
|
||||
Additionally a few option defaults have been synced up with upstream default values, for example the `max_upload_size` grew from `10M` to `50M`.
|
||||
Additionally a few option defaults have been synced up with upstream default values, for example the `max_upload_size` grew from `10M` to `50M`. For the same reason, the default
|
||||
`media_store_path` was changed from `${dataDir}/media` to `${dataDir}/media_store` if `system.stateVersion` is at least `22.05`. Files will need to be manually moved to the new
|
||||
location if the `stateVersion` is updated.
|
||||
|
||||
- The MoinMoin wiki engine (`services.moinmoin`) has been removed, because Python 2 is being retired from nixpkgs.
|
||||
|
||||
@ -304,6 +313,8 @@ In addition to numerous new and upgraded packages, this release has the followin
|
||||
|
||||
- `pkgs.docbookrx` was removed since it's unmaintained
|
||||
|
||||
- `pkgs._7zz` is now correctly licensed as LGPL3+ and BSD3 with optional unfree unRAR licensed code
|
||||
|
||||
- `tilp2` was removed together with its module
|
||||
|
||||
- The F-PROT antivirus (`fprot` package) and its service module were removed because it
|
||||
@ -317,6 +328,8 @@ In addition to numerous new and upgraded packages, this release has the followin
|
||||
|
||||
- `systemd-nspawn@.service` settings have been reverted to the default systemd behaviour. User namespaces are now activated by default. If you want to keep running nspawn containers without user namespaces you need to set `systemd.nspawn.<name>.execConfig.PrivateUsers = false`
|
||||
|
||||
- The Tor SOCKS proxy is now actually disabled if `services.tor.client.enable` is set to `false` (the default). If you are using this functionality but didn't change the setting or set it to `false`, you now need to set it to `true`.
|
||||
|
||||
- The terraform 0.12 compatibility has been removed and the `terraform.withPlugins` and `terraform-providers.mkProvider` implementations simplified. Providers now need to be stored under
|
||||
`$out/libexec/terraform-providers/<registry>/<owner>/<name>/<version>/<os>_<arch>/terraform-provider-<name>_v<version>` (which mkProvider does).
|
||||
|
||||
@ -439,7 +452,7 @@ In addition to numerous new and upgraded packages, this release has the followin
|
||||
Similarly [virtualisation.vmVariantWithBootloader](#opt-virtualisation.vmVariantWithBootLoader) was added.
|
||||
|
||||
- The configuration portion of the `nix-daemon` module has been reworked and exposed as [nix.settings](options.html#opt-nix-settings):
|
||||
* Legacy options have been mapped to the corresponding options under under [nix.settings](options.html#opt-nix.settings) but may be deprecated in the future.
|
||||
* Legacy options have been mapped to the corresponding options under under [nix.settings](options.html#opt-nix.settings) and will be deprecated when NixOS 21.11 reaches end of life.
|
||||
* [nix.buildMachines.publicHostKey](options.html#opt-nix.buildMachines.publicHostKey) has been added.
|
||||
|
||||
- The `writers.writePyPy2`/`writers.writePyPy3` and corresponding `writers.writePyPy2Bin`/`writers.writePyPy3Bin` convenience functions to create executable Python 2/3 scripts using the PyPy interpreter were added.
|
||||
@ -462,6 +475,9 @@ In addition to numerous new and upgraded packages, this release has the followin
|
||||
combined `influxdb2` package is still provided in this release for
|
||||
backwards compatibilty, but will be removed at a later date.
|
||||
|
||||
- The `unifi` package was switched from `unifi6` to `unifi7`.
|
||||
Direct downgrades from Unifi 7 to Unifi 6 are not possible and require restoring from a backup made by Unifi 6.
|
||||
|
||||
- `programs.zsh.autosuggestions.strategy` now takes a list of strings instead of a string.
|
||||
|
||||
- The `services.unifi.openPorts` option default value of `true` is now deprecated and will be changed to `false` in 22.11.
|
||||
@ -491,10 +507,18 @@ In addition to numerous new and upgraded packages, this release has the followin
|
||||
|
||||
- The option `services.duplicati.dataDir` has been added to allow changing the location of duplicati's files.
|
||||
|
||||
- A new option `boot.initrd.extraModprobeConfig` has been added which can be used to configure kernel modules that are loaded in the initrd.
|
||||
- The options `boot.extraModprobeConfig` and `boot.blacklistedKernelModules` now also take effect in the initrd by copying the file `/etc/modprobe.d/nixos.conf` into the initrd.
|
||||
|
||||
- `nixos-generate-config` now puts the dhcp configuration in `hardware-configuration.nix` instead of `configuration.nix`.
|
||||
|
||||
- ORY Kratos was updated to version 0.8.3-alpha.1.pre.0, which introduces some breaking changes:
|
||||
- If you are relying on the SQLite images, update your Docker Pull commands as follows:
|
||||
- `docker pull oryd/kratos:{version}`
|
||||
- Additionally, all passwords now have to be at least 8 characters long.
|
||||
- For more details, see:
|
||||
- [Release Notes for v0.8.1-alpha-1](https://github.com/ory/kratos/releases/tag/v0.8.1-alpha.1)
|
||||
- [Release Notes for v0.8.2-alpha-1](https://github.com/ory/kratos/releases/tag/v0.8.2-alpha.1)
|
||||
|
||||
- `fetchFromSourcehut` now allows fetching repositories recursively
|
||||
using `fetchgit` or `fetchhg` if the argument `fetchSubmodules`
|
||||
is set to `true`.
|
||||
|
@ -66,14 +66,21 @@ for (k, v) in overrides.items():
|
||||
elif ov is not None or cur.get(ok, None) is None:
|
||||
cur[ok] = ov
|
||||
|
||||
severity = "error" if warningsAreErrors else "warning"
|
||||
|
||||
# check that every option has a description
|
||||
hasWarnings = False
|
||||
for (k, v) in options.items():
|
||||
if v.value.get('description', None) is None:
|
||||
severity = "error" if warningsAreErrors else "warning"
|
||||
hasWarnings = True
|
||||
print(f"\x1b[1;31m{severity}: option {v.name} has no description\x1b[0m", file=sys.stderr)
|
||||
v.value['description'] = "This option has no description."
|
||||
if v.value.get('type', "unspecified") == "unspecified":
|
||||
hasWarnings = True
|
||||
print(
|
||||
f"\x1b[1;31m{severity}: option {v.name} has no type. Please specify a valid type, see " +
|
||||
"https://nixos.org/manual/nixos/stable/index.html#sec-option-types\x1b[0m", file=sys.stderr)
|
||||
|
||||
if hasWarnings and warningsAreErrors:
|
||||
print(
|
||||
"\x1b[1;31m" +
|
||||
|
@ -5,6 +5,7 @@ with lib;
|
||||
let
|
||||
cfg = config.systemd;
|
||||
lndir = "${pkgs.buildPackages.xorg.lndir}/bin/lndir";
|
||||
systemd = cfg.package;
|
||||
in rec {
|
||||
|
||||
shellEscape = s: (replaceChars [ "\\" ] [ "\\\\" ] s);
|
||||
@ -235,4 +236,205 @@ in rec {
|
||||
''}
|
||||
''; # */
|
||||
|
||||
makeJobScript = name: text:
|
||||
let
|
||||
scriptName = replaceChars [ "\\" "@" ] [ "-" "_" ] (shellEscape name);
|
||||
out = (pkgs.writeShellScriptBin scriptName ''
|
||||
set -e
|
||||
${text}
|
||||
'').overrideAttrs (_: {
|
||||
# The derivation name is different from the script file name
|
||||
# to keep the script file name short to avoid cluttering logs.
|
||||
name = "unit-script-${scriptName}";
|
||||
});
|
||||
in "${out}/bin/${scriptName}";
|
||||
|
||||
unitConfig = { config, options, ... }: {
|
||||
config = {
|
||||
unitConfig =
|
||||
optionalAttrs (config.requires != [])
|
||||
{ Requires = toString config.requires; }
|
||||
// optionalAttrs (config.wants != [])
|
||||
{ Wants = toString config.wants; }
|
||||
// optionalAttrs (config.after != [])
|
||||
{ After = toString config.after; }
|
||||
// optionalAttrs (config.before != [])
|
||||
{ Before = toString config.before; }
|
||||
// optionalAttrs (config.bindsTo != [])
|
||||
{ BindsTo = toString config.bindsTo; }
|
||||
// optionalAttrs (config.partOf != [])
|
||||
{ PartOf = toString config.partOf; }
|
||||
// optionalAttrs (config.conflicts != [])
|
||||
{ Conflicts = toString config.conflicts; }
|
||||
// optionalAttrs (config.requisite != [])
|
||||
{ Requisite = toString config.requisite; }
|
||||
// optionalAttrs (config.restartTriggers != [])
|
||||
{ X-Restart-Triggers = toString config.restartTriggers; }
|
||||
// optionalAttrs (config.reloadTriggers != [])
|
||||
{ X-Reload-Triggers = toString config.reloadTriggers; }
|
||||
// optionalAttrs (config.description != "") {
|
||||
Description = config.description; }
|
||||
// optionalAttrs (config.documentation != []) {
|
||||
Documentation = toString config.documentation; }
|
||||
// optionalAttrs (config.onFailure != []) {
|
||||
OnFailure = toString config.onFailure; }
|
||||
// optionalAttrs (options.startLimitIntervalSec.isDefined) {
|
||||
StartLimitIntervalSec = toString config.startLimitIntervalSec;
|
||||
} // optionalAttrs (options.startLimitBurst.isDefined) {
|
||||
StartLimitBurst = toString config.startLimitBurst;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
serviceConfig = { name, config, ... }: {
|
||||
config = mkMerge
|
||||
[ { # Default path for systemd services. Should be quite minimal.
|
||||
path = mkAfter
|
||||
[ pkgs.coreutils
|
||||
pkgs.findutils
|
||||
pkgs.gnugrep
|
||||
pkgs.gnused
|
||||
systemd
|
||||
];
|
||||
environment.PATH = "${makeBinPath config.path}:${makeSearchPathOutput "bin" "sbin" config.path}";
|
||||
}
|
||||
(mkIf (config.preStart != "")
|
||||
{ serviceConfig.ExecStartPre =
|
||||
[ (makeJobScript "${name}-pre-start" config.preStart) ];
|
||||
})
|
||||
(mkIf (config.script != "")
|
||||
{ serviceConfig.ExecStart =
|
||||
makeJobScript "${name}-start" config.script + " " + config.scriptArgs;
|
||||
})
|
||||
(mkIf (config.postStart != "")
|
||||
{ serviceConfig.ExecStartPost =
|
||||
[ (makeJobScript "${name}-post-start" config.postStart) ];
|
||||
})
|
||||
(mkIf (config.reload != "")
|
||||
{ serviceConfig.ExecReload =
|
||||
makeJobScript "${name}-reload" config.reload;
|
||||
})
|
||||
(mkIf (config.preStop != "")
|
||||
{ serviceConfig.ExecStop =
|
||||
makeJobScript "${name}-pre-stop" config.preStop;
|
||||
})
|
||||
(mkIf (config.postStop != "")
|
||||
{ serviceConfig.ExecStopPost =
|
||||
makeJobScript "${name}-post-stop" config.postStop;
|
||||
})
|
||||
];
|
||||
};
|
||||
|
||||
mountConfig = { config, ... }: {
|
||||
config = {
|
||||
mountConfig =
|
||||
{ What = config.what;
|
||||
Where = config.where;
|
||||
} // optionalAttrs (config.type != "") {
|
||||
Type = config.type;
|
||||
} // optionalAttrs (config.options != "") {
|
||||
Options = config.options;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
automountConfig = { config, ... }: {
|
||||
config = {
|
||||
automountConfig =
|
||||
{ Where = config.where;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
commonUnitText = def: ''
|
||||
[Unit]
|
||||
${attrsToSection def.unitConfig}
|
||||
'';
|
||||
|
||||
targetToUnit = name: def:
|
||||
{ inherit (def) aliases wantedBy requiredBy enable;
|
||||
text =
|
||||
''
|
||||
[Unit]
|
||||
${attrsToSection def.unitConfig}
|
||||
'';
|
||||
};
|
||||
|
||||
serviceToUnit = name: def:
|
||||
{ inherit (def) aliases wantedBy requiredBy enable;
|
||||
text = commonUnitText def +
|
||||
''
|
||||
[Service]
|
||||
${let env = cfg.globalEnvironment // def.environment;
|
||||
in concatMapStrings (n:
|
||||
let s = optionalString (env.${n} != null)
|
||||
"Environment=${builtins.toJSON "${n}=${env.${n}}"}\n";
|
||||
# systemd max line length is now 1MiB
|
||||
# https://github.com/systemd/systemd/commit/e6dde451a51dc5aaa7f4d98d39b8fe735f73d2af
|
||||
in if stringLength s >= 1048576 then throw "The value of the environment variable ‘${n}’ in systemd service ‘${name}.service’ is too long." else s) (attrNames env)}
|
||||
${if def.reloadIfChanged then ''
|
||||
X-ReloadIfChanged=true
|
||||
'' else if !def.restartIfChanged then ''
|
||||
X-RestartIfChanged=false
|
||||
'' else ""}
|
||||
${optionalString (!def.stopIfChanged) "X-StopIfChanged=false"}
|
||||
${attrsToSection def.serviceConfig}
|
||||
'';
|
||||
};
|
||||
|
||||
socketToUnit = name: def:
|
||||
{ inherit (def) aliases wantedBy requiredBy enable;
|
||||
text = commonUnitText def +
|
||||
''
|
||||
[Socket]
|
||||
${attrsToSection def.socketConfig}
|
||||
${concatStringsSep "\n" (map (s: "ListenStream=${s}") def.listenStreams)}
|
||||
${concatStringsSep "\n" (map (s: "ListenDatagram=${s}") def.listenDatagrams)}
|
||||
'';
|
||||
};
|
||||
|
||||
timerToUnit = name: def:
|
||||
{ inherit (def) aliases wantedBy requiredBy enable;
|
||||
text = commonUnitText def +
|
||||
''
|
||||
[Timer]
|
||||
${attrsToSection def.timerConfig}
|
||||
'';
|
||||
};
|
||||
|
||||
pathToUnit = name: def:
|
||||
{ inherit (def) aliases wantedBy requiredBy enable;
|
||||
text = commonUnitText def +
|
||||
''
|
||||
[Path]
|
||||
${attrsToSection def.pathConfig}
|
||||
'';
|
||||
};
|
||||
|
||||
mountToUnit = name: def:
|
||||
{ inherit (def) aliases wantedBy requiredBy enable;
|
||||
text = commonUnitText def +
|
||||
''
|
||||
[Mount]
|
||||
${attrsToSection def.mountConfig}
|
||||
'';
|
||||
};
|
||||
|
||||
automountToUnit = name: def:
|
||||
{ inherit (def) aliases wantedBy requiredBy enable;
|
||||
text = commonUnitText def +
|
||||
''
|
||||
[Automount]
|
||||
${attrsToSection def.automountConfig}
|
||||
'';
|
||||
};
|
||||
|
||||
sliceToUnit = name: def:
|
||||
{ inherit (def) aliases wantedBy requiredBy enable;
|
||||
text = commonUnitText def +
|
||||
''
|
||||
[Slice]
|
||||
${attrsToSection def.sliceConfig}
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
@ -244,7 +244,7 @@ in
|
||||
modules = optional (igpuDriver == "amdgpu") [ pkgs.xorg.xf86videoamdgpu ];
|
||||
deviceSection = ''
|
||||
BusID "${igpuBusId}"
|
||||
${optionalString syncCfg.enable ''Option "AccelMethod" "none"''}
|
||||
${optionalString (syncCfg.enable && igpuDriver != "amdgpu") ''Option "AccelMethod" "none"''}
|
||||
'';
|
||||
} ++ singleton {
|
||||
name = "nvidia";
|
||||
@ -269,9 +269,15 @@ in
|
||||
Option "AllowNVIDIAGPUScreens"
|
||||
'';
|
||||
|
||||
services.xserver.displayManager.setupCommands = optionalString syncCfg.enable ''
|
||||
services.xserver.displayManager.setupCommands = let
|
||||
sinkGpuProviderName = if igpuDriver == "amdgpu" then
|
||||
# find the name of the provider if amdgpu
|
||||
"`${pkgs.xorg.xrandr}/bin/xrandr --listproviders | ${pkgs.gnugrep}/bin/grep -i AMD | ${pkgs.gnused}/bin/sed -n 's/^.*name://p'`"
|
||||
else
|
||||
igpuDriver;
|
||||
in optionalString syncCfg.enable ''
|
||||
# Added by nvidia configuration module for Optimus/PRIME.
|
||||
${pkgs.xorg.xrandr}/bin/xrandr --setprovideroutputsource ${igpuDriver} NVIDIA-0
|
||||
${pkgs.xorg.xrandr}/bin/xrandr --setprovideroutputsource "${sinkGpuProviderName}" NVIDIA-0
|
||||
${pkgs.xorg.xrandr}/bin/xrandr --auto
|
||||
'';
|
||||
|
||||
@ -283,14 +289,14 @@ in
|
||||
environment.etc."egl/egl_external_platform.d".source =
|
||||
"/run/opengl-driver/share/egl/egl_external_platform.d/";
|
||||
|
||||
hardware.opengl.package = mkIf (!offloadCfg.enable) nvidia_x11.out;
|
||||
hardware.opengl.package32 = mkIf (!offloadCfg.enable) nvidia_x11.lib32;
|
||||
hardware.opengl.extraPackages = [
|
||||
nvidia_x11.out
|
||||
pkgs.nvidia-vaapi-driver
|
||||
] ++ optional offloadCfg.enable nvidia_x11.out;
|
||||
];
|
||||
hardware.opengl.extraPackages32 = [
|
||||
nvidia_x11.lib32
|
||||
pkgs.pkgsi686Linux.nvidia-vaapi-driver
|
||||
] ++ optional offloadCfg.enable nvidia_x11.lib32;
|
||||
];
|
||||
|
||||
environment.systemPackages = [ nvidia_x11.bin ]
|
||||
++ optionals cfg.nvidiaSettings [ nvidia_x11.settings ]
|
||||
|
@ -63,32 +63,32 @@ mount --rbind /sys "$mountPoint/sys"
|
||||
|
||||
# modified from https://github.com/archlinux/arch-install-scripts/blob/bb04ab435a5a89cd5e5ee821783477bc80db797f/arch-chroot.in#L26-L52
|
||||
chroot_add_resolv_conf() {
|
||||
local chrootdir=$1 resolv_conf=$1/etc/resolv.conf
|
||||
local chrootDir="$1" resolvConf="$1/etc/resolv.conf"
|
||||
|
||||
[[ -e /etc/resolv.conf ]] || return 0
|
||||
|
||||
# Handle resolv.conf as a symlink to somewhere else.
|
||||
if [[ -L $chrootdir/etc/resolv.conf ]]; then
|
||||
if [[ -L "$resolvConf" ]]; then
|
||||
# readlink(1) should always give us *something* since we know at this point
|
||||
# it's a symlink. For simplicity, ignore the case of nested symlinks.
|
||||
# We also ignore the possibility if `../`s escaping the root.
|
||||
resolv_conf=$(readlink "$chrootdir/etc/resolv.conf")
|
||||
if [[ $resolv_conf = /* ]]; then
|
||||
resolv_conf=$chrootdir$resolv_conf
|
||||
# We also ignore the possibility of `../`s escaping the root.
|
||||
resolvConf="$(readlink "$resolvConf")"
|
||||
if [[ "$resolvConf" = /* ]]; then
|
||||
resolvConf="$chrootDir$resolvConf"
|
||||
else
|
||||
resolv_conf=$chrootdir/etc/$resolv_conf
|
||||
resolvConf="$chrootDir/etc/$resolvConf"
|
||||
fi
|
||||
fi
|
||||
|
||||
# ensure file exists to bind mount over
|
||||
if [[ ! -f $resolv_conf ]]; then
|
||||
install -Dm644 /dev/null "$resolv_conf" || return 1
|
||||
if [[ ! -f "$resolvConf" ]]; then
|
||||
install -Dm644 /dev/null "$resolvConf" || return 1
|
||||
fi
|
||||
|
||||
mount --bind /etc/resolv.conf "$resolv_conf"
|
||||
mount --bind /etc/resolv.conf "$resolvConf"
|
||||
}
|
||||
|
||||
chroot_add_resolv_conf "$mountPoint" || print "ERROR: failed to set up resolv.conf"
|
||||
chroot_add_resolv_conf "$mountPoint" || echo "$0: failed to set up resolv.conf" >&2
|
||||
|
||||
(
|
||||
# If silent, write both stdout and stderr of activation script to /dev/null
|
||||
|
@ -183,7 +183,11 @@ in
|
||||
|
||||
pruneNames = mkOption {
|
||||
type = listOf str;
|
||||
default = [ ".bzr" ".cache" ".git" ".hg" ".svn" ];
|
||||
default = lib.optionals (!isFindutils) [ ".bzr" ".cache" ".git" ".hg" ".svn" ];
|
||||
defaultText = literalDocBook ''
|
||||
<literal>[ ".bzr" ".cache" ".git" ".hg" ".svn" ]</literal>, if
|
||||
supported by the locate implementation (i.e. mlocate or plocate).
|
||||
'';
|
||||
description = ''
|
||||
Directory components which should exclude paths containing them from indexing
|
||||
'';
|
||||
|
@ -181,6 +181,7 @@
|
||||
./programs/mtr.nix
|
||||
./programs/nano.nix
|
||||
./programs/nbd.nix
|
||||
./programs/nix-ld.nix
|
||||
./programs/neovim.nix
|
||||
./programs/nm-applet.nix
|
||||
./programs/npm.nix
|
||||
@ -1168,7 +1169,12 @@
|
||||
./system/boot/stage-1.nix
|
||||
./system/boot/stage-2.nix
|
||||
./system/boot/systemd.nix
|
||||
./system/boot/systemd-nspawn.nix
|
||||
./system/boot/systemd/coredump.nix
|
||||
./system/boot/systemd/journald.nix
|
||||
./system/boot/systemd/logind.nix
|
||||
./system/boot/systemd/nspawn.nix
|
||||
./system/boot/systemd/tmpfiles.nix
|
||||
./system/boot/systemd/user.nix
|
||||
./system/boot/timesyncd.nix
|
||||
./system/boot/tmp.nix
|
||||
./system/etc/etc-activation.nix
|
||||
|
12
nixos/modules/programs/nix-ld.nix
Normal file
12
nixos/modules/programs/nix-ld.nix
Normal file
@ -0,0 +1,12 @@
|
||||
{ pkgs, lib, config, ... }:
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.mic92 ];
|
||||
options = {
|
||||
programs.nix-ld.enable = lib.mkEnableOption ''nix-ld, Documentation: <link xlink:href="https://github.com/Mic92/nix-ld"/>'';
|
||||
};
|
||||
config = lib.mkIf config.programs.nix-ld.enable {
|
||||
systemd.tmpfiles.rules = [
|
||||
"L+ ${pkgs.nix-ld.ldPath} - - - - ${pkgs.nix-ld}/libexec/nix-ld"
|
||||
];
|
||||
};
|
||||
}
|
@ -119,7 +119,7 @@ in {
|
||||
<link linkend="opt-services.matrix-synapse.settings.listeners">listeners</link> = [
|
||||
{
|
||||
<link linkend="opt-services.matrix-synapse.settings.listeners._.port">port</link> = 8008;
|
||||
<link linkend="opt-services.matrix-synapse.settings.listeners._.bind_addresses">bind_address</link> = [ "::1" ];
|
||||
<link linkend="opt-services.matrix-synapse.settings.listeners._.bind_addresses">bind_addresses</link> = [ "::1" ];
|
||||
<link linkend="opt-services.matrix-synapse.settings.listeners._.type">type</link> = "http";
|
||||
<link linkend="opt-services.matrix-synapse.settings.listeners._.tls">tls</link> = false;
|
||||
<link linkend="opt-services.matrix-synapse.settings.listeners._.x_forwarded">x_forwarded</link> = true;
|
||||
@ -152,10 +152,10 @@ in {
|
||||
|
||||
<para>
|
||||
If you want to run a server with public registration by anybody, you can
|
||||
then enable <literal><link linkend="opt-services.matrix-synapse.settings.enable_registration">services.matrix-synapse.enable_registration</link> =
|
||||
then enable <literal><link linkend="opt-services.matrix-synapse.settings.enable_registration">services.matrix-synapse.settings.enable_registration</link> =
|
||||
true;</literal>. Otherwise, or you can generate a registration secret with
|
||||
<command>pwgen -s 64 1</command> and set it with
|
||||
<option><link linkend="opt-services.matrix-synapse.settings.registration_shared_secret">services.matrix-synapse.registration_shared_secret</link></option>.
|
||||
<option><link linkend="opt-services.matrix-synapse.settings.registration_shared_secret">services.matrix-synapse.settings.registration_shared_secret</link></option>.
|
||||
To create a new user or admin, run the following after you have set the secret
|
||||
and have rebuilt NixOS:
|
||||
<screen>
|
||||
|
@ -112,11 +112,11 @@ in
|
||||
|
||||
{
|
||||
imports = [
|
||||
(mkRenamedOptionModule [ "nix" "useChroot" ] [ "nix" "useSandbox" ])
|
||||
(mkRenamedOptionModule [ "nix" "chrootDirs" ] [ "nix" "sandboxPaths" ])
|
||||
(mkRenamedOptionModule [ "nix" "daemonIONiceLevel" ] [ "nix" "daemonIOSchedPriority" ])
|
||||
(mkRenamedOptionModuleWith { sinceRelease = 2003; from = [ "nix" "useChroot" ]; to = [ "nix" "useSandbox" ]; })
|
||||
(mkRenamedOptionModuleWith { sinceRelease = 2003; from = [ "nix" "chrootDirs" ]; to = [ "nix" "sandboxPaths" ]; })
|
||||
(mkRenamedOptionModuleWith { sinceRelease = 2205; from = [ "nix" "daemonIONiceLevel" ]; to = [ "nix" "daemonIOSchedPriority" ]; })
|
||||
(mkRemovedOptionModule [ "nix" "daemonNiceLevel" ] "Consider nix.daemonCPUSchedPolicy instead.")
|
||||
] ++ mapAttrsToList (oldConf: newConf: mkRenamedOptionModule [ "nix" oldConf ] [ "nix" "settings" newConf ]) legacyConfMappings;
|
||||
] ++ mapAttrsToList (oldConf: newConf: mkRenamedOptionModuleWith { sinceRelease = 2205; from = [ "nix" oldConf ]; to = [ "nix" "settings" newConf ]; }) legacyConfMappings;
|
||||
|
||||
###### interface
|
||||
|
||||
|
@ -214,6 +214,8 @@ in
|
||||
User = cfg.user;
|
||||
ExecStart = "${cfg.package}/bin/paperless-ng qcluster";
|
||||
Restart = "on-failure";
|
||||
# The `mbind` syscall is needed for running the classifier.
|
||||
SystemCallFilter = defaultServiceConfig.SystemCallFilter ++ [ "mbind" ];
|
||||
};
|
||||
environment = env;
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
@ -224,6 +224,7 @@ in
|
||||
targets.samba = {
|
||||
description = "Samba Server";
|
||||
after = [ "network.target" ];
|
||||
wants = [ "network-online.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
};
|
||||
# Refer to https://github.com/samba-team/samba/tree/master/packaging/systemd
|
||||
|
@ -194,19 +194,8 @@ let
|
||||
zone.children
|
||||
);
|
||||
|
||||
# fighting infinite recursion
|
||||
zoneOptions = zoneOptionsRaw // childConfig zoneOptions1 true;
|
||||
zoneOptions1 = zoneOptionsRaw // childConfig zoneOptions2 false;
|
||||
zoneOptions2 = zoneOptionsRaw // childConfig zoneOptions3 false;
|
||||
zoneOptions3 = zoneOptionsRaw // childConfig zoneOptions4 false;
|
||||
zoneOptions4 = zoneOptionsRaw // childConfig zoneOptions5 false;
|
||||
zoneOptions5 = zoneOptionsRaw // childConfig zoneOptions6 false;
|
||||
zoneOptions6 = zoneOptionsRaw // childConfig null false;
|
||||
|
||||
childConfig = x: v: { options.children = { type = types.attrsOf x; visible = v; }; };
|
||||
|
||||
# options are ordered alphanumerically
|
||||
zoneOptionsRaw = types.submodule {
|
||||
zoneOptions = types.submodule {
|
||||
options = {
|
||||
|
||||
allowAXFRFallback = mkOption {
|
||||
@ -246,6 +235,13 @@ let
|
||||
};
|
||||
|
||||
children = mkOption {
|
||||
# TODO: This relies on the fact that `types.anything` doesn't set any
|
||||
# values of its own to any defaults, because in the above zoneConfigs',
|
||||
# values from children override ones from parents, but only if the
|
||||
# attributes are defined. Because of this, we can't replace the element
|
||||
# type here with `zoneConfigs`, since that would set all the attributes
|
||||
# to default values, breaking the parent inheriting function.
|
||||
type = types.attrsOf types.anything;
|
||||
default = {};
|
||||
description = ''
|
||||
Children zones inherit all options of their parents. Attributes
|
||||
|
@ -1,6 +1,7 @@
|
||||
{ config, options, lib, pkgs, stdenv, ... }:
|
||||
let
|
||||
cfg = config.services.pleroma;
|
||||
cookieFile = "/var/lib/pleroma/.cookie";
|
||||
in {
|
||||
options = {
|
||||
services.pleroma = with lib; {
|
||||
@ -8,7 +9,7 @@ in {
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.pleroma;
|
||||
default = pkgs.pleroma.override { inherit cookieFile; };
|
||||
defaultText = literalExpression "pkgs.pleroma";
|
||||
description = "Pleroma package to use.";
|
||||
};
|
||||
@ -100,7 +101,6 @@ in {
|
||||
after = [ "network-online.target" "postgresql.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
restartTriggers = [ config.environment.etc."/pleroma/config.exs".source ];
|
||||
environment.RELEASE_COOKIE = "/var/lib/pleroma/.cookie";
|
||||
serviceConfig = {
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
@ -118,10 +118,10 @@ in {
|
||||
# Better be safe than sorry migration-wise.
|
||||
ExecStartPre =
|
||||
let preScript = pkgs.writers.writeBashBin "pleromaStartPre" ''
|
||||
if [ ! -f /var/lib/pleroma/.cookie ]
|
||||
if [ ! -f "${cookieFile}" ] || [ ! -s "${cookieFile}" ]
|
||||
then
|
||||
echo "Creating cookie file"
|
||||
dd if=/dev/urandom bs=1 count=16 | hexdump -e '16/1 "%02x"' > /var/lib/pleroma/.cookie
|
||||
dd if=/dev/urandom bs=1 count=16 | ${pkgs.hexdump}/bin/hexdump -e '16/1 "%02x"' > "${cookieFile}"
|
||||
fi
|
||||
${cfg.package}/bin/pleroma_ctl migrate
|
||||
'';
|
||||
|
@ -62,6 +62,7 @@ in {
|
||||
};
|
||||
|
||||
stateDir = mkOption {
|
||||
type = types.path;
|
||||
default = "/var/lib/unbound";
|
||||
description = "Directory holding all state for unbound to run.";
|
||||
};
|
||||
|
@ -153,6 +153,7 @@ in
|
||||
|
||||
userlist = mkOption {
|
||||
default = [];
|
||||
type = types.listOf types.str;
|
||||
description = "See <option>userlistFile</option>.";
|
||||
};
|
||||
|
||||
|
@ -102,17 +102,19 @@ in
|
||||
# Taken from: https://github.com/oauth2-proxy/oauth2-proxy/blob/master/providers/providers.go
|
||||
provider = mkOption {
|
||||
type = types.enum [
|
||||
"google"
|
||||
"adfs"
|
||||
"azure"
|
||||
"bitbucket"
|
||||
"digitalocean"
|
||||
"facebook"
|
||||
"github"
|
||||
"keycloak"
|
||||
"gitlab"
|
||||
"google"
|
||||
"keycloak"
|
||||
"keycloak-oidc"
|
||||
"linkedin"
|
||||
"login.gov"
|
||||
"bitbucket"
|
||||
"nextcloud"
|
||||
"digitalocean"
|
||||
"oidc"
|
||||
];
|
||||
default = "google";
|
||||
|
@ -910,6 +910,11 @@ in
|
||||
ORPort = mkForce [];
|
||||
PublishServerDescriptor = mkForce false;
|
||||
})
|
||||
(mkIf (!cfg.client.enable) {
|
||||
# Make sure application connections via SOCKS are disabled
|
||||
# when services.tor.client.enable is false
|
||||
SOCKSPort = mkForce [ 0 ];
|
||||
})
|
||||
(mkIf cfg.client.enable (
|
||||
{ SOCKSPort = [ cfg.client.socksListenAddress ];
|
||||
} // optionalAttrs cfg.client.transparentProxy.enable {
|
||||
|
@ -153,7 +153,7 @@ in {
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
description = "Which package to use for the Nextcloud instance.";
|
||||
relatedPackages = [ "nextcloud21" "nextcloud22" "nextcloud23" ];
|
||||
relatedPackages = [ "nextcloud22" "nextcloud23" ];
|
||||
};
|
||||
phpPackage = mkOption {
|
||||
type = types.package;
|
||||
@ -571,15 +571,6 @@ in {
|
||||
nextcloud defined in an overlay, please set `services.nextcloud.package` to
|
||||
`pkgs.nextcloud`.
|
||||
''
|
||||
# 21.03 will not be an official release - it was instead 21.05.
|
||||
# This versionOlder statement remains set to 21.03 for backwards compatibility.
|
||||
# See https://github.com/NixOS/nixpkgs/pull/108899 and
|
||||
# https://github.com/NixOS/rfcs/blob/master/rfcs/0080-nixos-release-schedule.md.
|
||||
# FIXME(@Ma27) remove this else-if as soon as 21.05 is EOL! This is only here
|
||||
# to ensure that users who are on Nextcloud 19 with a stateVersion <21.05 with
|
||||
# no explicit services.nextcloud.package don't upgrade to v21 by accident (
|
||||
# nextcloud20 throws an eval-error because it's dropped).
|
||||
else if versionOlder stateVersion "21.03" then nextcloud20
|
||||
else if versionOlder stateVersion "21.11" then nextcloud21
|
||||
else if versionOlder stateVersion "22.05" then nextcloud22
|
||||
else nextcloud23
|
||||
|
@ -219,6 +219,7 @@ in
|
||||
|
||||
session = mkOption {
|
||||
default = [];
|
||||
type = types.listOf types.attrs;
|
||||
example = literalExpression
|
||||
''
|
||||
[ { manage = "desktop";
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -36,7 +36,7 @@ in
|
||||
|
||||
boot.kernelPackages = mkOption {
|
||||
default = pkgs.linuxPackages;
|
||||
type = types.unspecified // { merge = mergeEqualOption; };
|
||||
type = types.raw;
|
||||
apply = kernelPackages: kernelPackages.extend (self: super: {
|
||||
kernel = super.kernel.override (originalArgs: {
|
||||
inherit randstructSeed;
|
||||
|
@ -34,23 +34,6 @@ with lib;
|
||||
type = types.lines;
|
||||
};
|
||||
|
||||
boot.initrd.extraModprobeConfig = mkOption {
|
||||
default = "";
|
||||
example =
|
||||
''
|
||||
options zfs zfs_arc_max=1073741824
|
||||
'';
|
||||
description = ''
|
||||
Does exactly the same thing as
|
||||
<option>boot.extraModprobeConfig</option>, except
|
||||
that the generated <filename>modprobe.conf</filename>
|
||||
file is also included in the initrd.
|
||||
This is useful for setting module options for kernel
|
||||
modules that are loaded during early boot in the initrd.
|
||||
'';
|
||||
type = types.lines;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -67,9 +50,6 @@ with lib;
|
||||
'')}
|
||||
${config.boot.extraModprobeConfig}
|
||||
'';
|
||||
environment.etc."modprobe.d/nixos-initrd.conf".text = ''
|
||||
${config.boot.initrd.extraModprobeConfig}
|
||||
'';
|
||||
environment.etc."modprobe.d/debian.conf".source = pkgs.kmod-debian-aliases;
|
||||
|
||||
environment.etc."modprobe.d/systemd.conf".source = "${pkgs.systemd}/lib/modprobe.d/systemd.conf";
|
||||
|
@ -338,9 +338,6 @@ let
|
||||
{ object = pkgs.writeText "mdadm.conf" config.boot.initrd.mdadmConf;
|
||||
symlink = "/etc/mdadm.conf";
|
||||
}
|
||||
{ object = config.environment.etc."modprobe.d/nixos-initrd.conf".source;
|
||||
symlink = "/etc/modprobe.d/nixos-initrd.conf";
|
||||
}
|
||||
{ object = pkgs.runCommand "initrd-kmod-blacklist-ubuntu" {
|
||||
src = "${pkgs.kmod-blacklist-ubuntu}/modprobe.conf";
|
||||
preferLocalBuild = true;
|
||||
@ -581,7 +578,7 @@ in
|
||||
else "gzip"
|
||||
);
|
||||
defaultText = literalDocBook "<literal>zstd</literal> if the kernel supports it (5.9+), <literal>gzip</literal> if not";
|
||||
type = types.unspecified; # We don't have a function type...
|
||||
type = types.either types.str (types.functionTo types.str);
|
||||
description = ''
|
||||
The compressor to use on the initrd image. May be any of:
|
||||
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
with utils;
|
||||
with systemdUtils.unitOptions;
|
||||
with systemdUtils.lib;
|
||||
with lib;
|
||||
|
||||
let
|
||||
@ -11,6 +10,24 @@ let
|
||||
|
||||
systemd = cfg.package;
|
||||
|
||||
inherit (systemdUtils.lib)
|
||||
makeUnit
|
||||
generateUnits
|
||||
makeJobScript
|
||||
unitConfig
|
||||
serviceConfig
|
||||
mountConfig
|
||||
automountConfig
|
||||
commonUnitText
|
||||
targetToUnit
|
||||
serviceToUnit
|
||||
socketToUnit
|
||||
timerToUnit
|
||||
pathToUnit
|
||||
mountToUnit
|
||||
automountToUnit
|
||||
sliceToUnit;
|
||||
|
||||
upstreamSystemUnits =
|
||||
[ # Targets.
|
||||
"basic.target"
|
||||
@ -63,32 +80,6 @@ let
|
||||
"printer.target"
|
||||
"smartcard.target"
|
||||
|
||||
# Login stuff.
|
||||
"systemd-logind.service"
|
||||
"autovt@.service"
|
||||
"systemd-user-sessions.service"
|
||||
"dbus-org.freedesktop.import1.service"
|
||||
"dbus-org.freedesktop.machine1.service"
|
||||
"dbus-org.freedesktop.login1.service"
|
||||
"user@.service"
|
||||
"user-runtime-dir@.service"
|
||||
|
||||
# Journal.
|
||||
"systemd-journald.socket"
|
||||
"systemd-journald@.socket"
|
||||
"systemd-journald-varlink@.socket"
|
||||
"systemd-journald.service"
|
||||
"systemd-journald@.service"
|
||||
"systemd-journal-flush.service"
|
||||
"systemd-journal-catalog-update.service"
|
||||
] ++ (optional (!config.boot.isContainer) "systemd-journald-audit.socket") ++ [
|
||||
"systemd-journald-dev-log.socket"
|
||||
"syslog.socket"
|
||||
|
||||
# Coredumps.
|
||||
"systemd-coredump.socket"
|
||||
"systemd-coredump@.service"
|
||||
|
||||
# Kernel module loading.
|
||||
"systemd-modules-load.service"
|
||||
"kmod-static-nodes.service"
|
||||
@ -149,19 +140,12 @@ let
|
||||
|
||||
# Slices / containers.
|
||||
"slices.target"
|
||||
"user.slice"
|
||||
"machine.slice"
|
||||
"machines.target"
|
||||
"systemd-importd.service"
|
||||
"systemd-machined.service"
|
||||
"systemd-nspawn@.service"
|
||||
|
||||
# Temporary file creation / cleanup.
|
||||
"systemd-tmpfiles-clean.service"
|
||||
"systemd-tmpfiles-clean.timer"
|
||||
"systemd-tmpfiles-setup.service"
|
||||
"systemd-tmpfiles-setup-dev.service"
|
||||
|
||||
# Misc.
|
||||
"systemd-sysctl.service"
|
||||
"dbus-org.freedesktop.timedate1.service"
|
||||
@ -172,9 +156,6 @@ let
|
||||
"systemd-hostnamed.service"
|
||||
"systemd-exit.service"
|
||||
"systemd-update-done.service"
|
||||
] ++ optionals config.services.journald.enableHttpGateway [
|
||||
"systemd-journal-gatewayd.socket"
|
||||
"systemd-journal-gatewayd.service"
|
||||
] ++ cfg.additionalUpstreamSystemUnits;
|
||||
|
||||
upstreamSystemWants =
|
||||
@ -185,237 +166,6 @@ let
|
||||
"timers.target.wants"
|
||||
];
|
||||
|
||||
upstreamUserUnits = [
|
||||
"app.slice"
|
||||
"background.slice"
|
||||
"basic.target"
|
||||
"bluetooth.target"
|
||||
"default.target"
|
||||
"exit.target"
|
||||
"graphical-session-pre.target"
|
||||
"graphical-session.target"
|
||||
"paths.target"
|
||||
"printer.target"
|
||||
"session.slice"
|
||||
"shutdown.target"
|
||||
"smartcard.target"
|
||||
"sockets.target"
|
||||
"sound.target"
|
||||
"systemd-exit.service"
|
||||
"systemd-tmpfiles-clean.service"
|
||||
"systemd-tmpfiles-clean.timer"
|
||||
"systemd-tmpfiles-setup.service"
|
||||
"timers.target"
|
||||
"xdg-desktop-autostart.target"
|
||||
];
|
||||
|
||||
makeJobScript = name: text:
|
||||
let
|
||||
scriptName = replaceChars [ "\\" "@" ] [ "-" "_" ] (shellEscape name);
|
||||
out = (pkgs.writeShellScriptBin scriptName ''
|
||||
set -e
|
||||
${text}
|
||||
'').overrideAttrs (_: {
|
||||
# The derivation name is different from the script file name
|
||||
# to keep the script file name short to avoid cluttering logs.
|
||||
name = "unit-script-${scriptName}";
|
||||
});
|
||||
in "${out}/bin/${scriptName}";
|
||||
|
||||
unitConfig = { config, options, ... }: {
|
||||
config = {
|
||||
unitConfig =
|
||||
optionalAttrs (config.requires != [])
|
||||
{ Requires = toString config.requires; }
|
||||
// optionalAttrs (config.wants != [])
|
||||
{ Wants = toString config.wants; }
|
||||
// optionalAttrs (config.after != [])
|
||||
{ After = toString config.after; }
|
||||
// optionalAttrs (config.before != [])
|
||||
{ Before = toString config.before; }
|
||||
// optionalAttrs (config.bindsTo != [])
|
||||
{ BindsTo = toString config.bindsTo; }
|
||||
// optionalAttrs (config.partOf != [])
|
||||
{ PartOf = toString config.partOf; }
|
||||
// optionalAttrs (config.conflicts != [])
|
||||
{ Conflicts = toString config.conflicts; }
|
||||
// optionalAttrs (config.requisite != [])
|
||||
{ Requisite = toString config.requisite; }
|
||||
// optionalAttrs (config.restartTriggers != [])
|
||||
{ X-Restart-Triggers = toString config.restartTriggers; }
|
||||
// optionalAttrs (config.reloadTriggers != [])
|
||||
{ X-Reload-Triggers = toString config.reloadTriggers; }
|
||||
// optionalAttrs (config.description != "") {
|
||||
Description = config.description; }
|
||||
// optionalAttrs (config.documentation != []) {
|
||||
Documentation = toString config.documentation; }
|
||||
// optionalAttrs (config.onFailure != []) {
|
||||
OnFailure = toString config.onFailure; }
|
||||
// optionalAttrs (options.startLimitIntervalSec.isDefined) {
|
||||
StartLimitIntervalSec = toString config.startLimitIntervalSec;
|
||||
} // optionalAttrs (options.startLimitBurst.isDefined) {
|
||||
StartLimitBurst = toString config.startLimitBurst;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
serviceConfig = { name, config, ... }: {
|
||||
config = mkMerge
|
||||
[ { # Default path for systemd services. Should be quite minimal.
|
||||
path = mkAfter
|
||||
[ pkgs.coreutils
|
||||
pkgs.findutils
|
||||
pkgs.gnugrep
|
||||
pkgs.gnused
|
||||
systemd
|
||||
];
|
||||
environment.PATH = "${makeBinPath config.path}:${makeSearchPathOutput "bin" "sbin" config.path}";
|
||||
}
|
||||
(mkIf (config.preStart != "")
|
||||
{ serviceConfig.ExecStartPre =
|
||||
[ (makeJobScript "${name}-pre-start" config.preStart) ];
|
||||
})
|
||||
(mkIf (config.script != "")
|
||||
{ serviceConfig.ExecStart =
|
||||
makeJobScript "${name}-start" config.script + " " + config.scriptArgs;
|
||||
})
|
||||
(mkIf (config.postStart != "")
|
||||
{ serviceConfig.ExecStartPost =
|
||||
[ (makeJobScript "${name}-post-start" config.postStart) ];
|
||||
})
|
||||
(mkIf (config.reload != "")
|
||||
{ serviceConfig.ExecReload =
|
||||
makeJobScript "${name}-reload" config.reload;
|
||||
})
|
||||
(mkIf (config.preStop != "")
|
||||
{ serviceConfig.ExecStop =
|
||||
makeJobScript "${name}-pre-stop" config.preStop;
|
||||
})
|
||||
(mkIf (config.postStop != "")
|
||||
{ serviceConfig.ExecStopPost =
|
||||
makeJobScript "${name}-post-stop" config.postStop;
|
||||
})
|
||||
];
|
||||
};
|
||||
|
||||
mountConfig = { config, ... }: {
|
||||
config = {
|
||||
mountConfig =
|
||||
{ What = config.what;
|
||||
Where = config.where;
|
||||
} // optionalAttrs (config.type != "") {
|
||||
Type = config.type;
|
||||
} // optionalAttrs (config.options != "") {
|
||||
Options = config.options;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
automountConfig = { config, ... }: {
|
||||
config = {
|
||||
automountConfig =
|
||||
{ Where = config.where;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
commonUnitText = def: ''
|
||||
[Unit]
|
||||
${attrsToSection def.unitConfig}
|
||||
'';
|
||||
|
||||
targetToUnit = name: def:
|
||||
{ inherit (def) aliases wantedBy requiredBy enable;
|
||||
text =
|
||||
''
|
||||
[Unit]
|
||||
${attrsToSection def.unitConfig}
|
||||
'';
|
||||
};
|
||||
|
||||
serviceToUnit = name: def:
|
||||
{ inherit (def) aliases wantedBy requiredBy enable;
|
||||
text = commonUnitText def +
|
||||
''
|
||||
[Service]
|
||||
${let env = cfg.globalEnvironment // def.environment;
|
||||
in concatMapStrings (n:
|
||||
let s = optionalString (env.${n} != null)
|
||||
"Environment=${builtins.toJSON "${n}=${env.${n}}"}\n";
|
||||
# systemd max line length is now 1MiB
|
||||
# https://github.com/systemd/systemd/commit/e6dde451a51dc5aaa7f4d98d39b8fe735f73d2af
|
||||
in if stringLength s >= 1048576 then throw "The value of the environment variable ‘${n}’ in systemd service ‘${name}.service’ is too long." else s) (attrNames env)}
|
||||
${if def.reloadIfChanged then ''
|
||||
X-ReloadIfChanged=true
|
||||
'' else if !def.restartIfChanged then ''
|
||||
X-RestartIfChanged=false
|
||||
'' else ""}
|
||||
${optionalString (!def.stopIfChanged) "X-StopIfChanged=false"}
|
||||
${attrsToSection def.serviceConfig}
|
||||
'';
|
||||
};
|
||||
|
||||
socketToUnit = name: def:
|
||||
{ inherit (def) aliases wantedBy requiredBy enable;
|
||||
text = commonUnitText def +
|
||||
''
|
||||
[Socket]
|
||||
${attrsToSection def.socketConfig}
|
||||
${concatStringsSep "\n" (map (s: "ListenStream=${s}") def.listenStreams)}
|
||||
${concatStringsSep "\n" (map (s: "ListenDatagram=${s}") def.listenDatagrams)}
|
||||
'';
|
||||
};
|
||||
|
||||
timerToUnit = name: def:
|
||||
{ inherit (def) aliases wantedBy requiredBy enable;
|
||||
text = commonUnitText def +
|
||||
''
|
||||
[Timer]
|
||||
${attrsToSection def.timerConfig}
|
||||
'';
|
||||
};
|
||||
|
||||
pathToUnit = name: def:
|
||||
{ inherit (def) aliases wantedBy requiredBy enable;
|
||||
text = commonUnitText def +
|
||||
''
|
||||
[Path]
|
||||
${attrsToSection def.pathConfig}
|
||||
'';
|
||||
};
|
||||
|
||||
mountToUnit = name: def:
|
||||
{ inherit (def) aliases wantedBy requiredBy enable;
|
||||
text = commonUnitText def +
|
||||
''
|
||||
[Mount]
|
||||
${attrsToSection def.mountConfig}
|
||||
'';
|
||||
};
|
||||
|
||||
automountToUnit = name: def:
|
||||
{ inherit (def) aliases wantedBy requiredBy enable;
|
||||
text = commonUnitText def +
|
||||
''
|
||||
[Automount]
|
||||
${attrsToSection def.automountConfig}
|
||||
'';
|
||||
};
|
||||
|
||||
sliceToUnit = name: def:
|
||||
{ inherit (def) aliases wantedBy requiredBy enable;
|
||||
text = commonUnitText def +
|
||||
''
|
||||
[Slice]
|
||||
${attrsToSection def.sliceConfig}
|
||||
'';
|
||||
};
|
||||
|
||||
logindHandlerType = types.enum [
|
||||
"ignore" "poweroff" "reboot" "halt" "kexec" "suspend"
|
||||
"hibernate" "hybrid-sleep" "suspend-then-hibernate" "lock"
|
||||
];
|
||||
|
||||
proxy_env = config.networking.proxy.envVars;
|
||||
|
||||
in
|
||||
@ -568,26 +318,6 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.coredump.enable = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether core dumps should be processed by
|
||||
<command>systemd-coredump</command>. If disabled, core dumps
|
||||
appear in the current directory of the crashing process.
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.coredump.extraConfig = mkOption {
|
||||
default = "";
|
||||
type = types.lines;
|
||||
example = "Storage=journal";
|
||||
description = ''
|
||||
Extra config options for systemd-coredump. See coredump.conf(5) man page
|
||||
for available options.
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.extraConfig = mkOption {
|
||||
default = "";
|
||||
type = types.lines;
|
||||
@ -598,142 +328,6 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
services.journald.console = mkOption {
|
||||
default = "";
|
||||
type = types.str;
|
||||
description = "If non-empty, write log messages to the specified TTY device.";
|
||||
};
|
||||
|
||||
services.journald.rateLimitInterval = mkOption {
|
||||
default = "30s";
|
||||
type = types.str;
|
||||
description = ''
|
||||
Configures the rate limiting interval that is applied to all
|
||||
messages generated on the system. This rate limiting is applied
|
||||
per-service, so that two services which log do not interfere with
|
||||
each other's limit. The value may be specified in the following
|
||||
units: s, min, h, ms, us. To turn off any kind of rate limiting,
|
||||
set either value to 0.
|
||||
|
||||
See <option>services.journald.rateLimitBurst</option> for important
|
||||
considerations when setting this value.
|
||||
'';
|
||||
};
|
||||
|
||||
services.journald.rateLimitBurst = mkOption {
|
||||
default = 10000;
|
||||
type = types.int;
|
||||
description = ''
|
||||
Configures the rate limiting burst limit (number of messages per
|
||||
interval) that is applied to all messages generated on the system.
|
||||
This rate limiting is applied per-service, so that two services
|
||||
which log do not interfere with each other's limit.
|
||||
|
||||
Note that the effective rate limit is multiplied by a factor derived
|
||||
from the available free disk space for the journal as described on
|
||||
<link xlink:href="https://www.freedesktop.org/software/systemd/man/journald.conf.html">
|
||||
journald.conf(5)</link>.
|
||||
|
||||
Note that the total amount of logs stored is limited by journald settings
|
||||
such as <literal>SystemMaxUse</literal>, which defaults to a 4 GB cap.
|
||||
|
||||
It is thus recommended to compute what period of time that you will be
|
||||
able to store logs for when an application logs at full burst rate.
|
||||
With default settings for log lines that are 100 Bytes long, this can
|
||||
amount to just a few hours.
|
||||
'';
|
||||
};
|
||||
|
||||
services.journald.extraConfig = mkOption {
|
||||
default = "";
|
||||
type = types.lines;
|
||||
example = "Storage=volatile";
|
||||
description = ''
|
||||
Extra config options for systemd-journald. See man journald.conf
|
||||
for available options.
|
||||
'';
|
||||
};
|
||||
|
||||
services.journald.enableHttpGateway = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to enable the HTTP gateway to the journal.
|
||||
'';
|
||||
};
|
||||
|
||||
services.journald.forwardToSyslog = mkOption {
|
||||
default = config.services.rsyslogd.enable || config.services.syslog-ng.enable;
|
||||
defaultText = literalExpression "services.rsyslogd.enable || services.syslog-ng.enable";
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to forward log messages to syslog.
|
||||
'';
|
||||
};
|
||||
|
||||
services.logind.extraConfig = mkOption {
|
||||
default = "";
|
||||
type = types.lines;
|
||||
example = "IdleAction=lock";
|
||||
description = ''
|
||||
Extra config options for systemd-logind. See
|
||||
<link xlink:href="https://www.freedesktop.org/software/systemd/man/logind.conf.html">
|
||||
logind.conf(5)</link> for available options.
|
||||
'';
|
||||
};
|
||||
|
||||
services.logind.killUserProcesses = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Specifies whether the processes of a user should be killed
|
||||
when the user logs out. If true, the scope unit corresponding
|
||||
to the session and all processes inside that scope will be
|
||||
terminated. If false, the scope is "abandoned" (see
|
||||
<link xlink:href="https://www.freedesktop.org/software/systemd/man/systemd.scope.html#">
|
||||
systemd.scope(5)</link>), and processes are not killed.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
See <link xlink:href="https://www.freedesktop.org/software/systemd/man/logind.conf.html#KillUserProcesses=">logind.conf(5)</link>
|
||||
for more details.
|
||||
'';
|
||||
};
|
||||
|
||||
services.logind.lidSwitch = mkOption {
|
||||
default = "suspend";
|
||||
example = "ignore";
|
||||
type = logindHandlerType;
|
||||
|
||||
description = ''
|
||||
Specifies what to be done when the laptop lid is closed.
|
||||
'';
|
||||
};
|
||||
|
||||
services.logind.lidSwitchDocked = mkOption {
|
||||
default = "ignore";
|
||||
example = "suspend";
|
||||
type = logindHandlerType;
|
||||
|
||||
description = ''
|
||||
Specifies what to be done when the laptop lid is closed
|
||||
and another screen is added.
|
||||
'';
|
||||
};
|
||||
|
||||
services.logind.lidSwitchExternalPower = mkOption {
|
||||
default = config.services.logind.lidSwitch;
|
||||
defaultText = literalExpression "services.logind.lidSwitch";
|
||||
example = "ignore";
|
||||
type = logindHandlerType;
|
||||
|
||||
description = ''
|
||||
Specifies what to do when the laptop lid is closed and the system is
|
||||
on external power. By default use the same action as specified in
|
||||
services.logind.lidSwitch.
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.sleep.extraConfig = mkOption {
|
||||
default = "";
|
||||
type = types.lines;
|
||||
@ -744,95 +338,6 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.user.extraConfig = mkOption {
|
||||
default = "";
|
||||
type = types.lines;
|
||||
example = "DefaultCPUAccounting=yes";
|
||||
description = ''
|
||||
Extra config options for systemd user instances. See man systemd-user.conf for
|
||||
available options.
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.tmpfiles.rules = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
example = [ "d /tmp 1777 root root 10d" ];
|
||||
description = ''
|
||||
Rules for creation, deletion and cleaning of volatile and temporary files
|
||||
automatically. See
|
||||
<citerefentry><refentrytitle>tmpfiles.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||
for the exact format.
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.tmpfiles.packages = mkOption {
|
||||
type = types.listOf types.package;
|
||||
default = [];
|
||||
example = literalExpression "[ pkgs.lvm2 ]";
|
||||
apply = map getLib;
|
||||
description = ''
|
||||
List of packages containing <command>systemd-tmpfiles</command> rules.
|
||||
|
||||
All files ending in .conf found in
|
||||
<filename><replaceable>pkg</replaceable>/lib/tmpfiles.d</filename>
|
||||
will be included.
|
||||
If this folder does not exist or does not contain any files an error will be returned instead.
|
||||
|
||||
If a <filename>lib</filename> output is available, rules are searched there and only there.
|
||||
If there is no <filename>lib</filename> output it will fall back to <filename>out</filename>
|
||||
and if that does not exist either, the default output will be used.
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.user.units = mkOption {
|
||||
description = "Definition of systemd per-user units.";
|
||||
default = {};
|
||||
type = with types; attrsOf (submodule (
|
||||
{ name, config, ... }:
|
||||
{ options = concreteUnitOptions;
|
||||
config = {
|
||||
unit = mkDefault (makeUnit name config);
|
||||
};
|
||||
}));
|
||||
};
|
||||
|
||||
systemd.user.paths = mkOption {
|
||||
default = {};
|
||||
type = with types; attrsOf (submodule [ { options = pathOptions; } unitConfig ]);
|
||||
description = "Definition of systemd per-user path units.";
|
||||
};
|
||||
|
||||
systemd.user.services = mkOption {
|
||||
default = {};
|
||||
type = with types; attrsOf (submodule [ { options = serviceOptions; } unitConfig serviceConfig ] );
|
||||
description = "Definition of systemd per-user service units.";
|
||||
};
|
||||
|
||||
systemd.user.slices = mkOption {
|
||||
default = {};
|
||||
type = with types; attrsOf (submodule [ { options = sliceOptions; } unitConfig ] );
|
||||
description = "Definition of systemd per-user slice units.";
|
||||
};
|
||||
|
||||
systemd.user.sockets = mkOption {
|
||||
default = {};
|
||||
type = with types; attrsOf (submodule [ { options = socketOptions; } unitConfig ] );
|
||||
description = "Definition of systemd per-user socket units.";
|
||||
};
|
||||
|
||||
systemd.user.targets = mkOption {
|
||||
default = {};
|
||||
type = with types; attrsOf (submodule [ { options = targetOptions; } unitConfig] );
|
||||
description = "Definition of systemd per-user target units.";
|
||||
};
|
||||
|
||||
systemd.user.timers = mkOption {
|
||||
default = {};
|
||||
type = with types; attrsOf (submodule [ { options = timerOptions; } unitConfig ] );
|
||||
description = "Definition of systemd per-user timer units.";
|
||||
};
|
||||
|
||||
systemd.additionalUpstreamSystemUnits = mkOption {
|
||||
default = [ ];
|
||||
type = types.listOf types.str;
|
||||
@ -968,8 +473,6 @@ in
|
||||
in ({
|
||||
"systemd/system".source = generateUnits "system" enabledUnits enabledUpstreamSystemUnits upstreamSystemWants;
|
||||
|
||||
"systemd/user".source = generateUnits "user" cfg.user.units upstreamUserUnits [];
|
||||
|
||||
"systemd/system.conf".text = ''
|
||||
[Manager]
|
||||
${optionalString config.systemd.enableCgroupAccounting ''
|
||||
@ -995,76 +498,17 @@ in
|
||||
${config.systemd.extraConfig}
|
||||
'';
|
||||
|
||||
"systemd/user.conf".text = ''
|
||||
[Manager]
|
||||
${config.systemd.user.extraConfig}
|
||||
'';
|
||||
|
||||
"systemd/journald.conf".text = ''
|
||||
[Journal]
|
||||
Storage=persistent
|
||||
RateLimitInterval=${config.services.journald.rateLimitInterval}
|
||||
RateLimitBurst=${toString config.services.journald.rateLimitBurst}
|
||||
${optionalString (config.services.journald.console != "") ''
|
||||
ForwardToConsole=yes
|
||||
TTYPath=${config.services.journald.console}
|
||||
''}
|
||||
${optionalString (config.services.journald.forwardToSyslog) ''
|
||||
ForwardToSyslog=yes
|
||||
''}
|
||||
${config.services.journald.extraConfig}
|
||||
'';
|
||||
|
||||
"systemd/coredump.conf".text =
|
||||
''
|
||||
[Coredump]
|
||||
${config.systemd.coredump.extraConfig}
|
||||
'';
|
||||
|
||||
"systemd/logind.conf".text = ''
|
||||
[Login]
|
||||
KillUserProcesses=${if config.services.logind.killUserProcesses then "yes" else "no"}
|
||||
HandleLidSwitch=${config.services.logind.lidSwitch}
|
||||
HandleLidSwitchDocked=${config.services.logind.lidSwitchDocked}
|
||||
HandleLidSwitchExternalPower=${config.services.logind.lidSwitchExternalPower}
|
||||
${config.services.logind.extraConfig}
|
||||
'';
|
||||
|
||||
"systemd/sleep.conf".text = ''
|
||||
[Sleep]
|
||||
${config.systemd.sleep.extraConfig}
|
||||
'';
|
||||
|
||||
# install provided sysctl snippets
|
||||
"sysctl.d/50-coredump.conf".source = "${systemd}/example/sysctl.d/50-coredump.conf";
|
||||
"sysctl.d/50-default.conf".source = "${systemd}/example/sysctl.d/50-default.conf";
|
||||
|
||||
"tmpfiles.d".source = (pkgs.symlinkJoin {
|
||||
name = "tmpfiles.d";
|
||||
paths = map (p: p + "/lib/tmpfiles.d") cfg.tmpfiles.packages;
|
||||
postBuild = ''
|
||||
for i in $(cat $pathsPath); do
|
||||
(test -d "$i" && test $(ls "$i"/*.conf | wc -l) -ge 1) || (
|
||||
echo "ERROR: The path '$i' from systemd.tmpfiles.packages contains no *.conf files."
|
||||
exit 1
|
||||
)
|
||||
done
|
||||
'' + concatMapStrings (name: optionalString (hasPrefix "tmpfiles.d/" name) ''
|
||||
rm -f $out/${removePrefix "tmpfiles.d/" name}
|
||||
'') config.system.build.etc.passthru.targets;
|
||||
}) + "/*";
|
||||
|
||||
"systemd/system-generators" = { source = hooks "generators" cfg.generators; };
|
||||
"systemd/system-shutdown" = { source = hooks "shutdown" cfg.shutdown; };
|
||||
});
|
||||
|
||||
services.dbus.enable = true;
|
||||
|
||||
users.users.systemd-coredump = {
|
||||
uid = config.ids.uids.systemd-coredump;
|
||||
group = "systemd-coredump";
|
||||
};
|
||||
users.groups.systemd-coredump = {};
|
||||
users.users.systemd-network = {
|
||||
uid = config.ids.uids.systemd-network;
|
||||
group = "systemd-network";
|
||||
@ -1084,36 +528,6 @@ in
|
||||
unitConfig.X-StopOnReconfiguration = true;
|
||||
};
|
||||
|
||||
systemd.tmpfiles.packages = [
|
||||
# Default tmpfiles rules provided by systemd
|
||||
(pkgs.runCommand "systemd-default-tmpfiles" {} ''
|
||||
mkdir -p $out/lib/tmpfiles.d
|
||||
cd $out/lib/tmpfiles.d
|
||||
|
||||
ln -s "${systemd}/example/tmpfiles.d/home.conf"
|
||||
ln -s "${systemd}/example/tmpfiles.d/journal-nocow.conf"
|
||||
ln -s "${systemd}/example/tmpfiles.d/static-nodes-permissions.conf"
|
||||
ln -s "${systemd}/example/tmpfiles.d/systemd.conf"
|
||||
ln -s "${systemd}/example/tmpfiles.d/systemd-nologin.conf"
|
||||
ln -s "${systemd}/example/tmpfiles.d/systemd-nspawn.conf"
|
||||
ln -s "${systemd}/example/tmpfiles.d/systemd-tmp.conf"
|
||||
ln -s "${systemd}/example/tmpfiles.d/tmp.conf"
|
||||
ln -s "${systemd}/example/tmpfiles.d/var.conf"
|
||||
ln -s "${systemd}/example/tmpfiles.d/x11.conf"
|
||||
'')
|
||||
# User-specified tmpfiles rules
|
||||
(pkgs.writeTextFile {
|
||||
name = "nixos-tmpfiles.d";
|
||||
destination = "/lib/tmpfiles.d/00-nixos.conf";
|
||||
text = ''
|
||||
# This file is created automatically and should not be modified.
|
||||
# Please change the option ‘systemd.tmpfiles.rules’ instead.
|
||||
|
||||
${concatStringsSep "\n" cfg.tmpfiles.rules}
|
||||
'';
|
||||
})
|
||||
];
|
||||
|
||||
systemd.units =
|
||||
mapAttrs' (n: v: nameValuePair "${n}.path" (pathToUnit n v)) cfg.paths
|
||||
// mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.services
|
||||
@ -1128,14 +542,6 @@ in
|
||||
(v: let n = escapeSystemdPath v.where;
|
||||
in nameValuePair "${n}.automount" (automountToUnit n v)) cfg.automounts);
|
||||
|
||||
systemd.user.units =
|
||||
mapAttrs' (n: v: nameValuePair "${n}.path" (pathToUnit n v)) cfg.user.paths
|
||||
// mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.user.services
|
||||
// mapAttrs' (n: v: nameValuePair "${n}.slice" (sliceToUnit n v)) cfg.user.slices
|
||||
// mapAttrs' (n: v: nameValuePair "${n}.socket" (socketToUnit n v)) cfg.user.sockets
|
||||
// mapAttrs' (n: v: nameValuePair "${n}.target" (targetToUnit n v)) cfg.user.targets
|
||||
// mapAttrs' (n: v: nameValuePair "${n}.timer" (timerToUnit n v)) cfg.user.timers;
|
||||
|
||||
system.requiredKernelConfig = map config.lib.kernelConfig.isEnabled
|
||||
[ "DEVTMPFS" "CGROUPS" "INOTIFY_USER" "SIGNALFD" "TIMERFD" "EPOLL" "NET"
|
||||
"SYSFS" "PROC_FS" "FHANDLE" "CRYPTO_USER_API_HASH" "CRYPTO_HMAC"
|
||||
@ -1143,11 +549,6 @@ in
|
||||
"TMPFS_XATTR" "SECCOMP"
|
||||
];
|
||||
|
||||
users.groups.systemd-journal.gid = config.ids.gids.systemd-journal;
|
||||
users.users.systemd-journal-gateway.uid = config.ids.uids.systemd-journal-gateway;
|
||||
users.users.systemd-journal-gateway.group = "systemd-journal-gateway";
|
||||
users.groups.systemd-journal-gateway.gid = config.ids.gids.systemd-journal-gateway;
|
||||
|
||||
# Generate timer units for all services that have a ‘startAt’ value.
|
||||
systemd.timers =
|
||||
mapAttrs (name: service:
|
||||
@ -1164,42 +565,14 @@ in
|
||||
})
|
||||
(filterAttrs (name: service: service.startAt != []) cfg.user.services);
|
||||
|
||||
systemd.sockets.systemd-journal-gatewayd.wantedBy =
|
||||
optional config.services.journald.enableHttpGateway "sockets.target";
|
||||
|
||||
# Provide the systemd-user PAM service, required to run systemd
|
||||
# user instances.
|
||||
security.pam.services.systemd-user =
|
||||
{ # Ensure that pam_systemd gets included. This is special-cased
|
||||
# in systemd to provide XDG_RUNTIME_DIR.
|
||||
startSession = true;
|
||||
};
|
||||
|
||||
# Some overrides to upstream units.
|
||||
systemd.services."systemd-backlight@".restartIfChanged = false;
|
||||
systemd.services."systemd-fsck@".restartIfChanged = false;
|
||||
systemd.services."systemd-fsck@".path = [ config.system.path ];
|
||||
systemd.services."user@".restartIfChanged = false;
|
||||
systemd.services.systemd-journal-flush.restartIfChanged = false;
|
||||
systemd.services.systemd-random-seed.restartIfChanged = false;
|
||||
systemd.services.systemd-remount-fs.restartIfChanged = false;
|
||||
systemd.services.systemd-update-utmp.restartIfChanged = false;
|
||||
systemd.services.systemd-user-sessions.restartIfChanged = false; # Restart kills all active sessions.
|
||||
systemd.services.systemd-udev-settle.restartIfChanged = false; # Causes long delays in nixos-rebuild
|
||||
# Restarting systemd-logind breaks X11
|
||||
# - upstream commit: https://cgit.freedesktop.org/xorg/xserver/commit/?id=dc48bd653c7e101
|
||||
# - systemd announcement: https://github.com/systemd/systemd/blob/22043e4317ecd2bc7834b48a6d364de76bb26d91/NEWS#L103-L112
|
||||
# - this might be addressed in the future by xorg
|
||||
#systemd.services.systemd-logind.restartTriggers = [ config.environment.etc."systemd/logind.conf".source ];
|
||||
systemd.services.systemd-logind.restartIfChanged = false;
|
||||
systemd.services.systemd-logind.stopIfChanged = false;
|
||||
# The user-runtime-dir@ service is managed by systemd-logind we should not touch it or else we break the users' sessions.
|
||||
systemd.services."user-runtime-dir@".stopIfChanged = false;
|
||||
systemd.services."user-runtime-dir@".restartIfChanged = false;
|
||||
systemd.services.systemd-journald.restartTriggers = [ config.environment.etc."systemd/journald.conf".source ];
|
||||
systemd.services.systemd-journald.stopIfChanged = false;
|
||||
systemd.services."systemd-journald@".restartTriggers = [ config.environment.etc."systemd/journald.conf".source ];
|
||||
systemd.services."systemd-journald@".stopIfChanged = false;
|
||||
systemd.targets.local-fs.unitConfig.X-StopOnReconfiguration = true;
|
||||
systemd.targets.remote-fs.unitConfig.X-StopOnReconfiguration = true;
|
||||
systemd.targets.network-online.wantedBy = [ "multi-user.target" ];
|
||||
@ -1210,8 +583,6 @@ in
|
||||
systemd.services.systemd-remount-fs.unitConfig.ConditionVirtualization = "!container";
|
||||
systemd.services.systemd-random-seed.unitConfig.ConditionVirtualization = "!container";
|
||||
|
||||
boot.kernel.sysctl."kernel.core_pattern" = mkIf (!cfg.coredump.enable) "core";
|
||||
|
||||
# Increase numeric PID range (set directly instead of copying a one-line file from systemd)
|
||||
# https://github.com/systemd/systemd/pull/12226
|
||||
boot.kernel.sysctl."kernel.pid_max" = mkIf pkgs.stdenv.is64bit (lib.mkDefault 4194304);
|
||||
|
57
nixos/modules/system/boot/systemd/coredump.nix
Normal file
57
nixos/modules/system/boot/systemd/coredump.nix
Normal file
@ -0,0 +1,57 @@
|
||||
{ config, lib, pkgs, utils, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.systemd.coredump;
|
||||
systemd = config.systemd.package;
|
||||
in {
|
||||
options = {
|
||||
systemd.coredump.enable = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether core dumps should be processed by
|
||||
<command>systemd-coredump</command>. If disabled, core dumps
|
||||
appear in the current directory of the crashing process.
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.coredump.extraConfig = mkOption {
|
||||
default = "";
|
||||
type = types.lines;
|
||||
example = "Storage=journal";
|
||||
description = ''
|
||||
Extra config options for systemd-coredump. See coredump.conf(5) man page
|
||||
for available options.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
systemd.additionalUpstreamSystemUnits = [
|
||||
"systemd-coredump.socket"
|
||||
"systemd-coredump@.service"
|
||||
];
|
||||
|
||||
environment.etc = {
|
||||
"systemd/coredump.conf".text =
|
||||
''
|
||||
[Coredump]
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
|
||||
# install provided sysctl snippets
|
||||
"sysctl.d/50-coredump.conf".source = "${systemd}/example/sysctl.d/50-coredump.conf";
|
||||
"sysctl.d/50-default.conf".source = "${systemd}/example/sysctl.d/50-default.conf";
|
||||
};
|
||||
|
||||
users.users.systemd-coredump = {
|
||||
uid = config.ids.uids.systemd-coredump;
|
||||
group = "systemd-coredump";
|
||||
};
|
||||
users.groups.systemd-coredump = {};
|
||||
|
||||
boot.kernel.sysctl."kernel.core_pattern" = mkIf (!cfg.enable) "core";
|
||||
};
|
||||
}
|
131
nixos/modules/system/boot/systemd/journald.nix
Normal file
131
nixos/modules/system/boot/systemd/journald.nix
Normal file
@ -0,0 +1,131 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.journald;
|
||||
in {
|
||||
options = {
|
||||
services.journald.console = mkOption {
|
||||
default = "";
|
||||
type = types.str;
|
||||
description = "If non-empty, write log messages to the specified TTY device.";
|
||||
};
|
||||
|
||||
services.journald.rateLimitInterval = mkOption {
|
||||
default = "30s";
|
||||
type = types.str;
|
||||
description = ''
|
||||
Configures the rate limiting interval that is applied to all
|
||||
messages generated on the system. This rate limiting is applied
|
||||
per-service, so that two services which log do not interfere with
|
||||
each other's limit. The value may be specified in the following
|
||||
units: s, min, h, ms, us. To turn off any kind of rate limiting,
|
||||
set either value to 0.
|
||||
|
||||
See <option>services.journald.rateLimitBurst</option> for important
|
||||
considerations when setting this value.
|
||||
'';
|
||||
};
|
||||
|
||||
services.journald.rateLimitBurst = mkOption {
|
||||
default = 10000;
|
||||
type = types.int;
|
||||
description = ''
|
||||
Configures the rate limiting burst limit (number of messages per
|
||||
interval) that is applied to all messages generated on the system.
|
||||
This rate limiting is applied per-service, so that two services
|
||||
which log do not interfere with each other's limit.
|
||||
|
||||
Note that the effective rate limit is multiplied by a factor derived
|
||||
from the available free disk space for the journal as described on
|
||||
<link xlink:href="https://www.freedesktop.org/software/systemd/man/journald.conf.html">
|
||||
journald.conf(5)</link>.
|
||||
|
||||
Note that the total amount of logs stored is limited by journald settings
|
||||
such as <literal>SystemMaxUse</literal>, which defaults to a 4 GB cap.
|
||||
|
||||
It is thus recommended to compute what period of time that you will be
|
||||
able to store logs for when an application logs at full burst rate.
|
||||
With default settings for log lines that are 100 Bytes long, this can
|
||||
amount to just a few hours.
|
||||
'';
|
||||
};
|
||||
|
||||
services.journald.extraConfig = mkOption {
|
||||
default = "";
|
||||
type = types.lines;
|
||||
example = "Storage=volatile";
|
||||
description = ''
|
||||
Extra config options for systemd-journald. See man journald.conf
|
||||
for available options.
|
||||
'';
|
||||
};
|
||||
|
||||
services.journald.enableHttpGateway = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to enable the HTTP gateway to the journal.
|
||||
'';
|
||||
};
|
||||
|
||||
services.journald.forwardToSyslog = mkOption {
|
||||
default = config.services.rsyslogd.enable || config.services.syslog-ng.enable;
|
||||
defaultText = literalExpression "services.rsyslogd.enable || services.syslog-ng.enable";
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to forward log messages to syslog.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
systemd.additionalUpstreamSystemUnits = [
|
||||
"systemd-journald.socket"
|
||||
"systemd-journald@.socket"
|
||||
"systemd-journald-varlink@.socket"
|
||||
"systemd-journald.service"
|
||||
"systemd-journald@.service"
|
||||
"systemd-journal-flush.service"
|
||||
"systemd-journal-catalog-update.service"
|
||||
] ++ (optional (!config.boot.isContainer) "systemd-journald-audit.socket") ++ [
|
||||
"systemd-journald-dev-log.socket"
|
||||
"syslog.socket"
|
||||
] ++ optionals cfg.enableHttpGateway [
|
||||
"systemd-journal-gatewayd.socket"
|
||||
"systemd-journal-gatewayd.service"
|
||||
];
|
||||
|
||||
environment.etc = {
|
||||
"systemd/journald.conf".text = ''
|
||||
[Journal]
|
||||
Storage=persistent
|
||||
RateLimitInterval=${cfg.rateLimitInterval}
|
||||
RateLimitBurst=${toString cfg.rateLimitBurst}
|
||||
${optionalString (cfg.console != "") ''
|
||||
ForwardToConsole=yes
|
||||
TTYPath=${cfg.console}
|
||||
''}
|
||||
${optionalString (cfg.forwardToSyslog) ''
|
||||
ForwardToSyslog=yes
|
||||
''}
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
};
|
||||
|
||||
users.groups.systemd-journal.gid = config.ids.gids.systemd-journal;
|
||||
users.users.systemd-journal-gateway.uid = config.ids.uids.systemd-journal-gateway;
|
||||
users.users.systemd-journal-gateway.group = "systemd-journal-gateway";
|
||||
users.groups.systemd-journal-gateway.gid = config.ids.gids.systemd-journal-gateway;
|
||||
|
||||
systemd.sockets.systemd-journal-gatewayd.wantedBy =
|
||||
optional cfg.enableHttpGateway "sockets.target";
|
||||
|
||||
systemd.services.systemd-journal-flush.restartIfChanged = false;
|
||||
systemd.services.systemd-journald.restartTriggers = [ config.environment.etc."systemd/journald.conf".source ];
|
||||
systemd.services.systemd-journald.stopIfChanged = false;
|
||||
systemd.services."systemd-journald@".restartTriggers = [ config.environment.etc."systemd/journald.conf".source ];
|
||||
systemd.services."systemd-journald@".stopIfChanged = false;
|
||||
};
|
||||
}
|
114
nixos/modules/system/boot/systemd/logind.nix
Normal file
114
nixos/modules/system/boot/systemd/logind.nix
Normal file
@ -0,0 +1,114 @@
|
||||
{ config, lib, pkgs, utils, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.logind;
|
||||
|
||||
logindHandlerType = types.enum [
|
||||
"ignore" "poweroff" "reboot" "halt" "kexec" "suspend"
|
||||
"hibernate" "hybrid-sleep" "suspend-then-hibernate" "lock"
|
||||
];
|
||||
in
|
||||
{
|
||||
options = {
|
||||
services.logind.extraConfig = mkOption {
|
||||
default = "";
|
||||
type = types.lines;
|
||||
example = "IdleAction=lock";
|
||||
description = ''
|
||||
Extra config options for systemd-logind. See
|
||||
<link xlink:href="https://www.freedesktop.org/software/systemd/man/logind.conf.html">
|
||||
logind.conf(5)</link> for available options.
|
||||
'';
|
||||
};
|
||||
|
||||
services.logind.killUserProcesses = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Specifies whether the processes of a user should be killed
|
||||
when the user logs out. If true, the scope unit corresponding
|
||||
to the session and all processes inside that scope will be
|
||||
terminated. If false, the scope is "abandoned" (see
|
||||
<link xlink:href="https://www.freedesktop.org/software/systemd/man/systemd.scope.html#">
|
||||
systemd.scope(5)</link>), and processes are not killed.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
See <link xlink:href="https://www.freedesktop.org/software/systemd/man/logind.conf.html#KillUserProcesses=">logind.conf(5)</link>
|
||||
for more details.
|
||||
'';
|
||||
};
|
||||
|
||||
services.logind.lidSwitch = mkOption {
|
||||
default = "suspend";
|
||||
example = "ignore";
|
||||
type = logindHandlerType;
|
||||
|
||||
description = ''
|
||||
Specifies what to be done when the laptop lid is closed.
|
||||
'';
|
||||
};
|
||||
|
||||
services.logind.lidSwitchDocked = mkOption {
|
||||
default = "ignore";
|
||||
example = "suspend";
|
||||
type = logindHandlerType;
|
||||
|
||||
description = ''
|
||||
Specifies what to be done when the laptop lid is closed
|
||||
and another screen is added.
|
||||
'';
|
||||
};
|
||||
|
||||
services.logind.lidSwitchExternalPower = mkOption {
|
||||
default = cfg.lidSwitch;
|
||||
defaultText = literalExpression "services.logind.lidSwitch";
|
||||
example = "ignore";
|
||||
type = logindHandlerType;
|
||||
|
||||
description = ''
|
||||
Specifies what to do when the laptop lid is closed and the system is
|
||||
on external power. By default use the same action as specified in
|
||||
services.logind.lidSwitch.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
systemd.additionalUpstreamSystemUnits = [
|
||||
"systemd-logind.service"
|
||||
"autovt@.service"
|
||||
"systemd-user-sessions.service"
|
||||
"dbus-org.freedesktop.import1.service"
|
||||
"dbus-org.freedesktop.machine1.service"
|
||||
"dbus-org.freedesktop.login1.service"
|
||||
"user@.service"
|
||||
"user-runtime-dir@.service"
|
||||
];
|
||||
|
||||
environment.etc = {
|
||||
"systemd/logind.conf".text = ''
|
||||
[Login]
|
||||
KillUserProcesses=${if cfg.killUserProcesses then "yes" else "no"}
|
||||
HandleLidSwitch=${cfg.lidSwitch}
|
||||
HandleLidSwitchDocked=${cfg.lidSwitchDocked}
|
||||
HandleLidSwitchExternalPower=${cfg.lidSwitchExternalPower}
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
};
|
||||
|
||||
# Restarting systemd-logind breaks X11
|
||||
# - upstream commit: https://cgit.freedesktop.org/xorg/xserver/commit/?id=dc48bd653c7e101
|
||||
# - systemd announcement: https://github.com/systemd/systemd/blob/22043e4317ecd2bc7834b48a6d364de76bb26d91/NEWS#L103-L112
|
||||
# - this might be addressed in the future by xorg
|
||||
#systemd.services.systemd-logind.restartTriggers = [ config.environment.etc."systemd/logind.conf".source ];
|
||||
systemd.services.systemd-logind.restartIfChanged = false;
|
||||
systemd.services.systemd-logind.stopIfChanged = false;
|
||||
|
||||
# The user-runtime-dir@ service is managed by systemd-logind we should not touch it or else we break the users' sessions.
|
||||
systemd.services."user-runtime-dir@".stopIfChanged = false;
|
||||
systemd.services."user-runtime-dir@".restartIfChanged = false;
|
||||
};
|
||||
}
|
104
nixos/modules/system/boot/systemd/tmpfiles.nix
Normal file
104
nixos/modules/system/boot/systemd/tmpfiles.nix
Normal file
@ -0,0 +1,104 @@
|
||||
{ config, lib, pkgs, utils, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.systemd.tmpfiles;
|
||||
systemd = config.systemd.package;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
systemd.tmpfiles.rules = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
example = [ "d /tmp 1777 root root 10d" ];
|
||||
description = ''
|
||||
Rules for creation, deletion and cleaning of volatile and temporary files
|
||||
automatically. See
|
||||
<citerefentry><refentrytitle>tmpfiles.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||
for the exact format.
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.tmpfiles.packages = mkOption {
|
||||
type = types.listOf types.package;
|
||||
default = [];
|
||||
example = literalExpression "[ pkgs.lvm2 ]";
|
||||
apply = map getLib;
|
||||
description = ''
|
||||
List of packages containing <command>systemd-tmpfiles</command> rules.
|
||||
|
||||
All files ending in .conf found in
|
||||
<filename><replaceable>pkg</replaceable>/lib/tmpfiles.d</filename>
|
||||
will be included.
|
||||
If this folder does not exist or does not contain any files an error will be returned instead.
|
||||
|
||||
If a <filename>lib</filename> output is available, rules are searched there and only there.
|
||||
If there is no <filename>lib</filename> output it will fall back to <filename>out</filename>
|
||||
and if that does not exist either, the default output will be used.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
systemd.additionalUpstreamSystemUnits = [
|
||||
"systemd-tmpfiles-clean.service"
|
||||
"systemd-tmpfiles-clean.timer"
|
||||
"systemd-tmpfiles-setup.service"
|
||||
"systemd-tmpfiles-setup-dev.service"
|
||||
];
|
||||
|
||||
systemd.additionalUpstreamUserUnits = [
|
||||
"systemd-tmpfiles-clean.service"
|
||||
"systemd-tmpfiles-clean.timer"
|
||||
"systemd-tmpfiles-setup.service"
|
||||
];
|
||||
|
||||
environment.etc = {
|
||||
"tmpfiles.d".source = (pkgs.symlinkJoin {
|
||||
name = "tmpfiles.d";
|
||||
paths = map (p: p + "/lib/tmpfiles.d") cfg.packages;
|
||||
postBuild = ''
|
||||
for i in $(cat $pathsPath); do
|
||||
(test -d "$i" && test $(ls "$i"/*.conf | wc -l) -ge 1) || (
|
||||
echo "ERROR: The path '$i' from systemd.tmpfiles.packages contains no *.conf files."
|
||||
exit 1
|
||||
)
|
||||
done
|
||||
'' + concatMapStrings (name: optionalString (hasPrefix "tmpfiles.d/" name) ''
|
||||
rm -f $out/${removePrefix "tmpfiles.d/" name}
|
||||
'') config.system.build.etc.passthru.targets;
|
||||
}) + "/*";
|
||||
};
|
||||
|
||||
systemd.tmpfiles.packages = [
|
||||
# Default tmpfiles rules provided by systemd
|
||||
(pkgs.runCommand "systemd-default-tmpfiles" {} ''
|
||||
mkdir -p $out/lib/tmpfiles.d
|
||||
cd $out/lib/tmpfiles.d
|
||||
|
||||
ln -s "${systemd}/example/tmpfiles.d/home.conf"
|
||||
ln -s "${systemd}/example/tmpfiles.d/journal-nocow.conf"
|
||||
ln -s "${systemd}/example/tmpfiles.d/static-nodes-permissions.conf"
|
||||
ln -s "${systemd}/example/tmpfiles.d/systemd.conf"
|
||||
ln -s "${systemd}/example/tmpfiles.d/systemd-nologin.conf"
|
||||
ln -s "${systemd}/example/tmpfiles.d/systemd-nspawn.conf"
|
||||
ln -s "${systemd}/example/tmpfiles.d/systemd-tmp.conf"
|
||||
ln -s "${systemd}/example/tmpfiles.d/tmp.conf"
|
||||
ln -s "${systemd}/example/tmpfiles.d/var.conf"
|
||||
ln -s "${systemd}/example/tmpfiles.d/x11.conf"
|
||||
'')
|
||||
# User-specified tmpfiles rules
|
||||
(pkgs.writeTextFile {
|
||||
name = "nixos-tmpfiles.d";
|
||||
destination = "/lib/tmpfiles.d/00-nixos.conf";
|
||||
text = ''
|
||||
# This file is created automatically and should not be modified.
|
||||
# Please change the option ‘systemd.tmpfiles.rules’ instead.
|
||||
|
||||
${concatStringsSep "\n" cfg.rules}
|
||||
'';
|
||||
})
|
||||
];
|
||||
};
|
||||
}
|
158
nixos/modules/system/boot/systemd/user.nix
Normal file
158
nixos/modules/system/boot/systemd/user.nix
Normal file
@ -0,0 +1,158 @@
|
||||
{ config, lib, pkgs, utils, ... }:
|
||||
with utils;
|
||||
with systemdUtils.unitOptions;
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.systemd.user;
|
||||
|
||||
systemd = config.systemd.package;
|
||||
|
||||
inherit
|
||||
(systemdUtils.lib)
|
||||
makeUnit
|
||||
generateUnits
|
||||
makeJobScript
|
||||
unitConfig
|
||||
serviceConfig
|
||||
commonUnitText
|
||||
targetToUnit
|
||||
serviceToUnit
|
||||
socketToUnit
|
||||
timerToUnit
|
||||
pathToUnit;
|
||||
|
||||
upstreamUserUnits = [
|
||||
"app.slice"
|
||||
"background.slice"
|
||||
"basic.target"
|
||||
"bluetooth.target"
|
||||
"default.target"
|
||||
"exit.target"
|
||||
"graphical-session-pre.target"
|
||||
"graphical-session.target"
|
||||
"paths.target"
|
||||
"printer.target"
|
||||
"session.slice"
|
||||
"shutdown.target"
|
||||
"smartcard.target"
|
||||
"sockets.target"
|
||||
"sound.target"
|
||||
"systemd-exit.service"
|
||||
"timers.target"
|
||||
"xdg-desktop-autostart.target"
|
||||
] ++ config.systemd.additionalUpstreamUserUnits;
|
||||
in {
|
||||
options = {
|
||||
systemd.user.extraConfig = mkOption {
|
||||
default = "";
|
||||
type = types.lines;
|
||||
example = "DefaultCPUAccounting=yes";
|
||||
description = ''
|
||||
Extra config options for systemd user instances. See man systemd-user.conf for
|
||||
available options.
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.user.units = mkOption {
|
||||
description = "Definition of systemd per-user units.";
|
||||
default = {};
|
||||
type = with types; attrsOf (submodule (
|
||||
{ name, config, ... }:
|
||||
{ options = concreteUnitOptions;
|
||||
config = {
|
||||
unit = mkDefault (makeUnit name config);
|
||||
};
|
||||
}));
|
||||
};
|
||||
|
||||
systemd.user.paths = mkOption {
|
||||
default = {};
|
||||
type = with types; attrsOf (submodule [ { options = pathOptions; } unitConfig ]);
|
||||
description = "Definition of systemd per-user path units.";
|
||||
};
|
||||
|
||||
systemd.user.services = mkOption {
|
||||
default = {};
|
||||
type = with types; attrsOf (submodule [ { options = serviceOptions; } unitConfig serviceConfig ] );
|
||||
description = "Definition of systemd per-user service units.";
|
||||
};
|
||||
|
||||
systemd.user.slices = mkOption {
|
||||
default = {};
|
||||
type = with types; attrsOf (submodule [ { options = sliceOptions; } unitConfig ] );
|
||||
description = "Definition of systemd per-user slice units.";
|
||||
};
|
||||
|
||||
systemd.user.sockets = mkOption {
|
||||
default = {};
|
||||
type = with types; attrsOf (submodule [ { options = socketOptions; } unitConfig ] );
|
||||
description = "Definition of systemd per-user socket units.";
|
||||
};
|
||||
|
||||
systemd.user.targets = mkOption {
|
||||
default = {};
|
||||
type = with types; attrsOf (submodule [ { options = targetOptions; } unitConfig] );
|
||||
description = "Definition of systemd per-user target units.";
|
||||
};
|
||||
|
||||
systemd.user.timers = mkOption {
|
||||
default = {};
|
||||
type = with types; attrsOf (submodule [ { options = timerOptions; } unitConfig ] );
|
||||
description = "Definition of systemd per-user timer units.";
|
||||
};
|
||||
|
||||
systemd.additionalUpstreamUserUnits = mkOption {
|
||||
default = [];
|
||||
type = types.listOf types.str;
|
||||
example = [];
|
||||
description = ''
|
||||
Additional units shipped with systemd that should be enabled for per-user systemd instances.
|
||||
'';
|
||||
internal = true;
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
systemd.additionalUpstreamSystemUnits = [
|
||||
"user.slice"
|
||||
];
|
||||
|
||||
environment.etc = {
|
||||
"systemd/user".source = generateUnits "user" cfg.units upstreamUserUnits [];
|
||||
|
||||
"systemd/user.conf".text = ''
|
||||
[Manager]
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.user.units =
|
||||
mapAttrs' (n: v: nameValuePair "${n}.path" (pathToUnit n v)) cfg.paths
|
||||
// mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.services
|
||||
// mapAttrs' (n: v: nameValuePair "${n}.slice" (sliceToUnit n v)) cfg.slices
|
||||
// mapAttrs' (n: v: nameValuePair "${n}.socket" (socketToUnit n v)) cfg.sockets
|
||||
// mapAttrs' (n: v: nameValuePair "${n}.target" (targetToUnit n v)) cfg.targets
|
||||
// mapAttrs' (n: v: nameValuePair "${n}.timer" (timerToUnit n v)) cfg.timers;
|
||||
|
||||
# Generate timer units for all services that have a ‘startAt’ value.
|
||||
systemd.user.timers =
|
||||
mapAttrs (name: service: {
|
||||
wantedBy = ["timers.target"];
|
||||
timerConfig.OnCalendar = service.startAt;
|
||||
})
|
||||
(filterAttrs (name: service: service.startAt != []) cfg.services);
|
||||
|
||||
# Provide the systemd-user PAM service, required to run systemd
|
||||
# user instances.
|
||||
security.pam.services.systemd-user =
|
||||
{ # Ensure that pam_systemd gets included. This is special-cased
|
||||
# in systemd to provide XDG_RUNTIME_DIR.
|
||||
startSession = true;
|
||||
};
|
||||
|
||||
# Some overrides to upstream units.
|
||||
systemd.services."user@".restartIfChanged = false;
|
||||
systemd.services.systemd-user-sessions.restartIfChanged = false; # Restart kills all active sessions.
|
||||
};
|
||||
}
|
@ -80,6 +80,7 @@ in {
|
||||
Reboot the system into the new generation instead of a switch
|
||||
if the new generation uses a different kernel, kernel modules
|
||||
or initrd than the booted system.
|
||||
See <option>rebootWindow</option> for configuring the times at which a reboot is allowed.
|
||||
'';
|
||||
};
|
||||
|
||||
@ -96,6 +97,32 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
rebootWindow = mkOption {
|
||||
description = ''
|
||||
Define a lower and upper time value (in HH:MM format) which
|
||||
constitute a time window during which reboots are allowed after an upgrade.
|
||||
This option only has an effect when <option>allowReboot</option> is enabled.
|
||||
The default value of <literal>null</literal> means that reboots are allowed at any time.
|
||||
'';
|
||||
default = null;
|
||||
example = { lower = "01:00"; upper = "05:00"; };
|
||||
type = with types; nullOr (submodule {
|
||||
options = {
|
||||
lower = mkOption {
|
||||
description = "Lower limit of the reboot window";
|
||||
type = types.strMatching "[[:digit:]]{2}:[[:digit:]]{2}";
|
||||
example = "01:00";
|
||||
};
|
||||
|
||||
upper = mkOption {
|
||||
description = "Upper limit of the reboot window";
|
||||
type = types.strMatching "[[:digit:]]{2}:[[:digit:]]{2}";
|
||||
example = "05:00";
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
@ -110,12 +137,10 @@ in {
|
||||
}];
|
||||
|
||||
system.autoUpgrade.flags = (if cfg.flake == null then
|
||||
[ "--no-build-output" ] ++ (if cfg.channel == null then
|
||||
[ "--upgrade" ]
|
||||
else [
|
||||
[ "--no-build-output" ] ++ optionals (cfg.channel != null) [
|
||||
"-I"
|
||||
"nixpkgs=${cfg.channel}/nixexprs.tar.xz"
|
||||
])
|
||||
]
|
||||
else
|
||||
[ "--flake ${cfg.flake}" ]);
|
||||
|
||||
@ -143,19 +168,52 @@ in {
|
||||
];
|
||||
|
||||
script = let
|
||||
nixos-rebuild =
|
||||
"${config.system.build.nixos-rebuild}/bin/nixos-rebuild";
|
||||
nixos-rebuild = "${config.system.build.nixos-rebuild}/bin/nixos-rebuild";
|
||||
date = "${pkgs.coreutils}/bin/date";
|
||||
readlink = "${pkgs.coreutils}/bin/readlink";
|
||||
shutdown = "${pkgs.systemd}/bin/shutdown";
|
||||
upgradeFlag = optional (cfg.channel == null) "--upgrade";
|
||||
in if cfg.allowReboot then ''
|
||||
${nixos-rebuild} boot ${toString cfg.flags}
|
||||
booted="$(readlink /run/booted-system/{initrd,kernel,kernel-modules})"
|
||||
built="$(readlink /nix/var/nix/profiles/system/{initrd,kernel,kernel-modules})"
|
||||
if [ "$booted" = "$built" ]; then
|
||||
${nixos-rebuild} boot ${toString (cfg.flags ++ upgradeFlag)}
|
||||
booted="$(${readlink} /run/booted-system/{initrd,kernel,kernel-modules})"
|
||||
built="$(${readlink} /nix/var/nix/profiles/system/{initrd,kernel,kernel-modules})"
|
||||
|
||||
${optionalString (cfg.rebootWindow != null) ''
|
||||
current_time="$(${date} +%H:%M)"
|
||||
|
||||
lower="${cfg.rebootWindow.lower}"
|
||||
upper="${cfg.rebootWindow.upper}"
|
||||
|
||||
if [[ "''${lower}" < "''${upper}" ]]; then
|
||||
if [[ "''${current_time}" > "''${lower}" ]] && \
|
||||
[[ "''${current_time}" < "''${upper}" ]]; then
|
||||
do_reboot="true"
|
||||
else
|
||||
do_reboot="false"
|
||||
fi
|
||||
else
|
||||
# lower > upper, so we are crossing midnight (e.g. lower=23h, upper=6h)
|
||||
# we want to reboot if cur > 23h or cur < 6h
|
||||
if [[ "''${current_time}" < "''${upper}" ]] || \
|
||||
[[ "''${current_time}" > "''${lower}" ]]; then
|
||||
do_reboot="true"
|
||||
else
|
||||
do_reboot="false"
|
||||
fi
|
||||
fi
|
||||
''}
|
||||
|
||||
if [ "''${booted}" = "''${built}" ]; then
|
||||
${nixos-rebuild} switch ${toString cfg.flags}
|
||||
${optionalString (cfg.rebootWindow != null) ''
|
||||
elif [ "''${do_reboot}" != true ]; then
|
||||
echo "Outside of configured reboot window, skipping."
|
||||
''}
|
||||
else
|
||||
/run/current-system/sw/bin/shutdown -r +1
|
||||
${shutdown} -r +1
|
||||
fi
|
||||
'' else ''
|
||||
${nixos-rebuild} switch ${toString cfg.flags}
|
||||
${nixos-rebuild} switch ${toString (cfg.flags ++ upgradeFlag)}
|
||||
'';
|
||||
|
||||
startAt = cfg.dates;
|
||||
@ -167,3 +225,4 @@ in {
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
@ -1021,6 +1021,12 @@ in
|
||||
dev = "enp4s0f0";
|
||||
type = "tap";
|
||||
};
|
||||
gre6Tunnel = {
|
||||
remote = "fd7a:5634::1";
|
||||
local = "fd7a:5634::2";
|
||||
dev = "enp4s0f0";
|
||||
type = "tun6";
|
||||
};
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
@ -1058,10 +1064,15 @@ in
|
||||
};
|
||||
|
||||
type = mkOption {
|
||||
type = with types; enum [ "tun" "tap" ];
|
||||
type = with types; enum [ "tun" "tap" "tun6" "tap6" ];
|
||||
default = "tap";
|
||||
example = "tap";
|
||||
apply = v: if v == "tun" then "gre" else "gretap";
|
||||
apply = v: {
|
||||
tun = "gre";
|
||||
tap = "gretap";
|
||||
tun6 = "ip6gre";
|
||||
tap6 = "ip6gretap";
|
||||
}.${v};
|
||||
description = ''
|
||||
Whether the tunnel routes layer 2 (tap) or layer 3 (tun) traffic.
|
||||
'';
|
||||
|
@ -286,6 +286,7 @@ in
|
||||
mailhog = handleTest ./mailhog.nix {};
|
||||
man = handleTest ./man.nix {};
|
||||
mariadb-galera = handleTest ./mysql/mariadb-galera.nix {};
|
||||
mastodon = handleTestOn ["x86_64-linux" "i686-linux" "aarch64-linux"] ./web-apps/mastodon.nix {};
|
||||
matomo = handleTest ./matomo.nix {};
|
||||
matrix-appservice-irc = handleTest ./matrix-appservice-irc.nix {};
|
||||
matrix-conduit = handleTest ./matrix-conduit.nix {};
|
||||
@ -355,6 +356,7 @@ in
|
||||
nginx-sso = handleTest ./nginx-sso.nix {};
|
||||
nginx-variants = handleTest ./nginx-variants.nix {};
|
||||
nitter = handleTest ./nitter.nix {};
|
||||
nix-ld = handleTest ./nix-ld {};
|
||||
nix-serve = handleTest ./nix-serve.nix {};
|
||||
nix-serve-ssh = handleTest ./nix-serve-ssh.nix {};
|
||||
nixops = handleTest ./nixops/default.nix {};
|
||||
@ -521,6 +523,7 @@ in
|
||||
telegraf = handleTest ./telegraf.nix {};
|
||||
teleport = handleTest ./teleport.nix {};
|
||||
thelounge = handleTest ./thelounge.nix {};
|
||||
terminal-emulators = handleTest ./terminal-emulators.nix {};
|
||||
tiddlywiki = handleTest ./tiddlywiki.nix {};
|
||||
tigervnc = handleTest ./tigervnc.nix {};
|
||||
timezone = handleTest ./timezone.nix {};
|
||||
|
@ -15,20 +15,54 @@ import ./make-test-python.nix ({ pkgs, ...} :
|
||||
];
|
||||
|
||||
services.xserver.enable = true;
|
||||
|
||||
# Regression test for https://github.com/NixOS/nixpkgs/issues/163482
|
||||
qt5 = {
|
||||
enable = true;
|
||||
platformTheme = "gnome";
|
||||
style = "adwaita-dark";
|
||||
};
|
||||
|
||||
test-support.displayManager.auto.user = "alice";
|
||||
environment.systemPackages = [ pkgs.keepassxc ];
|
||||
environment.systemPackages = with pkgs; [
|
||||
keepassxc
|
||||
xdotool
|
||||
];
|
||||
};
|
||||
|
||||
enableOCR = true;
|
||||
|
||||
testScript = { nodes, ... }: ''
|
||||
start_all()
|
||||
machine.wait_for_x()
|
||||
testScript = { nodes, ... }: let
|
||||
aliceDo = cmd: ''machine.succeed("su - alice -c '${cmd}' >&2 &");'';
|
||||
in ''
|
||||
with subtest("Ensure X starts"):
|
||||
start_all()
|
||||
machine.wait_for_x()
|
||||
|
||||
# start KeePassXC window
|
||||
machine.execute("su - alice -c keepassxc >&2 &")
|
||||
with subtest("Can create database and entry with CLI"):
|
||||
${aliceDo "keepassxc-cli db-create -k foo.keyfile foo.kdbx"}
|
||||
${aliceDo "keepassxc-cli add --no-password -k foo.keyfile foo.kdbx bar"}
|
||||
|
||||
machine.wait_for_text("KeePassXC ${pkgs.keepassxc.version}")
|
||||
machine.screenshot("KeePassXC")
|
||||
with subtest("Ensure KeePassXC starts"):
|
||||
# start KeePassXC window
|
||||
${aliceDo "keepassxc >&2 &"}
|
||||
|
||||
machine.wait_for_text("KeePassXC ${pkgs.keepassxc.version}")
|
||||
machine.screenshot("KeePassXC")
|
||||
|
||||
with subtest("Can open existing database"):
|
||||
machine.send_key("ctrl-o")
|
||||
machine.sleep(5)
|
||||
# Regression #163482: keepassxc did not crash
|
||||
machine.succeed("ps -e | grep keepassxc")
|
||||
machine.wait_for_text("foo.kdbx")
|
||||
machine.send_key("ret")
|
||||
machine.sleep(1)
|
||||
# Click on "Browse" button to select keyfile
|
||||
machine.send_key("tab")
|
||||
machine.send_chars("/home/alice/foo.keyfile")
|
||||
machine.send_key("ret")
|
||||
# Passwords folder is displayed
|
||||
machine.wait_for_text("Passwords")
|
||||
'';
|
||||
})
|
||||
|
@ -498,6 +498,7 @@ let
|
||||
networking = {
|
||||
useNetworkd = networkd;
|
||||
useDHCP = false;
|
||||
firewall.extraCommands = "ip6tables -A nixos-fw -p gre -j nixos-fw-accept";
|
||||
};
|
||||
};
|
||||
in {
|
||||
@ -506,7 +507,7 @@ let
|
||||
mkMerge [
|
||||
(node args)
|
||||
{
|
||||
virtualisation.vlans = [ 1 2 ];
|
||||
virtualisation.vlans = [ 1 2 4 ];
|
||||
networking = {
|
||||
greTunnels = {
|
||||
greTunnel = {
|
||||
@ -515,12 +516,24 @@ let
|
||||
dev = "eth2";
|
||||
type = "tap";
|
||||
};
|
||||
gre6Tunnel = {
|
||||
local = "fd00:1234:5678:4::1";
|
||||
remote = "fd00:1234:5678:4::2";
|
||||
dev = "eth3";
|
||||
type = "tun6";
|
||||
};
|
||||
};
|
||||
bridges.bridge.interfaces = [ "greTunnel" "eth1" ];
|
||||
interfaces.eth1.ipv4.addresses = mkOverride 0 [];
|
||||
interfaces.bridge.ipv4.addresses = mkOverride 0 [
|
||||
{ address = "192.168.1.1"; prefixLength = 24; }
|
||||
];
|
||||
interfaces.eth3.ipv6.addresses = [
|
||||
{ address = "fd00:1234:5678:4::1"; prefixLength = 64; }
|
||||
];
|
||||
interfaces.gre6Tunnel.ipv6.addresses = mkOverride 0 [
|
||||
{ address = "fc00::1"; prefixLength = 64; }
|
||||
];
|
||||
};
|
||||
}
|
||||
];
|
||||
@ -528,7 +541,7 @@ let
|
||||
mkMerge [
|
||||
(node args)
|
||||
{
|
||||
virtualisation.vlans = [ 2 3 ];
|
||||
virtualisation.vlans = [ 2 3 4 ];
|
||||
networking = {
|
||||
greTunnels = {
|
||||
greTunnel = {
|
||||
@ -537,12 +550,24 @@ let
|
||||
dev = "eth1";
|
||||
type = "tap";
|
||||
};
|
||||
gre6Tunnel = {
|
||||
local = "fd00:1234:5678:4::2";
|
||||
remote = "fd00:1234:5678:4::1";
|
||||
dev = "eth3";
|
||||
type = "tun6";
|
||||
};
|
||||
};
|
||||
bridges.bridge.interfaces = [ "greTunnel" "eth2" ];
|
||||
interfaces.eth2.ipv4.addresses = mkOverride 0 [];
|
||||
interfaces.bridge.ipv4.addresses = mkOverride 0 [
|
||||
{ address = "192.168.1.2"; prefixLength = 24; }
|
||||
];
|
||||
interfaces.eth3.ipv6.addresses = [
|
||||
{ address = "fd00:1234:5678:4::2"; prefixLength = 64; }
|
||||
];
|
||||
interfaces.gre6Tunnel.ipv6.addresses = mkOverride 0 [
|
||||
{ address = "fc00::2"; prefixLength = 64; }
|
||||
];
|
||||
};
|
||||
}
|
||||
];
|
||||
@ -562,6 +587,10 @@ let
|
||||
client1.wait_until_succeeds("ping -c 1 192.168.1.2")
|
||||
|
||||
client2.wait_until_succeeds("ping -c 1 192.168.1.1")
|
||||
|
||||
client1.wait_until_succeeds("ping -c 1 fc00::2")
|
||||
|
||||
client2.wait_until_succeeds("ping -c 1 fc00::1")
|
||||
'';
|
||||
};
|
||||
vlan = let
|
||||
|
@ -18,4 +18,4 @@ foldl
|
||||
};
|
||||
})
|
||||
{ }
|
||||
[ 21 22 23 ]
|
||||
[ 22 23 ]
|
||||
|
20
nixos/tests/nix-ld.nix
Normal file
20
nixos/tests/nix-ld.nix
Normal file
@ -0,0 +1,20 @@
|
||||
import ./make-test-python.nix ({ lib, pkgs, ...} :
|
||||
{
|
||||
name = "nix-ld";
|
||||
nodes.machine = { pkgs, ... }: {
|
||||
programs.nix-ld.enable = true;
|
||||
environment.systemPackages = [
|
||||
(pkgs.runCommand "patched-hello" {} ''
|
||||
install -D -m755 ${pkgs.hello}/bin/hello $out/bin/hello
|
||||
patchelf $out/bin/hello --set-interpreter ${pkgs.nix-ld.ldPath}
|
||||
'')
|
||||
];
|
||||
};
|
||||
testScript = ''
|
||||
start_all()
|
||||
path = "${pkgs.stdenv.cc}/nix-support/dynamic-linker"
|
||||
with open(path) as f:
|
||||
real_ld = f.read().strip()
|
||||
machine.succeed(f"NIX_LD={real_ld} hello")
|
||||
'';
|
||||
})
|
@ -32,8 +32,7 @@ import ./make-test-python.nix ({ pkgs, ... }:
|
||||
# system one. Overriding this pretty bad default behaviour.
|
||||
export REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt
|
||||
|
||||
export TOOT_LOGIN_CLI_PASSWORD="jamy-password"
|
||||
toot login_cli -i "pleroma.nixos.test" -e "jamy@nixos.test"
|
||||
echo "jamy-password" | toot login_cli -i "pleroma.nixos.test" -e "jamy@nixos.test"
|
||||
echo "Login OK"
|
||||
|
||||
# Send a toot then verify it's part of the public timeline
|
||||
@ -168,21 +167,6 @@ import ./make-test-python.nix ({ pkgs, ... }:
|
||||
cp key.pem cert.pem $out
|
||||
'';
|
||||
|
||||
/* Toot is preventing users from feeding login_cli a password non
|
||||
interactively. While it makes sense most of the times, it's
|
||||
preventing us to login in this non-interactive test. This patch
|
||||
introduce a TOOT_LOGIN_CLI_PASSWORD env variable allowing us to
|
||||
provide a password to toot login_cli
|
||||
|
||||
If https://github.com/ihabunek/toot/pull/180 gets merged at some
|
||||
point, feel free to remove this patch. */
|
||||
custom-toot = pkgs.toot.overrideAttrs(old:{
|
||||
patches = [ (pkgs.fetchpatch {
|
||||
url = "https://github.com/NinjaTrappeur/toot/commit/b4a4c30f41c0cb7e336714c2c4af9bc9bfa0c9f2.patch";
|
||||
sha256 = "sha256-0xxNwjR/fStLjjUUhwzCCfrghRVts+fc+fvVJqVcaFg=";
|
||||
}) ];
|
||||
});
|
||||
|
||||
hosts = nodes: ''
|
||||
${nodes.pleroma.config.networking.primaryIPAddress} pleroma.nixos.test
|
||||
${nodes.client.config.networking.primaryIPAddress} client.nixos.test
|
||||
@ -194,7 +178,7 @@ import ./make-test-python.nix ({ pkgs, ... }:
|
||||
security.pki.certificateFiles = [ "${tls-cert}/cert.pem" ];
|
||||
networking.extraHosts = hosts nodes;
|
||||
environment.systemPackages = with pkgs; [
|
||||
custom-toot
|
||||
toot
|
||||
send-toot
|
||||
];
|
||||
};
|
||||
|
@ -51,6 +51,12 @@ in {
|
||||
environment.systemPackages = [ pkgs.socat ]; # for the socket activation stuff
|
||||
users.mutableUsers = false;
|
||||
|
||||
# For boot/switch testing
|
||||
system.build.installBootLoader = lib.mkForce (pkgs.writeShellScript "install-dummy-loader" ''
|
||||
echo "installing dummy bootloader"
|
||||
touch /tmp/bootloader-installed
|
||||
'');
|
||||
|
||||
specialisation = rec {
|
||||
simpleService.configuration = {
|
||||
systemd.services.test = {
|
||||
@ -502,10 +508,33 @@ in {
|
||||
machine.succeed(
|
||||
"${stderrRunner} ${originalSystem}/bin/switch-to-configuration test"
|
||||
)
|
||||
# This tests whether the /etc/os-release parser works which is a fallback
|
||||
# when /etc/NIXOS is missing. If the parser does not work, switch-to-configuration
|
||||
# would fail.
|
||||
machine.succeed("rm /etc/NIXOS")
|
||||
machine.succeed(
|
||||
"${stderrRunner} ${otherSystem}/bin/switch-to-configuration test"
|
||||
)
|
||||
|
||||
|
||||
with subtest("actions"):
|
||||
# boot action
|
||||
machine.fail("test -f /tmp/bootloader-installed")
|
||||
out = switch_to_specialisation("${machine}", "simpleService", action="boot")
|
||||
assert_contains(out, "installing dummy bootloader")
|
||||
assert_lacks(out, "activating the configuration...") # good indicator of a system activation
|
||||
machine.succeed("test -f /tmp/bootloader-installed")
|
||||
machine.succeed("rm /tmp/bootloader-installed")
|
||||
|
||||
# switch action
|
||||
machine.fail("test -f /tmp/bootloader-installed")
|
||||
out = switch_to_specialisation("${machine}", "", action="switch")
|
||||
assert_contains(out, "installing dummy bootloader")
|
||||
assert_contains(out, "activating the configuration...") # good indicator of a system activation
|
||||
machine.succeed("test -f /tmp/bootloader-installed")
|
||||
|
||||
# test and dry-activate actions are tested further down below
|
||||
|
||||
with subtest("services"):
|
||||
switch_to_specialisation("${machine}", "")
|
||||
# Nothing happens when nothing is changed
|
||||
@ -519,6 +548,7 @@ in {
|
||||
|
||||
# Start a simple service
|
||||
out = switch_to_specialisation("${machine}", "simpleService")
|
||||
assert_lacks(out, "installing dummy bootloader") # test does not install a bootloader
|
||||
assert_lacks(out, "stopping the following units:")
|
||||
assert_lacks(out, "NOT restarting the following changed units:")
|
||||
assert_contains(out, "reloading the following units: dbus.service\n") # huh
|
||||
|
207
nixos/tests/terminal-emulators.nix
Normal file
207
nixos/tests/terminal-emulators.nix
Normal file
@ -0,0 +1,207 @@
|
||||
# Terminal emulators all present a pretty similar interface.
|
||||
# That gives us an opportunity to easily test their basic functionality with a single codebase.
|
||||
#
|
||||
# There are two tests run on each terminal emulator
|
||||
# - can it successfully execute a command passed on the cmdline?
|
||||
# - can it successfully display a colour?
|
||||
# the latter is used as a proxy for "can it display text?", without going through all the intricacies of OCR.
|
||||
#
|
||||
# 256-colour terminal mode is used to display the test colour, since it has a universally-applicable palette (unlike 8- and 16- colour, where the colours are implementation-defined), and it is widely supported (unlike 24-bit colour).
|
||||
#
|
||||
# Future work:
|
||||
# - Wayland support (both for testing the existing terminals, and for testing wayland-only terminals like foot and havoc)
|
||||
# - Test keyboard input? (skipped for now, to eliminate the possibility of race conditions and focus issues)
|
||||
|
||||
{ system ? builtins.currentSystem,
|
||||
config ? {},
|
||||
pkgs ? import ../.. { inherit system config; }
|
||||
}:
|
||||
|
||||
with import ../lib/testing-python.nix { inherit system pkgs; };
|
||||
with pkgs.lib;
|
||||
|
||||
let tests = {
|
||||
alacritty.pkg = p: p.alacritty;
|
||||
|
||||
contour.pkg = p: p.contour;
|
||||
contour.cmd = "contour $command";
|
||||
|
||||
cool-retro-term.pkg = p: p.cool-retro-term;
|
||||
cool-retro-term.colourTest = false; # broken by gloss effect
|
||||
|
||||
ctx.pkg = p: p.ctx;
|
||||
ctx.pinkValue = "#FE0065";
|
||||
|
||||
darktile.pkg = p: p.darktile;
|
||||
|
||||
eterm.pkg = p: p.eterm;
|
||||
eterm.executable = "Eterm";
|
||||
eterm.pinkValue = "#D40055";
|
||||
|
||||
germinal.pkg = p: p.germinal;
|
||||
|
||||
gnome-terminal.pkg = p: p.gnome.gnome-terminal;
|
||||
|
||||
guake.pkg = p: p.guake;
|
||||
guake.cmd = "SHELL=$command guake --show";
|
||||
guake.kill = true;
|
||||
|
||||
hyper.pkg = p: p.hyper;
|
||||
|
||||
kermit.pkg = p: p.kermit-terminal;
|
||||
|
||||
kgx.pkg = p: p.kgx;
|
||||
kgx.cmd = "kgx -e $command";
|
||||
kgx.kill = true;
|
||||
|
||||
kitty.pkg = p: p.kitty;
|
||||
kitty.cmd = "kitty $command";
|
||||
|
||||
konsole.pkg = p: p.plasma5Packages.konsole;
|
||||
|
||||
lxterminal.pkg = p: p.lxterminal;
|
||||
|
||||
mate-terminal.pkg = p: p.mate.mate-terminal;
|
||||
mate-terminal.cmd = "SHELL=$command mate-terminal --disable-factory"; # factory mode uses dbus, and we don't have a proper dbus session set up
|
||||
|
||||
mlterm.pkg = p: p.mlterm;
|
||||
|
||||
mrxvt.pkg = p: p.mrxvt;
|
||||
|
||||
qterminal.pkg = p: p.lxqt.qterminal;
|
||||
qterminal.kill = true;
|
||||
|
||||
roxterm.pkg = p: p.roxterm;
|
||||
roxterm.cmd = "roxterm -e $command";
|
||||
|
||||
sakura.pkg = p: p.sakura;
|
||||
|
||||
st.pkg = p: p.st;
|
||||
st.kill = true;
|
||||
|
||||
stupidterm.pkg = p: p.stupidterm;
|
||||
stupidterm.cmd = "stupidterm -- $command";
|
||||
|
||||
terminator.pkg = p: p.terminator;
|
||||
terminator.cmd = "terminator -e $command";
|
||||
|
||||
terminology.pkg = p: p.enlightenment.terminology;
|
||||
terminology.cmd = "SHELL=$command terminology --no-wizard=true";
|
||||
terminology.colourTest = false; # broken by gloss effect
|
||||
|
||||
termite.pkg = p: p.termite;
|
||||
|
||||
termonad.pkg = p: p.termonad;
|
||||
|
||||
tilda.pkg = p: p.tilda;
|
||||
|
||||
tilix.pkg = p: p.tilix;
|
||||
tilix.cmd = "tilix -e $command";
|
||||
|
||||
urxvt.pkg = p: p.rxvt-unicode;
|
||||
|
||||
wayst.pkg = p: p.wayst;
|
||||
wayst.pinkValue = "#FF0066";
|
||||
|
||||
wezterm.pkg = p: p.wezterm;
|
||||
|
||||
xfce4-terminal.pkg = p: p.xfce.xfce4-terminal;
|
||||
|
||||
xterm.pkg = p: p.xterm;
|
||||
};
|
||||
in mapAttrs (name: { pkg, executable ? name, cmd ? "SHELL=$command ${executable}", colourTest ? true, pinkValue ? "#FF0087", kill ? false }: makeTest
|
||||
{
|
||||
name = "terminal-emulator-${name}";
|
||||
meta = with pkgs.stdenv.lib.maintainers; {
|
||||
maintainers = [ jjjollyjim ];
|
||||
};
|
||||
|
||||
machine = { pkgsInner, ... }:
|
||||
|
||||
{
|
||||
imports = [ ./common/x11.nix ./common/user-account.nix ];
|
||||
|
||||
# Hyper (and any other electron-based terminals) won't run as root
|
||||
test-support.displayManager.auto.user = "alice";
|
||||
|
||||
environment.systemPackages = [
|
||||
(pkg pkgs)
|
||||
(pkgs.writeShellScriptBin "report-success" ''
|
||||
echo 1 > /tmp/term-ran-successfully
|
||||
${optionalString kill "pkill ${executable}"}
|
||||
'')
|
||||
(pkgs.writeShellScriptBin "display-colour" ''
|
||||
# A 256-colour background colour code for pink, then spaces.
|
||||
#
|
||||
# Background is used rather than foreground to minimize the effect of anti-aliasing.
|
||||
#
|
||||
# Keep adding more in case the window is partially offscreen to the left or requires
|
||||
# a change to correctly redraw after initialising the window (as with ctx).
|
||||
|
||||
while :
|
||||
do
|
||||
echo -ne "\e[48;5;198m "
|
||||
sleep 0.5
|
||||
done
|
||||
sleep infinity
|
||||
'')
|
||||
(pkgs.writeShellScriptBin "run-in-this-term" "sudo -u alice run-in-this-term-wrapped $1")
|
||||
|
||||
(pkgs.writeShellScriptBin "run-in-this-term-wrapped" "command=\"$(which \"$1\")\"; ${cmd}")
|
||||
];
|
||||
|
||||
# Helpful reminder to add this test to passthru.tests
|
||||
warnings = if !((pkg pkgs) ? "passthru" && (pkg pkgs).passthru ? "tests") then [ "The package for ${name} doesn't have a passthru.tests" ] else [ ];
|
||||
};
|
||||
|
||||
# We need imagemagick, though not tesseract
|
||||
enableOCR = true;
|
||||
|
||||
testScript = { nodes, ... }: let
|
||||
in ''
|
||||
with subtest("wait for x"):
|
||||
start_all()
|
||||
machine.wait_for_x()
|
||||
|
||||
with subtest("have the terminal run a command"):
|
||||
# We run this command synchronously, so we can be certain the exit codes are happy
|
||||
machine.${if kill then "execute" else "succeed"}("run-in-this-term report-success")
|
||||
machine.wait_for_file("/tmp/term-ran-successfully")
|
||||
${optionalString colourTest ''
|
||||
|
||||
import tempfile
|
||||
import subprocess
|
||||
|
||||
|
||||
def check_for_pink(final=False) -> bool:
|
||||
with tempfile.NamedTemporaryFile() as tmpin:
|
||||
machine.send_monitor_command("screendump {}".format(tmpin.name))
|
||||
|
||||
cmd = 'convert {} -define histogram:unique-colors=true -format "%c" histogram:info:'.format(
|
||||
tmpin.name
|
||||
)
|
||||
ret = subprocess.run(cmd, shell=True, capture_output=True)
|
||||
if ret.returncode != 0:
|
||||
raise Exception(
|
||||
"image analysis failed with exit code {}".format(ret.returncode)
|
||||
)
|
||||
|
||||
text = ret.stdout.decode("utf-8")
|
||||
return "${pinkValue}" in text
|
||||
|
||||
|
||||
with subtest("ensuring no pink is present without the terminal"):
|
||||
assert (
|
||||
check_for_pink() == False
|
||||
), "Pink was present on the screen before we even launched a terminal!"
|
||||
|
||||
with subtest("have the terminal display a colour"):
|
||||
# We run this command in the background
|
||||
machine.shell.send(b"(run-in-this-term display-colour |& systemd-cat -t terminal) &\n")
|
||||
|
||||
with machine.nested("Waiting for the screen to have pink on it:"):
|
||||
retry(check_for_pink)
|
||||
''}'';
|
||||
}
|
||||
|
||||
) tests
|
170
nixos/tests/web-apps/mastodon.nix
Normal file
170
nixos/tests/web-apps/mastodon.nix
Normal file
@ -0,0 +1,170 @@
|
||||
import ../make-test-python.nix ({pkgs, ...}:
|
||||
let
|
||||
test-certificates = pkgs.runCommandLocal "test-certificates" { } ''
|
||||
mkdir -p $out
|
||||
echo insecure-root-password > $out/root-password-file
|
||||
echo insecure-intermediate-password > $out/intermediate-password-file
|
||||
${pkgs.step-cli}/bin/step certificate create "Example Root CA" $out/root_ca.crt $out/root_ca.key --password-file=$out/root-password-file --profile root-ca
|
||||
${pkgs.step-cli}/bin/step certificate create "Example Intermediate CA 1" $out/intermediate_ca.crt $out/intermediate_ca.key --password-file=$out/intermediate-password-file --ca-password-file=$out/root-password-file --profile intermediate-ca --ca $out/root_ca.crt --ca-key $out/root_ca.key
|
||||
'';
|
||||
|
||||
hosts = ''
|
||||
192.168.2.10 ca.local
|
||||
192.168.2.11 mastodon.local
|
||||
'';
|
||||
|
||||
in
|
||||
{
|
||||
name = "mastodon";
|
||||
meta.maintainers = with pkgs.lib.maintainers; [ erictapen izorkin ];
|
||||
|
||||
nodes = {
|
||||
ca = { pkgs, ... }: {
|
||||
networking = {
|
||||
interfaces.eth1 = {
|
||||
ipv4.addresses = [
|
||||
{ address = "192.168.2.10"; prefixLength = 24; }
|
||||
];
|
||||
};
|
||||
extraHosts = hosts;
|
||||
};
|
||||
services.step-ca = {
|
||||
enable = true;
|
||||
address = "0.0.0.0";
|
||||
port = 8443;
|
||||
openFirewall = true;
|
||||
intermediatePasswordFile = "${test-certificates}/intermediate-password-file";
|
||||
settings = {
|
||||
dnsNames = [ "ca.local" ];
|
||||
root = "${test-certificates}/root_ca.crt";
|
||||
crt = "${test-certificates}/intermediate_ca.crt";
|
||||
key = "${test-certificates}/intermediate_ca.key";
|
||||
db = {
|
||||
type = "badger";
|
||||
dataSource = "/var/lib/step-ca/db";
|
||||
};
|
||||
authority = {
|
||||
provisioners = [
|
||||
{
|
||||
type = "ACME";
|
||||
name = "acme";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
server = { pkgs, ... }: {
|
||||
networking = {
|
||||
interfaces.eth1 = {
|
||||
ipv4.addresses = [
|
||||
{ address = "192.168.2.11"; prefixLength = 24; }
|
||||
];
|
||||
};
|
||||
extraHosts = hosts;
|
||||
firewall.allowedTCPPorts = [ 80 443 ];
|
||||
};
|
||||
|
||||
security = {
|
||||
acme = {
|
||||
acceptTerms = true;
|
||||
defaults.server = "https://ca.local:8443/acme/acme/directory";
|
||||
defaults.email = "mastodon@mastodon.local";
|
||||
};
|
||||
pki.certificateFiles = [ "${test-certificates}/root_ca.crt" ];
|
||||
};
|
||||
|
||||
services.redis.servers.mastodon = {
|
||||
enable = true;
|
||||
bind = "127.0.0.1";
|
||||
port = 31637;
|
||||
};
|
||||
|
||||
services.mastodon = {
|
||||
enable = true;
|
||||
configureNginx = true;
|
||||
localDomain = "mastodon.local";
|
||||
enableUnixSocket = false;
|
||||
redis = {
|
||||
createLocally = true;
|
||||
host = "127.0.0.1";
|
||||
port = 31637;
|
||||
};
|
||||
database = {
|
||||
createLocally = true;
|
||||
host = "/run/postgresql";
|
||||
port = 5432;
|
||||
};
|
||||
smtp = {
|
||||
createLocally = false;
|
||||
fromAddress = "mastodon@mastodon.local";
|
||||
};
|
||||
extraConfig = {
|
||||
EMAIL_DOMAIN_ALLOWLIST = "example.com";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
client = { pkgs, ... }: {
|
||||
environment.systemPackages = [ pkgs.jq ];
|
||||
networking = {
|
||||
interfaces.eth1 = {
|
||||
ipv4.addresses = [
|
||||
{ address = "192.168.2.12"; prefixLength = 24; }
|
||||
];
|
||||
};
|
||||
extraHosts = hosts;
|
||||
};
|
||||
|
||||
security = {
|
||||
pki.certificateFiles = [ "${test-certificates}/root_ca.crt" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
start_all()
|
||||
|
||||
ca.wait_for_unit("step-ca.service")
|
||||
ca.wait_for_open_port(8443)
|
||||
|
||||
server.wait_for_unit("nginx.service")
|
||||
server.wait_for_unit("redis-mastodon.service")
|
||||
server.wait_for_unit("postgresql.service")
|
||||
server.wait_for_unit("mastodon-sidekiq.service")
|
||||
server.wait_for_unit("mastodon-streaming.service")
|
||||
server.wait_for_unit("mastodon-web.service")
|
||||
server.wait_for_open_port(55000)
|
||||
server.wait_for_open_port(55001)
|
||||
|
||||
# Check Mastodon version from remote client
|
||||
client.succeed("curl --fail https://mastodon.local/api/v1/instance | jq -r '.version' | grep '${pkgs.mastodon.version}'")
|
||||
|
||||
# Check using admin CLI
|
||||
# Check Mastodon version
|
||||
server.succeed("su - mastodon -s /bin/sh -c 'mastodon-env tootctl version' | grep '${pkgs.mastodon.version}'")
|
||||
|
||||
# Manage accounts
|
||||
server.succeed("su - mastodon -s /bin/sh -c 'mastodon-env tootctl email_domain_blocks add example.com'")
|
||||
server.succeed("su - mastodon -s /bin/sh -c 'mastodon-env tootctl email_domain_blocks list' | grep 'example.com'")
|
||||
server.fail("su - mastodon -s /bin/sh -c 'mastodon-env tootctl email_domain_blocks list' | grep 'mastodon.local'")
|
||||
server.fail("su - mastodon -s /bin/sh -c 'mastodon-env tootctl accounts create alice --email=alice@example.com'")
|
||||
server.succeed("su - mastodon -s /bin/sh -c 'mastodon-env tootctl email_domain_blocks remove example.com'")
|
||||
server.succeed("su - mastodon -s /bin/sh -c 'mastodon-env tootctl accounts create bob --email=bob@example.com'")
|
||||
server.succeed("su - mastodon -s /bin/sh -c 'mastodon-env tootctl accounts approve bob'")
|
||||
server.succeed("su - mastodon -s /bin/sh -c 'mastodon-env tootctl accounts delete bob'")
|
||||
|
||||
# Manage IP access
|
||||
server.succeed("su - mastodon -s /bin/sh -c 'mastodon-env tootctl ip_blocks add 192.168.0.0/16 --severity=no_access'")
|
||||
server.succeed("su - mastodon -s /bin/sh -c 'mastodon-env tootctl ip_blocks export' | grep '192.168.0.0/16'")
|
||||
server.fail("su - mastodon -s /bin/sh -c 'mastodon-env tootctl p_blocks export' | grep '172.16.0.0/16'")
|
||||
client.fail("curl --fail https://mastodon.local/about")
|
||||
server.succeed("su - mastodon -s /bin/sh -c 'mastodon-env tootctl ip_blocks remove 192.168.0.0/16'")
|
||||
client.succeed("curl --fail https://mastodon.local/about")
|
||||
|
||||
ca.shutdown()
|
||||
server.shutdown()
|
||||
client.shutdown()
|
||||
'';
|
||||
})
|
@ -120,6 +120,9 @@ import ../make-test-python.nix ({pkgs, ...}:
|
||||
# Check if PeerTube is running
|
||||
client.succeed("curl --fail http://peertube.local:9000/api/v1/config/about | jq -r '.instance.name' | grep 'PeerTube\ Test\ Server'")
|
||||
|
||||
# Check PeerTube CLI version
|
||||
assert "${pkgs.peertube.version}" in server.succeed('su - peertube -s /bin/sh -c "peertube --version"')
|
||||
|
||||
client.shutdown()
|
||||
server.shutdown()
|
||||
database.shutdown()
|
||||
|
@ -3,7 +3,7 @@
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (pkgs.lib) concatMapStrings listToAttrs;
|
||||
inherit (pkgs.lib) concatMapStrings listToAttrs optionals optionalString;
|
||||
inherit (import ../lib/testing-python.nix { inherit system pkgs; }) makeTest;
|
||||
|
||||
hello32 = "${pkgs.pkgsCross.mingw32.hello}/bin/hello.exe";
|
||||
@ -27,6 +27,9 @@ let
|
||||
"bash -c 'wine ${exe} 2> >(tee wine-stderr >&2)'"
|
||||
)
|
||||
assert 'Hello, world!' in greeting
|
||||
''
|
||||
# only the full version contains Gecko, but the error is not printed reliably in other variants
|
||||
+ optionalString (variant == "full") ''
|
||||
machine.fail(
|
||||
"fgrep 'Could not find Wine Gecko. HTML rendering will be disabled.' wine-stderr"
|
||||
)
|
||||
@ -37,5 +40,9 @@ let
|
||||
|
||||
variants = [ "base" "full" "minimal" "staging" "unstable" "wayland" ];
|
||||
|
||||
in listToAttrs (map (makeWineTest "winePackages" [ hello32 ]) variants
|
||||
++ map (makeWineTest "wineWowPackages" [ hello32 hello64 ]) variants)
|
||||
in
|
||||
listToAttrs (
|
||||
map (makeWineTest "winePackages" [ hello32 ]) variants
|
||||
++ optionals pkgs.stdenv.is64bit
|
||||
(map (makeWineTest "wineWowPackages" [ hello32 hello64 ]) variants)
|
||||
)
|
||||
|
30
pkgs/applications/audio/cider/default.nix
Normal file
30
pkgs/applications/audio/cider/default.nix
Normal file
@ -0,0 +1,30 @@
|
||||
{ appimageTools, lib, fetchurl }:
|
||||
|
||||
appimageTools.wrapType2 rec {
|
||||
pname = "cider";
|
||||
version = "1.3.1308";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://1308-429851205-gh.circle-artifacts.com/0/%7E/Cider/dist/artifacts/Cider-${version}.AppImage";
|
||||
sha256 = "1lbyvn1c8155p039qfzx7jwad7km073phkmrzjm0w3ahdpwz3wgi";
|
||||
};
|
||||
|
||||
extraInstallCommands =
|
||||
let contents = appimageTools.extract { inherit pname version src; };
|
||||
in ''
|
||||
mv $out/bin/${pname}-${version} $out/bin/${pname}
|
||||
|
||||
install -m 444 -D ${contents}/${pname}.desktop -t $out/share/applications
|
||||
substituteInPlace $out/share/applications/${pname}.desktop \
|
||||
--replace 'Exec=AppRun' 'Exec=${pname}'
|
||||
cp -r ${contents}/usr/share/icons $out/share
|
||||
'';
|
||||
|
||||
meta = with lib; {
|
||||
description = "A new look into listening and enjoying Apple Music in style and performance.";
|
||||
homepage = "https://github.com/ciderapp/Cider";
|
||||
license = licenses.agpl3;
|
||||
maintainers = [ maintainers.cigrainger ];
|
||||
platforms = [ "x86_64-linux" ];
|
||||
};
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
{ lib, stdenv, fetchFromGitHub, cmake, pkg-config, libuv, lv2 }:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "eteroj.lv2";
|
||||
version = "0.4.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "OpenMusicKontrollers";
|
||||
repo = pname;
|
||||
rev = version;
|
||||
sha256 = "0lzdk7hlz3vqgshrfpj0izjad1fmsnzk2vxqrry70xgz8xglvnmn";
|
||||
};
|
||||
|
||||
buildInputs = [ libuv lv2 ];
|
||||
nativeBuildInputs = [ cmake pkg-config ];
|
||||
|
||||
meta = with lib; {
|
||||
description = "OSC injection/ejection from/to UDP/TCP/Serial for LV2";
|
||||
homepage = "https://open-music-kontrollers.ch/lv2/eteroj";
|
||||
license = licenses.artistic2;
|
||||
maintainers = with maintainers; [ magnetophon ];
|
||||
};
|
||||
}
|
@ -1,8 +1,9 @@
|
||||
{ stdenv
|
||||
, lib
|
||||
, nix-update-script
|
||||
, gitUpdater
|
||||
, testVersion
|
||||
, furnace
|
||||
, fetchFromGitHub
|
||||
, fetchpatch
|
||||
, cmake
|
||||
, pkg-config
|
||||
, makeWrapper
|
||||
@ -18,24 +19,16 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "furnace";
|
||||
version = "0.5.6";
|
||||
version = "0.5.8";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "tildearrow";
|
||||
repo = "furnace";
|
||||
rev = "v${version}";
|
||||
fetchSubmodules = true;
|
||||
sha256 = "sha256-BcaPQuDFkAaxFQKwoI6xdSWcyHo5VsqZcwf++JISqRs=";
|
||||
sha256 = "103ymd3wa1sfsr6qg15vpcs53j350i7zidv3azlf7cynk6k28xim";
|
||||
};
|
||||
|
||||
patches = [
|
||||
(fetchpatch {
|
||||
name = "0001-furnace-fix-wrong-include-path.patch";
|
||||
url = "https://github.com/tildearrow/furnace/commit/456db22f9d9f0ed40d74fe50dde492e69e901fcc.patch";
|
||||
sha256 = "17ikb1z9ldm7kdj00m4swsrq1qx94vlzhc6h020x3ryzwnglc8d3";
|
||||
})
|
||||
];
|
||||
|
||||
postPatch = ''
|
||||
# rtmidi is not used yet
|
||||
sed -i -e '/add_subdirectory(extern\/rtmidi/d' -e '/DEPENDENCIES_LIBRARIES rtmidi/d' CMakeLists.txt
|
||||
@ -85,8 +78,16 @@ stdenv.mkDerivation rec {
|
||||
cp -r ../demos $out/share/furnace/
|
||||
'';
|
||||
|
||||
passthru.updateScript = nix-update-script {
|
||||
attrPath = pname;
|
||||
passthru = {
|
||||
updateScript = gitUpdater {
|
||||
inherit pname version;
|
||||
rev-prefix = "v";
|
||||
};
|
||||
tests.version = testVersion {
|
||||
package = furnace;
|
||||
# The command always exits with code 1
|
||||
command = "(furnace --version || [ $? -eq 1 ])";
|
||||
};
|
||||
};
|
||||
|
||||
meta = with lib; {
|
||||
|
22
pkgs/applications/audio/lv2lint/default.nix
Normal file
22
pkgs/applications/audio/lv2lint/default.nix
Normal file
@ -0,0 +1,22 @@
|
||||
{ stdenv, lib, fetchurl, pkg-config, meson, ninja, lv2, lilv, curl, libelf }:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "lv2lint";
|
||||
version = "0.14.0";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://git.open-music-kontrollers.ch/lv2/${pname}/snapshot/${pname}-${version}.tar.xz";
|
||||
sha256 = "sha256-yPKM7RToLNBT+AXSjfxxpncESmv89/wcGCt//pnEGqI=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ pkg-config meson ninja ];
|
||||
buildInputs = [ lv2 lilv curl libelf ];
|
||||
|
||||
meta = with lib; {
|
||||
description = "Check whether a given LV2 plugin is up to the specification";
|
||||
homepage = "https://open-music-kontrollers.ch/lv2/${pname}:";
|
||||
license = licenses.artistic2;
|
||||
maintainers = [ maintainers.magnetophon ];
|
||||
platforms = platforms.all;
|
||||
};
|
||||
}
|
@ -2,24 +2,33 @@
|
||||
|
||||
python3Packages.buildPythonApplication rec {
|
||||
pname = "mopidy-ytmusic";
|
||||
version = "0.3.2";
|
||||
version = "0.3.5";
|
||||
|
||||
src = python3Packages.fetchPypi {
|
||||
inherit version;
|
||||
pname = "Mopidy-YTMusic";
|
||||
sha256 = "sha256-BZtW+qHsTnOMj+jdAFI8ZMwGxJc9lNosgPJZGbt4JgU=";
|
||||
sha256 = "0pncyxfqxvznb9y4ksndbny1yf5mxh4089ak0yz86dp2qi5j99iv";
|
||||
};
|
||||
|
||||
postPatch = ''
|
||||
substituteInPlace setup.py \
|
||||
--replace 'ytmusicapi>=0.20.0,<0.21.0' 'ytmusicapi>=0.20.0'
|
||||
'';
|
||||
|
||||
propagatedBuildInputs = [
|
||||
mopidy
|
||||
python3Packages.ytmusicapi
|
||||
python3Packages.pytube
|
||||
];
|
||||
|
||||
pythonImportsCheck = [ "mopidy_ytmusic" ];
|
||||
|
||||
# has no tests
|
||||
doCheck = false;
|
||||
|
||||
meta = with lib; {
|
||||
description = "Mopidy extension for playing music from YouTube Music";
|
||||
homepage = "https://github.com/OzymandiasTheGreat/mopidy-ytmusic";
|
||||
license = licenses.asl20;
|
||||
maintainers = [ maintainers.nickhu ];
|
||||
};
|
||||
|
10
pkgs/applications/audio/open-music-kontrollers/eteroj.nix
Normal file
10
pkgs/applications/audio/open-music-kontrollers/eteroj.nix
Normal file
@ -0,0 +1,10 @@
|
||||
{ callPackage, ... } @ args:
|
||||
|
||||
callPackage ./generic.nix (args // rec {
|
||||
pname = "eteroj";
|
||||
version = "0.10.0";
|
||||
|
||||
sha256 = "18iv1sdwm0g6b53shsylj6bf3svmvvy5xadhfsgb4xg39qr07djz";
|
||||
|
||||
description = "OSC injection/ejection from/to UDP/TCP/Serial for LV2";
|
||||
})
|
37
pkgs/applications/audio/open-music-kontrollers/generic.nix
Normal file
37
pkgs/applications/audio/open-music-kontrollers/generic.nix
Normal file
@ -0,0 +1,37 @@
|
||||
{ stdenv, lib, fetchurl, pkg-config, meson, ninja, libGLU, lv2, serd, sord, libX11, libXext, glew, lv2lint
|
||||
, pname, version, sha256, description
|
||||
, url ? "https://git.open-music-kontrollers.ch/lv2/${pname}.lv2/snapshot/${pname}.lv2-${version}.tar.xz"
|
||||
, additionalBuildInputs ? []
|
||||
, postPatch ? ""
|
||||
, ...
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation {
|
||||
inherit pname;
|
||||
|
||||
inherit version;
|
||||
|
||||
inherit postPatch;
|
||||
|
||||
src = fetchurl {
|
||||
url = url;
|
||||
sha256 = sha256;
|
||||
};
|
||||
nativeBuildInputs = [ pkg-config meson ninja ];
|
||||
buildInputs = [
|
||||
lv2
|
||||
sord
|
||||
libX11
|
||||
libXext
|
||||
glew
|
||||
lv2lint
|
||||
] ++ additionalBuildInputs;
|
||||
|
||||
meta = with lib; {
|
||||
description = description;
|
||||
homepage = "https://open-music-kontrollers.ch/lv2/${pname}:";
|
||||
license = licenses.artistic2;
|
||||
maintainers = [ maintainers.magnetophon ];
|
||||
platforms = platforms.all;
|
||||
};
|
||||
}
|
12
pkgs/applications/audio/open-music-kontrollers/jit.nix
Normal file
12
pkgs/applications/audio/open-music-kontrollers/jit.nix
Normal file
@ -0,0 +1,12 @@
|
||||
{ callPackage, lv2, fontconfig, libvterm-neovim, ... } @ args:
|
||||
|
||||
callPackage ./generic.nix (args // rec {
|
||||
pname = "jit";
|
||||
version = "unstable-2021-08-15";
|
||||
url = "https://git.open-music-kontrollers.ch/lv2/${pname}.lv2/snapshot/${pname}.lv2-1f5d6935049fc0dd5a4dc257b84b36d2048f2d83.tar.xz";
|
||||
sha256 = "sha256-XGICowVb0JgLJpn2h9GtViobYTdmo1LJ7/JFEyVsIqU=";
|
||||
|
||||
additionalBuildInputs = [ lv2 fontconfig libvterm-neovim ];
|
||||
|
||||
description = "A Just-in-Time C/Rust compiler embedded in an LV2 plugin";
|
||||
})
|
17
pkgs/applications/audio/open-music-kontrollers/mephisto.nix
Normal file
17
pkgs/applications/audio/open-music-kontrollers/mephisto.nix
Normal file
@ -0,0 +1,17 @@
|
||||
{ callPackage, faust, fontconfig, cmake, libvterm-neovim, libevdev, libglvnd, fira-code, ... } @ args:
|
||||
|
||||
callPackage ./generic.nix (args // rec {
|
||||
pname = "mephisto";
|
||||
version = "0.16.0";
|
||||
|
||||
sha256 = "0vgr3rsvdj4w0xpc5iqpvyqilk42wr9zs8bg26sfv3f2wi4hb6gx";
|
||||
|
||||
additionalBuildInputs = [ faust fontconfig cmake libvterm-neovim libevdev libglvnd fira-code ];
|
||||
|
||||
# see: https://github.com/OpenMusicKontrollers/mephisto.lv2/issues/6
|
||||
postPatch = ''
|
||||
sed -i 's/llvm-c-dsp/llvm-dsp-c/g' mephisto.c
|
||||
'';
|
||||
|
||||
description = "A Just-in-time FAUST embedded in an LV2 plugin";
|
||||
})
|
@ -0,0 +1,10 @@
|
||||
{ callPackage, ... } @ args:
|
||||
|
||||
callPackage ./generic.nix (args // rec {
|
||||
pname = "midi_matrix";
|
||||
version = "0.30.0";
|
||||
|
||||
sha256 = "1nwmfxdzk4pvbwcgi3d7v4flqc10bmi2fxhrhrpfa7cafqs40ib6";
|
||||
|
||||
description = "An LV2 MIDI channel matrix patcher";
|
||||
})
|
13
pkgs/applications/audio/open-music-kontrollers/moony.nix
Normal file
13
pkgs/applications/audio/open-music-kontrollers/moony.nix
Normal file
@ -0,0 +1,13 @@
|
||||
{ callPackage, cairo, libvterm-neovim, robodoc, cmake, ... } @ args:
|
||||
|
||||
callPackage ./generic.nix (args // rec {
|
||||
pname = "moony";
|
||||
version = "0.40.0";
|
||||
|
||||
sha256 = "sha256-9a3gR3lV8xFFTDZD+fJPCALVztgmggzyIpsPZCOw/uY=";
|
||||
|
||||
additionalBuildInputs = [ cairo libvterm-neovim robodoc cmake ];
|
||||
|
||||
description = "Realtime Lua as programmable glue in LV2";
|
||||
|
||||
})
|
12
pkgs/applications/audio/open-music-kontrollers/orbit.nix
Normal file
12
pkgs/applications/audio/open-music-kontrollers/orbit.nix
Normal file
@ -0,0 +1,12 @@
|
||||
{ callPackage, zlib, ... } @ args:
|
||||
|
||||
callPackage ./generic.nix (args // rec {
|
||||
pname = "orbit";
|
||||
version = "unstable-2021-04-13";
|
||||
url = "https://git.open-music-kontrollers.ch/lv2/${pname}.lv2/snapshot/${pname}.lv2-f4aa620fc8d77418856581a6a955192af15b3860.tar.xz";
|
||||
sha256 = "0z8d8h2w8fb2zx84n697jvy32dc0vf60jyiyh4gm22prgr2dvgkc";
|
||||
|
||||
additionalBuildInputs = [ zlib ];
|
||||
|
||||
description = "An LV2 time event manipulation plugin bundle";
|
||||
})
|
@ -0,0 +1,13 @@
|
||||
{ callPackage, libjack2, ... } @ args:
|
||||
|
||||
callPackage ./generic.nix (args // rec {
|
||||
pname = "patchmatrix";
|
||||
version = "0.26.0";
|
||||
|
||||
url = "https://git.open-music-kontrollers.ch/lad/${pname}/snapshot/${pname}-${version}.tar.xz";
|
||||
sha256 = "sha256-cqPHCnrAhHB6a0xmPUYOAsZfLsqnGpXEuGR1W6i6W7I=";
|
||||
|
||||
additionalBuildInputs = [ libjack2 ];
|
||||
|
||||
description = "A JACK patchbay in flow matrix style";
|
||||
})
|
11
pkgs/applications/audio/open-music-kontrollers/router.nix
Normal file
11
pkgs/applications/audio/open-music-kontrollers/router.nix
Normal file
@ -0,0 +1,11 @@
|
||||
{ callPackage, ... } @ args:
|
||||
|
||||
callPackage ./generic.nix (args // rec {
|
||||
pname = "router";
|
||||
version = "unstable-2021-04-13";
|
||||
|
||||
url = "https://git.open-music-kontrollers.ch/lv2/${pname}.lv2/snapshot/${pname}.lv2-7d754dd64c540d40b828166401617715dc235ca3.tar.xz";
|
||||
sha256 = "sha256-LjaW5Xdxfjzd6IJ2ptHzmHt7fhU1HQo7ubZ4USVqRE8=";
|
||||
|
||||
description = "An atom/audio/CV router LV2 plugin bundle";
|
||||
})
|
12
pkgs/applications/audio/open-music-kontrollers/sherlock.nix
Normal file
12
pkgs/applications/audio/open-music-kontrollers/sherlock.nix
Normal file
@ -0,0 +1,12 @@
|
||||
{ callPackage, sratom, flex, ... } @ args:
|
||||
|
||||
callPackage ./generic.nix (args // rec {
|
||||
pname = "sherlock";
|
||||
version = "0.28.0";
|
||||
|
||||
sha256 = "07zj88s1593fpw2s0r3ix7cj2icfd9zyirsyhr2i8l6d30b6n6fb";
|
||||
|
||||
additionalBuildInputs = [ sratom flex ];
|
||||
|
||||
description = "Plugins for visualizing LV2 atom, MIDI and OSC events";
|
||||
})
|
13
pkgs/applications/audio/open-music-kontrollers/synthpod.nix
Normal file
13
pkgs/applications/audio/open-music-kontrollers/synthpod.nix
Normal file
@ -0,0 +1,13 @@
|
||||
{ callPackage, lilv, libjack2, alsa-lib, zita-alsa-pcmi, libxcb, xcbutilxrm, sratom, gtk2, qt5, libvterm-neovim, robodoc, cmake,... } @ args:
|
||||
|
||||
callPackage ./generic.nix (args // rec {
|
||||
pname = "synthpod";
|
||||
version = "unstable-2021-10-22";
|
||||
|
||||
url = "https://git.open-music-kontrollers.ch/lv2/synthpod/snapshot/synthpod-6f284bdad882037a522c120af92b96d8abf2de60.tar.xz";
|
||||
sha256 = "sha256-59WBlOKum5Pcmq2CfFfRHCNEa8uPCoBk0kSjFlIcypw=";
|
||||
|
||||
additionalBuildInputs = [ lilv libjack2 alsa-lib zita-alsa-pcmi libxcb xcbutilxrm sratom gtk2 qt5.qtbase qt5.wrapQtAppsHook libvterm-neovim robodoc cmake ];
|
||||
|
||||
description = "Lightweight Nonlinear LV2 Plugin Container";
|
||||
})
|
10
pkgs/applications/audio/open-music-kontrollers/vm.nix
Normal file
10
pkgs/applications/audio/open-music-kontrollers/vm.nix
Normal file
@ -0,0 +1,10 @@
|
||||
{ callPackage, ... } @ args:
|
||||
|
||||
callPackage ./generic.nix (args // rec {
|
||||
pname = "vm";
|
||||
version = "0.14.0";
|
||||
|
||||
sha256 = "013gq7jn556nkk1nq6zzh9nmp3fb36jd7ndzvyq3qryw7khzkagc";
|
||||
|
||||
description = "A programmable virtual machine LV2 plugin";
|
||||
})
|
@ -1,45 +0,0 @@
|
||||
{ stdenv
|
||||
, lib
|
||||
, fetchFromGitHub
|
||||
, libjack2
|
||||
, lv2
|
||||
, meson
|
||||
, ninja
|
||||
, pkg-config
|
||||
, glew
|
||||
, xorg
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "patchmatrix";
|
||||
version = "0.26.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "OpenMusicKontrollers";
|
||||
repo = pname;
|
||||
rev = version;
|
||||
hash = "sha256-rR3y5rGzmib//caPmhthvMelAdHRvV0lMRfvcj9kcCg=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
meson
|
||||
ninja
|
||||
pkg-config
|
||||
];
|
||||
|
||||
buildInputs = [
|
||||
glew
|
||||
libjack2
|
||||
lv2
|
||||
xorg.libX11
|
||||
xorg.libXext
|
||||
];
|
||||
|
||||
meta = with lib; {
|
||||
description = "A JACK patchbay in flow matrix style";
|
||||
homepage = "https://github.com/OpenMusicKontrollers/patchmatrix";
|
||||
license = licenses.artistic2;
|
||||
maintainers = with maintainers; [ pennae ];
|
||||
platforms = platforms.linux;
|
||||
};
|
||||
}
|
@ -8,13 +8,13 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "pt2-clone";
|
||||
version = "1.42";
|
||||
version = "1.43";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "8bitbubsy";
|
||||
repo = "pt2-clone";
|
||||
rev = "v${version}";
|
||||
sha256 = "sha256-CwnEvQsxrYStJ4RxnE0lHt1fBHQEZrjSldnQnTOPaE0=";
|
||||
sha256 = "sha256-+sHGjgDqizv/9n0dDj8knsl+4MBfO3/pMkmD+MPsuNM=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ cmake ];
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
python3Packages.buildPythonApplication rec {
|
||||
pname = "pyradio";
|
||||
version = "0.8.9.14";
|
||||
version = "0.8.9.15";
|
||||
|
||||
propagatedBuildInputs = with python3Packages; [
|
||||
requests
|
||||
@ -14,7 +14,7 @@ python3Packages.buildPythonApplication rec {
|
||||
owner = "coderholic";
|
||||
repo = pname;
|
||||
rev = version;
|
||||
sha256 = "sha256-9q+YsQPFB7Ql5WnXvPj100cD7pGkmr1hHztqbpZStt8=";
|
||||
sha256 = "sha256-r4T7t8Q46N59jqTkvdKBo6tffkrOYhoO/CZWvkBHOAQ=";
|
||||
};
|
||||
|
||||
checkPhase = ''
|
||||
|
@ -10,14 +10,14 @@ let
|
||||
# If an update breaks things, one of those might have valuable info:
|
||||
# https://aur.archlinux.org/packages/spotify/
|
||||
# https://community.spotify.com/t5/Desktop-Linux
|
||||
version = "1.1.77.643.g3c4c6fc6";
|
||||
version = "1.1.80.699.gc3dac750";
|
||||
# To get the latest stable revision:
|
||||
# curl -H 'X-Ubuntu-Series: 16' 'https://api.snapcraft.io/api/v1/snaps/details/spotify?channel=stable' | jq '.download_url,.version,.last_updated'
|
||||
# To get general information:
|
||||
# curl -H 'Snap-Device-Series: 16' 'https://api.snapcraft.io/v2/snaps/info/spotify' | jq '.'
|
||||
# More examples of api usage:
|
||||
# https://github.com/canonical-websites/snapcraft.io/blob/master/webapp/publisher/snaps/views.py
|
||||
rev = "57";
|
||||
rev = "58";
|
||||
|
||||
deps = [
|
||||
alsa-lib
|
||||
@ -80,7 +80,7 @@ stdenv.mkDerivation {
|
||||
# https://community.spotify.com/t5/Desktop-Linux/Redistribute-Spotify-on-Linux-Distributions/td-p/1695334
|
||||
src = fetchurl {
|
||||
url = "https://api.snapcraft.io/api/v1/snaps/download/pOBIoZ2LrCB3rDohMxoYGnbN14EHOgD7_${rev}.snap";
|
||||
sha512 = "d9f8fe692db479bcce1f47c87b65c5ac6d62e16b76a0f9b2d693d82d2b9ed2c7cf370cb091ce8ecd291c47d1efdbaa897c9bffb210edd901dc3d5425995229f7";
|
||||
sha512 = "91385a5a8de31d6e9f1945d23108447fd369c1cdc2e4d95cbb7cec5d403c3be14a1b0fabe3fb01aef809a39b033d289add1bcb307ab19c7fcb63689dbae57c53";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ makeWrapper wrapGAppsHook squashfsTools ];
|
||||
|
@ -13,11 +13,11 @@ let
|
||||
in
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "SunVox";
|
||||
version = "2.0c";
|
||||
version = "2.0e";
|
||||
|
||||
src = fetchurl {
|
||||
url = "http://www.warmplace.ru/soft/sunvox/sunvox-${version}.zip";
|
||||
sha256 = "949e5348da9faa92ce17aac943b58027bdb797b65c7f5f365ef0610bb6dd8a3d";
|
||||
url = "https://www.warmplace.ru/soft/sunvox/sunvox-${version}.zip";
|
||||
sha256 = "sha256-v4dQnRr7pusOAHX8ytDChKixYxEIjg30vOTD6uA/S0o=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ unzip ];
|
||||
|
@ -56,7 +56,6 @@ stdenv.mkDerivation rec {
|
||||
libgee
|
||||
libnotify
|
||||
libunity
|
||||
pantheon.elementary-icon-theme
|
||||
pantheon.granite
|
||||
sqlite
|
||||
webkitgtk
|
||||
@ -73,6 +72,13 @@ stdenv.mkDerivation rec {
|
||||
})
|
||||
];
|
||||
|
||||
postPatch = ''
|
||||
# Fix build with vala 0.56
|
||||
# https://github.com/needle-and-thread/vocal/pull/503
|
||||
substituteInPlace src/Vocal.vala \
|
||||
--replace "public const OptionEntry[] app_options" "private const OptionEntry[] app_options"
|
||||
'';
|
||||
|
||||
passthru = {
|
||||
updateScript = nix-update-script {
|
||||
attrPath = pname;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user