Merge remote-tracking branch 'origin/master' into haskell-updates.

This commit is contained in:
Peter Simons 2020-09-04 15:56:33 +02:00
commit fcbf5bf857
827 changed files with 20754 additions and 21911 deletions

View File

@ -57,10 +57,13 @@ indent_size = unset
[deps.nix]
insert_final_newline = unset
[eggs.nix]
trim_trailing_whitespace = unset
[gemset.nix]
insert_final_newline = unset
[node-packages.nix]
[node-{composition,packages}.nix]
insert_final_newline = unset
[nixos/modules/services/networking/ircd-hybrid/*.{conf,in}]
@ -102,5 +105,8 @@ insert_final_newline = unset
indent_size = unset
trim_trailing_whitespace = unset
[pkgs/top-level/emscripten-packages.nix]
trim_trailing_whitespace = unset
[pkgs/top-level/perl-packages.nix]
indent_size = unset

27
.github/workflows/editorconfig.yml vendored Normal file
View 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 }}

View File

@ -436,6 +436,12 @@ lib.mapAttrs (n: v: v // { shortName = n; }) {
};
# Proprietary binaries; free to redistribute without modification.
databricks = {
fullName = "Databricks Proprietary License";
url = "https://pypi.org/project/databricks-connect";
free = false;
};
issl = {
fullName = "Intel Simplified Software License";
url = "https://software.intel.com/en-us/license/intel-simplified-software-license";

View File

@ -613,7 +613,6 @@ rec {
if tp.name == "option set" || tp.name == "submodule" then
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 "loaOf" then types.loaOf (types.submodule options)
else if optionSetIn "listOf" then types.listOf (types.submodule options)
else if optionSetIn "nullOr" then types.nullOr (types.submodule options)
else tp;

View File

@ -689,14 +689,15 @@ rec {
"/prefix/nix-profiles-library-paths.patch"
"/prefix/compose-search-path.patch" ]
*/
readPathsFromFile = rootPath: file:
let
lines = lib.splitString "\n" (builtins.readFile file);
removeComments = lib.filter (line: line != "" && !(lib.hasPrefix "#" line));
relativePaths = removeComments lines;
absolutePaths = builtins.map (path: rootPath + "/${path}") relativePaths;
in
absolutePaths;
readPathsFromFile = lib.warn "lib.readPathsFromFile is deprecated, use a list instead"
(rootPath: file:
let
lines = lib.splitString "\n" (builtins.readFile file);
removeComments = lib.filter (line: line != "" && !(lib.hasPrefix "#" line));
relativePaths = removeComments lines;
absolutePaths = builtins.map (path: rootPath + "/${path}") relativePaths;
in
absolutePaths);
/* Read the contents of a file removing the trailing \n

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

View File

@ -7,6 +7,7 @@ rec {
inspect = import ./inspect.nix { inherit lib; };
platforms = import ./platforms.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
# necessary.
@ -76,6 +77,7 @@ rec {
# uname -r
release = null;
};
isStatic = final.isWasm || final.isRedox;
kernelArch =
if final.isAarch32 then "arm"
@ -125,6 +127,7 @@ rec {
else throw "Don't know how to run ${final.config} executables.";
} // mapAttrs (n: v: v final.parsed) inspect.predicates
// mapAttrs (n: v: v final.platform.gcc.arch or "default") architectures.predicates
// args;
in assert final.useAndroidPrebuilt -> final.isAndroid;
assert lib.foldl

View File

@ -46,7 +46,7 @@ rec {
armv7a-android-prebuilt = {
config = "armv7a-unknown-linux-androideabi";
sdkVer = "24";
sdkVer = "29";
ndkVer = "18b";
platform = platforms.armv7a-android;
useAndroidPrebuilt = true;
@ -54,7 +54,7 @@ rec {
aarch64-android-prebuilt = {
config = "aarch64-unknown-linux-android";
sdkVer = "24";
sdkVer = "29";
ndkVer = "18b";
platform = platforms.aarch64-multiplatform;
useAndroidPrebuilt = true;

View File

@ -252,8 +252,8 @@ rec {
merge = mergeEqualOption;
};
# drop this in the future:
list = builtins.trace "`types.list` is deprecated; use `types.listOf` instead" types.listOf;
# TODO: drop this in the future:
list = builtins.trace "`types.list` has been removed; please use `types.listOf` instead" types.listOf;
listOf = elemType: mkOptionType rec {
name = "listOf";
@ -326,110 +326,15 @@ rec {
functor = (defaultFunctor name) // { wrapped = elemType; };
};
# List or attribute set of ...
loaOf = elemType:
let
convertAllLists = loc: defs:
let
padWidth = stringLength (toString (length defs));
unnamedPrefix = i: "unnamed-" + fixedWidthNumber padWidth i + ".";
in
imap1 (i: convertIfList loc (unnamedPrefix i)) defs;
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; };
};
# TODO: drop this in the future:
loaOf =
let msg =
''
`types.loaOf` has been removed and mixing lists with attribute values
is no longer possible; please use `types.attrsOf` instead.
See https://github.com/NixOS/nixpkgs/issues/1800 for the motivation.
'';
in builtins.trace msg types.attrsOf;
# Value of given type but with no merging (i.e. `uniq list`s are not concatenated).
uniq = elemType: mkOptionType rec {

View File

@ -2879,6 +2879,12 @@
githubId = 5918766;
name = "Franz Thoma";
};
fooker = {
email = "fooker@lab.sh";
github = "fooker";
githubId = 405105;
name = "Dustin Frisch";
};
forkk = {
email = "forkk@forkk.net";
github = "forkk";
@ -4092,6 +4098,12 @@
githubId = 1918771;
name = "Joe Doyle";
};
jperras = {
email = "joel@nerderati.com";
github = "jperras";
githubId = 20675;
name = "Joël Perras";
};
jpierre03 = {
email = "nix@prunetwork.fr";
github = "jpierre03";
@ -4304,6 +4316,12 @@
githubId = 494012;
name = "Kevin Cox";
};
kfollesdal = {
email = "kfollesdal@gmail.com";
github = "kfollesdal";
githubId = 546087;
name = "Kristoffer K. Føllesdal";
};
khumba = {
email = "bog@khumba.net";
github = "khumba";
@ -7169,6 +7187,16 @@
githubId = 3621083;
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 = {
email = "christian@ulrich.earth";
github = "royneary";
@ -7355,6 +7383,12 @@
githubId = 1153271;
name = "Sander van der Burg";
};
sarcasticadmin = {
email = "rob@sarcasticadmin.com";
github = "sarcasticadmin";
githubId = 30531572;
name = "Robert James Hernandez";
};
sargon = {
email = "danielehlers@mindeye.net";
github = "sargon";
@ -7989,6 +8023,12 @@
githubId = 65870;
name = "Сухарик";
};
SuperSandro2000 = {
email = "sandro.jaeckel@gmail.com";
github = "SuperSandro2000";
githubId = 7258858;
name = "Sandro Jäckel";
};
SuprDewd = {
email = "suprdewd@gmail.com";
github = "SuprDewd";
@ -9488,6 +9528,12 @@
github = "fzakaria";
githubId = 605070;
};
nagisa = {
name = "Simonas Kazlauskas";
email = "nixpkgs@kazlauskas.me";
github = "nagisa";
githubId = 679122;
};
yevhenshymotiuk = {
name = "Yevhen Shymotiuk";
email = "yevhenshymotiuk@gmail.com";

View File

@ -35,6 +35,10 @@ lua-cmsgpack,,,,,
lua-iconv,,,,,
lua-lsp,,http://luarocks.org/dev,,,
lua-messagepack,,,,,
lua-resty-http,,,,,
lua-resty-jwt,,,,,
lua-resty-openidc,,,,,
lua-resty-session,,,,,
lua-term,,,,,
lua-toml,,,,,
lua-zlib,,,,,koral

1 # nix name luarocks name server version luaversion maintainers
35 lua-iconv
36 lua-lsp http://luarocks.org/dev
37 lua-messagepack
38 lua-resty-http
39 lua-resty-jwt
40 lua-resty-openidc
41 lua-resty-session
42 lua-term
43 lua-toml
44 lua-zlib koral

View File

@ -58,9 +58,9 @@
Like <literal>boot.debug1</literal> or
<literal>boot.debug1devices</literal>, but runs stage1 until all
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
<option><link linkend="opt-fileSystems._name__.neededForBoot">neededForBoot</link></option>
<option><link linkend="opt-fileSystems._name_.neededForBoot">neededForBoot</link></option>
on a file system.
</para>
</listitem>

View File

@ -27,7 +27,7 @@
<screen>
# nixos-container create foo --config '
<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>
By default the next free address in the <literal>10.233.0.0/16</literal> subnet will be chosen

View File

@ -23,12 +23,12 @@
<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
<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
<command>systemctl</command> e.g. <command>systemctl start
data.mount</command>.
Mount points are created automatically if they dont already exist. For
<option><link linkend="opt-fileSystems._name__.device">device</link></option>,
<option><link linkend="opt-fileSystems._name_.device">device</link></option>,
its best to use the topology-independent device aliases in
<filename>/dev/disk/by-label</filename> and
<filename>/dev/disk/by-uuid</filename>, as these dont change if the
@ -36,7 +36,7 @@
</para>
<para>
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
necessary kernel module automatically. However, if the file system is needed
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
you to the emergency shell. You can make a mount asynchronous and
non-critical by adding
<literal><link linkend="opt-fileSystems._name__.options">options</link> = [
<literal><link linkend="opt-fileSystems._name_.options">options</link> = [
"nofail" ];</literal>.
</para>
</note>

View File

@ -10,7 +10,7 @@
automatically configure network interfaces. However, you can configure an
interface manually as follows:
<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";
prefixLength = 24;
} ];

View File

@ -26,7 +26,7 @@
As with IPv4 networking interfaces are automatically configured via DHCPv6.
You can configure an interface manually:
<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";
prefixLength = 64;
} ];

View File

@ -30,7 +30,7 @@ Enter passphrase for /dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d: ***
<filename>/</filename>, add the following to
<filename>configuration.nix</filename>:
<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";
</programlisting>
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>:
<programlisting>
<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>
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>
<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>
</para>
</section>

View File

@ -19,7 +19,7 @@
All users that should have permission to change network settings must belong
to the <code>networkmanager</code> group:
<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>
</para>

View File

@ -20,7 +20,7 @@
follows:
<!-- FIXME: this might not work if the user is unmanaged. -->
<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..." ];
</programlisting>
</para>

View File

@ -11,11 +11,11 @@
that a user account named <literal>alice</literal> shall exist:
<programlisting>
<xref linkend="opt-users.users"/>.alice = {
<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__.description">description</link> = "Alice Foobar";
<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_.isNormalUser">isNormalUser</link> = true;
<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_.extraGroups">extraGroups</link> = [ "wheel" "networkmanager" ];
<link linkend="opt-users.users._name_.openssh.authorizedKeys.keys">openssh.authorizedKeys.keys</link> = [ "ssh-dss AAAAB3Nza... alice@foobar" ];
};
</programlisting>
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
groups, such as useradd, are no longer available. Passwords may still be
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
sha-512</command> after installing the <literal>mkpasswd</literal> package.
</para>

View File

@ -385,17 +385,6 @@
</para>
</listitem>
</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>
<term>
<varname>types.nullOr</varname> <replaceable>t</replaceable>

View File

@ -78,7 +78,7 @@
<literal>mutableUsers = false</literal>. Another way is to temporarily add
the following to your configuration:
<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>
<emphasis>Important:</emphasis> delete the $hostname.qcow2 file if you have
started the virtual machine at least once without the right users, otherwise

View File

@ -211,7 +211,7 @@ nixpkgs https://nixos.org/channels/nixpkgs-unstable</screen>
use <literal>sudo</literal>)
</para>
<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>
</listitem>
<listitem>

View File

@ -550,7 +550,7 @@ Retype new UNIX password: ***</screen>
# Note: setting fileSystems is generally not
# necessary, since nixos-generate-config figures them out
# 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.
services.sshd.enable = true;

View File

@ -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
because it permitted root auto-login you can override the lightdm-autologin pam module like:
<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 required pam_succeed_if.so quiet
auth required pam_permit.so

View File

@ -233,6 +233,11 @@ GRANT ALL PRIVILEGES ON *.* TO 'mysql'@'localhost' WITH GRANT OPTION;
<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.
</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>
</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.
</para>
</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>
</section>
@ -992,6 +1012,53 @@ services.transmission.settings.rpc-bind-address = "0.0.0.0";
the previous behaviour using <literal>undervolt.useTimer</literal>.
</para>
</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>
</section>
</section>

View File

@ -20,7 +20,7 @@
<title>Configuration Options</title>
<variablelist xml:id="configuration-variable-list">
<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, '*', '_'), '&lt;', '_'), '>', '_'), '?', '_'))" />
<xsl:variable name="id" select="concat('opt-', str:replace(str:replace(str:replace(attr[@name = 'name']/string/@value, '*', '_'), '&lt;', '_'), '>', '_'))" />
<varlistentry>
<term xlink:href="#{$id}">
<xsl:attribute name="xml:id"><xsl:value-of select="$id"/></xsl:attribute>

View File

@ -1,14 +1,19 @@
#! /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 atexit
import base64
import io
import itertools
import logging
import codecs
import os
import pathlib
import ptpython.repl
import pty
import queue
import re
import shlex
import shutil
@ -16,12 +21,9 @@ import socket
import subprocess
import sys
import tempfile
import _thread
import time
from contextlib import contextmanager
from typing import Any, Callable, Dict, Iterator, List, Optional, Tuple
import ptpython.repl
import traceback
import unicodedata
CHAR_TO_KEY = {
"A": "shift-a",
@ -86,24 +88,13 @@ CHAR_TO_KEY = {
")": "shift-0x0B",
}
# Forward reference
# Forward references
log: "Logger"
machines: "List[Machine]"
logging.basicConfig(format="%(message)s")
logger = logging.getLogger("test-driver")
logger.setLevel(logging.INFO)
machine_colours_iter = (
"\x1b[{}m".format(x) for x in itertools.cycle(reversed(range(31, 37)))
)
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 eprint(*args: object, **kwargs: Any) -> None:
print(*args, file=sys.stderr, **kwargs)
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]:
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(
prefix="nixos-test-vde-", suffix="-vde{}.ctl".format(vlan_nr)
)
@ -150,6 +142,70 @@ def retry(fn: Callable) -> None:
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:
def __init__(self, args: Dict[str, Any]) -> None:
if "name" in args:
@ -179,11 +235,8 @@ class Machine:
self.pid: Optional[int] = None
self.socket = None
self.monitor: Optional[socket.socket] = None
self.logger: Logger = args["log"]
self.allow_reboot = args.get("allowReboot", False)
self.logger = MachineLogAdapter(
logger,
extra=dict(machine=self.name, colour_code=next(machine_colours_iter)),
)
@staticmethod
def create_startcommand(args: Dict[str, str]) -> str:
@ -239,6 +292,14 @@ class Machine:
def is_up(self) -> bool:
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:
assert self.monitor is not None
answer = ""
@ -253,7 +314,7 @@ class Machine:
def send_monitor_command(self, command: str) -> str:
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
self.monitor.send(message)
return self.wait_for_monitor_prompt()
@ -320,19 +381,16 @@ class Machine:
return self.execute("systemctl {}".format(q))
def require_unit_state(self, unit: str, require_state: str = "active") -> None:
self.logger.info(
f"checking if unit {unit} has reached state '{require_state}'"
)
info = self.get_unit_info(unit)
state = info["ActiveState"]
if state != require_state:
raise Exception(
"Expected unit {} to to be in state ".format(unit)
+ "'{}' but it is in state {}".format(require_state, state)
)
def log(self, message: str) -> None:
self.logger.info(message)
with self.nested(
"checking if unit {} has reached state '{}'".format(unit, require_state)
):
info = self.get_unit_info(unit)
state = info["ActiveState"]
if state != require_state:
raise Exception(
"Expected unit {} to to be in state ".format(unit)
+ "'{}' but it is in state {}".format(require_state, state)
)
def execute(self, command: str) -> Tuple[int, str]:
self.connect()
@ -356,25 +414,27 @@ class Machine:
"""Execute each command and check that it succeeds."""
output = ""
for command in commands:
self.logger.info(f"must succeed: {command}")
(status, out) = self.execute(command)
if status != 0:
self.logger.info(f"output: {out}")
raise Exception(
"command `{}` failed (exit code {})".format(command, status)
)
output += out
with self.nested("must succeed: {}".format(command)):
(status, out) = self.execute(command)
if status != 0:
self.log("output: {}".format(out))
raise Exception(
"command `{}` failed (exit code {})".format(command, status)
)
output += out
return output
def fail(self, *commands: str) -> str:
"""Execute each command and check that it fails."""
output = ""
for command in commands:
self.logger.info(f"must fail: {command}")
(status, out) = self.execute(command)
if status == 0:
raise Exception("command `{}` unexpectedly succeeded".format(command))
output += out
with self.nested("must fail: {}".format(command)):
(status, out) = self.execute(command)
if status == 0:
raise Exception(
"command `{}` unexpectedly succeeded".format(command)
)
output += out
return output
def wait_until_succeeds(self, command: str) -> str:
@ -388,9 +448,9 @@ class Machine:
status, output = self.execute(command)
return status == 0
self.logger.info(f"waiting for success: {command}")
retry(check_success)
return output
with self.nested("waiting for success: {}".format(command)):
retry(check_success)
return output
def wait_until_fails(self, command: str) -> str:
"""Wait until a command returns failure.
@ -403,21 +463,21 @@ class Machine:
status, output = self.execute(command)
return status != 0
self.logger.info(f"waiting for failure: {command}")
retry(check_failure)
return output
with self.nested("waiting for failure: {}".format(command)):
retry(check_failure)
return output
def wait_for_shutdown(self) -> None:
if not self.booted:
return
self.logger.info("waiting for the VM to power off")
sys.stdout.flush()
self.process.wait()
with self.nested("waiting for the VM to power off"):
sys.stdout.flush()
self.process.wait()
self.pid = None
self.booted = False
self.connected = False
self.pid = None
self.booted = False
self.connected = False
def get_tty_text(self, tty: str) -> str:
status, output = self.execute(
@ -435,19 +495,19 @@ class Machine:
def tty_matches(last: bool) -> bool:
text = self.get_tty_text(tty)
if last:
self.logger.info(
self.log(
f"Last chance to match /{regexp}/ on TTY{tty}, "
f"which currently contains: {text}"
)
return len(matcher.findall(text)) > 0
self.logger.info(f"waiting for {regexp} to appear on tty {tty}")
retry(tty_matches)
with self.nested("waiting for {} to appear on tty {}".format(regexp, tty)):
retry(tty_matches)
def send_chars(self, chars: List[str]) -> None:
self.logger.info(f"sending keys {chars}")
for char in chars:
self.send_key(char)
with self.nested("sending keys {}".format(chars)):
for char in chars:
self.send_key(char)
def wait_for_file(self, filename: str) -> None:
"""Waits until the file exists in machine's file system."""
@ -456,16 +516,16 @@ class Machine:
status, _ = self.execute("test -e {}".format(filename))
return status == 0
self.logger.info(f"waiting for file {filename}")
retry(check_file)
with self.nested("waiting for file {}".format(filename)):
retry(check_file)
def wait_for_open_port(self, port: int) -> None:
def port_is_open(_: Any) -> bool:
status, _ = self.execute("nc -z localhost {}".format(port))
return status == 0
self.logger.info(f"waiting for TCP port {port}")
retry(port_is_open)
with self.nested("waiting for TCP port {}".format(port)):
retry(port_is_open)
def wait_for_closed_port(self, port: int) -> None:
def port_is_closed(_: Any) -> bool:
@ -487,17 +547,17 @@ class Machine:
if self.connected:
return
self.logger.info("waiting for the VM to finish booting")
self.start()
with self.nested("waiting for the VM to finish booting"):
self.start()
tic = time.time()
self.shell.recv(1024)
# TODO: Timeout
toc = time.time()
tic = time.time()
self.shell.recv(1024)
# TODO: Timeout
toc = time.time()
self.logger.info("connected to guest root shell")
self.logger.info(f"(connecting took {toc - tic:.2f} seconds)")
self.connected = True
self.log("connected to guest root shell")
self.log("(connecting took {:.2f} seconds)".format(toc - tic))
self.connected = True
def screenshot(self, filename: str) -> None:
out_dir = os.environ.get("out", os.getcwd())
@ -506,12 +566,15 @@ class Machine:
filename = os.path.join(out_dir, "{}.png".format(filename))
tmp = "{}.ppm".format(filename)
self.logger.info(f"making screenshot {filename}")
self.send_monitor_command("screendump {}".format(tmp))
ret = subprocess.run("pnmtopng {} > {}".format(tmp, filename), shell=True)
os.unlink(tmp)
if ret.returncode != 0:
raise Exception("Cannot convert screenshot")
with self.nested(
"making screenshot {}".format(filename),
{"image": os.path.basename(filename)},
):
self.send_monitor_command("screendump {}".format(tmp))
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:
"""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"
self.logger.info("performing optical character recognition")
with tempfile.NamedTemporaryFile() as tmpin:
self.send_monitor_command("screendump {}".format(tmpin.name))
with self.nested("performing optical character recognition"):
with tempfile.NamedTemporaryFile() as tmpin:
self.send_monitor_command("screendump {}".format(tmpin.name))
cmd = "convert {} {} tiff:- | tesseract - - {}".format(
magick_args, tmpin.name, tess_args
)
ret = subprocess.run(cmd, shell=True, capture_output=True)
if ret.returncode != 0:
raise Exception("OCR failed with exit code {}".format(ret.returncode))
cmd = "convert {} {} tiff:- | tesseract - - {}".format(
magick_args, tmpin.name, tess_args
)
ret = subprocess.run(cmd, shell=True, capture_output=True)
if ret.returncode != 0:
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 screen_matches(last: bool) -> bool:
@ -606,15 +671,15 @@ class Machine:
matches = re.search(regex, text) is not None
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
self.logger.info(f"waiting for {regex} to appear on screen")
retry(screen_matches)
with self.nested("waiting for {} to appear on screen".format(regex)):
retry(screen_matches)
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
# to match multiline regexes.
console = io.StringIO()
@ -637,7 +702,7 @@ class Machine:
if self.booted:
return
self.logger.info("starting vm")
self.log("starting vm")
def create_socket(path: str) -> socket.socket:
if os.path.exists(path):
@ -694,7 +759,7 @@ class Machine:
# Store last serial console lines for use
# of wait_for_console_text
self.last_lines: queue.Queue = queue.Queue()
self.last_lines: Queue = Queue()
def process_serial_output() -> None:
assert self.process.stdout is not None
@ -702,7 +767,8 @@ class Machine:
# Ignore undecodable bytes that may occur in boot menus
line = _line.decode(errors="ignore").replace("\r", "").rstrip()
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, ())
@ -711,10 +777,10 @@ class Machine:
self.pid = self.process.pid
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:
self.logger.info("delete the VM state directory")
self.log("delete the VM state directory")
if os.path.isfile(self.state_dir):
shutil.rmtree(self.state_dir)
@ -729,7 +795,7 @@ class Machine:
if not self.booted:
return
self.logger.info("forced crash")
self.log("forced crash")
self.send_monitor_command("quit")
self.wait_for_shutdown()
@ -749,8 +815,8 @@ class Machine:
status, _ = self.execute("[ -e /tmp/.X11-unix/X0 ]")
return status == 0
self.logger.info("waiting for the X11 server")
retry(check_x)
with self.nested("waiting for the X11 server"):
retry(check_x)
def get_window_names(self) -> List[str]:
return self.succeed(
@ -763,17 +829,19 @@ class Machine:
def window_is_visible(last_try: bool) -> bool:
names = self.get_window_names()
if last_try:
self.logger.info(
f"Last chance to match {regexp} on the window list, "
+ f"which currently contains: {', '.join(names)}"
self.log(
"Last chance to match {} on the window list,".format(regexp)
+ " which currently contains: "
+ ", ".join(names)
)
return any(pattern.search(name) for name in names)
self.logger.info("Waiting for a window to appear")
retry(window_is_visible)
with self.nested("Waiting for a window to appear"):
retry(window_is_visible)
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:
"""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:
global log
args["log"] = log
args["redirectSerial"] = os.environ.get("USE_SERIAL", "0") == "1"
return Machine(args)
def start_all() -> None:
global machines
logger.info("starting all VMs")
for machine in machines:
machine.start()
with log.nested("starting all VMs"):
for machine in machines:
machine.start()
def join_all() -> None:
global machines
logger.info("waiting for all VMs to finish")
for machine in machines:
machine.wait_for_shutdown()
with log.nested("waiting for all VMs to finish"):
for machine in machines:
machine.wait_for_shutdown()
def test_script() -> None:
@ -824,12 +893,13 @@ def run_tests() -> None:
global machines
tests = os.environ.get("tests", None)
if tests is not None:
logger.info("running the VM test script")
try:
exec(tests, globals())
except Exception:
logging.exception("error:")
sys.exit(1)
with log.nested("running the VM test script"):
try:
exec(tests, globals())
except Exception as e:
eprint("error: ")
traceback.print_exc()
sys.exit(1)
else:
ptpython.repl.embed(locals(), globals())
@ -842,19 +912,18 @@ def run_tests() -> None:
@contextmanager
def subtest(name: str) -> Iterator[None]:
logger.info(name)
try:
yield
return True
except Exception as e:
logger.info(f'Test "{name}" failed with error: "{e}"')
raise e
with log.nested(name):
try:
yield
return True
except Exception as e:
log.log(f'Test "{name}" failed with error: "{e}"')
raise e
return False
def main() -> None:
global machines
if __name__ == "__main__":
arg_parser = argparse.ArgumentParser()
arg_parser.add_argument(
"-K",
@ -864,6 +933,8 @@ def main() -> None:
)
(cli_args, vm_scripts) = arg_parser.parse_known_args()
log = Logger()
vlan_nrs = list(dict.fromkeys(os.environ.get("VLANS", "").split()))
vde_sockets = [create_vlan(v) for v in vlan_nrs]
for nr, vde_socket, _, _ in vde_sockets:
@ -874,27 +945,23 @@ def main() -> None:
if not cli_args.keep_vm_state:
machine.cleanup_statedir()
machine_eval = [
"global {0}; {0} = machines[{1}]".format(m.name, idx)
for idx, m in enumerate(machines)
"{0} = machines[{1}]".format(m.name, idx) for idx, m in enumerate(machines)
]
exec("\n".join(machine_eval))
@atexit.register
def clean_up() -> None:
logger.info("cleaning up")
for machine in machines:
if machine.pid is None:
continue
logger.info(f"killing {machine.name} (pid {machine.pid})")
machine.process.kill()
for _, _, process, _ in vde_sockets:
process.terminate()
with log.nested("cleaning up"):
for machine in machines:
if machine.pid is None:
continue
log.log("killing {} (pid {})".format(machine.name, machine.pid))
machine.process.kill()
for _, _, process, _ in vde_sockets:
process.terminate()
log.close()
tic = time.time()
run_tests()
toc = time.time()
print("test script finished in {:.2f}s".format(toc - tic))
if __name__ == "__main__":
main()

View File

@ -62,7 +62,7 @@ rec {
''
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
mkdir -p $out/coverage-data

View File

@ -41,31 +41,30 @@ let
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"
else if (value == false) then "false"
else if (isInt value) then (toString value)
else if (isList value) then
concatMapStringsSep " " mkVal { inherit value depth; }
else if (isAttrs value) then
(concatStringsSep "\n${mkIndent (depth + 1)}"
([ "{" ] ++ (mapAttrsToList
(attrName: attrValue: let
mappedAttrValue = mkVal {
value = attrValue;
depth = depth + 1;
};
in "${attrName} = ${mappedAttrValue}")
value))) + "\n${mkIndent depth}}"
let configLines = concatLists
(map (splitString "\n")
(mapAttrsToList mkRelation value));
in
(concatStringsSep "\n${indent}"
([ "{" ] ++ configLines))
+ "\n}"
else value;
mkMappedAttrsOrString = value: concatMapStringsSep "\n"
(line: if builtins.stringLength line > 0
then "${mkIndent 1}${line}"
then "${indent}${line}"
else line)
(splitString "\n"
(if isAttrs value then
@ -114,7 +113,10 @@ in {
{
"ATHENA.MIT.EDU" = {
admin_server = "athena.mit.edu";
kdc = "athena.mit.edu";
kdc = [
"athena01.mit.edu"
"athena02.mit.edu"
];
};
};
'';

View File

@ -463,7 +463,7 @@ in {
users.users = mkOption {
default = {};
type = with types; loaOf (submodule userOpts);
type = with types; attrsOf (submodule userOpts);
example = {
alice = {
uid = 1234;
@ -487,7 +487,7 @@ in {
{ students.gid = 1001;
hackers = { };
};
type = with types; loaOf (submodule groupOpts);
type = with types; attrsOf (submodule groupOpts);
description = ''
Additional groups to be created automatically by the system.
'';

View File

@ -27,7 +27,7 @@
};
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";
neededForBoot = true;
};

View File

@ -224,7 +224,7 @@ bool optionTypeIs(Context & ctx, Value & v, const std::string & soughtType)
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);

View File

@ -288,7 +288,10 @@ fi
if [ "$action" = edit ]; then
if [[ -z $flake ]]; then
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
exec nix edit "${lockFlags[@]}" -- "$flake#$flakeAttr"
fi

View File

@ -262,6 +262,7 @@
./services/continuous-integration/buildbot/worker.nix
./services/continuous-integration/buildkite-agents.nix
./services/continuous-integration/hail.nix
./services/continuous-integration/hercules-ci-agent/default.nix
./services/continuous-integration/hydra/default.nix
./services/continuous-integration/gitlab-runner.nix
./services/continuous-integration/gocd-agent/default.nix
@ -296,7 +297,6 @@
./services/desktops/accountsservice.nix
./services/desktops/bamf.nix
./services/desktops/blueman.nix
./services/desktops/deepin/deepin.nix
./services/desktops/dleyna-renderer.nix
./services/desktops/dleyna-server.nix
./services/desktops/pantheon/files.nix
@ -587,6 +587,7 @@
./services/networking/atftpd.nix
./services/networking/avahi-daemon.nix
./services/networking/babeld.nix
./services/networking/biboumi.nix
./services/networking/bind.nix
./services/networking/bitcoind.nix
./services/networking/autossh.nix
@ -718,6 +719,7 @@
./services/networking/rdnssd.nix
./services/networking/redsocks.nix
./services/networking/resilio.nix
./services/networking/robustirc-bridge.nix
./services/networking/rpcbind.nix
./services/networking/rxe.nix
./services/networking/sabnzbd.nix

View File

@ -33,7 +33,6 @@ in
{ PATH = [ "/bin" ];
INFOPATH = [ "/info" "/share/info" ];
KDEDIRS = [ "" ];
STRIGI_PLUGIN_PATH = [ "/lib/strigi/" ];
QT_PLUGIN_PATH = [ "/lib/qt4/plugins" "/lib/kde4/plugins" ];
QTWEBKIT_PLUGIN_PATH = [ "/lib/mozilla/plugins/" ];
GTK_PATH = [ "/lib/gtk-2.0" "/lib/gtk-3.0" ];

View File

@ -30,5 +30,7 @@ with lib;
environment.systemPackages = [ pkgs.gnome3.gpaste ];
services.dbus.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 ];
};
}

View File

@ -131,7 +131,7 @@ in
knownHosts = mkOption {
default = {};
type = types.loaOf (types.submodule ({ name, ... }: {
type = types.attrsOf (types.submodule ({ name, ... }: {
options = {
certAuthority = mkOption {
type = types.bool;

View File

@ -7,7 +7,7 @@ let
inherit (lib.modules) mkDefault mkIf;
inherit (lib.options) literalExample mkEnableOption mkOption;
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
# elements when compared without considering case.
@ -178,7 +178,7 @@ let
client system-options file "dsm.sys"
'';
servers = mkOption {
type = loaOf (submodule [ serverOptions ]);
type = attrsOf (submodule [ serverOptions ]);
default = {};
example.mainTsmServer = {
server = "tsmserver.company.com";

View File

@ -73,7 +73,7 @@
<programlisting>
{ pkgs, ... }:
{
programs.zsh.ohMyZsh.customPkgs = with pkgs; [
programs.zsh.ohMyZsh.customPkgs = [
pkgs.nix-zsh-completions
# and even more...
];

View File

@ -19,6 +19,7 @@ with lib;
# Completely removed modules
(mkRemovedOptionModule [ "fonts" "fontconfig" "penultimate" ] "The corresponding package has 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" "group" ] "")
(mkRemovedOptionModule [ "services" "marathon" ] "The corresponding package was removed from nixpkgs.")

View File

@ -544,7 +544,7 @@ in
security.pam.services = mkOption {
default = [];
type = with types; loaOf (submodule pamOpts);
type = with types; attrsOf (submodule pamOpts);
description =
''
This option defines the PAM services. A service typically

View File

@ -220,7 +220,7 @@ let
};
destinations = mkOption {
type = loaOf (destType config);
type = attrsOf (destType config);
description = "Additional destinations.";
default = {};
example = literalExample ''
@ -328,7 +328,7 @@ in
};
zetup = mkOption {
type = loaOf srcType;
type = attrsOf srcType;
description = "Znapzend configuration.";
default = {};
example = literalExample ''

View File

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

View File

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

View File

@ -11,23 +11,23 @@ let
then cfg.package
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.
configFile = pkgs.writeText "postgresql.conf"
''
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}
'';
configFile = pkgs.writeText "postgresql.conf" (concatStringsSep "\n" (mapAttrsToList (n: v: "${n} = ${toStr v}") cfg.settings));
groupAccessAvailable = versionAtLeast postgresql.version "11.0";
in
{
imports = [
(mkRemovedOptionModule [ "services" "postgresql" "extraConfig" ] "Use services.postgresql.settings instead.")
];
###### interface
@ -212,10 +212,28 @@ in
'';
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = "Additional text to be appended to <filename>postgresql.conf</filename>.";
settings = mkOption {
type = with types; attrsOf (oneOf [ bool float int str ]);
default = {};
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 {
@ -245,6 +263,16 @@ in
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 =
# Note: when changing the default, make it conditional on
# system.stateVersion to maintain compatibility with existing

View File

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

View File

@ -160,7 +160,7 @@ in
};
appConfig = mkOption {
type = types.loaOf appConfigModule;
type = types.attrsOf appConfigModule;
default = {};
example = literalExample ''
"com.github.app" = {

View File

@ -81,7 +81,7 @@ in
{ office1 = { model = "MFC-7860DW"; ip = "192.168.1.2"; };
office2 = { model = "MFC-7860DW"; nodename = "BRW0080927AFBCE"; };
};
type = with types; loaOf (submodule netDeviceOpts);
type = with types; attrsOf (submodule netDeviceOpts);
description = ''
The list of network devices that will be registered against the brscan4
sane backend.

View File

@ -28,6 +28,12 @@ in
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 {
networking.firewall = mkIf cfg.openFirewall {
allowedTCPPorts = [ cfg.listen.port ];
};
environment.systemPackages = [ pkg ];
systemd.services.beanstalkd = {

View File

@ -500,13 +500,6 @@ in
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.binaryCaches = [ "https://cache.nixos.org/" ];
@ -594,16 +587,10 @@ in
nix.systemFeatures = mkDefault (
[ "nixos-test" "benchmark" "big-parallel" "kvm" ] ++
optionals (pkgs.stdenv.isx86_64 && pkgs.hostPlatform.platform ? gcc.arch) (
# a x86_64 builder can run code for `platform.gcc.arch` and minor architectures:
[ "gccarch-${pkgs.hostPlatform.platform.gcc.arch}" ] ++ {
sandybridge = [ "gccarch-westmere" ];
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 []
optionals (pkgs.hostPlatform.platform ? gcc.arch) (
# a builder can run code for `platform.gcc.arch` and inferior architectures
[ "gccarch-${pkgs.hostPlatform.platform.gcc.arch}" ] ++
map (x: "gccarch-${x}") lib.systems.architectures.inferiors.${pkgs.hostPlatform.platform.gcc.arch}
)
);

View File

@ -1,12 +1,12 @@
{ config, lib, pkgs, ... }:
let
inherit (lib) mkDefault mkEnableOption mkIf mkOption types;
inherit (lib) mkBefore mkDefault mkEnableOption mkIf mkOption mkRemovedOptionModule types;
inherit (lib) concatStringsSep literalExample mapAttrsToList;
inherit (lib) optional optionalAttrs optionalString singleton versionAtLeast;
inherit (lib) optional optionalAttrs optionalString;
cfg = config.services.redmine;
format = pkgs.formats.yaml {};
bundle = "${cfg.package}/share/redmine/bin/bundle";
databaseYml = pkgs.writeText "database.yml" ''
@ -20,24 +20,8 @@ let
${optionalString (cfg.database.type == "mysql2" && cfg.database.socket != null) "socket: ${cfg.database.socket}"}
'';
configurationYml = pkgs.writeText "configuration.yml" ''
default:
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}
'';
configurationYml = format.generate "configuration.yml" cfg.settings;
additionalEnvironment = pkgs.writeText "additional_environment.rb" cfg.extraEnv;
unpackTheme = unpack "theme";
unpackPlugin = unpack "plugin";
@ -56,8 +40,13 @@ let
pgsqlLocal = cfg.database.createLocally && cfg.database.type == "postgresql";
in
{
imports = [
(mkRemovedOptionModule [ "services" "redmine" "extraConfig" ] "Use services.redmine.settings instead.")
(mkRemovedOptionModule [ "services" "redmine" "database" "password" ] "Use services.redmine.database.passwordFile instead.")
];
# interface
options = {
services.redmine = {
enable = mkEnableOption "Redmine";
@ -93,21 +82,24 @@ in
description = "The state directory, logs and plugins are stored here.";
};
extraConfig = mkOption {
type = types.lines;
default = "";
settings = mkOption {
type = format.type;
default = {};
description = ''
Extra configuration in configuration.yml.
See <link xlink:href="https://guides.rubyonrails.org/action_mailer_basics.html#action-mailer-configuration"/>
Redmine configuration (<filename>configuration.yml</filename>). Refer to
<link xlink:href="https://guides.rubyonrails.org/action_mailer_basics.html#action-mailer-configuration"/>
for details.
'';
example = literalExample ''
email_delivery:
delivery_method: smtp
smtp_settings:
address: mail.example.com
port: 25
{
email_delivery = {
delivery_method = "smtp";
smtp_settings = {
address = "mail.example.com";
port = 25;
};
};
}
'';
};
@ -186,16 +178,6 @@ in
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 {
type = types.nullOr types.path;
default = null;
@ -226,11 +208,12 @@ in
};
};
# implementation
config = mkIf cfg.enable {
assertions = [
{ assertion = cfg.database.passwordFile != null || cfg.database.password != "" || cfg.database.socket != null;
message = "one of services.redmine.database.socket, services.redmine.database.passwordFile, or services.redmine.database.password must be set";
{ assertion = cfg.database.passwordFile != null || cfg.database.socket != null;
message = "one of services.redmine.database.socket or services.redmine.database.passwordFile must be set";
}
{ 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";
@ -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 {
enable = true;
package = mkDefault pkgs.mariadb;
@ -338,7 +337,7 @@ in
# 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"
sed -e "s,#dbpass#,$DBPASS,g" -i "${cfg.stateDir}/config/database.yml"
chmod 440 "${cfg.stateDir}/config/database.yml"
@ -379,17 +378,6 @@ in
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;
})));
};
}

View 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 XMPPgateway.
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 Botans 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 ];
}

View File

@ -3,7 +3,7 @@
let
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;
commonDescr = ''
@ -248,7 +248,7 @@ in
};
modems = mkOption {
type = loaOf (submodule [ modemConfigOptions ]);
type = attrsOf (submodule [ modemConfigOptions ]);
default = {};
example.ttyS1 = {
type = "cirrus";

View File

@ -458,7 +458,7 @@ in {
systemd.services.NetworkManager-dispatcher = {
wantedBy = [ "network.target" ];
restartTriggers = [ configFile ];
restartTriggers = [ configFile overrideNameserversScript ];
# useful binaries for user-specified hooks
path = [ pkgs.iproute pkgs.utillinux pkgs.coreutils ];

View File

@ -140,7 +140,7 @@ in
services.nylon = mkOption {
default = {};
description = "Collection of named nylon instances";
type = with types; loaOf (submodule nylonOpts);
type = with types; attrsOf (submodule nylonOpts);
internal = true;
};

View File

@ -655,7 +655,7 @@ in
description = "Define the virtual hosts";
type = with types; loaOf (submodule vHostOpts);
type = with types; attrsOf (submodule vHostOpts);
example = {
myhost = {

View File

@ -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.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._name__.enabled">enabled</link> = true;
<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.key">ssl.key</link> = "/var/lib/acme/example.org/key.pem";
<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_.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.muc">muc</link> = [ {
<link linkend="opt-services.prosody.muc">domain</link> = "conference.example.org";

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

View File

@ -361,7 +361,7 @@ in
};
users.users = mkOption {
type = with types; loaOf (submodule userOptions);
type = with types; attrsOf (submodule userOptions);
};
};

View File

@ -34,8 +34,8 @@ let
User tor
DataDirectory ${torDirectory}
${optionalString cfg.enableGeoIP ''
GeoIPFile ${pkgs.tor.geoip}/share/tor/geoip
GeoIPv6File ${pkgs.tor.geoip}/share/tor/geoip6
GeoIPFile ${cfg.package.geoip}/share/tor/geoip
GeoIPv6File ${cfg.package.geoip}/share/tor/geoip6
''}
${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 {
type = types.bool;
default = true;
@ -597,7 +607,7 @@ in
];
}
'';
type = types.loaOf (types.submodule ({name, ...}: {
type = types.attrsOf (types.submodule ({name, ...}: {
options = {
name = mkOption {
@ -749,8 +759,8 @@ in
serviceConfig =
{ Type = "simple";
# Translated from the upstream contrib/dist/tor.service.in
ExecStartPre = "${pkgs.tor}/bin/tor -f ${torRcFile} --verify-config";
ExecStart = "${pkgs.tor}/bin/tor -f ${torRcFile}";
ExecStartPre = "${cfg.package}/bin/tor -f ${torRcFile} --verify-config";
ExecStart = "${cfg.package}/bin/tor -f ${torRcFile}";
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
KillSignal = "SIGINT";
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) {
enable = true;

View File

@ -516,7 +516,7 @@ in
<filename>/dev/mapper/<replaceable>name</replaceable></filename>.
'';
type = with types; loaOf (submodule (
type = with types; attrsOf (submodule (
{ name, ... }: { options = {
name = mkOption {

View File

@ -121,12 +121,13 @@ let
copy_bin_and_libs ${pkgs.mdadm}/sbin/mdmon
# 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}/lib/systemd/systemd-sysctl
for BIN in ${udev}/lib/udev/*_id; do
copy_bin_and_libs $BIN
done
# systemd-udevd is only a symlink to udevadm these days
ln -sf udevadm $out/bin/systemd-udevd
# Copy modprobe.
copy_bin_and_libs ${pkgs.kmod}/bin/kmod
@ -557,7 +558,7 @@ in
};
fileSystems = mkOption {
type = with lib.types; loaOf (submodule {
type = with lib.types; attrsOf (submodule {
options.neededForBoot = mkOption {
default = false;
type = types.bool;

View File

@ -234,7 +234,6 @@ in rec {
path = mkOption {
default = [];
type = with types; listOf (oneOf [ package str ]);
apply = ps: "${makeBinPath ps}:${makeSearchPathOutput "bin" "sbin" ps}";
description = ''
Packages added to the service's <envar>PATH</envar>
environment variable. Both the <filename>bin</filename>

View File

@ -257,7 +257,7 @@ let
pkgs.gnused
systemd
];
environment.PATH = config.path;
environment.PATH = "${makeBinPath config.path}:${makeSearchPathOutput "bin" "sbin" config.path}";
}
(mkIf (config.preStart != "")
{ serviceConfig.ExecStartPre =
@ -903,11 +903,9 @@ in
)
]);
passwd = (mkMerge [
[ "mymachines" ]
(mkAfter [ "systemd" ])
]);
group = (mkMerge [
[ "mymachines" ]
(mkAfter [ "systemd" ])
]);
};
@ -1008,7 +1006,7 @@ in
"sysctl.d/50-coredump.conf".source = "${systemd}/example/sysctl.d/50-coredump.conf";
"sysctl.d/50-default.conf".source = "${systemd}/example/sysctl.d/50-default.conf";
"tmpfiles.d".source = pkgs.symlinkJoin {
"tmpfiles.d".source = (pkgs.symlinkJoin {
name = "tmpfiles.d";
paths = map (p: p + "/lib/tmpfiles.d") cfg.tmpfiles.packages;
postBuild = ''
@ -1018,8 +1016,10 @@ in
exit 1
)
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-shutdown" = { source = hooks "shutdown" cfg.shutdown; };

View File

@ -46,7 +46,7 @@ in
Set of files that have to be linked in <filename>/etc</filename>.
'';
type = with types; loaOf (submodule (
type = with types; attrsOf (submodule (
{ name, config, ... }:
{ options = {

View File

@ -54,7 +54,7 @@ in
options = {
fileSystems = mkOption {
type = with lib.types; loaOf (submodule encryptedFSOptions);
type = with lib.types; attrsOf (submodule encryptedFSOptions);
};
swapDevices = mkOption {
type = with lib.types; listOf (submodule encryptedFSOptions);

View File

@ -159,7 +159,7 @@ in
"/bigdisk".label = "bigdisk";
}
'';
type = types.loaOf (types.submodule [coreFileSystemOpts fileSystemOpts]);
type = types.attrsOf (types.submodule [coreFileSystemOpts fileSystemOpts]);
description = ''
The file systems to be mounted. It must include an entry for
the root directory (<literal>mountPoint = "/"</literal>). Each
@ -193,7 +193,7 @@ in
boot.specialFileSystems = mkOption {
default = {};
type = types.loaOf (types.submodule coreFileSystemOpts);
type = types.attrsOf (types.submodule coreFileSystemOpts);
internal = true;
description = ''
Special filesystems that are mounted very early during boot.

View File

@ -519,7 +519,7 @@ in
<option>networking.useDHCP</option> is true, then every
interface not listed here will be configured using DHCP.
'';
type = with types; loaOf (submodule interfaceOpts);
type = with types; attrsOf (submodule interfaceOpts);
};
networking.vswitches = mkOption {
@ -544,7 +544,7 @@ in
interfaces = mkOption {
example = [ "eth0" "eth1" ];
description = "The physical network interfaces connected by the vSwitch.";
type = with types; loaOf (submodule vswitchInterfaceOpts);
type = with types; attrsOf (submodule vswitchInterfaceOpts);
};
controllers = mkOption {

View File

@ -43,6 +43,12 @@ in
'';
};
ociSeccompBpfHook.enable = mkOption {
type = types.bool;
default = false;
description = "Enable the OCI seccomp BPF hook";
};
containersConf = mkOption {
default = {};
description = "containers.conf configuration";
@ -116,6 +122,12 @@ in
[network]
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;
environment.etc."containers/registries.conf".source = toTOML "registries.conf" {

View File

@ -101,6 +101,7 @@ in
log_level = "${cfg.logLevel}"
manage_ns_lifecycle = true
pinns_path = "${cfg.package}/bin/pinns"
hooks_dir = []
${optionalString (cfg.runtime != null) ''
default_runtime = "${cfg.runtime}"

View File

@ -627,7 +627,7 @@ in
};
bindMounts = mkOption {
type = with types; loaOf (submodule bindMountOpts);
type = with types; attrsOf (submodule bindMountOpts);
default = {};
example = literalExample ''
{ "/home" = { hostPath = "/home/alice";

View File

@ -41,7 +41,7 @@ let
description = "Source for the in-container mount";
};
options = mkOption {
type = loaOf (str);
type = attrsOf (str);
default = [ "bind" ];
description = ''
Mount options of the filesystem to be used.
@ -61,7 +61,7 @@ in
containers = mkOption {
default = {};
description = "Declarative container configuration";
type = with types; loaOf (submodule ({ name, config, ... }: {
type = with types; attrsOf (submodule ({ name, config, ... }: {
options = {
cmd = mkOption {
type = types.lines;

View File

@ -121,7 +121,8 @@ in rec {
(onFullSupported "nixos.tests.networking.networkd.dhcpSimple")
(onFullSupported "nixos.tests.networking.networkd.link")
(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.routes")
(onFullSupported "nixos.tests.networking.networkd.sit")

View File

@ -298,6 +298,7 @@ in
redis = handleTest ./redis.nix {};
redmine = handleTest ./redmine.nix {};
restic = handleTest ./restic.nix {};
robustirc-bridge = handleTest ./robustirc-bridge.nix {};
roundcube = handleTest ./roundcube.nix {};
rspamd = handleTest ./rspamd.nix {};
rss2email = handleTest ./rss2email.nix {};

View File

@ -59,7 +59,8 @@ pkgs.runCommand "acme-snakeoil-ca" {
openssl genrsa -out snakeoil.key 4096
openssl req -new -key snakeoil.key -out snakeoil.csr
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.pem ${lib.escapeShellArg fqdn} cert
'') domains}

View File

@ -2,170 +2,171 @@
{
ca.key = builtins.toFile "ca.key" ''
-----BEGIN PRIVATE KEY-----
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
JUsBXFNz132nP4iIr3UKrPedQZijSi4=
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
s9o9Sr49cibZ3CbMjCSNE3AOeVE1/Q==
-----END PRIVATE KEY-----
'';
ca.cert = builtins.toFile "ca.cert" ''
-----BEGIN CERTIFICATE-----
MIIFDzCCAvegAwIBAgIUTRDYSWJvmlhwIR3pzVrIQfnboLEwDQYJKoZIhvcNAQEL
BQAwFjEUMBIGA1UEAwwLU25ha2VvaWwgQ0EwIBcNMjAwMzIyMjI1NjE3WhgPMjEy
MDAyMjcyMjU2MTdaMBYxFDASBgNVBAMMC1NuYWtlb2lsIENBMIICIjANBgkqhkiG
9w0BAQEFAAOCAg8AMIICCgKCAgEAwp1WRhJ+vHs15Q1hOYI7Aj6rrUeJ8cP8LyGw
MQdlZNlnkOhxr7diXa8+anq9iF3e+mLaUHqnfn33rWi7THhU6/l8vcqhKcdgH75h
BHC57olm7FBmc7B8Fu/+JD4ABQcvU8CZ/5PPdpUerkGGtEEt/Ql/OZCzGfy2V1Mg
pSAWviMU9TqL5hqjDq+JxgEkUD+nf558p+NSp2rf3bacmmuc4H2MAOmFulMXMsLw
UqTDlzNP/NgRWRsgC7d50Pn35q7SnLzI7DSwRWrJVfs2DtTzGy20wlvEpiU44c7m
qV7QR67r6HtuNd911pb3D9cpWk8dGpcIkFia9VxDlFixBU4Dk3kcolQ8Q7p6c/u6
BnMM3HThvJwoHesNGmGhAs9c70txWE0M/jIqphJMerOG49VPdCNJMFCW3lo46xju
2PUKuItfRmnw4O3ADJ/XhwojWzaz4+rf4H2lWwq25Jt2VY5Ly00Npm9pb+/rVYou
Odtu4jT7jUupcdhVZa/w14kazlX4IT76DsVH186ICYWS1eGZIvsnGxkGucPGDA2A
r+HNPHSgOwGrVYTUutHNc4EDY7lhdwb6HEskshlKJ1U+odQ2JSfWAKoKjaXnYDUf
ZKadN+EjIQe3Y/ZXgei0TAPnNXxv0/tZQ25APr6KXqbePt9KA3Ak2HxIn5dR8Kjc
P21w5tcCAwEAAaNTMFEwHQYDVR0OBBYEFCIoeYSYjtMiPrmxfHmcrsZkyTpvMB8G
A1UdIwQYMBaAFCIoeYSYjtMiPrmxfHmcrsZkyTpvMA8GA1UdEwEB/wQFMAMBAf8w
DQYJKoZIhvcNAQELBQADggIBAHPdwOgAxyhIhbqFObNftW8K3sptorB/Fj6jwYCm
mHleFueqQnjTHMWsflOjREvQp1M307FWooGj+KQkjwvAyDc/Hmy7WgJxBg9p3vc+
/Xf/e7ZfBl8rv7vH8VXW/BC1vVsILdFncrgTrP8/4psV50/cl1F4+nPBiekvvxwZ
k+R7SgeSvcWT7YlOG8tm1M3al4F4mWzSRkYjkrXmwRCKAiya9xcGSt0Bob+LoM/O
mpDGV/PMC1WAoDc1mMuXN2hSc0n68xMcuFs+dj/nQYn8uL5pzOxpX9560ynKyLDv
yOzQlM2VuZ7H2hSIeYOFgrtHJJwhDtzjmUNDQpQdp9Fx+LONQTS1VLCTXND2i/3F
10X6PkdnLEn09RiPt5qy20pQkICxoEydmlwpFs32musYfJPdBPkZqZWrwINBv2Wb
HfOmEB4xUvXufZ5Ju5icgggBkyNA3PCLo0GZFRrMtvA7i9IXOcXNR+njhKa9246V
QQfeWiz05RmIvgShJYVsnZWtael8ni366d+UXypBYncohimyNlAD1n+Bh3z0PvBB
+FK4JgOSeouM4SuBHdwmlZ/H0mvfUG81Y8Jbrw0yuRHtuCtX5HpN5GKpZPHDE7aQ
fEShVB/GElC3n3DvgK9OJBeVVhYQgUEfJi4rsSxt3cdEI0NrdckUoZbApWVJ3CBc
F8Y7
MIIFDzCCAvegAwIBAgIUX0P6NfX4gRUpFz+TNV/f26GHokgwDQYJKoZIhvcNAQEL
BQAwFjEUMBIGA1UEAwwLU25ha2VvaWwgQ0EwIBcNMjAwODI0MDc0MjEyWhgPMjEy
MDA3MzEwNzQyMTJaMBYxFDASBgNVBAMMC1NuYWtlb2lsIENBMIICIjANBgkqhkiG
9w0BAQEFAAOCAg8AMIICCgKCAgEA3dRuzhaVyKB5668XcPoYiVQ2Op0AwyhbfRQS
sJb+8doQr1+258rx2i+x+tXPvNDHBjyEq0J9/jI7kWbqsGsePQ3XTV2xreFqhpce
CwHiN+zoDVFM/X6Da9qww1e+OL8KdePzw9X956qVnzoM87IfK8WnNJmeUnvR8TiK
SOzUTbhyY4+x1meGMXjr4tvPa5qbtCT3KduZ48O4ehTXx7vBhqd+FI+sAMbm3Ucn
1YlfM/RTH24JS7gPYtTokstzUKavFcARvrv9Iguz0LEI8Uq2oELtubHwE2CKxSUO
GQr4dJ8aijHsjzwYunQHDKWtgGQKrar/gsFnaN+gbUuV4gu6wKYGJ/srXikB0m5w
ohtlv26Em34PZUZN8ONXREhDQgA1Woy29xKL76dLQTvwQC7nb1o8wD26V5XlTa+p
4FrRpbGUwuy1w4AanVtipc6WRnM/j1twE5cIqf2RUbewNebuXVZFj1aD7kNMNU8P
oPXcVhUzZN4ftneyvOyMUG3L6sXiA0hFRTK8aNHuAhtrnTHHpWcAEZeojUwBE2ts
yVtF7QHRlTPh2NUv5FOlPSd57mw7bQJADAAYz8Moyxu4X8lqlB3/cj7OPRrH7QFb
yMvFyHrtLIQ9QRtdf1c78KVAokXPm7blotnq2eGXz6EOWKEvYLeEviKc+0zxgZfg
FJPRztkCAwEAAaNTMFEwHQYDVR0OBBYEFNhBZxryvykCjfPO85xB3wof2enAMB8G
A1UdIwQYMBaAFNhBZxryvykCjfPO85xB3wof2enAMA8GA1UdEwEB/wQFMAMBAf8w
DQYJKoZIhvcNAQELBQADggIBAEZwlsQ+3yd1MVxLRy9RjoA8hI7iWBNmvPUyNjlb
l/L9N+dZgdx9G5h/KPRUyzvUc/uk/ZxTWVPIOp13WI65qwsBKrwvYKiXiwzjt+9V
CKDRc1sOghTSXk4FD3L5UcKvTQ2lRcFsqxbkopEwQWhoCuhe4vFyt3Nx8ZGLCBUD
3I5zMHtO8FtpZWKJPw46Yc1kasv0nlfly/vUbnErYfgjWX1hgWUcRgYdKwO4sOZ7
KbNma0WUsX5mWhXo4Kk7D15wATHO+j9s+j8m86duBL3A4HzpTo1DhHvBi0dkg0CO
XuSdByIzVLIPh3yhCHN1loRCP2rbzKM8IQeU/X5Q4UJeC/x9ew8Kk+RKXoHc8Y2C
JQO1DxuidyDJRhbb98wZo2YfIsdWQGjYZBe1XQRwBD28JnB+Rb9shml6lORWQn9y
P/STo9uWm5zvOCfqwbnCoetljDweItINx622G9SafBwPZc3o79oL7QSl8DgCtN6g
p0wGIlIBx+25w/96PqZcrYb8B7/uBHJviiKjBXDoIJWNiNRhW5HaFjeJdSKq7KIL
I/PO9KuHafif36ksG69X02Rio2/cTjgjEW1hGHcDRyyJWWaj7bd2eWuouh6FF22b
PA6FGY4vewDPnbLKLaix2ZIKxtedUDOH/qru3Mv58IFXmQ4iyM8oC8aOxYSQLZDn
1yJD
-----END CERTIFICATE-----
'';
"acme.test".key = builtins.toFile "acme.test.key" ''
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----
'';
"acme.test".cert = builtins.toFile "acme.test.cert" ''
-----BEGIN CERTIFICATE-----
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
NbjvWnP8lDU8j2l3eSG58S14iGs=
-----END CERTIFICATE-----
'';
}

View File

@ -18,7 +18,10 @@ import ../make-test-python.nix ({ pkgs, ...} : {
realms = {
"ATHENA.MIT.EDU" = {
admin_server = "athena.mit.edu";
kdc = "athena.mit.edu";
kdc = [
"athena01.mit.edu"
"athena02.mit.edu"
];
};
};
domain_realm = {
@ -65,7 +68,8 @@ import ../make-test-python.nix ({ pkgs, ...} : {
[realms]
ATHENA.MIT.EDU = {
admin_server = athena.mit.edu
kdc = athena.mit.edu
kdc = athena01.mit.edu
kdc = athena02.mit.edu
}
[domain_realm]

View File

@ -14,13 +14,10 @@ let
baseBackupDir = "/tmp/pg_basebackup";
walBackupDir = "/tmp/pg_wal";
atLeast12 = lib.versionAtLeast pkg.version "12.0";
restoreCommand = ''
restore_command = 'cp ${walBackupDir}/%f %p'
'';
recoveryFile = if atLeast12
then pkgs.writeTextDir "recovery.signal" ""
else pkgs.writeTextDir "recovery.conf" "${restoreCommand}";
else pkgs.writeTextDir "recovery.conf" "restore_command = 'cp ${walBackupDir}/%f %p'";
in {
name = "postgresql-wal-receiver-${postgresqlPackage}";
@ -30,14 +27,17 @@ let
services.postgresql = {
package = pkg;
enable = true;
extraConfig = ''
wal_level = archive # alias for replica on pg >= 9.6
max_wal_senders = 10
max_replication_slots = 10
'' + lib.optionalString atLeast12 ''
${restoreCommand}
recovery_end_command = 'touch recovery.done'
'';
settings = lib.mkMerge [
{
wal_level = "archive"; # alias for replica on pg >= 9.6
max_wal_senders = 10;
max_replication_slots = 10;
}
(lib.mkIf atLeast12 {
restore_command = "cp ${walBackupDir}/%f %p";
recovery_end_command = "touch recovery.done";
})
];
authentication = ''
host replication ${replicationUser} all trust
'';

View 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)
'';
})

View File

@ -7,18 +7,19 @@ let generateNodeConf = { lib, pkgs, config, privk, pubk, peerId, nodeId, ...}: {
virtualisation.vlans = [ 1 ];
environment.systemPackages = with pkgs; [ wireguard-tools ];
boot.extraModulePackages = [ config.boot.kernelPackages.wireguard ];
systemd.tmpfiles.rules = [
"f /run/wg_priv 0640 root systemd-network - ${privk}"
];
systemd.network = {
enable = true;
netdevs = {
"90-wg0" = {
netdevConfig = { Kind = "wireguard"; Name = "wg0"; };
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;
FwMark = 42;
FirewallMark = 42;
};
wireguardPeers = [ {wireguardPeerConfig={
Endpoint = "192.168.1.${peerId}:51820";

View File

@ -144,9 +144,10 @@ import ./make-test-python.nix ({ pkgs, ... }: {
)
output = machine.succeed("systemctl show | grep Watchdog")
assert "RuntimeWatchdogUSec=30s" in output
assert "RebootWatchdogUSec=10m" in output
assert "KExecWatchdogUSec=5m" in output
# assert "RuntimeWatchdogUSec=30s" in output
# for some reason RuntimeWatchdogUSec, doesn't seem to be updated in here.
assert "RebootWatchdogUSec=10min" in output
assert "KExecWatchdogUSec=5min" in output
# Test systemd cryptsetup support
with subtest("systemd successfully reads /etc/crypttab and unlocks volumes"):

View File

@ -57,7 +57,7 @@ stdenv.mkDerivation rec {
meta = with stdenv.lib; {
description = "Sound editor with graphical UI";
homepage = "http://audacityteam.org/";
homepage = "https://www.audacityteam.org/";
license = licenses.gpl2Plus;
maintainers = with maintainers; [ lheckemann ];
platforms = intersectLists platforms.linux platforms.x86; # fails on ARM

View File

@ -1,4 +1,4 @@
{ stdenv, fetchurl, pkgconfig, systemd ? null, libobjc, IOKit, fetchpatch }:
{ stdenv, lib, fetchurl, pkgconfig, systemd ? null, libobjc, IOKit, fetchpatch }:
stdenv.mkDerivation rec {
name = "libusb-1.0.19";
@ -26,7 +26,7 @@ stdenv.mkDerivation rec {
NIX_LDFLAGS = stdenv.lib.optionalString stdenv.isLinux "-lgcc_s";
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; {

View File

@ -1,8 +1,6 @@
{ mkDerivation
, stdenv
, fetchFromGitHub
, fetchpatch
, installShellFiles
, qmake
, qtbase
, qtmultimedia
@ -21,26 +19,18 @@ let
in
mkDerivation rec {
pname = "bambootracker";
version = "0.4.3";
version = "0.4.4";
src = fetchFromGitHub {
owner = "rerrahkr";
repo = "BambooTracker";
rev = "v${version}";
sha256 = "0gq40qmsdavsyl2d6a71rwp4mjlwvp1c8bry32srn4hliwfnvqa6";
sha256 = "0d0f4jqzknsiq725pvfndarfjg183f92rb0lim3wzshnsixr5vdc";
};
# Fix macOS build until new release
patches = [
(fetchpatch {
url = "https://github.com/rerrahkr/BambooTracker/commit/45346ed99559d44c2e32a5c6138a0835b212e875.patch";
sha256 = "1xkiqira1kpcqkacycy0y7qm1brhf89amliv42byijl4palmykh2";
})
];
sourceRoot = "source/BambooTracker";
preConfigure = "cd BambooTracker";
nativeBuildInputs = [ qmake qttools installShellFiles ];
nativeBuildInputs = [ qmake qttools ];
buildInputs = [ qtbase qtmultimedia ]
++ optional alsaSupport alsaLib
@ -51,17 +41,6 @@ mkDerivation rec {
++ optional pulseSupport "CONFIG+=use_pulse"
++ 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; {
description = "A tracker for YM2608 (OPNA) which was used in NEC PC-8801/9801 series computers";
homepage = "https://github.com/rerrahkr/BambooTracker";

View File

@ -2,13 +2,13 @@
stdenv.mkDerivation rec {
pname = "bchoppr";
version = "1.6.4";
version = "1.8.0";
src = fetchFromGitHub {
owner = "sjaehn";
repo = pname;
rev = "${version}";
sha256 = "16b0sg7q2b8l4y4bp5s3yzsj9j6jayjy2mlvqkby6l7hcgjcj493";
sha256 = "1nd6byy75f0rbz9dm9drhxmpsfhxhg0y7q3v2m3098llynhy9k2j";
};
nativeBuildInputs = [ pkg-config ];

View File

@ -2,13 +2,13 @@
stdenv.mkDerivation rec {
pname = "BJumblr";
version = "1.4.0";
version = "1.4.2";
src = fetchFromGitHub {
owner = "sjaehn";
repo = pname;
rev = version;
sha256 = "03x1gvri9yk000fvvc8zvvywf38cc41vkyhhp9xby71b23n5wbn0";
sha256 = "0kl6hrxmqrdf0195bfnzsa2h1073fgiqrfhg2276fm1954sm994v";
};
nativeBuildInputs = [ pkgconfig ];

View File

@ -2,13 +2,13 @@
stdenv.mkDerivation rec {
pname = "bschaffl";
version = "0.3";
version = "1.2.0";
src = fetchFromGitHub {
owner = "sjaehn";
repo = pname;
rev = version;
sha256 = "1pcch7j1wgsb77mjy58hl3z43p83dv0vcmyh129m9k216b09gy29";
sha256 = "1c09acqrbd387ba41f8ch1qykdap5h6cg9if5pgd16i4dmjnpghj";
};
nativeBuildInputs = [ pkg-config ];

View File

@ -2,13 +2,13 @@
stdenv.mkDerivation rec {
pname = "dragonfly-reverb";
version = "3.1.1";
version = "3.2.1";
src = fetchFromGitHub {
owner = "michaelwillis";
repo = "dragonfly-reverb";
rev = version;
sha256 = "188cm45hr0i33m4h2irql1wrsmsfis65s706wjiid0z59q47rf9p";
sha256 = "0vfm2510shah67k87mdyar4wr4vqwii59y9lqfhwm6blxparkrqa";
fetchSubmodules = true;
};

View File

@ -5,8 +5,7 @@
, pkgconfig
, cmake
, llvm
# TODO: put back when it builds again
# , emscripten
, emscripten
, openssl
, libsndfile
, libmicrohttpd
@ -47,7 +46,7 @@ let
inherit src;
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 = {

View File

@ -11,13 +11,13 @@ with stdenv.lib;
mkDerivation rec {
pname = "fmit";
version = "1.2.13";
version = "1.2.14";
src = fetchFromGitHub {
owner = "gillesdegottex";
repo = "fmit";
rev = "v${version}";
sha256 = "1qyskam053pvlap1av80rgp12pzhr92rs88vqs6s0ia3ypnixcc6";
sha256 = "1q062pfwz2vr9hbfn29fv54ip3jqfd9r99nhpr8w7mn1csy38azx";
};
nativeBuildInputs = [ qmake itstool wrapQtAppsHook ];

View File

@ -2,20 +2,21 @@
stdenv.mkDerivation rec {
pname = "geonkick";
version = "2.3.3";
version = "2.3.7";
src = fetchFromGitLab {
owner = "iurie-sw";
repo = pname;
rev = "v${version}";
sha256 = "0h1abb6q2bmi01a3v37adkc4zc03j47jpvffz8p2lpp33xhljghs";
sha256 = "1wdcbwiyy6i5agq5lffkyilyc8mv1cc4mp9h0nybn240vb2flqc2";
};
nativeBuildInputs = [ cmake pkg-config ];
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 = {
homepage = "https://gitlab.com/iurie-sw/geonkick";

View File

@ -14,7 +14,7 @@ python3Packages.buildPythonApplication rec {
] ++ (with python3Packages; [
configobj
requests
tornado_4
tornado
]);
# no tests implemented

View File

@ -21,7 +21,7 @@ pythonPackages.buildPythonApplication rec {
];
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;
# There are no tests

View File

@ -14,16 +14,16 @@ let
in
rustPlatform.buildRustPackage rec {
pname = "ncspot";
version = "0.2.1";
version = "0.2.2";
src = fetchFromGitHub {
owner = "hrkfdn";
repo = "ncspot";
rev = "v${version}";
sha256 = "1yx0fc24bgh1x6fdwznc1hqvjq0j7i0zvws3bsyijzs7q48jm0z7";
sha256 = "1i17pidw2hylijwfn96f2bnswfxxwdln2ydsq8b1q4hfzfbxlfk2";
};
cargoSha256 = "0bh2shg80xbs2cw10dabrdxkvhf2csk5h9wmmk5z87q6w25paz1f";
cargoSha256 = "1cpy4wrj9dz2crva4p18f8hzym73x4m2mcfds4ppri4ir7qg29dr";
cargoBuildFlags = [ "--no-default-features" "--features" "${lib.concatStringsSep "," features}" ];

View File

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

View File

@ -1,37 +1,34 @@
{ stdenv, fetchFromGitHub, python2Packages, chromaprint }:
{ stdenv, fetchFromGitHub, python3Packages, chromaprint }:
python2Packages.buildPythonApplication rec {
python3Packages.buildPythonApplication rec {
pname = "puddletag";
version = "1.2.0";
version = "2.0.1";
src = fetchFromGitHub {
owner = "keithgg";
repo = "puddletag";
rev = "v${version}";
sha256 = "1g6wa91awy17z5b704yi9kfynnvfm9lkrvpfvwccscr1h8s3qmiz";
owner = "keithgg";
repo = "puddletag";
rev = version;
sha256 = "sha256-9l8Pc77MX5zFkOqU00HFS8//3Bzd2OMnVV1brmWsNAQ=";
};
setSourceRoot = ''
sourceRoot=$(echo */source)
'';
sourceRoot = "source/source";
disabled = python2Packages.isPy3k; # work to support python 3 has not begun
propagatedBuildInputs = [ chromaprint ] ++ (with python2Packages; [
propagatedBuildInputs = [ chromaprint ] ++ (with python3Packages; [
configobj
mutagen
pyparsing
pyqt4
pyqt5
]);
doCheck = false; # there are no tests
dontStrip = true; # we are not generating any binaries
meta = with stdenv.lib; {
description = "An audio tag editor similar to the Windows program, Mp3tag";
homepage = "https://docs.puddletag.net";
license = licenses.gpl3;
homepage = "https://docs.puddletag.net";
license = licenses.gpl3;
maintainers = with maintainers; [ peterhoeg ];
platforms = platforms.linux;
platforms = platforms.linux;
};
}

View File

@ -4,7 +4,7 @@
, faacSupport ? false, faac ? null
, flacSupport ? true, flac ? null
, soxSupport ? true, sox ? null
, vorbisSupport ? true, vorbisTools ? null
, vorbisSupport ? true, vorbis-tools ? null
}:
assert mp3Support -> lame != null;
@ -12,7 +12,7 @@ assert opusSupport -> opusTools != null;
assert faacSupport -> faac != null;
assert flacSupport -> flac != null;
assert soxSupport -> sox != null;
assert vorbisSupport -> vorbisTools != null;
assert vorbisSupport -> vorbis-tools != null;
let
zeroconf = pythonPackages.callPackage ./zeroconf.nix { };
@ -37,7 +37,7 @@ pythonPackages.buildPythonApplication {
++ stdenv.lib.optional faacSupport faac
++ stdenv.lib.optional flacSupport flac
++ stdenv.lib.optional soxSupport sox
++ stdenv.lib.optional vorbisSupport vorbisTools;
++ stdenv.lib.optional vorbisSupport vorbis-tools;
# upstream has no tests
checkPhase = ''

View File

@ -4,11 +4,11 @@
mkDerivation rec {
pname = "qsynth";
version = "0.6.2";
version = "0.6.3";
src = fetchurl {
url = "mirror://sourceforge/qsynth/${pname}-${version}.tar.gz";
sha256 = "0cp6vrqrj37rv3a7qfvqrg64j7zwpfj60y5b83mlkzvmg1sgjnlv";
sha256 = "0xiqmpzpxjvh32vivfj6h33w0ahmyfjzjb41b6fnf92bbg9k6mqv";
};
nativeBuildInputs = [ autoconf pkgconfig ];

View File

@ -14,7 +14,7 @@ in
stdenv.mkDerivation rec {
pname = "renoise";
version = "3.2.1";
version = "3.2.2";
src =
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://web.archive.org/web/https://files.renoise.com/demo/Renoise_${urlVersion version}_Demo_Linux.tar.gz"
];
sha256 = "0dhcidgnjzd4abw0xw1waj9mazp03nbvjcr2xx09l8gnfrkvny46";
sha256 = "1v249kmyidx55kppk3sry7yg6hl1a91ixhnwz36h4y134fs7bkrl";
}
else
releasePath

Some files were not shown because too many files have changed in this diff Show More