Merge remote-tracking branch 'origin/staging' into dnicponski/scratch/update_darwin_cctools
This commit is contained in:
commit
08d6c4019d
8
.github/CODEOWNERS
vendored
8
.github/CODEOWNERS
vendored
@ -47,6 +47,9 @@
|
|||||||
/nixos/doc/manual/man-nixos-option.xml @nbp
|
/nixos/doc/manual/man-nixos-option.xml @nbp
|
||||||
/nixos/modules/installer/tools/nixos-option.sh @nbp
|
/nixos/modules/installer/tools/nixos-option.sh @nbp
|
||||||
|
|
||||||
|
# NixOS integration test driver
|
||||||
|
/nixos/lib/test-driver @tfc
|
||||||
|
|
||||||
# New NixOS modules
|
# New NixOS modules
|
||||||
/nixos/modules/module-list.nix @Infinisil
|
/nixos/modules/module-list.nix @Infinisil
|
||||||
|
|
||||||
@ -167,3 +170,8 @@
|
|||||||
/nixos/modules/services/monitoring/prometheus/exporters.nix @WilliButz
|
/nixos/modules/services/monitoring/prometheus/exporters.nix @WilliButz
|
||||||
/nixos/modules/services/monitoring/prometheus/exporters.xml @WilliButz
|
/nixos/modules/services/monitoring/prometheus/exporters.xml @WilliButz
|
||||||
/nixos/tests/prometheus-exporters.nix @WilliButz
|
/nixos/tests/prometheus-exporters.nix @WilliButz
|
||||||
|
|
||||||
|
# PHP
|
||||||
|
/pkgs/development/interpreters/php @etu
|
||||||
|
/pkgs/top-level/php-packages.nix @etu
|
||||||
|
/pkgs/build-support/build-pecl.nix @etu
|
||||||
|
@ -141,11 +141,10 @@
|
|||||||
For a more useful example, try the following. This configuration only allows unfree packages named flash player and visual studio code:
|
For a more useful example, try the following. This configuration only allows unfree packages named flash player and visual studio code:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
{
|
{
|
||||||
allowUnfreePredicate = (pkg: builtins.elem
|
allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [
|
||||||
(pkg.pname or (builtins.parseDrvName pkg.name).name) [
|
|
||||||
"flashplayer"
|
"flashplayer"
|
||||||
"vscode"
|
"vscode"
|
||||||
]);
|
];
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
@ -217,7 +216,7 @@
|
|||||||
The following configuration example only allows insecure packages with very short names:
|
The following configuration example only allows insecure packages with very short names:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
{
|
{
|
||||||
allowInsecurePredicate = (pkg: (builtins.stringLength (builtins.parseDrvName pkg.name).name) <= 5);
|
allowInsecurePredicate = pkg: builtins.stringLength (lib.getName pkg) <= 5;
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
|
@ -84,7 +84,8 @@ let
|
|||||||
hasInfix hasPrefix hasSuffix stringToCharacters stringAsChars escape
|
hasInfix hasPrefix hasSuffix stringToCharacters stringAsChars escape
|
||||||
escapeShellArg escapeShellArgs replaceChars lowerChars
|
escapeShellArg escapeShellArgs replaceChars lowerChars
|
||||||
upperChars toLower toUpper addContextFrom splitString
|
upperChars toLower toUpper addContextFrom splitString
|
||||||
removePrefix removeSuffix versionOlder versionAtLeast getVersion
|
removePrefix removeSuffix versionOlder versionAtLeast
|
||||||
|
getName getVersion
|
||||||
nameFromURL enableFeature enableFeatureAs withFeature
|
nameFromURL enableFeature enableFeatureAs withFeature
|
||||||
withFeatureAs fixedWidthString fixedWidthNumber isStorePath
|
withFeatureAs fixedWidthString fixedWidthNumber isStorePath
|
||||||
toInt readPathsFromFile fileContents;
|
toInt readPathsFromFile fileContents;
|
||||||
|
@ -472,6 +472,23 @@ rec {
|
|||||||
*/
|
*/
|
||||||
versionAtLeast = v1: v2: !versionOlder v1 v2;
|
versionAtLeast = v1: v2: !versionOlder v1 v2;
|
||||||
|
|
||||||
|
/* This function takes an argument that's either a derivation or a
|
||||||
|
derivation's "name" attribute and extracts the name part from that
|
||||||
|
argument.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
getName "youtube-dl-2016.01.01"
|
||||||
|
=> "youtube-dl"
|
||||||
|
getName pkgs.youtube-dl
|
||||||
|
=> "youtube-dl"
|
||||||
|
*/
|
||||||
|
getName = x:
|
||||||
|
let
|
||||||
|
parse = drv: (builtins.parseDrvName drv).name;
|
||||||
|
in if isString x
|
||||||
|
then parse x
|
||||||
|
else x.pname or (parse x.name);
|
||||||
|
|
||||||
/* This function takes an argument that's either a derivation or a
|
/* This function takes an argument that's either a derivation or a
|
||||||
derivation's "name" attribute and extracts the version part from that
|
derivation's "name" attribute and extracts the version part from that
|
||||||
argument.
|
argument.
|
||||||
|
@ -37,6 +37,7 @@ rec {
|
|||||||
else if final.isAndroid then "bionic"
|
else if final.isAndroid then "bionic"
|
||||||
else if final.isLinux /* default */ then "glibc"
|
else if final.isLinux /* default */ then "glibc"
|
||||||
else if final.isMsp430 then "newlib"
|
else if final.isMsp430 then "newlib"
|
||||||
|
else if final.isVc4 then "newlib"
|
||||||
else if final.isAvr then "avrlibc"
|
else if final.isAvr then "avrlibc"
|
||||||
else if final.isNetBSD then "nblibc"
|
else if final.isNetBSD then "nblibc"
|
||||||
# TODO(@Ericson2314) think more about other operating systems
|
# TODO(@Ericson2314) think more about other operating systems
|
||||||
|
@ -26,7 +26,7 @@ let
|
|||||||
|
|
||||||
"riscv32-linux" "riscv64-linux"
|
"riscv32-linux" "riscv64-linux"
|
||||||
|
|
||||||
"aarch64-none" "avr-none" "arm-none" "i686-none" "x86_64-none" "powerpc-none" "msp430-none" "riscv64-none" "riscv32-none"
|
"aarch64-none" "avr-none" "arm-none" "i686-none" "x86_64-none" "powerpc-none" "msp430-none" "riscv64-none" "riscv32-none" "vc4-none"
|
||||||
];
|
];
|
||||||
|
|
||||||
allParsed = map parse.mkSystemFromString all;
|
allParsed = map parse.mkSystemFromString all;
|
||||||
@ -45,6 +45,7 @@ in {
|
|||||||
x86_64 = filterDoubles predicates.isx86_64;
|
x86_64 = filterDoubles predicates.isx86_64;
|
||||||
mips = filterDoubles predicates.isMips;
|
mips = filterDoubles predicates.isMips;
|
||||||
riscv = filterDoubles predicates.isRiscV;
|
riscv = filterDoubles predicates.isRiscV;
|
||||||
|
vc4 = filterDoubles predicates.isVc4;
|
||||||
|
|
||||||
cygwin = filterDoubles predicates.isCygwin;
|
cygwin = filterDoubles predicates.isCygwin;
|
||||||
darwin = filterDoubles predicates.isDarwin;
|
darwin = filterDoubles predicates.isDarwin;
|
||||||
|
@ -118,6 +118,12 @@ rec {
|
|||||||
config = "avr";
|
config = "avr";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
vc4 = {
|
||||||
|
config = "vc4-elf";
|
||||||
|
libc = "newlib";
|
||||||
|
platform = {};
|
||||||
|
};
|
||||||
|
|
||||||
arm-embedded = {
|
arm-embedded = {
|
||||||
config = "arm-none-eabi";
|
config = "arm-none-eabi";
|
||||||
libc = "newlib";
|
libc = "newlib";
|
||||||
|
@ -21,6 +21,7 @@ rec {
|
|||||||
isSparc = { cpu = { family = "sparc"; }; };
|
isSparc = { cpu = { family = "sparc"; }; };
|
||||||
isWasm = { cpu = { family = "wasm"; }; };
|
isWasm = { cpu = { family = "wasm"; }; };
|
||||||
isMsp430 = { cpu = { family = "msp430"; }; };
|
isMsp430 = { cpu = { family = "msp430"; }; };
|
||||||
|
isVc4 = { cpu = { family = "vc4"; }; };
|
||||||
isAvr = { cpu = { family = "avr"; }; };
|
isAvr = { cpu = { family = "avr"; }; };
|
||||||
isAlpha = { cpu = { family = "alpha"; }; };
|
isAlpha = { cpu = { family = "alpha"; }; };
|
||||||
isJavaScript = { cpu = cpuTypes.js; };
|
isJavaScript = { cpu = cpuTypes.js; };
|
||||||
|
@ -112,6 +112,8 @@ rec {
|
|||||||
msp430 = { bits = 16; significantByte = littleEndian; family = "msp430"; };
|
msp430 = { bits = 16; significantByte = littleEndian; family = "msp430"; };
|
||||||
avr = { bits = 8; family = "avr"; };
|
avr = { bits = 8; family = "avr"; };
|
||||||
|
|
||||||
|
vc4 = { bits = 32; significantByte = littleEndian; family = "vc4"; };
|
||||||
|
|
||||||
js = { bits = 32; significantByte = littleEndian; family = "js"; };
|
js = { bits = 32; significantByte = littleEndian; family = "js"; };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1780,6 +1780,12 @@
|
|||||||
githubId = 875324;
|
githubId = 875324;
|
||||||
name = "David Johnson";
|
name = "David Johnson";
|
||||||
};
|
};
|
||||||
|
dmrauh = {
|
||||||
|
email = "dmrauh@posteo.de";
|
||||||
|
github = "dmrauh";
|
||||||
|
githubId = 37698547;
|
||||||
|
name = "Dominik Michael Rauh";
|
||||||
|
};
|
||||||
dmvianna = {
|
dmvianna = {
|
||||||
email = "dmlvianna@gmail.com";
|
email = "dmlvianna@gmail.com";
|
||||||
github = "dmvianna";
|
github = "dmvianna";
|
||||||
@ -2515,6 +2521,7 @@
|
|||||||
gazally = {
|
gazally = {
|
||||||
email = "gazally@runbox.com";
|
email = "gazally@runbox.com";
|
||||||
github = "gazally";
|
github = "gazally";
|
||||||
|
githubId = 16470252;
|
||||||
name = "Gemini Lasswell";
|
name = "Gemini Lasswell";
|
||||||
};
|
};
|
||||||
gebner = {
|
gebner = {
|
||||||
@ -3594,6 +3601,12 @@
|
|||||||
github = "klntsky";
|
github = "klntsky";
|
||||||
githubId = 18447310;
|
githubId = 18447310;
|
||||||
};
|
};
|
||||||
|
kmcopper = {
|
||||||
|
email = "kmcopper@danwin1210.me";
|
||||||
|
name = "Kyle Copperfield";
|
||||||
|
github = "kmcopper";
|
||||||
|
githubId = 57132115;
|
||||||
|
};
|
||||||
kmeakin = {
|
kmeakin = {
|
||||||
email = "karlwfmeakin@gmail.com";
|
email = "karlwfmeakin@gmail.com";
|
||||||
name = "Karl Meakin";
|
name = "Karl Meakin";
|
||||||
@ -3700,6 +3713,18 @@
|
|||||||
githubId = 449813;
|
githubId = 449813;
|
||||||
name = "Roman Kuznetsov";
|
name = "Roman Kuznetsov";
|
||||||
};
|
};
|
||||||
|
kylesferrazza = {
|
||||||
|
name = "Kyle Sferrazza";
|
||||||
|
email = "kyle.sferrazza@gmail.com";
|
||||||
|
|
||||||
|
github = "kylesferrazza";
|
||||||
|
githubId = 6677292;
|
||||||
|
|
||||||
|
keys = [{
|
||||||
|
longkeyid = "rsa4096/81A1540948162372";
|
||||||
|
fingerprint = "5A9A 1C9B 2369 8049 3B48 CF5B 81A1 5409 4816 2372";
|
||||||
|
}];
|
||||||
|
};
|
||||||
kylewlacy = {
|
kylewlacy = {
|
||||||
email = "kylelacy+nix@pm.me";
|
email = "kylelacy+nix@pm.me";
|
||||||
github = "kylewlacy";
|
github = "kylewlacy";
|
||||||
@ -4505,6 +4530,12 @@
|
|||||||
githubId = 117842;
|
githubId = 117842;
|
||||||
name = "Henri Bourcereau";
|
name = "Henri Bourcereau";
|
||||||
};
|
};
|
||||||
|
mmilata = {
|
||||||
|
email = "martin@martinmilata.cz";
|
||||||
|
github = "mmilata";
|
||||||
|
gitHubId = 85857;
|
||||||
|
name = "Martin Milata";
|
||||||
|
};
|
||||||
mmlb = {
|
mmlb = {
|
||||||
email = "me.mmlb@mmlb.me";
|
email = "me.mmlb@mmlb.me";
|
||||||
github = "mmlb";
|
github = "mmlb";
|
||||||
@ -6087,7 +6118,7 @@
|
|||||||
name = "Shahrukh Khan";
|
name = "Shahrukh Khan";
|
||||||
};
|
};
|
||||||
shanemikel = {
|
shanemikel = {
|
||||||
email = "shanemikel1@gmail.com";
|
email = "shanepearlman@pm.me";
|
||||||
github = "shanemikel";
|
github = "shanemikel";
|
||||||
githubId = 6720672;
|
githubId = 6720672;
|
||||||
name = "Shane Pearlman";
|
name = "Shane Pearlman";
|
||||||
@ -6708,6 +6739,12 @@
|
|||||||
githubId = 42933;
|
githubId = 42933;
|
||||||
name = "Andrew Childs";
|
name = "Andrew Childs";
|
||||||
};
|
};
|
||||||
|
thefenriswolf = {
|
||||||
|
email = "stefan.rohrbacher97@gmail.com";
|
||||||
|
github = "thefenriswolf";
|
||||||
|
githubId = "8547242";
|
||||||
|
name = "Stefan Rohrbacher";
|
||||||
|
};
|
||||||
thesola10 = {
|
thesola10 = {
|
||||||
email = "thesola10@bobile.fr";
|
email = "thesola10@bobile.fr";
|
||||||
github = "thesola10";
|
github = "thesola10";
|
||||||
|
@ -126,7 +126,7 @@ let
|
|||||||
|
|
||||||
packageData = package: {
|
packageData = package: {
|
||||||
name = package.name;
|
name = package.name;
|
||||||
pname = (builtins.parseDrvName package.name).name;
|
pname = pkgs.lib.getName package;
|
||||||
updateScript = map builtins.toString (pkgs.lib.toList package.updateScript);
|
updateScript = map builtins.toString (pkgs.lib.toList package.updateScript);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -13,9 +13,7 @@
|
|||||||
<para>
|
<para>
|
||||||
It sets <xref linkend="opt-services.xserver.enable"/>,
|
It sets <xref linkend="opt-services.xserver.enable"/>,
|
||||||
<xref linkend="opt-services.xserver.displayManager.sddm.enable"/>,
|
<xref linkend="opt-services.xserver.displayManager.sddm.enable"/>,
|
||||||
<xref linkend="opt-services.xserver.desktopManager.plasma5.enable"/> (
|
<xref linkend="opt-services.xserver.desktopManager.plasma5.enable"/>, and
|
||||||
<link linkend="opt-services.xserver.desktopManager.plasma5.enableQt4Support">
|
|
||||||
without Qt4 Support</link>), and
|
|
||||||
<xref linkend="opt-services.xserver.libinput.enable"/> to true. It also
|
<xref linkend="opt-services.xserver.libinput.enable"/> to true. It also
|
||||||
includes glxinfo and firefox in the system packages list.
|
includes glxinfo and firefox in the system packages list.
|
||||||
</para>
|
</para>
|
||||||
|
@ -45,12 +45,12 @@
|
|||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
<literal>git tag -a -s -m "Release 17.09-beta" 17.09-beta
|
<literal>git tag -a -s -m "Release 17.09-beta" 17.09-beta
|
||||||
&& git push --tags</literal>
|
&& git push origin 17.09-beta</literal>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
From the master branch run <literal>git checkout -B
|
From the master branch run <literal>git checkout -b
|
||||||
release-17.09</literal>.
|
release-17.09</literal>.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
@ -157,7 +157,7 @@
|
|||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Release Nix (currently only Eelco Dolstra can do that).
|
Release Nix (currently only Eelco Dolstra can do that).
|
||||||
<link xlink:href="https://github.com/NixOS/nixpkgs/commit/53710c752a85f00658882531bc90a23a3d1287e4">
|
<link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/installer/tools/nix-fallback-paths.nix">
|
||||||
Make sure fallback is updated. </link>
|
Make sure fallback is updated. </link>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
@ -169,8 +169,8 @@
|
|||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Change <literal>stableBranch</literal> to true and wait for channel to
|
Change <literal>stableBranch</literal> to <literal>true</literal> in Hydra and wait for
|
||||||
update.
|
the channel to update.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
@ -193,9 +193,11 @@
|
|||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Update http://nixos.org/nixos/download.html and
|
Update the
|
||||||
http://nixos.org/nixos/manual in
|
<link xlink:href="https://github.com/NixOS/nixos-homepage/commit/2a37975d5a617ecdfca94696242b6f32ffcba9f1"><code>NIXOS_SERIES</code></link>
|
||||||
https://github.com/NixOS/nixos-org-configurations
|
in the
|
||||||
|
<link xlink:href="https://github.com/NixOS/nixos-homepage">nixos-homepage</link>
|
||||||
|
repository.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
@ -212,7 +214,8 @@
|
|||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Send an email to nix-dev to announce the release with above information.
|
Create a new topic on <link xlink:href="https://discourse.nixos.org/">the
|
||||||
|
Discourse instance</link> to announce the release with the above information.
|
||||||
Best to check how previous email was formulated to see what needs to be
|
Best to check how previous email was formulated to see what needs to be
|
||||||
included.
|
included.
|
||||||
</para>
|
</para>
|
||||||
|
@ -418,11 +418,11 @@
|
|||||||
Do the installation:
|
Do the installation:
|
||||||
<screen>
|
<screen>
|
||||||
<prompt># </prompt>nixos-install</screen>
|
<prompt># </prompt>nixos-install</screen>
|
||||||
Cross fingers. If this fails due to a temporary problem (such as a network
|
This will install your system based on the configuration you provided.
|
||||||
issue while downloading binaries from the NixOS binary cache), you can
|
If anything fails due to a configuration problem or any other issue
|
||||||
just re-run <command>nixos-install</command>. Otherwise, fix your
|
(such as a network outage while downloading binaries from the NixOS
|
||||||
<filename>configuration.nix</filename> and then re-run
|
binary cache), you can re-run <command>nixos-install</command> after
|
||||||
<command>nixos-install</command>.
|
fixing your <filename>configuration.nix</filename>.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
As the last step, <command>nixos-install</command> will ask you to set the
|
As the last step, <command>nixos-install</command> will ask you to set the
|
||||||
|
@ -155,6 +155,37 @@
|
|||||||
You should now use the different build tools coming with the languages with sandbox mode disabled.
|
You should now use the different build tools coming with the languages with sandbox mode disabled.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
There is now only one Xfce package-set and module. This means attributes, <literal>xfce4-14</literal>
|
||||||
|
<literal>xfce4-12</literal>, and <literal>xfceUnstable</literal> all now point to the latest Xfce 4.14
|
||||||
|
packages. And in future NixOS releases will be the latest released version of Xfce available at the
|
||||||
|
time during the releases development (if viable).
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The <link linkend="opt-services.phpfpm.pools">phpfpm</link> module now sets
|
||||||
|
<literal>PrivateTmp=true</literal> in its systemd units for better process isolation.
|
||||||
|
If you rely on <literal>/tmp</literal> being shared with other services, explicitly override this by
|
||||||
|
setting <literal>serviceConfig.PrivateTmp</literal> to <literal>false</literal> for each phpfpm unit.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
KDE’s old multimedia framework Phonon no longer supports Qt 4. For that reason, Plasma desktop also does not have <option>enableQt4Support</option> option any more.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The BeeGFS module has been removed.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The osquery module has been removed.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ let
|
|||||||
optionsList = lib.sort optionLess optionsListDesc;
|
optionsList = lib.sort optionLess optionsListDesc;
|
||||||
|
|
||||||
# Convert the list of options into an XML file.
|
# Convert the list of options into an XML file.
|
||||||
optionsXML = builtins.toFile "options.xml" (builtins.toXML optionsList);
|
optionsXML = pkgs.writeText "options.xml" (builtins.toXML optionsList);
|
||||||
|
|
||||||
optionsNix = builtins.listToAttrs (map (o: { name = o.name; value = removeAttrs o ["name" "visible" "internal"]; }) optionsList);
|
optionsNix = builtins.listToAttrs (map (o: { name = o.name; value = removeAttrs o ["name" "visible" "internal"]; }) optionsList);
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@ from contextlib import contextmanager, _GeneratorContextManager
|
|||||||
from xml.sax.saxutils import XMLGenerator
|
from xml.sax.saxutils import XMLGenerator
|
||||||
import _thread
|
import _thread
|
||||||
import atexit
|
import atexit
|
||||||
import json
|
|
||||||
import os
|
import os
|
||||||
import ptpython.repl
|
import ptpython.repl
|
||||||
import pty
|
import pty
|
||||||
@ -16,7 +15,7 @@ import sys
|
|||||||
import tempfile
|
import tempfile
|
||||||
import time
|
import time
|
||||||
import unicodedata
|
import unicodedata
|
||||||
from typing import Tuple, TextIO, Any, Callable, Dict, Iterator, Optional, List
|
from typing import Tuple, Any, Callable, Dict, Iterator, Optional, List
|
||||||
|
|
||||||
CHAR_TO_KEY = {
|
CHAR_TO_KEY = {
|
||||||
"A": "shift-a",
|
"A": "shift-a",
|
||||||
@ -290,9 +289,14 @@ class Machine:
|
|||||||
|
|
||||||
def wait_for_monitor_prompt(self) -> str:
|
def wait_for_monitor_prompt(self) -> str:
|
||||||
assert self.monitor is not None
|
assert self.monitor is not None
|
||||||
|
answer = ""
|
||||||
while True:
|
while True:
|
||||||
answer = self.monitor.recv(1024).decode()
|
undecoded_answer = self.monitor.recv(1024)
|
||||||
|
if not undecoded_answer:
|
||||||
|
break
|
||||||
|
answer += undecoded_answer.decode()
|
||||||
if answer.endswith("(qemu) "):
|
if answer.endswith("(qemu) "):
|
||||||
|
break
|
||||||
return answer
|
return answer
|
||||||
|
|
||||||
def send_monitor_command(self, command: str) -> str:
|
def send_monitor_command(self, command: str) -> str:
|
||||||
@ -606,12 +610,15 @@ class Machine:
|
|||||||
+ os.environ.get("QEMU_OPTS", "")
|
+ os.environ.get("QEMU_OPTS", "")
|
||||||
)
|
)
|
||||||
|
|
||||||
environment = {
|
environment = dict(os.environ)
|
||||||
"QEMU_OPTS": qemu_options,
|
environment.update(
|
||||||
|
{
|
||||||
|
"TMPDIR": self.state_dir,
|
||||||
"SHARED_DIR": self.shared_dir,
|
"SHARED_DIR": self.shared_dir,
|
||||||
"USE_TMPDIR": "1",
|
"USE_TMPDIR": "1",
|
||||||
|
"QEMU_OPTS": qemu_options,
|
||||||
}
|
}
|
||||||
environment.update(dict(os.environ))
|
)
|
||||||
|
|
||||||
self.process = subprocess.Popen(
|
self.process = subprocess.Popen(
|
||||||
self.script,
|
self.script,
|
||||||
@ -749,7 +756,7 @@ def run_tests() -> None:
|
|||||||
if tests is not None:
|
if tests is not None:
|
||||||
with log.nested("running the VM test script"):
|
with log.nested("running the VM test script"):
|
||||||
try:
|
try:
|
||||||
exec(tests)
|
exec(tests, globals())
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
eprint("error: {}".format(str(e)))
|
eprint("error: {}".format(str(e)))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
@ -763,7 +770,9 @@ def run_tests() -> None:
|
|||||||
machine.execute("sync")
|
machine.execute("sync")
|
||||||
|
|
||||||
if nr_tests != 0:
|
if nr_tests != 0:
|
||||||
log.log("{} out of {} tests succeeded".format(nr_succeeded, nr_tests))
|
eprint("{} out of {} tests succeeded".format(nr_succeeded, nr_tests))
|
||||||
|
if nr_tests > nr_succeeded:
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
|
@ -211,11 +211,11 @@ upload_image() {
|
|||||||
log "Registering snapshot $snapshot_id as AMI"
|
log "Registering snapshot $snapshot_id as AMI"
|
||||||
|
|
||||||
local block_device_mappings=(
|
local block_device_mappings=(
|
||||||
"DeviceName=/dev/sda1,Ebs={SnapshotId=$snapshot_id,VolumeSize=$image_logical_gigabytes,DeleteOnTermination=true,VolumeType=gp2}"
|
"DeviceName=/dev/xvda,Ebs={SnapshotId=$snapshot_id,VolumeSize=$image_logical_gigabytes,DeleteOnTermination=true,VolumeType=gp2}"
|
||||||
)
|
)
|
||||||
|
|
||||||
local extra_flags=(
|
local extra_flags=(
|
||||||
--root-device-name /dev/sda1
|
--root-device-name /dev/xvda
|
||||||
--sriov-net-support simple
|
--sriov-net-support simple
|
||||||
--ena-support
|
--ena-support
|
||||||
--virtualization-type hvm
|
--virtualization-type hvm
|
||||||
|
@ -10,7 +10,7 @@ let
|
|||||||
isQtStyle = cfg.platformTheme == "gtk2" && cfg.style != "adwaita";
|
isQtStyle = cfg.platformTheme == "gtk2" && cfg.style != "adwaita";
|
||||||
|
|
||||||
packages = if isQGnome then [ pkgs.qgnomeplatform pkgs.adwaita-qt ]
|
packages = if isQGnome then [ pkgs.qgnomeplatform pkgs.adwaita-qt ]
|
||||||
else if isQtStyle then [ pkgs.qtstyleplugins ]
|
else if isQtStyle then [ pkgs.libsForQt5.qtstyleplugins ]
|
||||||
else throw "`qt5.platformTheme` ${cfg.platformTheme} and `qt5.style` ${cfg.style} are not compatible.";
|
else throw "`qt5.platformTheme` ${cfg.platformTheme} and `qt5.style` ${cfg.style} are not compatible.";
|
||||||
|
|
||||||
in
|
in
|
||||||
|
@ -1,41 +0,0 @@
|
|||||||
{ config, lib, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
|
||||||
cfg = config.networking.vpnc;
|
|
||||||
mkServiceDef = name: value:
|
|
||||||
{
|
|
||||||
name = "vpnc/${name}.conf";
|
|
||||||
value = { text = value; };
|
|
||||||
};
|
|
||||||
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options = {
|
|
||||||
networking.vpnc = {
|
|
||||||
services = mkOption {
|
|
||||||
type = types.attrsOf types.str;
|
|
||||||
default = {};
|
|
||||||
example = literalExample ''
|
|
||||||
{ test = '''
|
|
||||||
IPSec gateway 192.168.1.1
|
|
||||||
IPSec ID someID
|
|
||||||
IPSec secret secretKey
|
|
||||||
Xauth username name
|
|
||||||
Xauth password pass
|
|
||||||
''';
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
description =
|
|
||||||
''
|
|
||||||
The names of cisco VPNs and their associated definitions
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config.environment.etc = mapAttrs' mkServiceDef cfg.services;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -11,7 +11,6 @@ with lib;
|
|||||||
services.xserver = {
|
services.xserver = {
|
||||||
desktopManager.plasma5 = {
|
desktopManager.plasma5 = {
|
||||||
enable = true;
|
enable = true;
|
||||||
enableQt4Support = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# Automatically login as nixos.
|
# Automatically login as nixos.
|
||||||
|
@ -11,6 +11,9 @@
|
|||||||
|
|
||||||
{ lib, ... }:
|
{ lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
inherit (lib) types;
|
||||||
|
in
|
||||||
{
|
{
|
||||||
options = {
|
options = {
|
||||||
|
|
||||||
@ -19,6 +22,7 @@
|
|||||||
description = ''
|
description = ''
|
||||||
The user IDs used in NixOS.
|
The user IDs used in NixOS.
|
||||||
'';
|
'';
|
||||||
|
type = types.attrsOf types.int;
|
||||||
};
|
};
|
||||||
|
|
||||||
ids.gids = lib.mkOption {
|
ids.gids = lib.mkOption {
|
||||||
@ -26,6 +30,7 @@
|
|||||||
description = ''
|
description = ''
|
||||||
The group IDs used in NixOS.
|
The group IDs used in NixOS.
|
||||||
'';
|
'';
|
||||||
|
type = types.attrsOf types.int;
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -35,7 +35,6 @@
|
|||||||
./config/terminfo.nix
|
./config/terminfo.nix
|
||||||
./config/unix-odbc-drivers.nix
|
./config/unix-odbc-drivers.nix
|
||||||
./config/users-groups.nix
|
./config/users-groups.nix
|
||||||
./config/vpnc.nix
|
|
||||||
./config/vte.nix
|
./config/vte.nix
|
||||||
./config/zram.nix
|
./config/zram.nix
|
||||||
./hardware/acpilight.nix
|
./hardware/acpilight.nix
|
||||||
@ -519,7 +518,6 @@
|
|||||||
./services/monitoring/munin.nix
|
./services/monitoring/munin.nix
|
||||||
./services/monitoring/nagios.nix
|
./services/monitoring/nagios.nix
|
||||||
./services/monitoring/netdata.nix
|
./services/monitoring/netdata.nix
|
||||||
./services/monitoring/osquery.nix
|
|
||||||
./services/monitoring/prometheus/default.nix
|
./services/monitoring/prometheus/default.nix
|
||||||
./services/monitoring/prometheus/alertmanager.nix
|
./services/monitoring/prometheus/alertmanager.nix
|
||||||
./services/monitoring/prometheus/exporters.nix
|
./services/monitoring/prometheus/exporters.nix
|
||||||
@ -539,7 +537,6 @@
|
|||||||
./services/monitoring/zabbix-agent.nix
|
./services/monitoring/zabbix-agent.nix
|
||||||
./services/monitoring/zabbix-proxy.nix
|
./services/monitoring/zabbix-proxy.nix
|
||||||
./services/monitoring/zabbix-server.nix
|
./services/monitoring/zabbix-server.nix
|
||||||
./services/network-filesystems/beegfs.nix
|
|
||||||
./services/network-filesystems/cachefilesd.nix
|
./services/network-filesystems/cachefilesd.nix
|
||||||
./services/network-filesystems/davfs2.nix
|
./services/network-filesystems/davfs2.nix
|
||||||
./services/network-filesystems/drbd.nix
|
./services/network-filesystems/drbd.nix
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
displayManager.sddm.enable = true;
|
displayManager.sddm.enable = true;
|
||||||
desktopManager.plasma5 = {
|
desktopManager.plasma5 = {
|
||||||
enable = true;
|
enable = true;
|
||||||
enableQt4Support = false;
|
|
||||||
};
|
};
|
||||||
libinput.enable = true; # for touchpad support on many laptops
|
libinput.enable = true; # for touchpad support on many laptops
|
||||||
};
|
};
|
||||||
|
@ -23,7 +23,8 @@ with lib;
|
|||||||
###### implementation
|
###### implementation
|
||||||
config = mkIf config.programs.adb.enable {
|
config = mkIf config.programs.adb.enable {
|
||||||
services.udev.packages = [ pkgs.android-udev-rules ];
|
services.udev.packages = [ pkgs.android-udev-rules ];
|
||||||
environment.systemPackages = [ pkgs.androidenv.androidPkgs_9_0.platform-tools ];
|
# Give platform-tools lower priority so mke2fs+friends are taken from other packages first
|
||||||
|
environment.systemPackages = [ (lowPrio pkgs.androidenv.androidPkgs_9_0.platform-tools) ];
|
||||||
users.groups.adbusers = {};
|
users.groups.adbusers = {};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ with lib;
|
|||||||
(mkRenamedOptionModule [ "networking" "enableRalinkFirmware" ] [ "hardware" "enableRedistributableFirmware" ])
|
(mkRenamedOptionModule [ "networking" "enableRalinkFirmware" ] [ "hardware" "enableRedistributableFirmware" ])
|
||||||
(mkRenamedOptionModule [ "networking" "enableRTL8192cFirmware" ] [ "hardware" "enableRedistributableFirmware" ])
|
(mkRenamedOptionModule [ "networking" "enableRTL8192cFirmware" ] [ "hardware" "enableRedistributableFirmware" ])
|
||||||
(mkRenamedOptionModule [ "networking" "networkmanager" "useDnsmasq" ] [ "networking" "networkmanager" "dns" ])
|
(mkRenamedOptionModule [ "networking" "networkmanager" "useDnsmasq" ] [ "networking" "networkmanager" "dns" ])
|
||||||
|
(mkRenamedOptionModule [ "networking" "connman" ] [ "services" "connman" ])
|
||||||
(mkChangedOptionModule [ "services" "printing" "gutenprint" ] [ "services" "printing" "drivers" ]
|
(mkChangedOptionModule [ "services" "printing" "gutenprint" ] [ "services" "printing" "drivers" ]
|
||||||
(config:
|
(config:
|
||||||
let enabled = getAttrFromPath [ "services" "printing" "gutenprint" ] config;
|
let enabled = getAttrFromPath [ "services" "printing" "gutenprint" ] config;
|
||||||
@ -235,6 +236,7 @@ with lib;
|
|||||||
(mkRemovedOptionModule [ "services" "zabbixServer" "dbPassword" ] "Use services.zabbixServer.database.passwordFile instead.")
|
(mkRemovedOptionModule [ "services" "zabbixServer" "dbPassword" ] "Use services.zabbixServer.database.passwordFile instead.")
|
||||||
(mkRemovedOptionModule [ "systemd" "generator-packages" ] "Use systemd.packages instead.")
|
(mkRemovedOptionModule [ "systemd" "generator-packages" ] "Use systemd.packages instead.")
|
||||||
(mkRemovedOptionModule [ "fonts" "enableCoreFonts" ] "Use fonts.fonts = [ pkgs.corefonts ]; instead.")
|
(mkRemovedOptionModule [ "fonts" "enableCoreFonts" ] "Use fonts.fonts = [ pkgs.corefonts ]; instead.")
|
||||||
|
(mkRemovedOptionModule [ "networking" "vpnc" ] "Use environment.etc.\"vpnc/service.conf\" instead.")
|
||||||
|
|
||||||
# ZSH
|
# ZSH
|
||||||
(mkRenamedOptionModule [ "programs" "zsh" "enableSyntaxHighlighting" ] [ "programs" "zsh" "syntaxHighlighting" "enable" ])
|
(mkRenamedOptionModule [ "programs" "zsh" "enableSyntaxHighlighting" ] [ "programs" "zsh" "syntaxHighlighting" "enable" ])
|
||||||
@ -279,6 +281,13 @@ with lib;
|
|||||||
# BLCR
|
# BLCR
|
||||||
(mkRemovedOptionModule [ "environment.blcr.enable" ] "The BLCR module has been removed")
|
(mkRemovedOptionModule [ "environment.blcr.enable" ] "The BLCR module has been removed")
|
||||||
|
|
||||||
|
# beegfs
|
||||||
|
(mkRemovedOptionModule [ "services.beegfsEnable" ] "The BeeGFS module has been removed")
|
||||||
|
(mkRemovedOptionModule [ "services.beegfs" ] "The BeeGFS module has been removed")
|
||||||
|
|
||||||
|
# osquery
|
||||||
|
(mkRemovedOptionModule [ "services.osquery" ] "The osquery module has been removed")
|
||||||
|
|
||||||
# Redis
|
# Redis
|
||||||
(mkRemovedOptionModule [ "services" "redis" "user" ] "The redis module now is hardcoded to the redis user.")
|
(mkRemovedOptionModule [ "services" "redis" "user" ] "The redis module now is hardcoded to the redis user.")
|
||||||
(mkRemovedOptionModule [ "services" "redis" "dbpath" ] "The redis module now uses /var/lib/redis as data directory.")
|
(mkRemovedOptionModule [ "services" "redis" "dbpath" ] "The redis module now uses /var/lib/redis as data directory.")
|
||||||
|
@ -8,15 +8,11 @@ let
|
|||||||
|
|
||||||
mysql = cfg.package;
|
mysql = cfg.package;
|
||||||
|
|
||||||
isMariaDB =
|
isMariaDB = lib.getName mysql == lib.getName pkgs.mariadb;
|
||||||
let
|
|
||||||
pName = _p: (builtins.parseDrvName (_p.name)).name;
|
|
||||||
in pName mysql == pName pkgs.mariadb;
|
|
||||||
isMysqlAtLeast57 =
|
isMysqlAtLeast57 =
|
||||||
let
|
(lib.getName mysql == lib.getName pkgs.mysql57)
|
||||||
pName = _p: (builtins.parseDrvName (_p.name)).name;
|
&& (builtins.compareVersions mysql.version "5.7" >= 0);
|
||||||
in (pName mysql == pName pkgs.mysql57)
|
|
||||||
&& ((builtins.compareVersions mysql.version "5.7") >= 0);
|
|
||||||
|
|
||||||
mysqldOptions =
|
mysqldOptions =
|
||||||
"--user=${cfg.user} --datadir=${cfg.dataDir} --basedir=${mysql}";
|
"--user=${cfg.user} --datadir=${cfg.dataDir} --basedir=${mysql}";
|
||||||
|
@ -7,12 +7,17 @@ with lib;
|
|||||||
let
|
let
|
||||||
|
|
||||||
cfg = config.services.tumbler;
|
cfg = config.services.tumbler;
|
||||||
tumbler = cfg.package;
|
|
||||||
|
|
||||||
in
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
(mkRemovedOptionModule
|
||||||
|
[ "services" "tumbler" "package" ]
|
||||||
|
"")
|
||||||
|
];
|
||||||
|
|
||||||
###### interface
|
###### interface
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
@ -21,13 +26,6 @@ in
|
|||||||
|
|
||||||
enable = mkEnableOption "Tumbler, A D-Bus thumbnailer service";
|
enable = mkEnableOption "Tumbler, A D-Bus thumbnailer service";
|
||||||
|
|
||||||
package = mkOption {
|
|
||||||
type = types.package;
|
|
||||||
default = pkgs.xfce4-14.tumbler;
|
|
||||||
description = "Which tumbler package to use";
|
|
||||||
example = pkgs.xfce4-12.tumbler;
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -37,11 +35,11 @@ in
|
|||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
|
|
||||||
environment.systemPackages = [
|
environment.systemPackages = with pkgs.xfce; [
|
||||||
tumbler
|
tumbler
|
||||||
];
|
];
|
||||||
|
|
||||||
services.dbus.packages = [
|
services.dbus.packages = with pkgs.xfce; [
|
||||||
tumbler
|
tumbler
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ in
|
|||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
DynamicUser = true;
|
DynamicUser = true;
|
||||||
StateDirectory = "openarena";
|
StateDirectory = "openarena";
|
||||||
ExecStart = "${pkgs.openarena}/bin/openarena-server +set fs_basepath ${pkgs.openarena}/openarena-0.8.8 +set fs_homepath /var/lib/openarena ${concatStringsSep " " cfg.extraFlags}";
|
ExecStart = "${pkgs.openarena}/bin/oa_ded +set fs_basepath ${pkgs.openarena}/openarena-0.8.8 +set fs_homepath /var/lib/openarena ${concatStringsSep " " cfg.extraFlags}";
|
||||||
Restart = "on-failure";
|
Restart = "on-failure";
|
||||||
|
|
||||||
# Hardening
|
# Hardening
|
||||||
|
@ -74,7 +74,7 @@ in {
|
|||||||
default = false;
|
default = false;
|
||||||
description = ''
|
description = ''
|
||||||
Whether to enable test remote. This is used by
|
Whether to enable test remote. This is used by
|
||||||
<link xlink:href="https://github.com/hughsie/fwupd/blob/master/data/installed-tests/README.md">installed tests</link>.
|
<link xlink:href="https://github.com/fwupd/fwupd/blob/master/data/installed-tests/README.md">installed tests</link>.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -115,10 +115,6 @@ in {
|
|||||||
services.udev.packages = [ cfg.package ];
|
services.udev.packages = [ cfg.package ];
|
||||||
|
|
||||||
systemd.packages = [ cfg.package ];
|
systemd.packages = [ cfg.package ];
|
||||||
|
|
||||||
systemd.tmpfiles.rules = [
|
|
||||||
"d /var/lib/fwupd 0755 root root -"
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
meta = {
|
meta = {
|
||||||
|
@ -37,7 +37,7 @@ in
|
|||||||
enable = mkOption {
|
enable = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
description = "Whether to enable the TLP daemon.";
|
description = "Whether to enable the TLP power management daemon.";
|
||||||
};
|
};
|
||||||
|
|
||||||
extraConfig = mkOption {
|
extraConfig = mkOption {
|
||||||
|
@ -25,6 +25,13 @@ in
|
|||||||
description = "The port address of the http server.";
|
description = "The port address of the http server.";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
http.path = mkOption {
|
||||||
|
type = with types; nullOr str;
|
||||||
|
default = null;
|
||||||
|
description = "Prefix to all HTTP paths.";
|
||||||
|
example = "/mailcatcher";
|
||||||
|
};
|
||||||
|
|
||||||
smtp.ip = mkOption {
|
smtp.ip = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "127.0.0.1";
|
default = "127.0.0.1";
|
||||||
@ -53,7 +60,7 @@ in
|
|||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
DynamicUser = true;
|
DynamicUser = true;
|
||||||
Restart = "always";
|
Restart = "always";
|
||||||
ExecStart = "${pkgs.mailcatcher}/bin/mailcatcher --foreground --no-quit --http-ip ${cfg.http.ip} --http-port ${toString cfg.http.port} --smtp-ip ${cfg.smtp.ip} --smtp-port ${toString cfg.smtp.port}";
|
ExecStart = "${pkgs.mailcatcher}/bin/mailcatcher --foreground --no-quit --http-ip ${cfg.http.ip} --http-port ${toString cfg.http.port} --smtp-ip ${cfg.smtp.ip} --smtp-port ${toString cfg.smtp.port}" + optionalString (cfg.http.path != null) " --http-path ${cfg.http.path}";
|
||||||
AmbientCapabilities = optionalString (cfg.http.port < 1024 || cfg.smtp.port < 1024) "cap_net_bind_service";
|
AmbientCapabilities = optionalString (cfg.http.port < 1024 || cfg.smtp.port < 1024) "cap_net_bind_service";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -160,7 +160,7 @@ in
|
|||||||
${pkgs.sudo}/bin/sudo -u ${pgSuperUser} psql postgres -c "create role ${cfg.database.username} with login password '${cfg.database.password}'";
|
${pkgs.sudo}/bin/sudo -u ${pgSuperUser} psql postgres -c "create role ${cfg.database.username} with login password '${cfg.database.password}'";
|
||||||
${pkgs.sudo}/bin/sudo -u ${pgSuperUser} psql postgres -c "create database ${cfg.database.dbname} with owner ${cfg.database.username}";
|
${pkgs.sudo}/bin/sudo -u ${pgSuperUser} psql postgres -c "create database ${cfg.database.dbname} with owner ${cfg.database.username}";
|
||||||
fi
|
fi
|
||||||
PGPASSWORD=${cfg.database.password} ${pkgs.postgresql}/bin/psql -U ${cfg.database.username} \
|
PGPASSWORD="${cfg.database.password}" ${pkgs.postgresql}/bin/psql -U ${cfg.database.username} \
|
||||||
-f ${cfg.package}/SQL/postgres.initial.sql \
|
-f ${cfg.package}/SQL/postgres.initial.sql \
|
||||||
-h ${cfg.database.host} ${cfg.database.dbname}
|
-h ${cfg.database.host} ${cfg.database.dbname}
|
||||||
touch /var/lib/roundcube/db-created
|
touch /var/lib/roundcube/db-created
|
||||||
|
@ -60,7 +60,7 @@ let
|
|||||||
};
|
};
|
||||||
type = mkOption {
|
type = mkOption {
|
||||||
type = types.nullOr (types.enum [
|
type = types.nullOr (types.enum [
|
||||||
"normal" "controller" "fuzzy_storage" "rspamd_proxy" "lua" "proxy"
|
"normal" "controller" "fuzzy" "rspamd_proxy" "lua" "proxy"
|
||||||
]);
|
]);
|
||||||
description = ''
|
description = ''
|
||||||
The type of this worker. The type <literal>proxy</literal> is
|
The type of this worker. The type <literal>proxy</literal> is
|
||||||
|
@ -44,7 +44,8 @@ in
|
|||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
DynamicUser = true;
|
DynamicUser = true;
|
||||||
Restart = "always";
|
Restart = "always";
|
||||||
ExecStart = "${pkg}/bin/beanstalkd -l ${cfg.listen.address} -p ${toString cfg.listen.port}";
|
ExecStart = "${pkg}/bin/beanstalkd -l ${cfg.listen.address} -p ${toString cfg.listen.port} -b $STATE_DIRECTORY";
|
||||||
|
StateDirectory = "beanstalkd";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,91 +0,0 @@
|
|||||||
{ config, lib, pkgs, ... }:
|
|
||||||
|
|
||||||
with builtins;
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
|
||||||
cfg = config.services.osquery;
|
|
||||||
|
|
||||||
in
|
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
options = {
|
|
||||||
|
|
||||||
services.osquery = {
|
|
||||||
|
|
||||||
enable = mkEnableOption "osquery";
|
|
||||||
|
|
||||||
loggerPath = mkOption {
|
|
||||||
type = types.path;
|
|
||||||
description = "Base directory used for logging.";
|
|
||||||
default = "/var/log/osquery";
|
|
||||||
};
|
|
||||||
|
|
||||||
pidfile = mkOption {
|
|
||||||
type = types.path;
|
|
||||||
description = "Path used for pid file.";
|
|
||||||
default = "/var/osquery/osqueryd.pidfile";
|
|
||||||
};
|
|
||||||
|
|
||||||
utc = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
description = "Attempt to convert all UNIX calendar times to UTC.";
|
|
||||||
default = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
databasePath = mkOption {
|
|
||||||
type = types.path;
|
|
||||||
description = "Path used for database file.";
|
|
||||||
default = "/var/osquery/osquery.db";
|
|
||||||
};
|
|
||||||
|
|
||||||
extraConfig = mkOption {
|
|
||||||
type = types.attrs // {
|
|
||||||
merge = loc: foldl' (res: def: recursiveUpdate res def.value) {};
|
|
||||||
};
|
|
||||||
description = "Extra config to be recursively merged into the JSON config file.";
|
|
||||||
default = { };
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
|
|
||||||
environment.systemPackages = [ pkgs.osquery ];
|
|
||||||
|
|
||||||
environment.etc."osquery/osquery.conf".text = toJSON (
|
|
||||||
recursiveUpdate {
|
|
||||||
options = {
|
|
||||||
config_plugin = "filesystem";
|
|
||||||
logger_plugin = "filesystem";
|
|
||||||
logger_path = cfg.loggerPath;
|
|
||||||
database_path = cfg.databasePath;
|
|
||||||
utc = cfg.utc;
|
|
||||||
};
|
|
||||||
} cfg.extraConfig
|
|
||||||
);
|
|
||||||
|
|
||||||
systemd.services.osqueryd = {
|
|
||||||
description = "The osquery Daemon";
|
|
||||||
after = [ "network.target" "syslog.service" ];
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
path = [ pkgs.osquery ];
|
|
||||||
preStart = ''
|
|
||||||
mkdir -p ${escapeShellArg cfg.loggerPath}
|
|
||||||
mkdir -p "$(dirname ${escapeShellArg cfg.pidfile})"
|
|
||||||
mkdir -p "$(dirname ${escapeShellArg cfg.databasePath})"
|
|
||||||
'';
|
|
||||||
serviceConfig = {
|
|
||||||
TimeoutStartSec = "infinity";
|
|
||||||
ExecStart = "${pkgs.osquery}/bin/osqueryd --logger_path ${escapeShellArg cfg.loggerPath} --pidfile ${escapeShellArg cfg.pidfile} --database_path ${escapeShellArg cfg.databasePath}";
|
|
||||||
KillMode = "process";
|
|
||||||
KillSignal = "SIGTERM";
|
|
||||||
Restart = "on-failure";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
@ -1,357 +0,0 @@
|
|||||||
{ config, lib, pkgs, ...} :
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
|
||||||
cfg = config.services.beegfs;
|
|
||||||
|
|
||||||
# functions for the generations of config files
|
|
||||||
|
|
||||||
configMgmtd = name: cfg: pkgs.writeText "mgmt-${name}.conf" ''
|
|
||||||
storeMgmtdDirectory = ${cfg.mgmtd.storeDir}
|
|
||||||
storeAllowFirstRunInit = false
|
|
||||||
connAuthFile = ${cfg.connAuthFile}
|
|
||||||
connPortShift = ${toString cfg.connPortShift}
|
|
||||||
|
|
||||||
${cfg.mgmtd.extraConfig}
|
|
||||||
'';
|
|
||||||
|
|
||||||
configAdmon = name: cfg: pkgs.writeText "admon-${name}.conf" ''
|
|
||||||
sysMgmtdHost = ${cfg.mgmtdHost}
|
|
||||||
connAuthFile = ${cfg.connAuthFile}
|
|
||||||
connPortShift = ${toString cfg.connPortShift}
|
|
||||||
|
|
||||||
${cfg.admon.extraConfig}
|
|
||||||
'';
|
|
||||||
|
|
||||||
configMeta = name: cfg: pkgs.writeText "meta-${name}.conf" ''
|
|
||||||
storeMetaDirectory = ${cfg.meta.storeDir}
|
|
||||||
sysMgmtdHost = ${cfg.mgmtdHost}
|
|
||||||
connAuthFile = ${cfg.connAuthFile}
|
|
||||||
connPortShift = ${toString cfg.connPortShift}
|
|
||||||
storeAllowFirstRunInit = false
|
|
||||||
|
|
||||||
${cfg.meta.extraConfig}
|
|
||||||
'';
|
|
||||||
|
|
||||||
configStorage = name: cfg: pkgs.writeText "storage-${name}.conf" ''
|
|
||||||
storeStorageDirectory = ${cfg.storage.storeDir}
|
|
||||||
sysMgmtdHost = ${cfg.mgmtdHost}
|
|
||||||
connAuthFile = ${cfg.connAuthFile}
|
|
||||||
connPortShift = ${toString cfg.connPortShift}
|
|
||||||
storeAllowFirstRunInit = false
|
|
||||||
|
|
||||||
${cfg.storage.extraConfig}
|
|
||||||
'';
|
|
||||||
|
|
||||||
configHelperd = name: cfg: pkgs.writeText "helperd-${name}.conf" ''
|
|
||||||
connAuthFile = ${cfg.connAuthFile}
|
|
||||||
${cfg.helperd.extraConfig}
|
|
||||||
'';
|
|
||||||
|
|
||||||
configClientFilename = name : "/etc/beegfs/client-${name}.conf";
|
|
||||||
|
|
||||||
configClient = name: cfg: ''
|
|
||||||
sysMgmtdHost = ${cfg.mgmtdHost}
|
|
||||||
connAuthFile = ${cfg.connAuthFile}
|
|
||||||
connPortShift = ${toString cfg.connPortShift}
|
|
||||||
|
|
||||||
${cfg.client.extraConfig}
|
|
||||||
'';
|
|
||||||
|
|
||||||
serviceList = [
|
|
||||||
{ service = "admon"; cfgFile = configAdmon; }
|
|
||||||
{ service = "meta"; cfgFile = configMeta; }
|
|
||||||
{ service = "mgmtd"; cfgFile = configMgmtd; }
|
|
||||||
{ service = "storage"; cfgFile = configStorage; }
|
|
||||||
];
|
|
||||||
|
|
||||||
# functions to generate systemd.service entries
|
|
||||||
|
|
||||||
systemdEntry = service: cfgFile: (mapAttrs' ( name: cfg:
|
|
||||||
(nameValuePair "beegfs-${service}-${name}" (mkIf cfg.${service}.enable {
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
requires = [ "network-online.target" ];
|
|
||||||
after = [ "network-online.target" ];
|
|
||||||
serviceConfig = rec {
|
|
||||||
ExecStart = ''
|
|
||||||
${pkgs.beegfs}/bin/beegfs-${service} \
|
|
||||||
cfgFile=${cfgFile name cfg} \
|
|
||||||
pidFile=${PIDFile}
|
|
||||||
'';
|
|
||||||
PIDFile = "/run/beegfs-${service}-${name}.pid";
|
|
||||||
TimeoutStopSec = "300";
|
|
||||||
};
|
|
||||||
}))) cfg);
|
|
||||||
|
|
||||||
systemdHelperd = mapAttrs' ( name: cfg:
|
|
||||||
(nameValuePair "beegfs-helperd-${name}" (mkIf cfg.client.enable {
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
requires = [ "network-online.target" ];
|
|
||||||
after = [ "network-online.target" ];
|
|
||||||
serviceConfig = rec {
|
|
||||||
ExecStart = ''
|
|
||||||
${pkgs.beegfs}/bin/beegfs-helperd \
|
|
||||||
cfgFile=${configHelperd name cfg} \
|
|
||||||
pidFile=${PIDFile}
|
|
||||||
'';
|
|
||||||
PIDFile = "/run/beegfs-helperd-${name}.pid";
|
|
||||||
TimeoutStopSec = "300";
|
|
||||||
};
|
|
||||||
}))) cfg;
|
|
||||||
|
|
||||||
# wrappers to beegfs tools. Avoid typing path of config files
|
|
||||||
utilWrappers = mapAttrsToList ( name: cfg:
|
|
||||||
( pkgs.runCommand "beegfs-utils-${name}" {
|
|
||||||
nativeBuildInputs = [ pkgs.makeWrapper ];
|
|
||||||
preferLocalBuild = true;
|
|
||||||
} ''
|
|
||||||
mkdir -p $out/bin
|
|
||||||
|
|
||||||
makeWrapper ${pkgs.beegfs}/bin/beegfs-check-servers \
|
|
||||||
$out/bin/beegfs-check-servers-${name} \
|
|
||||||
--add-flags "-c ${configClientFilename name}" \
|
|
||||||
--prefix PATH : ${lib.makeBinPath [ pkgs.beegfs ]}
|
|
||||||
|
|
||||||
makeWrapper ${pkgs.beegfs}/bin/beegfs-ctl \
|
|
||||||
$out/bin/beegfs-ctl-${name} \
|
|
||||||
--add-flags "--cfgFile=${configClientFilename name}"
|
|
||||||
|
|
||||||
makeWrapper ${pkgs.beegfs}/bin/beegfs-ctl \
|
|
||||||
$out/bin/beegfs-df-${name} \
|
|
||||||
--add-flags "--cfgFile=${configClientFilename name}" \
|
|
||||||
--add-flags --listtargets \
|
|
||||||
--add-flags --hidenodeid \
|
|
||||||
--add-flags --pools \
|
|
||||||
--add-flags --spaceinfo
|
|
||||||
|
|
||||||
makeWrapper ${pkgs.beegfs}/bin/beegfs-fsck \
|
|
||||||
$out/bin/beegfs-fsck-${name} \
|
|
||||||
--add-flags "--cfgFile=${configClientFilename name}"
|
|
||||||
''
|
|
||||||
)) cfg;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
###### interface
|
|
||||||
|
|
||||||
options = {
|
|
||||||
services.beegfsEnable = mkEnableOption "BeeGFS";
|
|
||||||
|
|
||||||
services.beegfs = mkOption {
|
|
||||||
default = {};
|
|
||||||
description = ''
|
|
||||||
BeeGFS configurations. Every mount point requires a separate configuration.
|
|
||||||
'';
|
|
||||||
type = with types; attrsOf (submodule ({ ... } : {
|
|
||||||
options = {
|
|
||||||
mgmtdHost = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = null;
|
|
||||||
example = "master";
|
|
||||||
description = ''Hostname of managament host.'';
|
|
||||||
};
|
|
||||||
|
|
||||||
connAuthFile = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "";
|
|
||||||
example = "/etc/my.key";
|
|
||||||
description = "File containing shared secret authentication.";
|
|
||||||
};
|
|
||||||
|
|
||||||
connPortShift = mkOption {
|
|
||||||
type = types.int;
|
|
||||||
default = 0;
|
|
||||||
example = 5;
|
|
||||||
description = ''
|
|
||||||
For each additional beegfs configuration shift all
|
|
||||||
service TCP/UDP ports by at least 5.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
client = {
|
|
||||||
enable = mkEnableOption "BeeGFS client";
|
|
||||||
|
|
||||||
mount = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = true;
|
|
||||||
description = "Create fstab entry automatically";
|
|
||||||
};
|
|
||||||
|
|
||||||
mountPoint = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "/run/beegfs";
|
|
||||||
description = ''
|
|
||||||
Mount point under which the beegfs filesytem should be mounted.
|
|
||||||
If mounted manually the mount option specifing the config file is needed:
|
|
||||||
cfgFile=/etc/beegfs/beegfs-client-<name>.conf
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
extraConfig = mkOption {
|
|
||||||
type = types.lines;
|
|
||||||
default = "";
|
|
||||||
description = ''
|
|
||||||
Additional lines for beegfs-client.conf.
|
|
||||||
See documentation for further details.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
helperd = {
|
|
||||||
enable = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = true;
|
|
||||||
description = ''
|
|
||||||
Enable the BeeGFS helperd.
|
|
||||||
The helpered is need for logging purposes on the client.
|
|
||||||
Disabling <literal>helperd</literal> allows for runing the client
|
|
||||||
with <literal>allowUnfree = false</literal>.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
extraConfig = mkOption {
|
|
||||||
type = types.lines;
|
|
||||||
default = "";
|
|
||||||
description = ''
|
|
||||||
Additional lines for beegfs-helperd.conf. See documentation
|
|
||||||
for further details.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
mgmtd = {
|
|
||||||
enable = mkEnableOption "BeeGFS mgmtd daemon";
|
|
||||||
|
|
||||||
storeDir = mkOption {
|
|
||||||
type = types.path;
|
|
||||||
default = null;
|
|
||||||
example = "/data/beegfs-mgmtd";
|
|
||||||
description = ''
|
|
||||||
Data directory for mgmtd.
|
|
||||||
Must not be shared with other beegfs daemons.
|
|
||||||
This directory must exist and it must be initialized
|
|
||||||
with beegfs-setup-mgmtd, e.g. "beegfs-setup-mgmtd -C -p <storeDir>"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
extraConfig = mkOption {
|
|
||||||
type = types.lines;
|
|
||||||
default = "";
|
|
||||||
description = ''
|
|
||||||
Additional lines for beegfs-mgmtd.conf. See documentation
|
|
||||||
for further details.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
admon = {
|
|
||||||
enable = mkEnableOption "BeeGFS admon daemon";
|
|
||||||
|
|
||||||
extraConfig = mkOption {
|
|
||||||
type = types.lines;
|
|
||||||
default = "";
|
|
||||||
description = ''
|
|
||||||
Additional lines for beegfs-admon.conf. See documentation
|
|
||||||
for further details.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
meta = {
|
|
||||||
enable = mkEnableOption "BeeGFS meta data daemon";
|
|
||||||
|
|
||||||
storeDir = mkOption {
|
|
||||||
type = types.path;
|
|
||||||
default = null;
|
|
||||||
example = "/data/beegfs-meta";
|
|
||||||
description = ''
|
|
||||||
Data directory for meta data service.
|
|
||||||
Must not be shared with other beegfs daemons.
|
|
||||||
The underlying filesystem must be mounted with xattr turned on.
|
|
||||||
This directory must exist and it must be initialized
|
|
||||||
with beegfs-setup-meta, e.g.
|
|
||||||
"beegfs-setup-meta -C -s <serviceID> -p <storeDir>"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
extraConfig = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "";
|
|
||||||
description = ''
|
|
||||||
Additional lines for beegfs-meta.conf. See documentation
|
|
||||||
for further details.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
storage = {
|
|
||||||
enable = mkEnableOption "BeeGFS storage daemon";
|
|
||||||
|
|
||||||
storeDir = mkOption {
|
|
||||||
type = types.path;
|
|
||||||
default = null;
|
|
||||||
example = "/data/beegfs-storage";
|
|
||||||
description = ''
|
|
||||||
Data directories for storage service.
|
|
||||||
Must not be shared with other beegfs daemons.
|
|
||||||
The underlying filesystem must be mounted with xattr turned on.
|
|
||||||
This directory must exist and it must be initialized
|
|
||||||
with beegfs-setup-storage, e.g.
|
|
||||||
"beegfs-setup-storage -C -s <serviceID> -i <storageTargetID> -p <storeDir>"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
extraConfig = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "";
|
|
||||||
description = ''
|
|
||||||
Addional lines for beegfs-storage.conf. See documentation
|
|
||||||
for further details.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
###### implementation
|
|
||||||
|
|
||||||
config =
|
|
||||||
mkIf config.services.beegfsEnable {
|
|
||||||
|
|
||||||
environment.systemPackages = utilWrappers;
|
|
||||||
|
|
||||||
# Put the client.conf files in /etc since they are needed
|
|
||||||
# by the commandline tools
|
|
||||||
environment.etc = mapAttrs' ( name: cfg:
|
|
||||||
(nameValuePair "beegfs/client-${name}.conf" (mkIf (cfg.client.enable)
|
|
||||||
{
|
|
||||||
enable = true;
|
|
||||||
text = configClient name cfg;
|
|
||||||
}))) cfg;
|
|
||||||
|
|
||||||
# Kernel module, we need it only once per host.
|
|
||||||
boot = mkIf (
|
|
||||||
foldr (a: b: a || b) false
|
|
||||||
(map (x: x.client.enable) (collect (x: x ? client) cfg)))
|
|
||||||
{
|
|
||||||
kernelModules = [ "beegfs" ];
|
|
||||||
extraModulePackages = [ pkgs.linuxPackages.beegfs-module ];
|
|
||||||
};
|
|
||||||
|
|
||||||
# generate fstab entries
|
|
||||||
fileSystems = mapAttrs' (name: cfg:
|
|
||||||
(nameValuePair cfg.client.mountPoint (optionalAttrs cfg.client.mount (mkIf cfg.client.enable {
|
|
||||||
device = "beegfs_nodev";
|
|
||||||
fsType = "beegfs";
|
|
||||||
mountPoint = cfg.client.mountPoint;
|
|
||||||
options = [ "cfgFile=${configClientFilename name}" "_netdev" ];
|
|
||||||
})))) cfg;
|
|
||||||
|
|
||||||
# generate systemd services
|
|
||||||
systemd.services = systemdHelperd //
|
|
||||||
foldr (a: b: a // b) {}
|
|
||||||
(map (x: systemdEntry x.service x.cfgFile) serviceList);
|
|
||||||
};
|
|
||||||
}
|
|
@ -78,7 +78,11 @@ in
|
|||||||
cacheNetworks = mkOption {
|
cacheNetworks = mkOption {
|
||||||
default = ["127.0.0.0/24"];
|
default = ["127.0.0.0/24"];
|
||||||
description = "
|
description = "
|
||||||
What networks are allowed to use us as a resolver.
|
What networks are allowed to use us as a resolver. Note
|
||||||
|
that this is for recursive queries -- all networks are
|
||||||
|
allowed to query zones configured with the `zones` option.
|
||||||
|
It is recommended that you limit cacheNetworks to avoid your
|
||||||
|
server being used for DNS amplification attacks.
|
||||||
";
|
";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -177,9 +177,6 @@ in {
|
|||||||
NoNewPrivileges = "true";
|
NoNewPrivileges = "true";
|
||||||
PrivateDevices = "true";
|
PrivateDevices = "true";
|
||||||
MemoryDenyWriteExecute = "true";
|
MemoryDenyWriteExecute = "true";
|
||||||
|
|
||||||
# Permission for preStart
|
|
||||||
PermissionsStartOnly = "true";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
users.users.${cfg.user} = {
|
users.users.${cfg.user} = {
|
||||||
|
@ -4,7 +4,7 @@ with pkgs;
|
|||||||
with lib;
|
with lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.networking.connman;
|
cfg = config.services.connman;
|
||||||
configFile = pkgs.writeText "connman.conf" ''
|
configFile = pkgs.writeText "connman.conf" ''
|
||||||
[General]
|
[General]
|
||||||
NetworkInterfaceBlacklist=${concatStringsSep "," cfg.networkInterfaceBlacklist}
|
NetworkInterfaceBlacklist=${concatStringsSep "," cfg.networkInterfaceBlacklist}
|
||||||
@ -17,7 +17,7 @@ in {
|
|||||||
|
|
||||||
options = {
|
options = {
|
||||||
|
|
||||||
networking.connman = {
|
services.connman = {
|
||||||
|
|
||||||
enable = mkOption {
|
enable = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
@ -71,13 +71,13 @@ in {
|
|||||||
|
|
||||||
assertions = [{
|
assertions = [{
|
||||||
assertion = !config.networking.useDHCP;
|
assertion = !config.networking.useDHCP;
|
||||||
message = "You can not use services.networking.connman with services.networking.useDHCP";
|
message = "You can not use services.connman with networking.useDHCP";
|
||||||
}{
|
}{
|
||||||
assertion = config.networking.wireless.enable;
|
assertion = config.networking.wireless.enable;
|
||||||
message = "You must use services.networking.connman with services.networking.wireless";
|
message = "You must use services.connman with networking.wireless";
|
||||||
}{
|
}{
|
||||||
assertion = !config.networking.networkmanager.enable;
|
assertion = !config.networking.networkmanager.enable;
|
||||||
message = "You can not use services.networking.connman with services.networking.networkmanager";
|
message = "You can not use services.connman with networking.networkmanager";
|
||||||
}];
|
}];
|
||||||
|
|
||||||
environment.systemPackages = [ connman ];
|
environment.systemPackages = [ connman ];
|
||||||
|
@ -23,6 +23,8 @@ in
|
|||||||
type = types.int;
|
type = types.int;
|
||||||
description = ''
|
description = ''
|
||||||
The port the server should listen on. Will use the server's default (2022) if not specified.
|
The port the server should listen on. Will use the server's default (2022) if not specified.
|
||||||
|
|
||||||
|
Make sure to open this port in the firewall if necessary.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -86,4 +88,8 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
maintainers = with lib.maintainers; [ pingiun ];
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ let
|
|||||||
fsWatcherEnabled = folder.watch;
|
fsWatcherEnabled = folder.watch;
|
||||||
fsWatcherDelayS = folder.watchDelay;
|
fsWatcherDelayS = folder.watchDelay;
|
||||||
ignorePerms = folder.ignorePerms;
|
ignorePerms = folder.ignorePerms;
|
||||||
|
versioning = folder.versioning;
|
||||||
}) (filterAttrs (
|
}) (filterAttrs (
|
||||||
_: folder:
|
_: folder:
|
||||||
folder.enable
|
folder.enable
|
||||||
@ -220,6 +221,69 @@ in {
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
versioning = mkOption {
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
How to keep changed/deleted files with syncthing.
|
||||||
|
There are 4 different types of versioning with different parameters.
|
||||||
|
See https://docs.syncthing.net/users/versioning.html
|
||||||
|
'';
|
||||||
|
example = [
|
||||||
|
{
|
||||||
|
versioning = {
|
||||||
|
type = "simple";
|
||||||
|
params.keep = "10";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
versioning = {
|
||||||
|
type = "trashcan";
|
||||||
|
params.cleanoutDays = "1000";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
versioning = {
|
||||||
|
type = "staggered";
|
||||||
|
params = {
|
||||||
|
cleanInterval = "3600";
|
||||||
|
maxAge = "31536000";
|
||||||
|
versionsPath = "/syncthing/backup";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
versioning = {
|
||||||
|
type = "external";
|
||||||
|
params.versionsPath = pkgs.writers.writeBash "backup" ''
|
||||||
|
folderpath="$1"
|
||||||
|
filepath="$2"
|
||||||
|
rm -rf "$folderpath/$filepath"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
type = with types; nullOr (submodule {
|
||||||
|
options = {
|
||||||
|
type = mkOption {
|
||||||
|
type = enum [ "external" "simple" "staggered" "trashcan" ];
|
||||||
|
description = ''
|
||||||
|
Type of versioning.
|
||||||
|
See https://docs.syncthing.net/users/versioning.html
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
params = mkOption {
|
||||||
|
type = attrsOf (either str path);
|
||||||
|
description = ''
|
||||||
|
Parameters for versioning. Structure depends on versioning.type.
|
||||||
|
See https://docs.syncthing.net/users/versioning.html
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
rescanInterval = mkOption {
|
rescanInterval = mkOption {
|
||||||
type = types.int;
|
type = types.int;
|
||||||
default = 3600;
|
default = 3600;
|
||||||
|
@ -239,7 +239,7 @@ in
|
|||||||
services.znc = {
|
services.znc = {
|
||||||
configFile = mkDefault (pkgs.writeText "znc-generated.conf" semanticString);
|
configFile = mkDefault (pkgs.writeText "znc-generated.conf" semanticString);
|
||||||
config = {
|
config = {
|
||||||
Version = (builtins.parseDrvName pkgs.znc.name).version;
|
Version = lib.getVersion pkgs.znc;
|
||||||
Listener.l.Port = mkDefault 5000;
|
Listener.l.Port = mkDefault 5000;
|
||||||
Listener.l.SSL = mkDefault true;
|
Listener.l.SSL = mkDefault true;
|
||||||
};
|
};
|
||||||
|
@ -390,6 +390,7 @@ in {
|
|||||||
in {
|
in {
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
before = [ "phpfpm-nextcloud.service" ];
|
before = [ "phpfpm-nextcloud.service" ];
|
||||||
|
path = [ occ ];
|
||||||
script = ''
|
script = ''
|
||||||
chmod og+x ${cfg.home}
|
chmod og+x ${cfg.home}
|
||||||
ln -sf ${pkgs.nextcloud}/apps ${cfg.home}/
|
ln -sf ${pkgs.nextcloud}/apps ${cfg.home}/
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# This file defines the options that can be used both for the Apache
|
# This file defines the options that can be used both for the Nginx
|
||||||
# main server configuration, and for the virtual hosts. (The latter
|
# main server configuration, and for the virtual hosts. (The latter
|
||||||
# has additional options that affect the web server as a whole, like
|
# has additional options that affect the web server as a whole, like
|
||||||
# the user/group to run under.)
|
# the user/group to run under.)
|
||||||
@ -92,4 +92,3 @@ with lib;
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# This file defines the options that can be used both for the Apache
|
# This file defines the options that can be used both for the Nginx
|
||||||
# main server configuration, and for the virtual hosts. (The latter
|
# main server configuration, and for the virtual hosts. (The latter
|
||||||
# has additional options that affect the web server as a whole, like
|
# has additional options that affect the web server as a whole, like
|
||||||
# the user/group to run under.)
|
# the user/group to run under.)
|
||||||
|
@ -262,6 +262,7 @@ in {
|
|||||||
in {
|
in {
|
||||||
Slice = "phpfpm.slice";
|
Slice = "phpfpm.slice";
|
||||||
PrivateDevices = true;
|
PrivateDevices = true;
|
||||||
|
PrivateTmp = true;
|
||||||
ProtectSystem = "full";
|
ProtectSystem = "full";
|
||||||
ProtectHome = true;
|
ProtectHome = true;
|
||||||
# XXX: We need AF_NETLINK to make the sendmail SUID binary from postfix work
|
# XXX: We need AF_NETLINK to make the sendmail SUID binary from postfix work
|
||||||
|
@ -18,7 +18,7 @@ in
|
|||||||
# determines the default: later modules (if enabled) are preferred.
|
# determines the default: later modules (if enabled) are preferred.
|
||||||
# E.g., if Plasma 5 is enabled, it supersedes xterm.
|
# E.g., if Plasma 5 is enabled, it supersedes xterm.
|
||||||
imports = [
|
imports = [
|
||||||
./none.nix ./xterm.nix ./xfce.nix ./xfce4-14.nix ./plasma5.nix ./lumina.nix
|
./none.nix ./xterm.nix ./xfce.nix ./plasma5.nix ./lumina.nix
|
||||||
./lxqt.nix ./enlightenment.nix ./gnome3.nix ./kodi.nix ./maxx.nix
|
./lxqt.nix ./enlightenment.nix ./gnome3.nix ./kodi.nix ./maxx.nix
|
||||||
./mate.nix ./pantheon.nix ./surf-display.nix
|
./mate.nix ./pantheon.nix ./surf-display.nix
|
||||||
];
|
];
|
||||||
|
@ -309,7 +309,7 @@ in
|
|||||||
gnome-shell
|
gnome-shell
|
||||||
gnome-shell-extensions
|
gnome-shell-extensions
|
||||||
gnome-themes-extra
|
gnome-themes-extra
|
||||||
gnome-user-docs
|
pkgs.gnome-user-docs
|
||||||
pkgs.orca
|
pkgs.orca
|
||||||
pkgs.glib # for gsettings
|
pkgs.glib # for gsettings
|
||||||
pkgs.gnome-menus
|
pkgs.gnome-menus
|
||||||
|
@ -27,20 +27,13 @@ in
|
|||||||
example = "vlc";
|
example = "vlc";
|
||||||
description = "Phonon audio backend to install.";
|
description = "Phonon audio backend to install.";
|
||||||
};
|
};
|
||||||
|
|
||||||
enableQt4Support = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = true;
|
|
||||||
description = ''
|
|
||||||
Enable support for Qt 4-based applications. Particularly, install a
|
|
||||||
default backend for Phonon.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
(mkRemovedOptionModule [ "services" "xserver" "desktopManager" "plasma5" "enableQt4Support" ] "Phonon no longer supports Qt 4.")
|
||||||
|
];
|
||||||
|
|
||||||
config = mkMerge [
|
config = mkMerge [
|
||||||
(mkIf cfg.enable {
|
(mkIf cfg.enable {
|
||||||
@ -173,9 +166,7 @@ in
|
|||||||
|
|
||||||
# Phonon audio backend
|
# Phonon audio backend
|
||||||
++ lib.optional (cfg.phononBackend == "gstreamer") libsForQt5.phonon-backend-gstreamer
|
++ lib.optional (cfg.phononBackend == "gstreamer") libsForQt5.phonon-backend-gstreamer
|
||||||
++ lib.optional (cfg.phononBackend == "gstreamer" && cfg.enableQt4Support) pkgs.phonon-backend-gstreamer
|
|
||||||
++ lib.optional (cfg.phononBackend == "vlc") libsForQt5.phonon-backend-vlc
|
++ lib.optional (cfg.phononBackend == "vlc") libsForQt5.phonon-backend-vlc
|
||||||
++ lib.optional (cfg.phononBackend == "vlc" && cfg.enableQt4Support) pkgs.phonon-backend-vlc
|
|
||||||
|
|
||||||
# Optional hardware support features
|
# Optional hardware support features
|
||||||
++ lib.optionals config.hardware.bluetooth.enable [ bluedevil bluez-qt ]
|
++ lib.optionals config.hardware.bluetooth.enable [ bluedevil bluez-qt ]
|
||||||
|
@ -7,6 +7,32 @@ let
|
|||||||
in
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
# added 2019-08-18
|
||||||
|
# needed to preserve some semblance of UI familarity
|
||||||
|
# with original XFCE module
|
||||||
|
(mkRenamedOptionModule
|
||||||
|
[ "services" "xserver" "desktopManager" "xfce4-14" "extraSessionCommands" ]
|
||||||
|
[ "services" "xserver" "displayManager" "sessionCommands" ])
|
||||||
|
|
||||||
|
# added 2019-11-04
|
||||||
|
# xfce4-14 module removed and promoted to xfce.
|
||||||
|
# Needed for configs that used xfce4-14 module to migrate to this one.
|
||||||
|
(mkRenamedOptionModule
|
||||||
|
[ "services" "xserver" "desktopManager" "xfce4-14" "enable" ]
|
||||||
|
[ "services" "xserver" "desktopManager" "xfce" "enable" ])
|
||||||
|
(mkRenamedOptionModule
|
||||||
|
[ "services" "xserver" "desktopManager" "xfce4-14" "noDesktop" ]
|
||||||
|
[ "services" "xserver" "desktopManager" "xfce" "noDesktop" ])
|
||||||
|
(mkRenamedOptionModule
|
||||||
|
[ "services" "xserver" "desktopManager" "xfce4-14" "enableXfwm" ]
|
||||||
|
[ "services" "xserver" "desktopManager" "xfce" "enableXfwm" ])
|
||||||
|
(mkRenamedOptionModule
|
||||||
|
[ "services" "xserver" "desktopManager" "xfce" "extraSessionCommands" ]
|
||||||
|
[ "services" "xserver" "displayManager" "sessionCommands" ])
|
||||||
|
];
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
services.xserver.desktopManager.xfce = {
|
services.xserver.desktopManager.xfce = {
|
||||||
enable = mkOption {
|
enable = mkOption {
|
||||||
@ -30,14 +56,6 @@ in
|
|||||||
description = "Don't install XFCE desktop components (xfdesktop, panel and notification daemon).";
|
description = "Don't install XFCE desktop components (xfdesktop, panel and notification daemon).";
|
||||||
};
|
};
|
||||||
|
|
||||||
extraSessionCommands = mkOption {
|
|
||||||
default = "";
|
|
||||||
type = types.lines;
|
|
||||||
description = ''
|
|
||||||
Shell commands executed just before XFCE is started.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
enableXfwm = mkOption {
|
enableXfwm = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = true;
|
default = true;
|
||||||
@ -48,76 +66,101 @@ in
|
|||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
environment.systemPackages = with pkgs.xfce // pkgs; [
|
environment.systemPackages = with pkgs.xfce // pkgs; [
|
||||||
# Get GTK themes and gtk-update-icon-cache
|
glib # for gsettings
|
||||||
gtk2.out
|
gtk3.out # gtk-update-icon-cache
|
||||||
|
|
||||||
# Supplies some abstract icons such as:
|
gnome3.gnome-themes-extra
|
||||||
# utilities-terminal, accessories-text-editor
|
|
||||||
gnome3.adwaita-icon-theme
|
gnome3.adwaita-icon-theme
|
||||||
|
|
||||||
hicolor-icon-theme
|
hicolor-icon-theme
|
||||||
tango-icon-theme
|
tango-icon-theme
|
||||||
xfce4-icon-theme
|
xfce4-icon-theme
|
||||||
|
|
||||||
|
desktop-file-utils
|
||||||
|
shared-mime-info # for update-mime-database
|
||||||
|
|
||||||
|
# For a polkit authentication agent
|
||||||
|
polkit_gnome
|
||||||
|
|
||||||
# Needed by Xfce's xinitrc script
|
# Needed by Xfce's xinitrc script
|
||||||
# TODO: replace with command -v
|
xdg-user-dirs # Update user dirs as described in https://freedesktop.org/wiki/Software/xdg-user-dirs/
|
||||||
which
|
|
||||||
|
|
||||||
exo
|
exo
|
||||||
garcon
|
garcon
|
||||||
gtk-xfce-engine
|
|
||||||
libxfce4ui
|
libxfce4ui
|
||||||
tumbler
|
|
||||||
xfconf
|
xfconf
|
||||||
|
|
||||||
mousepad
|
mousepad
|
||||||
|
parole
|
||||||
ristretto
|
ristretto
|
||||||
xfce4-appfinder
|
xfce4-appfinder
|
||||||
xfce4-screenshooter
|
xfce4-screenshooter
|
||||||
xfce4-session
|
xfce4-session
|
||||||
xfce4-settings
|
xfce4-settings
|
||||||
|
xfce4-taskmanager
|
||||||
xfce4-terminal
|
xfce4-terminal
|
||||||
|
|
||||||
(thunar.override { thunarPlugins = cfg.thunarPlugins; })
|
(thunar.override { thunarPlugins = cfg.thunarPlugins; })
|
||||||
thunar-volman # TODO: drop
|
] # TODO: NetworkManager doesn't belong here
|
||||||
] ++ (if config.hardware.pulseaudio.enable
|
++ optional config.networking.networkmanager.enable networkmanagerapplet
|
||||||
then [ xfce4-mixer-pulse xfce4-volumed-pulse ]
|
++ optional config.powerManagement.enable xfce4-power-manager
|
||||||
else [ xfce4-mixer xfce4-volumed ])
|
++ optionals config.hardware.pulseaudio.enable [
|
||||||
# TODO: NetworkManager doesn't belong here
|
pavucontrol
|
||||||
++ optionals config.networking.networkmanager.enable [ networkmanagerapplet ]
|
# volume up/down keys support:
|
||||||
++ optionals config.powerManagement.enable [ xfce4-power-manager ]
|
# xfce4-pulseaudio-plugin includes all the functionalities of xfce4-volumed-pulse
|
||||||
++ optionals cfg.enableXfwm [ xfwm4 ]
|
# but can only be used with xfce4-panel, so for no-desktop usage we still include
|
||||||
++ optionals (!cfg.noDesktop) [
|
# xfce4-volumed-pulse
|
||||||
xfce4-panel
|
(if cfg.noDesktop then xfce4-volumed-pulse else xfce4-pulseaudio-plugin)
|
||||||
|
] ++ optionals cfg.enableXfwm [
|
||||||
|
xfwm4
|
||||||
|
xfwm4-themes
|
||||||
|
] ++ optionals (!cfg.noDesktop) [
|
||||||
xfce4-notifyd
|
xfce4-notifyd
|
||||||
|
xfce4-panel
|
||||||
xfdesktop
|
xfdesktop
|
||||||
];
|
];
|
||||||
|
|
||||||
environment.pathsToLink = [
|
environment.pathsToLink = [
|
||||||
"/share/xfce4"
|
"/share/xfce4"
|
||||||
"/share/themes"
|
"/lib/xfce4"
|
||||||
"/share/gtksourceview-2.0"
|
"/share/gtksourceview-3.0"
|
||||||
|
"/share/gtksourceview-4.0"
|
||||||
];
|
];
|
||||||
|
|
||||||
services.xserver.gdk-pixbuf.modulePackages = [ pkgs.librsvg ];
|
|
||||||
|
|
||||||
services.xserver.desktopManager.session = [{
|
services.xserver.desktopManager.session = [{
|
||||||
name = "xfce";
|
name = "xfce";
|
||||||
bgSupport = true;
|
bgSupport = true;
|
||||||
start = ''
|
start = ''
|
||||||
${cfg.extraSessionCommands}
|
${pkgs.runtimeShell} ${pkgs.xfce.xfce4-session.xinitrc} &
|
||||||
|
|
||||||
${pkgs.runtimeShell} ${pkgs.xfce.xinitrc} &
|
|
||||||
waitPID=$!
|
waitPID=$!
|
||||||
'';
|
'';
|
||||||
}];
|
}];
|
||||||
|
|
||||||
services.xserver.updateDbusEnvironment = true;
|
services.xserver.updateDbusEnvironment = true;
|
||||||
|
services.xserver.gdk-pixbuf.modulePackages = [ pkgs.librsvg ];
|
||||||
|
|
||||||
# Enable helpful DBus services.
|
# Enable helpful DBus services.
|
||||||
services.udisks2.enable = true;
|
services.udisks2.enable = true;
|
||||||
|
security.polkit.enable = true;
|
||||||
|
services.accounts-daemon.enable = true;
|
||||||
services.upower.enable = config.powerManagement.enable;
|
services.upower.enable = config.powerManagement.enable;
|
||||||
|
services.gnome3.glib-networking.enable = true;
|
||||||
services.gvfs.enable = true;
|
services.gvfs.enable = true;
|
||||||
services.gvfs.package = pkgs.xfce.gvfs;
|
services.gvfs.package = pkgs.xfce.gvfs;
|
||||||
|
services.tumbler.enable = true;
|
||||||
|
services.system-config-printer.enable = (mkIf config.services.printing.enable (mkDefault true));
|
||||||
|
services.xserver.libinput.enable = mkDefault true; # used in xfce4-settings-manager
|
||||||
|
|
||||||
|
# Enable default programs
|
||||||
|
programs.dconf.enable = true;
|
||||||
|
|
||||||
|
# Shell integration for VTE terminals
|
||||||
|
programs.bash.vteIntegration = mkDefault true;
|
||||||
|
programs.zsh.vteIntegration = mkDefault true;
|
||||||
|
|
||||||
|
# Systemd services
|
||||||
|
systemd.packages = with pkgs.xfce; [
|
||||||
|
(thunar.override { thunarPlugins = cfg.thunarPlugins; })
|
||||||
|
] ++ optional (!cfg.noDesktop) xfce4-notifyd;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,152 +0,0 @@
|
|||||||
{ config, lib, pkgs, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
|
||||||
cfg = config.services.xserver.desktopManager.xfce4-14;
|
|
||||||
in
|
|
||||||
|
|
||||||
{
|
|
||||||
# added 2019-08-18
|
|
||||||
# needed to preserve some semblance of UI familarity
|
|
||||||
# with original XFCE module
|
|
||||||
imports = [
|
|
||||||
(mkRenamedOptionModule
|
|
||||||
[ "services" "xserver" "desktopManager" "xfce4-14" "extraSessionCommands" ]
|
|
||||||
[ "services" "xserver" "displayManager" "sessionCommands" ])
|
|
||||||
];
|
|
||||||
|
|
||||||
options = {
|
|
||||||
services.xserver.desktopManager.xfce4-14 = {
|
|
||||||
enable = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = "Enable the Xfce desktop environment.";
|
|
||||||
};
|
|
||||||
|
|
||||||
# TODO: support thunar plugins
|
|
||||||
# thunarPlugins = mkOption {
|
|
||||||
# default = [];
|
|
||||||
# type = types.listOf types.package;
|
|
||||||
# example = literalExample "[ pkgs.xfce4-14.thunar-archive-plugin ]";
|
|
||||||
# description = ''
|
|
||||||
# A list of plugin that should be installed with Thunar.
|
|
||||||
# '';
|
|
||||||
# };
|
|
||||||
|
|
||||||
noDesktop = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = "Don't install XFCE desktop components (xfdesktop, panel and notification daemon).";
|
|
||||||
};
|
|
||||||
|
|
||||||
enableXfwm = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = true;
|
|
||||||
description = "Enable the XFWM (default) window manager.";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
environment.systemPackages = with pkgs.xfce4-14 // pkgs; [
|
|
||||||
glib # for gsettings
|
|
||||||
gtk3.out # gtk-update-icon-cache
|
|
||||||
|
|
||||||
gnome3.gnome-themes-extra
|
|
||||||
gnome3.adwaita-icon-theme
|
|
||||||
hicolor-icon-theme
|
|
||||||
tango-icon-theme
|
|
||||||
xfce4-icon-theme
|
|
||||||
|
|
||||||
desktop-file-utils
|
|
||||||
shared-mime-info # for update-mime-database
|
|
||||||
|
|
||||||
# For a polkit authentication agent
|
|
||||||
polkit_gnome
|
|
||||||
|
|
||||||
# Needed by Xfce's xinitrc script
|
|
||||||
xdg-user-dirs # Update user dirs as described in https://freedesktop.org/wiki/Software/xdg-user-dirs/
|
|
||||||
|
|
||||||
exo
|
|
||||||
garcon
|
|
||||||
libxfce4ui
|
|
||||||
xfconf
|
|
||||||
|
|
||||||
mousepad
|
|
||||||
parole
|
|
||||||
ristretto
|
|
||||||
xfce4-appfinder
|
|
||||||
xfce4-screenshooter
|
|
||||||
xfce4-session
|
|
||||||
xfce4-settings
|
|
||||||
xfce4-taskmanager
|
|
||||||
xfce4-terminal
|
|
||||||
|
|
||||||
# TODO: resync patch for plugins
|
|
||||||
#(thunar.override { thunarPlugins = cfg.thunarPlugins; })
|
|
||||||
thunar
|
|
||||||
] # TODO: NetworkManager doesn't belong here
|
|
||||||
++ optional config.networking.networkmanager.enable networkmanagerapplet
|
|
||||||
++ optional config.powerManagement.enable xfce4-power-manager
|
|
||||||
++ optionals config.hardware.pulseaudio.enable [
|
|
||||||
pavucontrol
|
|
||||||
# volume up/down keys support:
|
|
||||||
# xfce4-pulseaudio-plugin includes all the functionalities of xfce4-volumed-pulse
|
|
||||||
# but can only be used with xfce4-panel, so for no-desktop usage we still include
|
|
||||||
# xfce4-volumed-pulse
|
|
||||||
(if cfg.noDesktop then xfce4-volumed-pulse else xfce4-pulseaudio-plugin)
|
|
||||||
] ++ optionals cfg.enableXfwm [
|
|
||||||
xfwm4
|
|
||||||
xfwm4-themes
|
|
||||||
] ++ optionals (!cfg.noDesktop) [
|
|
||||||
xfce4-notifyd
|
|
||||||
xfce4-panel
|
|
||||||
xfdesktop
|
|
||||||
];
|
|
||||||
|
|
||||||
environment.pathsToLink = [
|
|
||||||
"/share/xfce4"
|
|
||||||
"/lib/xfce4"
|
|
||||||
"/share/gtksourceview-3.0"
|
|
||||||
"/share/gtksourceview-4.0"
|
|
||||||
];
|
|
||||||
|
|
||||||
services.xserver.desktopManager.session = [{
|
|
||||||
name = "xfce4-14";
|
|
||||||
bgSupport = true;
|
|
||||||
start = ''
|
|
||||||
${pkgs.runtimeShell} ${pkgs.xfce4-14.xinitrc} &
|
|
||||||
waitPID=$!
|
|
||||||
'';
|
|
||||||
}];
|
|
||||||
|
|
||||||
services.xserver.updateDbusEnvironment = true;
|
|
||||||
services.xserver.gdk-pixbuf.modulePackages = [ pkgs.librsvg ];
|
|
||||||
|
|
||||||
# Enable helpful DBus services.
|
|
||||||
services.udisks2.enable = true;
|
|
||||||
security.polkit.enable = true;
|
|
||||||
services.accounts-daemon.enable = true;
|
|
||||||
services.upower.enable = config.powerManagement.enable;
|
|
||||||
services.gnome3.glib-networking.enable = true;
|
|
||||||
services.gvfs.enable = true;
|
|
||||||
services.gvfs.package = pkgs.xfce.gvfs;
|
|
||||||
services.tumbler.enable = true;
|
|
||||||
services.system-config-printer.enable = (mkIf config.services.printing.enable (mkDefault true));
|
|
||||||
services.xserver.libinput.enable = mkDefault true; # used in xfce4-settings-manager
|
|
||||||
|
|
||||||
# Enable default programs
|
|
||||||
programs.dconf.enable = true;
|
|
||||||
|
|
||||||
# Shell integration for VTE terminals
|
|
||||||
programs.bash.vteIntegration = mkDefault true;
|
|
||||||
programs.zsh.vteIntegration = mkDefault true;
|
|
||||||
|
|
||||||
# Systemd services
|
|
||||||
systemd.packages = with pkgs.xfce4-14; [
|
|
||||||
thunar
|
|
||||||
] ++ optional (!cfg.noDesktop) xfce4-notifyd;
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
@ -31,6 +31,44 @@ let
|
|||||||
load-module module-position-event-sounds
|
load-module module-position-event-sounds
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
dmDefault = config.services.xserver.desktopManager.default;
|
||||||
|
wmDefault = config.services.xserver.windowManager.default;
|
||||||
|
hasDefaultUserSession = dmDefault != "none" || wmDefault != "none";
|
||||||
|
defaultSessionName = dmDefault + optionalString (wmDefault != "none") ("+" + wmDefault);
|
||||||
|
|
||||||
|
setSessionScript = pkgs.python3.pkgs.buildPythonApplication {
|
||||||
|
name = "set-session";
|
||||||
|
|
||||||
|
format = "other";
|
||||||
|
|
||||||
|
src = ./set-session.py;
|
||||||
|
|
||||||
|
dontUnpack = true;
|
||||||
|
|
||||||
|
strictDeps = false;
|
||||||
|
|
||||||
|
nativeBuildInputs = with pkgs; [
|
||||||
|
wrapGAppsHook
|
||||||
|
gobject-introspection
|
||||||
|
];
|
||||||
|
|
||||||
|
buildInputs = with pkgs; [
|
||||||
|
accountsservice
|
||||||
|
glib
|
||||||
|
];
|
||||||
|
|
||||||
|
propagatedBuildInputs = with pkgs.python3.pkgs; [
|
||||||
|
pygobject3
|
||||||
|
ordered-set
|
||||||
|
];
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out/bin
|
||||||
|
cp $src $out/bin/set-session
|
||||||
|
chmod +x $out/bin/set-session
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
in
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -156,6 +194,8 @@ in
|
|||||||
cat - > /run/gdm/.config/gnome-initial-setup-done <<- EOF
|
cat - > /run/gdm/.config/gnome-initial-setup-done <<- EOF
|
||||||
yes
|
yes
|
||||||
EOF
|
EOF
|
||||||
|
'' + optionalString hasDefaultUserSession ''
|
||||||
|
${setSessionScript}/bin/set-session ${defaultSessionName}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
86
nixos/modules/services/x11/display-managers/set-session.py
Executable file
86
nixos/modules/services/x11/display-managers/set-session.py
Executable file
@ -0,0 +1,86 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import gi, argparse, os, logging, sys
|
||||||
|
|
||||||
|
gi.require_version("AccountsService", "1.0")
|
||||||
|
from gi.repository import AccountsService, GLib
|
||||||
|
from ordered_set import OrderedSet
|
||||||
|
|
||||||
|
|
||||||
|
def get_session_file(session):
|
||||||
|
system_data_dirs = GLib.get_system_data_dirs()
|
||||||
|
|
||||||
|
session_dirs = OrderedSet(
|
||||||
|
os.path.join(data_dir, session)
|
||||||
|
for data_dir in system_data_dirs
|
||||||
|
for session in {"wayland-sessions", "xsessions"}
|
||||||
|
)
|
||||||
|
|
||||||
|
session_files = OrderedSet(
|
||||||
|
os.path.join(dir, session + ".desktop")
|
||||||
|
for dir in session_dirs
|
||||||
|
if os.path.exists(os.path.join(dir, session + ".desktop"))
|
||||||
|
)
|
||||||
|
|
||||||
|
# Deal with duplicate wayland-sessions and xsessions.
|
||||||
|
# Needed for the situation in gnome-session, where there's
|
||||||
|
# a xsession named the same as a wayland session.
|
||||||
|
if any(map(is_session_wayland, session_files)):
|
||||||
|
session_files = OrderedSet(
|
||||||
|
session for session in session_files if is_session_wayland(session)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
session_files = OrderedSet(
|
||||||
|
session for session in session_files if is_session_xsession(session)
|
||||||
|
)
|
||||||
|
|
||||||
|
if len(session_files) == 0:
|
||||||
|
logging.warning("No session files are found.")
|
||||||
|
sys.exit(0)
|
||||||
|
else:
|
||||||
|
return session_files[0]
|
||||||
|
|
||||||
|
|
||||||
|
def is_session_xsession(session_file):
|
||||||
|
return "/xsessions/" in session_file
|
||||||
|
|
||||||
|
|
||||||
|
def is_session_wayland(session_file):
|
||||||
|
return "/wayland-sessions/" in session_file
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description="Set session type for all normal users."
|
||||||
|
)
|
||||||
|
parser.add_argument("session", help="Name of session to set.")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
session = getattr(args, "session")
|
||||||
|
session_file = get_session_file(session)
|
||||||
|
|
||||||
|
user_manager = AccountsService.UserManager.get_default()
|
||||||
|
users = user_manager.list_users()
|
||||||
|
|
||||||
|
for user in users:
|
||||||
|
if user.is_system_account():
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
if is_session_wayland(session_file):
|
||||||
|
logging.debug(
|
||||||
|
f"Setting session name: {session}, as we found the existing wayland-session: {session_file}"
|
||||||
|
)
|
||||||
|
user.set_session(session)
|
||||||
|
elif is_session_xsession(session_file):
|
||||||
|
logging.debug(
|
||||||
|
f"Setting session name: {session}, as we found the existing xsession: {session_file}"
|
||||||
|
)
|
||||||
|
user.set_x_session(session)
|
||||||
|
else:
|
||||||
|
logging.error(f"Couldn't figure out session type for {session_file}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
@ -209,12 +209,12 @@ in {
|
|||||||
|
|
||||||
services.xserver.config =
|
services.xserver.config =
|
||||||
''
|
''
|
||||||
# Automatically enable the libinput driver for all touchpads.
|
# General libinput configuration.
|
||||||
|
# See CONFIGURATION DETAILS section of man:libinput(4).
|
||||||
Section "InputClass"
|
Section "InputClass"
|
||||||
Identifier "libinputConfiguration"
|
Identifier "libinputConfiguration"
|
||||||
MatchIsTouchpad "on"
|
MatchDriver "libinput"
|
||||||
${optionalString (cfg.dev != null) ''MatchDevicePath "${cfg.dev}"''}
|
${optionalString (cfg.dev != null) ''MatchDevicePath "${cfg.dev}"''}
|
||||||
Driver "libinput"
|
|
||||||
Option "AccelProfile" "${cfg.accelProfile}"
|
Option "AccelProfile" "${cfg.accelProfile}"
|
||||||
${optionalString (cfg.accelSpeed != null) ''Option "AccelSpeed" "${cfg.accelSpeed}"''}
|
${optionalString (cfg.accelSpeed != null) ''Option "AccelSpeed" "${cfg.accelSpeed}"''}
|
||||||
${optionalString (cfg.buttonMapping != null) ''Option "ButtonMapping" "${cfg.buttonMapping}"''}
|
${optionalString (cfg.buttonMapping != null) ''Option "ButtonMapping" "${cfg.buttonMapping}"''}
|
||||||
|
@ -47,8 +47,8 @@ let
|
|||||||
grub = f grub;
|
grub = f grub;
|
||||||
grubTarget = f (grub.grubTarget or "");
|
grubTarget = f (grub.grubTarget or "");
|
||||||
shell = "${pkgs.runtimeShell}";
|
shell = "${pkgs.runtimeShell}";
|
||||||
fullName = (builtins.parseDrvName realGrub.name).name;
|
fullName = lib.getName realGrub;
|
||||||
fullVersion = (builtins.parseDrvName realGrub.name).version;
|
fullVersion = lib.getVersion realGrub;
|
||||||
grubEfi = f grubEfi;
|
grubEfi = f grubEfi;
|
||||||
grubTargetEfi = if cfg.efiSupport && (cfg.version == 2) then f (grubEfi.grubTarget or "") else "";
|
grubTargetEfi = if cfg.efiSupport && (cfg.version == 2) then f (grubEfi.grubTarget or "") else "";
|
||||||
bootPath = args.path;
|
bootPath = args.path;
|
||||||
|
@ -10,7 +10,7 @@ let
|
|||||||
|
|
||||||
checkLink = checkUnitConfig "Link" [
|
checkLink = checkUnitConfig "Link" [
|
||||||
(assertOnlyFields [
|
(assertOnlyFields [
|
||||||
"Description" "Alias" "MACAddressPolicy" "MACAddress" "NamePolicy" "OriginalName"
|
"Description" "Alias" "MACAddressPolicy" "MACAddress" "NamePolicy" "Name" "OriginalName"
|
||||||
"MTUBytes" "BitsPerSecond" "Duplex" "AutoNegotiation" "WakeOnLan" "Port"
|
"MTUBytes" "BitsPerSecond" "Duplex" "AutoNegotiation" "WakeOnLan" "Port"
|
||||||
"TCPSegmentationOffload" "TCP6SegmentationOffload" "GenericSegmentationOffload"
|
"TCPSegmentationOffload" "TCP6SegmentationOffload" "GenericSegmentationOffload"
|
||||||
"GenericReceiveOffload" "LargeReceiveOffload" "RxChannels" "TxChannels"
|
"GenericReceiveOffload" "LargeReceiveOffload" "RxChannels" "TxChannels"
|
||||||
@ -201,7 +201,7 @@ let
|
|||||||
(assertValueOneOf "IPv6AcceptRA" boolValues)
|
(assertValueOneOf "IPv6AcceptRA" boolValues)
|
||||||
(assertValueOneOf "IPv4ProxyARP" boolValues)
|
(assertValueOneOf "IPv4ProxyARP" boolValues)
|
||||||
(assertValueOneOf "IPv6ProxyNDP" boolValues)
|
(assertValueOneOf "IPv6ProxyNDP" boolValues)
|
||||||
(assertValueOneOf "IPv6PrefixDelegation" boolValues)
|
(assertValueOneOf "IPv6PrefixDelegation" (boolValues ++ [ "dhcpv6" "static" ]))
|
||||||
(assertValueOneOf "ActiveSlave" boolValues)
|
(assertValueOneOf "ActiveSlave" boolValues)
|
||||||
(assertValueOneOf "PrimarySlave" boolValues)
|
(assertValueOneOf "PrimarySlave" boolValues)
|
||||||
(assertValueOneOf "ConfigureWithoutCarrier" boolValues)
|
(assertValueOneOf "ConfigureWithoutCarrier" boolValues)
|
||||||
@ -924,6 +924,8 @@ in
|
|||||||
|
|
||||||
config = mkIf config.systemd.network.enable {
|
config = mkIf config.systemd.network.enable {
|
||||||
|
|
||||||
|
users.users.systemd-network.group = "systemd-network";
|
||||||
|
|
||||||
systemd.additionalUpstreamSystemUnits = [
|
systemd.additionalUpstreamSystemUnits = [
|
||||||
"systemd-networkd.service" "systemd-networkd-wait-online.service"
|
"systemd-networkd.service" "systemd-networkd-wait-online.service"
|
||||||
];
|
];
|
||||||
|
@ -136,6 +136,8 @@ in
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
users.users.resolved.group = "systemd-resolve";
|
||||||
|
|
||||||
systemd.additionalUpstreamSystemUnits = [
|
systemd.additionalUpstreamSystemUnits = [
|
||||||
"systemd-resolved.service"
|
"systemd-resolved.service"
|
||||||
];
|
];
|
||||||
|
@ -20,6 +20,18 @@ with lib;
|
|||||||
The set of NTP servers from which to synchronise.
|
The set of NTP servers from which to synchronise.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
extraConfig = mkOption {
|
||||||
|
default = "";
|
||||||
|
type = types.lines;
|
||||||
|
example = ''
|
||||||
|
PollIntervalMaxSec=180
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
Extra config options for systemd-timesyncd. See
|
||||||
|
<link xlink:href="https://www.freedesktop.org/software/systemd/man/timesyncd.conf.html">
|
||||||
|
timesyncd.conf(5)</link> for available options.
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -35,9 +47,13 @@ with lib;
|
|||||||
environment.etc."systemd/timesyncd.conf".text = ''
|
environment.etc."systemd/timesyncd.conf".text = ''
|
||||||
[Time]
|
[Time]
|
||||||
NTP=${concatStringsSep " " config.services.timesyncd.servers}
|
NTP=${concatStringsSep " " config.services.timesyncd.servers}
|
||||||
|
${config.services.timesyncd.extraConfig}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
users.users.systemd-timesync.uid = config.ids.uids.systemd-timesync;
|
users.users.systemd-timesync = {
|
||||||
|
uid = config.ids.uids.systemd-timesync;
|
||||||
|
group = "systemd-timesync";
|
||||||
|
};
|
||||||
users.groups.systemd-timesync.gid = config.ids.gids.systemd-timesync;
|
users.groups.systemd-timesync.gid = config.ids.gids.systemd-timesync;
|
||||||
|
|
||||||
system.activationScripts.systemd-timesyncd-migration = mkIf (versionOlder config.system.stateVersion "19.09") ''
|
system.activationScripts.systemd-timesyncd-migration = mkIf (versionOlder config.system.stateVersion "19.09") ''
|
||||||
|
@ -149,7 +149,7 @@ let
|
|||||||
--setenv PATH="$PATH" \
|
--setenv PATH="$PATH" \
|
||||||
${optionalString cfg.ephemeral "--ephemeral"} \
|
${optionalString cfg.ephemeral "--ephemeral"} \
|
||||||
${if cfg.additionalCapabilities != null && cfg.additionalCapabilities != [] then
|
${if cfg.additionalCapabilities != null && cfg.additionalCapabilities != [] then
|
||||||
''--capability="${concatStringsSep " " cfg.additionalCapabilities}"'' else ""
|
''--capability="${concatStringsSep "," cfg.additionalCapabilities}"'' else ""
|
||||||
} \
|
} \
|
||||||
${if cfg.tmpfs != null && cfg.tmpfs != [] then
|
${if cfg.tmpfs != null && cfg.tmpfs != [] then
|
||||||
''--tmpfs=${concatStringsSep " --tmpfs=" cfg.tmpfs}'' else ""
|
''--tmpfs=${concatStringsSep " --tmpfs=" cfg.tmpfs}'' else ""
|
||||||
|
197
nixos/modules/virtualisation/digital-ocean-config.nix
Normal file
197
nixos/modules/virtualisation/digital-ocean-config.nix
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
{ config, pkgs, lib, modulesPath, ... }:
|
||||||
|
with lib;
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
(modulesPath + "/profiles/qemu-guest.nix")
|
||||||
|
(modulesPath + "/virtualisation/digital-ocean-init.nix")
|
||||||
|
];
|
||||||
|
options.virtualisation.digitalOcean = with types; {
|
||||||
|
setRootPassword = mkOption {
|
||||||
|
type = bool;
|
||||||
|
default = false;
|
||||||
|
example = true;
|
||||||
|
description = "Whether to set the root password from the Digital Ocean metadata";
|
||||||
|
};
|
||||||
|
setSshKeys = mkOption {
|
||||||
|
type = bool;
|
||||||
|
default = true;
|
||||||
|
example = true;
|
||||||
|
description = "Whether to fetch ssh keys from Digital Ocean";
|
||||||
|
};
|
||||||
|
seedEntropy = mkOption {
|
||||||
|
type = bool;
|
||||||
|
default = true;
|
||||||
|
example = true;
|
||||||
|
description = "Whether to run the kernel RNG entropy seeding script from the Digital Ocean vendor data";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
cfg = config.virtualisation.digitalOcean;
|
||||||
|
hostName = config.networking.hostName;
|
||||||
|
doMetadataFile = "/run/do-metadata/v1.json";
|
||||||
|
in mkMerge [{
|
||||||
|
fileSystems."/" = {
|
||||||
|
device = "/dev/disk/by-label/nixos";
|
||||||
|
autoResize = true;
|
||||||
|
fsType = "ext4";
|
||||||
|
};
|
||||||
|
boot = {
|
||||||
|
growPartition = true;
|
||||||
|
kernelParams = [ "console=ttyS0" "panic=1" "boot.panic_on_fail" ];
|
||||||
|
initrd.kernelModules = [ "virtio_scsi" ];
|
||||||
|
kernelModules = [ "virtio_pci" "virtio_net" ];
|
||||||
|
loader = {
|
||||||
|
grub.device = "/dev/vda";
|
||||||
|
timeout = 0;
|
||||||
|
grub.configurationLimit = 0;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
services.openssh = {
|
||||||
|
enable = mkDefault true;
|
||||||
|
passwordAuthentication = mkDefault false;
|
||||||
|
};
|
||||||
|
services.do-agent.enable = mkDefault true;
|
||||||
|
networking = {
|
||||||
|
hostName = mkDefault ""; # use Digital Ocean metadata server
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Check for and wait for the metadata server to become reachable.
|
||||||
|
* This serves as a dependency for all the other metadata services. */
|
||||||
|
systemd.services.digitalocean-metadata = {
|
||||||
|
path = [ pkgs.curl ];
|
||||||
|
description = "Get host metadata provided by Digitalocean";
|
||||||
|
script = ''
|
||||||
|
set -eu
|
||||||
|
DO_DELAY_ATTEMPTS=0
|
||||||
|
while ! curl -fsSL -o $RUNTIME_DIRECTORY/v1.json http://169.254.169.254/metadata/v1.json; do
|
||||||
|
DO_DELAY_ATTEMPTS=$((DO_DELAY_ATTEMPTS + 1))
|
||||||
|
if (( $DO_DELAY_ATTEMPTS >= $DO_DELAY_ATTEMPTS_MAX )); then
|
||||||
|
echo "giving up"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "metadata unavailable, trying again in 1s..."
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
chmod 600 $RUNTIME_DIRECTORY/v1.json
|
||||||
|
'';
|
||||||
|
environment = {
|
||||||
|
DO_DELAY_ATTEMPTS_MAX = "10";
|
||||||
|
};
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
RemainAfterExit = true;
|
||||||
|
RuntimeDirectory = "do-metadata";
|
||||||
|
RuntimeDirectoryPreserve = "yes";
|
||||||
|
};
|
||||||
|
unitConfig = {
|
||||||
|
ConditionPathExists = "!${doMetadataFile}";
|
||||||
|
After = [ "network-pre.target" ] ++
|
||||||
|
optional config.networking.dhcpcd.enable "dhcpcd.service" ++
|
||||||
|
optional config.systemd.network.enable "systemd-networkd.service";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Fetch the root password from the digital ocean metadata.
|
||||||
|
* There is no specific route for this, so we use jq to get
|
||||||
|
* it from the One Big JSON metadata blob */
|
||||||
|
systemd.services.digitalocean-set-root-password = mkIf cfg.setRootPassword {
|
||||||
|
path = [ pkgs.shadow pkgs.jq ];
|
||||||
|
description = "Set root password provided by Digitalocean";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
script = ''
|
||||||
|
set -eo pipefail
|
||||||
|
ROOT_PASSWORD=$(jq -er '.auth_key' ${doMetadataFile})
|
||||||
|
echo "root:$ROOT_PASSWORD" | chpasswd
|
||||||
|
mkdir -p /etc/do-metadata/set-root-password
|
||||||
|
'';
|
||||||
|
unitConfig = {
|
||||||
|
ConditionPathExists = "!/etc/do-metadata/set-root-password";
|
||||||
|
Before = optional config.services.openssh.enable "sshd.service";
|
||||||
|
After = [ "digitalocean-metadata.service" ];
|
||||||
|
Requires = [ "digitalocean-metadata.service" ];
|
||||||
|
};
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Set the hostname from Digital Ocean, unless the user configured it in
|
||||||
|
* the NixOS configuration. The cached metadata file isn't used here
|
||||||
|
* because the hostname is a mutable part of the droplet. */
|
||||||
|
systemd.services.digitalocean-set-hostname = mkIf (hostName == "") {
|
||||||
|
path = [ pkgs.curl pkgs.nettools ];
|
||||||
|
description = "Set hostname provided by Digitalocean";
|
||||||
|
wantedBy = [ "network.target" ];
|
||||||
|
script = ''
|
||||||
|
set -e
|
||||||
|
DIGITALOCEAN_HOSTNAME=$(curl -fsSL http://169.254.169.254/metadata/v1/hostname)
|
||||||
|
hostname "$DIGITALOCEAN_HOSTNAME"
|
||||||
|
if [[ ! -e /etc/hostname || -w /etc/hostname ]]; then
|
||||||
|
printf "%s\n" "$DIGITALOCEAN_HOSTNAME" > /etc/hostname
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
unitConfig = {
|
||||||
|
Before = [ "network.target" ];
|
||||||
|
After = [ "digitalocean-metadata.service" ];
|
||||||
|
Wants = [ "digitalocean-metadata.service" ];
|
||||||
|
};
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Fetch the ssh keys for root from Digital Ocean */
|
||||||
|
systemd.services.digitalocean-ssh-keys = mkIf cfg.setSshKeys {
|
||||||
|
description = "Set root ssh keys provided by Digital Ocean";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
path = [ pkgs.jq ];
|
||||||
|
script = ''
|
||||||
|
set -e
|
||||||
|
mkdir -m 0700 -p /root/.ssh
|
||||||
|
jq -er '.public_keys[]' ${doMetadataFile} > /root/.ssh/authorized_keys
|
||||||
|
chmod 600 /root/.ssh/authorized_keys
|
||||||
|
'';
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
RemainAfterExit = true;
|
||||||
|
};
|
||||||
|
unitConfig = {
|
||||||
|
ConditionPathExists = "!/root/.ssh/authorized_keys";
|
||||||
|
Before = optional config.services.openssh.enable "sshd.service";
|
||||||
|
After = [ "digitalocean-metadata.service" ];
|
||||||
|
Requires = [ "digitalocean-metadata.service" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Initialize the RNG by running the entropy-seed script from the
|
||||||
|
* Digital Ocean metadata
|
||||||
|
*/
|
||||||
|
systemd.services.digitalocean-entropy-seed = mkIf cfg.seedEntropy {
|
||||||
|
description = "Run the kernel RNG entropy seeding script from the Digital Ocean vendor data";
|
||||||
|
wantedBy = [ "network.target" ];
|
||||||
|
path = [ pkgs.jq pkgs.mpack ];
|
||||||
|
script = ''
|
||||||
|
set -eo pipefail
|
||||||
|
TEMPDIR=$(mktemp -d)
|
||||||
|
jq -er '.vendor_data' ${doMetadataFile} | munpack -tC $TEMPDIR
|
||||||
|
ENTROPY_SEED=$(grep -rl "DigitalOcean Entropy Seed script" $TEMPDIR)
|
||||||
|
${pkgs.runtimeShell} $ENTROPY_SEED
|
||||||
|
rm -rf $TEMPDIR
|
||||||
|
'';
|
||||||
|
unitConfig = {
|
||||||
|
Before = [ "network.target" ];
|
||||||
|
After = [ "digitalocean-metadata.service" ];
|
||||||
|
Requires = [ "digitalocean-metadata.service" ];
|
||||||
|
};
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
];
|
||||||
|
meta.maintainers = with maintainers; [ arianvp eamsden ];
|
||||||
|
}
|
||||||
|
|
69
nixos/modules/virtualisation/digital-ocean-image.nix
Normal file
69
nixos/modules/virtualisation/digital-ocean-image.nix
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.virtualisation.digitalOceanImage;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
|
||||||
|
imports = [ ./digital-ocean-config.nix ];
|
||||||
|
|
||||||
|
options = {
|
||||||
|
virtualisation.digitalOceanImage.diskSize = mkOption {
|
||||||
|
type = with types; int;
|
||||||
|
default = 4096;
|
||||||
|
description = ''
|
||||||
|
Size of disk image. Unit is MB.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
virtualisation.digitalOceanImage.configFile = mkOption {
|
||||||
|
type = with types; nullOr path;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
A path to a configuration file which will be placed at
|
||||||
|
<literal>/etc/nixos/configuration.nix</literal> and be used when switching
|
||||||
|
to a new configuration. If set to <literal>null</literal>, a default
|
||||||
|
configuration is used that imports
|
||||||
|
<literal>(modulesPath + "/virtualisation/digital-ocean-config.nix")</literal>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
virtualisation.digitalOceanImage.compressionMethod = mkOption {
|
||||||
|
type = types.enum [ "gzip" "bzip2" ];
|
||||||
|
default = "gzip";
|
||||||
|
example = "bzip2";
|
||||||
|
description = ''
|
||||||
|
Disk image compression method. Choose bzip2 to generate smaller images that
|
||||||
|
take longer to generate but will consume less metered storage space on your
|
||||||
|
Digital Ocean account.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#### implementation
|
||||||
|
config = {
|
||||||
|
|
||||||
|
system.build.digitalOceanImage = import ../../lib/make-disk-image.nix {
|
||||||
|
name = "digital-ocean-image";
|
||||||
|
format = "qcow2";
|
||||||
|
postVM = let
|
||||||
|
compress = {
|
||||||
|
"gzip" = "${pkgs.gzip}/bin/gzip";
|
||||||
|
"bzip2" = "${pkgs.bzip2}/bin/bzip2";
|
||||||
|
}.${cfg.compressionMethod};
|
||||||
|
in ''
|
||||||
|
${compress} $diskImage
|
||||||
|
'';
|
||||||
|
configFile = if cfg.configFile == null
|
||||||
|
then config.virtualisation.digitalOcean.defaultConfigFile
|
||||||
|
else cfg.configFile;
|
||||||
|
inherit (cfg) diskSize;
|
||||||
|
inherit config lib pkgs;
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
meta.maintainers = with maintainers; [ arianvp eamsden ];
|
||||||
|
|
||||||
|
}
|
95
nixos/modules/virtualisation/digital-ocean-init.nix
Normal file
95
nixos/modules/virtualisation/digital-ocean-init.nix
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.virtualisation.digitalOcean;
|
||||||
|
defaultConfigFile = pkgs.writeText "digitalocean-configuration.nix" ''
|
||||||
|
{ modulesPath, lib, ... }:
|
||||||
|
{
|
||||||
|
imports = lib.optional (builtins.pathExists ./do-userdata.nix) ./do-userdata.nix ++ [
|
||||||
|
(modulesPath + "/virtualisation/digital-ocean-config.nix")
|
||||||
|
];
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
in {
|
||||||
|
options.virtualisation.digitalOcean.rebuildFromUserData = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
example = true;
|
||||||
|
description = "Whether to reconfigure the system from Digital Ocean user data";
|
||||||
|
};
|
||||||
|
options.virtualisation.digitalOcean.defaultConfigFile = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
default = defaultConfigFile;
|
||||||
|
defaultText = ''
|
||||||
|
The default configuration imports user-data if applicable and
|
||||||
|
<literal>(modulesPath + "/virtualisation/digital-ocean-config.nix")</literal>.
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
A path to a configuration file which will be placed at
|
||||||
|
<literal>/etc/nixos/configuration.nix</literal> and be used when switching to
|
||||||
|
a new configuration.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
systemd.services.digitalocean-init = mkIf cfg.rebuildFromUserData {
|
||||||
|
description = "Reconfigure the system from Digital Ocean userdata on startup";
|
||||||
|
wantedBy = [ "network-online.target" ];
|
||||||
|
unitConfig = {
|
||||||
|
ConditionPathExists = "!/etc/nixos/do-userdata.nix";
|
||||||
|
After = [ "digitalocean-metadata.service" "network-online.target" ];
|
||||||
|
Requires = [ "digitalocean-metadata.service" ];
|
||||||
|
X-StopOnRemoval = false;
|
||||||
|
};
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
RemainAfterExit = true;
|
||||||
|
};
|
||||||
|
restartIfChanged = false;
|
||||||
|
path = [ pkgs.jq pkgs.gnused pkgs.gnugrep pkgs.systemd config.nix.package config.system.build.nixos-rebuild ];
|
||||||
|
environment = {
|
||||||
|
HOME = "/root";
|
||||||
|
NIX_PATH = concatStringsSep ":" [
|
||||||
|
"/nix/var/nix/profiles/per-user/root/channels/nixos"
|
||||||
|
"nixos-config=/etc/nixos/configuration.nix"
|
||||||
|
"/nix/var/nix/profiles/per-user/root/channels"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
script = ''
|
||||||
|
set -e
|
||||||
|
echo "attempting to fetch configuration from Digital Ocean user data..."
|
||||||
|
userData=$(mktemp)
|
||||||
|
if jq -er '.user_data' /run/do-metadata/v1.json > $userData; then
|
||||||
|
# If the user-data looks like it could be a nix expression,
|
||||||
|
# copy it over. Also, look for a magic three-hash comment and set
|
||||||
|
# that as the channel.
|
||||||
|
if nix-instantiate --parse $userData > /dev/null; then
|
||||||
|
channels="$(grep '^###' "$userData" | sed 's|###\s*||')"
|
||||||
|
printf "%s" "$channels" | while read channel; do
|
||||||
|
echo "writing channel: $channel"
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ -n "$channels" ]]; then
|
||||||
|
printf "%s" "$channels" > /root/.nix-channels
|
||||||
|
nix-channel --update
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "setting configuration from Digital Ocean user data"
|
||||||
|
cp "$userData" /etc/nixos/do-userdata.nix
|
||||||
|
if [[ ! -e /etc/nixos/configuration.nix ]]; then
|
||||||
|
install -m0644 ${cfg.defaultConfigFile} /etc/nixos/configuration.nix
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "user data does not appear to be a Nix expression; ignoring"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
nixos-rebuild switch
|
||||||
|
else
|
||||||
|
echo "no user data is available"
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
meta.maintainers = with maintainers; [ arianvp eamsden ];
|
||||||
|
}
|
@ -42,6 +42,9 @@ in {
|
|||||||
default = false;
|
default = false;
|
||||||
description = ''
|
description = ''
|
||||||
Whether to start racoon service for openvswitch.
|
Whether to start racoon service for openvswitch.
|
||||||
|
Supported only if openvswitch version is less than 2.6.0.
|
||||||
|
Use <literal>virtualisation.vswitch.package = pkgs.openvswitch-lts</literal>
|
||||||
|
for a version that supports ipsec over GRE.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -89,6 +92,13 @@ in {
|
|||||||
"${cfg.package}/share/openvswitch/vswitch.ovsschema"
|
"${cfg.package}/share/openvswitch/vswitch.ovsschema"
|
||||||
fi
|
fi
|
||||||
chmod -R +w /var/db/openvswitch
|
chmod -R +w /var/db/openvswitch
|
||||||
|
if ${cfg.package}/bin/ovsdb-tool needs-conversion /var/db/openvswitch/conf.db | grep -q "yes"
|
||||||
|
then
|
||||||
|
echo "Performing database upgrade"
|
||||||
|
${cfg.package}/bin/ovsdb-tool convert /var/db/openvswitch/conf.db
|
||||||
|
else
|
||||||
|
echo "Database already up to date"
|
||||||
|
fi
|
||||||
'';
|
'';
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
ExecStart =
|
ExecStart =
|
||||||
@ -133,7 +143,7 @@ in {
|
|||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
(mkIf cfg.ipsec {
|
(mkIf (cfg.ipsec && (versionOlder cfg.package.version "2.6.0")) {
|
||||||
services.racoon.enable = true;
|
services.racoon.enable = true;
|
||||||
services.racoon.configPath = "${runDir}/ipsec/etc/racoon/racoon.conf";
|
services.racoon.configPath = "${runDir}/ipsec/etc/racoon/racoon.conf";
|
||||||
|
|
||||||
@ -172,5 +182,4 @@ in {
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
})]));
|
})]));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -620,7 +620,7 @@ in
|
|||||||
|
|
||||||
# Wireless won't work in the VM.
|
# Wireless won't work in the VM.
|
||||||
networking.wireless.enable = mkVMOverride false;
|
networking.wireless.enable = mkVMOverride false;
|
||||||
networking.connman.enable = mkVMOverride false;
|
services.connman.enable = mkVMOverride false;
|
||||||
|
|
||||||
# Speed up booting by not waiting for ARP.
|
# Speed up booting by not waiting for ARP.
|
||||||
networking.dhcpcd.extraConfig = "noarp";
|
networking.dhcpcd.extraConfig = "noarp";
|
||||||
|
@ -136,7 +136,6 @@ in rec {
|
|||||||
(all nixos.tests.switchTest)
|
(all nixos.tests.switchTest)
|
||||||
(all nixos.tests.udisks2)
|
(all nixos.tests.udisks2)
|
||||||
(all nixos.tests.xfce)
|
(all nixos.tests.xfce)
|
||||||
(all nixos.tests.xfce4-14)
|
|
||||||
|
|
||||||
nixpkgs.tarball
|
nixpkgs.tarball
|
||||||
(all allSupportedNixpkgs.emacs)
|
(all allSupportedNixpkgs.emacs)
|
||||||
|
@ -28,7 +28,7 @@ in
|
|||||||
babeld = handleTest ./babeld.nix {};
|
babeld = handleTest ./babeld.nix {};
|
||||||
bcachefs = handleTestOn ["x86_64-linux"] ./bcachefs.nix {}; # linux-4.18.2018.10.12 is unsupported on aarch64
|
bcachefs = handleTestOn ["x86_64-linux"] ./bcachefs.nix {}; # linux-4.18.2018.10.12 is unsupported on aarch64
|
||||||
beanstalkd = handleTest ./beanstalkd.nix {};
|
beanstalkd = handleTest ./beanstalkd.nix {};
|
||||||
beegfs = handleTestOn ["x86_64-linux"] ./beegfs.nix {}; # beegfs is unsupported on aarch64
|
bees = handleTest ./bees.nix {};
|
||||||
bind = handleTest ./bind.nix {};
|
bind = handleTest ./bind.nix {};
|
||||||
bittorrent = handleTest ./bittorrent.nix {};
|
bittorrent = handleTest ./bittorrent.nix {};
|
||||||
#blivet = handleTest ./blivet.nix {}; # broken since 2017-07024
|
#blivet = handleTest ./blivet.nix {}; # broken since 2017-07024
|
||||||
@ -206,7 +206,6 @@ in
|
|||||||
openstack-image-metadata = (handleTestOn ["x86_64-linux"] ./openstack-image.nix {}).metadata or {};
|
openstack-image-metadata = (handleTestOn ["x86_64-linux"] ./openstack-image.nix {}).metadata or {};
|
||||||
orangefs = handleTest ./orangefs.nix {};
|
orangefs = handleTest ./orangefs.nix {};
|
||||||
os-prober = handleTestOn ["x86_64-linux"] ./os-prober.nix {};
|
os-prober = handleTestOn ["x86_64-linux"] ./os-prober.nix {};
|
||||||
osquery = handleTest ./osquery.nix {};
|
|
||||||
osrm-backend = handleTest ./osrm-backend.nix {};
|
osrm-backend = handleTest ./osrm-backend.nix {};
|
||||||
overlayfs = handleTest ./overlayfs.nix {};
|
overlayfs = handleTest ./overlayfs.nix {};
|
||||||
packagekit = handleTest ./packagekit.nix {};
|
packagekit = handleTest ./packagekit.nix {};
|
||||||
@ -285,7 +284,6 @@ in
|
|||||||
wordpress = handleTest ./wordpress.nix {};
|
wordpress = handleTest ./wordpress.nix {};
|
||||||
xautolock = handleTest ./xautolock.nix {};
|
xautolock = handleTest ./xautolock.nix {};
|
||||||
xfce = handleTest ./xfce.nix {};
|
xfce = handleTest ./xfce.nix {};
|
||||||
xfce4-14 = handleTest ./xfce4-14.nix {};
|
|
||||||
xmonad = handleTest ./xmonad.nix {};
|
xmonad = handleTest ./xmonad.nix {};
|
||||||
xrdp = handleTest ./xrdp.nix {};
|
xrdp = handleTest ./xrdp.nix {};
|
||||||
xss-lock = handleTest ./xss-lock.nix {};
|
xss-lock = handleTest ./xss-lock.nix {};
|
||||||
|
@ -1,115 +0,0 @@
|
|||||||
import ./make-test.nix ({ ... } :
|
|
||||||
|
|
||||||
let
|
|
||||||
connAuthFile="beegfs/auth-def.key";
|
|
||||||
|
|
||||||
client = { pkgs, ... } : {
|
|
||||||
networking.firewall.enable = false;
|
|
||||||
services.beegfsEnable = true;
|
|
||||||
services.beegfs.default = {
|
|
||||||
mgmtdHost = "mgmt";
|
|
||||||
connAuthFile = "/etc/${connAuthFile}";
|
|
||||||
client = {
|
|
||||||
mount = false;
|
|
||||||
enable = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
fileSystems = pkgs.lib.mkVMOverride # FIXME: this should be creatd by the module
|
|
||||||
[ { mountPoint = "/beegfs";
|
|
||||||
device = "default";
|
|
||||||
fsType = "beegfs";
|
|
||||||
options = [ "cfgFile=/etc/beegfs/client-default.conf" "_netdev" ];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
environment.etc.${connAuthFile} = {
|
|
||||||
enable = true;
|
|
||||||
text = "ThisIsALousySecret";
|
|
||||||
mode = "0600";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
server = service : { pkgs, ... } : {
|
|
||||||
networking.firewall.enable = false;
|
|
||||||
boot.initrd.postDeviceCommands = ''
|
|
||||||
${pkgs.e2fsprogs}/bin/mkfs.ext4 -L data /dev/vdb
|
|
||||||
'';
|
|
||||||
|
|
||||||
virtualisation.emptyDiskImages = [ 4096 ];
|
|
||||||
|
|
||||||
fileSystems = pkgs.lib.mkVMOverride
|
|
||||||
[ { mountPoint = "/data";
|
|
||||||
device = "/dev/disk/by-label/data";
|
|
||||||
fsType = "ext4";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [ beegfs ];
|
|
||||||
environment.etc.${connAuthFile} = {
|
|
||||||
enable = true;
|
|
||||||
text = "ThisIsALousySecret";
|
|
||||||
mode = "0600";
|
|
||||||
};
|
|
||||||
|
|
||||||
services.beegfsEnable = true;
|
|
||||||
services.beegfs.default = {
|
|
||||||
mgmtdHost = "mgmt";
|
|
||||||
connAuthFile = "/etc/${connAuthFile}";
|
|
||||||
${service} = {
|
|
||||||
enable = true;
|
|
||||||
storeDir = "/data";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
in
|
|
||||||
{
|
|
||||||
name = "beegfs";
|
|
||||||
|
|
||||||
nodes = {
|
|
||||||
meta = server "meta";
|
|
||||||
mgmt = server "mgmtd";
|
|
||||||
storage1 = server "storage";
|
|
||||||
storage2 = server "storage";
|
|
||||||
client1 = client;
|
|
||||||
client2 = client;
|
|
||||||
};
|
|
||||||
|
|
||||||
testScript = ''
|
|
||||||
# Initalize the data directories
|
|
||||||
$mgmt->waitForUnit("default.target");
|
|
||||||
$mgmt->succeed("beegfs-setup-mgmtd -C -f -p /data");
|
|
||||||
$mgmt->succeed("systemctl start beegfs-mgmtd-default");
|
|
||||||
|
|
||||||
$meta->waitForUnit("default.target");
|
|
||||||
$meta->succeed("beegfs-setup-meta -C -f -s 1 -p /data");
|
|
||||||
$meta->succeed("systemctl start beegfs-meta-default");
|
|
||||||
|
|
||||||
$storage1->waitForUnit("default.target");
|
|
||||||
$storage1->succeed("beegfs-setup-storage -C -f -s 1 -i 1 -p /data");
|
|
||||||
$storage1->succeed("systemctl start beegfs-storage-default");
|
|
||||||
|
|
||||||
$storage2->waitForUnit("default.target");
|
|
||||||
$storage2->succeed("beegfs-setup-storage -C -f -s 2 -i 2 -p /data");
|
|
||||||
$storage2->succeed("systemctl start beegfs-storage-default");
|
|
||||||
|
|
||||||
#
|
|
||||||
|
|
||||||
# Basic test
|
|
||||||
$client1->waitForUnit("beegfs.mount");
|
|
||||||
$client1->succeed("beegfs-check-servers-default");
|
|
||||||
$client1->succeed("echo test > /beegfs/test");
|
|
||||||
$client2->waitForUnit("beegfs.mount");
|
|
||||||
$client2->succeed("test -e /beegfs/test");
|
|
||||||
$client2->succeed("cat /beegfs/test | grep test");
|
|
||||||
|
|
||||||
# test raid0/stripping
|
|
||||||
$client1->succeed("dd if=/dev/urandom bs=1M count=10 of=/beegfs/striped");
|
|
||||||
$client2->succeed("cat /beegfs/striped > /dev/null");
|
|
||||||
|
|
||||||
# check if fs is still healthy
|
|
||||||
$client1->succeed("beegfs-fsck-default --checkfs");
|
|
||||||
'';
|
|
||||||
})
|
|
@ -1,4 +1,4 @@
|
|||||||
import ./make-test.nix ({ lib, ... }:
|
import ./make-test-python.nix ({ lib, pkgs, ... }:
|
||||||
{
|
{
|
||||||
name = "bees";
|
name = "bees";
|
||||||
|
|
||||||
@ -29,27 +29,34 @@ import ./make-test.nix ({ lib, ... }:
|
|||||||
|
|
||||||
testScript =
|
testScript =
|
||||||
let
|
let
|
||||||
withRetry = content: maxTests: sleepTime: ''
|
someContentIsShared = loc: pkgs.writeShellScript "some-content-is-shared" ''
|
||||||
max_tests=${lib.escapeShellArg maxTests}; sleep_time=${lib.escapeShellArg sleepTime}; for ((i=0; i<max_tests; i++)); do ${content} && exit 0; sleep "$sleep_time"; done; exit 1;
|
[[ $(btrfs fi du -s --raw ${lib.escapeShellArg loc}/dedup-me-{1,2} | awk 'BEGIN { count=0; } NR>1 && $3 == 0 { count++ } END { print count }') -eq 0 ]]
|
||||||
'';
|
'';
|
||||||
someContentIsShared = loc: ''[[ $(btrfs fi du -s --raw ${lib.escapeShellArg loc}/dedup-me-{1,2} | awk 'BEGIN { count=0; } NR>1 && $3 == 0 { count++ } END { print count }') -eq 0 ]]'';
|
|
||||||
in ''
|
in ''
|
||||||
# shut down the instance started by systemd at boot, so we can test our test procedure
|
# shut down the instance started by systemd at boot, so we can test our test procedure
|
||||||
$machine->succeed("systemctl stop beesd\@aux1.service");
|
machine.succeed("systemctl stop beesd@aux1.service")
|
||||||
|
|
||||||
$machine->succeed("dd if=/dev/urandom of=/aux1/dedup-me-1 bs=1M count=8");
|
machine.succeed(
|
||||||
$machine->succeed("cp --reflink=never /aux1/dedup-me-1 /aux1/dedup-me-2");
|
"dd if=/dev/urandom of=/aux1/dedup-me-1 bs=1M count=8",
|
||||||
$machine->succeed("cp --reflink=never /aux1/* /aux2/");
|
"cp --reflink=never /aux1/dedup-me-1 /aux1/dedup-me-2",
|
||||||
$machine->succeed("sync");
|
"cp --reflink=never /aux1/* /aux2/",
|
||||||
$machine->fail(q(${someContentIsShared "/aux1"}));
|
"sync",
|
||||||
$machine->fail(q(${someContentIsShared "/aux2"}));
|
)
|
||||||
$machine->succeed("systemctl start beesd\@aux1.service");
|
machine.fail(
|
||||||
|
"${someContentIsShared "/aux1"}",
|
||||||
|
"${someContentIsShared "/aux2"}",
|
||||||
|
)
|
||||||
|
machine.succeed("systemctl start beesd@aux1.service")
|
||||||
|
|
||||||
# assert that "Set Shared" column is nonzero
|
# assert that "Set Shared" column is nonzero
|
||||||
$machine->succeed(q(${withRetry (someContentIsShared "/aux1") 20 2}));
|
machine.wait_until_succeeds(
|
||||||
$machine->fail(q(${someContentIsShared "/aux2"}));
|
"${someContentIsShared "/aux1"}",
|
||||||
|
)
|
||||||
|
machine.fail("${someContentIsShared "/aux2"}")
|
||||||
|
|
||||||
# assert that 16MB hash table size requested was honored
|
# assert that 16MB hash table size requested was honored
|
||||||
$machine->succeed(q([[ $(stat -c %s /aux1/.beeshome/beeshash.dat) = $(( 16 * 1024 * 1024)) ]]))
|
machine.succeed(
|
||||||
|
"[[ $(stat -c %s /aux1/.beeshome/beeshash.dat) = $(( 16 * 1024 * 1024)) ]]"
|
||||||
|
)
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import ./make-test.nix ({pkgs, lib, ...}:
|
import ./make-test-python.nix ({pkgs, lib, ...}:
|
||||||
|
|
||||||
let
|
let
|
||||||
cfg = {
|
cfg = {
|
||||||
@ -109,14 +109,14 @@ let
|
|||||||
# For other ways to deploy a ceph cluster, look at the documentation at
|
# For other ways to deploy a ceph cluster, look at the documentation at
|
||||||
# https://docs.ceph.com/docs/master/
|
# https://docs.ceph.com/docs/master/
|
||||||
testscript = { ... }: ''
|
testscript = { ... }: ''
|
||||||
startAll;
|
start_all()
|
||||||
|
|
||||||
$monA->waitForUnit("network.target");
|
monA.wait_for_unit("network.target")
|
||||||
$osd0->waitForUnit("network.target");
|
osd0.wait_for_unit("network.target")
|
||||||
$osd1->waitForUnit("network.target");
|
osd1.wait_for_unit("network.target")
|
||||||
|
|
||||||
# Bootstrap ceph-mon daemon
|
# Bootstrap ceph-mon daemon
|
||||||
$monA->mustSucceed(
|
monA.succeed(
|
||||||
"sudo -u ceph ceph-authtool --create-keyring /tmp/ceph.mon.keyring --gen-key -n mon. --cap mon 'allow *'",
|
"sudo -u ceph ceph-authtool --create-keyring /tmp/ceph.mon.keyring --gen-key -n mon. --cap mon 'allow *'",
|
||||||
"sudo -u ceph ceph-authtool --create-keyring /etc/ceph/ceph.client.admin.keyring --gen-key -n client.admin --cap mon 'allow *' --cap osd 'allow *' --cap mds 'allow *' --cap mgr 'allow *'",
|
"sudo -u ceph ceph-authtool --create-keyring /etc/ceph/ceph.client.admin.keyring --gen-key -n client.admin --cap mon 'allow *' --cap osd 'allow *' --cap mds 'allow *' --cap mgr 'allow *'",
|
||||||
"sudo -u ceph ceph-authtool /tmp/ceph.mon.keyring --import-keyring /etc/ceph/ceph.client.admin.keyring",
|
"sudo -u ceph ceph-authtool /tmp/ceph.mon.keyring --import-keyring /etc/ceph/ceph.client.admin.keyring",
|
||||||
@ -124,90 +124,90 @@ let
|
|||||||
"sudo -u ceph ceph-mon --mkfs -i ${cfg.monA.name} --monmap /tmp/monmap --keyring /tmp/ceph.mon.keyring",
|
"sudo -u ceph ceph-mon --mkfs -i ${cfg.monA.name} --monmap /tmp/monmap --keyring /tmp/ceph.mon.keyring",
|
||||||
"sudo -u ceph mkdir -p /var/lib/ceph/mgr/ceph-${cfg.monA.name}/",
|
"sudo -u ceph mkdir -p /var/lib/ceph/mgr/ceph-${cfg.monA.name}/",
|
||||||
"sudo -u ceph touch /var/lib/ceph/mon/ceph-${cfg.monA.name}/done",
|
"sudo -u ceph touch /var/lib/ceph/mon/ceph-${cfg.monA.name}/done",
|
||||||
"systemctl start ceph-mon-${cfg.monA.name}"
|
"systemctl start ceph-mon-${cfg.monA.name}",
|
||||||
);
|
)
|
||||||
$monA->waitForUnit("ceph-mon-${cfg.monA.name}");
|
monA.wait_for_unit("ceph-mon-${cfg.monA.name}")
|
||||||
$monA->mustSucceed("ceph mon enable-msgr2");
|
monA.succeed("ceph mon enable-msgr2")
|
||||||
|
|
||||||
# Can't check ceph status until a mon is up
|
# Can't check ceph status until a mon is up
|
||||||
$monA->succeed("ceph -s | grep 'mon: 1 daemons'");
|
monA.succeed("ceph -s | grep 'mon: 1 daemons'")
|
||||||
|
|
||||||
# Start the ceph-mgr daemon, it has no deps and hardly any setup
|
# Start the ceph-mgr daemon, it has no deps and hardly any setup
|
||||||
$monA->mustSucceed(
|
monA.succeed(
|
||||||
"ceph auth get-or-create mgr.${cfg.monA.name} mon 'allow profile mgr' osd 'allow *' mds 'allow *' > /var/lib/ceph/mgr/ceph-${cfg.monA.name}/keyring",
|
"ceph auth get-or-create mgr.${cfg.monA.name} mon 'allow profile mgr' osd 'allow *' mds 'allow *' > /var/lib/ceph/mgr/ceph-${cfg.monA.name}/keyring",
|
||||||
"systemctl start ceph-mgr-${cfg.monA.name}"
|
"systemctl start ceph-mgr-${cfg.monA.name}",
|
||||||
);
|
)
|
||||||
$monA->waitForUnit("ceph-mgr-a");
|
monA.wait_for_unit("ceph-mgr-a")
|
||||||
$monA->waitUntilSucceeds("ceph -s | grep 'quorum ${cfg.monA.name}'");
|
monA.wait_until_succeeds("ceph -s | grep 'quorum ${cfg.monA.name}'")
|
||||||
$monA->waitUntilSucceeds("ceph -s | grep 'mgr: ${cfg.monA.name}(active,'");
|
monA.wait_until_succeeds("ceph -s | grep 'mgr: ${cfg.monA.name}(active,'")
|
||||||
|
|
||||||
# Send the admin keyring to the OSD machines
|
# Send the admin keyring to the OSD machines
|
||||||
$monA->mustSucceed("cp /etc/ceph/ceph.client.admin.keyring /tmp/shared");
|
monA.succeed("cp /etc/ceph/ceph.client.admin.keyring /tmp/shared")
|
||||||
$osd0->mustSucceed("cp /tmp/shared/ceph.client.admin.keyring /etc/ceph");
|
osd0.succeed("cp /tmp/shared/ceph.client.admin.keyring /etc/ceph")
|
||||||
$osd1->mustSucceed("cp /tmp/shared/ceph.client.admin.keyring /etc/ceph");
|
osd1.succeed("cp /tmp/shared/ceph.client.admin.keyring /etc/ceph")
|
||||||
|
|
||||||
# Bootstrap both OSDs
|
# Bootstrap both OSDs
|
||||||
$osd0->mustSucceed(
|
osd0.succeed(
|
||||||
"mkfs.xfs /dev/vdb",
|
"mkfs.xfs /dev/vdb",
|
||||||
"mkdir -p /var/lib/ceph/osd/ceph-${cfg.osd0.name}",
|
"mkdir -p /var/lib/ceph/osd/ceph-${cfg.osd0.name}",
|
||||||
"mount /dev/vdb /var/lib/ceph/osd/ceph-${cfg.osd0.name}",
|
"mount /dev/vdb /var/lib/ceph/osd/ceph-${cfg.osd0.name}",
|
||||||
"ceph-authtool --create-keyring /var/lib/ceph/osd/ceph-${cfg.osd0.name}/keyring --name osd.${cfg.osd0.name} --add-key ${cfg.osd0.key}",
|
"ceph-authtool --create-keyring /var/lib/ceph/osd/ceph-${cfg.osd0.name}/keyring --name osd.${cfg.osd0.name} --add-key ${cfg.osd0.key}",
|
||||||
"echo '{\"cephx_secret\": \"${cfg.osd0.key}\"}' | ceph osd new ${cfg.osd0.uuid} -i -",
|
'echo \'{"cephx_secret": "${cfg.osd0.key}"}\' | ceph osd new ${cfg.osd0.uuid} -i -',
|
||||||
);
|
)
|
||||||
$osd1->mustSucceed(
|
osd1.succeed(
|
||||||
"mkfs.xfs /dev/vdb",
|
"mkfs.xfs /dev/vdb",
|
||||||
"mkdir -p /var/lib/ceph/osd/ceph-${cfg.osd1.name}",
|
"mkdir -p /var/lib/ceph/osd/ceph-${cfg.osd1.name}",
|
||||||
"mount /dev/vdb /var/lib/ceph/osd/ceph-${cfg.osd1.name}",
|
"mount /dev/vdb /var/lib/ceph/osd/ceph-${cfg.osd1.name}",
|
||||||
"ceph-authtool --create-keyring /var/lib/ceph/osd/ceph-${cfg.osd1.name}/keyring --name osd.${cfg.osd1.name} --add-key ${cfg.osd1.key}",
|
"ceph-authtool --create-keyring /var/lib/ceph/osd/ceph-${cfg.osd1.name}/keyring --name osd.${cfg.osd1.name} --add-key ${cfg.osd1.key}",
|
||||||
"echo '{\"cephx_secret\": \"${cfg.osd1.key}\"}' | ceph osd new ${cfg.osd1.uuid} -i -"
|
'echo \'{"cephx_secret": "${cfg.osd1.key}"}\' | ceph osd new ${cfg.osd1.uuid} -i -',
|
||||||
);
|
)
|
||||||
|
|
||||||
# Initialize the OSDs with regular filestore
|
# Initialize the OSDs with regular filestore
|
||||||
$osd0->mustSucceed(
|
osd0.succeed(
|
||||||
"ceph-osd -i ${cfg.osd0.name} --mkfs --osd-uuid ${cfg.osd0.uuid}",
|
"ceph-osd -i ${cfg.osd0.name} --mkfs --osd-uuid ${cfg.osd0.uuid}",
|
||||||
"chown -R ceph:ceph /var/lib/ceph/osd",
|
"chown -R ceph:ceph /var/lib/ceph/osd",
|
||||||
"systemctl start ceph-osd-${cfg.osd0.name}",
|
"systemctl start ceph-osd-${cfg.osd0.name}",
|
||||||
);
|
)
|
||||||
$osd1->mustSucceed(
|
osd1.succeed(
|
||||||
"ceph-osd -i ${cfg.osd1.name} --mkfs --osd-uuid ${cfg.osd1.uuid}",
|
"ceph-osd -i ${cfg.osd1.name} --mkfs --osd-uuid ${cfg.osd1.uuid}",
|
||||||
"chown -R ceph:ceph /var/lib/ceph/osd",
|
"chown -R ceph:ceph /var/lib/ceph/osd",
|
||||||
"systemctl start ceph-osd-${cfg.osd1.name}"
|
"systemctl start ceph-osd-${cfg.osd1.name}",
|
||||||
);
|
)
|
||||||
$monA->waitUntilSucceeds("ceph osd stat | grep -e '2 osds: 2 up[^,]*, 2 in'");
|
monA.wait_until_succeeds("ceph osd stat | grep -e '2 osds: 2 up[^,]*, 2 in'")
|
||||||
$monA->waitUntilSucceeds("ceph -s | grep 'mgr: ${cfg.monA.name}(active,'");
|
monA.wait_until_succeeds("ceph -s | grep 'mgr: ${cfg.monA.name}(active,'")
|
||||||
$monA->waitUntilSucceeds("ceph -s | grep 'HEALTH_OK'");
|
monA.wait_until_succeeds("ceph -s | grep 'HEALTH_OK'")
|
||||||
|
|
||||||
$monA->mustSucceed(
|
monA.succeed(
|
||||||
"ceph osd pool create multi-node-test 100 100",
|
"ceph osd pool create multi-node-test 100 100",
|
||||||
"ceph osd pool ls | grep 'multi-node-test'",
|
"ceph osd pool ls | grep 'multi-node-test'",
|
||||||
"ceph osd pool rename multi-node-test multi-node-other-test",
|
"ceph osd pool rename multi-node-test multi-node-other-test",
|
||||||
"ceph osd pool ls | grep 'multi-node-other-test'"
|
"ceph osd pool ls | grep 'multi-node-other-test'",
|
||||||
);
|
)
|
||||||
$monA->waitUntilSucceeds("ceph -s | grep '1 pools, 100 pgs'");
|
monA.wait_until_succeeds("ceph -s | grep '1 pools, 100 pgs'")
|
||||||
$monA->mustSucceed("ceph osd pool set multi-node-other-test size 2");
|
monA.succeed("ceph osd pool set multi-node-other-test size 2")
|
||||||
$monA->waitUntilSucceeds("ceph -s | grep 'HEALTH_OK'");
|
monA.wait_until_succeeds("ceph -s | grep 'HEALTH_OK'")
|
||||||
$monA->waitUntilSucceeds("ceph -s | grep '100 active+clean'");
|
monA.wait_until_succeeds("ceph -s | grep '100 active+clean'")
|
||||||
$monA->mustFail(
|
monA.fail(
|
||||||
"ceph osd pool ls | grep 'multi-node-test'",
|
"ceph osd pool ls | grep 'multi-node-test'",
|
||||||
"ceph osd pool delete multi-node-other-test multi-node-other-test --yes-i-really-really-mean-it"
|
"ceph osd pool delete multi-node-other-test multi-node-other-test --yes-i-really-really-mean-it",
|
||||||
);
|
)
|
||||||
|
|
||||||
# Shut down ceph on all machines in a very unpolite way
|
# Shut down ceph on all machines in a very unpolite way
|
||||||
$monA->crash;
|
monA.crash()
|
||||||
$osd0->crash;
|
osd0.crash()
|
||||||
$osd1->crash;
|
osd1.crash()
|
||||||
|
|
||||||
# Start it up
|
# Start it up
|
||||||
$osd0->start;
|
osd0.start()
|
||||||
$osd1->start;
|
osd1.start()
|
||||||
$monA->start;
|
monA.start()
|
||||||
|
|
||||||
# Ensure the cluster comes back up again
|
# Ensure the cluster comes back up again
|
||||||
$monA->succeed("ceph -s | grep 'mon: 1 daemons'");
|
monA.succeed("ceph -s | grep 'mon: 1 daemons'")
|
||||||
$monA->waitUntilSucceeds("ceph -s | grep 'quorum ${cfg.monA.name}'");
|
monA.wait_until_succeeds("ceph -s | grep 'quorum ${cfg.monA.name}'")
|
||||||
$monA->waitUntilSucceeds("ceph osd stat | grep -e '2 osds: 2 up[^,]*, 2 in'");
|
monA.wait_until_succeeds("ceph osd stat | grep -e '2 osds: 2 up[^,]*, 2 in'")
|
||||||
$monA->waitUntilSucceeds("ceph -s | grep 'mgr: ${cfg.monA.name}(active,'");
|
monA.wait_until_succeeds("ceph -s | grep 'mgr: ${cfg.monA.name}(active,'")
|
||||||
$monA->waitUntilSucceeds("ceph -s | grep 'HEALTH_OK'");
|
monA.wait_until_succeeds("ceph -s | grep 'HEALTH_OK'")
|
||||||
'';
|
'';
|
||||||
in {
|
in {
|
||||||
name = "basic-multi-node-ceph-cluster";
|
name = "basic-multi-node-ceph-cluster";
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import ./make-test.nix ({pkgs, lib, ...}:
|
import ./make-test-python.nix ({pkgs, lib, ...}:
|
||||||
|
|
||||||
let
|
let
|
||||||
cfg = {
|
cfg = {
|
||||||
@ -74,38 +74,38 @@ let
|
|||||||
# For other ways to deploy a ceph cluster, look at the documentation at
|
# For other ways to deploy a ceph cluster, look at the documentation at
|
||||||
# https://docs.ceph.com/docs/master/
|
# https://docs.ceph.com/docs/master/
|
||||||
testscript = { ... }: ''
|
testscript = { ... }: ''
|
||||||
startAll;
|
start_all()
|
||||||
|
|
||||||
$monA->waitForUnit("network.target");
|
monA.wait_for_unit("network.target")
|
||||||
|
|
||||||
# Bootstrap ceph-mon daemon
|
# Bootstrap ceph-mon daemon
|
||||||
$monA->mustSucceed(
|
monA.succeed(
|
||||||
"sudo -u ceph ceph-authtool --create-keyring /tmp/ceph.mon.keyring --gen-key -n mon. --cap mon 'allow *'",
|
"sudo -u ceph ceph-authtool --create-keyring /tmp/ceph.mon.keyring --gen-key -n mon. --cap mon 'allow *'",
|
||||||
"sudo -u ceph ceph-authtool --create-keyring /etc/ceph/ceph.client.admin.keyring --gen-key -n client.admin --cap mon 'allow *' --cap osd 'allow *' --cap mds 'allow *' --cap mgr 'allow *'",
|
"sudo -u ceph ceph-authtool --create-keyring /etc/ceph/ceph.client.admin.keyring --gen-key -n client.admin --cap mon 'allow *' --cap osd 'allow *' --cap mds 'allow *' --cap mgr 'allow *'",
|
||||||
"sudo -u ceph ceph-authtool /tmp/ceph.mon.keyring --import-keyring /etc/ceph/ceph.client.admin.keyring",
|
"sudo -u ceph ceph-authtool /tmp/ceph.mon.keyring --import-keyring /etc/ceph/ceph.client.admin.keyring",
|
||||||
"monmaptool --create --add ${cfg.monA.name} ${cfg.monA.ip} --fsid ${cfg.clusterId} /tmp/monmap",
|
"monmaptool --create --add ${cfg.monA.name} ${cfg.monA.ip} --fsid ${cfg.clusterId} /tmp/monmap",
|
||||||
"sudo -u ceph ceph-mon --mkfs -i ${cfg.monA.name} --monmap /tmp/monmap --keyring /tmp/ceph.mon.keyring",
|
"sudo -u ceph ceph-mon --mkfs -i ${cfg.monA.name} --monmap /tmp/monmap --keyring /tmp/ceph.mon.keyring",
|
||||||
"sudo -u ceph touch /var/lib/ceph/mon/ceph-${cfg.monA.name}/done",
|
"sudo -u ceph touch /var/lib/ceph/mon/ceph-${cfg.monA.name}/done",
|
||||||
"systemctl start ceph-mon-${cfg.monA.name}"
|
"systemctl start ceph-mon-${cfg.monA.name}",
|
||||||
);
|
)
|
||||||
$monA->waitForUnit("ceph-mon-${cfg.monA.name}");
|
monA.wait_for_unit("ceph-mon-${cfg.monA.name}")
|
||||||
$monA->mustSucceed("ceph mon enable-msgr2");
|
monA.succeed("ceph mon enable-msgr2")
|
||||||
|
|
||||||
# Can't check ceph status until a mon is up
|
# Can't check ceph status until a mon is up
|
||||||
$monA->succeed("ceph -s | grep 'mon: 1 daemons'");
|
monA.succeed("ceph -s | grep 'mon: 1 daemons'")
|
||||||
|
|
||||||
# Start the ceph-mgr daemon, after copying in the keyring
|
# Start the ceph-mgr daemon, after copying in the keyring
|
||||||
$monA->mustSucceed(
|
monA.succeed(
|
||||||
"sudo -u ceph mkdir -p /var/lib/ceph/mgr/ceph-${cfg.monA.name}/",
|
"sudo -u ceph mkdir -p /var/lib/ceph/mgr/ceph-${cfg.monA.name}/",
|
||||||
"ceph auth get-or-create mgr.${cfg.monA.name} mon 'allow profile mgr' osd 'allow *' mds 'allow *' > /var/lib/ceph/mgr/ceph-${cfg.monA.name}/keyring",
|
"ceph auth get-or-create mgr.${cfg.monA.name} mon 'allow profile mgr' osd 'allow *' mds 'allow *' > /var/lib/ceph/mgr/ceph-${cfg.monA.name}/keyring",
|
||||||
"systemctl start ceph-mgr-${cfg.monA.name}"
|
"systemctl start ceph-mgr-${cfg.monA.name}",
|
||||||
);
|
)
|
||||||
$monA->waitForUnit("ceph-mgr-a");
|
monA.wait_for_unit("ceph-mgr-a")
|
||||||
$monA->waitUntilSucceeds("ceph -s | grep 'quorum ${cfg.monA.name}'");
|
monA.wait_until_succeeds("ceph -s | grep 'quorum ${cfg.monA.name}'")
|
||||||
$monA->waitUntilSucceeds("ceph -s | grep 'mgr: ${cfg.monA.name}(active,'");
|
monA.wait_until_succeeds("ceph -s | grep 'mgr: ${cfg.monA.name}(active,'")
|
||||||
|
|
||||||
# Bootstrap both OSDs
|
# Bootstrap both OSDs
|
||||||
$monA->mustSucceed(
|
monA.succeed(
|
||||||
"mkfs.xfs /dev/vdb",
|
"mkfs.xfs /dev/vdb",
|
||||||
"mkfs.xfs /dev/vdc",
|
"mkfs.xfs /dev/vdc",
|
||||||
"mkdir -p /var/lib/ceph/osd/ceph-${cfg.osd0.name}",
|
"mkdir -p /var/lib/ceph/osd/ceph-${cfg.osd0.name}",
|
||||||
@ -114,60 +114,60 @@ let
|
|||||||
"mount /dev/vdc /var/lib/ceph/osd/ceph-${cfg.osd1.name}",
|
"mount /dev/vdc /var/lib/ceph/osd/ceph-${cfg.osd1.name}",
|
||||||
"ceph-authtool --create-keyring /var/lib/ceph/osd/ceph-${cfg.osd0.name}/keyring --name osd.${cfg.osd0.name} --add-key ${cfg.osd0.key}",
|
"ceph-authtool --create-keyring /var/lib/ceph/osd/ceph-${cfg.osd0.name}/keyring --name osd.${cfg.osd0.name} --add-key ${cfg.osd0.key}",
|
||||||
"ceph-authtool --create-keyring /var/lib/ceph/osd/ceph-${cfg.osd1.name}/keyring --name osd.${cfg.osd1.name} --add-key ${cfg.osd1.key}",
|
"ceph-authtool --create-keyring /var/lib/ceph/osd/ceph-${cfg.osd1.name}/keyring --name osd.${cfg.osd1.name} --add-key ${cfg.osd1.key}",
|
||||||
"echo '{\"cephx_secret\": \"${cfg.osd0.key}\"}' | ceph osd new ${cfg.osd0.uuid} -i -",
|
'echo \'{"cephx_secret": "${cfg.osd0.key}"}\' | ceph osd new ${cfg.osd0.uuid} -i -',
|
||||||
"echo '{\"cephx_secret\": \"${cfg.osd1.key}\"}' | ceph osd new ${cfg.osd1.uuid} -i -"
|
'echo \'{"cephx_secret": "${cfg.osd1.key}"}\' | ceph osd new ${cfg.osd1.uuid} -i -',
|
||||||
);
|
)
|
||||||
|
|
||||||
# Initialize the OSDs with regular filestore
|
# Initialize the OSDs with regular filestore
|
||||||
$monA->mustSucceed(
|
monA.succeed(
|
||||||
"ceph-osd -i ${cfg.osd0.name} --mkfs --osd-uuid ${cfg.osd0.uuid}",
|
"ceph-osd -i ${cfg.osd0.name} --mkfs --osd-uuid ${cfg.osd0.uuid}",
|
||||||
"ceph-osd -i ${cfg.osd1.name} --mkfs --osd-uuid ${cfg.osd1.uuid}",
|
"ceph-osd -i ${cfg.osd1.name} --mkfs --osd-uuid ${cfg.osd1.uuid}",
|
||||||
"chown -R ceph:ceph /var/lib/ceph/osd",
|
"chown -R ceph:ceph /var/lib/ceph/osd",
|
||||||
"systemctl start ceph-osd-${cfg.osd0.name}",
|
"systemctl start ceph-osd-${cfg.osd0.name}",
|
||||||
"systemctl start ceph-osd-${cfg.osd1.name}"
|
"systemctl start ceph-osd-${cfg.osd1.name}",
|
||||||
);
|
)
|
||||||
$monA->waitUntilSucceeds("ceph osd stat | grep -e '2 osds: 2 up[^,]*, 2 in'");
|
monA.wait_until_succeeds("ceph osd stat | grep -e '2 osds: 2 up[^,]*, 2 in'")
|
||||||
$monA->waitUntilSucceeds("ceph -s | grep 'mgr: ${cfg.monA.name}(active,'");
|
monA.wait_until_succeeds("ceph -s | grep 'mgr: ${cfg.monA.name}(active,'")
|
||||||
$monA->waitUntilSucceeds("ceph -s | grep 'HEALTH_OK'");
|
monA.wait_until_succeeds("ceph -s | grep 'HEALTH_OK'")
|
||||||
|
|
||||||
$monA->mustSucceed(
|
monA.succeed(
|
||||||
"ceph osd pool create single-node-test 100 100",
|
"ceph osd pool create single-node-test 100 100",
|
||||||
"ceph osd pool ls | grep 'single-node-test'",
|
"ceph osd pool ls | grep 'single-node-test'",
|
||||||
"ceph osd pool rename single-node-test single-node-other-test",
|
"ceph osd pool rename single-node-test single-node-other-test",
|
||||||
"ceph osd pool ls | grep 'single-node-other-test'"
|
"ceph osd pool ls | grep 'single-node-other-test'",
|
||||||
);
|
)
|
||||||
$monA->waitUntilSucceeds("ceph -s | grep '1 pools, 100 pgs'");
|
monA.wait_until_succeeds("ceph -s | grep '1 pools, 100 pgs'")
|
||||||
$monA->mustSucceed(
|
monA.succeed(
|
||||||
"ceph osd getcrushmap -o crush",
|
"ceph osd getcrushmap -o crush",
|
||||||
"crushtool -d crush -o decrushed",
|
"crushtool -d crush -o decrushed",
|
||||||
"sed 's/step chooseleaf firstn 0 type host/step chooseleaf firstn 0 type osd/' decrushed > modcrush",
|
"sed 's/step chooseleaf firstn 0 type host/step chooseleaf firstn 0 type osd/' decrushed > modcrush",
|
||||||
"crushtool -c modcrush -o recrushed",
|
"crushtool -c modcrush -o recrushed",
|
||||||
"ceph osd setcrushmap -i recrushed",
|
"ceph osd setcrushmap -i recrushed",
|
||||||
"ceph osd pool set single-node-other-test size 2"
|
"ceph osd pool set single-node-other-test size 2",
|
||||||
);
|
)
|
||||||
$monA->waitUntilSucceeds("ceph -s | grep 'HEALTH_OK'");
|
monA.wait_until_succeeds("ceph -s | grep 'HEALTH_OK'")
|
||||||
$monA->waitUntilSucceeds("ceph -s | grep '100 active+clean'");
|
monA.wait_until_succeeds("ceph -s | grep '100 active+clean'")
|
||||||
$monA->mustFail(
|
monA.fail(
|
||||||
"ceph osd pool ls | grep 'multi-node-test'",
|
"ceph osd pool ls | grep 'multi-node-test'",
|
||||||
"ceph osd pool delete single-node-other-test single-node-other-test --yes-i-really-really-mean-it"
|
"ceph osd pool delete single-node-other-test single-node-other-test --yes-i-really-really-mean-it",
|
||||||
);
|
)
|
||||||
|
|
||||||
# Shut down ceph by stopping ceph.target.
|
# Shut down ceph by stopping ceph.target.
|
||||||
$monA->mustSucceed("systemctl stop ceph.target");
|
monA.succeed("systemctl stop ceph.target")
|
||||||
|
|
||||||
# Start it up
|
# Start it up
|
||||||
$monA->succeed("systemctl start ceph.target");
|
monA.succeed("systemctl start ceph.target")
|
||||||
$monA->waitForUnit("ceph-mon-${cfg.monA.name}");
|
monA.wait_for_unit("ceph-mon-${cfg.monA.name}")
|
||||||
$monA->waitForUnit("ceph-mgr-${cfg.monA.name}");
|
monA.wait_for_unit("ceph-mgr-${cfg.monA.name}")
|
||||||
$monA->waitForUnit("ceph-osd-${cfg.osd0.name}");
|
monA.wait_for_unit("ceph-osd-${cfg.osd0.name}")
|
||||||
$monA->waitForUnit("ceph-osd-${cfg.osd1.name}");
|
monA.wait_for_unit("ceph-osd-${cfg.osd1.name}")
|
||||||
|
|
||||||
# Ensure the cluster comes back up again
|
# Ensure the cluster comes back up again
|
||||||
$monA->succeed("ceph -s | grep 'mon: 1 daemons'");
|
monA.succeed("ceph -s | grep 'mon: 1 daemons'")
|
||||||
$monA->waitUntilSucceeds("ceph -s | grep 'quorum ${cfg.monA.name}'");
|
monA.wait_until_succeeds("ceph -s | grep 'quorum ${cfg.monA.name}'")
|
||||||
$monA->waitUntilSucceeds("ceph osd stat | grep -e '2 osds: 2 up[^,]*, 2 in'");
|
monA.wait_until_succeeds("ceph osd stat | grep -e '2 osds: 2 up[^,]*, 2 in'")
|
||||||
$monA->waitUntilSucceeds("ceph -s | grep 'mgr: ${cfg.monA.name}(active,'");
|
monA.wait_until_succeeds("ceph -s | grep 'mgr: ${cfg.monA.name}(active,'")
|
||||||
$monA->waitUntilSucceeds("ceph -s | grep 'HEALTH_OK'");
|
monA.wait_until_succeeds("ceph -s | grep 'HEALTH_OK'")
|
||||||
'';
|
'';
|
||||||
in {
|
in {
|
||||||
name = "basic-single-node-ceph-cluster";
|
name = "basic-single-node-ceph-cluster";
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import ./make-test.nix ({ pkgs, ... }: {
|
import ./make-test-python.nix ({ pkgs, ... }: {
|
||||||
name = "clickhouse";
|
name = "clickhouse";
|
||||||
meta.maintainers = with pkgs.stdenv.lib.maintainers; [ ma27 ];
|
meta.maintainers = with pkgs.stdenv.lib.maintainers; [ ma27 ];
|
||||||
|
|
||||||
@ -14,12 +14,18 @@ import ./make-test.nix ({ pkgs, ... }: {
|
|||||||
selectQuery = pkgs.writeText "select.sql" "SELECT * from `demo`";
|
selectQuery = pkgs.writeText "select.sql" "SELECT * from `demo`";
|
||||||
in
|
in
|
||||||
''
|
''
|
||||||
$machine->start();
|
machine.start()
|
||||||
$machine->waitForUnit("clickhouse.service");
|
machine.wait_for_unit("clickhouse.service")
|
||||||
$machine->waitForOpenPort(9000);
|
machine.wait_for_open_port(9000)
|
||||||
|
|
||||||
$machine->succeed("cat ${tableDDL} | clickhouse-client");
|
machine.succeed(
|
||||||
$machine->succeed("cat ${insertQuery} | clickhouse-client");
|
"cat ${tableDDL} | clickhouse-client"
|
||||||
$machine->succeed("cat ${selectQuery} | clickhouse-client | grep foo");
|
)
|
||||||
|
machine.succeed(
|
||||||
|
"cat ${insertQuery} | clickhouse-client"
|
||||||
|
)
|
||||||
|
machine.succeed(
|
||||||
|
"cat ${selectQuery} | clickhouse-client | grep foo"
|
||||||
|
)
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import ./make-test.nix ({ pkgs, lib, ... }:
|
import ./make-test-python.nix ({ pkgs, lib, ... }:
|
||||||
{
|
{
|
||||||
name = "codimd";
|
name = "codimd";
|
||||||
|
|
||||||
@ -35,20 +35,18 @@ import ./make-test.nix ({ pkgs, lib, ... }:
|
|||||||
};
|
};
|
||||||
|
|
||||||
testScript = ''
|
testScript = ''
|
||||||
startAll();
|
start_all()
|
||||||
|
|
||||||
subtest "CodiMD sqlite", sub {
|
with subtest("CodiMD sqlite"):
|
||||||
$codimdSqlite->waitForUnit("codimd.service");
|
codimdSqlite.wait_for_unit("codimd.service")
|
||||||
$codimdSqlite->waitForOpenPort(3000);
|
codimdSqlite.wait_for_open_port(3000)
|
||||||
$codimdSqlite->waitUntilSucceeds("curl -sSf http://localhost:3000/new");
|
codimdSqlite.wait_until_succeeds("curl -sSf http://localhost:3000/new")
|
||||||
};
|
|
||||||
|
|
||||||
subtest "CodiMD postgres", sub {
|
with subtest("CodiMD postgres"):
|
||||||
$codimdPostgres->waitForUnit("postgresql.service");
|
codimdPostgres.wait_for_unit("postgresql.service")
|
||||||
$codimdPostgres->waitForUnit("codimd.service");
|
codimdPostgres.wait_for_unit("codimd.service")
|
||||||
$codimdPostgres->waitForOpenPort(5432);
|
codimdPostgres.wait_for_open_port(5432)
|
||||||
$codimdPostgres->waitForOpenPort(3000);
|
codimdPostgres.wait_for_open_port(3000)
|
||||||
$codimdPostgres->waitUntilSucceeds("curl -sSf http://localhost:3000/new");
|
codimdPostgres.wait_until_succeeds("curl -sSf http://localhost:3000/new")
|
||||||
};
|
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import ./make-test.nix ({ pkgs, ...} : {
|
import ./make-test-python.nix ({ pkgs, ...} : {
|
||||||
name = "deluge";
|
name = "deluge";
|
||||||
meta = with pkgs.stdenv.lib.maintainers; {
|
meta = with pkgs.stdenv.lib.maintainers; {
|
||||||
maintainers = [ flokli ];
|
maintainers = [ flokli ];
|
||||||
@ -45,18 +45,20 @@ import ./make-test.nix ({ pkgs, ...} : {
|
|||||||
};
|
};
|
||||||
|
|
||||||
testScript = ''
|
testScript = ''
|
||||||
startAll;
|
start_all()
|
||||||
|
|
||||||
$simple->waitForUnit("deluged");
|
simple.wait_for_unit("deluged")
|
||||||
$simple->waitForUnit("delugeweb");
|
simple.wait_for_unit("delugeweb")
|
||||||
$simple->waitForOpenPort("8112");
|
simple.wait_for_open_port("8112")
|
||||||
$declarative->waitForUnit("network.target");
|
declarative.wait_for_unit("network.target")
|
||||||
$declarative->waitUntilSucceeds("curl --fail http://simple:8112");
|
declarative.wait_until_succeeds("curl --fail http://simple:8112")
|
||||||
|
|
||||||
$declarative->waitForUnit("deluged");
|
declarative.wait_for_unit("deluged")
|
||||||
$declarative->waitForUnit("delugeweb");
|
declarative.wait_for_unit("delugeweb")
|
||||||
$declarative->waitUntilSucceeds("curl --fail http://declarative:3142");
|
declarative.wait_until_succeeds("curl --fail http://declarative:3142")
|
||||||
$declarative->succeed("deluge-console 'help' | grep -q 'rm - Remove a torrent'");
|
declarative.succeed("deluge-console 'help' | grep -q 'rm - Remove a torrent'")
|
||||||
$declarative->succeed("deluge-console 'connect 127.0.0.1:58846 andrew password; help' | grep -q 'rm - Remove a torrent'");
|
declarative.succeed(
|
||||||
|
"deluge-console 'connect 127.0.0.1:58846 andrew password; help' | grep -q 'rm - Remove a torrent'"
|
||||||
|
)
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# This test runs docker-registry and check if it works
|
# This test runs docker-registry and check if it works
|
||||||
|
|
||||||
import ./make-test.nix ({ pkgs, ...} : {
|
import ./make-test-python.nix ({ pkgs, ...} : {
|
||||||
name = "docker-registry";
|
name = "docker-registry";
|
||||||
meta = with pkgs.stdenv.lib.maintainers; {
|
meta = with pkgs.stdenv.lib.maintainers; {
|
||||||
maintainers = [ globin ma27 ironpinguin ];
|
maintainers = [ globin ma27 ironpinguin ];
|
||||||
@ -28,36 +28,34 @@ import ./make-test.nix ({ pkgs, ...} : {
|
|||||||
};
|
};
|
||||||
|
|
||||||
testScript = ''
|
testScript = ''
|
||||||
$client1->start();
|
client1.start()
|
||||||
$client1->waitForUnit("docker.service");
|
client1.wait_for_unit("docker.service")
|
||||||
$client1->succeed("tar cv --files-from /dev/null | docker import - scratch");
|
client1.succeed("tar cv --files-from /dev/null | docker import - scratch")
|
||||||
$client1->succeed("docker tag scratch registry:8080/scratch");
|
client1.succeed("docker tag scratch registry:8080/scratch")
|
||||||
|
|
||||||
$registry->start();
|
registry.start()
|
||||||
$registry->waitForUnit("docker-registry.service");
|
registry.wait_for_unit("docker-registry.service")
|
||||||
$registry->waitForOpenPort("8080");
|
registry.wait_for_open_port("8080")
|
||||||
$client1->succeed("docker push registry:8080/scratch");
|
client1.succeed("docker push registry:8080/scratch")
|
||||||
|
|
||||||
$client2->start();
|
client2.start()
|
||||||
$client2->waitForUnit("docker.service");
|
client2.wait_for_unit("docker.service")
|
||||||
$client2->succeed("docker pull registry:8080/scratch");
|
client2.succeed("docker pull registry:8080/scratch")
|
||||||
$client2->succeed("docker images | grep scratch");
|
client2.succeed("docker images | grep scratch")
|
||||||
|
|
||||||
$client2->succeed(
|
client2.succeed(
|
||||||
'curl -fsS -X DELETE registry:8080/v2/scratch/manifests/$(curl -fsS -I -H"Accept: application/vnd.docker.distribution.manifest.v2+json" registry:8080/v2/scratch/manifests/latest | grep Docker-Content-Digest | sed -e \'s/Docker-Content-Digest: //\' | tr -d \'\r\')'
|
"curl -fsS -X DELETE registry:8080/v2/scratch/manifests/$(curl -fsS -I -H\"Accept: application/vnd.docker.distribution.manifest.v2+json\" registry:8080/v2/scratch/manifests/latest | grep Docker-Content-Digest | sed -e 's/Docker-Content-Digest: //' | tr -d '\\r')"
|
||||||
);
|
)
|
||||||
|
|
||||||
$registry->systemctl("start docker-registry-garbage-collect.service");
|
registry.systemctl("start docker-registry-garbage-collect.service")
|
||||||
$registry->waitUntilFails("systemctl status docker-registry-garbage-collect.service");
|
registry.wait_until_fails("systemctl status docker-registry-garbage-collect.service")
|
||||||
$registry->waitForUnit("docker-registry.service");
|
registry.wait_for_unit("docker-registry.service")
|
||||||
|
|
||||||
$registry->fail(
|
registry.fail("ls -l /var/lib/docker-registry/docker/registry/v2/blobs/sha256/*/*/data")
|
||||||
'ls -l /var/lib/docker-registry/docker/registry/v2/blobs/sha256/*/*/data'
|
|
||||||
);
|
|
||||||
|
|
||||||
$client1->succeed("docker push registry:8080/scratch");
|
client1.succeed("docker push registry:8080/scratch")
|
||||||
$registry->succeed(
|
registry.succeed(
|
||||||
'ls -l /var/lib/docker-registry/docker/registry/v2/blobs/sha256/*/*/data'
|
"ls -l /var/lib/docker-registry/docker/registry/v2/blobs/sha256/*/*/data"
|
||||||
);
|
)
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import ./make-test.nix {
|
import ./make-test-python.nix {
|
||||||
name = "dovecot";
|
name = "dovecot";
|
||||||
|
|
||||||
machine = { pkgs, ... }: {
|
machine = { pkgs, ... }: {
|
||||||
@ -66,12 +66,12 @@ import ./make-test.nix {
|
|||||||
};
|
};
|
||||||
|
|
||||||
testScript = ''
|
testScript = ''
|
||||||
$machine->waitForUnit('postfix.service');
|
machine.wait_for_unit("postfix.service")
|
||||||
$machine->waitForUnit('dovecot2.service');
|
machine.wait_for_unit("dovecot2.service")
|
||||||
$machine->succeed('send-testmail');
|
machine.succeed("send-testmail")
|
||||||
$machine->succeed('send-lda');
|
machine.succeed("send-lda")
|
||||||
$machine->waitUntilFails('[ "$(postqueue -p)" != "Mail queue is empty" ]');
|
machine.wait_until_fails('[ "$(postqueue -p)" != "Mail queue is empty" ]')
|
||||||
$machine->succeed('test-imap');
|
machine.succeed("test-imap")
|
||||||
$machine->succeed('test-pop');
|
machine.succeed("test-pop")
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# This test runs simple etcd cluster
|
# This test runs simple etcd cluster
|
||||||
|
|
||||||
import ./make-test.nix ({ pkgs, ... } : let
|
import ./make-test-python.nix ({ pkgs, ... } : let
|
||||||
|
|
||||||
runWithOpenSSL = file: cmd: pkgs.runCommand file {
|
runWithOpenSSL = file: cmd: pkgs.runCommand file {
|
||||||
buildInputs = [ pkgs.openssl ];
|
buildInputs = [ pkgs.openssl ];
|
||||||
@ -129,29 +129,26 @@ in {
|
|||||||
};
|
};
|
||||||
|
|
||||||
testScript = ''
|
testScript = ''
|
||||||
subtest "should start etcd cluster", sub {
|
with subtest("should start etcd cluster"):
|
||||||
$node1->start();
|
node1.start()
|
||||||
$node2->start();
|
node2.start()
|
||||||
$node1->waitForUnit("etcd.service");
|
node1.wait_for_unit("etcd.service")
|
||||||
$node2->waitForUnit("etcd.service");
|
node2.wait_for_unit("etcd.service")
|
||||||
$node2->waitUntilSucceeds("etcdctl cluster-health");
|
node2.wait_until_succeeds("etcdctl cluster-health")
|
||||||
$node1->succeed("etcdctl set /foo/bar 'Hello world'");
|
node1.succeed("etcdctl set /foo/bar 'Hello world'")
|
||||||
$node2->succeed("etcdctl get /foo/bar | grep 'Hello world'");
|
node2.succeed("etcdctl get /foo/bar | grep 'Hello world'")
|
||||||
};
|
|
||||||
|
|
||||||
subtest "should add another member", sub {
|
with subtest("should add another member"):
|
||||||
$node1->waitUntilSucceeds("etcdctl member add node3 https://node3:2380");
|
node1.wait_until_succeeds("etcdctl member add node3 https://node3:2380")
|
||||||
$node3->start();
|
node3.start()
|
||||||
$node3->waitForUnit("etcd.service");
|
node3.wait_for_unit("etcd.service")
|
||||||
$node3->waitUntilSucceeds("etcdctl member list | grep 'node3'");
|
node3.wait_until_succeeds("etcdctl member list | grep 'node3'")
|
||||||
$node3->succeed("etcdctl cluster-health");
|
node3.succeed("etcdctl cluster-health")
|
||||||
};
|
|
||||||
|
|
||||||
subtest "should survive member crash", sub {
|
with subtest("should survive member crash"):
|
||||||
$node3->crash;
|
node3.crash()
|
||||||
$node1->succeed("etcdctl cluster-health");
|
node1.succeed("etcdctl cluster-health")
|
||||||
$node1->succeed("etcdctl set /foo/bar 'Hello degraded world'");
|
node1.succeed("etcdctl set /foo/bar 'Hello degraded world'")
|
||||||
$node1->succeed("etcdctl get /foo/bar | grep 'Hello degraded world'");
|
node1.succeed("etcdctl get /foo/bar | grep 'Hello degraded world'")
|
||||||
};
|
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# This test runs simple etcd node
|
# This test runs simple etcd node
|
||||||
|
|
||||||
import ./make-test.nix ({ pkgs, ... } : {
|
import ./make-test-python.nix ({ pkgs, ... } : {
|
||||||
name = "etcd";
|
name = "etcd";
|
||||||
|
|
||||||
meta = with pkgs.stdenv.lib.maintainers; {
|
meta = with pkgs.stdenv.lib.maintainers; {
|
||||||
@ -14,14 +14,12 @@ import ./make-test.nix ({ pkgs, ... } : {
|
|||||||
};
|
};
|
||||||
|
|
||||||
testScript = ''
|
testScript = ''
|
||||||
subtest "should start etcd node", sub {
|
with subtest("should start etcd node"):
|
||||||
$node->start();
|
node.start()
|
||||||
$node->waitForUnit("etcd.service");
|
node.wait_for_unit("etcd.service")
|
||||||
};
|
|
||||||
|
|
||||||
subtest "should write and read some values to etcd", sub {
|
with subtest("should write and read some values to etcd"):
|
||||||
$node->succeed("etcdctl set /foo/bar 'Hello world'");
|
node.succeed("etcdctl set /foo/bar 'Hello world'")
|
||||||
$node->succeed("etcdctl get /foo/bar | grep 'Hello world'");
|
node.succeed("etcdctl get /foo/bar | grep 'Hello world'")
|
||||||
}
|
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import ./make-test.nix ({ pkgs, ... } : {
|
import ./make-test-python.nix ({ pkgs, ... } : {
|
||||||
name = "fancontrol";
|
name = "fancontrol";
|
||||||
|
|
||||||
machine =
|
machine =
|
||||||
@ -19,7 +19,10 @@ import ./make-test.nix ({ pkgs, ... } : {
|
|||||||
|
|
||||||
# This configuration cannot be valid for the test VM, so it's expected to get an 'outdated' error.
|
# This configuration cannot be valid for the test VM, so it's expected to get an 'outdated' error.
|
||||||
testScript = ''
|
testScript = ''
|
||||||
$machine->waitForUnit("fancontrol.service");
|
start_all()
|
||||||
$machine->waitUntilSucceeds("journalctl -eu fancontrol | grep 'Configuration appears to be outdated'");
|
machine.wait_for_unit("fancontrol.service")
|
||||||
|
machine.wait_until_succeeds(
|
||||||
|
"journalctl -eu fancontrol | grep 'Configuration appears to be outdated'"
|
||||||
|
)
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# Test the firewall module.
|
# Test the firewall module.
|
||||||
|
|
||||||
import ./make-test.nix ( { pkgs, ... } : {
|
import ./make-test-python.nix ( { pkgs, ... } : {
|
||||||
name = "firewall";
|
name = "firewall";
|
||||||
meta = with pkgs.stdenv.lib.maintainers; {
|
meta = with pkgs.stdenv.lib.maintainers; {
|
||||||
maintainers = [ eelco ];
|
maintainers = [ eelco ];
|
||||||
@ -36,30 +36,30 @@ import ./make-test.nix ( { pkgs, ... } : {
|
|||||||
testScript = { nodes, ... }: let
|
testScript = { nodes, ... }: let
|
||||||
newSystem = nodes.walled2.config.system.build.toplevel;
|
newSystem = nodes.walled2.config.system.build.toplevel;
|
||||||
in ''
|
in ''
|
||||||
$walled->start;
|
start_all()
|
||||||
$attacker->start;
|
|
||||||
|
|
||||||
$walled->waitForUnit("firewall");
|
walled.wait_for_unit("firewall")
|
||||||
$walled->waitForUnit("httpd");
|
walled.wait_for_unit("httpd")
|
||||||
$attacker->waitForUnit("network.target");
|
attacker.wait_for_unit("network.target")
|
||||||
|
|
||||||
# Local connections should still work.
|
# Local connections should still work.
|
||||||
$walled->succeed("curl -v http://localhost/ >&2");
|
walled.succeed("curl -v http://localhost/ >&2")
|
||||||
|
|
||||||
# Connections to the firewalled machine should fail, but ping should succeed.
|
# Connections to the firewalled machine should fail, but ping should succeed.
|
||||||
$attacker->fail("curl --fail --connect-timeout 2 http://walled/ >&2");
|
attacker.fail("curl --fail --connect-timeout 2 http://walled/ >&2")
|
||||||
$attacker->succeed("ping -c 1 walled >&2");
|
attacker.succeed("ping -c 1 walled >&2")
|
||||||
|
|
||||||
# Outgoing connections/pings should still work.
|
# Outgoing connections/pings should still work.
|
||||||
$walled->succeed("curl -v http://attacker/ >&2");
|
walled.succeed("curl -v http://attacker/ >&2")
|
||||||
$walled->succeed("ping -c 1 attacker >&2");
|
walled.succeed("ping -c 1 attacker >&2")
|
||||||
|
|
||||||
# If we stop the firewall, then connections should succeed.
|
# If we stop the firewall, then connections should succeed.
|
||||||
$walled->stopJob("firewall");
|
walled.stop_job("firewall")
|
||||||
$attacker->succeed("curl -v http://walled/ >&2");
|
attacker.succeed("curl -v http://walled/ >&2")
|
||||||
|
|
||||||
# Check whether activation of a new configuration reloads the firewall.
|
# Check whether activation of a new configuration reloads the firewall.
|
||||||
$walled->succeed("${newSystem}/bin/switch-to-configuration test 2>&1" .
|
walled.succeed(
|
||||||
" | grep -qF firewall.service");
|
"${newSystem}/bin/switch-to-configuration test 2>&1 | grep -qF firewall.service"
|
||||||
|
)
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import ./make-test.nix ({ pkgs, ... }: {
|
import ./make-test-python.nix ({ pkgs, ... }: {
|
||||||
name = "fish";
|
name = "fish";
|
||||||
|
|
||||||
machine =
|
machine =
|
||||||
@ -14,8 +14,11 @@ import ./make-test.nix ({ pkgs, ... }: {
|
|||||||
|
|
||||||
testScript =
|
testScript =
|
||||||
''
|
''
|
||||||
$machine->waitForFile("/etc/fish/generated_completions/coreutils.fish");
|
start_all()
|
||||||
$machine->waitForFile("/etc/fish/generated_completions/kill.fish");
|
machine.wait_for_file("/etc/fish/generated_completions/coreutils.fish")
|
||||||
$machine->succeed("fish -ic 'echo \$fish_complete_path' | grep -q '/share/fish/completions /etc/fish/generated_completions /root/.local/share/fish/generated_completions\$'");
|
machine.wait_for_file("/etc/fish/generated_completions/kill.fish")
|
||||||
|
machine.succeed(
|
||||||
|
"fish -ic 'echo $fish_complete_path' | grep -q '/share/fish/completions /etc/fish/generated_completions /root/.local/share/fish/generated_completions$'"
|
||||||
|
)
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import ./make-test.nix ({ pkgs, lib, ... }: {
|
import ./make-test-python.nix ({ pkgs, lib, ... }: {
|
||||||
name = "fluentd";
|
name = "fluentd";
|
||||||
|
|
||||||
machine = { pkgs, ... }: {
|
machine = { pkgs, ... }: {
|
||||||
@ -33,14 +33,17 @@ import ./make-test.nix ({ pkgs, lib, ... }: {
|
|||||||
inherit testMessage;
|
inherit testMessage;
|
||||||
});
|
});
|
||||||
in ''
|
in ''
|
||||||
$machine->start;
|
machine.start()
|
||||||
$machine->waitForUnit('fluentd.service');
|
machine.wait_for_unit("fluentd.service")
|
||||||
$machine->waitForOpenPort(9880);
|
machine.wait_for_open_port(9880)
|
||||||
|
|
||||||
$machine->succeed("curl -fsSL -X POST -H 'Content-type: application/json' -d @${payload} http://localhost:9880/test.tag");
|
machine.succeed(
|
||||||
|
"curl -fsSL -X POST -H 'Content-type: application/json' -d @${payload} http://localhost:9880/test.tag"
|
||||||
|
)
|
||||||
|
|
||||||
$machine->succeed("systemctl stop fluentd"); # blocking flush
|
# blocking flush
|
||||||
|
machine.succeed("systemctl stop fluentd")
|
||||||
|
|
||||||
$machine->succeed("grep '${testMessage}' /tmp/current-log");
|
machine.succeed("grep '${testMessage}' /tmp/current-log")
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
let
|
let
|
||||||
initialRootPassword = "notproduction";
|
initialRootPassword = "notproduction";
|
||||||
in
|
in
|
||||||
import ./make-test.nix ({ pkgs, lib, ...} : with lib; {
|
import ./make-test-python.nix ({ pkgs, lib, ...} : with lib; {
|
||||||
name = "gitlab";
|
name = "gitlab";
|
||||||
meta = with pkgs.stdenv.lib.maintainers; {
|
meta = with pkgs.stdenv.lib.maintainers; {
|
||||||
maintainers = [ globin ];
|
maintainers = [ globin ];
|
||||||
@ -63,21 +63,35 @@ import ./make-test.nix ({ pkgs, lib, ...} : with lib; {
|
|||||||
});
|
});
|
||||||
in
|
in
|
||||||
''
|
''
|
||||||
$gitlab->start();
|
gitlab.start()
|
||||||
$gitlab->waitForUnit("gitaly.service");
|
gitlab.wait_for_unit("gitaly.service")
|
||||||
$gitlab->waitForUnit("gitlab-workhorse.service");
|
gitlab.wait_for_unit("gitlab-workhorse.service")
|
||||||
$gitlab->waitForUnit("gitlab.service");
|
gitlab.wait_for_unit("gitlab.service")
|
||||||
$gitlab->waitForUnit("gitlab-sidekiq.service");
|
gitlab.wait_for_unit("gitlab-sidekiq.service")
|
||||||
$gitlab->waitForFile("/var/gitlab/state/tmp/sockets/gitlab.socket");
|
gitlab.wait_for_file("/var/gitlab/state/tmp/sockets/gitlab.socket")
|
||||||
$gitlab->waitUntilSucceeds("curl -sSf http://gitlab/users/sign_in");
|
gitlab.wait_until_succeeds("curl -sSf http://gitlab/users/sign_in")
|
||||||
$gitlab->succeed("curl -isSf http://gitlab | grep -i location | grep -q http://gitlab/users/sign_in");
|
gitlab.succeed(
|
||||||
$gitlab->succeed("${pkgs.sudo}/bin/sudo -u gitlab -H gitlab-rake gitlab:check 1>&2");
|
"curl -isSf http://gitlab | grep -i location | grep -q http://gitlab/users/sign_in"
|
||||||
$gitlab->succeed("echo \"Authorization: Bearer \$(curl -X POST -H 'Content-Type: application/json' -d @${auth} http://gitlab/oauth/token | ${pkgs.jq}/bin/jq -r '.access_token')\" >/tmp/headers");
|
)
|
||||||
$gitlab->succeed("curl -X POST -H 'Content-Type: application/json' -H @/tmp/headers -d @${createProject} http://gitlab/api/v4/projects");
|
gitlab.succeed(
|
||||||
$gitlab->succeed("curl -X POST -H 'Content-Type: application/json' -H @/tmp/headers -d @${putFile} http://gitlab/api/v4/projects/1/repository/files/some-file.txt");
|
"${pkgs.sudo}/bin/sudo -u gitlab -H gitlab-rake gitlab:check 1>&2"
|
||||||
$gitlab->succeed("curl -H @/tmp/headers http://gitlab/api/v4/projects/1/repository/archive.tar.gz > /tmp/archive.tar.gz");
|
)
|
||||||
$gitlab->succeed("curl -H @/tmp/headers http://gitlab/api/v4/projects/1/repository/archive.tar.bz2 > /tmp/archive.tar.bz2");
|
gitlab.succeed(
|
||||||
$gitlab->succeed("test -s /tmp/archive.tar.gz");
|
"echo \"Authorization: Bearer \$(curl -X POST -H 'Content-Type: application/json' -d @${auth} http://gitlab/oauth/token | ${pkgs.jq}/bin/jq -r '.access_token')\" >/tmp/headers"
|
||||||
$gitlab->succeed("test -s /tmp/archive.tar.bz2");
|
)
|
||||||
|
gitlab.succeed(
|
||||||
|
"curl -X POST -H 'Content-Type: application/json' -H @/tmp/headers -d @${createProject} http://gitlab/api/v4/projects"
|
||||||
|
)
|
||||||
|
gitlab.succeed(
|
||||||
|
"curl -X POST -H 'Content-Type: application/json' -H @/tmp/headers -d @${putFile} http://gitlab/api/v4/projects/1/repository/files/some-file.txt"
|
||||||
|
)
|
||||||
|
gitlab.succeed(
|
||||||
|
"curl -H @/tmp/headers http://gitlab/api/v4/projects/1/repository/archive.tar.gz > /tmp/archive.tar.gz"
|
||||||
|
)
|
||||||
|
gitlab.succeed(
|
||||||
|
"curl -H @/tmp/headers http://gitlab/api/v4/projects/1/repository/archive.tar.bz2 > /tmp/archive.tar.bz2"
|
||||||
|
)
|
||||||
|
gitlab.succeed("test -s /tmp/archive.tar.gz")
|
||||||
|
gitlab.succeed("test -s /tmp/archive.tar.bz2")
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import ./make-test.nix ({ pkgs, ...}:
|
import ./make-test-python.nix ({ pkgs, ...}:
|
||||||
|
|
||||||
let
|
let
|
||||||
adminPrivateKey = pkgs.writeText "id_ed25519" ''
|
adminPrivateKey = pkgs.writeText "id_ed25519" ''
|
||||||
@ -43,7 +43,7 @@ let
|
|||||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJZNonUP1ePHLrvn0W9D2hdN6zWWZYFyJc+QR6pOKQEw bob@client
|
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJZNonUP1ePHLrvn0W9D2hdN6zWWZYFyJc+QR6pOKQEw bob@client
|
||||||
'';
|
'';
|
||||||
|
|
||||||
gitoliteAdminConfSnippet = ''
|
gitoliteAdminConfSnippet = pkgs.writeText "gitolite-admin-conf-snippet" ''
|
||||||
repo alice-project
|
repo alice-project
|
||||||
RW+ = alice
|
RW+ = alice
|
||||||
'';
|
'';
|
||||||
@ -85,55 +85,54 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
testScript = ''
|
testScript = ''
|
||||||
startAll;
|
start_all()
|
||||||
|
|
||||||
subtest "can setup ssh keys on system", sub {
|
with subtest("can setup ssh keys on system"):
|
||||||
$client->mustSucceed("mkdir -p ~root/.ssh");
|
client.succeed(
|
||||||
$client->mustSucceed("cp ${adminPrivateKey} ~root/.ssh/id_ed25519");
|
"mkdir -p ~root/.ssh",
|
||||||
$client->mustSucceed("chmod 600 ~root/.ssh/id_ed25519");
|
"cp ${adminPrivateKey} ~root/.ssh/id_ed25519",
|
||||||
|
"chmod 600 ~root/.ssh/id_ed25519",
|
||||||
|
)
|
||||||
|
client.succeed(
|
||||||
|
"sudo -u alice mkdir -p ~alice/.ssh",
|
||||||
|
"sudo -u alice cp ${alicePrivateKey} ~alice/.ssh/id_ed25519",
|
||||||
|
"sudo -u alice chmod 600 ~alice/.ssh/id_ed25519",
|
||||||
|
)
|
||||||
|
client.succeed(
|
||||||
|
"sudo -u bob mkdir -p ~bob/.ssh",
|
||||||
|
"sudo -u bob cp ${bobPrivateKey} ~bob/.ssh/id_ed25519",
|
||||||
|
"sudo -u bob chmod 600 ~bob/.ssh/id_ed25519",
|
||||||
|
)
|
||||||
|
|
||||||
$client->mustSucceed("sudo -u alice mkdir -p ~alice/.ssh");
|
with subtest("gitolite server starts"):
|
||||||
$client->mustSucceed("sudo -u alice cp ${alicePrivateKey} ~alice/.ssh/id_ed25519");
|
server.wait_for_unit("gitolite-init.service")
|
||||||
$client->mustSucceed("sudo -u alice chmod 600 ~alice/.ssh/id_ed25519");
|
server.wait_for_unit("sshd.service")
|
||||||
|
client.succeed("ssh gitolite@server info")
|
||||||
|
|
||||||
$client->mustSucceed("sudo -u bob mkdir -p ~bob/.ssh");
|
with subtest("admin can clone and configure gitolite-admin.git"):
|
||||||
$client->mustSucceed("sudo -u bob cp ${bobPrivateKey} ~bob/.ssh/id_ed25519");
|
client.succeed(
|
||||||
$client->mustSucceed("sudo -u bob chmod 600 ~bob/.ssh/id_ed25519");
|
"git clone gitolite@server:gitolite-admin.git",
|
||||||
};
|
"git config --global user.name 'System Administrator'",
|
||||||
|
"git config --global user.email root\@domain.example",
|
||||||
|
"cp ${alicePublicKey} gitolite-admin/keydir/alice.pub",
|
||||||
|
"cp ${bobPublicKey} gitolite-admin/keydir/bob.pub",
|
||||||
|
"(cd gitolite-admin && git add . && git commit -m 'Add keys for alice, bob' && git push)",
|
||||||
|
"cat ${gitoliteAdminConfSnippet} >> gitolite-admin/conf/gitolite.conf",
|
||||||
|
"(cd gitolite-admin && git add . && git commit -m 'Add repo for alice' && git push)",
|
||||||
|
)
|
||||||
|
|
||||||
subtest "gitolite server starts", sub {
|
with subtest("non-admins cannot clone gitolite-admin.git"):
|
||||||
$server->waitForUnit("gitolite-init.service");
|
client.fail("sudo -i -u alice git clone gitolite@server:gitolite-admin.git")
|
||||||
$server->waitForUnit("sshd.service");
|
client.fail("sudo -i -u bob git clone gitolite@server:gitolite-admin.git")
|
||||||
$client->mustSucceed('ssh gitolite@server info');
|
|
||||||
};
|
|
||||||
|
|
||||||
subtest "admin can clone and configure gitolite-admin.git", sub {
|
with subtest("non-admins can clone testing.git"):
|
||||||
$client->mustSucceed('git clone gitolite@server:gitolite-admin.git');
|
client.succeed("sudo -i -u alice git clone gitolite@server:testing.git")
|
||||||
$client->mustSucceed("git config --global user.name 'System Administrator'");
|
client.succeed("sudo -i -u bob git clone gitolite@server:testing.git")
|
||||||
$client->mustSucceed("git config --global user.email root\@domain.example");
|
|
||||||
$client->mustSucceed("cp ${alicePublicKey} gitolite-admin/keydir/alice.pub");
|
|
||||||
$client->mustSucceed("cp ${bobPublicKey} gitolite-admin/keydir/bob.pub");
|
|
||||||
$client->mustSucceed('(cd gitolite-admin && git add . && git commit -m "Add keys for alice, bob" && git push)');
|
|
||||||
$client->mustSucceed("printf '${gitoliteAdminConfSnippet}' >> gitolite-admin/conf/gitolite.conf");
|
|
||||||
$client->mustSucceed('(cd gitolite-admin && git add . && git commit -m "Add repo for alice" && git push)');
|
|
||||||
};
|
|
||||||
|
|
||||||
subtest "non-admins cannot clone gitolite-admin.git", sub {
|
with subtest("alice can clone alice-project.git"):
|
||||||
$client->mustFail('sudo -i -u alice git clone gitolite@server:gitolite-admin.git');
|
client.succeed("sudo -i -u alice git clone gitolite@server:alice-project.git")
|
||||||
$client->mustFail('sudo -i -u bob git clone gitolite@server:gitolite-admin.git');
|
|
||||||
};
|
|
||||||
|
|
||||||
subtest "non-admins can clone testing.git", sub {
|
with subtest("bob cannot clone alice-project.git"):
|
||||||
$client->mustSucceed('sudo -i -u alice git clone gitolite@server:testing.git');
|
client.fail("sudo -i -u bob git clone gitolite@server:alice-project.git")
|
||||||
$client->mustSucceed('sudo -i -u bob git clone gitolite@server:testing.git');
|
|
||||||
};
|
|
||||||
|
|
||||||
subtest "alice can clone alice-project.git", sub {
|
|
||||||
$client->mustSucceed('sudo -i -u alice git clone gitolite@server:alice-project.git');
|
|
||||||
};
|
|
||||||
|
|
||||||
subtest "bob cannot clone alice-project.git", sub {
|
|
||||||
$client->mustFail('sudo -i -u bob git clone gitolite@server:alice-project.git');
|
|
||||||
};
|
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import ./make-test.nix ({ ... } :
|
import ./make-test-python.nix ({pkgs, lib, ...}:
|
||||||
|
|
||||||
let
|
let
|
||||||
client = { pkgs, ... } : {
|
client = { pkgs, ... } : {
|
||||||
@ -39,27 +39,29 @@ in {
|
|||||||
};
|
};
|
||||||
|
|
||||||
testScript = ''
|
testScript = ''
|
||||||
$server1->waitForUnit("glusterd.service");
|
server1.wait_for_unit("glusterd.service")
|
||||||
$server2->waitForUnit("glusterd.service");
|
server2.wait_for_unit("glusterd.service")
|
||||||
|
|
||||||
|
server1.wait_until_succeeds("gluster peer status")
|
||||||
|
server2.wait_until_succeeds("gluster peer status")
|
||||||
|
|
||||||
# establish initial contact
|
# establish initial contact
|
||||||
$server1->succeed("sleep 2");
|
server1.succeed("gluster peer probe server2")
|
||||||
$server1->succeed("gluster peer probe server2");
|
server1.succeed("gluster peer probe server1")
|
||||||
$server1->succeed("gluster peer probe server1");
|
|
||||||
|
|
||||||
$server1->succeed("gluster peer status | grep Connected");
|
server1.succeed("gluster peer status | grep Connected")
|
||||||
|
|
||||||
# create volumes
|
# create volumes
|
||||||
$server1->succeed("mkdir -p /data/vg0");
|
server1.succeed("mkdir -p /data/vg0")
|
||||||
$server2->succeed("mkdir -p /data/vg0");
|
server2.succeed("mkdir -p /data/vg0")
|
||||||
$server1->succeed("gluster volume create gv0 server1:/data/vg0 server2:/data/vg0");
|
server1.succeed("gluster volume create gv0 server1:/data/vg0 server2:/data/vg0")
|
||||||
$server1->succeed("gluster volume start gv0");
|
server1.succeed("gluster volume start gv0")
|
||||||
|
|
||||||
# test clients
|
# test clients
|
||||||
$client1->waitForUnit("gluster.mount");
|
client1.wait_for_unit("gluster.mount")
|
||||||
$client2->waitForUnit("gluster.mount");
|
client2.wait_for_unit("gluster.mount")
|
||||||
|
|
||||||
$client1->succeed("echo test > /gluster/file1");
|
client1.succeed("echo test > /gluster/file1")
|
||||||
$client2->succeed("grep test /gluster/file1");
|
client2.succeed("grep test /gluster/file1")
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
|
@ -1,7 +1,14 @@
|
|||||||
import ../make-test.nix ({ pkgs, ... } :
|
import ../make-test-python.nix ({ pkgs, ... } :
|
||||||
let
|
let
|
||||||
inherit (import ./../ssh-keys.nix pkgs)
|
inherit (import ./../ssh-keys.nix pkgs)
|
||||||
snakeOilPrivateKey snakeOilPublicKey;
|
snakeOilPrivateKey snakeOilPublicKey;
|
||||||
|
|
||||||
|
# don't check host keys or known hosts, use the snakeoil ssh key
|
||||||
|
ssh-config = builtins.toFile "ssh.conf" ''
|
||||||
|
UserKnownHostsFile=/dev/null
|
||||||
|
StrictHostKeyChecking=no
|
||||||
|
IdentityFile=~/.ssh/id_snakeoil
|
||||||
|
'';
|
||||||
in {
|
in {
|
||||||
name = "google-oslogin";
|
name = "google-oslogin";
|
||||||
meta = with pkgs.stdenv.lib.maintainers; {
|
meta = with pkgs.stdenv.lib.maintainers; {
|
||||||
@ -15,38 +22,49 @@ in {
|
|||||||
client = { ... }: {};
|
client = { ... }: {};
|
||||||
};
|
};
|
||||||
testScript = ''
|
testScript = ''
|
||||||
startAll;
|
start_all()
|
||||||
|
|
||||||
$server->waitForUnit("mock-google-metadata.service");
|
server.wait_for_unit("mock-google-metadata.service")
|
||||||
$server->waitForOpenPort(80);
|
server.wait_for_open_port(80)
|
||||||
|
|
||||||
# mockserver should return a non-expired ssh key for both mockuser and mockadmin
|
# mockserver should return a non-expired ssh key for both mockuser and mockadmin
|
||||||
$server->succeed('${pkgs.google-compute-engine-oslogin}/bin/google_authorized_keys mockuser | grep -q "${snakeOilPublicKey}"');
|
server.succeed(
|
||||||
$server->succeed('${pkgs.google-compute-engine-oslogin}/bin/google_authorized_keys mockadmin | grep -q "${snakeOilPublicKey}"');
|
'${pkgs.google-compute-engine-oslogin}/bin/google_authorized_keys mockuser | grep -q "${snakeOilPublicKey}"'
|
||||||
|
)
|
||||||
|
server.succeed(
|
||||||
|
'${pkgs.google-compute-engine-oslogin}/bin/google_authorized_keys mockadmin | grep -q "${snakeOilPublicKey}"'
|
||||||
|
)
|
||||||
|
|
||||||
# install snakeoil ssh key on the client
|
# install snakeoil ssh key on the client, and provision .ssh/config file
|
||||||
$client->succeed("mkdir -p ~/.ssh");
|
client.succeed("mkdir -p ~/.ssh")
|
||||||
$client->succeed("cat ${snakeOilPrivateKey} > ~/.ssh/id_snakeoil");
|
client.succeed(
|
||||||
$client->succeed("chmod 600 ~/.ssh/id_snakeoil");
|
"cat ${snakeOilPrivateKey} > ~/.ssh/id_snakeoil"
|
||||||
|
)
|
||||||
|
client.succeed("chmod 600 ~/.ssh/id_snakeoil")
|
||||||
|
client.succeed("cp ${ssh-config} ~/.ssh/config")
|
||||||
|
|
||||||
$client->waitForUnit("network.target");
|
client.wait_for_unit("network.target")
|
||||||
$server->waitForUnit("sshd.service");
|
server.wait_for_unit("sshd.service")
|
||||||
|
|
||||||
# we should not be able to connect as non-existing user
|
# we should not be able to connect as non-existing user
|
||||||
$client->fail("ssh -o User=ghost -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no server -i ~/.ssh/id_snakeoil 'true'");
|
client.fail("ssh ghost@server 'true'")
|
||||||
|
|
||||||
# we should be able to connect as mockuser
|
# we should be able to connect as mockuser
|
||||||
$client->succeed("ssh -o User=mockuser -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no server -i ~/.ssh/id_snakeoil 'true'");
|
client.succeed("ssh mockuser@server 'true'")
|
||||||
# but we shouldn't be able to sudo
|
# but we shouldn't be able to sudo
|
||||||
$client->fail("ssh -o User=mockuser -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no server -i ~/.ssh/id_snakeoil '/run/wrappers/bin/sudo /run/current-system/sw/bin/id' | grep -q 'root'");
|
client.fail(
|
||||||
|
"ssh mockuser@server '/run/wrappers/bin/sudo /run/current-system/sw/bin/id' | grep -q 'root'"
|
||||||
|
)
|
||||||
|
|
||||||
# we should also be able to log in as mockadmin
|
# we should also be able to log in as mockadmin
|
||||||
$client->succeed("ssh -o User=mockadmin -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no server -i ~/.ssh/id_snakeoil 'true'");
|
client.succeed("ssh mockadmin@server 'true'")
|
||||||
# pam_oslogin_admin.so should now have generated a sudoers file
|
# pam_oslogin_admin.so should now have generated a sudoers file
|
||||||
$server->succeed("find /run/google-sudoers.d | grep -q '/run/google-sudoers.d/mockadmin'");
|
server.succeed("find /run/google-sudoers.d | grep -q '/run/google-sudoers.d/mockadmin'")
|
||||||
|
|
||||||
# and we should be able to sudo
|
# and we should be able to sudo
|
||||||
$client->succeed("ssh -o User=mockadmin -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no server -i ~/.ssh/id_snakeoil '/run/wrappers/bin/sudo /run/current-system/sw/bin/id' | grep -q 'root'");
|
client.succeed(
|
||||||
|
"ssh mockadmin@server '/run/wrappers/bin/sudo /run/current-system/sw/bin/id' | grep -q 'root'"
|
||||||
|
)
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import ./make-test.nix ({ pkgs, lib, ...} : {
|
import ./make-test-python.nix ({ pkgs, lib, ...} : {
|
||||||
name = "gotify-server";
|
name = "gotify-server";
|
||||||
meta = with pkgs.stdenv.lib.maintainers; {
|
meta = with pkgs.stdenv.lib.maintainers; {
|
||||||
maintainers = [ ma27 ];
|
maintainers = [ ma27 ];
|
||||||
@ -14,32 +14,32 @@ import ./make-test.nix ({ pkgs, lib, ...} : {
|
|||||||
};
|
};
|
||||||
|
|
||||||
testScript = ''
|
testScript = ''
|
||||||
startAll;
|
machine.start()
|
||||||
|
|
||||||
$machine->waitForUnit("gotify-server");
|
machine.wait_for_unit("gotify-server.service")
|
||||||
$machine->waitForOpenPort(3000);
|
machine.wait_for_open_port(3000)
|
||||||
|
|
||||||
my $token = $machine->succeed(
|
token = machine.succeed(
|
||||||
"curl --fail -sS -X POST localhost:3000/application -F name=nixos " .
|
"curl --fail -sS -X POST localhost:3000/application -F name=nixos "
|
||||||
'-H "Authorization: Basic $(echo -ne "admin:admin" | base64 --wrap 0)" ' .
|
+ '-H "Authorization: Basic $(echo -ne "admin:admin" | base64 --wrap 0)" '
|
||||||
'| jq .token | xargs echo -n'
|
+ "| jq .token | xargs echo -n"
|
||||||
);
|
)
|
||||||
|
|
||||||
my $usertoken = $machine->succeed(
|
usertoken = machine.succeed(
|
||||||
"curl --fail -sS -X POST localhost:3000/client -F name=nixos " .
|
"curl --fail -sS -X POST localhost:3000/client -F name=nixos "
|
||||||
'-H "Authorization: Basic $(echo -ne "admin:admin" | base64 --wrap 0)" ' .
|
+ '-H "Authorization: Basic $(echo -ne "admin:admin" | base64 --wrap 0)" '
|
||||||
'| jq .token | xargs echo -n'
|
+ "| jq .token | xargs echo -n"
|
||||||
);
|
)
|
||||||
|
|
||||||
$machine->succeed(
|
machine.succeed(
|
||||||
"curl --fail -sS -X POST 'localhost:3000/message?token=$token' -H 'Accept: application/json' " .
|
f"curl --fail -sS -X POST 'localhost:3000/message?token={token}' -H 'Accept: application/json' "
|
||||||
'-F title=Gotify -F message=Works'
|
+ "-F title=Gotify -F message=Works"
|
||||||
);
|
)
|
||||||
|
|
||||||
my $title = $machine->succeed(
|
title = machine.succeed(
|
||||||
"curl --fail -sS 'localhost:3000/message?since=0&token=$usertoken' | jq '.messages|.[0]|.title' | xargs echo -n"
|
f"curl --fail -sS 'localhost:3000/message?since=0&token={usertoken}' | jq '.messages|.[0]|.title' | xargs echo -n"
|
||||||
);
|
)
|
||||||
|
|
||||||
$title eq "Gotify" or die "Wrong title ($title), expected 'Gotify'!";
|
assert title == "Gotify"
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import ./make-test.nix ({ pkgs, lib, ... }: {
|
import ./make-test-python.nix ({ pkgs, lib, ... }: {
|
||||||
name = "graylog";
|
name = "graylog";
|
||||||
meta.maintainers = with lib.maintainers; [ ma27 ];
|
meta.maintainers = with lib.maintainers; [ ma27 ];
|
||||||
|
|
||||||
@ -64,48 +64,52 @@ import ./make-test.nix ({ pkgs, lib, ... }: {
|
|||||||
facility = "Test";
|
facility = "Test";
|
||||||
});
|
});
|
||||||
in ''
|
in ''
|
||||||
$machine->start;
|
machine.start()
|
||||||
$machine->waitForUnit("graylog.service");
|
machine.wait_for_unit("graylog.service")
|
||||||
$machine->waitForOpenPort(9000);
|
machine.wait_for_open_port(9000)
|
||||||
$machine->succeed("curl -sSfL http://127.0.0.1:9000/");
|
machine.succeed("curl -sSfL http://127.0.0.1:9000/")
|
||||||
|
|
||||||
my $session = $machine->succeed("curl -X POST "
|
session = machine.succeed(
|
||||||
. "-sSfL http://127.0.0.1:9000/api/system/sessions "
|
"curl -X POST "
|
||||||
. "-d \$(cat ${payloads.login}) "
|
+ "-sSfL http://127.0.0.1:9000/api/system/sessions "
|
||||||
. "-H 'Content-Type: application/json' "
|
+ "-d $(cat ${payloads.login}) "
|
||||||
. "-H 'Accept: application/json' "
|
+ "-H 'Content-Type: application/json' "
|
||||||
. "-H 'x-requested-by: cli' "
|
+ "-H 'Accept: application/json' "
|
||||||
. "| jq .session_id | xargs echo"
|
+ "-H 'x-requested-by: cli' "
|
||||||
);
|
+ "| jq .session_id | xargs echo"
|
||||||
|
).rstrip()
|
||||||
|
|
||||||
chomp($session);
|
machine.succeed(
|
||||||
|
"curl -X POST "
|
||||||
|
+ f"-sSfL http://127.0.0.1:9000/api/system/inputs -u {session}:session "
|
||||||
|
+ '-d $(cat ${payloads.input} | sed -e "s,@node@,$(cat /var/lib/graylog/server/node-id),") '
|
||||||
|
+ "-H 'Accept: application/json' "
|
||||||
|
+ "-H 'Content-Type: application/json' "
|
||||||
|
+ "-H 'x-requested-by: cli' "
|
||||||
|
)
|
||||||
|
|
||||||
$machine->succeed("curl -X POST "
|
machine.wait_until_succeeds(
|
||||||
. "-sSfL http://127.0.0.1:9000/api/system/inputs -u $session:session "
|
"test \"$(curl -sSfL 'http://127.0.0.1:9000/api/cluster/inputstates' "
|
||||||
. "-d \$(cat ${payloads.input} | sed -e \"s,\@node\@,\$(cat /var/lib/graylog/server/node-id),\") "
|
+ f"-u {session}:session "
|
||||||
. "-H 'Accept: application/json' "
|
+ "-H 'Accept: application/json' "
|
||||||
. "-H 'Content-Type: application/json' "
|
+ "-H 'Content-Type: application/json' "
|
||||||
. "-H 'x-requested-by: cli' "
|
+ "-H 'x-requested-by: cli'"
|
||||||
);
|
+ "| jq 'to_entries[]|.value|.[0]|.state' | xargs echo"
|
||||||
|
+ ')" = "RUNNING"'
|
||||||
|
)
|
||||||
|
|
||||||
$machine->waitUntilSucceeds("test \"\$(curl -sSfL 'http://127.0.0.1:9000/api/cluster/inputstates' "
|
machine.succeed(
|
||||||
. "-u $session:session "
|
"echo -n $(cat ${payloads.gelf_message}) | nc -w10 -u 127.0.0.1 12201"
|
||||||
. "-H 'Accept: application/json' "
|
)
|
||||||
. "-H 'Content-Type: application/json' "
|
|
||||||
. "-H 'x-requested-by: cli'"
|
|
||||||
. "| jq 'to_entries[]|.value|.[0]|.state' | xargs echo"
|
|
||||||
. ")\" = \"RUNNING\""
|
|
||||||
);
|
|
||||||
|
|
||||||
$machine->succeed("echo -n \$(cat ${payloads.gelf_message}) | nc -w10 -u 127.0.0.1 12201");
|
machine.succeed(
|
||||||
|
'test "$(curl -X GET '
|
||||||
$machine->succeed("test \"\$(curl -X GET "
|
+ "-sSfL 'http://127.0.0.1:9000/api/search/universal/relative?query=*' "
|
||||||
. "-sSfL 'http://127.0.0.1:9000/api/search/universal/relative?query=*' "
|
+ f"-u {session}:session "
|
||||||
. "-u $session:session "
|
+ "-H 'Accept: application/json' "
|
||||||
. "-H 'Accept: application/json' "
|
+ "-H 'Content-Type: application/json' "
|
||||||
. "-H 'Content-Type: application/json' "
|
+ "-H 'x-requested-by: cli'"
|
||||||
. "-H 'x-requested-by: cli'"
|
+ ' | jq \'.total_results\' | xargs echo)" = "1"'
|
||||||
. " | jq '.total_results' | xargs echo)\" = \"1\""
|
)
|
||||||
);
|
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import ./make-test.nix ({ pkgs, ... }:
|
import ./make-test-python.nix ({ pkgs, ... }:
|
||||||
let
|
let
|
||||||
# Download Big Buck Bunny example, licensed under CC Attribution 3.0.
|
# Download Big Buck Bunny example, licensed under CC Attribution 3.0.
|
||||||
testMkv = pkgs.fetchurl {
|
testMkv = pkgs.fetchurl {
|
||||||
@ -19,7 +19,13 @@ in {
|
|||||||
testScript = ''
|
testScript = ''
|
||||||
# Test MP4 and MKV transcoding. Since this is a short clip, transcoding typically
|
# Test MP4 and MKV transcoding. Since this is a short clip, transcoding typically
|
||||||
# only takes a few seconds.
|
# only takes a few seconds.
|
||||||
$machine->succeed("HandBrakeCLI -i ${testMkv} -o test.mp4 -e x264 -q 20 -B 160");
|
start_all()
|
||||||
$machine->succeed("HandBrakeCLI -i ${testMkv} -o test.mkv -e x264 -q 20 -B 160");
|
|
||||||
|
machine.succeed(
|
||||||
|
"HandBrakeCLI -i ${testMkv} -o test.mp4 -e x264 -q 20 -B 160"
|
||||||
|
)
|
||||||
|
machine.succeed(
|
||||||
|
"HandBrakeCLI -i ${testMkv} -o test.mkv -e x264 -q 20 -B 160"
|
||||||
|
)
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# Test whether hibernation from partition works.
|
# Test whether hibernation from partition works.
|
||||||
|
|
||||||
import ./make-test.nix (pkgs: {
|
import ./make-test-python.nix (pkgs: {
|
||||||
name = "hibernate";
|
name = "hibernate";
|
||||||
|
|
||||||
nodes = {
|
nodes = {
|
||||||
@ -28,16 +28,17 @@ import ./make-test.nix (pkgs: {
|
|||||||
|
|
||||||
testScript =
|
testScript =
|
||||||
''
|
''
|
||||||
$machine->waitForUnit("multi-user.target");
|
machine.start()
|
||||||
$machine->succeed("mkswap /dev/vdb");
|
machine.wait_for_unit("multi-user.target")
|
||||||
$machine->succeed("swapon -a");
|
machine.succeed("mkswap /dev/vdb")
|
||||||
$machine->startJob("listener");
|
machine.succeed("swapon -a")
|
||||||
$machine->waitForOpenPort(4444);
|
machine.start_job("listener")
|
||||||
$machine->succeed("systemctl hibernate &");
|
machine.wait_for_open_port(4444)
|
||||||
$machine->waitForShutdown;
|
machine.succeed("systemctl hibernate &")
|
||||||
$probe->waitForUnit("multi-user.target");
|
machine.wait_for_shutdown()
|
||||||
$machine->start;
|
probe.wait_for_unit("multi-user.target")
|
||||||
$probe->waitUntilSucceeds("echo test | nc machine 4444 -N");
|
machine.start()
|
||||||
|
probe.wait_until_succeeds("echo test | nc machine 4444 -N")
|
||||||
'';
|
'';
|
||||||
|
|
||||||
})
|
})
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# Test whether `houndd` indexes nixpkgs
|
# Test whether `houndd` indexes nixpkgs
|
||||||
import ./make-test.nix ({ pkgs, ... } : {
|
import ./make-test-python.nix ({ pkgs, ... } : {
|
||||||
name = "hound";
|
name = "hound";
|
||||||
meta = with pkgs.stdenv.lib.maintainers; {
|
meta = with pkgs.stdenv.lib.maintainers; {
|
||||||
maintainers = [ grahamc ];
|
maintainers = [ grahamc ];
|
||||||
@ -46,13 +46,14 @@ import ./make-test.nix ({ pkgs, ... } : {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
testScript =
|
testScript = ''
|
||||||
'' startAll;
|
start_all()
|
||||||
|
|
||||||
$machine->waitForUnit("network.target");
|
|
||||||
$machine->waitForUnit("hound.service");
|
|
||||||
$machine->waitForOpenPort(6080);
|
|
||||||
$machine->waitUntilSucceeds('curl http://127.0.0.1:6080/api/v1/search\?stats\=fosho\&repos\=\*\&rng=%3A20\&q\=hi\&files\=\&i=nope | grep "Filename" | grep "hello"');
|
|
||||||
|
|
||||||
|
machine.wait_for_unit("network.target")
|
||||||
|
machine.wait_for_unit("hound.service")
|
||||||
|
machine.wait_for_open_port(6080)
|
||||||
|
machine.wait_until_succeeds(
|
||||||
|
"curl http://127.0.0.1:6080/api/v1/search\?stats\=fosho\&repos\=\*\&rng=%3A20\&q\=hi\&files\=\&i=nope | grep 'Filename' | grep 'hello'"
|
||||||
|
)
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import ./make-test.nix ({ pkgs, ... }: {
|
import ./make-test-python.nix ({ pkgs, ... }: {
|
||||||
name = "icingaweb2";
|
name = "icingaweb2";
|
||||||
meta = with pkgs.stdenv.lib.maintainers; {
|
meta = with pkgs.stdenv.lib.maintainers; {
|
||||||
maintainers = [ das_j ];
|
maintainers = [ das_j ];
|
||||||
@ -64,8 +64,8 @@ import ./make-test.nix ({ pkgs, ... }: {
|
|||||||
};
|
};
|
||||||
|
|
||||||
testScript = ''
|
testScript = ''
|
||||||
startAll();
|
start_all()
|
||||||
$icingaweb2->waitForUnit("multi-user.target");
|
icingaweb2.wait_for_unit("multi-user.target")
|
||||||
$icingaweb2->succeed("curl -sSf http://icingaweb2/authentication/login");
|
icingaweb2.succeed("curl -sSf http://icingaweb2/authentication/login")
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import ./make-test.nix ({ pkgs, lib, ... }:
|
import ./make-test-python.nix ({ pkgs, lib, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
name = "incron";
|
name = "incron";
|
||||||
@ -19,34 +19,34 @@ import ./make-test.nix ({ pkgs, lib, ... }:
|
|||||||
};
|
};
|
||||||
|
|
||||||
testScript = ''
|
testScript = ''
|
||||||
startAll;
|
start_all()
|
||||||
|
|
||||||
$machine->waitForUnit("multi-user.target");
|
machine.wait_for_unit("multi-user.target")
|
||||||
$machine->waitForUnit("incron.service");
|
machine.wait_for_unit("incron.service")
|
||||||
|
|
||||||
$machine->succeed("test -d /test");
|
machine.succeed("test -d /test")
|
||||||
# create some activity for incron to monitor
|
# create some activity for incron to monitor
|
||||||
$machine->succeed("touch /test/file");
|
machine.succeed("touch /test/file")
|
||||||
$machine->succeed("echo foo >> /test/file");
|
machine.succeed("echo foo >> /test/file")
|
||||||
$machine->succeed("mv /test/file /root");
|
machine.succeed("mv /test/file /root")
|
||||||
$machine->succeed("mv /root/file /test");
|
machine.succeed("mv /root/file /test")
|
||||||
|
|
||||||
$machine->sleep(1);
|
machine.sleep(1)
|
||||||
|
|
||||||
# touch /test/file
|
# touch /test/file
|
||||||
$machine->succeed("grep '/test/file IN_CREATE' /root/incron.log");
|
machine.succeed("grep '/test/file IN_CREATE' /root/incron.log")
|
||||||
|
|
||||||
# echo foo >> /test/file
|
# echo foo >> /test/file
|
||||||
$machine->succeed("grep '/test/file IN_MODIFY' /root/incron.log");
|
machine.succeed("grep '/test/file IN_MODIFY' /root/incron.log")
|
||||||
$machine->succeed("grep '/test/file IN_CLOSE_WRITE' /root/incron.log");
|
machine.succeed("grep '/test/file IN_CLOSE_WRITE' /root/incron.log")
|
||||||
|
|
||||||
# mv /test/file /root
|
# mv /test/file /root
|
||||||
$machine->succeed("grep '/test/file IN_MOVED_FROM' /root/incron.log");
|
machine.succeed("grep '/test/file IN_MOVED_FROM' /root/incron.log")
|
||||||
|
|
||||||
# mv /root/file /test
|
# mv /root/file /test
|
||||||
$machine->succeed("grep '/test/file IN_MOVED_TO' /root/incron.log");
|
machine.succeed("grep '/test/file IN_MOVED_TO' /root/incron.log")
|
||||||
|
|
||||||
# ensure something unexpected is not present
|
# ensure something unexpected is not present
|
||||||
$machine->fail("grep 'IN_OPEN' /root/incron.log");
|
machine.fail("grep 'IN_OPEN' /root/incron.log")
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# This test runs influxdb and checks if influxdb is up and running
|
# This test runs influxdb and checks if influxdb is up and running
|
||||||
|
|
||||||
import ./make-test.nix ({ pkgs, ...} : {
|
import ./make-test-python.nix ({ pkgs, ...} : {
|
||||||
name = "influxdb";
|
name = "influxdb";
|
||||||
meta = with pkgs.stdenv.lib.maintainers; {
|
meta = with pkgs.stdenv.lib.maintainers; {
|
||||||
maintainers = [ offline ];
|
maintainers = [ offline ];
|
||||||
@ -9,25 +9,32 @@ import ./make-test.nix ({ pkgs, ...} : {
|
|||||||
nodes = {
|
nodes = {
|
||||||
one = { ... }: {
|
one = { ... }: {
|
||||||
services.influxdb.enable = true;
|
services.influxdb.enable = true;
|
||||||
|
environment.systemPackages = [ pkgs.httpie ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
testScript = ''
|
testScript = ''
|
||||||
startAll;
|
import shlex
|
||||||
|
|
||||||
$one->waitForUnit("influxdb.service");
|
start_all()
|
||||||
|
|
||||||
|
one.wait_for_unit("influxdb.service")
|
||||||
|
|
||||||
# create database
|
# create database
|
||||||
$one->succeed(q~
|
one.succeed(
|
||||||
curl -XPOST http://localhost:8086/query --data-urlencode "q=CREATE DATABASE test"
|
"curl -XPOST http://localhost:8086/query --data-urlencode 'q=CREATE DATABASE test'"
|
||||||
~);
|
)
|
||||||
|
|
||||||
# write some points and run simple query
|
# write some points and run simple query
|
||||||
$one->succeed(q~
|
out = one.succeed(
|
||||||
curl -XPOST 'http://localhost:8086/write?db=test' --data-binary 'cpu_load_short,host=server01,region=us-west value=0.64 1434055562000000000'
|
"curl -XPOST 'http://localhost:8086/write?db=test' --data-binary 'cpu_load_short,host=server01,region=us-west value=0.64 1434055562000000000'"
|
||||||
~);
|
)
|
||||||
$one->succeed(q~
|
|
||||||
curl -GET 'http://localhost:8086/query' --data-urlencode "db=test" --data-urlencode "q=SELECT \"value\" FROM \"cpu_load_short\" WHERE \"region\"='us-west'" | grep "0\.64"
|
qv = "SELECT value FROM cpu_load_short WHERE region='us-west'"
|
||||||
~);
|
cmd = f'curl -GET "http://localhost:8086/query?db=test" --data-urlencode {shlex.quote("q="+ qv)}'
|
||||||
|
out = one.succeed(cmd)
|
||||||
|
|
||||||
|
assert "2015-06-11T20:46:02Z" in out
|
||||||
|
assert "0.64" in out
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import ./make-test.nix ({ lib, ... }:
|
import ./make-test-python.nix ({ lib, ... }:
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
|
|
||||||
@ -11,8 +11,9 @@ with lib;
|
|||||||
{ services.jackett.enable = true; };
|
{ services.jackett.enable = true; };
|
||||||
|
|
||||||
testScript = ''
|
testScript = ''
|
||||||
$machine->waitForUnit('jackett.service');
|
machine.start()
|
||||||
$machine->waitForOpenPort('9117');
|
machine.wait_for_unit("jackett.service")
|
||||||
$machine->succeed("curl --fail http://localhost:9117/");
|
machine.wait_for_open_port(9117)
|
||||||
|
machine.succeed("curl --fail http://localhost:9117/")
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
# 2. jenkins user can be extended on both master and slave
|
# 2. jenkins user can be extended on both master and slave
|
||||||
# 3. jenkins service not started on slave node
|
# 3. jenkins service not started on slave node
|
||||||
|
|
||||||
import ./make-test.nix ({ pkgs, ...} : {
|
import ./make-test-python.nix ({ pkgs, ...} : {
|
||||||
name = "jenkins";
|
name = "jenkins";
|
||||||
meta = with pkgs.stdenv.lib.maintainers; {
|
meta = with pkgs.stdenv.lib.maintainers; {
|
||||||
maintainers = [ bjornfor coconnor domenkozar eelco ];
|
maintainers = [ bjornfor coconnor domenkozar eelco ];
|
||||||
@ -33,18 +33,17 @@ import ./make-test.nix ({ pkgs, ...} : {
|
|||||||
};
|
};
|
||||||
|
|
||||||
testScript = ''
|
testScript = ''
|
||||||
startAll;
|
start_all()
|
||||||
|
|
||||||
$master->waitForUnit("jenkins");
|
master.wait_for_unit("jenkins")
|
||||||
|
|
||||||
$master->mustSucceed("curl http://localhost:8080 | grep 'Authentication required'");
|
assert "Authentication required" in master.succeed("curl http://localhost:8080")
|
||||||
|
|
||||||
print $master->execute("sudo -u jenkins groups");
|
for host in master, slave:
|
||||||
$master->mustSucceed("sudo -u jenkins groups | grep jenkins | grep users");
|
groups = host.succeed("sudo -u jenkins groups")
|
||||||
|
assert "jenkins" in groups
|
||||||
|
assert "users" in groups
|
||||||
|
|
||||||
print $slave->execute("sudo -u jenkins groups");
|
slave.fail("systemctl is-enabled jenkins.service")
|
||||||
$slave->mustSucceed("sudo -u jenkins groups | grep jenkins | grep users");
|
|
||||||
|
|
||||||
$slave->mustFail("systemctl is-enabled jenkins.service");
|
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import ../make-test.nix ({pkgs, ...}: {
|
import ../make-test-python.nix ({pkgs, ...}: {
|
||||||
name = "kerberos_server-heimdal";
|
name = "kerberos_server-heimdal";
|
||||||
machine = { config, libs, pkgs, ...}:
|
machine = { config, libs, pkgs, ...}:
|
||||||
{ services.kerberos_server =
|
{ services.kerberos_server =
|
||||||
@ -23,31 +23,20 @@ import ../make-test.nix ({pkgs, ...}: {
|
|||||||
};
|
};
|
||||||
|
|
||||||
testScript = ''
|
testScript = ''
|
||||||
$machine->start;
|
machine.succeed(
|
||||||
|
"kadmin -l init --realm-max-ticket-life='8 day' --realm-max-renewable-life='10 day' FOO.BAR",
|
||||||
|
"systemctl restart kadmind.service kdc.service",
|
||||||
|
)
|
||||||
|
|
||||||
$machine->succeed(
|
for unit in ["kadmind", "kdc", "kpasswdd"]:
|
||||||
"kadmin -l init --realm-max-ticket-life='8 day' \\
|
machine.wait_for_unit(f"{unit}.service")
|
||||||
--realm-max-renewable-life='10 day' FOO.BAR"
|
|
||||||
);
|
|
||||||
|
|
||||||
$machine->succeed("systemctl restart kadmind.service kdc.service");
|
machine.succeed(
|
||||||
$machine->waitForUnit("kadmind.service");
|
"kadmin -l add --password=admin_pw --use-defaults admin",
|
||||||
$machine->waitForUnit("kdc.service");
|
"kadmin -l ext_keytab --keytab=admin.keytab admin",
|
||||||
$machine->waitForUnit("kpasswdd.service");
|
"kadmin -p admin -K admin.keytab add --password=alice_pw --use-defaults alice",
|
||||||
|
"kadmin -l ext_keytab --keytab=alice.keytab alice",
|
||||||
$machine->succeed(
|
"kinit -kt alice.keytab alice",
|
||||||
"kadmin -l add --password=admin_pw --use-defaults admin"
|
)
|
||||||
);
|
|
||||||
$machine->succeed(
|
|
||||||
"kadmin -l ext_keytab --keytab=admin.keytab admin"
|
|
||||||
);
|
|
||||||
$machine->succeed(
|
|
||||||
"kadmin -p admin -K admin.keytab add --password=alice_pw --use-defaults \\
|
|
||||||
alice"
|
|
||||||
);
|
|
||||||
$machine->succeed(
|
|
||||||
"kadmin -l ext_keytab --keytab=alice.keytab alice"
|
|
||||||
);
|
|
||||||
$machine->succeed("kinit -kt alice.keytab alice");
|
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import ../make-test.nix ({pkgs, ...}: {
|
import ../make-test-python.nix ({pkgs, ...}: {
|
||||||
name = "kerberos_server-mit";
|
name = "kerberos_server-mit";
|
||||||
machine = { config, libs, pkgs, ...}:
|
machine = { config, libs, pkgs, ...}:
|
||||||
{ services.kerberos_server =
|
{ services.kerberos_server =
|
||||||
@ -24,22 +24,18 @@ import ../make-test.nix ({pkgs, ...}: {
|
|||||||
};
|
};
|
||||||
|
|
||||||
testScript = ''
|
testScript = ''
|
||||||
$machine->start;
|
machine.succeed(
|
||||||
|
"kdb5_util create -s -r FOO.BAR -P master_key",
|
||||||
|
"systemctl restart kadmind.service kdc.service",
|
||||||
|
)
|
||||||
|
|
||||||
$machine->succeed(
|
for unit in ["kadmind", "kdc"]:
|
||||||
"kdb5_util create -s -r FOO.BAR -P master_key"
|
machine.wait_for_unit(f"{unit}.service")
|
||||||
);
|
|
||||||
|
|
||||||
$machine->succeed("systemctl restart kadmind.service kdc.service");
|
machine.succeed(
|
||||||
$machine->waitForUnit("kadmind.service");
|
"kadmin.local add_principal -pw admin_pw admin",
|
||||||
$machine->waitForUnit("kdc.service");
|
"kadmin -p admin -w admin_pw addprinc -pw alice_pw alice",
|
||||||
|
"echo alice_pw | sudo -u alice kinit",
|
||||||
$machine->succeed(
|
)
|
||||||
"kadmin.local add_principal -pw admin_pw admin"
|
|
||||||
);
|
|
||||||
$machine->succeed(
|
|
||||||
"kadmin -p admin -w admin_pw addprinc -pw alice_pw alice"
|
|
||||||
);
|
|
||||||
$machine->succeed("echo alice_pw | sudo -u alice kinit");
|
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import ./make-test.nix ({ pkgs, ... }: {
|
import ./make-test-python.nix ({ pkgs, ... }: {
|
||||||
name = "minidlna";
|
name = "minidlna";
|
||||||
|
|
||||||
nodes = {
|
nodes = {
|
||||||
@ -29,11 +29,11 @@ import ./make-test.nix ({ pkgs, ... }: {
|
|||||||
|
|
||||||
testScript =
|
testScript =
|
||||||
''
|
''
|
||||||
startAll;
|
start_all()
|
||||||
$server->succeed("mkdir -p /tmp/stuff && chown minidlna: /tmp/stuff");
|
server.succeed("mkdir -p /tmp/stuff && chown minidlna: /tmp/stuff")
|
||||||
$server->waitForUnit("minidlna");
|
server.wait_for_unit("minidlna")
|
||||||
$server->waitForOpenPort("8200");
|
server.wait_for_open_port("8200")
|
||||||
$server->succeed("curl --fail http://localhost:8200/");
|
server.succeed("curl --fail http://localhost:8200/")
|
||||||
$client->succeed("curl --fail http://server:8200/");
|
client.succeed("curl --fail http://server:8200/")
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import ./make-test.nix ({ pkgs, lib, ... }:
|
import ./make-test-python.nix ({ pkgs, lib, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
port = 3142;
|
port = 3142;
|
||||||
@ -37,16 +37,20 @@ with lib;
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
testScript = ''
|
testScript = ''
|
||||||
startAll;
|
start_all()
|
||||||
|
|
||||||
$default->waitForUnit('miniflux.service');
|
default.wait_for_unit("miniflux.service")
|
||||||
$default->waitForOpenPort(${toString defaultPort});
|
default.wait_for_open_port(${toString defaultPort})
|
||||||
$default->succeed("curl --fail 'http://localhost:${toString defaultPort}/healthcheck' | grep -q OK");
|
default.succeed("curl --fail 'http://localhost:${toString defaultPort}/healthcheck' | grep -q OK")
|
||||||
$default->succeed("curl 'http://localhost:${toString defaultPort}/v1/me' -u '${defaultUsername}:${defaultPassword}' -H Content-Type:application/json | grep -q '\"is_admin\":true'");
|
default.succeed(
|
||||||
|
"curl 'http://localhost:${toString defaultPort}/v1/me' -u '${defaultUsername}:${defaultPassword}' -H Content-Type:application/json | grep -q '\"is_admin\":true'"
|
||||||
|
)
|
||||||
|
|
||||||
$customized->waitForUnit('miniflux.service');
|
customized.wait_for_unit("miniflux.service")
|
||||||
$customized->waitForOpenPort(${toString port});
|
customized.wait_for_open_port(${toString port})
|
||||||
$customized->succeed("curl --fail 'http://localhost:${toString port}/healthcheck' | grep -q OK");
|
customized.succeed("curl --fail 'http://localhost:${toString port}/healthcheck' | grep -q OK")
|
||||||
$customized->succeed("curl 'http://localhost:${toString port}/v1/me' -u '${username}:${password}' -H Content-Type:application/json | grep -q '\"is_admin\":true'");
|
customized.succeed(
|
||||||
|
"curl 'http://localhost:${toString port}/v1/me' -u '${username}:${password}' -H Content-Type:application/json | grep -q '\"is_admin\":true'"
|
||||||
|
)
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user