Merge remote-tracking branch 'origin/master' into haskell-updates.
This commit is contained in:
commit
fcbf5bf857
@ -57,10 +57,13 @@ indent_size = unset
|
|||||||
[deps.nix]
|
[deps.nix]
|
||||||
insert_final_newline = unset
|
insert_final_newline = unset
|
||||||
|
|
||||||
|
[eggs.nix]
|
||||||
|
trim_trailing_whitespace = unset
|
||||||
|
|
||||||
[gemset.nix]
|
[gemset.nix]
|
||||||
insert_final_newline = unset
|
insert_final_newline = unset
|
||||||
|
|
||||||
[node-packages.nix]
|
[node-{composition,packages}.nix]
|
||||||
insert_final_newline = unset
|
insert_final_newline = unset
|
||||||
|
|
||||||
[nixos/modules/services/networking/ircd-hybrid/*.{conf,in}]
|
[nixos/modules/services/networking/ircd-hybrid/*.{conf,in}]
|
||||||
@ -102,5 +105,8 @@ insert_final_newline = unset
|
|||||||
indent_size = unset
|
indent_size = unset
|
||||||
trim_trailing_whitespace = unset
|
trim_trailing_whitespace = unset
|
||||||
|
|
||||||
|
[pkgs/top-level/emscripten-packages.nix]
|
||||||
|
trim_trailing_whitespace = unset
|
||||||
|
|
||||||
[pkgs/top-level/perl-packages.nix]
|
[pkgs/top-level/perl-packages.nix]
|
||||||
indent_size = unset
|
indent_size = unset
|
||||||
|
27
.github/workflows/editorconfig.yml
vendored
Normal file
27
.github/workflows/editorconfig.yml
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
name: "Checking EditorConfig"
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
tests:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- uses: technote-space/get-diff-action@v3.1.0
|
||||||
|
- name: Fetch editorconfig-checker
|
||||||
|
if: env.GIT_DIFF
|
||||||
|
env:
|
||||||
|
ECC_VERSION: "2.1.0"
|
||||||
|
ECC_URL: "https://github.com/editorconfig-checker/editorconfig-checker/releases/download"
|
||||||
|
run: |
|
||||||
|
curl -sSf -O -L -C - "$ECC_URL/$ECC_VERSION/ec-linux-amd64.tar.gz" && \
|
||||||
|
tar xzf ec-linux-amd64.tar.gz && \
|
||||||
|
mv ./bin/ec-linux-amd64 ./bin/editorconfig-checker
|
||||||
|
- name: Checking EditorConfig
|
||||||
|
if: env.GIT_DIFF
|
||||||
|
run: |
|
||||||
|
./bin/editorconfig-checker -disable-indentation \
|
||||||
|
${{ env.GIT_DIFF }}
|
@ -436,6 +436,12 @@ lib.mapAttrs (n: v: v // { shortName = n; }) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
# Proprietary binaries; free to redistribute without modification.
|
# Proprietary binaries; free to redistribute without modification.
|
||||||
|
databricks = {
|
||||||
|
fullName = "Databricks Proprietary License";
|
||||||
|
url = "https://pypi.org/project/databricks-connect";
|
||||||
|
free = false;
|
||||||
|
};
|
||||||
|
|
||||||
issl = {
|
issl = {
|
||||||
fullName = "Intel Simplified Software License";
|
fullName = "Intel Simplified Software License";
|
||||||
url = "https://software.intel.com/en-us/license/intel-simplified-software-license";
|
url = "https://software.intel.com/en-us/license/intel-simplified-software-license";
|
||||||
|
@ -613,7 +613,6 @@ rec {
|
|||||||
if tp.name == "option set" || tp.name == "submodule" then
|
if tp.name == "option set" || tp.name == "submodule" then
|
||||||
throw "The option ${showOption loc} uses submodules without a wrapping type, in ${showFiles opt.declarations}."
|
throw "The option ${showOption loc} uses submodules without a wrapping type, in ${showFiles opt.declarations}."
|
||||||
else if optionSetIn "attrsOf" then types.attrsOf (types.submodule options)
|
else if optionSetIn "attrsOf" then types.attrsOf (types.submodule options)
|
||||||
else if optionSetIn "loaOf" then types.loaOf (types.submodule options)
|
|
||||||
else if optionSetIn "listOf" then types.listOf (types.submodule options)
|
else if optionSetIn "listOf" then types.listOf (types.submodule options)
|
||||||
else if optionSetIn "nullOr" then types.nullOr (types.submodule options)
|
else if optionSetIn "nullOr" then types.nullOr (types.submodule options)
|
||||||
else tp;
|
else tp;
|
||||||
|
@ -689,14 +689,15 @@ rec {
|
|||||||
"/prefix/nix-profiles-library-paths.patch"
|
"/prefix/nix-profiles-library-paths.patch"
|
||||||
"/prefix/compose-search-path.patch" ]
|
"/prefix/compose-search-path.patch" ]
|
||||||
*/
|
*/
|
||||||
readPathsFromFile = rootPath: file:
|
readPathsFromFile = lib.warn "lib.readPathsFromFile is deprecated, use a list instead"
|
||||||
let
|
(rootPath: file:
|
||||||
lines = lib.splitString "\n" (builtins.readFile file);
|
let
|
||||||
removeComments = lib.filter (line: line != "" && !(lib.hasPrefix "#" line));
|
lines = lib.splitString "\n" (builtins.readFile file);
|
||||||
relativePaths = removeComments lines;
|
removeComments = lib.filter (line: line != "" && !(lib.hasPrefix "#" line));
|
||||||
absolutePaths = builtins.map (path: rootPath + "/${path}") relativePaths;
|
relativePaths = removeComments lines;
|
||||||
in
|
absolutePaths = builtins.map (path: rootPath + "/${path}") relativePaths;
|
||||||
absolutePaths;
|
in
|
||||||
|
absolutePaths);
|
||||||
|
|
||||||
/* Read the contents of a file removing the trailing \n
|
/* Read the contents of a file removing the trailing \n
|
||||||
|
|
||||||
|
77
lib/systems/architectures.nix
Normal file
77
lib/systems/architectures.nix
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
{ lib }:
|
||||||
|
|
||||||
|
rec {
|
||||||
|
# platform.gcc.arch to its features (as in /proc/cpuinfo)
|
||||||
|
features = {
|
||||||
|
default = [ ];
|
||||||
|
# x86_64 Intel
|
||||||
|
westmere = [ "sse3" "ssse3" "sse4_1" "sse4_2" "aes" ];
|
||||||
|
sandybridge = [ "sse3" "ssse3" "sse4_1" "sse4_2" "aes" "avx" ];
|
||||||
|
ivybridge = [ "sse3" "ssse3" "sse4_1" "sse4_2" "aes" "avx" ];
|
||||||
|
haswell = [ "sse3" "ssse3" "sse4_1" "sse4_2" "aes" "avx" "avx2" "fma" ];
|
||||||
|
broadwell = [ "sse3" "ssse3" "sse4_1" "sse4_2" "aes" "avx" "avx2" "fma" ];
|
||||||
|
skylake = [ "sse3" "ssse3" "sse4_1" "sse4_2" "aes" "avx" "avx2" "fma" ];
|
||||||
|
skylake-avx512 = [ "sse3" "ssse3" "sse4_1" "sse4_2" "aes" "avx" "avx2" "avx512" "fma" ];
|
||||||
|
# x86_64 AMD
|
||||||
|
btver1 = [ "sse3" "ssse3" "sse4_1" "sse4_2" ];
|
||||||
|
btver2 = [ "sse3" "ssse3" "sse4_1" "sse4_2" "aes" "avx" ];
|
||||||
|
bdver1 = [ "sse3" "ssse3" "sse4_1" "sse4_2" "sse4a" "aes" "avx" "fma" "fma4" ];
|
||||||
|
bdver2 = [ "sse3" "ssse3" "sse4_1" "sse4_2" "sse4a" "aes" "avx" "fma" "fma4" ];
|
||||||
|
bdver3 = [ "sse3" "ssse3" "sse4_1" "sse4_2" "sse4a" "aes" "avx" "fma" "fma4" ];
|
||||||
|
bdver4 = [ "sse3" "ssse3" "sse4_1" "sse4_2" "sse4a" "aes" "avx" "avx2" "fma" "fma4" ];
|
||||||
|
znver1 = [ "sse3" "ssse3" "sse4_1" "sse4_2" "sse4a" "aes" "avx" "avx2" "fma" ];
|
||||||
|
znver2 = [ "sse3" "ssse3" "sse4_1" "sse4_2" "sse4a" "aes" "avx" "avx2" "fma" ];
|
||||||
|
# other
|
||||||
|
armv5te = [ ];
|
||||||
|
armv6 = [ ];
|
||||||
|
armv7-a = [ ];
|
||||||
|
armv8-a = [ ];
|
||||||
|
mips32 = [ ];
|
||||||
|
loongson2f = [ ];
|
||||||
|
};
|
||||||
|
|
||||||
|
# a superior CPU has all the features of an inferior and is able to build and test code for it
|
||||||
|
inferiors = {
|
||||||
|
# x86_64 Intel
|
||||||
|
default = [ ];
|
||||||
|
westmere = [ ];
|
||||||
|
sandybridge = [ "westmere" ] ++ inferiors.westmere;
|
||||||
|
ivybridge = [ "sandybridge" ] ++ inferiors.sandybridge;
|
||||||
|
haswell = [ "ivybridge" ] ++ inferiors.ivybridge;
|
||||||
|
broadwell = [ "haswell" ] ++ inferiors.haswell;
|
||||||
|
skylake = [ "broadwell" ] ++ inferiors.broadwell;
|
||||||
|
skylake-avx512 = [ "skylake" ] ++ inferiors.skylake;
|
||||||
|
# x86_64 AMD
|
||||||
|
btver1 = [ ];
|
||||||
|
btver2 = [ ]; # TODO: fill this (need testing)
|
||||||
|
bdver1 = [ ]; # TODO: fill this (need testing)
|
||||||
|
bdver2 = [ ]; # TODO: fill this (need testing)
|
||||||
|
bdver3 = [ ]; # TODO: fill this (need testing)
|
||||||
|
bdver4 = [ ]; # TODO: fill this (need testing)
|
||||||
|
znver1 = [ ]; # TODO: fill this (need testing)
|
||||||
|
znver2 = [ ]; # TODO: fill this (need testing)
|
||||||
|
# other
|
||||||
|
armv5te = [ ];
|
||||||
|
armv6 = [ ];
|
||||||
|
armv7-a = [ ];
|
||||||
|
armv8-a = [ ];
|
||||||
|
mips32 = [ ];
|
||||||
|
loongson2f = [ ];
|
||||||
|
};
|
||||||
|
|
||||||
|
predicates = let
|
||||||
|
featureSupport = feature: x: builtins.elem feature features.${x};
|
||||||
|
in {
|
||||||
|
sse3Support = featureSupport "sse3";
|
||||||
|
ssse3Support = featureSupport "ssse3";
|
||||||
|
sse4_1Support = featureSupport "sse4_1";
|
||||||
|
sse4_2Support = featureSupport "sse4_2";
|
||||||
|
sse4_aSupport = featureSupport "sse4a";
|
||||||
|
avxSupport = featureSupport "avx";
|
||||||
|
avx2Support = featureSupport "avx2";
|
||||||
|
avx512Support = featureSupport "avx512";
|
||||||
|
aesSupport = featureSupport "aes";
|
||||||
|
fmaSupport = featureSupport "fma";
|
||||||
|
fma4Support = featureSupport "fma4";
|
||||||
|
};
|
||||||
|
}
|
@ -7,6 +7,7 @@ rec {
|
|||||||
inspect = import ./inspect.nix { inherit lib; };
|
inspect = import ./inspect.nix { inherit lib; };
|
||||||
platforms = import ./platforms.nix { inherit lib; };
|
platforms = import ./platforms.nix { inherit lib; };
|
||||||
examples = import ./examples.nix { inherit lib; };
|
examples = import ./examples.nix { inherit lib; };
|
||||||
|
architectures = import ./architectures.nix { inherit lib; };
|
||||||
|
|
||||||
# Elaborate a `localSystem` or `crossSystem` so that it contains everything
|
# Elaborate a `localSystem` or `crossSystem` so that it contains everything
|
||||||
# necessary.
|
# necessary.
|
||||||
@ -76,6 +77,7 @@ rec {
|
|||||||
# uname -r
|
# uname -r
|
||||||
release = null;
|
release = null;
|
||||||
};
|
};
|
||||||
|
isStatic = final.isWasm || final.isRedox;
|
||||||
|
|
||||||
kernelArch =
|
kernelArch =
|
||||||
if final.isAarch32 then "arm"
|
if final.isAarch32 then "arm"
|
||||||
@ -125,6 +127,7 @@ rec {
|
|||||||
else throw "Don't know how to run ${final.config} executables.";
|
else throw "Don't know how to run ${final.config} executables.";
|
||||||
|
|
||||||
} // mapAttrs (n: v: v final.parsed) inspect.predicates
|
} // mapAttrs (n: v: v final.parsed) inspect.predicates
|
||||||
|
// mapAttrs (n: v: v final.platform.gcc.arch or "default") architectures.predicates
|
||||||
// args;
|
// args;
|
||||||
in assert final.useAndroidPrebuilt -> final.isAndroid;
|
in assert final.useAndroidPrebuilt -> final.isAndroid;
|
||||||
assert lib.foldl
|
assert lib.foldl
|
||||||
|
@ -46,7 +46,7 @@ rec {
|
|||||||
|
|
||||||
armv7a-android-prebuilt = {
|
armv7a-android-prebuilt = {
|
||||||
config = "armv7a-unknown-linux-androideabi";
|
config = "armv7a-unknown-linux-androideabi";
|
||||||
sdkVer = "24";
|
sdkVer = "29";
|
||||||
ndkVer = "18b";
|
ndkVer = "18b";
|
||||||
platform = platforms.armv7a-android;
|
platform = platforms.armv7a-android;
|
||||||
useAndroidPrebuilt = true;
|
useAndroidPrebuilt = true;
|
||||||
@ -54,7 +54,7 @@ rec {
|
|||||||
|
|
||||||
aarch64-android-prebuilt = {
|
aarch64-android-prebuilt = {
|
||||||
config = "aarch64-unknown-linux-android";
|
config = "aarch64-unknown-linux-android";
|
||||||
sdkVer = "24";
|
sdkVer = "29";
|
||||||
ndkVer = "18b";
|
ndkVer = "18b";
|
||||||
platform = platforms.aarch64-multiplatform;
|
platform = platforms.aarch64-multiplatform;
|
||||||
useAndroidPrebuilt = true;
|
useAndroidPrebuilt = true;
|
||||||
|
117
lib/types.nix
117
lib/types.nix
@ -252,8 +252,8 @@ rec {
|
|||||||
merge = mergeEqualOption;
|
merge = mergeEqualOption;
|
||||||
};
|
};
|
||||||
|
|
||||||
# drop this in the future:
|
# TODO: drop this in the future:
|
||||||
list = builtins.trace "`types.list` is deprecated; use `types.listOf` instead" types.listOf;
|
list = builtins.trace "`types.list` has been removed; please use `types.listOf` instead" types.listOf;
|
||||||
|
|
||||||
listOf = elemType: mkOptionType rec {
|
listOf = elemType: mkOptionType rec {
|
||||||
name = "listOf";
|
name = "listOf";
|
||||||
@ -326,110 +326,15 @@ rec {
|
|||||||
functor = (defaultFunctor name) // { wrapped = elemType; };
|
functor = (defaultFunctor name) // { wrapped = elemType; };
|
||||||
};
|
};
|
||||||
|
|
||||||
# List or attribute set of ...
|
# TODO: drop this in the future:
|
||||||
loaOf = elemType:
|
loaOf =
|
||||||
let
|
let msg =
|
||||||
convertAllLists = loc: defs:
|
''
|
||||||
let
|
`types.loaOf` has been removed and mixing lists with attribute values
|
||||||
padWidth = stringLength (toString (length defs));
|
is no longer possible; please use `types.attrsOf` instead.
|
||||||
unnamedPrefix = i: "unnamed-" + fixedWidthNumber padWidth i + ".";
|
See https://github.com/NixOS/nixpkgs/issues/1800 for the motivation.
|
||||||
in
|
'';
|
||||||
imap1 (i: convertIfList loc (unnamedPrefix i)) defs;
|
in builtins.trace msg types.attrsOf;
|
||||||
convertIfList = loc: unnamedPrefix: def:
|
|
||||||
if isList def.value then
|
|
||||||
let
|
|
||||||
padWidth = stringLength (toString (length def.value));
|
|
||||||
unnamed = i: unnamedPrefix + fixedWidthNumber padWidth i;
|
|
||||||
anyString = placeholder "name";
|
|
||||||
nameAttrs = [
|
|
||||||
{ path = [ "environment" "etc" ];
|
|
||||||
name = "target";
|
|
||||||
}
|
|
||||||
{ path = [ "containers" anyString "bindMounts" ];
|
|
||||||
name = "mountPoint";
|
|
||||||
}
|
|
||||||
{ path = [ "programs" "ssh" "knownHosts" ];
|
|
||||||
# hostNames is actually a list so we would need to handle it only when singleton
|
|
||||||
name = "hostNames";
|
|
||||||
}
|
|
||||||
{ path = [ "fileSystems" ];
|
|
||||||
name = "mountPoint";
|
|
||||||
}
|
|
||||||
{ path = [ "boot" "specialFileSystems" ];
|
|
||||||
name = "mountPoint";
|
|
||||||
}
|
|
||||||
{ path = [ "services" "znapzend" "zetup" ];
|
|
||||||
name = "dataset";
|
|
||||||
}
|
|
||||||
{ path = [ "services" "znapzend" "zetup" anyString "destinations" ];
|
|
||||||
name = "label";
|
|
||||||
}
|
|
||||||
{ path = [ "services" "geoclue2" "appConfig" ];
|
|
||||||
name = "desktopID";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
matched = let
|
|
||||||
equals = a: b: b == anyString || a == b;
|
|
||||||
fallback = { name = "name"; };
|
|
||||||
in findFirst ({ path, ... }: all (v: v == true) (zipListsWith equals loc path)) fallback nameAttrs;
|
|
||||||
nameAttr = matched.name;
|
|
||||||
nameValueOld = value:
|
|
||||||
if isList value then
|
|
||||||
if length value > 0 then
|
|
||||||
"[ " + concatMapStringsSep " " escapeNixString value + " ]"
|
|
||||||
else
|
|
||||||
"[ ]"
|
|
||||||
else
|
|
||||||
escapeNixString value;
|
|
||||||
nameValueNew = value: unnamed:
|
|
||||||
if isList value then
|
|
||||||
if length value > 0 then
|
|
||||||
head value
|
|
||||||
else
|
|
||||||
unnamed
|
|
||||||
else
|
|
||||||
value;
|
|
||||||
res =
|
|
||||||
{ inherit (def) file;
|
|
||||||
value = listToAttrs (
|
|
||||||
imap1 (elemIdx: elem:
|
|
||||||
{ name = nameValueNew (elem.${nameAttr} or (unnamed elemIdx)) (unnamed elemIdx);
|
|
||||||
value = elem;
|
|
||||||
}) def.value);
|
|
||||||
};
|
|
||||||
option = concatStringsSep "." loc;
|
|
||||||
sample = take 3 def.value;
|
|
||||||
more = lib.optionalString (length def.value > 3) "... ";
|
|
||||||
list = concatMapStrings (x: ''{ ${nameAttr} = ${nameValueOld (x.${nameAttr} or "unnamed")}; ...} '') sample;
|
|
||||||
set = concatMapStrings (x: ''${nameValueNew (x.${nameAttr} or "unnamed") "unnamed"} = {...}; '') sample;
|
|
||||||
msg = ''
|
|
||||||
In file ${def.file}
|
|
||||||
a list is being assigned to the option config.${option}.
|
|
||||||
This will soon be an error as type loaOf is deprecated.
|
|
||||||
See https://github.com/NixOS/nixpkgs/pull/63103 for more information.
|
|
||||||
Do
|
|
||||||
${option} =
|
|
||||||
{ ${set}${more}}
|
|
||||||
instead of
|
|
||||||
${option} =
|
|
||||||
[ ${list}${more}]
|
|
||||||
'';
|
|
||||||
in
|
|
||||||
lib.warn msg res
|
|
||||||
else
|
|
||||||
def;
|
|
||||||
attrOnly = attrsOf elemType;
|
|
||||||
in mkOptionType rec {
|
|
||||||
name = "loaOf";
|
|
||||||
description = "list or attribute set of ${elemType.description}s";
|
|
||||||
check = x: isList x || isAttrs x;
|
|
||||||
merge = loc: defs: attrOnly.merge loc (convertAllLists loc defs);
|
|
||||||
emptyValue = { value = {}; };
|
|
||||||
getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["<name?>"]);
|
|
||||||
getSubModules = elemType.getSubModules;
|
|
||||||
substSubModules = m: loaOf (elemType.substSubModules m);
|
|
||||||
functor = (defaultFunctor name) // { wrapped = elemType; };
|
|
||||||
};
|
|
||||||
|
|
||||||
# Value of given type but with no merging (i.e. `uniq list`s are not concatenated).
|
# Value of given type but with no merging (i.e. `uniq list`s are not concatenated).
|
||||||
uniq = elemType: mkOptionType rec {
|
uniq = elemType: mkOptionType rec {
|
||||||
|
@ -2879,6 +2879,12 @@
|
|||||||
githubId = 5918766;
|
githubId = 5918766;
|
||||||
name = "Franz Thoma";
|
name = "Franz Thoma";
|
||||||
};
|
};
|
||||||
|
fooker = {
|
||||||
|
email = "fooker@lab.sh";
|
||||||
|
github = "fooker";
|
||||||
|
githubId = 405105;
|
||||||
|
name = "Dustin Frisch";
|
||||||
|
};
|
||||||
forkk = {
|
forkk = {
|
||||||
email = "forkk@forkk.net";
|
email = "forkk@forkk.net";
|
||||||
github = "forkk";
|
github = "forkk";
|
||||||
@ -4092,6 +4098,12 @@
|
|||||||
githubId = 1918771;
|
githubId = 1918771;
|
||||||
name = "Joe Doyle";
|
name = "Joe Doyle";
|
||||||
};
|
};
|
||||||
|
jperras = {
|
||||||
|
email = "joel@nerderati.com";
|
||||||
|
github = "jperras";
|
||||||
|
githubId = 20675;
|
||||||
|
name = "Joël Perras";
|
||||||
|
};
|
||||||
jpierre03 = {
|
jpierre03 = {
|
||||||
email = "nix@prunetwork.fr";
|
email = "nix@prunetwork.fr";
|
||||||
github = "jpierre03";
|
github = "jpierre03";
|
||||||
@ -4304,6 +4316,12 @@
|
|||||||
githubId = 494012;
|
githubId = 494012;
|
||||||
name = "Kevin Cox";
|
name = "Kevin Cox";
|
||||||
};
|
};
|
||||||
|
kfollesdal = {
|
||||||
|
email = "kfollesdal@gmail.com";
|
||||||
|
github = "kfollesdal";
|
||||||
|
githubId = 546087;
|
||||||
|
name = "Kristoffer K. Føllesdal";
|
||||||
|
};
|
||||||
khumba = {
|
khumba = {
|
||||||
email = "bog@khumba.net";
|
email = "bog@khumba.net";
|
||||||
github = "khumba";
|
github = "khumba";
|
||||||
@ -7169,6 +7187,16 @@
|
|||||||
githubId = 3621083;
|
githubId = 3621083;
|
||||||
name = "Roosembert (Roosemberth) Palacios";
|
name = "Roosembert (Roosemberth) Palacios";
|
||||||
};
|
};
|
||||||
|
rople380 = {
|
||||||
|
name = "rople380";
|
||||||
|
email = "55679162+rople380@users.noreply.github.com";
|
||||||
|
github = "rople380";
|
||||||
|
githubId = 55679162;
|
||||||
|
keys = [{
|
||||||
|
longkeyid = "rsa2048/0x8526B7574A536236";
|
||||||
|
fingerprint = "1401 1B63 393D 16C1 AA9C C521 8526 B757 4A53 6236";
|
||||||
|
}];
|
||||||
|
};
|
||||||
royneary = {
|
royneary = {
|
||||||
email = "christian@ulrich.earth";
|
email = "christian@ulrich.earth";
|
||||||
github = "royneary";
|
github = "royneary";
|
||||||
@ -7355,6 +7383,12 @@
|
|||||||
githubId = 1153271;
|
githubId = 1153271;
|
||||||
name = "Sander van der Burg";
|
name = "Sander van der Burg";
|
||||||
};
|
};
|
||||||
|
sarcasticadmin = {
|
||||||
|
email = "rob@sarcasticadmin.com";
|
||||||
|
github = "sarcasticadmin";
|
||||||
|
githubId = 30531572;
|
||||||
|
name = "Robert James Hernandez";
|
||||||
|
};
|
||||||
sargon = {
|
sargon = {
|
||||||
email = "danielehlers@mindeye.net";
|
email = "danielehlers@mindeye.net";
|
||||||
github = "sargon";
|
github = "sargon";
|
||||||
@ -7989,6 +8023,12 @@
|
|||||||
githubId = 65870;
|
githubId = 65870;
|
||||||
name = "Сухарик";
|
name = "Сухарик";
|
||||||
};
|
};
|
||||||
|
SuperSandro2000 = {
|
||||||
|
email = "sandro.jaeckel@gmail.com";
|
||||||
|
github = "SuperSandro2000";
|
||||||
|
githubId = 7258858;
|
||||||
|
name = "Sandro Jäckel";
|
||||||
|
};
|
||||||
SuprDewd = {
|
SuprDewd = {
|
||||||
email = "suprdewd@gmail.com";
|
email = "suprdewd@gmail.com";
|
||||||
github = "SuprDewd";
|
github = "SuprDewd";
|
||||||
@ -9488,6 +9528,12 @@
|
|||||||
github = "fzakaria";
|
github = "fzakaria";
|
||||||
githubId = 605070;
|
githubId = 605070;
|
||||||
};
|
};
|
||||||
|
nagisa = {
|
||||||
|
name = "Simonas Kazlauskas";
|
||||||
|
email = "nixpkgs@kazlauskas.me";
|
||||||
|
github = "nagisa";
|
||||||
|
githubId = 679122;
|
||||||
|
};
|
||||||
yevhenshymotiuk = {
|
yevhenshymotiuk = {
|
||||||
name = "Yevhen Shymotiuk";
|
name = "Yevhen Shymotiuk";
|
||||||
email = "yevhenshymotiuk@gmail.com";
|
email = "yevhenshymotiuk@gmail.com";
|
||||||
|
@ -35,6 +35,10 @@ lua-cmsgpack,,,,,
|
|||||||
lua-iconv,,,,,
|
lua-iconv,,,,,
|
||||||
lua-lsp,,http://luarocks.org/dev,,,
|
lua-lsp,,http://luarocks.org/dev,,,
|
||||||
lua-messagepack,,,,,
|
lua-messagepack,,,,,
|
||||||
|
lua-resty-http,,,,,
|
||||||
|
lua-resty-jwt,,,,,
|
||||||
|
lua-resty-openidc,,,,,
|
||||||
|
lua-resty-session,,,,,
|
||||||
lua-term,,,,,
|
lua-term,,,,,
|
||||||
lua-toml,,,,,
|
lua-toml,,,,,
|
||||||
lua-zlib,,,,,koral
|
lua-zlib,,,,,koral
|
||||||
|
|
@ -58,9 +58,9 @@
|
|||||||
Like <literal>boot.debug1</literal> or
|
Like <literal>boot.debug1</literal> or
|
||||||
<literal>boot.debug1devices</literal>, but runs stage1 until all
|
<literal>boot.debug1devices</literal>, but runs stage1 until all
|
||||||
filesystems that are mounted during initrd are mounted (see
|
filesystems that are mounted during initrd are mounted (see
|
||||||
<option><link linkend="opt-fileSystems._name__.neededForBoot">neededForBoot</link></option>
|
<option><link linkend="opt-fileSystems._name_.neededForBoot">neededForBoot</link></option>
|
||||||
). As a motivating example, this could be useful if you've forgotten to set
|
). As a motivating example, this could be useful if you've forgotten to set
|
||||||
<option><link linkend="opt-fileSystems._name__.neededForBoot">neededForBoot</link></option>
|
<option><link linkend="opt-fileSystems._name_.neededForBoot">neededForBoot</link></option>
|
||||||
on a file system.
|
on a file system.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
<screen>
|
<screen>
|
||||||
# nixos-container create foo --config '
|
# nixos-container create foo --config '
|
||||||
<xref linkend="opt-services.openssh.enable"/> = true;
|
<xref linkend="opt-services.openssh.enable"/> = true;
|
||||||
<link linkend="opt-users.users._name__.openssh.authorizedKeys.keys">users.users.root.openssh.authorizedKeys.keys</link> = ["ssh-dss AAAAB3N…"];
|
<link linkend="opt-users.users._name_.openssh.authorizedKeys.keys">users.users.root.openssh.authorizedKeys.keys</link> = ["ssh-dss AAAAB3N…"];
|
||||||
'
|
'
|
||||||
</screen>
|
</screen>
|
||||||
By default the next free address in the <literal>10.233.0.0/16</literal> subnet will be chosen
|
By default the next free address in the <literal>10.233.0.0/16</literal> subnet will be chosen
|
||||||
|
@ -23,12 +23,12 @@
|
|||||||
<link xlink:href="https://www.freedesktop.org/software/systemd/man/systemd-fstab-generator.html">systemd-fstab-generator</link>.
|
<link xlink:href="https://www.freedesktop.org/software/systemd/man/systemd-fstab-generator.html">systemd-fstab-generator</link>.
|
||||||
The filesystem will be mounted automatically unless
|
The filesystem will be mounted automatically unless
|
||||||
<literal>"noauto"</literal> is present in <link
|
<literal>"noauto"</literal> is present in <link
|
||||||
linkend="opt-fileSystems._name__.options">options</link>.
|
linkend="opt-fileSystems._name_.options">options</link>.
|
||||||
<literal>"noauto"</literal> filesystems can be mounted explicitly using
|
<literal>"noauto"</literal> filesystems can be mounted explicitly using
|
||||||
<command>systemctl</command> e.g. <command>systemctl start
|
<command>systemctl</command> e.g. <command>systemctl start
|
||||||
data.mount</command>.
|
data.mount</command>.
|
||||||
Mount points are created automatically if they don’t already exist. For
|
Mount points are created automatically if they don’t already exist. For
|
||||||
<option><link linkend="opt-fileSystems._name__.device">device</link></option>,
|
<option><link linkend="opt-fileSystems._name_.device">device</link></option>,
|
||||||
it’s best to use the topology-independent device aliases in
|
it’s best to use the topology-independent device aliases in
|
||||||
<filename>/dev/disk/by-label</filename> and
|
<filename>/dev/disk/by-label</filename> and
|
||||||
<filename>/dev/disk/by-uuid</filename>, as these don’t change if the
|
<filename>/dev/disk/by-uuid</filename>, as these don’t change if the
|
||||||
@ -36,7 +36,7 @@
|
|||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
You can usually omit the file system type
|
You can usually omit the file system type
|
||||||
(<option><link linkend="opt-fileSystems._name__.fsType">fsType</link></option>),
|
(<option><link linkend="opt-fileSystems._name_.fsType">fsType</link></option>),
|
||||||
since <command>mount</command> can usually detect the type and load the
|
since <command>mount</command> can usually detect the type and load the
|
||||||
necessary kernel module automatically. However, if the file system is needed
|
necessary kernel module automatically. However, if the file system is needed
|
||||||
at early boot (in the initial ramdisk) and is not <literal>ext2</literal>,
|
at early boot (in the initial ramdisk) and is not <literal>ext2</literal>,
|
||||||
@ -49,7 +49,7 @@
|
|||||||
System startup will fail if any of the filesystems fails to mount, dropping
|
System startup will fail if any of the filesystems fails to mount, dropping
|
||||||
you to the emergency shell. You can make a mount asynchronous and
|
you to the emergency shell. You can make a mount asynchronous and
|
||||||
non-critical by adding
|
non-critical by adding
|
||||||
<literal><link linkend="opt-fileSystems._name__.options">options</link> = [
|
<literal><link linkend="opt-fileSystems._name_.options">options</link> = [
|
||||||
"nofail" ];</literal>.
|
"nofail" ];</literal>.
|
||||||
</para>
|
</para>
|
||||||
</note>
|
</note>
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
automatically configure network interfaces. However, you can configure an
|
automatically configure network interfaces. However, you can configure an
|
||||||
interface manually as follows:
|
interface manually as follows:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
<link linkend="opt-networking.interfaces._name__.ipv4.addresses">networking.interfaces.eth0.ipv4.addresses</link> = [ {
|
<link linkend="opt-networking.interfaces._name_.ipv4.addresses">networking.interfaces.eth0.ipv4.addresses</link> = [ {
|
||||||
address = "192.168.1.2";
|
address = "192.168.1.2";
|
||||||
prefixLength = 24;
|
prefixLength = 24;
|
||||||
} ];
|
} ];
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
As with IPv4 networking interfaces are automatically configured via DHCPv6.
|
As with IPv4 networking interfaces are automatically configured via DHCPv6.
|
||||||
You can configure an interface manually:
|
You can configure an interface manually:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
<link linkend="opt-networking.interfaces._name__.ipv6.addresses">networking.interfaces.eth0.ipv6.addresses</link> = [ {
|
<link linkend="opt-networking.interfaces._name_.ipv6.addresses">networking.interfaces.eth0.ipv6.addresses</link> = [ {
|
||||||
address = "fe00:aa:bb:cc::2";
|
address = "fe00:aa:bb:cc::2";
|
||||||
prefixLength = 64;
|
prefixLength = 64;
|
||||||
} ];
|
} ];
|
||||||
|
@ -30,7 +30,7 @@ Enter passphrase for /dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d: ***
|
|||||||
<filename>/</filename>, add the following to
|
<filename>/</filename>, add the following to
|
||||||
<filename>configuration.nix</filename>:
|
<filename>configuration.nix</filename>:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
<link linkend="opt-boot.initrd.luks.devices._name__.device">boot.initrd.luks.devices.crypted.device</link> = "/dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d";
|
<link linkend="opt-boot.initrd.luks.devices._name_.device">boot.initrd.luks.devices.crypted.device</link> = "/dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d";
|
||||||
<xref linkend="opt-fileSystems"/>."/".device = "/dev/mapper/crypted";
|
<xref linkend="opt-fileSystems"/>."/".device = "/dev/mapper/crypted";
|
||||||
</programlisting>
|
</programlisting>
|
||||||
Should grub be used as bootloader, and <filename>/boot</filename> is located
|
Should grub be used as bootloader, and <filename>/boot</filename> is located
|
||||||
@ -60,13 +60,13 @@ Added to key to device /dev/sda2, slot: 2
|
|||||||
To ensure that this file system is decrypted using the FIDO2 compatible key, add the following to <filename>configuration.nix</filename>:
|
To ensure that this file system is decrypted using the FIDO2 compatible key, add the following to <filename>configuration.nix</filename>:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
<link linkend="opt-boot.initrd.luks.fido2Support">boot.initrd.luks.fido2Support</link> = true;
|
<link linkend="opt-boot.initrd.luks.fido2Support">boot.initrd.luks.fido2Support</link> = true;
|
||||||
<link linkend="opt-boot.initrd.luks.devices._name__.fido2.credential">boot.initrd.luks.devices."/dev/sda2".fido2.credential</link> = "f1d00200108b9d6e849a8b388da457688e3dd653b4e53770012d8f28e5d3b269865038c346802f36f3da7278b13ad6a3bb6a1452e24ebeeaa24ba40eef559b1b287d2a2f80b7";
|
<link linkend="opt-boot.initrd.luks.devices._name_.fido2.credential">boot.initrd.luks.devices."/dev/sda2".fido2.credential</link> = "f1d00200108b9d6e849a8b388da457688e3dd653b4e53770012d8f28e5d3b269865038c346802f36f3da7278b13ad6a3bb6a1452e24ebeeaa24ba40eef559b1b287d2a2f80b7";
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
You can also use the FIDO2 passwordless setup, but for security reasons, you might want to enable it only when your device is PIN protected, such as <link xlink:href="https://trezor.io/">Trezor</link>.
|
You can also use the FIDO2 passwordless setup, but for security reasons, you might want to enable it only when your device is PIN protected, such as <link xlink:href="https://trezor.io/">Trezor</link>.
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
<link linkend="opt-boot.initrd.luks.devices._name__.fido2.passwordLess">boot.initrd.luks.devices."/dev/sda2".fido2.passwordLess</link> = true;
|
<link linkend="opt-boot.initrd.luks.devices._name_.fido2.passwordLess">boot.initrd.luks.devices."/dev/sda2".fido2.passwordLess</link> = true;
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
</section>
|
</section>
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
All users that should have permission to change network settings must belong
|
All users that should have permission to change network settings must belong
|
||||||
to the <code>networkmanager</code> group:
|
to the <code>networkmanager</code> group:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
<link linkend="opt-users.users._name__.extraGroups">users.users.alice.extraGroups</link> = [ "networkmanager" ];
|
<link linkend="opt-users.users._name_.extraGroups">users.users.alice.extraGroups</link> = [ "networkmanager" ];
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
follows:
|
follows:
|
||||||
<!-- FIXME: this might not work if the user is unmanaged. -->
|
<!-- FIXME: this might not work if the user is unmanaged. -->
|
||||||
<programlisting>
|
<programlisting>
|
||||||
<link linkend="opt-users.users._name__.openssh.authorizedKeys.keys">users.users.alice.openssh.authorizedKeys.keys</link> =
|
<link linkend="opt-users.users._name_.openssh.authorizedKeys.keys">users.users.alice.openssh.authorizedKeys.keys</link> =
|
||||||
[ "ssh-dss AAAAB3NzaC1kc3MAAACBAPIkGWVEt4..." ];
|
[ "ssh-dss AAAAB3NzaC1kc3MAAACBAPIkGWVEt4..." ];
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
|
@ -11,11 +11,11 @@
|
|||||||
that a user account named <literal>alice</literal> shall exist:
|
that a user account named <literal>alice</literal> shall exist:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
<xref linkend="opt-users.users"/>.alice = {
|
<xref linkend="opt-users.users"/>.alice = {
|
||||||
<link linkend="opt-users.users._name__.isNormalUser">isNormalUser</link> = true;
|
<link linkend="opt-users.users._name_.isNormalUser">isNormalUser</link> = true;
|
||||||
<link linkend="opt-users.users._name__.home">home</link> = "/home/alice";
|
<link linkend="opt-users.users._name_.home">home</link> = "/home/alice";
|
||||||
<link linkend="opt-users.users._name__.description">description</link> = "Alice Foobar";
|
<link linkend="opt-users.users._name_.description">description</link> = "Alice Foobar";
|
||||||
<link linkend="opt-users.users._name__.extraGroups">extraGroups</link> = [ "wheel" "networkmanager" ];
|
<link linkend="opt-users.users._name_.extraGroups">extraGroups</link> = [ "wheel" "networkmanager" ];
|
||||||
<link linkend="opt-users.users._name__.openssh.authorizedKeys.keys">openssh.authorizedKeys.keys</link> = [ "ssh-dss AAAAB3Nza... alice@foobar" ];
|
<link linkend="opt-users.users._name_.openssh.authorizedKeys.keys">openssh.authorizedKeys.keys</link> = [ "ssh-dss AAAAB3Nza... alice@foobar" ];
|
||||||
};
|
};
|
||||||
</programlisting>
|
</programlisting>
|
||||||
Note that <literal>alice</literal> is a member of the
|
Note that <literal>alice</literal> is a member of the
|
||||||
@ -36,7 +36,7 @@
|
|||||||
account will cease to exist. Also, imperative commands for managing users and
|
account will cease to exist. Also, imperative commands for managing users and
|
||||||
groups, such as useradd, are no longer available. Passwords may still be
|
groups, such as useradd, are no longer available. Passwords may still be
|
||||||
assigned by setting the user's
|
assigned by setting the user's
|
||||||
<link linkend="opt-users.users._name__.hashedPassword">hashedPassword</link>
|
<link linkend="opt-users.users._name_.hashedPassword">hashedPassword</link>
|
||||||
option. A hashed password can be generated using <command>mkpasswd -m
|
option. A hashed password can be generated using <command>mkpasswd -m
|
||||||
sha-512</command> after installing the <literal>mkpasswd</literal> package.
|
sha-512</command> after installing the <literal>mkpasswd</literal> package.
|
||||||
</para>
|
</para>
|
||||||
|
@ -385,17 +385,6 @@
|
|||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>types.loaOf</varname> <replaceable>t</replaceable>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
An attribute set or a list of <replaceable>t</replaceable> type. Multiple
|
|
||||||
definitions are merged according to the value.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>
|
<term>
|
||||||
<varname>types.nullOr</varname> <replaceable>t</replaceable>
|
<varname>types.nullOr</varname> <replaceable>t</replaceable>
|
||||||
|
@ -78,7 +78,7 @@
|
|||||||
<literal>mutableUsers = false</literal>. Another way is to temporarily add
|
<literal>mutableUsers = false</literal>. Another way is to temporarily add
|
||||||
the following to your configuration:
|
the following to your configuration:
|
||||||
<screen>
|
<screen>
|
||||||
<link linkend="opt-users.users._name__.initialHashedPassword">users.users.your-user.initialHashedPassword</link> = "test";
|
<link linkend="opt-users.users._name_.initialHashedPassword">users.users.your-user.initialHashedPassword</link> = "test";
|
||||||
</screen>
|
</screen>
|
||||||
<emphasis>Important:</emphasis> delete the $hostname.qcow2 file if you have
|
<emphasis>Important:</emphasis> delete the $hostname.qcow2 file if you have
|
||||||
started the virtual machine at least once without the right users, otherwise
|
started the virtual machine at least once without the right users, otherwise
|
||||||
|
@ -211,7 +211,7 @@ nixpkgs https://nixos.org/channels/nixpkgs-unstable</screen>
|
|||||||
use <literal>sudo</literal>)
|
use <literal>sudo</literal>)
|
||||||
</para>
|
</para>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
<link linkend="opt-users.users._name__.initialHashedPassword">users.users.root.initialHashedPassword</link> = "";
|
<link linkend="opt-users.users._name_.initialHashedPassword">users.users.root.initialHashedPassword</link> = "";
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
@ -550,7 +550,7 @@ Retype new UNIX password: ***</screen>
|
|||||||
# Note: setting fileSystems is generally not
|
# Note: setting fileSystems is generally not
|
||||||
# necessary, since nixos-generate-config figures them out
|
# necessary, since nixos-generate-config figures them out
|
||||||
# automatically in hardware-configuration.nix.
|
# automatically in hardware-configuration.nix.
|
||||||
#<link linkend="opt-fileSystems._name__.device">fileSystems."/".device</link> = "/dev/disk/by-label/nixos";
|
#<link linkend="opt-fileSystems._name_.device">fileSystems."/".device</link> = "/dev/disk/by-label/nixos";
|
||||||
|
|
||||||
# Enable the OpenSSH server.
|
# Enable the OpenSSH server.
|
||||||
services.sshd.enable = true;
|
services.sshd.enable = true;
|
||||||
|
@ -796,7 +796,7 @@ users.users.me =
|
|||||||
or any other display manager in NixOS as they all support auto-login. If you used this module specifically
|
or any other display manager in NixOS as they all support auto-login. If you used this module specifically
|
||||||
because it permitted root auto-login you can override the lightdm-autologin pam module like:
|
because it permitted root auto-login you can override the lightdm-autologin pam module like:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
<link xlink:href="#opt-security.pam.services._name__.text">security.pam.services.lightdm-autologin.text</link> = lib.mkForce ''
|
<link xlink:href="#opt-security.pam.services._name_.text">security.pam.services.lightdm-autologin.text</link> = lib.mkForce ''
|
||||||
auth requisite pam_nologin.so
|
auth requisite pam_nologin.so
|
||||||
auth required pam_succeed_if.so quiet
|
auth required pam_succeed_if.so quiet
|
||||||
auth required pam_permit.so
|
auth required pam_permit.so
|
||||||
|
@ -233,6 +233,11 @@ GRANT ALL PRIVILEGES ON *.* TO 'mysql'@'localhost' WITH GRANT OPTION;
|
|||||||
<para>
|
<para>
|
||||||
There is a new <xref linkend="opt-security.doas.enable"/> module that provides <command>doas</command>, a lighter alternative to <command>sudo</command> with many of the same features.
|
There is a new <xref linkend="opt-security.doas.enable"/> module that provides <command>doas</command>, a lighter alternative to <command>sudo</command> with many of the same features.
|
||||||
</para>
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<link xlink:href="https://hercules-ci.com">Hercules CI</link> Agent is a specialized build agent for projects built with Nix. See the <link xlink:href="https://nixos.org/nixos/options.html#services.hercules-ci-agent">options</link> and <link xlink:href="https://docs.hercules-ci.com/hercules-ci/getting-started/#deploy-agent">setup</link>.
|
||||||
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
@ -762,6 +767,21 @@ CREATE ROLE postgres LOGIN SUPERUSER;
|
|||||||
See <link xlink:href="https://github.com/NixOS/nixpkgs/pull/82743#issuecomment-674520472">the PR that changed this</link> for more info.
|
See <link xlink:href="https://github.com/NixOS/nixpkgs/pull/82743#issuecomment-674520472">the PR that changed this</link> for more info.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
For NixOS configuration options, the type <literal>loaOf</literal>, after
|
||||||
|
its initial deprecation in release 20.03, has been removed. In NixOS and
|
||||||
|
Nixpkgs options using this type have been converted to <literal>attrsOf</literal>.
|
||||||
|
For more information on this change have look at these links:
|
||||||
|
<link xlink:href="https://github.com/NixOS/nixpkgs/issues/1800">issue #1800</link>,
|
||||||
|
<link xlink:href="https://github.com/NixOS/nixpkgs/pull/63103">PR #63103</link>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal>config.systemd.services.${name}.path</literal> now returns a list of paths instead of a colon-separated string.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@ -992,6 +1012,53 @@ services.transmission.settings.rpc-bind-address = "0.0.0.0";
|
|||||||
the previous behaviour using <literal>undervolt.useTimer</literal>.
|
the previous behaviour using <literal>undervolt.useTimer</literal>.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Agda has been heavily reworked.
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal>agda.mkDerivation</literal> has been heavily changed and
|
||||||
|
is now located at <package>agdaPackages.mkDerivation</package>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
New top-level packages <package>agda</package> and
|
||||||
|
<literal>agda.withPackages</literal> have been added, the second
|
||||||
|
of which sets up agda with access to chosen libraries.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
All agda libraries now live under
|
||||||
|
<literal>agdaPackages</literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Many broken libraries have been removed.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
See the <link
|
||||||
|
xlink:href="https://nixos.org/nixpkgs/manual/#agda">new
|
||||||
|
documentation</link> for more information.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The <literal>deepin</literal> package set has been removed from
|
||||||
|
nixpkgs. It was a work in progress to package the
|
||||||
|
<link xlink:href="https://www.deepin.org/en/dde/">Deepin Desktop Environment (DDE)</link>,
|
||||||
|
including libraries, tools and applications, and it was still
|
||||||
|
missing a service to lauch the desktop environment. It has shown
|
||||||
|
to no longer be a feasible goal due to reasons discussed in
|
||||||
|
<link xlink:href="https://github.com/NixOS/nixpkgs/issues/94870">issue #94870</link>.
|
||||||
|
The package <literal>netease-cloud-music</literal> has also been
|
||||||
|
removed, as it depends on libraries from deepin.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
<title>Configuration Options</title>
|
<title>Configuration Options</title>
|
||||||
<variablelist xml:id="configuration-variable-list">
|
<variablelist xml:id="configuration-variable-list">
|
||||||
<xsl:for-each select="attrs">
|
<xsl:for-each select="attrs">
|
||||||
<xsl:variable name="id" select="concat('opt-', str:replace(str:replace(str:replace(str:replace(attr[@name = 'name']/string/@value, '*', '_'), '<', '_'), '>', '_'), '?', '_'))" />
|
<xsl:variable name="id" select="concat('opt-', str:replace(str:replace(str:replace(attr[@name = 'name']/string/@value, '*', '_'), '<', '_'), '>', '_'))" />
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term xlink:href="#{$id}">
|
<term xlink:href="#{$id}">
|
||||||
<xsl:attribute name="xml:id"><xsl:value-of select="$id"/></xsl:attribute>
|
<xsl:attribute name="xml:id"><xsl:value-of select="$id"/></xsl:attribute>
|
||||||
|
@ -1,14 +1,19 @@
|
|||||||
#! /somewhere/python3
|
#! /somewhere/python3
|
||||||
|
from contextlib import contextmanager, _GeneratorContextManager
|
||||||
|
from queue import Queue, Empty
|
||||||
|
from typing import Tuple, Any, Callable, Dict, Iterator, Optional, List
|
||||||
|
from xml.sax.saxutils import XMLGenerator
|
||||||
|
import queue
|
||||||
|
import io
|
||||||
|
import _thread
|
||||||
import argparse
|
import argparse
|
||||||
import atexit
|
import atexit
|
||||||
import base64
|
import base64
|
||||||
import io
|
import codecs
|
||||||
import itertools
|
|
||||||
import logging
|
|
||||||
import os
|
import os
|
||||||
import pathlib
|
import pathlib
|
||||||
|
import ptpython.repl
|
||||||
import pty
|
import pty
|
||||||
import queue
|
|
||||||
import re
|
import re
|
||||||
import shlex
|
import shlex
|
||||||
import shutil
|
import shutil
|
||||||
@ -16,12 +21,9 @@ import socket
|
|||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import _thread
|
|
||||||
import time
|
import time
|
||||||
from contextlib import contextmanager
|
import traceback
|
||||||
from typing import Any, Callable, Dict, Iterator, List, Optional, Tuple
|
import unicodedata
|
||||||
|
|
||||||
import ptpython.repl
|
|
||||||
|
|
||||||
CHAR_TO_KEY = {
|
CHAR_TO_KEY = {
|
||||||
"A": "shift-a",
|
"A": "shift-a",
|
||||||
@ -86,24 +88,13 @@ CHAR_TO_KEY = {
|
|||||||
")": "shift-0x0B",
|
")": "shift-0x0B",
|
||||||
}
|
}
|
||||||
|
|
||||||
# Forward reference
|
# Forward references
|
||||||
|
log: "Logger"
|
||||||
machines: "List[Machine]"
|
machines: "List[Machine]"
|
||||||
|
|
||||||
logging.basicConfig(format="%(message)s")
|
|
||||||
logger = logging.getLogger("test-driver")
|
|
||||||
logger.setLevel(logging.INFO)
|
|
||||||
|
|
||||||
machine_colours_iter = (
|
def eprint(*args: object, **kwargs: Any) -> None:
|
||||||
"\x1b[{}m".format(x) for x in itertools.cycle(reversed(range(31, 37)))
|
print(*args, file=sys.stderr, **kwargs)
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class MachineLogAdapter(logging.LoggerAdapter):
|
|
||||||
def process(self, msg: str, kwargs: Any) -> Tuple[str, Any]:
|
|
||||||
return (
|
|
||||||
f"{self.extra['colour_code']}{self.extra['machine']}\x1b[39m: {msg}",
|
|
||||||
kwargs,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def make_command(args: list) -> str:
|
def make_command(args: list) -> str:
|
||||||
@ -111,7 +102,8 @@ def make_command(args: list) -> str:
|
|||||||
|
|
||||||
|
|
||||||
def create_vlan(vlan_nr: str) -> Tuple[str, str, "subprocess.Popen[bytes]", Any]:
|
def create_vlan(vlan_nr: str) -> Tuple[str, str, "subprocess.Popen[bytes]", Any]:
|
||||||
logger.info(f"starting VDE switch for network {vlan_nr}")
|
global log
|
||||||
|
log.log("starting VDE switch for network {}".format(vlan_nr))
|
||||||
vde_socket = tempfile.mkdtemp(
|
vde_socket = tempfile.mkdtemp(
|
||||||
prefix="nixos-test-vde-", suffix="-vde{}.ctl".format(vlan_nr)
|
prefix="nixos-test-vde-", suffix="-vde{}.ctl".format(vlan_nr)
|
||||||
)
|
)
|
||||||
@ -150,6 +142,70 @@ def retry(fn: Callable) -> None:
|
|||||||
raise Exception("action timed out")
|
raise Exception("action timed out")
|
||||||
|
|
||||||
|
|
||||||
|
class Logger:
|
||||||
|
def __init__(self) -> None:
|
||||||
|
self.logfile = os.environ.get("LOGFILE", "/dev/null")
|
||||||
|
self.logfile_handle = codecs.open(self.logfile, "wb")
|
||||||
|
self.xml = XMLGenerator(self.logfile_handle, encoding="utf-8")
|
||||||
|
self.queue: "Queue[Dict[str, str]]" = Queue()
|
||||||
|
|
||||||
|
self.xml.startDocument()
|
||||||
|
self.xml.startElement("logfile", attrs={})
|
||||||
|
|
||||||
|
def close(self) -> None:
|
||||||
|
self.xml.endElement("logfile")
|
||||||
|
self.xml.endDocument()
|
||||||
|
self.logfile_handle.close()
|
||||||
|
|
||||||
|
def sanitise(self, message: str) -> str:
|
||||||
|
return "".join(ch for ch in message if unicodedata.category(ch)[0] != "C")
|
||||||
|
|
||||||
|
def maybe_prefix(self, message: str, attributes: Dict[str, str]) -> str:
|
||||||
|
if "machine" in attributes:
|
||||||
|
return "{}: {}".format(attributes["machine"], message)
|
||||||
|
return message
|
||||||
|
|
||||||
|
def log_line(self, message: str, attributes: Dict[str, str]) -> None:
|
||||||
|
self.xml.startElement("line", attributes)
|
||||||
|
self.xml.characters(message)
|
||||||
|
self.xml.endElement("line")
|
||||||
|
|
||||||
|
def log(self, message: str, attributes: Dict[str, str] = {}) -> None:
|
||||||
|
eprint(self.maybe_prefix(message, attributes))
|
||||||
|
self.drain_log_queue()
|
||||||
|
self.log_line(message, attributes)
|
||||||
|
|
||||||
|
def enqueue(self, message: Dict[str, str]) -> None:
|
||||||
|
self.queue.put(message)
|
||||||
|
|
||||||
|
def drain_log_queue(self) -> None:
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
item = self.queue.get_nowait()
|
||||||
|
attributes = {"machine": item["machine"], "type": "serial"}
|
||||||
|
self.log_line(self.sanitise(item["msg"]), attributes)
|
||||||
|
except Empty:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def nested(self, message: str, attributes: Dict[str, str] = {}) -> Iterator[None]:
|
||||||
|
eprint(self.maybe_prefix(message, attributes))
|
||||||
|
|
||||||
|
self.xml.startElement("nest", attrs={})
|
||||||
|
self.xml.startElement("head", attributes)
|
||||||
|
self.xml.characters(message)
|
||||||
|
self.xml.endElement("head")
|
||||||
|
|
||||||
|
tic = time.time()
|
||||||
|
self.drain_log_queue()
|
||||||
|
yield
|
||||||
|
self.drain_log_queue()
|
||||||
|
toc = time.time()
|
||||||
|
self.log("({:.2f} seconds)".format(toc - tic))
|
||||||
|
|
||||||
|
self.xml.endElement("nest")
|
||||||
|
|
||||||
|
|
||||||
class Machine:
|
class Machine:
|
||||||
def __init__(self, args: Dict[str, Any]) -> None:
|
def __init__(self, args: Dict[str, Any]) -> None:
|
||||||
if "name" in args:
|
if "name" in args:
|
||||||
@ -179,11 +235,8 @@ class Machine:
|
|||||||
self.pid: Optional[int] = None
|
self.pid: Optional[int] = None
|
||||||
self.socket = None
|
self.socket = None
|
||||||
self.monitor: Optional[socket.socket] = None
|
self.monitor: Optional[socket.socket] = None
|
||||||
|
self.logger: Logger = args["log"]
|
||||||
self.allow_reboot = args.get("allowReboot", False)
|
self.allow_reboot = args.get("allowReboot", False)
|
||||||
self.logger = MachineLogAdapter(
|
|
||||||
logger,
|
|
||||||
extra=dict(machine=self.name, colour_code=next(machine_colours_iter)),
|
|
||||||
)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create_startcommand(args: Dict[str, str]) -> str:
|
def create_startcommand(args: Dict[str, str]) -> str:
|
||||||
@ -239,6 +292,14 @@ class Machine:
|
|||||||
def is_up(self) -> bool:
|
def is_up(self) -> bool:
|
||||||
return self.booted and self.connected
|
return self.booted and self.connected
|
||||||
|
|
||||||
|
def log(self, msg: str) -> None:
|
||||||
|
self.logger.log(msg, {"machine": self.name})
|
||||||
|
|
||||||
|
def nested(self, msg: str, attrs: Dict[str, str] = {}) -> _GeneratorContextManager:
|
||||||
|
my_attrs = {"machine": self.name}
|
||||||
|
my_attrs.update(attrs)
|
||||||
|
return self.logger.nested(msg, my_attrs)
|
||||||
|
|
||||||
def wait_for_monitor_prompt(self) -> str:
|
def wait_for_monitor_prompt(self) -> str:
|
||||||
assert self.monitor is not None
|
assert self.monitor is not None
|
||||||
answer = ""
|
answer = ""
|
||||||
@ -253,7 +314,7 @@ class Machine:
|
|||||||
|
|
||||||
def send_monitor_command(self, command: str) -> str:
|
def send_monitor_command(self, command: str) -> str:
|
||||||
message = ("{}\n".format(command)).encode()
|
message = ("{}\n".format(command)).encode()
|
||||||
self.logger.info(f"sending monitor command: {command}")
|
self.log("sending monitor command: {}".format(command))
|
||||||
assert self.monitor is not None
|
assert self.monitor is not None
|
||||||
self.monitor.send(message)
|
self.monitor.send(message)
|
||||||
return self.wait_for_monitor_prompt()
|
return self.wait_for_monitor_prompt()
|
||||||
@ -320,19 +381,16 @@ class Machine:
|
|||||||
return self.execute("systemctl {}".format(q))
|
return self.execute("systemctl {}".format(q))
|
||||||
|
|
||||||
def require_unit_state(self, unit: str, require_state: str = "active") -> None:
|
def require_unit_state(self, unit: str, require_state: str = "active") -> None:
|
||||||
self.logger.info(
|
with self.nested(
|
||||||
f"checking if unit ‘{unit}’ has reached state '{require_state}'"
|
"checking if unit ‘{}’ has reached state '{}'".format(unit, require_state)
|
||||||
)
|
):
|
||||||
info = self.get_unit_info(unit)
|
info = self.get_unit_info(unit)
|
||||||
state = info["ActiveState"]
|
state = info["ActiveState"]
|
||||||
if state != require_state:
|
if state != require_state:
|
||||||
raise Exception(
|
raise Exception(
|
||||||
"Expected unit ‘{}’ to to be in state ".format(unit)
|
"Expected unit ‘{}’ to to be in state ".format(unit)
|
||||||
+ "'{}' but it is in state ‘{}’".format(require_state, state)
|
+ "'{}' but it is in state ‘{}’".format(require_state, state)
|
||||||
)
|
)
|
||||||
|
|
||||||
def log(self, message: str) -> None:
|
|
||||||
self.logger.info(message)
|
|
||||||
|
|
||||||
def execute(self, command: str) -> Tuple[int, str]:
|
def execute(self, command: str) -> Tuple[int, str]:
|
||||||
self.connect()
|
self.connect()
|
||||||
@ -356,25 +414,27 @@ class Machine:
|
|||||||
"""Execute each command and check that it succeeds."""
|
"""Execute each command and check that it succeeds."""
|
||||||
output = ""
|
output = ""
|
||||||
for command in commands:
|
for command in commands:
|
||||||
self.logger.info(f"must succeed: {command}")
|
with self.nested("must succeed: {}".format(command)):
|
||||||
(status, out) = self.execute(command)
|
(status, out) = self.execute(command)
|
||||||
if status != 0:
|
if status != 0:
|
||||||
self.logger.info(f"output: {out}")
|
self.log("output: {}".format(out))
|
||||||
raise Exception(
|
raise Exception(
|
||||||
"command `{}` failed (exit code {})".format(command, status)
|
"command `{}` failed (exit code {})".format(command, status)
|
||||||
)
|
)
|
||||||
output += out
|
output += out
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def fail(self, *commands: str) -> str:
|
def fail(self, *commands: str) -> str:
|
||||||
"""Execute each command and check that it fails."""
|
"""Execute each command and check that it fails."""
|
||||||
output = ""
|
output = ""
|
||||||
for command in commands:
|
for command in commands:
|
||||||
self.logger.info(f"must fail: {command}")
|
with self.nested("must fail: {}".format(command)):
|
||||||
(status, out) = self.execute(command)
|
(status, out) = self.execute(command)
|
||||||
if status == 0:
|
if status == 0:
|
||||||
raise Exception("command `{}` unexpectedly succeeded".format(command))
|
raise Exception(
|
||||||
output += out
|
"command `{}` unexpectedly succeeded".format(command)
|
||||||
|
)
|
||||||
|
output += out
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def wait_until_succeeds(self, command: str) -> str:
|
def wait_until_succeeds(self, command: str) -> str:
|
||||||
@ -388,9 +448,9 @@ class Machine:
|
|||||||
status, output = self.execute(command)
|
status, output = self.execute(command)
|
||||||
return status == 0
|
return status == 0
|
||||||
|
|
||||||
self.logger.info(f"waiting for success: {command}")
|
with self.nested("waiting for success: {}".format(command)):
|
||||||
retry(check_success)
|
retry(check_success)
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def wait_until_fails(self, command: str) -> str:
|
def wait_until_fails(self, command: str) -> str:
|
||||||
"""Wait until a command returns failure.
|
"""Wait until a command returns failure.
|
||||||
@ -403,21 +463,21 @@ class Machine:
|
|||||||
status, output = self.execute(command)
|
status, output = self.execute(command)
|
||||||
return status != 0
|
return status != 0
|
||||||
|
|
||||||
self.logger.info(f"waiting for failure: {command}")
|
with self.nested("waiting for failure: {}".format(command)):
|
||||||
retry(check_failure)
|
retry(check_failure)
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def wait_for_shutdown(self) -> None:
|
def wait_for_shutdown(self) -> None:
|
||||||
if not self.booted:
|
if not self.booted:
|
||||||
return
|
return
|
||||||
|
|
||||||
self.logger.info("waiting for the VM to power off")
|
with self.nested("waiting for the VM to power off"):
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
self.process.wait()
|
self.process.wait()
|
||||||
|
|
||||||
self.pid = None
|
self.pid = None
|
||||||
self.booted = False
|
self.booted = False
|
||||||
self.connected = False
|
self.connected = False
|
||||||
|
|
||||||
def get_tty_text(self, tty: str) -> str:
|
def get_tty_text(self, tty: str) -> str:
|
||||||
status, output = self.execute(
|
status, output = self.execute(
|
||||||
@ -435,19 +495,19 @@ class Machine:
|
|||||||
def tty_matches(last: bool) -> bool:
|
def tty_matches(last: bool) -> bool:
|
||||||
text = self.get_tty_text(tty)
|
text = self.get_tty_text(tty)
|
||||||
if last:
|
if last:
|
||||||
self.logger.info(
|
self.log(
|
||||||
f"Last chance to match /{regexp}/ on TTY{tty}, "
|
f"Last chance to match /{regexp}/ on TTY{tty}, "
|
||||||
f"which currently contains: {text}"
|
f"which currently contains: {text}"
|
||||||
)
|
)
|
||||||
return len(matcher.findall(text)) > 0
|
return len(matcher.findall(text)) > 0
|
||||||
|
|
||||||
self.logger.info(f"waiting for {regexp} to appear on tty {tty}")
|
with self.nested("waiting for {} to appear on tty {}".format(regexp, tty)):
|
||||||
retry(tty_matches)
|
retry(tty_matches)
|
||||||
|
|
||||||
def send_chars(self, chars: List[str]) -> None:
|
def send_chars(self, chars: List[str]) -> None:
|
||||||
self.logger.info(f"sending keys ‘{chars}‘")
|
with self.nested("sending keys ‘{}‘".format(chars)):
|
||||||
for char in chars:
|
for char in chars:
|
||||||
self.send_key(char)
|
self.send_key(char)
|
||||||
|
|
||||||
def wait_for_file(self, filename: str) -> None:
|
def wait_for_file(self, filename: str) -> None:
|
||||||
"""Waits until the file exists in machine's file system."""
|
"""Waits until the file exists in machine's file system."""
|
||||||
@ -456,16 +516,16 @@ class Machine:
|
|||||||
status, _ = self.execute("test -e {}".format(filename))
|
status, _ = self.execute("test -e {}".format(filename))
|
||||||
return status == 0
|
return status == 0
|
||||||
|
|
||||||
self.logger.info(f"waiting for file ‘{filename}‘")
|
with self.nested("waiting for file ‘{}‘".format(filename)):
|
||||||
retry(check_file)
|
retry(check_file)
|
||||||
|
|
||||||
def wait_for_open_port(self, port: int) -> None:
|
def wait_for_open_port(self, port: int) -> None:
|
||||||
def port_is_open(_: Any) -> bool:
|
def port_is_open(_: Any) -> bool:
|
||||||
status, _ = self.execute("nc -z localhost {}".format(port))
|
status, _ = self.execute("nc -z localhost {}".format(port))
|
||||||
return status == 0
|
return status == 0
|
||||||
|
|
||||||
self.logger.info(f"waiting for TCP port {port}")
|
with self.nested("waiting for TCP port {}".format(port)):
|
||||||
retry(port_is_open)
|
retry(port_is_open)
|
||||||
|
|
||||||
def wait_for_closed_port(self, port: int) -> None:
|
def wait_for_closed_port(self, port: int) -> None:
|
||||||
def port_is_closed(_: Any) -> bool:
|
def port_is_closed(_: Any) -> bool:
|
||||||
@ -487,17 +547,17 @@ class Machine:
|
|||||||
if self.connected:
|
if self.connected:
|
||||||
return
|
return
|
||||||
|
|
||||||
self.logger.info("waiting for the VM to finish booting")
|
with self.nested("waiting for the VM to finish booting"):
|
||||||
self.start()
|
self.start()
|
||||||
|
|
||||||
tic = time.time()
|
tic = time.time()
|
||||||
self.shell.recv(1024)
|
self.shell.recv(1024)
|
||||||
# TODO: Timeout
|
# TODO: Timeout
|
||||||
toc = time.time()
|
toc = time.time()
|
||||||
|
|
||||||
self.logger.info("connected to guest root shell")
|
self.log("connected to guest root shell")
|
||||||
self.logger.info(f"(connecting took {toc - tic:.2f} seconds)")
|
self.log("(connecting took {:.2f} seconds)".format(toc - tic))
|
||||||
self.connected = True
|
self.connected = True
|
||||||
|
|
||||||
def screenshot(self, filename: str) -> None:
|
def screenshot(self, filename: str) -> None:
|
||||||
out_dir = os.environ.get("out", os.getcwd())
|
out_dir = os.environ.get("out", os.getcwd())
|
||||||
@ -506,12 +566,15 @@ class Machine:
|
|||||||
filename = os.path.join(out_dir, "{}.png".format(filename))
|
filename = os.path.join(out_dir, "{}.png".format(filename))
|
||||||
tmp = "{}.ppm".format(filename)
|
tmp = "{}.ppm".format(filename)
|
||||||
|
|
||||||
self.logger.info(f"making screenshot {filename}")
|
with self.nested(
|
||||||
self.send_monitor_command("screendump {}".format(tmp))
|
"making screenshot {}".format(filename),
|
||||||
ret = subprocess.run("pnmtopng {} > {}".format(tmp, filename), shell=True)
|
{"image": os.path.basename(filename)},
|
||||||
os.unlink(tmp)
|
):
|
||||||
if ret.returncode != 0:
|
self.send_monitor_command("screendump {}".format(tmp))
|
||||||
raise Exception("Cannot convert screenshot")
|
ret = subprocess.run("pnmtopng {} > {}".format(tmp, filename), shell=True)
|
||||||
|
os.unlink(tmp)
|
||||||
|
if ret.returncode != 0:
|
||||||
|
raise Exception("Cannot convert screenshot")
|
||||||
|
|
||||||
def copy_from_host_via_shell(self, source: str, target: str) -> None:
|
def copy_from_host_via_shell(self, source: str, target: str) -> None:
|
||||||
"""Copy a file from the host into the guest by piping it over the
|
"""Copy a file from the host into the guest by piping it over the
|
||||||
@ -587,18 +650,20 @@ class Machine:
|
|||||||
|
|
||||||
tess_args = "-c debug_file=/dev/null --psm 11 --oem 2"
|
tess_args = "-c debug_file=/dev/null --psm 11 --oem 2"
|
||||||
|
|
||||||
self.logger.info("performing optical character recognition")
|
with self.nested("performing optical character recognition"):
|
||||||
with tempfile.NamedTemporaryFile() as tmpin:
|
with tempfile.NamedTemporaryFile() as tmpin:
|
||||||
self.send_monitor_command("screendump {}".format(tmpin.name))
|
self.send_monitor_command("screendump {}".format(tmpin.name))
|
||||||
|
|
||||||
cmd = "convert {} {} tiff:- | tesseract - - {}".format(
|
cmd = "convert {} {} tiff:- | tesseract - - {}".format(
|
||||||
magick_args, tmpin.name, tess_args
|
magick_args, tmpin.name, tess_args
|
||||||
)
|
)
|
||||||
ret = subprocess.run(cmd, shell=True, capture_output=True)
|
ret = subprocess.run(cmd, shell=True, capture_output=True)
|
||||||
if ret.returncode != 0:
|
if ret.returncode != 0:
|
||||||
raise Exception("OCR failed with exit code {}".format(ret.returncode))
|
raise Exception(
|
||||||
|
"OCR failed with exit code {}".format(ret.returncode)
|
||||||
|
)
|
||||||
|
|
||||||
return ret.stdout.decode("utf-8")
|
return ret.stdout.decode("utf-8")
|
||||||
|
|
||||||
def wait_for_text(self, regex: str) -> None:
|
def wait_for_text(self, regex: str) -> None:
|
||||||
def screen_matches(last: bool) -> bool:
|
def screen_matches(last: bool) -> bool:
|
||||||
@ -606,15 +671,15 @@ class Machine:
|
|||||||
matches = re.search(regex, text) is not None
|
matches = re.search(regex, text) is not None
|
||||||
|
|
||||||
if last and not matches:
|
if last and not matches:
|
||||||
self.logger.info(f"Last OCR attempt failed. Text was: {text}")
|
self.log("Last OCR attempt failed. Text was: {}".format(text))
|
||||||
|
|
||||||
return matches
|
return matches
|
||||||
|
|
||||||
self.logger.info(f"waiting for {regex} to appear on screen")
|
with self.nested("waiting for {} to appear on screen".format(regex)):
|
||||||
retry(screen_matches)
|
retry(screen_matches)
|
||||||
|
|
||||||
def wait_for_console_text(self, regex: str) -> None:
|
def wait_for_console_text(self, regex: str) -> None:
|
||||||
self.logger.info(f"waiting for {regex} to appear on console")
|
self.log("waiting for {} to appear on console".format(regex))
|
||||||
# Buffer the console output, this is needed
|
# Buffer the console output, this is needed
|
||||||
# to match multiline regexes.
|
# to match multiline regexes.
|
||||||
console = io.StringIO()
|
console = io.StringIO()
|
||||||
@ -637,7 +702,7 @@ class Machine:
|
|||||||
if self.booted:
|
if self.booted:
|
||||||
return
|
return
|
||||||
|
|
||||||
self.logger.info("starting vm")
|
self.log("starting vm")
|
||||||
|
|
||||||
def create_socket(path: str) -> socket.socket:
|
def create_socket(path: str) -> socket.socket:
|
||||||
if os.path.exists(path):
|
if os.path.exists(path):
|
||||||
@ -694,7 +759,7 @@ class Machine:
|
|||||||
|
|
||||||
# Store last serial console lines for use
|
# Store last serial console lines for use
|
||||||
# of wait_for_console_text
|
# of wait_for_console_text
|
||||||
self.last_lines: queue.Queue = queue.Queue()
|
self.last_lines: Queue = Queue()
|
||||||
|
|
||||||
def process_serial_output() -> None:
|
def process_serial_output() -> None:
|
||||||
assert self.process.stdout is not None
|
assert self.process.stdout is not None
|
||||||
@ -702,7 +767,8 @@ class Machine:
|
|||||||
# Ignore undecodable bytes that may occur in boot menus
|
# Ignore undecodable bytes that may occur in boot menus
|
||||||
line = _line.decode(errors="ignore").replace("\r", "").rstrip()
|
line = _line.decode(errors="ignore").replace("\r", "").rstrip()
|
||||||
self.last_lines.put(line)
|
self.last_lines.put(line)
|
||||||
self.logger.info(line)
|
eprint("{} # {}".format(self.name, line))
|
||||||
|
self.logger.enqueue({"msg": line, "machine": self.name})
|
||||||
|
|
||||||
_thread.start_new_thread(process_serial_output, ())
|
_thread.start_new_thread(process_serial_output, ())
|
||||||
|
|
||||||
@ -711,10 +777,10 @@ class Machine:
|
|||||||
self.pid = self.process.pid
|
self.pid = self.process.pid
|
||||||
self.booted = True
|
self.booted = True
|
||||||
|
|
||||||
self.logger.info(f"QEMU running (pid {self.pid})")
|
self.log("QEMU running (pid {})".format(self.pid))
|
||||||
|
|
||||||
def cleanup_statedir(self) -> None:
|
def cleanup_statedir(self) -> None:
|
||||||
self.logger.info("delete the VM state directory")
|
self.log("delete the VM state directory")
|
||||||
if os.path.isfile(self.state_dir):
|
if os.path.isfile(self.state_dir):
|
||||||
shutil.rmtree(self.state_dir)
|
shutil.rmtree(self.state_dir)
|
||||||
|
|
||||||
@ -729,7 +795,7 @@ class Machine:
|
|||||||
if not self.booted:
|
if not self.booted:
|
||||||
return
|
return
|
||||||
|
|
||||||
self.logger.info("forced crash")
|
self.log("forced crash")
|
||||||
self.send_monitor_command("quit")
|
self.send_monitor_command("quit")
|
||||||
self.wait_for_shutdown()
|
self.wait_for_shutdown()
|
||||||
|
|
||||||
@ -749,8 +815,8 @@ class Machine:
|
|||||||
status, _ = self.execute("[ -e /tmp/.X11-unix/X0 ]")
|
status, _ = self.execute("[ -e /tmp/.X11-unix/X0 ]")
|
||||||
return status == 0
|
return status == 0
|
||||||
|
|
||||||
self.logger.info("waiting for the X11 server")
|
with self.nested("waiting for the X11 server"):
|
||||||
retry(check_x)
|
retry(check_x)
|
||||||
|
|
||||||
def get_window_names(self) -> List[str]:
|
def get_window_names(self) -> List[str]:
|
||||||
return self.succeed(
|
return self.succeed(
|
||||||
@ -763,17 +829,19 @@ class Machine:
|
|||||||
def window_is_visible(last_try: bool) -> bool:
|
def window_is_visible(last_try: bool) -> bool:
|
||||||
names = self.get_window_names()
|
names = self.get_window_names()
|
||||||
if last_try:
|
if last_try:
|
||||||
self.logger.info(
|
self.log(
|
||||||
f"Last chance to match {regexp} on the window list, "
|
"Last chance to match {} on the window list,".format(regexp)
|
||||||
+ f"which currently contains: {', '.join(names)}"
|
+ " which currently contains: "
|
||||||
|
+ ", ".join(names)
|
||||||
)
|
)
|
||||||
return any(pattern.search(name) for name in names)
|
return any(pattern.search(name) for name in names)
|
||||||
|
|
||||||
self.logger.info("Waiting for a window to appear")
|
with self.nested("Waiting for a window to appear"):
|
||||||
retry(window_is_visible)
|
retry(window_is_visible)
|
||||||
|
|
||||||
def sleep(self, secs: int) -> None:
|
def sleep(self, secs: int) -> None:
|
||||||
time.sleep(secs)
|
# We want to sleep in *guest* time, not *host* time.
|
||||||
|
self.succeed(f"sleep {secs}")
|
||||||
|
|
||||||
def forward_port(self, host_port: int = 8080, guest_port: int = 80) -> None:
|
def forward_port(self, host_port: int = 8080, guest_port: int = 80) -> None:
|
||||||
"""Forward a TCP port on the host to a TCP port on the guest.
|
"""Forward a TCP port on the host to a TCP port on the guest.
|
||||||
@ -798,22 +866,23 @@ class Machine:
|
|||||||
|
|
||||||
def create_machine(args: Dict[str, Any]) -> Machine:
|
def create_machine(args: Dict[str, Any]) -> Machine:
|
||||||
global log
|
global log
|
||||||
|
args["log"] = log
|
||||||
args["redirectSerial"] = os.environ.get("USE_SERIAL", "0") == "1"
|
args["redirectSerial"] = os.environ.get("USE_SERIAL", "0") == "1"
|
||||||
return Machine(args)
|
return Machine(args)
|
||||||
|
|
||||||
|
|
||||||
def start_all() -> None:
|
def start_all() -> None:
|
||||||
global machines
|
global machines
|
||||||
logger.info("starting all VMs")
|
with log.nested("starting all VMs"):
|
||||||
for machine in machines:
|
for machine in machines:
|
||||||
machine.start()
|
machine.start()
|
||||||
|
|
||||||
|
|
||||||
def join_all() -> None:
|
def join_all() -> None:
|
||||||
global machines
|
global machines
|
||||||
logger.info("waiting for all VMs to finish")
|
with log.nested("waiting for all VMs to finish"):
|
||||||
for machine in machines:
|
for machine in machines:
|
||||||
machine.wait_for_shutdown()
|
machine.wait_for_shutdown()
|
||||||
|
|
||||||
|
|
||||||
def test_script() -> None:
|
def test_script() -> None:
|
||||||
@ -824,12 +893,13 @@ def run_tests() -> None:
|
|||||||
global machines
|
global machines
|
||||||
tests = os.environ.get("tests", None)
|
tests = os.environ.get("tests", None)
|
||||||
if tests is not None:
|
if tests is not None:
|
||||||
logger.info("running the VM test script")
|
with log.nested("running the VM test script"):
|
||||||
try:
|
try:
|
||||||
exec(tests, globals())
|
exec(tests, globals())
|
||||||
except Exception:
|
except Exception as e:
|
||||||
logging.exception("error:")
|
eprint("error: ")
|
||||||
sys.exit(1)
|
traceback.print_exc()
|
||||||
|
sys.exit(1)
|
||||||
else:
|
else:
|
||||||
ptpython.repl.embed(locals(), globals())
|
ptpython.repl.embed(locals(), globals())
|
||||||
|
|
||||||
@ -842,19 +912,18 @@ def run_tests() -> None:
|
|||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def subtest(name: str) -> Iterator[None]:
|
def subtest(name: str) -> Iterator[None]:
|
||||||
logger.info(name)
|
with log.nested(name):
|
||||||
try:
|
try:
|
||||||
yield
|
yield
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.info(f'Test "{name}" failed with error: "{e}"')
|
log.log(f'Test "{name}" failed with error: "{e}"')
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
if __name__ == "__main__":
|
||||||
global machines
|
|
||||||
arg_parser = argparse.ArgumentParser()
|
arg_parser = argparse.ArgumentParser()
|
||||||
arg_parser.add_argument(
|
arg_parser.add_argument(
|
||||||
"-K",
|
"-K",
|
||||||
@ -864,6 +933,8 @@ def main() -> None:
|
|||||||
)
|
)
|
||||||
(cli_args, vm_scripts) = arg_parser.parse_known_args()
|
(cli_args, vm_scripts) = arg_parser.parse_known_args()
|
||||||
|
|
||||||
|
log = Logger()
|
||||||
|
|
||||||
vlan_nrs = list(dict.fromkeys(os.environ.get("VLANS", "").split()))
|
vlan_nrs = list(dict.fromkeys(os.environ.get("VLANS", "").split()))
|
||||||
vde_sockets = [create_vlan(v) for v in vlan_nrs]
|
vde_sockets = [create_vlan(v) for v in vlan_nrs]
|
||||||
for nr, vde_socket, _, _ in vde_sockets:
|
for nr, vde_socket, _, _ in vde_sockets:
|
||||||
@ -874,27 +945,23 @@ def main() -> None:
|
|||||||
if not cli_args.keep_vm_state:
|
if not cli_args.keep_vm_state:
|
||||||
machine.cleanup_statedir()
|
machine.cleanup_statedir()
|
||||||
machine_eval = [
|
machine_eval = [
|
||||||
"global {0}; {0} = machines[{1}]".format(m.name, idx)
|
"{0} = machines[{1}]".format(m.name, idx) for idx, m in enumerate(machines)
|
||||||
for idx, m in enumerate(machines)
|
|
||||||
]
|
]
|
||||||
exec("\n".join(machine_eval))
|
exec("\n".join(machine_eval))
|
||||||
|
|
||||||
@atexit.register
|
@atexit.register
|
||||||
def clean_up() -> None:
|
def clean_up() -> None:
|
||||||
logger.info("cleaning up")
|
with log.nested("cleaning up"):
|
||||||
for machine in machines:
|
for machine in machines:
|
||||||
if machine.pid is None:
|
if machine.pid is None:
|
||||||
continue
|
continue
|
||||||
logger.info(f"killing {machine.name} (pid {machine.pid})")
|
log.log("killing {} (pid {})".format(machine.name, machine.pid))
|
||||||
machine.process.kill()
|
machine.process.kill()
|
||||||
for _, _, process, _ in vde_sockets:
|
for _, _, process, _ in vde_sockets:
|
||||||
process.terminate()
|
process.terminate()
|
||||||
|
log.close()
|
||||||
|
|
||||||
tic = time.time()
|
tic = time.time()
|
||||||
run_tests()
|
run_tests()
|
||||||
toc = time.time()
|
toc = time.time()
|
||||||
print("test script finished in {:.2f}s".format(toc - tic))
|
print("test script finished in {:.2f}s".format(toc - tic))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
|
@ -62,7 +62,7 @@ rec {
|
|||||||
''
|
''
|
||||||
mkdir -p $out
|
mkdir -p $out
|
||||||
|
|
||||||
tests='exec(os.environ["testScript"])' ${driver}/bin/nixos-test-driver
|
LOGFILE=/dev/null tests='exec(os.environ["testScript"])' ${driver}/bin/nixos-test-driver
|
||||||
|
|
||||||
for i in */xchg/coverage-data; do
|
for i in */xchg/coverage-data; do
|
||||||
mkdir -p $out/coverage-data
|
mkdir -p $out/coverage-data
|
||||||
|
@ -41,31 +41,30 @@ let
|
|||||||
value)
|
value)
|
||||||
else value;
|
else value;
|
||||||
|
|
||||||
mkIndent = depth: concatStrings (builtins.genList (_: " ") (2 * depth));
|
indent = " ";
|
||||||
|
|
||||||
mkRelation = name: value: "${name} = ${mkVal { inherit value; }}";
|
mkRelation = name: value:
|
||||||
|
if (isList value) then
|
||||||
|
concatMapStringsSep "\n" (mkRelation name) value
|
||||||
|
else "${name} = ${mkVal value}";
|
||||||
|
|
||||||
mkVal = { value, depth ? 0 }:
|
mkVal = value:
|
||||||
if (value == true) then "true"
|
if (value == true) then "true"
|
||||||
else if (value == false) then "false"
|
else if (value == false) then "false"
|
||||||
else if (isInt value) then (toString value)
|
else if (isInt value) then (toString value)
|
||||||
else if (isList value) then
|
|
||||||
concatMapStringsSep " " mkVal { inherit value depth; }
|
|
||||||
else if (isAttrs value) then
|
else if (isAttrs value) then
|
||||||
(concatStringsSep "\n${mkIndent (depth + 1)}"
|
let configLines = concatLists
|
||||||
([ "{" ] ++ (mapAttrsToList
|
(map (splitString "\n")
|
||||||
(attrName: attrValue: let
|
(mapAttrsToList mkRelation value));
|
||||||
mappedAttrValue = mkVal {
|
in
|
||||||
value = attrValue;
|
(concatStringsSep "\n${indent}"
|
||||||
depth = depth + 1;
|
([ "{" ] ++ configLines))
|
||||||
};
|
+ "\n}"
|
||||||
in "${attrName} = ${mappedAttrValue}")
|
|
||||||
value))) + "\n${mkIndent depth}}"
|
|
||||||
else value;
|
else value;
|
||||||
|
|
||||||
mkMappedAttrsOrString = value: concatMapStringsSep "\n"
|
mkMappedAttrsOrString = value: concatMapStringsSep "\n"
|
||||||
(line: if builtins.stringLength line > 0
|
(line: if builtins.stringLength line > 0
|
||||||
then "${mkIndent 1}${line}"
|
then "${indent}${line}"
|
||||||
else line)
|
else line)
|
||||||
(splitString "\n"
|
(splitString "\n"
|
||||||
(if isAttrs value then
|
(if isAttrs value then
|
||||||
@ -114,7 +113,10 @@ in {
|
|||||||
{
|
{
|
||||||
"ATHENA.MIT.EDU" = {
|
"ATHENA.MIT.EDU" = {
|
||||||
admin_server = "athena.mit.edu";
|
admin_server = "athena.mit.edu";
|
||||||
kdc = "athena.mit.edu";
|
kdc = [
|
||||||
|
"athena01.mit.edu"
|
||||||
|
"athena02.mit.edu"
|
||||||
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
'';
|
'';
|
||||||
|
@ -463,7 +463,7 @@ in {
|
|||||||
|
|
||||||
users.users = mkOption {
|
users.users = mkOption {
|
||||||
default = {};
|
default = {};
|
||||||
type = with types; loaOf (submodule userOpts);
|
type = with types; attrsOf (submodule userOpts);
|
||||||
example = {
|
example = {
|
||||||
alice = {
|
alice = {
|
||||||
uid = 1234;
|
uid = 1234;
|
||||||
@ -487,7 +487,7 @@ in {
|
|||||||
{ students.gid = 1001;
|
{ students.gid = 1001;
|
||||||
hackers = { };
|
hackers = { };
|
||||||
};
|
};
|
||||||
type = with types; loaOf (submodule groupOpts);
|
type = with types; attrsOf (submodule groupOpts);
|
||||||
description = ''
|
description = ''
|
||||||
Additional groups to be created automatically by the system.
|
Additional groups to be created automatically by the system.
|
||||||
'';
|
'';
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/boot/firmware" = {
|
fileSystems."/boot/firmware" = {
|
||||||
# This effectively "renames" the loaOf entry set in sd-image.nix
|
# This effectively "renames" the attrsOf entry set in sd-image.nix
|
||||||
mountPoint = "/boot";
|
mountPoint = "/boot";
|
||||||
neededForBoot = true;
|
neededForBoot = true;
|
||||||
};
|
};
|
||||||
|
@ -224,7 +224,7 @@ bool optionTypeIs(Context & ctx, Value & v, const std::string & soughtType)
|
|||||||
|
|
||||||
bool isAggregateOptionType(Context & ctx, Value & v)
|
bool isAggregateOptionType(Context & ctx, Value & v)
|
||||||
{
|
{
|
||||||
return optionTypeIs(ctx, v, "attrsOf") || optionTypeIs(ctx, v, "listOf") || optionTypeIs(ctx, v, "loaOf");
|
return optionTypeIs(ctx, v, "attrsOf") || optionTypeIs(ctx, v, "listOf");
|
||||||
}
|
}
|
||||||
|
|
||||||
MakeError(OptionPathError, EvalError);
|
MakeError(OptionPathError, EvalError);
|
||||||
|
@ -288,7 +288,10 @@ fi
|
|||||||
if [ "$action" = edit ]; then
|
if [ "$action" = edit ]; then
|
||||||
if [[ -z $flake ]]; then
|
if [[ -z $flake ]]; then
|
||||||
NIXOS_CONFIG=${NIXOS_CONFIG:-$(nix-instantiate --find-file nixos-config)}
|
NIXOS_CONFIG=${NIXOS_CONFIG:-$(nix-instantiate --find-file nixos-config)}
|
||||||
exec "${EDITOR:-nano}" "$NIXOS_CONFIG"
|
if [[ -d $NIXOS_CONFIG ]]; then
|
||||||
|
NIXOS_CONFIG=$NIXOS_CONFIG/default.nix
|
||||||
|
fi
|
||||||
|
exec ${EDITOR:-nano} "$NIXOS_CONFIG"
|
||||||
else
|
else
|
||||||
exec nix edit "${lockFlags[@]}" -- "$flake#$flakeAttr"
|
exec nix edit "${lockFlags[@]}" -- "$flake#$flakeAttr"
|
||||||
fi
|
fi
|
||||||
|
@ -262,6 +262,7 @@
|
|||||||
./services/continuous-integration/buildbot/worker.nix
|
./services/continuous-integration/buildbot/worker.nix
|
||||||
./services/continuous-integration/buildkite-agents.nix
|
./services/continuous-integration/buildkite-agents.nix
|
||||||
./services/continuous-integration/hail.nix
|
./services/continuous-integration/hail.nix
|
||||||
|
./services/continuous-integration/hercules-ci-agent/default.nix
|
||||||
./services/continuous-integration/hydra/default.nix
|
./services/continuous-integration/hydra/default.nix
|
||||||
./services/continuous-integration/gitlab-runner.nix
|
./services/continuous-integration/gitlab-runner.nix
|
||||||
./services/continuous-integration/gocd-agent/default.nix
|
./services/continuous-integration/gocd-agent/default.nix
|
||||||
@ -296,7 +297,6 @@
|
|||||||
./services/desktops/accountsservice.nix
|
./services/desktops/accountsservice.nix
|
||||||
./services/desktops/bamf.nix
|
./services/desktops/bamf.nix
|
||||||
./services/desktops/blueman.nix
|
./services/desktops/blueman.nix
|
||||||
./services/desktops/deepin/deepin.nix
|
|
||||||
./services/desktops/dleyna-renderer.nix
|
./services/desktops/dleyna-renderer.nix
|
||||||
./services/desktops/dleyna-server.nix
|
./services/desktops/dleyna-server.nix
|
||||||
./services/desktops/pantheon/files.nix
|
./services/desktops/pantheon/files.nix
|
||||||
@ -587,6 +587,7 @@
|
|||||||
./services/networking/atftpd.nix
|
./services/networking/atftpd.nix
|
||||||
./services/networking/avahi-daemon.nix
|
./services/networking/avahi-daemon.nix
|
||||||
./services/networking/babeld.nix
|
./services/networking/babeld.nix
|
||||||
|
./services/networking/biboumi.nix
|
||||||
./services/networking/bind.nix
|
./services/networking/bind.nix
|
||||||
./services/networking/bitcoind.nix
|
./services/networking/bitcoind.nix
|
||||||
./services/networking/autossh.nix
|
./services/networking/autossh.nix
|
||||||
@ -718,6 +719,7 @@
|
|||||||
./services/networking/rdnssd.nix
|
./services/networking/rdnssd.nix
|
||||||
./services/networking/redsocks.nix
|
./services/networking/redsocks.nix
|
||||||
./services/networking/resilio.nix
|
./services/networking/resilio.nix
|
||||||
|
./services/networking/robustirc-bridge.nix
|
||||||
./services/networking/rpcbind.nix
|
./services/networking/rpcbind.nix
|
||||||
./services/networking/rxe.nix
|
./services/networking/rxe.nix
|
||||||
./services/networking/sabnzbd.nix
|
./services/networking/sabnzbd.nix
|
||||||
|
@ -33,7 +33,6 @@ in
|
|||||||
{ PATH = [ "/bin" ];
|
{ PATH = [ "/bin" ];
|
||||||
INFOPATH = [ "/info" "/share/info" ];
|
INFOPATH = [ "/info" "/share/info" ];
|
||||||
KDEDIRS = [ "" ];
|
KDEDIRS = [ "" ];
|
||||||
STRIGI_PLUGIN_PATH = [ "/lib/strigi/" ];
|
|
||||||
QT_PLUGIN_PATH = [ "/lib/qt4/plugins" "/lib/kde4/plugins" ];
|
QT_PLUGIN_PATH = [ "/lib/qt4/plugins" "/lib/kde4/plugins" ];
|
||||||
QTWEBKIT_PLUGIN_PATH = [ "/lib/mozilla/plugins/" ];
|
QTWEBKIT_PLUGIN_PATH = [ "/lib/mozilla/plugins/" ];
|
||||||
GTK_PATH = [ "/lib/gtk-2.0" "/lib/gtk-3.0" ];
|
GTK_PATH = [ "/lib/gtk-2.0" "/lib/gtk-3.0" ];
|
||||||
|
@ -30,5 +30,7 @@ with lib;
|
|||||||
environment.systemPackages = [ pkgs.gnome3.gpaste ];
|
environment.systemPackages = [ pkgs.gnome3.gpaste ];
|
||||||
services.dbus.packages = [ pkgs.gnome3.gpaste ];
|
services.dbus.packages = [ pkgs.gnome3.gpaste ];
|
||||||
systemd.packages = [ pkgs.gnome3.gpaste ];
|
systemd.packages = [ pkgs.gnome3.gpaste ];
|
||||||
|
# gnome-control-center crashes in Keyboard Shortcuts pane without the GSettings schemas.
|
||||||
|
services.xserver.desktopManager.gnome3.sessionPath = [ pkgs.gnome3.gpaste ];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -131,7 +131,7 @@ in
|
|||||||
|
|
||||||
knownHosts = mkOption {
|
knownHosts = mkOption {
|
||||||
default = {};
|
default = {};
|
||||||
type = types.loaOf (types.submodule ({ name, ... }: {
|
type = types.attrsOf (types.submodule ({ name, ... }: {
|
||||||
options = {
|
options = {
|
||||||
certAuthority = mkOption {
|
certAuthority = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
|
@ -7,7 +7,7 @@ let
|
|||||||
inherit (lib.modules) mkDefault mkIf;
|
inherit (lib.modules) mkDefault mkIf;
|
||||||
inherit (lib.options) literalExample mkEnableOption mkOption;
|
inherit (lib.options) literalExample mkEnableOption mkOption;
|
||||||
inherit (lib.strings) concatStringsSep optionalString toLower;
|
inherit (lib.strings) concatStringsSep optionalString toLower;
|
||||||
inherit (lib.types) addCheck attrsOf lines loaOf nullOr package path port str strMatching submodule;
|
inherit (lib.types) addCheck attrsOf lines nullOr package path port str strMatching submodule;
|
||||||
|
|
||||||
# Checks if given list of strings contains unique
|
# Checks if given list of strings contains unique
|
||||||
# elements when compared without considering case.
|
# elements when compared without considering case.
|
||||||
@ -178,7 +178,7 @@ let
|
|||||||
client system-options file "dsm.sys"
|
client system-options file "dsm.sys"
|
||||||
'';
|
'';
|
||||||
servers = mkOption {
|
servers = mkOption {
|
||||||
type = loaOf (submodule [ serverOptions ]);
|
type = attrsOf (submodule [ serverOptions ]);
|
||||||
default = {};
|
default = {};
|
||||||
example.mainTsmServer = {
|
example.mainTsmServer = {
|
||||||
server = "tsmserver.company.com";
|
server = "tsmserver.company.com";
|
||||||
|
@ -73,7 +73,7 @@
|
|||||||
<programlisting>
|
<programlisting>
|
||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
{
|
{
|
||||||
programs.zsh.ohMyZsh.customPkgs = with pkgs; [
|
programs.zsh.ohMyZsh.customPkgs = [
|
||||||
pkgs.nix-zsh-completions
|
pkgs.nix-zsh-completions
|
||||||
# and even more...
|
# and even more...
|
||||||
];
|
];
|
||||||
|
@ -19,6 +19,7 @@ with lib;
|
|||||||
# Completely removed modules
|
# Completely removed modules
|
||||||
(mkRemovedOptionModule [ "fonts" "fontconfig" "penultimate" ] "The corresponding package has removed from nixpkgs.")
|
(mkRemovedOptionModule [ "fonts" "fontconfig" "penultimate" ] "The corresponding package has removed from nixpkgs.")
|
||||||
(mkRemovedOptionModule [ "services" "chronos" ] "The corresponding package was removed from nixpkgs.")
|
(mkRemovedOptionModule [ "services" "chronos" ] "The corresponding package was removed from nixpkgs.")
|
||||||
|
(mkRemovedOptionModule [ "services" "deepin" ] "The corresponding packages were removed from nixpkgs.")
|
||||||
(mkRemovedOptionModule [ "services" "firefox" "syncserver" "user" ] "")
|
(mkRemovedOptionModule [ "services" "firefox" "syncserver" "user" ] "")
|
||||||
(mkRemovedOptionModule [ "services" "firefox" "syncserver" "group" ] "")
|
(mkRemovedOptionModule [ "services" "firefox" "syncserver" "group" ] "")
|
||||||
(mkRemovedOptionModule [ "services" "marathon" ] "The corresponding package was removed from nixpkgs.")
|
(mkRemovedOptionModule [ "services" "marathon" ] "The corresponding package was removed from nixpkgs.")
|
||||||
|
@ -544,7 +544,7 @@ in
|
|||||||
|
|
||||||
security.pam.services = mkOption {
|
security.pam.services = mkOption {
|
||||||
default = [];
|
default = [];
|
||||||
type = with types; loaOf (submodule pamOpts);
|
type = with types; attrsOf (submodule pamOpts);
|
||||||
description =
|
description =
|
||||||
''
|
''
|
||||||
This option defines the PAM services. A service typically
|
This option defines the PAM services. A service typically
|
||||||
|
@ -220,7 +220,7 @@ let
|
|||||||
};
|
};
|
||||||
|
|
||||||
destinations = mkOption {
|
destinations = mkOption {
|
||||||
type = loaOf (destType config);
|
type = attrsOf (destType config);
|
||||||
description = "Additional destinations.";
|
description = "Additional destinations.";
|
||||||
default = {};
|
default = {};
|
||||||
example = literalExample ''
|
example = literalExample ''
|
||||||
@ -328,7 +328,7 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
zetup = mkOption {
|
zetup = mkOption {
|
||||||
type = loaOf srcType;
|
type = attrsOf srcType;
|
||||||
description = "Znapzend configuration.";
|
description = "Znapzend configuration.";
|
||||||
default = {};
|
default = {};
|
||||||
example = literalExample ''
|
example = literalExample ''
|
||||||
|
@ -0,0 +1,213 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
This file is for options that NixOS and nix-darwin have in common.
|
||||||
|
|
||||||
|
Platform-specific code is in the respective default.nix files.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
{ config, lib, options, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
inherit (lib) mkOption mkIf types filterAttrs literalExample mkRenamedOptionModule;
|
||||||
|
|
||||||
|
cfg =
|
||||||
|
config.services.hercules-ci-agent;
|
||||||
|
|
||||||
|
format = pkgs.formats.toml {};
|
||||||
|
|
||||||
|
settingsModule = { config, ... }: {
|
||||||
|
freeformType = format.type;
|
||||||
|
options = {
|
||||||
|
baseDirectory = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
default = "/var/lib/hercules-ci-agent";
|
||||||
|
description = ''
|
||||||
|
State directory (secrets, work directory, etc) for agent
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
concurrentTasks = mkOption {
|
||||||
|
description = ''
|
||||||
|
Number of tasks to perform simultaneously, such as evaluations, derivations.
|
||||||
|
|
||||||
|
You must have a total capacity across agents of at least 2 concurrent tasks on <literal>x86_64-linux</literal>
|
||||||
|
to allow for import from derivation.
|
||||||
|
'';
|
||||||
|
type = types.int;
|
||||||
|
default = 4;
|
||||||
|
};
|
||||||
|
workDirectory = mkOption {
|
||||||
|
description = ''
|
||||||
|
The directory in which temporary subdirectories are created for task state. This includes sources for Nix evaluation.
|
||||||
|
'';
|
||||||
|
type = types.path;
|
||||||
|
default = config.baseDirectory + "/work";
|
||||||
|
defaultText = literalExample ''baseDirectory + "/work"'';
|
||||||
|
};
|
||||||
|
staticSecretsDirectory = mkOption {
|
||||||
|
description = ''
|
||||||
|
This is the default directory to look for statically configured secrets like <literal>cluster-join-token.key</literal>.
|
||||||
|
'';
|
||||||
|
type = types.path;
|
||||||
|
default = config.baseDirectory + "/secrets";
|
||||||
|
defaultText = literalExample ''baseDirectory + "/secrets"'';
|
||||||
|
};
|
||||||
|
clusterJoinTokenPath = mkOption {
|
||||||
|
description = ''
|
||||||
|
Location of the cluster-join-token.key file.
|
||||||
|
'';
|
||||||
|
type = types.path;
|
||||||
|
default = config.staticSecretsDirectory + "/cluster-join-token.key";
|
||||||
|
defaultText = literalExample ''staticSecretsDirectory + "/cluster-join-token.key"'';
|
||||||
|
# internal: It's a bit too detailed to show by default in the docs,
|
||||||
|
# but useful to define explicitly to allow reuse by other modules.
|
||||||
|
internal = true;
|
||||||
|
};
|
||||||
|
binaryCachesPath = mkOption {
|
||||||
|
description = ''
|
||||||
|
Location of the binary-caches.json file.
|
||||||
|
'';
|
||||||
|
type = types.path;
|
||||||
|
default = config.staticSecretsDirectory + "/binary-caches.json";
|
||||||
|
defaultText = literalExample ''staticSecretsDirectory + "/binary-caches.json"'';
|
||||||
|
# internal: It's a bit too detailed to show by default in the docs,
|
||||||
|
# but useful to define explicitly to allow reuse by other modules.
|
||||||
|
internal = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
checkNix =
|
||||||
|
if !cfg.checkNix
|
||||||
|
then ""
|
||||||
|
else if lib.versionAtLeast config.nix.package.version "2.4.0"
|
||||||
|
then ""
|
||||||
|
else pkgs.stdenv.mkDerivation {
|
||||||
|
name = "hercules-ci-check-system-nix-src";
|
||||||
|
inherit (config.nix.package) src patches;
|
||||||
|
configurePhase = ":";
|
||||||
|
buildPhase = ''
|
||||||
|
echo "Checking in-memory pathInfoCache expiry"
|
||||||
|
if ! grep 'struct PathInfoCacheValue' src/libstore/store-api.hh >/dev/null; then
|
||||||
|
cat 1>&2 <<EOF
|
||||||
|
|
||||||
|
You are deploying Hercules CI Agent on a system with an incompatible
|
||||||
|
nix-daemon. Please
|
||||||
|
- either upgrade Nix to version 2.4.0 (when released),
|
||||||
|
- or set option services.hercules-ci-agent.patchNix = true;
|
||||||
|
- or set option nix.package to a build of Nix 2.3 with this patch applied:
|
||||||
|
https://github.com/NixOS/nix/pull/3405
|
||||||
|
|
||||||
|
The patch is required for Nix-daemon clients that expect a change in binary
|
||||||
|
cache contents while running, like the agent's evaluator. Without it, import
|
||||||
|
from derivation will fail if your cluster has more than one machine.
|
||||||
|
We are conservative with changes to the overall system, which is why we
|
||||||
|
keep changes to a minimum and why we ask for confirmation in the form of
|
||||||
|
services.hercules-ci-agent.patchNix = true before applying.
|
||||||
|
|
||||||
|
EOF
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
installPhase = "touch $out";
|
||||||
|
};
|
||||||
|
|
||||||
|
patchedNix = lib.mkIf (!lib.versionAtLeast pkgs.nix.version "2.4.0") (
|
||||||
|
if lib.versionAtLeast pkgs.nix.version "2.4pre"
|
||||||
|
then lib.warn "Hercules CI Agent module will not patch 2.4 pre-release. Make sure it includes (equivalently) PR #3043, commit d048577909 or is no older than 2020-03-13." pkgs.nix
|
||||||
|
else pkgs.nix.overrideAttrs (
|
||||||
|
o: {
|
||||||
|
patches = (o.patches or []) ++ [ backportNix3398 ];
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
backportNix3398 = pkgs.fetchurl {
|
||||||
|
url = "https://raw.githubusercontent.com/hercules-ci/hercules-ci-agent/hercules-ci-agent-0.7.3/for-upstream/issue-3398-path-info-cache-ttls-backport-2.3.patch";
|
||||||
|
sha256 = "0jfckqjir9il2il7904yc1qyadw366y7xqzg81sp9sl3f1pw70ib";
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
(mkRenamedOptionModule ["services" "hercules-ci-agent" "extraOptions"] ["services" "hercules-ci-agent" "settings"])
|
||||||
|
(mkRenamedOptionModule ["services" "hercules-ci-agent" "baseDirectory"] ["services" "hercules-ci-agent" "settings" "baseDirectory"])
|
||||||
|
(mkRenamedOptionModule ["services" "hercules-ci-agent" "concurrentTasks"] ["services" "hercules-ci-agent" "settings" "concurrentTasks"])
|
||||||
|
];
|
||||||
|
|
||||||
|
options.services.hercules-ci-agent = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Enable to run Hercules CI Agent as a system service.
|
||||||
|
|
||||||
|
<link xlink:href="https://hercules-ci.com">Hercules CI</link> is a
|
||||||
|
continuous integation service that is centered around Nix.
|
||||||
|
|
||||||
|
Support is available at <link xlink:href="mailto:help@hercules-ci.com">help@hercules-ci.com</link>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
patchNix = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Fix Nix 2.3 cache path metadata caching behavior. Has the effect of <literal>nix.package = patch pkgs.nix;</literal>
|
||||||
|
|
||||||
|
This option will be removed when Hercules CI Agent moves to Nix 2.4 (upcoming Nix release).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
checkNix = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = ''
|
||||||
|
Whether to make sure that the system's Nix (nix-daemon) is compatible.
|
||||||
|
|
||||||
|
If you set this to false, please keep up with the change log.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
package = mkOption {
|
||||||
|
description = ''
|
||||||
|
Package containing the bin/hercules-ci-agent executable.
|
||||||
|
'';
|
||||||
|
type = types.package;
|
||||||
|
default = pkgs.hercules-ci-agent;
|
||||||
|
defaultText = literalExample "pkgs.hercules-ci-agent";
|
||||||
|
};
|
||||||
|
settings = mkOption {
|
||||||
|
description = ''
|
||||||
|
These settings are written to the <literal>agent.toml</literal> file.
|
||||||
|
|
||||||
|
Not all settings are listed as options, can be set nonetheless.
|
||||||
|
|
||||||
|
For the exhaustive list of settings, see <link xlink:href="https://docs.hercules-ci.com/hercules-ci/reference/agent-config/"/>.
|
||||||
|
'';
|
||||||
|
type = types.submoduleWith { modules = [ settingsModule ]; };
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Internal and/or computed values.
|
||||||
|
|
||||||
|
These are written as options instead of let binding to allow sharing with
|
||||||
|
default.nix on both NixOS and nix-darwin.
|
||||||
|
*/
|
||||||
|
tomlFile = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
internal = true;
|
||||||
|
defaultText = "generated hercules-ci-agent.toml";
|
||||||
|
description = ''
|
||||||
|
The fully assembled config file.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
nix.extraOptions = lib.addContextFrom checkNix ''
|
||||||
|
# A store path that was missing at first may well have finished building,
|
||||||
|
# even shortly after the previous lookup. This *also* applies to the daemon.
|
||||||
|
narinfo-cache-negative-ttl = 0
|
||||||
|
'';
|
||||||
|
nix.package = mkIf cfg.patchNix patchedNix;
|
||||||
|
services.hercules-ci-agent.tomlFile =
|
||||||
|
format.generate "hercules-ci-agent.toml" cfg.settings;
|
||||||
|
};
|
||||||
|
}
|
@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
This file is for NixOS-specific options and configs.
|
||||||
|
|
||||||
|
Code that is shared with nix-darwin goes in common.nix.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
{ pkgs, config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
inherit (lib) mkIf mkDefault;
|
||||||
|
|
||||||
|
cfg = config.services.hercules-ci-agent;
|
||||||
|
|
||||||
|
command = "${cfg.package}/bin/hercules-ci-agent --config ${cfg.tomlFile}";
|
||||||
|
testCommand = "${command} --test-configuration";
|
||||||
|
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./common.nix
|
||||||
|
(lib.mkRenamedOptionModule ["services" "hercules-ci-agent" "user"] ["systemd" "services" "hercules-ci-agent" "serviceConfig" "User"])
|
||||||
|
];
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
|
||||||
|
systemd.services.hercules-ci-agent = {
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
after = [ "network-online.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
|
path = [ config.nix.package ];
|
||||||
|
serviceConfig = {
|
||||||
|
User = "hercules-ci-agent";
|
||||||
|
ExecStart = command;
|
||||||
|
ExecStartPre = testCommand;
|
||||||
|
Restart = "on-failure";
|
||||||
|
RestartSec = 120;
|
||||||
|
StartLimitBurst = 30 * 1000000; # practically infinite
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Changes in the secrets do not affect the unit in any way that would cause
|
||||||
|
# a restart, which is currently necessary to reload the secrets.
|
||||||
|
systemd.paths.hercules-ci-agent-restart-files = {
|
||||||
|
wantedBy = [ "hercules-ci-agent.service" ];
|
||||||
|
pathConfig = {
|
||||||
|
Unit = "hercules-ci-agent-restarter.service";
|
||||||
|
PathChanged = [ cfg.settings.clusterJoinTokenPath cfg.settings.binaryCachesPath ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
systemd.services.hercules-ci-agent-restarter = {
|
||||||
|
serviceConfig.Type = "oneshot";
|
||||||
|
script = ''
|
||||||
|
# Wait a bit, with the effect of bundling up file changes into a single
|
||||||
|
# run of this script and hopefully a single restart.
|
||||||
|
sleep 10
|
||||||
|
if systemctl is-active --quiet hercules-ci-agent.service; then
|
||||||
|
if ${testCommand}; then
|
||||||
|
systemctl restart hercules-ci-agent.service
|
||||||
|
else
|
||||||
|
echo 1>&2 "WARNING: Not restarting agent because config is not valid at this time."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo 1>&2 "Not restarting hercules-ci-agent despite config file update, because it is not already active."
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# Trusted user allows simplified configuration and better performance
|
||||||
|
# when operating in a cluster.
|
||||||
|
nix.trustedUsers = [ config.systemd.services.hercules-ci-agent.serviceConfig.User ];
|
||||||
|
services.hercules-ci-agent.settings.nixUserIsTrusted = true;
|
||||||
|
|
||||||
|
users.users.hercules-ci-agent = {
|
||||||
|
home = cfg.settings.baseDirectory;
|
||||||
|
createHome = true;
|
||||||
|
group = "hercules-ci-agent";
|
||||||
|
description = "Hercules CI Agent system user";
|
||||||
|
isSystemUser = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
users.groups.hercules-ci-agent = {};
|
||||||
|
};
|
||||||
|
}
|
@ -11,23 +11,23 @@ let
|
|||||||
then cfg.package
|
then cfg.package
|
||||||
else cfg.package.withPackages (_: cfg.extraPlugins);
|
else cfg.package.withPackages (_: cfg.extraPlugins);
|
||||||
|
|
||||||
|
toStr = value:
|
||||||
|
if true == value then "yes"
|
||||||
|
else if false == value then "no"
|
||||||
|
else if isString value then "'${lib.replaceStrings ["'"] ["''"] value}'"
|
||||||
|
else toString value;
|
||||||
|
|
||||||
# The main PostgreSQL configuration file.
|
# The main PostgreSQL configuration file.
|
||||||
configFile = pkgs.writeText "postgresql.conf"
|
configFile = pkgs.writeText "postgresql.conf" (concatStringsSep "\n" (mapAttrsToList (n: v: "${n} = ${toStr v}") cfg.settings));
|
||||||
''
|
|
||||||
hba_file = '${pkgs.writeText "pg_hba.conf" cfg.authentication}'
|
|
||||||
ident_file = '${pkgs.writeText "pg_ident.conf" cfg.identMap}'
|
|
||||||
log_destination = 'stderr'
|
|
||||||
log_line_prefix = '${cfg.logLinePrefix}'
|
|
||||||
listen_addresses = '${if cfg.enableTCPIP then "*" else "localhost"}'
|
|
||||||
port = ${toString cfg.port}
|
|
||||||
${cfg.extraConfig}
|
|
||||||
'';
|
|
||||||
|
|
||||||
groupAccessAvailable = versionAtLeast postgresql.version "11.0";
|
groupAccessAvailable = versionAtLeast postgresql.version "11.0";
|
||||||
|
|
||||||
in
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
|
imports = [
|
||||||
|
(mkRemovedOptionModule [ "services" "postgresql" "extraConfig" ] "Use services.postgresql.settings instead.")
|
||||||
|
];
|
||||||
|
|
||||||
###### interface
|
###### interface
|
||||||
|
|
||||||
@ -212,10 +212,28 @@ in
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
extraConfig = mkOption {
|
settings = mkOption {
|
||||||
type = types.lines;
|
type = with types; attrsOf (oneOf [ bool float int str ]);
|
||||||
default = "";
|
default = {};
|
||||||
description = "Additional text to be appended to <filename>postgresql.conf</filename>.";
|
description = ''
|
||||||
|
PostgreSQL configuration. Refer to
|
||||||
|
<link xlink:href="https://www.postgresql.org/docs/11/config-setting.html#CONFIG-SETTING-CONFIGURATION-FILE"/>
|
||||||
|
for an overview of <literal>postgresql.conf</literal>.
|
||||||
|
|
||||||
|
<note><para>
|
||||||
|
String values will automatically be enclosed in single quotes. Single quotes will be
|
||||||
|
escaped with two single quotes as described by the upstream documentation linked above.
|
||||||
|
</para></note>
|
||||||
|
'';
|
||||||
|
example = literalExample ''
|
||||||
|
{
|
||||||
|
log_connections = true;
|
||||||
|
log_statement = "all";
|
||||||
|
logging_collector = true
|
||||||
|
log_disconnections = true
|
||||||
|
log_destination = lib.mkForce "syslog";
|
||||||
|
}
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
recoveryConfig = mkOption {
|
recoveryConfig = mkOption {
|
||||||
@ -245,6 +263,16 @@ in
|
|||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
|
|
||||||
|
services.postgresql.settings =
|
||||||
|
{
|
||||||
|
hba_file = "${pkgs.writeText "pg_hba.conf" cfg.authentication}";
|
||||||
|
ident_file = "${pkgs.writeText "pg_ident.conf" cfg.identMap}";
|
||||||
|
log_destination = "stderr";
|
||||||
|
log_line_prefix = cfg.logLinePrefix;
|
||||||
|
listen_addresses = if cfg.enableTCPIP then "*" else "localhost";
|
||||||
|
port = cfg.port;
|
||||||
|
};
|
||||||
|
|
||||||
services.postgresql.package =
|
services.postgresql.package =
|
||||||
# Note: when changing the default, make it conditional on
|
# Note: when changing the default, make it conditional on
|
||||||
# ‘system.stateVersion’ to maintain compatibility with existing
|
# ‘system.stateVersion’ to maintain compatibility with existing
|
||||||
|
@ -1,123 +0,0 @@
|
|||||||
# deepin
|
|
||||||
|
|
||||||
{ config, pkgs, lib, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
###### interface
|
|
||||||
|
|
||||||
options = {
|
|
||||||
|
|
||||||
services.deepin.core.enable = lib.mkEnableOption "
|
|
||||||
Basic dbus and systemd services, groups and users needed by the
|
|
||||||
Deepin Desktop Environment.
|
|
||||||
";
|
|
||||||
|
|
||||||
services.deepin.deepin-menu.enable = lib.mkEnableOption "
|
|
||||||
DBus service for unified menus in Deepin Desktop Environment.
|
|
||||||
";
|
|
||||||
|
|
||||||
services.deepin.deepin-turbo.enable = lib.mkEnableOption "
|
|
||||||
Turbo service for the Deepin Desktop Environment. It is a daemon
|
|
||||||
that helps to launch applications faster.
|
|
||||||
";
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
###### implementation
|
|
||||||
|
|
||||||
config = lib.mkMerge [
|
|
||||||
|
|
||||||
(lib.mkIf config.services.deepin.core.enable {
|
|
||||||
environment.systemPackages = [
|
|
||||||
pkgs.deepin.dde-api
|
|
||||||
pkgs.deepin.dde-calendar
|
|
||||||
pkgs.deepin.dde-control-center
|
|
||||||
pkgs.deepin.dde-daemon
|
|
||||||
pkgs.deepin.dde-dock
|
|
||||||
pkgs.deepin.dde-launcher
|
|
||||||
pkgs.deepin.dde-file-manager
|
|
||||||
pkgs.deepin.dde-session-ui
|
|
||||||
pkgs.deepin.deepin-anything
|
|
||||||
pkgs.deepin.deepin-image-viewer
|
|
||||||
];
|
|
||||||
|
|
||||||
services.dbus.packages = [
|
|
||||||
pkgs.deepin.dde-api
|
|
||||||
pkgs.deepin.dde-calendar
|
|
||||||
pkgs.deepin.dde-control-center
|
|
||||||
pkgs.deepin.dde-daemon
|
|
||||||
pkgs.deepin.dde-dock
|
|
||||||
pkgs.deepin.dde-launcher
|
|
||||||
pkgs.deepin.dde-file-manager
|
|
||||||
pkgs.deepin.dde-session-ui
|
|
||||||
pkgs.deepin.deepin-anything
|
|
||||||
pkgs.deepin.deepin-image-viewer
|
|
||||||
];
|
|
||||||
|
|
||||||
systemd.packages = [
|
|
||||||
pkgs.deepin.dde-api
|
|
||||||
pkgs.deepin.dde-daemon
|
|
||||||
pkgs.deepin.dde-file-manager
|
|
||||||
pkgs.deepin.deepin-anything
|
|
||||||
];
|
|
||||||
|
|
||||||
boot.extraModulePackages = [ config.boot.kernelPackages.deepin-anything ];
|
|
||||||
|
|
||||||
boot.kernelModules = [ "vfs_monitor" ];
|
|
||||||
|
|
||||||
users.groups.deepin-sound-player = { };
|
|
||||||
|
|
||||||
users.users.deepin-sound-player = {
|
|
||||||
description = "Deepin sound player";
|
|
||||||
group = "deepin-sound-player";
|
|
||||||
isSystemUser = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
users.groups.deepin-daemon = { };
|
|
||||||
|
|
||||||
users.users.deepin-daemon = {
|
|
||||||
description = "Deepin daemon user";
|
|
||||||
group = "deepin-daemon";
|
|
||||||
isSystemUser = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
users.groups.deepin_anything_server = { };
|
|
||||||
|
|
||||||
users.users.deepin_anything_server = {
|
|
||||||
description = "Deepin Anything Server";
|
|
||||||
group = "deepin_anything_server";
|
|
||||||
isSystemUser = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
security.pam.services.deepin-auth-keyboard.text = ''
|
|
||||||
# original at ${pkgs.deepin.dde-daemon}/etc/pam.d/deepin-auth-keyboard
|
|
||||||
auth [success=2 default=ignore] pam_lsass.so
|
|
||||||
auth [success=1 default=ignore] pam_unix.so nullok_secure try_first_pass
|
|
||||||
auth requisite pam_deny.so
|
|
||||||
auth required pam_permit.so
|
|
||||||
'';
|
|
||||||
|
|
||||||
environment.etc = {
|
|
||||||
"polkit-1/localauthority/10-vendor.d/com.deepin.api.device.pkla".source = "${pkgs.deepin.dde-api}/etc/polkit-1/localauthority/10-vendor.d/com.deepin.api.device.pkla";
|
|
||||||
"polkit-1/localauthority/10-vendor.d/com.deepin.daemon.Accounts.pkla".source = "${pkgs.deepin.dde-daemon}/etc/polkit-1/localauthority/10-vendor.d/com.deepin.daemon.Accounts.pkla";
|
|
||||||
"polkit-1/localauthority/10-vendor.d/com.deepin.daemon.Grub2.pkla".source = "${pkgs.deepin.dde-daemon}/etc/polkit-1/localauthority/10-vendor.d/com.deepin.daemon.Grub2.pkla";
|
|
||||||
};
|
|
||||||
|
|
||||||
services.deepin.deepin-menu.enable = true;
|
|
||||||
services.deepin.deepin-turbo.enable = true;
|
|
||||||
})
|
|
||||||
|
|
||||||
(lib.mkIf config.services.deepin.deepin-menu.enable {
|
|
||||||
services.dbus.packages = [ pkgs.deepin.deepin-menu ];
|
|
||||||
})
|
|
||||||
|
|
||||||
(lib.mkIf config.services.deepin.deepin-turbo.enable {
|
|
||||||
environment.systemPackages = [ pkgs.deepin.deepin-turbo ];
|
|
||||||
systemd.packages = [ pkgs.deepin.deepin-turbo ];
|
|
||||||
})
|
|
||||||
|
|
||||||
];
|
|
||||||
|
|
||||||
}
|
|
@ -160,7 +160,7 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
appConfig = mkOption {
|
appConfig = mkOption {
|
||||||
type = types.loaOf appConfigModule;
|
type = types.attrsOf appConfigModule;
|
||||||
default = {};
|
default = {};
|
||||||
example = literalExample ''
|
example = literalExample ''
|
||||||
"com.github.app" = {
|
"com.github.app" = {
|
||||||
|
@ -81,7 +81,7 @@ in
|
|||||||
{ office1 = { model = "MFC-7860DW"; ip = "192.168.1.2"; };
|
{ office1 = { model = "MFC-7860DW"; ip = "192.168.1.2"; };
|
||||||
office2 = { model = "MFC-7860DW"; nodename = "BRW0080927AFBCE"; };
|
office2 = { model = "MFC-7860DW"; nodename = "BRW0080927AFBCE"; };
|
||||||
};
|
};
|
||||||
type = with types; loaOf (submodule netDeviceOpts);
|
type = with types; attrsOf (submodule netDeviceOpts);
|
||||||
description = ''
|
description = ''
|
||||||
The list of network devices that will be registered against the brscan4
|
The list of network devices that will be registered against the brscan4
|
||||||
sane backend.
|
sane backend.
|
||||||
|
@ -28,6 +28,12 @@ in
|
|||||||
example = "0.0.0.0";
|
example = "0.0.0.0";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
openFirewall = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Whether to open ports in the firewall for the server.";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -35,6 +41,10 @@ in
|
|||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
|
|
||||||
|
networking.firewall = mkIf cfg.openFirewall {
|
||||||
|
allowedTCPPorts = [ cfg.listen.port ];
|
||||||
|
};
|
||||||
|
|
||||||
environment.systemPackages = [ pkg ];
|
environment.systemPackages = [ pkg ];
|
||||||
|
|
||||||
systemd.services.beanstalkd = {
|
systemd.services.beanstalkd = {
|
||||||
|
@ -500,13 +500,6 @@ in
|
|||||||
|
|
||||||
config = {
|
config = {
|
||||||
|
|
||||||
assertions = [
|
|
||||||
{
|
|
||||||
assertion = config.nix.distributedBuilds || config.nix.buildMachines == [];
|
|
||||||
message = "You must set `nix.distributedBuilds = true` to use nix.buildMachines";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
nix.binaryCachePublicKeys = [ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" ];
|
nix.binaryCachePublicKeys = [ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" ];
|
||||||
nix.binaryCaches = [ "https://cache.nixos.org/" ];
|
nix.binaryCaches = [ "https://cache.nixos.org/" ];
|
||||||
|
|
||||||
@ -594,16 +587,10 @@ in
|
|||||||
|
|
||||||
nix.systemFeatures = mkDefault (
|
nix.systemFeatures = mkDefault (
|
||||||
[ "nixos-test" "benchmark" "big-parallel" "kvm" ] ++
|
[ "nixos-test" "benchmark" "big-parallel" "kvm" ] ++
|
||||||
optionals (pkgs.stdenv.isx86_64 && pkgs.hostPlatform.platform ? gcc.arch) (
|
optionals (pkgs.hostPlatform.platform ? gcc.arch) (
|
||||||
# a x86_64 builder can run code for `platform.gcc.arch` and minor architectures:
|
# a builder can run code for `platform.gcc.arch` and inferior architectures
|
||||||
[ "gccarch-${pkgs.hostPlatform.platform.gcc.arch}" ] ++ {
|
[ "gccarch-${pkgs.hostPlatform.platform.gcc.arch}" ] ++
|
||||||
sandybridge = [ "gccarch-westmere" ];
|
map (x: "gccarch-${x}") lib.systems.architectures.inferiors.${pkgs.hostPlatform.platform.gcc.arch}
|
||||||
ivybridge = [ "gccarch-westmere" "gccarch-sandybridge" ];
|
|
||||||
haswell = [ "gccarch-westmere" "gccarch-sandybridge" "gccarch-ivybridge" ];
|
|
||||||
broadwell = [ "gccarch-westmere" "gccarch-sandybridge" "gccarch-ivybridge" "gccarch-haswell" ];
|
|
||||||
skylake = [ "gccarch-westmere" "gccarch-sandybridge" "gccarch-ivybridge" "gccarch-haswell" "gccarch-broadwell" ];
|
|
||||||
skylake-avx512 = [ "gccarch-westmere" "gccarch-sandybridge" "gccarch-ivybridge" "gccarch-haswell" "gccarch-broadwell" "gccarch-skylake" ];
|
|
||||||
}.${pkgs.hostPlatform.platform.gcc.arch} or []
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
inherit (lib) mkDefault mkEnableOption mkIf mkOption types;
|
inherit (lib) mkBefore mkDefault mkEnableOption mkIf mkOption mkRemovedOptionModule types;
|
||||||
inherit (lib) concatStringsSep literalExample mapAttrsToList;
|
inherit (lib) concatStringsSep literalExample mapAttrsToList;
|
||||||
inherit (lib) optional optionalAttrs optionalString singleton versionAtLeast;
|
inherit (lib) optional optionalAttrs optionalString;
|
||||||
|
|
||||||
cfg = config.services.redmine;
|
cfg = config.services.redmine;
|
||||||
|
format = pkgs.formats.yaml {};
|
||||||
bundle = "${cfg.package}/share/redmine/bin/bundle";
|
bundle = "${cfg.package}/share/redmine/bin/bundle";
|
||||||
|
|
||||||
databaseYml = pkgs.writeText "database.yml" ''
|
databaseYml = pkgs.writeText "database.yml" ''
|
||||||
@ -20,24 +20,8 @@ let
|
|||||||
${optionalString (cfg.database.type == "mysql2" && cfg.database.socket != null) "socket: ${cfg.database.socket}"}
|
${optionalString (cfg.database.type == "mysql2" && cfg.database.socket != null) "socket: ${cfg.database.socket}"}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
configurationYml = pkgs.writeText "configuration.yml" ''
|
configurationYml = format.generate "configuration.yml" cfg.settings;
|
||||||
default:
|
additionalEnvironment = pkgs.writeText "additional_environment.rb" cfg.extraEnv;
|
||||||
scm_subversion_command: ${pkgs.subversion}/bin/svn
|
|
||||||
scm_mercurial_command: ${pkgs.mercurial}/bin/hg
|
|
||||||
scm_git_command: ${pkgs.gitAndTools.git}/bin/git
|
|
||||||
scm_cvs_command: ${pkgs.cvs}/bin/cvs
|
|
||||||
scm_bazaar_command: ${pkgs.breezy}/bin/bzr
|
|
||||||
scm_darcs_command: ${pkgs.darcs}/bin/darcs
|
|
||||||
|
|
||||||
${cfg.extraConfig}
|
|
||||||
'';
|
|
||||||
|
|
||||||
additionalEnvironment = pkgs.writeText "additional_environment.rb" ''
|
|
||||||
config.logger = Logger.new("${cfg.stateDir}/log/production.log", 14, 1048576)
|
|
||||||
config.logger.level = Logger::INFO
|
|
||||||
|
|
||||||
${cfg.extraEnv}
|
|
||||||
'';
|
|
||||||
|
|
||||||
unpackTheme = unpack "theme";
|
unpackTheme = unpack "theme";
|
||||||
unpackPlugin = unpack "plugin";
|
unpackPlugin = unpack "plugin";
|
||||||
@ -56,8 +40,13 @@ let
|
|||||||
pgsqlLocal = cfg.database.createLocally && cfg.database.type == "postgresql";
|
pgsqlLocal = cfg.database.createLocally && cfg.database.type == "postgresql";
|
||||||
|
|
||||||
in
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
|
imports = [
|
||||||
|
(mkRemovedOptionModule [ "services" "redmine" "extraConfig" ] "Use services.redmine.settings instead.")
|
||||||
|
(mkRemovedOptionModule [ "services" "redmine" "database" "password" ] "Use services.redmine.database.passwordFile instead.")
|
||||||
|
];
|
||||||
|
|
||||||
|
# interface
|
||||||
options = {
|
options = {
|
||||||
services.redmine = {
|
services.redmine = {
|
||||||
enable = mkEnableOption "Redmine";
|
enable = mkEnableOption "Redmine";
|
||||||
@ -93,21 +82,24 @@ in
|
|||||||
description = "The state directory, logs and plugins are stored here.";
|
description = "The state directory, logs and plugins are stored here.";
|
||||||
};
|
};
|
||||||
|
|
||||||
extraConfig = mkOption {
|
settings = mkOption {
|
||||||
type = types.lines;
|
type = format.type;
|
||||||
default = "";
|
default = {};
|
||||||
description = ''
|
description = ''
|
||||||
Extra configuration in configuration.yml.
|
Redmine configuration (<filename>configuration.yml</filename>). Refer to
|
||||||
|
<link xlink:href="https://guides.rubyonrails.org/action_mailer_basics.html#action-mailer-configuration"/>
|
||||||
See <link xlink:href="https://guides.rubyonrails.org/action_mailer_basics.html#action-mailer-configuration"/>
|
|
||||||
for details.
|
for details.
|
||||||
'';
|
'';
|
||||||
example = literalExample ''
|
example = literalExample ''
|
||||||
email_delivery:
|
{
|
||||||
delivery_method: smtp
|
email_delivery = {
|
||||||
smtp_settings:
|
delivery_method = "smtp";
|
||||||
address: mail.example.com
|
smtp_settings = {
|
||||||
port: 25
|
address = "mail.example.com";
|
||||||
|
port = 25;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -186,16 +178,6 @@ in
|
|||||||
description = "Database user.";
|
description = "Database user.";
|
||||||
};
|
};
|
||||||
|
|
||||||
password = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "";
|
|
||||||
description = ''
|
|
||||||
The password corresponding to <option>database.user</option>.
|
|
||||||
Warning: this is stored in cleartext in the Nix store!
|
|
||||||
Use <option>database.passwordFile</option> instead.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
passwordFile = mkOption {
|
passwordFile = mkOption {
|
||||||
type = types.nullOr types.path;
|
type = types.nullOr types.path;
|
||||||
default = null;
|
default = null;
|
||||||
@ -226,11 +208,12 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# implementation
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
|
|
||||||
assertions = [
|
assertions = [
|
||||||
{ assertion = cfg.database.passwordFile != null || cfg.database.password != "" || cfg.database.socket != null;
|
{ assertion = cfg.database.passwordFile != null || cfg.database.socket != null;
|
||||||
message = "one of services.redmine.database.socket, services.redmine.database.passwordFile, or services.redmine.database.password must be set";
|
message = "one of services.redmine.database.socket or services.redmine.database.passwordFile must be set";
|
||||||
}
|
}
|
||||||
{ assertion = cfg.database.createLocally -> cfg.database.user == cfg.user;
|
{ assertion = cfg.database.createLocally -> cfg.database.user == cfg.user;
|
||||||
message = "services.redmine.database.user must be set to ${cfg.user} if services.redmine.database.createLocally is set true";
|
message = "services.redmine.database.user must be set to ${cfg.user} if services.redmine.database.createLocally is set true";
|
||||||
@ -243,6 +226,22 @@ in
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
services.redmine.settings = {
|
||||||
|
production = {
|
||||||
|
scm_subversion_command = "${pkgs.subversion}/bin/svn";
|
||||||
|
scm_mercurial_command = "${pkgs.mercurial}/bin/hg";
|
||||||
|
scm_git_command = "${pkgs.gitAndTools.git}/bin/git";
|
||||||
|
scm_cvs_command = "${pkgs.cvs}/bin/cvs";
|
||||||
|
scm_bazaar_command = "${pkgs.breezy}/bin/bzr";
|
||||||
|
scm_darcs_command = "${pkgs.darcs}/bin/darcs";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.redmine.extraEnv = mkBefore ''
|
||||||
|
config.logger = Logger.new("${cfg.stateDir}/log/production.log", 14, 1048576)
|
||||||
|
config.logger.level = Logger::INFO
|
||||||
|
'';
|
||||||
|
|
||||||
services.mysql = mkIf mysqlLocal {
|
services.mysql = mkIf mysqlLocal {
|
||||||
enable = true;
|
enable = true;
|
||||||
package = mkDefault pkgs.mariadb;
|
package = mkDefault pkgs.mariadb;
|
||||||
@ -338,7 +337,7 @@ in
|
|||||||
|
|
||||||
|
|
||||||
# handle database.passwordFile & permissions
|
# handle database.passwordFile & permissions
|
||||||
DBPASS=$(head -n1 ${cfg.database.passwordFile})
|
DBPASS=${optionalString (cfg.database.passwordFile != null) "$(head -n1 ${cfg.database.passwordFile})"}
|
||||||
cp -f ${databaseYml} "${cfg.stateDir}/config/database.yml"
|
cp -f ${databaseYml} "${cfg.stateDir}/config/database.yml"
|
||||||
sed -e "s,#dbpass#,$DBPASS,g" -i "${cfg.stateDir}/config/database.yml"
|
sed -e "s,#dbpass#,$DBPASS,g" -i "${cfg.stateDir}/config/database.yml"
|
||||||
chmod 440 "${cfg.stateDir}/config/database.yml"
|
chmod 440 "${cfg.stateDir}/config/database.yml"
|
||||||
@ -379,17 +378,6 @@ in
|
|||||||
redmine.gid = config.ids.gids.redmine;
|
redmine.gid = config.ids.gids.redmine;
|
||||||
};
|
};
|
||||||
|
|
||||||
warnings = optional (cfg.database.password != "")
|
|
||||||
''config.services.redmine.database.password will be stored as plaintext
|
|
||||||
in the Nix store. Use database.passwordFile instead.'';
|
|
||||||
|
|
||||||
# Create database passwordFile default when password is configured.
|
|
||||||
services.redmine.database.passwordFile =
|
|
||||||
(mkDefault (toString (pkgs.writeTextFile {
|
|
||||||
name = "redmine-database-password";
|
|
||||||
text = cfg.database.password;
|
|
||||||
})));
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
269
nixos/modules/services/networking/biboumi.nix
Normal file
269
nixos/modules/services/networking/biboumi.nix
Normal file
@ -0,0 +1,269 @@
|
|||||||
|
{ config, lib, pkgs, options, ... }:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.services.biboumi;
|
||||||
|
inherit (config.environment) etc;
|
||||||
|
rootDir = "/run/biboumi/mnt-root";
|
||||||
|
stateDir = "/var/lib/biboumi";
|
||||||
|
settingsFile = pkgs.writeText "biboumi.cfg" (
|
||||||
|
generators.toKeyValue {
|
||||||
|
mkKeyValue = k: v:
|
||||||
|
if v == null then ""
|
||||||
|
else generators.mkKeyValueDefault {} "=" k v;
|
||||||
|
} cfg.settings);
|
||||||
|
need_CAP_NET_BIND_SERVICE = cfg.settings.identd_port != 0 && cfg.settings.identd_port < 1024;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
services.biboumi = {
|
||||||
|
enable = mkEnableOption "the Biboumi XMPP gateway to IRC";
|
||||||
|
|
||||||
|
settings = mkOption {
|
||||||
|
description = ''
|
||||||
|
See <link xlink:href="https://lab.louiz.org/louiz/biboumi/blob/8.5/doc/biboumi.1.rst">biboumi 8.5</link>
|
||||||
|
for documentation.
|
||||||
|
'';
|
||||||
|
default = {};
|
||||||
|
type = types.submodule {
|
||||||
|
freeformType = with types;
|
||||||
|
(attrsOf (nullOr (oneOf [str int bool]))) // {
|
||||||
|
description = "settings option";
|
||||||
|
};
|
||||||
|
options.admin = mkOption {
|
||||||
|
type = with types; listOf str;
|
||||||
|
default = [];
|
||||||
|
example = ["admin@example.org"];
|
||||||
|
apply = concatStringsSep ":";
|
||||||
|
description = ''
|
||||||
|
The bare JID of the gateway administrator. This JID will have more
|
||||||
|
privileges than other standard users, for example some administration
|
||||||
|
ad-hoc commands will only be available to that JID.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
options.ca_file = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
default = "/etc/ssl/certs/ca-certificates.crt";
|
||||||
|
description = ''
|
||||||
|
Specifies which file should be used as the list of trusted CA
|
||||||
|
when negociating a TLS session.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
options.db_name = mkOption {
|
||||||
|
type = with types; either path str;
|
||||||
|
default = "${stateDir}/biboumi.sqlite";
|
||||||
|
description = ''
|
||||||
|
The name of the database to use.
|
||||||
|
'';
|
||||||
|
example = "postgresql://user:secret@localhost";
|
||||||
|
};
|
||||||
|
options.hostname = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
example = "biboumi.example.org";
|
||||||
|
description = ''
|
||||||
|
The hostname served by the XMPP gateway.
|
||||||
|
This domain must be configured in the XMPP server
|
||||||
|
as an external component.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
options.identd_port = mkOption {
|
||||||
|
type = types.port;
|
||||||
|
default = 113;
|
||||||
|
example = 0;
|
||||||
|
description = ''
|
||||||
|
The TCP port on which to listen for identd queries.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
options.log_level = mkOption {
|
||||||
|
type = types.ints.between 0 3;
|
||||||
|
default = 1;
|
||||||
|
description = ''
|
||||||
|
Indicate what type of log messages to write in the logs.
|
||||||
|
0 is debug, 1 is info, 2 is warning, 3 is error.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
options.password = mkOption {
|
||||||
|
type = with types; nullOr str;
|
||||||
|
description = ''
|
||||||
|
The password used to authenticate the XMPP component to your XMPP server.
|
||||||
|
This password must be configured in the XMPP server,
|
||||||
|
associated with the external component on
|
||||||
|
<link linkend="opt-services.biboumi.settings.hostname">hostname</link>.
|
||||||
|
|
||||||
|
Set it to null and use <link linkend="opt-services.biboumi.credentialsFile">credentialsFile</link>
|
||||||
|
if you do not want this password to go into the Nix store.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
options.persistent_by_default = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Whether all rooms will be persistent by default:
|
||||||
|
the value of the “persistent” option in the global configuration of each
|
||||||
|
user will be “true”, but the value of each individual room will still
|
||||||
|
default to false. This means that a user just needs to change the global
|
||||||
|
“persistent” configuration option to false in order to override this.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
options.policy_directory = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
default = "${pkgs.biboumi}/etc/biboumi";
|
||||||
|
description = ''
|
||||||
|
A directory that should contain the policy files,
|
||||||
|
used to customize Botan’s behaviour
|
||||||
|
when negociating the TLS connections with the IRC servers.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
options.port = mkOption {
|
||||||
|
type = types.port;
|
||||||
|
default = 5347;
|
||||||
|
description = ''
|
||||||
|
The TCP port to use to connect to the local XMPP component.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
options.realname_customization = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = ''
|
||||||
|
Whether the users will be able to use
|
||||||
|
the ad-hoc commands that lets them configure
|
||||||
|
their realname and username.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
options.realname_from_jid = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Whether the realname and username of each biboumi
|
||||||
|
user will be extracted from their JID.
|
||||||
|
Otherwise they will be set to the nick
|
||||||
|
they used to connect to the IRC server.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
options.xmpp_server_ip = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "127.0.0.1";
|
||||||
|
description = ''
|
||||||
|
The IP address to connect to the XMPP server on.
|
||||||
|
The connection to the XMPP server is unencrypted,
|
||||||
|
so the biboumi instance and the server should
|
||||||
|
normally be on the same host.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
credentialsFile = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
description = ''
|
||||||
|
Path to a configuration file to be merged with the settings.
|
||||||
|
Beware not to surround "=" with spaces when setting biboumi's options in this file.
|
||||||
|
Useful to merge a file which is better kept out of the Nix store
|
||||||
|
because it contains sensible data like
|
||||||
|
<link linkend="opt-services.biboumi.settings.password">password</link>.
|
||||||
|
'';
|
||||||
|
default = "/dev/null";
|
||||||
|
example = "/run/keys/biboumi.cfg";
|
||||||
|
};
|
||||||
|
|
||||||
|
openFirewall = mkEnableOption "opening of the identd port in the firewall";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
networking.firewall = mkIf (cfg.openFirewall && cfg.settings.identd_port != 0)
|
||||||
|
{ allowedTCPPorts = [ cfg.settings.identd_port ]; };
|
||||||
|
|
||||||
|
systemd.services.biboumi = {
|
||||||
|
description = "Biboumi, XMPP to IRC gateway";
|
||||||
|
after = [ "network.target" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "notify";
|
||||||
|
# Biboumi supports systemd's watchdog.
|
||||||
|
WatchdogSec = 20;
|
||||||
|
Restart = "always";
|
||||||
|
# Use "+" because credentialsFile may not be accessible to User= or Group=.
|
||||||
|
ExecStartPre = [("+" + pkgs.writeShellScript "biboumi-prestart" ''
|
||||||
|
set -eux
|
||||||
|
cat ${settingsFile} '${cfg.credentialsFile}' |
|
||||||
|
install -m 644 /dev/stdin /run/biboumi/biboumi.cfg
|
||||||
|
'')];
|
||||||
|
ExecStart = "${pkgs.biboumi}/bin/biboumi /run/biboumi/biboumi.cfg";
|
||||||
|
ExecReload = "${pkgs.coreutils}/bin/kill -USR1 $MAINPID";
|
||||||
|
# Firewalls needing opening for output connections can still do that
|
||||||
|
# selectively for biboumi with:
|
||||||
|
# users.users.biboumi.isSystemUser = true;
|
||||||
|
# and, for example:
|
||||||
|
# networking.nftables.ruleset = ''
|
||||||
|
# add rule inet filter output meta skuid biboumi tcp accept
|
||||||
|
# '';
|
||||||
|
DynamicUser = true;
|
||||||
|
RootDirectory = rootDir;
|
||||||
|
RootDirectoryStartOnly = true;
|
||||||
|
InaccessiblePaths = [ "-+${rootDir}" ];
|
||||||
|
RuntimeDirectory = [ "biboumi" (removePrefix "/run/" rootDir) ];
|
||||||
|
RuntimeDirectoryMode = "700";
|
||||||
|
StateDirectory = "biboumi";
|
||||||
|
StateDirectoryMode = "700";
|
||||||
|
MountAPIVFS = true;
|
||||||
|
UMask = "0066";
|
||||||
|
BindPaths = [
|
||||||
|
stateDir
|
||||||
|
# This is for Type="notify"
|
||||||
|
# See https://github.com/systemd/systemd/issues/3544
|
||||||
|
"/run/systemd/notify"
|
||||||
|
"/run/systemd/journal/socket"
|
||||||
|
];
|
||||||
|
BindReadOnlyPaths = [
|
||||||
|
builtins.storeDir
|
||||||
|
"/etc"
|
||||||
|
];
|
||||||
|
# The following options are only for optimizing:
|
||||||
|
# systemd-analyze security biboumi
|
||||||
|
AmbientCapabilities = [ (optionalString need_CAP_NET_BIND_SERVICE "CAP_NET_BIND_SERVICE") ];
|
||||||
|
CapabilityBoundingSet = [ (optionalString need_CAP_NET_BIND_SERVICE "CAP_NET_BIND_SERVICE") ];
|
||||||
|
# ProtectClock= adds DeviceAllow=char-rtc r
|
||||||
|
DeviceAllow = "";
|
||||||
|
LockPersonality = true;
|
||||||
|
MemoryDenyWriteExecute = true;
|
||||||
|
NoNewPrivileges = true;
|
||||||
|
PrivateDevices = true;
|
||||||
|
PrivateMounts = true;
|
||||||
|
PrivateNetwork = mkDefault false;
|
||||||
|
PrivateTmp = true;
|
||||||
|
# PrivateUsers=true breaks AmbientCapabilities=CAP_NET_BIND_SERVICE
|
||||||
|
# See https://bugs.archlinux.org/task/65921
|
||||||
|
PrivateUsers = !need_CAP_NET_BIND_SERVICE;
|
||||||
|
ProtectClock = true;
|
||||||
|
ProtectControlGroups = true;
|
||||||
|
ProtectHome = true;
|
||||||
|
ProtectHostname = true;
|
||||||
|
ProtectKernelLogs = true;
|
||||||
|
ProtectKernelModules = true;
|
||||||
|
ProtectKernelTunables = true;
|
||||||
|
ProtectSystem = "strict";
|
||||||
|
RemoveIPC = true;
|
||||||
|
# AF_UNIX is for /run/systemd/notify
|
||||||
|
RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ];
|
||||||
|
RestrictNamespaces = true;
|
||||||
|
RestrictRealtime = true;
|
||||||
|
RestrictSUIDSGID = true;
|
||||||
|
SystemCallFilter = [
|
||||||
|
"@system-service"
|
||||||
|
# Groups in @system-service which do not contain a syscall
|
||||||
|
# listed by perf stat -e 'syscalls:sys_enter_*' biboumi biboumi.cfg
|
||||||
|
# in tests, and seem likely not necessary for biboumi.
|
||||||
|
# To run such a perf in ExecStart=, you have to:
|
||||||
|
# - AmbientCapabilities="CAP_SYS_ADMIN"
|
||||||
|
# - mount -o remount,mode=755 /sys/kernel/debug/{,tracing}
|
||||||
|
"~@aio" "~@chown" "~@ipc" "~@keyring" "~@resources" "~@setuid" "~@timer"
|
||||||
|
];
|
||||||
|
SystemCallArchitectures = "native";
|
||||||
|
SystemCallErrorNumber = "EPERM";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
meta.maintainers = with maintainers; [ julm ];
|
||||||
|
}
|
@ -3,7 +3,7 @@
|
|||||||
let
|
let
|
||||||
|
|
||||||
inherit (lib.options) literalExample mkEnableOption mkOption;
|
inherit (lib.options) literalExample mkEnableOption mkOption;
|
||||||
inherit (lib.types) bool enum int lines loaOf nullOr path str submodule;
|
inherit (lib.types) bool enum int lines attrsOf nullOr path str submodule;
|
||||||
inherit (lib.modules) mkDefault mkIf mkMerge;
|
inherit (lib.modules) mkDefault mkIf mkMerge;
|
||||||
|
|
||||||
commonDescr = ''
|
commonDescr = ''
|
||||||
@ -248,7 +248,7 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
modems = mkOption {
|
modems = mkOption {
|
||||||
type = loaOf (submodule [ modemConfigOptions ]);
|
type = attrsOf (submodule [ modemConfigOptions ]);
|
||||||
default = {};
|
default = {};
|
||||||
example.ttyS1 = {
|
example.ttyS1 = {
|
||||||
type = "cirrus";
|
type = "cirrus";
|
||||||
|
@ -458,7 +458,7 @@ in {
|
|||||||
|
|
||||||
systemd.services.NetworkManager-dispatcher = {
|
systemd.services.NetworkManager-dispatcher = {
|
||||||
wantedBy = [ "network.target" ];
|
wantedBy = [ "network.target" ];
|
||||||
restartTriggers = [ configFile ];
|
restartTriggers = [ configFile overrideNameserversScript ];
|
||||||
|
|
||||||
# useful binaries for user-specified hooks
|
# useful binaries for user-specified hooks
|
||||||
path = [ pkgs.iproute pkgs.utillinux pkgs.coreutils ];
|
path = [ pkgs.iproute pkgs.utillinux pkgs.coreutils ];
|
||||||
|
@ -140,7 +140,7 @@ in
|
|||||||
services.nylon = mkOption {
|
services.nylon = mkOption {
|
||||||
default = {};
|
default = {};
|
||||||
description = "Collection of named nylon instances";
|
description = "Collection of named nylon instances";
|
||||||
type = with types; loaOf (submodule nylonOpts);
|
type = with types; attrsOf (submodule nylonOpts);
|
||||||
internal = true;
|
internal = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -655,7 +655,7 @@ in
|
|||||||
|
|
||||||
description = "Define the virtual hosts";
|
description = "Define the virtual hosts";
|
||||||
|
|
||||||
type = with types; loaOf (submodule vHostOpts);
|
type = with types; attrsOf (submodule vHostOpts);
|
||||||
|
|
||||||
example = {
|
example = {
|
||||||
myhost = {
|
myhost = {
|
||||||
|
@ -43,10 +43,10 @@ services.prosody = {
|
|||||||
<link linkend="opt-services.prosody.ssl.cert">ssl.cert</link> = "/var/lib/acme/example.org/fullchain.pem";
|
<link linkend="opt-services.prosody.ssl.cert">ssl.cert</link> = "/var/lib/acme/example.org/fullchain.pem";
|
||||||
<link linkend="opt-services.prosody.ssl.key">ssl.key</link> = "/var/lib/acme/example.org/key.pem";
|
<link linkend="opt-services.prosody.ssl.key">ssl.key</link> = "/var/lib/acme/example.org/key.pem";
|
||||||
<link linkend="opt-services.prosody.virtualHosts">virtualHosts</link>."example.org" = {
|
<link linkend="opt-services.prosody.virtualHosts">virtualHosts</link>."example.org" = {
|
||||||
<link linkend="opt-services.prosody.virtualHosts._name__.enabled">enabled</link> = true;
|
<link linkend="opt-services.prosody.virtualHosts._name_.enabled">enabled</link> = true;
|
||||||
<link linkend="opt-services.prosody.virtualHosts._name__.domain">domain</link> = "example.org";
|
<link linkend="opt-services.prosody.virtualHosts._name_.domain">domain</link> = "example.org";
|
||||||
<link linkend="opt-services.prosody.virtualHosts._name__.ssl.cert">ssl.cert</link> = "/var/lib/acme/example.org/fullchain.pem";
|
<link linkend="opt-services.prosody.virtualHosts._name_.ssl.cert">ssl.cert</link> = "/var/lib/acme/example.org/fullchain.pem";
|
||||||
<link linkend="opt-services.prosody.virtualHosts._name__.ssl.key">ssl.key</link> = "/var/lib/acme/example.org/key.pem";
|
<link linkend="opt-services.prosody.virtualHosts._name_.ssl.key">ssl.key</link> = "/var/lib/acme/example.org/key.pem";
|
||||||
};
|
};
|
||||||
<link linkend="opt-services.prosody.muc">muc</link> = [ {
|
<link linkend="opt-services.prosody.muc">muc</link> = [ {
|
||||||
<link linkend="opt-services.prosody.muc">domain</link> = "conference.example.org";
|
<link linkend="opt-services.prosody.muc">domain</link> = "conference.example.org";
|
||||||
|
47
nixos/modules/services/networking/robustirc-bridge.nix
Normal file
47
nixos/modules/services/networking/robustirc-bridge.nix
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.robustirc-bridge;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
services.robustirc-bridge = {
|
||||||
|
enable = mkEnableOption "RobustIRC bridge";
|
||||||
|
|
||||||
|
extraFlags = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
description = ''Extra flags passed to the <command>robustirc-bridge</command> command. See <link xlink:href="https://robustirc.net/docs/adminguide.html#_bridge">RobustIRC Documentation</link> or robustirc-bridge(1) for details.'';
|
||||||
|
example = [
|
||||||
|
"-network robustirc.net"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
systemd.services.robustirc-bridge = {
|
||||||
|
description = "RobustIRC bridge";
|
||||||
|
documentation = [
|
||||||
|
"man:robustirc-bridge(1)"
|
||||||
|
"https://robustirc.net/"
|
||||||
|
];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
after = [ "network.target" ];
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
DynamicUser = true;
|
||||||
|
ExecStart = "${pkgs.robustirc-bridge}/bin/robustirc-bridge ${concatStringsSep " " cfg.extraFlags}";
|
||||||
|
Restart = "on-failure";
|
||||||
|
|
||||||
|
# Hardening
|
||||||
|
PrivateDevices = true;
|
||||||
|
ProtectSystem = true;
|
||||||
|
ProtectHome = true;
|
||||||
|
PrivateTmp = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
@ -361,7 +361,7 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
users.users = mkOption {
|
users.users = mkOption {
|
||||||
type = with types; loaOf (submodule userOptions);
|
type = with types; attrsOf (submodule userOptions);
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -34,8 +34,8 @@ let
|
|||||||
User tor
|
User tor
|
||||||
DataDirectory ${torDirectory}
|
DataDirectory ${torDirectory}
|
||||||
${optionalString cfg.enableGeoIP ''
|
${optionalString cfg.enableGeoIP ''
|
||||||
GeoIPFile ${pkgs.tor.geoip}/share/tor/geoip
|
GeoIPFile ${cfg.package.geoip}/share/tor/geoip
|
||||||
GeoIPv6File ${pkgs.tor.geoip}/share/tor/geoip6
|
GeoIPv6File ${cfg.package.geoip}/share/tor/geoip6
|
||||||
''}
|
''}
|
||||||
|
|
||||||
${optint "ControlPort" cfg.controlPort}
|
${optint "ControlPort" cfg.controlPort}
|
||||||
@ -123,6 +123,16 @@ in
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
package = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = pkgs.tor;
|
||||||
|
defaultText = "pkgs.tor";
|
||||||
|
example = literalExample "pkgs.tor";
|
||||||
|
description = ''
|
||||||
|
Tor package to use
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
enableGeoIP = mkOption {
|
enableGeoIP = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = true;
|
default = true;
|
||||||
@ -597,7 +607,7 @@ in
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
type = types.loaOf (types.submodule ({name, ...}: {
|
type = types.attrsOf (types.submodule ({name, ...}: {
|
||||||
options = {
|
options = {
|
||||||
|
|
||||||
name = mkOption {
|
name = mkOption {
|
||||||
@ -749,8 +759,8 @@ in
|
|||||||
serviceConfig =
|
serviceConfig =
|
||||||
{ Type = "simple";
|
{ Type = "simple";
|
||||||
# Translated from the upstream contrib/dist/tor.service.in
|
# Translated from the upstream contrib/dist/tor.service.in
|
||||||
ExecStartPre = "${pkgs.tor}/bin/tor -f ${torRcFile} --verify-config";
|
ExecStartPre = "${cfg.package}/bin/tor -f ${torRcFile} --verify-config";
|
||||||
ExecStart = "${pkgs.tor}/bin/tor -f ${torRcFile}";
|
ExecStart = "${cfg.package}/bin/tor -f ${torRcFile}";
|
||||||
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
|
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
|
||||||
KillSignal = "SIGINT";
|
KillSignal = "SIGINT";
|
||||||
TimeoutSec = 30;
|
TimeoutSec = 30;
|
||||||
@ -773,7 +783,7 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
environment.systemPackages = [ pkgs.tor ];
|
environment.systemPackages = [ cfg.package ];
|
||||||
|
|
||||||
services.privoxy = mkIf (cfg.client.enable && cfg.client.privoxy.enable) {
|
services.privoxy = mkIf (cfg.client.enable && cfg.client.privoxy.enable) {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
@ -516,7 +516,7 @@ in
|
|||||||
<filename>/dev/mapper/<replaceable>name</replaceable></filename>.
|
<filename>/dev/mapper/<replaceable>name</replaceable></filename>.
|
||||||
'';
|
'';
|
||||||
|
|
||||||
type = with types; loaOf (submodule (
|
type = with types; attrsOf (submodule (
|
||||||
{ name, ... }: { options = {
|
{ name, ... }: { options = {
|
||||||
|
|
||||||
name = mkOption {
|
name = mkOption {
|
||||||
|
@ -121,12 +121,13 @@ let
|
|||||||
copy_bin_and_libs ${pkgs.mdadm}/sbin/mdmon
|
copy_bin_and_libs ${pkgs.mdadm}/sbin/mdmon
|
||||||
|
|
||||||
# Copy udev.
|
# Copy udev.
|
||||||
copy_bin_and_libs ${udev}/lib/systemd/systemd-udevd
|
|
||||||
copy_bin_and_libs ${udev}/lib/systemd/systemd-sysctl
|
|
||||||
copy_bin_and_libs ${udev}/bin/udevadm
|
copy_bin_and_libs ${udev}/bin/udevadm
|
||||||
|
copy_bin_and_libs ${udev}/lib/systemd/systemd-sysctl
|
||||||
for BIN in ${udev}/lib/udev/*_id; do
|
for BIN in ${udev}/lib/udev/*_id; do
|
||||||
copy_bin_and_libs $BIN
|
copy_bin_and_libs $BIN
|
||||||
done
|
done
|
||||||
|
# systemd-udevd is only a symlink to udevadm these days
|
||||||
|
ln -sf udevadm $out/bin/systemd-udevd
|
||||||
|
|
||||||
# Copy modprobe.
|
# Copy modprobe.
|
||||||
copy_bin_and_libs ${pkgs.kmod}/bin/kmod
|
copy_bin_and_libs ${pkgs.kmod}/bin/kmod
|
||||||
@ -557,7 +558,7 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
fileSystems = mkOption {
|
fileSystems = mkOption {
|
||||||
type = with lib.types; loaOf (submodule {
|
type = with lib.types; attrsOf (submodule {
|
||||||
options.neededForBoot = mkOption {
|
options.neededForBoot = mkOption {
|
||||||
default = false;
|
default = false;
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
|
@ -234,7 +234,6 @@ in rec {
|
|||||||
path = mkOption {
|
path = mkOption {
|
||||||
default = [];
|
default = [];
|
||||||
type = with types; listOf (oneOf [ package str ]);
|
type = with types; listOf (oneOf [ package str ]);
|
||||||
apply = ps: "${makeBinPath ps}:${makeSearchPathOutput "bin" "sbin" ps}";
|
|
||||||
description = ''
|
description = ''
|
||||||
Packages added to the service's <envar>PATH</envar>
|
Packages added to the service's <envar>PATH</envar>
|
||||||
environment variable. Both the <filename>bin</filename>
|
environment variable. Both the <filename>bin</filename>
|
||||||
|
@ -257,7 +257,7 @@ let
|
|||||||
pkgs.gnused
|
pkgs.gnused
|
||||||
systemd
|
systemd
|
||||||
];
|
];
|
||||||
environment.PATH = config.path;
|
environment.PATH = "${makeBinPath config.path}:${makeSearchPathOutput "bin" "sbin" config.path}";
|
||||||
}
|
}
|
||||||
(mkIf (config.preStart != "")
|
(mkIf (config.preStart != "")
|
||||||
{ serviceConfig.ExecStartPre =
|
{ serviceConfig.ExecStartPre =
|
||||||
@ -903,11 +903,9 @@ in
|
|||||||
)
|
)
|
||||||
]);
|
]);
|
||||||
passwd = (mkMerge [
|
passwd = (mkMerge [
|
||||||
[ "mymachines" ]
|
|
||||||
(mkAfter [ "systemd" ])
|
(mkAfter [ "systemd" ])
|
||||||
]);
|
]);
|
||||||
group = (mkMerge [
|
group = (mkMerge [
|
||||||
[ "mymachines" ]
|
|
||||||
(mkAfter [ "systemd" ])
|
(mkAfter [ "systemd" ])
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
@ -1008,7 +1006,7 @@ in
|
|||||||
"sysctl.d/50-coredump.conf".source = "${systemd}/example/sysctl.d/50-coredump.conf";
|
"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";
|
"sysctl.d/50-default.conf".source = "${systemd}/example/sysctl.d/50-default.conf";
|
||||||
|
|
||||||
"tmpfiles.d".source = pkgs.symlinkJoin {
|
"tmpfiles.d".source = (pkgs.symlinkJoin {
|
||||||
name = "tmpfiles.d";
|
name = "tmpfiles.d";
|
||||||
paths = map (p: p + "/lib/tmpfiles.d") cfg.tmpfiles.packages;
|
paths = map (p: p + "/lib/tmpfiles.d") cfg.tmpfiles.packages;
|
||||||
postBuild = ''
|
postBuild = ''
|
||||||
@ -1018,8 +1016,10 @@ in
|
|||||||
exit 1
|
exit 1
|
||||||
)
|
)
|
||||||
done
|
done
|
||||||
'';
|
'' + concatMapStrings (name: optionalString (hasPrefix "tmpfiles.d/" name) ''
|
||||||
};
|
rm -f $out/${removePrefix "tmpfiles.d/" name}
|
||||||
|
'') config.system.build.etc.targets;
|
||||||
|
}) + "/*";
|
||||||
|
|
||||||
"systemd/system-generators" = { source = hooks "generators" cfg.generators; };
|
"systemd/system-generators" = { source = hooks "generators" cfg.generators; };
|
||||||
"systemd/system-shutdown" = { source = hooks "shutdown" cfg.shutdown; };
|
"systemd/system-shutdown" = { source = hooks "shutdown" cfg.shutdown; };
|
||||||
|
@ -46,7 +46,7 @@ in
|
|||||||
Set of files that have to be linked in <filename>/etc</filename>.
|
Set of files that have to be linked in <filename>/etc</filename>.
|
||||||
'';
|
'';
|
||||||
|
|
||||||
type = with types; loaOf (submodule (
|
type = with types; attrsOf (submodule (
|
||||||
{ name, config, ... }:
|
{ name, config, ... }:
|
||||||
{ options = {
|
{ options = {
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ in
|
|||||||
|
|
||||||
options = {
|
options = {
|
||||||
fileSystems = mkOption {
|
fileSystems = mkOption {
|
||||||
type = with lib.types; loaOf (submodule encryptedFSOptions);
|
type = with lib.types; attrsOf (submodule encryptedFSOptions);
|
||||||
};
|
};
|
||||||
swapDevices = mkOption {
|
swapDevices = mkOption {
|
||||||
type = with lib.types; listOf (submodule encryptedFSOptions);
|
type = with lib.types; listOf (submodule encryptedFSOptions);
|
||||||
|
@ -159,7 +159,7 @@ in
|
|||||||
"/bigdisk".label = "bigdisk";
|
"/bigdisk".label = "bigdisk";
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
type = types.loaOf (types.submodule [coreFileSystemOpts fileSystemOpts]);
|
type = types.attrsOf (types.submodule [coreFileSystemOpts fileSystemOpts]);
|
||||||
description = ''
|
description = ''
|
||||||
The file systems to be mounted. It must include an entry for
|
The file systems to be mounted. It must include an entry for
|
||||||
the root directory (<literal>mountPoint = "/"</literal>). Each
|
the root directory (<literal>mountPoint = "/"</literal>). Each
|
||||||
@ -193,7 +193,7 @@ in
|
|||||||
|
|
||||||
boot.specialFileSystems = mkOption {
|
boot.specialFileSystems = mkOption {
|
||||||
default = {};
|
default = {};
|
||||||
type = types.loaOf (types.submodule coreFileSystemOpts);
|
type = types.attrsOf (types.submodule coreFileSystemOpts);
|
||||||
internal = true;
|
internal = true;
|
||||||
description = ''
|
description = ''
|
||||||
Special filesystems that are mounted very early during boot.
|
Special filesystems that are mounted very early during boot.
|
||||||
|
@ -519,7 +519,7 @@ in
|
|||||||
<option>networking.useDHCP</option> is true, then every
|
<option>networking.useDHCP</option> is true, then every
|
||||||
interface not listed here will be configured using DHCP.
|
interface not listed here will be configured using DHCP.
|
||||||
'';
|
'';
|
||||||
type = with types; loaOf (submodule interfaceOpts);
|
type = with types; attrsOf (submodule interfaceOpts);
|
||||||
};
|
};
|
||||||
|
|
||||||
networking.vswitches = mkOption {
|
networking.vswitches = mkOption {
|
||||||
@ -544,7 +544,7 @@ in
|
|||||||
interfaces = mkOption {
|
interfaces = mkOption {
|
||||||
example = [ "eth0" "eth1" ];
|
example = [ "eth0" "eth1" ];
|
||||||
description = "The physical network interfaces connected by the vSwitch.";
|
description = "The physical network interfaces connected by the vSwitch.";
|
||||||
type = with types; loaOf (submodule vswitchInterfaceOpts);
|
type = with types; attrsOf (submodule vswitchInterfaceOpts);
|
||||||
};
|
};
|
||||||
|
|
||||||
controllers = mkOption {
|
controllers = mkOption {
|
||||||
|
@ -43,6 +43,12 @@ in
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ociSeccompBpfHook.enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Enable the OCI seccomp BPF hook";
|
||||||
|
};
|
||||||
|
|
||||||
containersConf = mkOption {
|
containersConf = mkOption {
|
||||||
default = {};
|
default = {};
|
||||||
description = "containers.conf configuration";
|
description = "containers.conf configuration";
|
||||||
@ -116,6 +122,12 @@ in
|
|||||||
[network]
|
[network]
|
||||||
cni_plugin_dirs = ["${pkgs.cni-plugins}/bin/"]
|
cni_plugin_dirs = ["${pkgs.cni-plugins}/bin/"]
|
||||||
|
|
||||||
|
${lib.optionalString (cfg.ociSeccompBpfHook.enable == true) ''
|
||||||
|
[engine]
|
||||||
|
hooks_dir = [
|
||||||
|
"${config.boot.kernelPackages.oci-seccomp-bpf-hook}",
|
||||||
|
]
|
||||||
|
''}
|
||||||
'' + cfg.containersConf.extraConfig;
|
'' + cfg.containersConf.extraConfig;
|
||||||
|
|
||||||
environment.etc."containers/registries.conf".source = toTOML "registries.conf" {
|
environment.etc."containers/registries.conf".source = toTOML "registries.conf" {
|
||||||
|
@ -101,6 +101,7 @@ in
|
|||||||
log_level = "${cfg.logLevel}"
|
log_level = "${cfg.logLevel}"
|
||||||
manage_ns_lifecycle = true
|
manage_ns_lifecycle = true
|
||||||
pinns_path = "${cfg.package}/bin/pinns"
|
pinns_path = "${cfg.package}/bin/pinns"
|
||||||
|
hooks_dir = []
|
||||||
|
|
||||||
${optionalString (cfg.runtime != null) ''
|
${optionalString (cfg.runtime != null) ''
|
||||||
default_runtime = "${cfg.runtime}"
|
default_runtime = "${cfg.runtime}"
|
||||||
|
@ -627,7 +627,7 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
bindMounts = mkOption {
|
bindMounts = mkOption {
|
||||||
type = with types; loaOf (submodule bindMountOpts);
|
type = with types; attrsOf (submodule bindMountOpts);
|
||||||
default = {};
|
default = {};
|
||||||
example = literalExample ''
|
example = literalExample ''
|
||||||
{ "/home" = { hostPath = "/home/alice";
|
{ "/home" = { hostPath = "/home/alice";
|
||||||
|
@ -41,7 +41,7 @@ let
|
|||||||
description = "Source for the in-container mount";
|
description = "Source for the in-container mount";
|
||||||
};
|
};
|
||||||
options = mkOption {
|
options = mkOption {
|
||||||
type = loaOf (str);
|
type = attrsOf (str);
|
||||||
default = [ "bind" ];
|
default = [ "bind" ];
|
||||||
description = ''
|
description = ''
|
||||||
Mount options of the filesystem to be used.
|
Mount options of the filesystem to be used.
|
||||||
@ -61,7 +61,7 @@ in
|
|||||||
containers = mkOption {
|
containers = mkOption {
|
||||||
default = {};
|
default = {};
|
||||||
description = "Declarative container configuration";
|
description = "Declarative container configuration";
|
||||||
type = with types; loaOf (submodule ({ name, config, ... }: {
|
type = with types; attrsOf (submodule ({ name, config, ... }: {
|
||||||
options = {
|
options = {
|
||||||
cmd = mkOption {
|
cmd = mkOption {
|
||||||
type = types.lines;
|
type = types.lines;
|
||||||
|
@ -121,7 +121,8 @@ in rec {
|
|||||||
(onFullSupported "nixos.tests.networking.networkd.dhcpSimple")
|
(onFullSupported "nixos.tests.networking.networkd.dhcpSimple")
|
||||||
(onFullSupported "nixos.tests.networking.networkd.link")
|
(onFullSupported "nixos.tests.networking.networkd.link")
|
||||||
(onFullSupported "nixos.tests.networking.networkd.loopback")
|
(onFullSupported "nixos.tests.networking.networkd.loopback")
|
||||||
(onFullSupported "nixos.tests.networking.networkd.macvlan")
|
# Fails nondeterministically (https://github.com/NixOS/nixpkgs/issues/96709)
|
||||||
|
#(onFullSupported "nixos.tests.networking.networkd.macvlan")
|
||||||
(onFullSupported "nixos.tests.networking.networkd.privacy")
|
(onFullSupported "nixos.tests.networking.networkd.privacy")
|
||||||
(onFullSupported "nixos.tests.networking.networkd.routes")
|
(onFullSupported "nixos.tests.networking.networkd.routes")
|
||||||
(onFullSupported "nixos.tests.networking.networkd.sit")
|
(onFullSupported "nixos.tests.networking.networkd.sit")
|
||||||
|
@ -298,6 +298,7 @@ in
|
|||||||
redis = handleTest ./redis.nix {};
|
redis = handleTest ./redis.nix {};
|
||||||
redmine = handleTest ./redmine.nix {};
|
redmine = handleTest ./redmine.nix {};
|
||||||
restic = handleTest ./restic.nix {};
|
restic = handleTest ./restic.nix {};
|
||||||
|
robustirc-bridge = handleTest ./robustirc-bridge.nix {};
|
||||||
roundcube = handleTest ./roundcube.nix {};
|
roundcube = handleTest ./roundcube.nix {};
|
||||||
rspamd = handleTest ./rspamd.nix {};
|
rspamd = handleTest ./rspamd.nix {};
|
||||||
rss2email = handleTest ./rss2email.nix {};
|
rss2email = handleTest ./rss2email.nix {};
|
||||||
|
@ -59,7 +59,8 @@ pkgs.runCommand "acme-snakeoil-ca" {
|
|||||||
openssl genrsa -out snakeoil.key 4096
|
openssl genrsa -out snakeoil.key 4096
|
||||||
openssl req -new -key snakeoil.key -out snakeoil.csr
|
openssl req -new -key snakeoil.key -out snakeoil.csr
|
||||||
openssl x509 -req -in snakeoil.csr -sha256 -set_serial 666 \
|
openssl x509 -req -in snakeoil.csr -sha256 -set_serial 666 \
|
||||||
-CA ca.pem -CAkey ca.key -out snakeoil.pem -days 36500
|
-CA ca.pem -CAkey ca.key -out snakeoil.pem -days 36500 \
|
||||||
|
-extfile "$OPENSSL_CONF" -extensions req_ext
|
||||||
addpem snakeoil.key ${lib.escapeShellArg fqdn} key
|
addpem snakeoil.key ${lib.escapeShellArg fqdn} key
|
||||||
addpem snakeoil.pem ${lib.escapeShellArg fqdn} cert
|
addpem snakeoil.pem ${lib.escapeShellArg fqdn} cert
|
||||||
'') domains}
|
'') domains}
|
||||||
|
@ -2,170 +2,171 @@
|
|||||||
{
|
{
|
||||||
ca.key = builtins.toFile "ca.key" ''
|
ca.key = builtins.toFile "ca.key" ''
|
||||||
-----BEGIN PRIVATE KEY-----
|
-----BEGIN PRIVATE KEY-----
|
||||||
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
|
||||||
JUsBXFNz132nP4iIr3UKrPedQZijSi4=
|
s9o9Sr49cibZ3CbMjCSNE3AOeVE1/Q==
|
||||||
-----END PRIVATE KEY-----
|
-----END PRIVATE KEY-----
|
||||||
'';
|
'';
|
||||||
ca.cert = builtins.toFile "ca.cert" ''
|
ca.cert = builtins.toFile "ca.cert" ''
|
||||||
-----BEGIN CERTIFICATE-----
|
-----BEGIN CERTIFICATE-----
|
||||||
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
|
||||||
F8Y7
|
1yJD
|
||||||
-----END CERTIFICATE-----
|
-----END CERTIFICATE-----
|
||||||
'';
|
'';
|
||||||
"acme.test".key = builtins.toFile "acme.test.key" ''
|
"acme.test".key = builtins.toFile "acme.test.key" ''
|
||||||
-----BEGIN RSA PRIVATE KEY-----
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
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
|
||||||
-----END RSA PRIVATE KEY-----
|
-----END RSA PRIVATE KEY-----
|
||||||
'';
|
'';
|
||||||
"acme.test".cert = builtins.toFile "acme.test.cert" ''
|
"acme.test".cert = builtins.toFile "acme.test.cert" ''
|
||||||
-----BEGIN CERTIFICATE-----
|
-----BEGIN CERTIFICATE-----
|
||||||
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
|
||||||
|
NbjvWnP8lDU8j2l3eSG58S14iGs=
|
||||||
-----END CERTIFICATE-----
|
-----END CERTIFICATE-----
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,10 @@ import ../make-test-python.nix ({ pkgs, ...} : {
|
|||||||
realms = {
|
realms = {
|
||||||
"ATHENA.MIT.EDU" = {
|
"ATHENA.MIT.EDU" = {
|
||||||
admin_server = "athena.mit.edu";
|
admin_server = "athena.mit.edu";
|
||||||
kdc = "athena.mit.edu";
|
kdc = [
|
||||||
|
"athena01.mit.edu"
|
||||||
|
"athena02.mit.edu"
|
||||||
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
domain_realm = {
|
domain_realm = {
|
||||||
@ -65,7 +68,8 @@ import ../make-test-python.nix ({ pkgs, ...} : {
|
|||||||
[realms]
|
[realms]
|
||||||
ATHENA.MIT.EDU = {
|
ATHENA.MIT.EDU = {
|
||||||
admin_server = athena.mit.edu
|
admin_server = athena.mit.edu
|
||||||
kdc = athena.mit.edu
|
kdc = athena01.mit.edu
|
||||||
|
kdc = athena02.mit.edu
|
||||||
}
|
}
|
||||||
|
|
||||||
[domain_realm]
|
[domain_realm]
|
||||||
|
@ -14,13 +14,10 @@ let
|
|||||||
baseBackupDir = "/tmp/pg_basebackup";
|
baseBackupDir = "/tmp/pg_basebackup";
|
||||||
walBackupDir = "/tmp/pg_wal";
|
walBackupDir = "/tmp/pg_wal";
|
||||||
atLeast12 = lib.versionAtLeast pkg.version "12.0";
|
atLeast12 = lib.versionAtLeast pkg.version "12.0";
|
||||||
restoreCommand = ''
|
|
||||||
restore_command = 'cp ${walBackupDir}/%f %p'
|
|
||||||
'';
|
|
||||||
|
|
||||||
recoveryFile = if atLeast12
|
recoveryFile = if atLeast12
|
||||||
then pkgs.writeTextDir "recovery.signal" ""
|
then pkgs.writeTextDir "recovery.signal" ""
|
||||||
else pkgs.writeTextDir "recovery.conf" "${restoreCommand}";
|
else pkgs.writeTextDir "recovery.conf" "restore_command = 'cp ${walBackupDir}/%f %p'";
|
||||||
|
|
||||||
in {
|
in {
|
||||||
name = "postgresql-wal-receiver-${postgresqlPackage}";
|
name = "postgresql-wal-receiver-${postgresqlPackage}";
|
||||||
@ -30,14 +27,17 @@ let
|
|||||||
services.postgresql = {
|
services.postgresql = {
|
||||||
package = pkg;
|
package = pkg;
|
||||||
enable = true;
|
enable = true;
|
||||||
extraConfig = ''
|
settings = lib.mkMerge [
|
||||||
wal_level = archive # alias for replica on pg >= 9.6
|
{
|
||||||
max_wal_senders = 10
|
wal_level = "archive"; # alias for replica on pg >= 9.6
|
||||||
max_replication_slots = 10
|
max_wal_senders = 10;
|
||||||
'' + lib.optionalString atLeast12 ''
|
max_replication_slots = 10;
|
||||||
${restoreCommand}
|
}
|
||||||
recovery_end_command = 'touch recovery.done'
|
(lib.mkIf atLeast12 {
|
||||||
'';
|
restore_command = "cp ${walBackupDir}/%f %p";
|
||||||
|
recovery_end_command = "touch recovery.done";
|
||||||
|
})
|
||||||
|
];
|
||||||
authentication = ''
|
authentication = ''
|
||||||
host replication ${replicationUser} all trust
|
host replication ${replicationUser} all trust
|
||||||
'';
|
'';
|
||||||
|
29
nixos/tests/robustirc-bridge.nix
Normal file
29
nixos/tests/robustirc-bridge.nix
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import ./make-test-python.nix ({ pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
name = "robustirc-bridge";
|
||||||
|
meta = with pkgs.stdenv.lib.maintainers; {
|
||||||
|
maintainers = [ hax404 ];
|
||||||
|
};
|
||||||
|
|
||||||
|
nodes =
|
||||||
|
{ bridge =
|
||||||
|
{ services.robustirc-bridge = {
|
||||||
|
enable = true;
|
||||||
|
extraFlags = [
|
||||||
|
"-listen localhost:6667"
|
||||||
|
"-network example.com"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
testScript =
|
||||||
|
''
|
||||||
|
start_all()
|
||||||
|
|
||||||
|
bridge.wait_for_unit("robustirc-bridge.service")
|
||||||
|
bridge.wait_for_open_port(1080)
|
||||||
|
bridge.wait_for_open_port(6667)
|
||||||
|
'';
|
||||||
|
})
|
@ -7,18 +7,19 @@ let generateNodeConf = { lib, pkgs, config, privk, pubk, peerId, nodeId, ...}: {
|
|||||||
virtualisation.vlans = [ 1 ];
|
virtualisation.vlans = [ 1 ];
|
||||||
environment.systemPackages = with pkgs; [ wireguard-tools ];
|
environment.systemPackages = with pkgs; [ wireguard-tools ];
|
||||||
boot.extraModulePackages = [ config.boot.kernelPackages.wireguard ];
|
boot.extraModulePackages = [ config.boot.kernelPackages.wireguard ];
|
||||||
systemd.tmpfiles.rules = [
|
|
||||||
"f /run/wg_priv 0640 root systemd-network - ${privk}"
|
|
||||||
];
|
|
||||||
systemd.network = {
|
systemd.network = {
|
||||||
enable = true;
|
enable = true;
|
||||||
netdevs = {
|
netdevs = {
|
||||||
"90-wg0" = {
|
"90-wg0" = {
|
||||||
netdevConfig = { Kind = "wireguard"; Name = "wg0"; };
|
netdevConfig = { Kind = "wireguard"; Name = "wg0"; };
|
||||||
wireguardConfig = {
|
wireguardConfig = {
|
||||||
PrivateKeyFile = "/run/wg_priv";
|
# NOTE: we're storing the wireguard private key in the
|
||||||
|
# store for this test. Do not do this in the real
|
||||||
|
# world. Keep in mind the nix store is
|
||||||
|
# world-readable.
|
||||||
|
PrivateKeyFile = pkgs.writeText "wg0-priv" privk;
|
||||||
ListenPort = 51820;
|
ListenPort = 51820;
|
||||||
FwMark = 42;
|
FirewallMark = 42;
|
||||||
};
|
};
|
||||||
wireguardPeers = [ {wireguardPeerConfig={
|
wireguardPeers = [ {wireguardPeerConfig={
|
||||||
Endpoint = "192.168.1.${peerId}:51820";
|
Endpoint = "192.168.1.${peerId}:51820";
|
||||||
|
@ -144,9 +144,10 @@ import ./make-test-python.nix ({ pkgs, ... }: {
|
|||||||
)
|
)
|
||||||
|
|
||||||
output = machine.succeed("systemctl show | grep Watchdog")
|
output = machine.succeed("systemctl show | grep Watchdog")
|
||||||
assert "RuntimeWatchdogUSec=30s" in output
|
# assert "RuntimeWatchdogUSec=30s" in output
|
||||||
assert "RebootWatchdogUSec=10m" in output
|
# for some reason RuntimeWatchdogUSec, doesn't seem to be updated in here.
|
||||||
assert "KExecWatchdogUSec=5m" in output
|
assert "RebootWatchdogUSec=10min" in output
|
||||||
|
assert "KExecWatchdogUSec=5min" in output
|
||||||
|
|
||||||
# Test systemd cryptsetup support
|
# Test systemd cryptsetup support
|
||||||
with subtest("systemd successfully reads /etc/crypttab and unlocks volumes"):
|
with subtest("systemd successfully reads /etc/crypttab and unlocks volumes"):
|
||||||
|
@ -57,7 +57,7 @@ stdenv.mkDerivation rec {
|
|||||||
|
|
||||||
meta = with stdenv.lib; {
|
meta = with stdenv.lib; {
|
||||||
description = "Sound editor with graphical UI";
|
description = "Sound editor with graphical UI";
|
||||||
homepage = "http://audacityteam.org/";
|
homepage = "https://www.audacityteam.org/";
|
||||||
license = licenses.gpl2Plus;
|
license = licenses.gpl2Plus;
|
||||||
maintainers = with maintainers; [ lheckemann ];
|
maintainers = with maintainers; [ lheckemann ];
|
||||||
platforms = intersectLists platforms.linux platforms.x86; # fails on ARM
|
platforms = intersectLists platforms.linux platforms.x86; # fails on ARM
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{ stdenv, fetchurl, pkgconfig, systemd ? null, libobjc, IOKit, fetchpatch }:
|
{ stdenv, lib, fetchurl, pkgconfig, systemd ? null, libobjc, IOKit, fetchpatch }:
|
||||||
|
|
||||||
stdenv.mkDerivation rec {
|
stdenv.mkDerivation rec {
|
||||||
name = "libusb-1.0.19";
|
name = "libusb-1.0.19";
|
||||||
@ -26,7 +26,7 @@ stdenv.mkDerivation rec {
|
|||||||
NIX_LDFLAGS = stdenv.lib.optionalString stdenv.isLinux "-lgcc_s";
|
NIX_LDFLAGS = stdenv.lib.optionalString stdenv.isLinux "-lgcc_s";
|
||||||
|
|
||||||
preFixup = stdenv.lib.optionalString stdenv.isLinux ''
|
preFixup = stdenv.lib.optionalString stdenv.isLinux ''
|
||||||
sed 's,-ludev,-L${systemd.lib}/lib -ludev,' -i $out/lib/libusb-1.0.la
|
sed 's,-ludev,-L${lib.getLib systemd}/lib -ludev,' -i $out/lib/libusb-1.0.la
|
||||||
'';
|
'';
|
||||||
|
|
||||||
meta = with stdenv.lib; {
|
meta = with stdenv.lib; {
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
{ mkDerivation
|
{ mkDerivation
|
||||||
, stdenv
|
, stdenv
|
||||||
, fetchFromGitHub
|
, fetchFromGitHub
|
||||||
, fetchpatch
|
|
||||||
, installShellFiles
|
|
||||||
, qmake
|
, qmake
|
||||||
, qtbase
|
, qtbase
|
||||||
, qtmultimedia
|
, qtmultimedia
|
||||||
@ -21,26 +19,18 @@ let
|
|||||||
in
|
in
|
||||||
mkDerivation rec {
|
mkDerivation rec {
|
||||||
pname = "bambootracker";
|
pname = "bambootracker";
|
||||||
version = "0.4.3";
|
version = "0.4.4";
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "rerrahkr";
|
owner = "rerrahkr";
|
||||||
repo = "BambooTracker";
|
repo = "BambooTracker";
|
||||||
rev = "v${version}";
|
rev = "v${version}";
|
||||||
sha256 = "0gq40qmsdavsyl2d6a71rwp4mjlwvp1c8bry32srn4hliwfnvqa6";
|
sha256 = "0d0f4jqzknsiq725pvfndarfjg183f92rb0lim3wzshnsixr5vdc";
|
||||||
};
|
};
|
||||||
|
|
||||||
# Fix macOS build until new release
|
sourceRoot = "source/BambooTracker";
|
||||||
patches = [
|
|
||||||
(fetchpatch {
|
|
||||||
url = "https://github.com/rerrahkr/BambooTracker/commit/45346ed99559d44c2e32a5c6138a0835b212e875.patch";
|
|
||||||
sha256 = "1xkiqira1kpcqkacycy0y7qm1brhf89amliv42byijl4palmykh2";
|
|
||||||
})
|
|
||||||
];
|
|
||||||
|
|
||||||
preConfigure = "cd BambooTracker";
|
nativeBuildInputs = [ qmake qttools ];
|
||||||
|
|
||||||
nativeBuildInputs = [ qmake qttools installShellFiles ];
|
|
||||||
|
|
||||||
buildInputs = [ qtbase qtmultimedia ]
|
buildInputs = [ qtbase qtmultimedia ]
|
||||||
++ optional alsaSupport alsaLib
|
++ optional alsaSupport alsaLib
|
||||||
@ -51,17 +41,6 @@ mkDerivation rec {
|
|||||||
++ optional pulseSupport "CONFIG+=use_pulse"
|
++ optional pulseSupport "CONFIG+=use_pulse"
|
||||||
++ optionals jackSupport [ "CONFIG+=use_jack" "CONFIG+=jack_has_rename" ];
|
++ optionals jackSupport [ "CONFIG+=use_jack" "CONFIG+=jack_has_rename" ];
|
||||||
|
|
||||||
postInstall = ''
|
|
||||||
install -Dm644 ../BambooTracker.desktop $out/share/applications/BambooTracker.desktop
|
|
||||||
installManPage ../BambooTracker*.1
|
|
||||||
|
|
||||||
cp -r ../{demos,licenses,skins,LICENSE} $out/share/BambooTracker/
|
|
||||||
|
|
||||||
for size in 16x16 256x256; do
|
|
||||||
install -Dm644 res/icon/icon_$size.png $out/share/icons/hicolor/$size/apps/BambooTracker.png
|
|
||||||
done
|
|
||||||
'';
|
|
||||||
|
|
||||||
meta = with stdenv.lib; {
|
meta = with stdenv.lib; {
|
||||||
description = "A tracker for YM2608 (OPNA) which was used in NEC PC-8801/9801 series computers";
|
description = "A tracker for YM2608 (OPNA) which was used in NEC PC-8801/9801 series computers";
|
||||||
homepage = "https://github.com/rerrahkr/BambooTracker";
|
homepage = "https://github.com/rerrahkr/BambooTracker";
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
|
|
||||||
stdenv.mkDerivation rec {
|
stdenv.mkDerivation rec {
|
||||||
pname = "bchoppr";
|
pname = "bchoppr";
|
||||||
version = "1.6.4";
|
version = "1.8.0";
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "sjaehn";
|
owner = "sjaehn";
|
||||||
repo = pname;
|
repo = pname;
|
||||||
rev = "${version}";
|
rev = "${version}";
|
||||||
sha256 = "16b0sg7q2b8l4y4bp5s3yzsj9j6jayjy2mlvqkby6l7hcgjcj493";
|
sha256 = "1nd6byy75f0rbz9dm9drhxmpsfhxhg0y7q3v2m3098llynhy9k2j";
|
||||||
};
|
};
|
||||||
|
|
||||||
nativeBuildInputs = [ pkg-config ];
|
nativeBuildInputs = [ pkg-config ];
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
|
|
||||||
stdenv.mkDerivation rec {
|
stdenv.mkDerivation rec {
|
||||||
pname = "BJumblr";
|
pname = "BJumblr";
|
||||||
version = "1.4.0";
|
version = "1.4.2";
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "sjaehn";
|
owner = "sjaehn";
|
||||||
repo = pname;
|
repo = pname;
|
||||||
rev = version;
|
rev = version;
|
||||||
sha256 = "03x1gvri9yk000fvvc8zvvywf38cc41vkyhhp9xby71b23n5wbn0";
|
sha256 = "0kl6hrxmqrdf0195bfnzsa2h1073fgiqrfhg2276fm1954sm994v";
|
||||||
};
|
};
|
||||||
|
|
||||||
nativeBuildInputs = [ pkgconfig ];
|
nativeBuildInputs = [ pkgconfig ];
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
|
|
||||||
stdenv.mkDerivation rec {
|
stdenv.mkDerivation rec {
|
||||||
pname = "bschaffl";
|
pname = "bschaffl";
|
||||||
version = "0.3";
|
version = "1.2.0";
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "sjaehn";
|
owner = "sjaehn";
|
||||||
repo = pname;
|
repo = pname;
|
||||||
rev = version;
|
rev = version;
|
||||||
sha256 = "1pcch7j1wgsb77mjy58hl3z43p83dv0vcmyh129m9k216b09gy29";
|
sha256 = "1c09acqrbd387ba41f8ch1qykdap5h6cg9if5pgd16i4dmjnpghj";
|
||||||
};
|
};
|
||||||
|
|
||||||
nativeBuildInputs = [ pkg-config ];
|
nativeBuildInputs = [ pkg-config ];
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
|
|
||||||
stdenv.mkDerivation rec {
|
stdenv.mkDerivation rec {
|
||||||
pname = "dragonfly-reverb";
|
pname = "dragonfly-reverb";
|
||||||
version = "3.1.1";
|
version = "3.2.1";
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "michaelwillis";
|
owner = "michaelwillis";
|
||||||
repo = "dragonfly-reverb";
|
repo = "dragonfly-reverb";
|
||||||
rev = version;
|
rev = version;
|
||||||
sha256 = "188cm45hr0i33m4h2irql1wrsmsfis65s706wjiid0z59q47rf9p";
|
sha256 = "0vfm2510shah67k87mdyar4wr4vqwii59y9lqfhwm6blxparkrqa";
|
||||||
fetchSubmodules = true;
|
fetchSubmodules = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -5,8 +5,7 @@
|
|||||||
, pkgconfig
|
, pkgconfig
|
||||||
, cmake
|
, cmake
|
||||||
, llvm
|
, llvm
|
||||||
# TODO: put back when it builds again
|
, emscripten
|
||||||
# , emscripten
|
|
||||||
, openssl
|
, openssl
|
||||||
, libsndfile
|
, libsndfile
|
||||||
, libmicrohttpd
|
, libmicrohttpd
|
||||||
@ -47,7 +46,7 @@ let
|
|||||||
inherit src;
|
inherit src;
|
||||||
|
|
||||||
nativeBuildInputs = [ makeWrapper pkgconfig cmake vim which ];
|
nativeBuildInputs = [ makeWrapper pkgconfig cmake vim which ];
|
||||||
buildInputs = [ llvm /*emscripten*/ openssl libsndfile libmicrohttpd gnutls libtasn1 p11-kit ];
|
buildInputs = [ llvm emscripten openssl libsndfile libmicrohttpd gnutls libtasn1 p11-kit ];
|
||||||
|
|
||||||
|
|
||||||
passthru = {
|
passthru = {
|
||||||
|
@ -11,13 +11,13 @@ with stdenv.lib;
|
|||||||
|
|
||||||
mkDerivation rec {
|
mkDerivation rec {
|
||||||
pname = "fmit";
|
pname = "fmit";
|
||||||
version = "1.2.13";
|
version = "1.2.14";
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "gillesdegottex";
|
owner = "gillesdegottex";
|
||||||
repo = "fmit";
|
repo = "fmit";
|
||||||
rev = "v${version}";
|
rev = "v${version}";
|
||||||
sha256 = "1qyskam053pvlap1av80rgp12pzhr92rs88vqs6s0ia3ypnixcc6";
|
sha256 = "1q062pfwz2vr9hbfn29fv54ip3jqfd9r99nhpr8w7mn1csy38azx";
|
||||||
};
|
};
|
||||||
|
|
||||||
nativeBuildInputs = [ qmake itstool wrapQtAppsHook ];
|
nativeBuildInputs = [ qmake itstool wrapQtAppsHook ];
|
||||||
|
@ -2,20 +2,21 @@
|
|||||||
|
|
||||||
stdenv.mkDerivation rec {
|
stdenv.mkDerivation rec {
|
||||||
pname = "geonkick";
|
pname = "geonkick";
|
||||||
version = "2.3.3";
|
version = "2.3.7";
|
||||||
|
|
||||||
src = fetchFromGitLab {
|
src = fetchFromGitLab {
|
||||||
owner = "iurie-sw";
|
owner = "iurie-sw";
|
||||||
repo = pname;
|
repo = pname;
|
||||||
rev = "v${version}";
|
rev = "v${version}";
|
||||||
sha256 = "0h1abb6q2bmi01a3v37adkc4zc03j47jpvffz8p2lpp33xhljghs";
|
sha256 = "1wdcbwiyy6i5agq5lffkyilyc8mv1cc4mp9h0nybn240vb2flqc2";
|
||||||
};
|
};
|
||||||
|
|
||||||
nativeBuildInputs = [ cmake pkg-config ];
|
nativeBuildInputs = [ cmake pkg-config ];
|
||||||
|
|
||||||
buildInputs = [ redkite libsndfile rapidjson libjack2 lv2 libX11 cairo ];
|
buildInputs = [ redkite libsndfile rapidjson libjack2 lv2 libX11 cairo ];
|
||||||
|
|
||||||
cmakeFlags = [ "-DGKICK_REDKITE_SDK_PATH=${redkite}" ];
|
# https://github.com/iurie-sw/geonkick/issues/120
|
||||||
|
cmakeFlags = [ "-DGKICK_REDKITE_SDK_PATH=${redkite}" "-DCMAKE_INSTALL_LIBDIR=lib" ];
|
||||||
|
|
||||||
meta = {
|
meta = {
|
||||||
homepage = "https://gitlab.com/iurie-sw/geonkick";
|
homepage = "https://gitlab.com/iurie-sw/geonkick";
|
||||||
|
@ -14,7 +14,7 @@ python3Packages.buildPythonApplication rec {
|
|||||||
] ++ (with python3Packages; [
|
] ++ (with python3Packages; [
|
||||||
configobj
|
configobj
|
||||||
requests
|
requests
|
||||||
tornado_4
|
tornado
|
||||||
]);
|
]);
|
||||||
|
|
||||||
# no tests implemented
|
# no tests implemented
|
||||||
|
@ -21,7 +21,7 @@ pythonPackages.buildPythonApplication rec {
|
|||||||
];
|
];
|
||||||
|
|
||||||
propagatedBuildInputs = with pythonPackages; [
|
propagatedBuildInputs = with pythonPackages; [
|
||||||
gst-python pygobject3 pykka tornado_4 requests setuptools
|
gst-python pygobject3 pykka tornado requests setuptools
|
||||||
] ++ stdenv.lib.optional (!stdenv.isDarwin) dbus-python;
|
] ++ stdenv.lib.optional (!stdenv.isDarwin) dbus-python;
|
||||||
|
|
||||||
# There are no tests
|
# There are no tests
|
||||||
|
@ -14,16 +14,16 @@ let
|
|||||||
in
|
in
|
||||||
rustPlatform.buildRustPackage rec {
|
rustPlatform.buildRustPackage rec {
|
||||||
pname = "ncspot";
|
pname = "ncspot";
|
||||||
version = "0.2.1";
|
version = "0.2.2";
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "hrkfdn";
|
owner = "hrkfdn";
|
||||||
repo = "ncspot";
|
repo = "ncspot";
|
||||||
rev = "v${version}";
|
rev = "v${version}";
|
||||||
sha256 = "1yx0fc24bgh1x6fdwznc1hqvjq0j7i0zvws3bsyijzs7q48jm0z7";
|
sha256 = "1i17pidw2hylijwfn96f2bnswfxxwdln2ydsq8b1q4hfzfbxlfk2";
|
||||||
};
|
};
|
||||||
|
|
||||||
cargoSha256 = "0bh2shg80xbs2cw10dabrdxkvhf2csk5h9wmmk5z87q6w25paz1f";
|
cargoSha256 = "1cpy4wrj9dz2crva4p18f8hzym73x4m2mcfds4ppri4ir7qg29dr";
|
||||||
|
|
||||||
cargoBuildFlags = [ "--no-default-features" "--features" "${lib.concatStringsSep "," features}" ];
|
cargoBuildFlags = [ "--no-default-features" "--features" "${lib.concatStringsSep "," features}" ];
|
||||||
|
|
||||||
|
@ -1,81 +0,0 @@
|
|||||||
{ stdenv, lib, fontconfig, zlib, libGL, glib, pango
|
|
||||||
, gdk-pixbuf, freetype, atk, cairo, libsForQt5, xorg
|
|
||||||
, sqlite, taglib, nss, nspr, cups, dbus, alsaLib
|
|
||||||
, libpulseaudio, deepin, qt5, harfbuzz, p11-kit
|
|
||||||
, libgpgerror, libudev0-shim, makeWrapper, dpkg, fetchurl }:
|
|
||||||
let
|
|
||||||
rpath = lib.makeLibraryPath [
|
|
||||||
fontconfig.lib
|
|
||||||
zlib
|
|
||||||
stdenv.cc.cc.lib
|
|
||||||
libGL
|
|
||||||
glib
|
|
||||||
pango
|
|
||||||
gdk-pixbuf
|
|
||||||
freetype
|
|
||||||
atk
|
|
||||||
cairo
|
|
||||||
libsForQt5.vlc
|
|
||||||
sqlite
|
|
||||||
taglib
|
|
||||||
nss
|
|
||||||
nspr
|
|
||||||
cups.lib
|
|
||||||
dbus.lib
|
|
||||||
alsaLib
|
|
||||||
libpulseaudio
|
|
||||||
xorg.libX11
|
|
||||||
xorg.libXext
|
|
||||||
xorg.libXtst
|
|
||||||
xorg.libXdamage
|
|
||||||
xorg.libXScrnSaver
|
|
||||||
xorg.libxcb
|
|
||||||
xorg.libXi
|
|
||||||
deepin.qcef
|
|
||||||
qt5.qtwebchannel
|
|
||||||
qt5.qtbase
|
|
||||||
qt5.qtx11extras
|
|
||||||
qt5.qtdeclarative
|
|
||||||
harfbuzz
|
|
||||||
p11-kit
|
|
||||||
libgpgerror
|
|
||||||
];
|
|
||||||
|
|
||||||
runtimeLibs = lib.makeLibraryPath [ libudev0-shim ];
|
|
||||||
|
|
||||||
in stdenv.mkDerivation rec {
|
|
||||||
pname = "netease-cloud-music";
|
|
||||||
version = "1.2.0";
|
|
||||||
src = fetchurl {
|
|
||||||
url = "http://d1.music.126.net/dmusic/netease-cloud-music_1.2.0_amd64_deepin_stable_20190424.deb";
|
|
||||||
sha256 = "0hg8jqim77vd0fmk8gfbz2fmlj99byxcm9jn70xf7vk1sy7wp6h1";
|
|
||||||
curlOpts = "-A 'Mozilla/5.0'";
|
|
||||||
};
|
|
||||||
unpackCmd = "${dpkg}/bin/dpkg -x $src .";
|
|
||||||
sourceRoot = ".";
|
|
||||||
|
|
||||||
nativeBuildInputs = [ qt5.wrapQtAppsHook makeWrapper ];
|
|
||||||
|
|
||||||
installPhase = ''
|
|
||||||
mkdir -p $out
|
|
||||||
cp -r usr/* $out
|
|
||||||
'';
|
|
||||||
|
|
||||||
preFixup = ''
|
|
||||||
local exefile="$out/bin/netease-cloud-music"
|
|
||||||
patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" "$exefile"
|
|
||||||
patchelf --set-rpath "$out/libs:$(patchelf --print-rpath "$exefile"):${rpath}" "$exefile"
|
|
||||||
|
|
||||||
wrapProgram $out/bin/netease-cloud-music \
|
|
||||||
--prefix LD_LIBRARY_PATH : "${runtimeLibs}" \
|
|
||||||
--set QCEF_INSTALL_PATH "${deepin.qcef}/lib/qcef"
|
|
||||||
'';
|
|
||||||
|
|
||||||
meta = {
|
|
||||||
description = "Client for Netease Cloud Music service";
|
|
||||||
homepage = "https://music.163.com";
|
|
||||||
platforms = [ "i686-linux" "x86_64-linux" ];
|
|
||||||
maintainers = [ stdenv.lib.maintainers.mlatus ];
|
|
||||||
license = stdenv.lib.licenses.unfreeRedistributable;
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,37 +1,34 @@
|
|||||||
{ stdenv, fetchFromGitHub, python2Packages, chromaprint }:
|
{ stdenv, fetchFromGitHub, python3Packages, chromaprint }:
|
||||||
|
|
||||||
python2Packages.buildPythonApplication rec {
|
python3Packages.buildPythonApplication rec {
|
||||||
pname = "puddletag";
|
pname = "puddletag";
|
||||||
version = "1.2.0";
|
version = "2.0.1";
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "keithgg";
|
owner = "keithgg";
|
||||||
repo = "puddletag";
|
repo = "puddletag";
|
||||||
rev = "v${version}";
|
rev = version;
|
||||||
sha256 = "1g6wa91awy17z5b704yi9kfynnvfm9lkrvpfvwccscr1h8s3qmiz";
|
sha256 = "sha256-9l8Pc77MX5zFkOqU00HFS8//3Bzd2OMnVV1brmWsNAQ=";
|
||||||
};
|
};
|
||||||
|
|
||||||
setSourceRoot = ''
|
sourceRoot = "source/source";
|
||||||
sourceRoot=$(echo */source)
|
|
||||||
'';
|
|
||||||
|
|
||||||
disabled = python2Packages.isPy3k; # work to support python 3 has not begun
|
propagatedBuildInputs = [ chromaprint ] ++ (with python3Packages; [
|
||||||
|
|
||||||
propagatedBuildInputs = [ chromaprint ] ++ (with python2Packages; [
|
|
||||||
configobj
|
configobj
|
||||||
mutagen
|
mutagen
|
||||||
pyparsing
|
pyparsing
|
||||||
pyqt4
|
pyqt5
|
||||||
]);
|
]);
|
||||||
|
|
||||||
doCheck = false; # there are no tests
|
doCheck = false; # there are no tests
|
||||||
|
|
||||||
dontStrip = true; # we are not generating any binaries
|
dontStrip = true; # we are not generating any binaries
|
||||||
|
|
||||||
meta = with stdenv.lib; {
|
meta = with stdenv.lib; {
|
||||||
description = "An audio tag editor similar to the Windows program, Mp3tag";
|
description = "An audio tag editor similar to the Windows program, Mp3tag";
|
||||||
homepage = "https://docs.puddletag.net";
|
homepage = "https://docs.puddletag.net";
|
||||||
license = licenses.gpl3;
|
license = licenses.gpl3;
|
||||||
maintainers = with maintainers; [ peterhoeg ];
|
maintainers = with maintainers; [ peterhoeg ];
|
||||||
platforms = platforms.linux;
|
platforms = platforms.linux;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
, faacSupport ? false, faac ? null
|
, faacSupport ? false, faac ? null
|
||||||
, flacSupport ? true, flac ? null
|
, flacSupport ? true, flac ? null
|
||||||
, soxSupport ? true, sox ? null
|
, soxSupport ? true, sox ? null
|
||||||
, vorbisSupport ? true, vorbisTools ? null
|
, vorbisSupport ? true, vorbis-tools ? null
|
||||||
}:
|
}:
|
||||||
|
|
||||||
assert mp3Support -> lame != null;
|
assert mp3Support -> lame != null;
|
||||||
@ -12,7 +12,7 @@ assert opusSupport -> opusTools != null;
|
|||||||
assert faacSupport -> faac != null;
|
assert faacSupport -> faac != null;
|
||||||
assert flacSupport -> flac != null;
|
assert flacSupport -> flac != null;
|
||||||
assert soxSupport -> sox != null;
|
assert soxSupport -> sox != null;
|
||||||
assert vorbisSupport -> vorbisTools != null;
|
assert vorbisSupport -> vorbis-tools != null;
|
||||||
|
|
||||||
let
|
let
|
||||||
zeroconf = pythonPackages.callPackage ./zeroconf.nix { };
|
zeroconf = pythonPackages.callPackage ./zeroconf.nix { };
|
||||||
@ -37,7 +37,7 @@ pythonPackages.buildPythonApplication {
|
|||||||
++ stdenv.lib.optional faacSupport faac
|
++ stdenv.lib.optional faacSupport faac
|
||||||
++ stdenv.lib.optional flacSupport flac
|
++ stdenv.lib.optional flacSupport flac
|
||||||
++ stdenv.lib.optional soxSupport sox
|
++ stdenv.lib.optional soxSupport sox
|
||||||
++ stdenv.lib.optional vorbisSupport vorbisTools;
|
++ stdenv.lib.optional vorbisSupport vorbis-tools;
|
||||||
|
|
||||||
# upstream has no tests
|
# upstream has no tests
|
||||||
checkPhase = ''
|
checkPhase = ''
|
||||||
|
@ -4,11 +4,11 @@
|
|||||||
|
|
||||||
mkDerivation rec {
|
mkDerivation rec {
|
||||||
pname = "qsynth";
|
pname = "qsynth";
|
||||||
version = "0.6.2";
|
version = "0.6.3";
|
||||||
|
|
||||||
src = fetchurl {
|
src = fetchurl {
|
||||||
url = "mirror://sourceforge/qsynth/${pname}-${version}.tar.gz";
|
url = "mirror://sourceforge/qsynth/${pname}-${version}.tar.gz";
|
||||||
sha256 = "0cp6vrqrj37rv3a7qfvqrg64j7zwpfj60y5b83mlkzvmg1sgjnlv";
|
sha256 = "0xiqmpzpxjvh32vivfj6h33w0ahmyfjzjb41b6fnf92bbg9k6mqv";
|
||||||
};
|
};
|
||||||
|
|
||||||
nativeBuildInputs = [ autoconf pkgconfig ];
|
nativeBuildInputs = [ autoconf pkgconfig ];
|
||||||
|
@ -14,7 +14,7 @@ in
|
|||||||
|
|
||||||
stdenv.mkDerivation rec {
|
stdenv.mkDerivation rec {
|
||||||
pname = "renoise";
|
pname = "renoise";
|
||||||
version = "3.2.1";
|
version = "3.2.2";
|
||||||
|
|
||||||
src =
|
src =
|
||||||
if stdenv.hostPlatform.system == "x86_64-linux" then
|
if stdenv.hostPlatform.system == "x86_64-linux" then
|
||||||
@ -24,7 +24,7 @@ stdenv.mkDerivation rec {
|
|||||||
"https://files.renoise.com/demo/Renoise_${urlVersion version}_Demo_Linux.tar.gz"
|
"https://files.renoise.com/demo/Renoise_${urlVersion version}_Demo_Linux.tar.gz"
|
||||||
"https://web.archive.org/web/https://files.renoise.com/demo/Renoise_${urlVersion version}_Demo_Linux.tar.gz"
|
"https://web.archive.org/web/https://files.renoise.com/demo/Renoise_${urlVersion version}_Demo_Linux.tar.gz"
|
||||||
];
|
];
|
||||||
sha256 = "0dhcidgnjzd4abw0xw1waj9mazp03nbvjcr2xx09l8gnfrkvny46";
|
sha256 = "1v249kmyidx55kppk3sry7yg6hl1a91ixhnwz36h4y134fs7bkrl";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
releasePath
|
releasePath
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user