From c420de6b05710cccee5b0d9e5573ae36c3e31c5e Mon Sep 17 00:00:00 2001 From: aszlig Date: Fri, 22 Jan 2016 18:49:33 +0100 Subject: [PATCH 01/25] gobject-introspection: Fix patching shared objects The gi-r-scanner is generating a list of shared libraries that are referenced in the shared-library attribute of the element of the GIR file. However, this attribute only contains the names of the libraries and not the full store paths, like for example while preparing to package libblockdev, the following items were included in the shared-library attribute: /nix/store/...-libblockdev-1.3/lib/libblockdev.so.0 libm.so.6 libdmraid.so.1.0.0.rc16 libbd_utils.so.0 Unfortunately, loading such a library without setting LD_LIBRARY_PATH is going to fail finding libm.so.6 and libdmraid.so.1.0.0.rc16. Now the first attempt at solving this was to put absolute paths of all the libraries referenced in the shared-library attribute, but this also led up to including paths of build-time shared objects into that attribute: /nix/store/...-libblockdev-1.3/lib/libblockdev.so.0 /nix/store/...-glibc-2.21/lib/libm.so.6 /nix/store/...-dmraid-1.0.0.rc16/lib/libdmraid.so.1.0.0.rc16 /tmp/nix-build-libblockdev-1.3.drv-0/.../utils/.libs/libbd_utils.so.0 This of course is not what we want, so the final solution is to only use the absolute path whenever it is a Nix path and leave the library name as-is if the path doesn't reside within the store, like this: /nix/store/...-libblockdev-1.3/lib/libblockdev.so.0 /nix/store/...-glibc-2.21/lib/libm.so.6 /nix/store/...-dmraid-1.0.0.rc16/lib/libdmraid.so.1.0.0.rc16 libbd_utils.so.0 The downside of this approach is that if not even the output path of the library is in LD_LIBRARY_PATH, even loading of libbd_utils.so.0 could fail, so we need to patch the loader as well. Signed-off-by: aszlig --- .../absolute_shlib_path.patch | 40 +++++++++++++++++-- .../gobject-introspection/default.nix | 9 ++++- pkgs/top-level/all-packages.nix | 4 +- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/pkgs/development/libraries/gobject-introspection/absolute_shlib_path.patch b/pkgs/development/libraries/gobject-introspection/absolute_shlib_path.patch index 04bcc42a032..2803d767dc7 100644 --- a/pkgs/development/libraries/gobject-introspection/absolute_shlib_path.patch +++ b/pkgs/development/libraries/gobject-introspection/absolute_shlib_path.patch @@ -1,6 +1,40 @@ ---- ./giscanner/utils.py.orig 2014-08-14 22:05:05.055334080 +0200 -+++ ./giscanner/utils.py 2014-08-14 22:05:24.687497334 +0200 -@@ -110,17 +110,11 @@ +diff --git a/giscanner/shlibs.py b/giscanner/shlibs.py +index 838d343..9dbdc0f 100644 +--- a/giscanner/shlibs.py ++++ b/giscanner/shlibs.py +@@ -53,10 +53,24 @@ def _resolve_libtool(options, binary, libraries): + # Match absolute paths on OS X to conform to how libraries are usually + # referenced on OS X systems. + def _ldd_library_pattern(library_name): ++ nix_store_dir = re.escape('@nixStoreDir@'.rstrip('/')) + pattern = "(? Date: Fri, 22 Jan 2016 22:37:00 +0100 Subject: [PATCH 02/25] gobject-introspection: Add fallback for libraries After patching up the shared libraries in c420de6 to use absolute paths, there are still some libraries left which do not get an absolute paths assigned. Those libraries are the ones which have an absolute path outside of the Nix store, so we assume that they're build products of the current build and make them absolute by prepending "$out/lib" or "$lib/lib" (depending on whether it's a multiple output derivation or not) to its basename. So for my test case, the resulting library paths now look like this: /nix/store/...-libblockdev-1.3/lib/libblockdev.so.0 /nix/store/...-glibc-2.21/lib/libm.so.6 /nix/store/...-dmraid-1.0.0.rc16/lib/libdmraid.so.1.0.0.rc16 /nix/store/...-libblockdev-1.3/lib/libbd_utils.so.0 Which is perfectly fine and everything gets resolved correctly after importing the library using GI. However, I didn't test it against other libraries and programs, so this still needs testing, especially for Darwin. Signed-off-by: aszlig --- .../absolute_shlib_path.patch | 65 ++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/pkgs/development/libraries/gobject-introspection/absolute_shlib_path.patch b/pkgs/development/libraries/gobject-introspection/absolute_shlib_path.patch index 2803d767dc7..84f303b42a0 100644 --- a/pkgs/development/libraries/gobject-introspection/absolute_shlib_path.patch +++ b/pkgs/development/libraries/gobject-introspection/absolute_shlib_path.patch @@ -1,5 +1,55 @@ +diff --git a/giscanner/scannermain.py b/giscanner/scannermain.py +index 89ec193..8ee92c3 100755 +--- a/giscanner/scannermain.py ++++ b/giscanner/scannermain.py +@@ -94,6 +94,34 @@ def get_windows_option_group(parser): + return group + + ++def _get_default_fallback_libpath(): ++ outputs = os.environ.get("outputs", "out").split() ++ if "lib" in outputs: ++ # For multiple output derivations let's try whether there is a $lib ++ # environment variable and use that as the base store path. ++ store_path = os.environ.get("lib") ++ elif "out" in outputs: ++ # Otherwise we have a single output derivation, so the libraries most ++ # certainly will end up in "$out/lib". ++ store_path = os.environ.get("out") ++ ++ if store_path is not None: ++ # Even if we have a $lib as output, there still should be a $lib/lib ++ # directory. ++ return os.path.join(store_path, 'lib') ++ else: ++ # If we haven't found a possible scenario, let's return an empty string ++ # so that the shared library won't be prepended with a path. ++ # ++ # Note that this doesn't mean that all hope is lost, because after all ++ # we can still use --fallback-library-path to set one. ++ # ++ # Also, we're not returning None, because that would make it very ++ # difficult to disable adding fallback paths altogether using something ++ # like: --fallback-library-path="" ++ return "" ++ ++ + def _get_option_parser(): + parser = optparse.OptionParser('%prog [options] sources') + parser.add_option('', "--quiet", +@@ -200,6 +228,10 @@ match the namespace prefix.""") + parser.add_option("", "--filelist", + action="store", dest="filelist", default=[], + help="file containing headers and sources to be scanned") ++ parser.add_option("", "--fallback-library-path", ++ action="store", dest="fallback_libpath", ++ default=_get_default_fallback_libpath(), ++ help="Path to prepend to unknown shared libraries") + + group = get_preprocessor_option_group(parser) + parser.add_option_group(group) diff --git a/giscanner/shlibs.py b/giscanner/shlibs.py -index 838d343..9dbdc0f 100644 +index 838d343..35b6dab 100644 --- a/giscanner/shlibs.py +++ b/giscanner/shlibs.py @@ -53,10 +53,24 @@ def _resolve_libtool(options, binary, libraries): @@ -30,6 +80,19 @@ index 838d343..9dbdc0f 100644 # This is a what we do for non-la files. We assume that we are on an +@@ -115,7 +129,11 @@ def _resolve_non_libtool(options, binary, libraries): + m = pattern.search(line) + if m: + del patterns[library] +- shlibs.append(m.group(1)) ++ match = m.group(1) ++ if not match.startswith('/') \ ++ and len(options.fallback_libpath) > 0: ++ match = os.path.join(options.fallback_libpath, match) ++ shlibs.append(match) + break + + if len(patterns) > 0: diff --git a/giscanner/utils.py b/giscanner/utils.py index 660081e..c9c767a 100644 --- a/giscanner/utils.py From 723f7f8f4fc44f0621227e1feaf61901fca12db9 Mon Sep 17 00:00:00 2001 From: aszlig Date: Fri, 22 Jan 2016 23:55:31 +0100 Subject: [PATCH 03/25] gobject-introspection: Don't hardcode /nix/store If no config.nix.storeDir has been set, don't fall back to "/nix/store" but use builtins.storeDir instead so we always should end up with the correct store path no matter whether config.nix.storeDir has been set. Thanks to @lethalman for pointing this out. Signed-off-by: aszlig --- pkgs/development/libraries/gobject-introspection/default.nix | 2 +- pkgs/top-level/all-packages.nix | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/development/libraries/gobject-introspection/default.nix b/pkgs/development/libraries/gobject-introspection/default.nix index c2f60d460d7..2567975aa66 100644 --- a/pkgs/development/libraries/gobject-introspection/default.nix +++ b/pkgs/development/libraries/gobject-introspection/default.nix @@ -1,6 +1,6 @@ { stdenv, fetchurl, glib, flex, bison, pkgconfig, libffi, python , libintlOrEmpty, autoconf, automake, otool -, substituteAll, nixStoreDir ? "/nix/store" +, substituteAll, nixStoreDir ? builtins.storeDir }: # now that gobjectIntrospection creates large .gir files (eg gtk3 case) # it may be worth thinking about using multiple derivation outputs diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index b04d2c1457b..8d270ce7f86 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -6640,7 +6640,7 @@ let mpfr = callPackage ../development/libraries/mpfr/default.nix { }; gobjectIntrospection = callPackage ../development/libraries/gobject-introspection { - nixStoreDir = config.nix.storeDir or "/nix/store"; + nixStoreDir = config.nix.storeDir or builtins.storeDir; }; goocanvas = callPackage ../development/libraries/goocanvas { }; From b3b444a79e53d4362a5995d01401b732f0b67eef Mon Sep 17 00:00:00 2001 From: aszlig Date: Sat, 23 Jan 2016 00:14:53 +0100 Subject: [PATCH 04/25] gobject-introspection: Improve comment in patch As the comment needed explanation, that it's about temporary build files, this should do better. Thanks again to @lethalman for pointing that out. Signed-off-by: aszlig --- .../gobject-introspection/absolute_shlib_path.patch | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkgs/development/libraries/gobject-introspection/absolute_shlib_path.patch b/pkgs/development/libraries/gobject-introspection/absolute_shlib_path.patch index 84f303b42a0..1cec9c1e1a5 100644 --- a/pkgs/development/libraries/gobject-introspection/absolute_shlib_path.patch +++ b/pkgs/development/libraries/gobject-introspection/absolute_shlib_path.patch @@ -49,7 +49,7 @@ index 89ec193..8ee92c3 100755 group = get_preprocessor_option_group(parser) parser.add_option_group(group) diff --git a/giscanner/shlibs.py b/giscanner/shlibs.py -index 838d343..35b6dab 100644 +index 838d343..ca7fc0d 100644 --- a/giscanner/shlibs.py +++ b/giscanner/shlibs.py @@ -53,10 +53,24 @@ def _resolve_libtool(options, binary, libraries): @@ -67,8 +67,8 @@ index 838d343..35b6dab 100644 + # First match Nix store paths because they need to be absolute. + (?:%s(?:/[^/]*)+) + # Everything else not a store path remains relative, because we -+ # would end up having absolute build paths in the resulting GIR -+ # file. ++ # would end up with temporary paths that are only valid during ++ # build time in the resulting GIR file. + | (?<=/) + ) + # And finally the library itself: From 740b30b937ee42a3ae3596e6c9ba0a08742db5d9 Mon Sep 17 00:00:00 2001 From: aszlig Date: Sat, 23 Jan 2016 16:24:03 +0100 Subject: [PATCH 05/25] gobject-introspection: Deal with $outputLib Once #7701 gets merged, we have another environment variable called $outputLib, which then points to another environment variable which is the final library output. This was brought up in discussion with @lethalman and @vcunat in: https://github.com/NixOS/nixpkgs/pull/12558#discussion_r50599813 The closure-size branch is not yet merged into master, so this is only a preparation and we're still falling back to $out and $lib whenever $outputLib isn't available. Signed-off-by: aszlig --- .../absolute_shlib_path.patch | 29 +++++++++++-------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/pkgs/development/libraries/gobject-introspection/absolute_shlib_path.patch b/pkgs/development/libraries/gobject-introspection/absolute_shlib_path.patch index 1cec9c1e1a5..49e059befdb 100644 --- a/pkgs/development/libraries/gobject-introspection/absolute_shlib_path.patch +++ b/pkgs/development/libraries/gobject-introspection/absolute_shlib_path.patch @@ -1,21 +1,26 @@ diff --git a/giscanner/scannermain.py b/giscanner/scannermain.py -index 89ec193..8ee92c3 100755 +index 89ec193..54f1d2e 100755 --- a/giscanner/scannermain.py +++ b/giscanner/scannermain.py -@@ -94,6 +94,34 @@ def get_windows_option_group(parser): +@@ -94,6 +94,39 @@ def get_windows_option_group(parser): return group +def _get_default_fallback_libpath(): -+ outputs = os.environ.get("outputs", "out").split() -+ if "lib" in outputs: -+ # For multiple output derivations let's try whether there is a $lib -+ # environment variable and use that as the base store path. -+ store_path = os.environ.get("lib") -+ elif "out" in outputs: -+ # Otherwise we have a single output derivation, so the libraries most -+ # certainly will end up in "$out/lib". -+ store_path = os.environ.get("out") ++ # Newer multiple-output-optimized stdenv has an environment variable ++ # $outputLib which in turn specifies another variable which then is used as ++ # the destination for the library contents (${!outputLib}/lib). ++ store_path = os.environ.get(os.environ.get("outputLib")) ++ if store_path is None: ++ outputs = os.environ.get("outputs", "out").split() ++ if "lib" in outputs: ++ # For multiple output derivations let's try whether there is a $lib ++ # environment variable and use that as the base store path. ++ store_path = os.environ.get("lib") ++ elif "out" in outputs: ++ # Otherwise we have a single output derivation, so the libraries ++ # most certainly will end up in "$out/lib". ++ store_path = os.environ.get("out") + + if store_path is not None: + # Even if we have a $lib as output, there still should be a $lib/lib @@ -37,7 +42,7 @@ index 89ec193..8ee92c3 100755 def _get_option_parser(): parser = optparse.OptionParser('%prog [options] sources') parser.add_option('', "--quiet", -@@ -200,6 +228,10 @@ match the namespace prefix.""") +@@ -200,6 +233,10 @@ match the namespace prefix.""") parser.add_option("", "--filelist", action="store", dest="filelist", default=[], help="file containing headers and sources to be scanned") From 5bab623fb93567e9f3217e90c7e2679388ec86a3 Mon Sep 17 00:00:00 2001 From: aszlig Date: Mon, 29 Feb 2016 19:15:36 +0100 Subject: [PATCH 06/25] nixos/tests/virtualbox: Split up subtests Now subtests are separate derivations, because the individual tests do not depend on state from previous test runs. This has the advantage that it's easier to run individiual tests and it's also easier to pinpoint individual tests that randomly fail. I ran all of these tests locally and they still succeed. Signed-off-by: aszlig --- nixos/release.nix | 7 +- nixos/tests/virtualbox.nix | 248 +++++++++++++++++++------------------ 2 files changed, 132 insertions(+), 123 deletions(-) diff --git a/nixos/release.nix b/nixos/release.nix index cfe152cc163..497056c2274 100644 --- a/nixos/release.nix +++ b/nixos/release.nix @@ -299,7 +299,12 @@ in rec { tests.simple = callTest tests/simple.nix {}; tests.tomcat = callTest tests/tomcat.nix {}; tests.udisks2 = callTest tests/udisks2.nix {}; - tests.virtualbox = hydraJob (import tests/virtualbox.nix { system = "x86_64-linux"; }); + tests.virtualbox = let + testsOnly = filterAttrs (const (t: t ? test)); + vboxTests = testsOnly (import tests/virtualbox.nix { + system = "x86_64-linux"; + }); + in mapAttrs (const (t: hydraJob t.test)) vboxTests; tests.xfce = callTest tests/xfce.nix {}; tests.bootBiosCdrom = forAllSystems (system: hydraJob (import tests/boot.nix { inherit system; }).bootBiosCdrom); tests.bootBiosUsb = forAllSystems (system: hydraJob (import tests/boot.nix { inherit system; }).bootBiosUsb); diff --git a/nixos/tests/virtualbox.nix b/nixos/tests/virtualbox.nix index 01fcd15fd8b..da4c0bddc34 100644 --- a/nixos/tests/virtualbox.nix +++ b/nixos/tests/virtualbox.nix @@ -1,7 +1,9 @@ -{ debug ? false, ... } @ args: +{ system ? builtins.currentSystem, debug ? false }: -import ./make-test.nix ({ pkgs, ... }: with pkgs.lib; let +with import ../lib/testing.nix { inherit system; }; +with pkgs.lib; +let testVMConfig = vmName: attrs: { config, pkgs, ... }: let guestAdditions = pkgs.linuxPackages.virtualboxGuestAdditions; @@ -314,138 +316,140 @@ import ./make-test.nix ({ pkgs, ... }: with pkgs.lib; let test2.vmScript = dhcpScript; }; -in { - name = "virtualbox"; - meta = with pkgs.stdenv.lib.maintainers; { - maintainers = [ aszlig wkennington ]; - }; + mkVBoxTest = name: testScript: makeTest { + name = "virtualbox-${name}"; - machine = { pkgs, lib, config, ... }: { - imports = let - mkVMConf = name: val: val.machine // { key = "${name}-config"; }; - vmConfigs = mapAttrsToList mkVMConf vboxVMs; - in [ ./common/user-account.nix ./common/x11.nix ] ++ vmConfigs; - virtualisation.memorySize = 2048; - virtualisation.virtualbox.host.enable = true; - users.extraUsers.alice.extraGroups = let - inherit (config.virtualisation.virtualbox.host) enableHardening; - in lib.mkIf enableHardening (lib.singleton "vboxusers"); - }; - - testScript = '' - sub ru ($) { - my $esc = $_[0] =~ s/'/'\\${"'"}'/gr; - return "su - alice -c '$esc'"; - } - - sub vbm { - $machine->succeed(ru("VBoxManage ".$_[0])); + machine = { lib, config, ... }: { + imports = let + mkVMConf = name: val: val.machine // { key = "${name}-config"; }; + vmConfigs = mapAttrsToList mkVMConf vboxVMs; + in [ ./common/user-account.nix ./common/x11.nix ] ++ vmConfigs; + virtualisation.memorySize = 2048; + virtualisation.virtualbox.host.enable = true; + users.extraUsers.alice.extraGroups = let + inherit (config.virtualisation.virtualbox.host) enableHardening; + in lib.mkIf enableHardening (lib.singleton "vboxusers"); }; - ${concatStrings (mapAttrsToList (_: getAttr "testSubs") vboxVMs)} + testScript = '' + sub ru ($) { + my $esc = $_[0] =~ s/'/'\\${"'"}'/gr; + return "su - alice -c '$esc'"; + } - $machine->waitForX; + sub vbm { + $machine->succeed(ru("VBoxManage ".$_[0])); + }; - ${mkLog "$HOME/.config/VirtualBox/VBoxSVC.log" "HOST-SVC"} + sub removeUUIDs { + return join("\n", grep { $_ !~ /^UUID:/ } split(/\n/, $_[0]))."\n"; + } + ${concatStrings (mapAttrsToList (_: getAttr "testSubs") vboxVMs)} + + $machine->waitForX; + + ${mkLog "$HOME/.config/VirtualBox/VBoxSVC.log" "HOST-SVC"} + + ${testScript} + ''; + + meta = with pkgs.stdenv.lib.maintainers; { + maintainers = [ aszlig wkennington ]; + }; + }; + +in mapAttrs mkVBoxTest { + simple-gui = '' createVM_simple; - - subtest "simple-gui", sub { - $machine->succeed(ru "VirtualBox &"); - $machine->waitForWindow(qr/Oracle VM VirtualBox Manager/); - $machine->sleep(5); - $machine->screenshot("gui_manager_started"); + $machine->succeed(ru "VirtualBox &"); + $machine->waitForWindow(qr/Oracle VM VirtualBox Manager/); + $machine->sleep(5); + $machine->screenshot("gui_manager_started"); + $machine->sendKeys("ret"); + $machine->screenshot("gui_manager_sent_startup"); + waitForStartup_simple (sub { $machine->sendKeys("ret"); - $machine->screenshot("gui_manager_sent_startup"); - waitForStartup_simple (sub { - $machine->sendKeys("ret"); - }); - $machine->screenshot("gui_started"); - waitForVMBoot_simple; - $machine->screenshot("gui_booted"); - shutdownVM_simple; - $machine->sleep(5); - $machine->screenshot("gui_stopped"); - $machine->sendKeys("ctrl-q"); - $machine->sleep(5); - $machine->screenshot("gui_manager_stopped"); - }; + }); + $machine->screenshot("gui_started"); + waitForVMBoot_simple; + $machine->screenshot("gui_booted"); + shutdownVM_simple; + $machine->sleep(5); + $machine->screenshot("gui_stopped"); + $machine->sendKeys("ctrl-q"); + $machine->sleep(5); + $machine->screenshot("gui_manager_stopped"); + ''; - cleanup_simple; + simple-cli = '' + createVM_simple; + vbm("startvm simple"); + waitForStartup_simple; + $machine->screenshot("cli_started"); + waitForVMBoot_simple; + $machine->screenshot("cli_booted"); - subtest "simple-cli", sub { - vbm("startvm simple"); - waitForStartup_simple; - $machine->screenshot("cli_started"); - waitForVMBoot_simple; - $machine->screenshot("cli_booted"); - shutdownVM_simple; - }; - - subtest "privilege-escalation", sub { + $machine->nest("Checking for privilege escalation", sub { $machine->fail("test -e '/root/VirtualBox VMs'"); $machine->fail("test -e '/root/.config/VirtualBox'"); $machine->succeed("test -e '/home/alice/VirtualBox VMs'"); - }; + }); - destroyVM_simple; - - sub removeUUIDs { - return join("\n", grep { $_ !~ /^UUID:/ } split(/\n/, $_[0]))."\n"; - } - - subtest "host-usb-permissions", sub { - my $userUSB = removeUUIDs vbm("list usbhost"); - print STDERR $userUSB; - my $rootUSB = removeUUIDs $machine->succeed("VBoxManage list usbhost"); - print STDERR $rootUSB; - - die "USB host devices differ for root and normal user" - if $userUSB ne $rootUSB; - die "No USB host devices found" if $userUSB =~ //; - }; - - subtest "systemd-detect-virt", sub { - createVM_detectvirt; - vbm("startvm detectvirt"); - waitForStartup_detectvirt; - waitForVMBoot_detectvirt; - shutdownVM_detectvirt; - my $result = $machine->succeed("cat '$detectvirt_sharepath/result'"); - chomp $result; - destroyVM_detectvirt; - die "systemd-detect-virt returned \"$result\" instead of \"oracle\"" - if $result ne "oracle"; - }; - - subtest "net-hostonlyif", sub { - createVM_test1; - createVM_test2; - - vbm("startvm test1"); - waitForStartup_test1; - waitForVMBoot_test1; - - vbm("startvm test2"); - waitForStartup_test2; - waitForVMBoot_test2; - - $machine->screenshot("net_booted"); - - my $test1IP = waitForIP_test1 1; - my $test2IP = waitForIP_test2 1; - - $machine->succeed("echo '$test2IP' | netcat -c '$test1IP' 1234"); - $machine->succeed("echo '$test1IP' | netcat -c '$test2IP' 1234"); - - $machine->waitUntilSucceeds("netcat -c '$test1IP' 5678 >&2"); - $machine->waitUntilSucceeds("netcat -c '$test2IP' 5678 >&2"); - - shutdownVM_test1; - shutdownVM_test2; - - destroyVM_test1; - destroyVM_test2; - }; + shutdownVM_simple; ''; -}) args + + host-usb-permissions = '' + my $userUSB = removeUUIDs vbm("list usbhost"); + print STDERR $userUSB; + my $rootUSB = removeUUIDs $machine->succeed("VBoxManage list usbhost"); + print STDERR $rootUSB; + + die "USB host devices differ for root and normal user" + if $userUSB ne $rootUSB; + die "No USB host devices found" if $userUSB =~ //; + ''; + + systemd-detect-virt = '' + createVM_detectvirt; + vbm("startvm detectvirt"); + waitForStartup_detectvirt; + waitForVMBoot_detectvirt; + shutdownVM_detectvirt; + my $result = $machine->succeed("cat '$detectvirt_sharepath/result'"); + chomp $result; + destroyVM_detectvirt; + die "systemd-detect-virt returned \"$result\" instead of \"oracle\"" + if $result ne "oracle"; + ''; + + net-hostonlyif = '' + createVM_test1; + createVM_test2; + + vbm("startvm test1"); + waitForStartup_test1; + waitForVMBoot_test1; + + vbm("startvm test2"); + waitForStartup_test2; + waitForVMBoot_test2; + + $machine->screenshot("net_booted"); + + my $test1IP = waitForIP_test1 1; + my $test2IP = waitForIP_test2 1; + + $machine->succeed("echo '$test2IP' | netcat -c '$test1IP' 1234"); + $machine->succeed("echo '$test1IP' | netcat -c '$test2IP' 1234"); + + $machine->waitUntilSucceeds("netcat -c '$test1IP' 5678 >&2"); + $machine->waitUntilSucceeds("netcat -c '$test2IP' 5678 >&2"); + + shutdownVM_test1; + shutdownVM_test2; + + destroyVM_test1; + destroyVM_test2; + ''; +} From b3337edd0b77f04d0abe4a29642a5e4fdb4ad692 Mon Sep 17 00:00:00 2001 From: aszlig Date: Mon, 29 Feb 2016 20:02:26 +0100 Subject: [PATCH 07/25] nixos/release.nix: Add a callSubTests function This should de-clutter the various redundant lines of callTest's on subtests so that every main test file should have only one line with a callSubTests instead. Overrides work the same way as callTest, except that if the system attribute is explicitly specified we do not generate attributes for all available systems. Signed-off-by: aszlig Cc: @edolstra --- nixos/release.nix | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/nixos/release.nix b/nixos/release.nix index 497056c2274..76d0ce90458 100644 --- a/nixos/release.nix +++ b/nixos/release.nix @@ -13,7 +13,25 @@ let forAllSystems = genAttrs supportedSystems; - callTest = fn: args: forAllSystems (system: hydraJob (import fn ({ inherit system; } // args))); + importTest = fn: args: system: import fn ({ + inherit system; + } // args); + + callTest = fn: args: forAllSystems (system: hydraJob (importTest fn args system)); + + callSubTests = fn: args: let + discover = attrs: let + subTests = filterAttrs (const (hasAttr "test")) attrs; + in mapAttrs (const (t: hydraJob t.test)) subTests; + + discoverForSystem = system: mapAttrs (_: test: { + ${system} = test; + }) (discover (importTest fn args system)); + + # If the test is only for a particular system, use only the specified + # system instead of generating attributes for all available systems. + in if args ? system then discover (import fn args) + else foldAttrs (a: b: a // b) {} (map discoverForSystem supportedSystems); pkgs = import nixpkgs { system = "x86_64-linux"; }; From 2f2536b9354b296dbf12343d232e113d211704df Mon Sep 17 00:00:00 2001 From: aszlig Date: Mon, 29 Feb 2016 20:06:55 +0100 Subject: [PATCH 08/25] nixos/tests/networking: Expose subtests via attrs So far the networking test expression only generated a single test depending on the passed "test" attribute. This makes it difficult to autodiscover the subtests with our shiny new callSubTests function. This change essentially doesn't change the behaviour of the subtests but rather exposes them as an attribute set instead of relying on a particular input argument. The useNetworkd argument still exists however. Signed-off-by: aszlig Cc: @wkennington --- nixos/tests/networking.nix | 799 +++++++++++++++++++------------------ 1 file changed, 402 insertions(+), 397 deletions(-) diff --git a/nixos/tests/networking.nix b/nixos/tests/networking.nix index 813d7c2bf51..d5a0a9b798f 100644 --- a/nixos/tests/networking.nix +++ b/nixos/tests/networking.nix @@ -1,406 +1,411 @@ -import ./make-test.nix ({ pkgs, networkd, test, ... }: - let - router = { config, pkgs, ... }: - with pkgs.lib; - let - vlanIfs = range 1 (length config.virtualisation.vlans); - in { - virtualisation.vlans = [ 1 2 3 ]; +{ system ? builtins.currentSystem, networkd }: + +with import ../lib/testing.nix { inherit system; }; +with pkgs.lib; + +let + router = { config, pkgs, ... }: + with pkgs.lib; + let + vlanIfs = range 1 (length config.virtualisation.vlans); + in { + virtualisation.vlans = [ 1 2 3 ]; + networking = { + useDHCP = false; + useNetworkd = networkd; + firewall.allowPing = true; + interfaces = mkOverride 0 (listToAttrs (flip map vlanIfs (n: + nameValuePair "eth${toString n}" { + ipAddress = "192.168.${toString n}.1"; + prefixLength = 24; + }))); + }; + services.dhcpd = { + enable = true; + interfaces = map (n: "eth${toString n}") vlanIfs; + extraConfig = '' + option subnet-mask 255.255.255.0; + '' + flip concatMapStrings vlanIfs (n: '' + subnet 192.168.${toString n}.0 netmask 255.255.255.0 { + option broadcast-address 192.168.${toString n}.255; + option routers 192.168.${toString n}.1; + range 192.168.${toString n}.2 192.168.${toString n}.254; + } + ''); + }; + }; + + testCases = { + loopback = { + name = "Loopback"; + machine.networking.useNetworkd = networkd; + testScript = '' + startAll; + $machine->waitForUnit("network-interfaces.target"); + $machine->waitForUnit("network.target"); + $machine->succeed("ip addr show lo | grep -q 'inet 127.0.0.1/8 '"); + $machine->succeed("ip addr show lo | grep -q 'inet6 ::1/128 '"); + ''; + }; + static = { + name = "Static"; + nodes.router = router; + nodes.client = { config, pkgs, ... }: with pkgs.lib; { + virtualisation.vlans = [ 1 2 ]; networking = { - useDHCP = false; useNetworkd = networkd; firewall.allowPing = true; - interfaces = mkOverride 0 (listToAttrs (flip map vlanIfs (n: - nameValuePair "eth${toString n}" { - ipAddress = "192.168.${toString n}.1"; - prefixLength = 24; - }))); - }; - services.dhcpd = { - enable = true; - interfaces = map (n: "eth${toString n}") vlanIfs; - extraConfig = '' - option subnet-mask 255.255.255.0; - '' + flip concatMapStrings vlanIfs (n: '' - subnet 192.168.${toString n}.0 netmask 255.255.255.0 { - option broadcast-address 192.168.${toString n}.255; - option routers 192.168.${toString n}.1; - range 192.168.${toString n}.2 192.168.${toString n}.254; - } - ''); + useDHCP = false; + defaultGateway = "192.168.1.1"; + interfaces.eth1.ip4 = mkOverride 0 [ + { address = "192.168.1.2"; prefixLength = 24; } + { address = "192.168.1.3"; prefixLength = 32; } + { address = "192.168.1.10"; prefixLength = 32; } + ]; + interfaces.eth2.ip4 = mkOverride 0 [ + { address = "192.168.2.2"; prefixLength = 24; } + ]; }; }; - testCases = { - loopback = { - name = "Loopback"; - machine.networking.useNetworkd = networkd; - testScript = '' + testScript = { nodes, ... }: + '' startAll; - $machine->waitForUnit("network-interfaces.target"); - $machine->waitForUnit("network.target"); - $machine->succeed("ip addr show lo | grep -q 'inet 127.0.0.1/8 '"); - $machine->succeed("ip addr show lo | grep -q 'inet6 ::1/128 '"); + + $client->waitForUnit("network-interfaces.target"); + $client->waitForUnit("network.target"); + $router->waitForUnit("network-interfaces.target"); + $router->waitForUnit("network.target"); + + # Make sure dhcpcd is not started + $client->fail("systemctl status dhcpcd.service"); + + # Test vlan 1 + $client->waitUntilSucceeds("ping -c 1 192.168.1.1"); + $client->waitUntilSucceeds("ping -c 1 192.168.1.2"); + $client->waitUntilSucceeds("ping -c 1 192.168.1.3"); + $client->waitUntilSucceeds("ping -c 1 192.168.1.10"); + + $router->waitUntilSucceeds("ping -c 1 192.168.1.1"); + $router->waitUntilSucceeds("ping -c 1 192.168.1.2"); + $router->waitUntilSucceeds("ping -c 1 192.168.1.3"); + $router->waitUntilSucceeds("ping -c 1 192.168.1.10"); + + # Test vlan 2 + $client->waitUntilSucceeds("ping -c 1 192.168.2.1"); + $client->waitUntilSucceeds("ping -c 1 192.168.2.2"); + + $router->waitUntilSucceeds("ping -c 1 192.168.2.1"); + $router->waitUntilSucceeds("ping -c 1 192.168.2.2"); + + # Test default gateway + $router->waitUntilSucceeds("ping -c 1 192.168.3.1"); + $client->waitUntilSucceeds("ping -c 1 192.168.3.1"); ''; - }; - static = { - name = "Static"; - nodes.router = router; - nodes.client = { config, pkgs, ... }: with pkgs.lib; { - virtualisation.vlans = [ 1 2 ]; - networking = { - useNetworkd = networkd; - firewall.allowPing = true; - useDHCP = false; - defaultGateway = "192.168.1.1"; - interfaces.eth1.ip4 = mkOverride 0 [ - { address = "192.168.1.2"; prefixLength = 24; } - { address = "192.168.1.3"; prefixLength = 32; } - { address = "192.168.1.10"; prefixLength = 32; } - ]; - interfaces.eth2.ip4 = mkOverride 0 [ - { address = "192.168.2.2"; prefixLength = 24; } - ]; - }; - }; - testScript = { nodes, ... }: - '' - startAll; - - $client->waitForUnit("network-interfaces.target"); - $client->waitForUnit("network.target"); - $router->waitForUnit("network-interfaces.target"); - $router->waitForUnit("network.target"); - - # Make sure dhcpcd is not started - $client->fail("systemctl status dhcpcd.service"); - - # Test vlan 1 - $client->waitUntilSucceeds("ping -c 1 192.168.1.1"); - $client->waitUntilSucceeds("ping -c 1 192.168.1.2"); - $client->waitUntilSucceeds("ping -c 1 192.168.1.3"); - $client->waitUntilSucceeds("ping -c 1 192.168.1.10"); - - $router->waitUntilSucceeds("ping -c 1 192.168.1.1"); - $router->waitUntilSucceeds("ping -c 1 192.168.1.2"); - $router->waitUntilSucceeds("ping -c 1 192.168.1.3"); - $router->waitUntilSucceeds("ping -c 1 192.168.1.10"); - - # Test vlan 2 - $client->waitUntilSucceeds("ping -c 1 192.168.2.1"); - $client->waitUntilSucceeds("ping -c 1 192.168.2.2"); - - $router->waitUntilSucceeds("ping -c 1 192.168.2.1"); - $router->waitUntilSucceeds("ping -c 1 192.168.2.2"); - - # Test default gateway - $router->waitUntilSucceeds("ping -c 1 192.168.3.1"); - $client->waitUntilSucceeds("ping -c 1 192.168.3.1"); - ''; - }; - dhcpSimple = { - name = "SimpleDHCP"; - nodes.router = router; - nodes.client = { config, pkgs, ... }: with pkgs.lib; { - virtualisation.vlans = [ 1 2 ]; - networking = { - useNetworkd = networkd; - firewall.allowPing = true; - useDHCP = true; - interfaces.eth1.ip4 = mkOverride 0 [ ]; - interfaces.eth2.ip4 = mkOverride 0 [ ]; - }; - }; - testScript = { nodes, ... }: - '' - startAll; - - $client->waitForUnit("network-interfaces.target"); - $client->waitForUnit("network.target"); - $router->waitForUnit("network-interfaces.target"); - $router->waitForUnit("network.target"); - - # Wait until we have an ip address on each interface - $client->waitUntilSucceeds("ip addr show dev eth1 | grep -q '192.168.1'"); - $client->waitUntilSucceeds("ip addr show dev eth2 | grep -q '192.168.2'"); - - # Test vlan 1 - $client->waitUntilSucceeds("ping -c 1 192.168.1.1"); - $client->waitUntilSucceeds("ping -c 1 192.168.1.2"); - - $router->waitUntilSucceeds("ping -c 1 192.168.1.1"); - $router->waitUntilSucceeds("ping -c 1 192.168.1.2"); - - # Test vlan 2 - $client->waitUntilSucceeds("ping -c 1 192.168.2.1"); - $client->waitUntilSucceeds("ping -c 1 192.168.2.2"); - - $router->waitUntilSucceeds("ping -c 1 192.168.2.1"); - $router->waitUntilSucceeds("ping -c 1 192.168.2.2"); - ''; - }; - dhcpOneIf = { - name = "OneInterfaceDHCP"; - nodes.router = router; - nodes.client = { config, pkgs, ... }: with pkgs.lib; { - virtualisation.vlans = [ 1 2 ]; - networking = { - useNetworkd = networkd; - firewall.allowPing = true; - useDHCP = false; - interfaces.eth1 = { - ip4 = mkOverride 0 [ ]; - useDHCP = true; - }; - interfaces.eth2.ip4 = mkOverride 0 [ ]; - }; - }; - testScript = { nodes, ... }: - '' - startAll; - - # Wait for networking to come up - $client->waitForUnit("network-interfaces.target"); - $client->waitForUnit("network.target"); - $router->waitForUnit("network-interfaces.target"); - $router->waitForUnit("network.target"); - - # Wait until we have an ip address on each interface - $client->waitUntilSucceeds("ip addr show dev eth1 | grep -q '192.168.1'"); - - # Test vlan 1 - $client->waitUntilSucceeds("ping -c 1 192.168.1.1"); - $client->waitUntilSucceeds("ping -c 1 192.168.1.2"); - - $router->waitUntilSucceeds("ping -c 1 192.168.1.1"); - $router->waitUntilSucceeds("ping -c 1 192.168.1.2"); - - # Test vlan 2 - $client->waitUntilSucceeds("ping -c 1 192.168.2.1"); - $client->fail("ping -c 1 192.168.2.2"); - - $router->waitUntilSucceeds("ping -c 1 192.168.2.1"); - $router->fail("ping -c 1 192.168.2.2"); - ''; - }; - bond = let - node = address: { config, pkgs, ... }: with pkgs.lib; { - virtualisation.vlans = [ 1 2 ]; - networking = { - useNetworkd = networkd; - firewall.allowPing = true; - useDHCP = false; - bonds.bond = { - mode = "balance-rr"; - interfaces = [ "eth1" "eth2" ]; - }; - interfaces.eth1.ip4 = mkOverride 0 [ ]; - interfaces.eth2.ip4 = mkOverride 0 [ ]; - interfaces.bond.ip4 = mkOverride 0 - [ { inherit address; prefixLength = 30; } ]; - }; - }; - in { - name = "Bond"; - nodes.client1 = node "192.168.1.1"; - nodes.client2 = node "192.168.1.2"; - testScript = { nodes, ... }: - '' - startAll; - - # Wait for networking to come up - $client1->waitForUnit("network-interfaces.target"); - $client1->waitForUnit("network.target"); - $client2->waitForUnit("network-interfaces.target"); - $client2->waitForUnit("network.target"); - - # Test bonding - $client1->waitUntilSucceeds("ping -c 2 192.168.1.1"); - $client1->waitUntilSucceeds("ping -c 2 192.168.1.2"); - - $client2->waitUntilSucceeds("ping -c 2 192.168.1.1"); - $client2->waitUntilSucceeds("ping -c 2 192.168.1.2"); - ''; - }; - bridge = let - node = { address, vlan }: { config, pkgs, ... }: with pkgs.lib; { - virtualisation.vlans = [ vlan ]; - networking = { - useNetworkd = networkd; - firewall.allowPing = true; - useDHCP = false; - interfaces.eth1.ip4 = mkOverride 0 - [ { inherit address; prefixLength = 24; } ]; - }; - }; - in { - name = "Bridge"; - nodes.client1 = node { address = "192.168.1.2"; vlan = 1; }; - nodes.client2 = node { address = "192.168.1.3"; vlan = 2; }; - nodes.router = { config, pkgs, ... }: with pkgs.lib; { - virtualisation.vlans = [ 1 2 ]; - networking = { - useNetworkd = networkd; - firewall.allowPing = true; - useDHCP = false; - bridges.bridge.interfaces = [ "eth1" "eth2" ]; - interfaces.eth1.ip4 = mkOverride 0 [ ]; - interfaces.eth2.ip4 = mkOverride 0 [ ]; - interfaces.bridge.ip4 = mkOverride 0 - [ { address = "192.168.1.1"; prefixLength = 24; } ]; - }; - }; - testScript = { nodes, ... }: - '' - startAll; - - # Wait for networking to come up - $client1->waitForUnit("network-interfaces.target"); - $client1->waitForUnit("network.target"); - $client2->waitForUnit("network-interfaces.target"); - $client2->waitForUnit("network.target"); - $router->waitForUnit("network-interfaces.target"); - $router->waitForUnit("network.target"); - - # Test bridging - $client1->waitUntilSucceeds("ping -c 1 192.168.1.1"); - $client1->waitUntilSucceeds("ping -c 1 192.168.1.2"); - $client1->waitUntilSucceeds("ping -c 1 192.168.1.3"); - - $client2->waitUntilSucceeds("ping -c 1 192.168.1.1"); - $client2->waitUntilSucceeds("ping -c 1 192.168.1.2"); - $client2->waitUntilSucceeds("ping -c 1 192.168.1.3"); - - $router->waitUntilSucceeds("ping -c 1 192.168.1.1"); - $router->waitUntilSucceeds("ping -c 1 192.168.1.2"); - $router->waitUntilSucceeds("ping -c 1 192.168.1.3"); - ''; - }; - macvlan = { - name = "MACVLAN"; - nodes.router = router; - nodes.client = { config, pkgs, ... }: with pkgs.lib; { - virtualisation.vlans = [ 1 ]; - networking = { - useNetworkd = networkd; - firewall.allowPing = true; - useDHCP = true; - macvlans.macvlan.interface = "eth1"; - interfaces.eth1.ip4 = mkOverride 0 [ ]; - }; - }; - testScript = { nodes, ... }: - '' - startAll; - - # Wait for networking to come up - $client->waitForUnit("network-interfaces.target"); - $client->waitForUnit("network.target"); - $router->waitForUnit("network-interfaces.target"); - $router->waitForUnit("network.target"); - - # Wait until we have an ip address on each interface - $client->waitUntilSucceeds("ip addr show dev eth1 | grep -q '192.168.1'"); - $client->waitUntilSucceeds("ip addr show dev macvlan | grep -q '192.168.1'"); - - # Print diagnosting information - $router->succeed("ip addr >&2"); - $client->succeed("ip addr >&2"); - - # Test macvlan creates routable ips - $client->waitUntilSucceeds("ping -c 1 192.168.1.1"); - $client->waitUntilSucceeds("ping -c 1 192.168.1.2"); - $client->waitUntilSucceeds("ping -c 1 192.168.1.3"); - - $router->waitUntilSucceeds("ping -c 1 192.168.1.1"); - $router->waitUntilSucceeds("ping -c 1 192.168.1.2"); - $router->waitUntilSucceeds("ping -c 1 192.168.1.3"); - ''; - }; - sit = let - node = { address4, remote, address6 }: { config, pkgs, ... }: with pkgs.lib; { - virtualisation.vlans = [ 1 ]; - networking = { - useNetworkd = networkd; - firewall.enable = false; - useDHCP = false; - sits.sit = { - inherit remote; - local = address4; - dev = "eth1"; - }; - interfaces.eth1.ip4 = mkOverride 0 - [ { address = address4; prefixLength = 24; } ]; - interfaces.sit.ip6 = mkOverride 0 - [ { address = address6; prefixLength = 64; } ]; - }; - }; - in { - name = "Sit"; - nodes.client1 = node { address4 = "192.168.1.1"; remote = "192.168.1.2"; address6 = "fc00::1"; }; - nodes.client2 = node { address4 = "192.168.1.2"; remote = "192.168.1.1"; address6 = "fc00::2"; }; - testScript = { nodes, ... }: - '' - startAll; - - # Wait for networking to be configured - $client1->waitForUnit("network-interfaces.target"); - $client1->waitForUnit("network.target"); - $client2->waitForUnit("network-interfaces.target"); - $client2->waitForUnit("network.target"); - - # Print diagnostic information - $client1->succeed("ip addr >&2"); - $client2->succeed("ip addr >&2"); - - # Test ipv6 - $client1->waitUntilSucceeds("ping6 -c 1 fc00::1"); - $client1->waitUntilSucceeds("ping6 -c 1 fc00::2"); - - $client2->waitUntilSucceeds("ping6 -c 1 fc00::1"); - $client2->waitUntilSucceeds("ping6 -c 1 fc00::2"); - ''; - }; - vlan = let - node = address: { config, pkgs, ... }: with pkgs.lib; { - #virtualisation.vlans = [ 1 ]; - networking = { - useNetworkd = networkd; - firewall.allowPing = true; - useDHCP = false; - vlans.vlan = { - id = 1; - interface = "eth0"; - }; - interfaces.eth0.ip4 = mkOverride 0 [ ]; - interfaces.eth1.ip4 = mkOverride 0 [ ]; - interfaces.vlan.ip4 = mkOverride 0 - [ { inherit address; prefixLength = 24; } ]; - }; - }; - in { - name = "vlan"; - nodes.client1 = node "192.168.1.1"; - nodes.client2 = node "192.168.1.2"; - testScript = { nodes, ... }: - '' - startAll; - - # Wait for networking to be configured - $client1->waitForUnit("network-interfaces.target"); - $client1->waitForUnit("network.target"); - $client2->waitForUnit("network-interfaces.target"); - $client2->waitForUnit("network.target"); - - # Test vlan is setup - $client1->succeed("ip addr show dev vlan >&2"); - $client2->succeed("ip addr show dev vlan >&2"); - ''; - }; }; - case = testCases.${test}; - in case // { - name = "${case.name}-Networking-${if networkd then "Networkd" else "Scripted"}"; - meta = with pkgs.stdenv.lib.maintainers; { - maintainers = [ wkennington ]; + dhcpSimple = { + name = "SimpleDHCP"; + nodes.router = router; + nodes.client = { config, pkgs, ... }: with pkgs.lib; { + virtualisation.vlans = [ 1 2 ]; + networking = { + useNetworkd = networkd; + firewall.allowPing = true; + useDHCP = true; + interfaces.eth1.ip4 = mkOverride 0 [ ]; + interfaces.eth2.ip4 = mkOverride 0 [ ]; + }; + }; + testScript = { nodes, ... }: + '' + startAll; + + $client->waitForUnit("network-interfaces.target"); + $client->waitForUnit("network.target"); + $router->waitForUnit("network-interfaces.target"); + $router->waitForUnit("network.target"); + + # Wait until we have an ip address on each interface + $client->waitUntilSucceeds("ip addr show dev eth1 | grep -q '192.168.1'"); + $client->waitUntilSucceeds("ip addr show dev eth2 | grep -q '192.168.2'"); + + # Test vlan 1 + $client->waitUntilSucceeds("ping -c 1 192.168.1.1"); + $client->waitUntilSucceeds("ping -c 1 192.168.1.2"); + + $router->waitUntilSucceeds("ping -c 1 192.168.1.1"); + $router->waitUntilSucceeds("ping -c 1 192.168.1.2"); + + # Test vlan 2 + $client->waitUntilSucceeds("ping -c 1 192.168.2.1"); + $client->waitUntilSucceeds("ping -c 1 192.168.2.2"); + + $router->waitUntilSucceeds("ping -c 1 192.168.2.1"); + $router->waitUntilSucceeds("ping -c 1 192.168.2.2"); + ''; }; - }) + dhcpOneIf = { + name = "OneInterfaceDHCP"; + nodes.router = router; + nodes.client = { config, pkgs, ... }: with pkgs.lib; { + virtualisation.vlans = [ 1 2 ]; + networking = { + useNetworkd = networkd; + firewall.allowPing = true; + useDHCP = false; + interfaces.eth1 = { + ip4 = mkOverride 0 [ ]; + useDHCP = true; + }; + interfaces.eth2.ip4 = mkOverride 0 [ ]; + }; + }; + testScript = { nodes, ... }: + '' + startAll; + + # Wait for networking to come up + $client->waitForUnit("network-interfaces.target"); + $client->waitForUnit("network.target"); + $router->waitForUnit("network-interfaces.target"); + $router->waitForUnit("network.target"); + + # Wait until we have an ip address on each interface + $client->waitUntilSucceeds("ip addr show dev eth1 | grep -q '192.168.1'"); + + # Test vlan 1 + $client->waitUntilSucceeds("ping -c 1 192.168.1.1"); + $client->waitUntilSucceeds("ping -c 1 192.168.1.2"); + + $router->waitUntilSucceeds("ping -c 1 192.168.1.1"); + $router->waitUntilSucceeds("ping -c 1 192.168.1.2"); + + # Test vlan 2 + $client->waitUntilSucceeds("ping -c 1 192.168.2.1"); + $client->fail("ping -c 1 192.168.2.2"); + + $router->waitUntilSucceeds("ping -c 1 192.168.2.1"); + $router->fail("ping -c 1 192.168.2.2"); + ''; + }; + bond = let + node = address: { config, pkgs, ... }: with pkgs.lib; { + virtualisation.vlans = [ 1 2 ]; + networking = { + useNetworkd = networkd; + firewall.allowPing = true; + useDHCP = false; + bonds.bond = { + mode = "balance-rr"; + interfaces = [ "eth1" "eth2" ]; + }; + interfaces.eth1.ip4 = mkOverride 0 [ ]; + interfaces.eth2.ip4 = mkOverride 0 [ ]; + interfaces.bond.ip4 = mkOverride 0 + [ { inherit address; prefixLength = 30; } ]; + }; + }; + in { + name = "Bond"; + nodes.client1 = node "192.168.1.1"; + nodes.client2 = node "192.168.1.2"; + testScript = { nodes, ... }: + '' + startAll; + + # Wait for networking to come up + $client1->waitForUnit("network-interfaces.target"); + $client1->waitForUnit("network.target"); + $client2->waitForUnit("network-interfaces.target"); + $client2->waitForUnit("network.target"); + + # Test bonding + $client1->waitUntilSucceeds("ping -c 2 192.168.1.1"); + $client1->waitUntilSucceeds("ping -c 2 192.168.1.2"); + + $client2->waitUntilSucceeds("ping -c 2 192.168.1.1"); + $client2->waitUntilSucceeds("ping -c 2 192.168.1.2"); + ''; + }; + bridge = let + node = { address, vlan }: { config, pkgs, ... }: with pkgs.lib; { + virtualisation.vlans = [ vlan ]; + networking = { + useNetworkd = networkd; + firewall.allowPing = true; + useDHCP = false; + interfaces.eth1.ip4 = mkOverride 0 + [ { inherit address; prefixLength = 24; } ]; + }; + }; + in { + name = "Bridge"; + nodes.client1 = node { address = "192.168.1.2"; vlan = 1; }; + nodes.client2 = node { address = "192.168.1.3"; vlan = 2; }; + nodes.router = { config, pkgs, ... }: with pkgs.lib; { + virtualisation.vlans = [ 1 2 ]; + networking = { + useNetworkd = networkd; + firewall.allowPing = true; + useDHCP = false; + bridges.bridge.interfaces = [ "eth1" "eth2" ]; + interfaces.eth1.ip4 = mkOverride 0 [ ]; + interfaces.eth2.ip4 = mkOverride 0 [ ]; + interfaces.bridge.ip4 = mkOverride 0 + [ { address = "192.168.1.1"; prefixLength = 24; } ]; + }; + }; + testScript = { nodes, ... }: + '' + startAll; + + # Wait for networking to come up + $client1->waitForUnit("network-interfaces.target"); + $client1->waitForUnit("network.target"); + $client2->waitForUnit("network-interfaces.target"); + $client2->waitForUnit("network.target"); + $router->waitForUnit("network-interfaces.target"); + $router->waitForUnit("network.target"); + + # Test bridging + $client1->waitUntilSucceeds("ping -c 1 192.168.1.1"); + $client1->waitUntilSucceeds("ping -c 1 192.168.1.2"); + $client1->waitUntilSucceeds("ping -c 1 192.168.1.3"); + + $client2->waitUntilSucceeds("ping -c 1 192.168.1.1"); + $client2->waitUntilSucceeds("ping -c 1 192.168.1.2"); + $client2->waitUntilSucceeds("ping -c 1 192.168.1.3"); + + $router->waitUntilSucceeds("ping -c 1 192.168.1.1"); + $router->waitUntilSucceeds("ping -c 1 192.168.1.2"); + $router->waitUntilSucceeds("ping -c 1 192.168.1.3"); + ''; + }; + macvlan = { + name = "MACVLAN"; + nodes.router = router; + nodes.client = { config, pkgs, ... }: with pkgs.lib; { + virtualisation.vlans = [ 1 ]; + networking = { + useNetworkd = networkd; + firewall.allowPing = true; + useDHCP = true; + macvlans.macvlan.interface = "eth1"; + interfaces.eth1.ip4 = mkOverride 0 [ ]; + }; + }; + testScript = { nodes, ... }: + '' + startAll; + + # Wait for networking to come up + $client->waitForUnit("network-interfaces.target"); + $client->waitForUnit("network.target"); + $router->waitForUnit("network-interfaces.target"); + $router->waitForUnit("network.target"); + + # Wait until we have an ip address on each interface + $client->waitUntilSucceeds("ip addr show dev eth1 | grep -q '192.168.1'"); + $client->waitUntilSucceeds("ip addr show dev macvlan | grep -q '192.168.1'"); + + # Print diagnosting information + $router->succeed("ip addr >&2"); + $client->succeed("ip addr >&2"); + + # Test macvlan creates routable ips + $client->waitUntilSucceeds("ping -c 1 192.168.1.1"); + $client->waitUntilSucceeds("ping -c 1 192.168.1.2"); + $client->waitUntilSucceeds("ping -c 1 192.168.1.3"); + + $router->waitUntilSucceeds("ping -c 1 192.168.1.1"); + $router->waitUntilSucceeds("ping -c 1 192.168.1.2"); + $router->waitUntilSucceeds("ping -c 1 192.168.1.3"); + ''; + }; + sit = let + node = { address4, remote, address6 }: { config, pkgs, ... }: with pkgs.lib; { + virtualisation.vlans = [ 1 ]; + networking = { + useNetworkd = networkd; + firewall.enable = false; + useDHCP = false; + sits.sit = { + inherit remote; + local = address4; + dev = "eth1"; + }; + interfaces.eth1.ip4 = mkOverride 0 + [ { address = address4; prefixLength = 24; } ]; + interfaces.sit.ip6 = mkOverride 0 + [ { address = address6; prefixLength = 64; } ]; + }; + }; + in { + name = "Sit"; + nodes.client1 = node { address4 = "192.168.1.1"; remote = "192.168.1.2"; address6 = "fc00::1"; }; + nodes.client2 = node { address4 = "192.168.1.2"; remote = "192.168.1.1"; address6 = "fc00::2"; }; + testScript = { nodes, ... }: + '' + startAll; + + # Wait for networking to be configured + $client1->waitForUnit("network-interfaces.target"); + $client1->waitForUnit("network.target"); + $client2->waitForUnit("network-interfaces.target"); + $client2->waitForUnit("network.target"); + + # Print diagnostic information + $client1->succeed("ip addr >&2"); + $client2->succeed("ip addr >&2"); + + # Test ipv6 + $client1->waitUntilSucceeds("ping6 -c 1 fc00::1"); + $client1->waitUntilSucceeds("ping6 -c 1 fc00::2"); + + $client2->waitUntilSucceeds("ping6 -c 1 fc00::1"); + $client2->waitUntilSucceeds("ping6 -c 1 fc00::2"); + ''; + }; + vlan = let + node = address: { config, pkgs, ... }: with pkgs.lib; { + #virtualisation.vlans = [ 1 ]; + networking = { + useNetworkd = networkd; + firewall.allowPing = true; + useDHCP = false; + vlans.vlan = { + id = 1; + interface = "eth0"; + }; + interfaces.eth0.ip4 = mkOverride 0 [ ]; + interfaces.eth1.ip4 = mkOverride 0 [ ]; + interfaces.vlan.ip4 = mkOverride 0 + [ { inherit address; prefixLength = 24; } ]; + }; + }; + in { + name = "vlan"; + nodes.client1 = node "192.168.1.1"; + nodes.client2 = node "192.168.1.2"; + testScript = { nodes, ... }: + '' + startAll; + + # Wait for networking to be configured + $client1->waitForUnit("network-interfaces.target"); + $client1->waitForUnit("network.target"); + $client2->waitForUnit("network-interfaces.target"); + $client2->waitForUnit("network.target"); + + # Test vlan is setup + $client1->succeed("ip addr show dev vlan >&2"); + $client2->succeed("ip addr show dev vlan >&2"); + ''; + }; + }; + +in mapAttrs (const (attrs: makeTest (attrs // { + name = "${attrs.name}-Networking-${if networkd then "Networkd" else "Scripted"}"; + meta = with pkgs.stdenv.lib.maintainers; { + maintainers = [ wkennington ]; + }; +}))) testCases From 7eea91fbc0efc19f416121369f566c6f5363fbc0 Mon Sep 17 00:00:00 2001 From: aszlig Date: Mon, 29 Feb 2016 20:11:04 +0100 Subject: [PATCH 09/25] nixos/release: Use callSubTests for subtests Should clean up a lot of these redundant lines for various sub-tests. Note that the tests.boot* are now called tests.boot.boot*, but otherwise all the test attribute names should stay the same. Signed-off-by: aszlig Cc: @edolstra Cc: @wkennington Cc: @bobvanderlinden --- nixos/release-combined.nix | 2 +- nixos/release.nix | 45 +++++--------------------------------- 2 files changed, 6 insertions(+), 41 deletions(-) diff --git a/nixos/release-combined.nix b/nixos/release-combined.nix index 06890b458ef..b3bef2deb79 100644 --- a/nixos/release-combined.nix +++ b/nixos/release-combined.nix @@ -63,7 +63,7 @@ in rec { (all nixos.tests.installer.btrfsSimple) (all nixos.tests.installer.btrfsSubvols) (all nixos.tests.installer.btrfsSubvolDefault) - (all nixos.tests.bootBiosCdrom) + (all nixos.tests.boot.bootBiosCdrom) (all nixos.tests.ipv6) (all nixos.tests.kde4) #(all nixos.tests.lightdm) diff --git a/nixos/release.nix b/nixos/release.nix index 76d0ce90458..eb614ac1103 100644 --- a/nixos/release.nix +++ b/nixos/release.nix @@ -233,6 +233,7 @@ in rec { tests.avahi = callTest tests/avahi.nix {}; tests.bittorrent = callTest tests/bittorrent.nix {}; tests.blivet = callTest tests/blivet.nix {}; + tests.boot = callSubTests tests/boot.nix {}; tests.cadvisor = hydraJob (import tests/cadvisor.nix { system = "x86_64-linux"; }); tests.chromium = callTest tests/chromium.nix {}; tests.cjdns = callTest tests/cjdns.nix {}; @@ -250,18 +251,7 @@ in rec { tests.gnome3-gdm = callTest tests/gnome3-gdm.nix {}; tests.grsecurity = callTest tests/grsecurity.nix {}; tests.i3wm = callTest tests/i3wm.nix {}; - tests.installer.grub1 = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).grub1.test); - tests.installer.lvm = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).lvm.test); - tests.installer.luksroot = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).luksroot.test); - tests.installer.separateBoot = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).separateBoot.test); - tests.installer.separateBootFat = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).separateBootFat.test); - tests.installer.simple = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).simple.test); - tests.installer.simpleLabels = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).simpleLabels.test); - tests.installer.simpleProvided = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).simpleProvided.test); - tests.installer.swraid = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).swraid.test); - tests.installer.btrfsSimple = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).btrfsSimple.test); - tests.installer.btrfsSubvols = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).btrfsSubvols.test); - tests.installer.btrfsSubvolDefault = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).btrfsSubvolDefault.test); + tests.installer = callSubTests tests/installer.nix {}; tests.influxdb = callTest tests/influxdb.nix {}; tests.ipv6 = callTest tests/ipv6.nix {}; tests.jenkins = callTest tests/jenkins.nix {}; @@ -280,24 +270,8 @@ in rec { tests.mysqlReplication = callTest tests/mysql-replication.nix {}; tests.nat.firewall = callTest tests/nat.nix { withFirewall = true; }; tests.nat.standalone = callTest tests/nat.nix { withFirewall = false; }; - tests.networking.networkd.loopback = callTest tests/networking.nix { networkd = true; test = "loopback"; }; - tests.networking.networkd.static = callTest tests/networking.nix { networkd = true; test = "static"; }; - tests.networking.networkd.dhcpSimple = callTest tests/networking.nix { networkd = true; test = "dhcpSimple"; }; - tests.networking.networkd.dhcpOneIf = callTest tests/networking.nix { networkd = true; test = "dhcpOneIf"; }; - tests.networking.networkd.bond = callTest tests/networking.nix { networkd = true; test = "bond"; }; - tests.networking.networkd.bridge = callTest tests/networking.nix { networkd = true; test = "bridge"; }; - tests.networking.networkd.macvlan = callTest tests/networking.nix { networkd = true; test = "macvlan"; }; - tests.networking.networkd.sit = callTest tests/networking.nix { networkd = true; test = "sit"; }; - tests.networking.networkd.vlan = callTest tests/networking.nix { networkd = true; test = "vlan"; }; - tests.networking.scripted.loopback = callTest tests/networking.nix { networkd = false; test = "loopback"; }; - tests.networking.scripted.static = callTest tests/networking.nix { networkd = false; test = "static"; }; - tests.networking.scripted.dhcpSimple = callTest tests/networking.nix { networkd = false; test = "dhcpSimple"; }; - tests.networking.scripted.dhcpOneIf = callTest tests/networking.nix { networkd = false; test = "dhcpOneIf"; }; - tests.networking.scripted.bond = callTest tests/networking.nix { networkd = false; test = "bond"; }; - tests.networking.scripted.bridge = callTest tests/networking.nix { networkd = false; test = "bridge"; }; - tests.networking.scripted.macvlan = callTest tests/networking.nix { networkd = false; test = "macvlan"; }; - tests.networking.scripted.sit = callTest tests/networking.nix { networkd = false; test = "sit"; }; - tests.networking.scripted.vlan = callTest tests/networking.nix { networkd = false; test = "vlan"; }; + tests.networking.networkd = callSubTests tests/networking.nix { networkd = true; }; + tests.networking.scripted = callSubTests tests/networking.nix { networkd = false; }; # TODO: put in networking.nix after the test becomes more complete tests.networkingProxy = callTest tests/networking-proxy.nix {}; tests.nfs3 = callTest tests/nfs.nix { version = 3; }; @@ -317,17 +291,8 @@ in rec { tests.simple = callTest tests/simple.nix {}; tests.tomcat = callTest tests/tomcat.nix {}; tests.udisks2 = callTest tests/udisks2.nix {}; - tests.virtualbox = let - testsOnly = filterAttrs (const (t: t ? test)); - vboxTests = testsOnly (import tests/virtualbox.nix { - system = "x86_64-linux"; - }); - in mapAttrs (const (t: hydraJob t.test)) vboxTests; + tests.virtualbox = callSubTests tests/virtualbox.nix { system = "x86_64-linux"; }; tests.xfce = callTest tests/xfce.nix {}; - tests.bootBiosCdrom = forAllSystems (system: hydraJob (import tests/boot.nix { inherit system; }).bootBiosCdrom); - tests.bootBiosUsb = forAllSystems (system: hydraJob (import tests/boot.nix { inherit system; }).bootBiosUsb); - tests.bootUefiCdrom = forAllSystems (system: hydraJob (import tests/boot.nix { inherit system; }).bootUefiCdrom); - tests.bootUefiUsb = forAllSystems (system: hydraJob (import tests/boot.nix { inherit system; }).bootUefiUsb); /* Build a bunch of typical closures so that Hydra can keep track of From e45c211b50c6f473e3d92d29e1a8426ec4579f05 Mon Sep 17 00:00:00 2001 From: aszlig Date: Tue, 1 Mar 2016 00:20:27 +0100 Subject: [PATCH 10/25] nixos/tests/chromium: Split up into subtests This makes it easier to test just a specific channel rather than to force testing all builds down the users/testers throat. Especially this makes it easier to test NixOS channel upgrades only against the Chromium stable channel instead of just removing the beta/dev channels from the tests entirely (as done in 69ec09f38aa1f1d37baec73ebdf9cf5f21050f94). Signed-off-by: aszlig --- nixos/release-combined.nix | 2 +- nixos/release.nix | 2 +- nixos/tests/chromium.nix | 133 +++++++++++++++++-------------------- 3 files changed, 63 insertions(+), 74 deletions(-) diff --git a/nixos/release-combined.nix b/nixos/release-combined.nix index b3bef2deb79..69cc357078d 100644 --- a/nixos/release-combined.nix +++ b/nixos/release-combined.nix @@ -48,7 +48,7 @@ in rec { (all nixos.ova) #(all nixos.tests.containers) - (all nixos.tests.chromium) + (all nixos.tests.chromium.stable) (all nixos.tests.firefox) (all nixos.tests.firewall) nixos.tests.gnome3.x86_64-linux # FIXME: i686-linux diff --git a/nixos/release.nix b/nixos/release.nix index eb614ac1103..18e4e2d6b17 100644 --- a/nixos/release.nix +++ b/nixos/release.nix @@ -235,7 +235,7 @@ in rec { tests.blivet = callTest tests/blivet.nix {}; tests.boot = callSubTests tests/boot.nix {}; tests.cadvisor = hydraJob (import tests/cadvisor.nix { system = "x86_64-linux"; }); - tests.chromium = callTest tests/chromium.nix {}; + tests.chromium = callSubTests tests/chromium.nix {}; tests.cjdns = callTest tests/cjdns.nix {}; tests.containers = callTest tests/containers.nix {}; tests.docker = hydraJob (import tests/docker.nix { system = "x86_64-linux"; }); diff --git a/nixos/tests/chromium.nix b/nixos/tests/chromium.nix index 6c61087760d..974af6888b6 100644 --- a/nixos/tests/chromium.nix +++ b/nixos/tests/chromium.nix @@ -1,13 +1,10 @@ -import ./make-test.nix ( -{ pkgs -, channelMap ? { - stable = pkgs.chromium; - #beta = pkgs.chromiumBeta; - #dev = pkgs.chromiumDev; - } -, ... -}: rec { - name = "chromium"; +{ system ? builtins.currentSystem }: + +with import ../lib/testing.nix { inherit system; }; +with pkgs.lib; + +mapAttrs (channel: chromiumPkg: makeTest rec { + name = "chromium-${channel}"; meta = with pkgs.stdenv.lib.maintainers; { maintainers = [ aszlig ]; }; @@ -16,6 +13,7 @@ import ./make-test.nix ( machine.imports = [ ./common/x11.nix ]; machine.virtualisation.memorySize = 2047; + machine.environment.systemPackages = [ chromiumPkg ]; startupHTML = pkgs.writeText "chromium-startup.html" '' @@ -105,74 +103,65 @@ import ./make-test.nix ( closeWin; } - sub chromiumTest { - my ($channel, $pkg, $code) = @_; - $machine->waitForX; + $machine->waitForX; - my $url = "file://${startupHTML}"; - my $args = "--user-data-dir=/tmp/chromium-$channel"; - $machine->execute( - "ulimit -c unlimited; ". - "$pkg/bin/chromium $args \"$url\" & disown" - ); - $machine->waitForText(qr/Type to search or enter a URL to navigate/); - $machine->waitUntilSucceeds("${xdo "check-startup" '' - search --sync --onlyvisible --name "startup done" - # close first start help popup - key -delay 1000 Escape + my $url = "file://${startupHTML}"; + my $args = "--user-data-dir=/tmp/chromium-${channel}"; + $machine->execute( + "ulimit -c unlimited; ". + "chromium $args \"$url\" & disown" + ); + $machine->waitForText(qr/Type to search or enter a URL to navigate/); + $machine->waitUntilSucceeds("${xdo "check-startup" '' + search --sync --onlyvisible --name "startup done" + # close first start help popup + key -delay 1000 Escape + windowfocus --sync + windowactivate --sync + ''}"); + + createAndWaitForNewWin; + $machine->screenshot("empty_windows"); + closeWin; + + $machine->screenshot("startup_done"); + + testNewWin "check sandbox", sub { + $machine->succeed("${xdo "type-url" '' + search --sync --onlyvisible --name "new tab" windowfocus --sync - windowactivate --sync + type --delay 1000 "chrome://sandbox" ''}"); - createAndWaitForNewWin; - $machine->screenshot($channel."_emptywin"); - closeWin; + $machine->succeed("${xdo "submit-url" '' + search --sync --onlyvisible --name "new tab" + windowfocus --sync + key --delay 1000 Return + ''}"); - $machine->screenshot($channel."_startup_done"); + $machine->screenshot("sandbox_info"); - subtest("Chromium $channel", $code); + $machine->succeed("${xdo "submit-url" '' + search --sync --onlyvisible --name "sandbox status" + windowfocus --sync + ''}"); + $machine->succeed("${xdo "submit-url" '' + key --delay 1000 Ctrl+a Ctrl+c + ''}"); - $machine->shutdown; - } + my $clipboard = $machine->succeed("${pkgs.xclip}/bin/xclip -o"); + die "sandbox not working properly: $clipboard" + unless $clipboard =~ /namespace sandbox.*yes/mi + && $clipboard =~ /pid namespaces.*yes/mi + && $clipboard =~ /network namespaces.*yes/mi + && $clipboard =~ /seccomp.*sandbox.*yes/mi + && $clipboard =~ /you are adequately sandboxed/mi; + }; - for (${let - mkArray = name: pkg: "[\"${name}\", \"${pkg}\"]"; - chanArrays = pkgs.lib.mapAttrsToList mkArray channelMap; - in pkgs.lib.concatStringsSep ", " chanArrays}) { - my ($channel, $pkg) = @$_; - chromiumTest $channel, $pkg, sub { - testNewWin "check sandbox", sub { - $machine->succeed("${xdo "type-url" '' - search --sync --onlyvisible --name "new tab" - windowfocus --sync - type --delay 1000 "chrome://sandbox" - ''}"); - - $machine->succeed("${xdo "submit-url" '' - search --sync --onlyvisible --name "new tab" - windowfocus --sync - key --delay 1000 Return - ''}"); - - $machine->screenshot($channel."_sandbox"); - - $machine->succeed("${xdo "submit-url" '' - search --sync --onlyvisible --name "sandbox status" - windowfocus --sync - ''}"); - $machine->succeed("${xdo "submit-url" '' - key --delay 1000 Ctrl+a Ctrl+c - ''}"); - - my $clipboard = $machine->succeed("${pkgs.xclip}/bin/xclip -o"); - die "sandbox not working properly: $clipboard" - unless $clipboard =~ /namespace sandbox.*yes/mi - && $clipboard =~ /pid namespaces.*yes/mi - && $clipboard =~ /network namespaces.*yes/mi - && $clipboard =~ /seccomp.*sandbox.*yes/mi - && $clipboard =~ /you are adequately sandboxed/mi; - }; - }; - } + $machine->shutdown; ''; -}) +}) { + stable = pkgs.chromium; + beta = pkgs.chromiumBeta; + dev = pkgs.chromiumDev; +} From 1f89aa6c7f2f16c8c0834cfa65b8484fecd72af3 Mon Sep 17 00:00:00 2001 From: aszlig Date: Tue, 1 Mar 2016 19:02:36 +0100 Subject: [PATCH 11/25] nixos/tests: Remove tests.boot.boot* prefixes As @bobvanderlinden suggests in #13585: "Looks like that cleans things up quite a bit! Just one aesthetics note, the boot tests could now be renamed from boot.bootBiosCdrom to boot.biosCdrom in nixos/tests/boot.nix:L33. That makes them more consistent with the other tests." Signed-off-by: aszlig --- nixos/release-combined.nix | 2 +- nixos/tests/boot.nix | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/nixos/release-combined.nix b/nixos/release-combined.nix index 69cc357078d..958e587444d 100644 --- a/nixos/release-combined.nix +++ b/nixos/release-combined.nix @@ -63,7 +63,7 @@ in rec { (all nixos.tests.installer.btrfsSimple) (all nixos.tests.installer.btrfsSubvols) (all nixos.tests.installer.btrfsSubvolDefault) - (all nixos.tests.boot.bootBiosCdrom) + (all nixos.tests.boot.biosCdrom) (all nixos.tests.ipv6) (all nixos.tests.kde4) #(all nixos.tests.lightdm) diff --git a/nixos/tests/boot.nix b/nixos/tests/boot.nix index 6a1d330155e..905d1645882 100644 --- a/nixos/tests/boot.nix +++ b/nixos/tests/boot.nix @@ -30,17 +30,17 @@ let ''; }; in { - bootBiosCdrom = makeBootTest "bios-cdrom" '' + biosCdrom = makeBootTest "bios-cdrom" '' cdrom => glob("${iso}/iso/*.iso") ''; - bootBiosUsb = makeBootTest "bios-usb" '' + biosUsb = makeBootTest "bios-usb" '' usb => glob("${iso}/iso/*.iso") ''; - bootUefiCdrom = makeBootTest "uefi-cdrom" '' + uefiCdrom = makeBootTest "uefi-cdrom" '' cdrom => glob("${iso}/iso/*.iso"), bios => '${pkgs.OVMF}/FV/OVMF.fd' ''; - bootUefiUsb = makeBootTest "uefi-usb" '' + uefiUsb = makeBootTest "uefi-usb" '' usb => glob("${iso}/iso/*.iso"), bios => '${pkgs.OVMF}/FV/OVMF.fd' ''; From 78b80ee635262ef39ca855bbfd3a348a93bdfee4 Mon Sep 17 00:00:00 2001 From: Marius Bakke Date: Tue, 1 Mar 2016 19:41:09 +0000 Subject: [PATCH 12/25] girara: 0.2.4 -> 0.2.5 --- pkgs/applications/misc/girara/default.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/applications/misc/girara/default.nix b/pkgs/applications/misc/girara/default.nix index e91e94695f5..0b721b562b5 100644 --- a/pkgs/applications/misc/girara/default.nix +++ b/pkgs/applications/misc/girara/default.nix @@ -5,11 +5,11 @@ assert withBuildColors -> ncurses != null; with stdenv.lib; stdenv.mkDerivation rec { name = "girara-${version}"; - version = "0.2.4"; + version = "0.2.5"; src = fetchurl { url = "http://pwmt.org/projects/girara/download/${name}.tar.gz"; - sha256 = "0pnfdsg435b5vc4x8l9pgm77aj7ram1q0bzrp9g4a3bh1r64xq1f"; + sha256 = "14m8mfbck49ldwi1w2i47bbg5c9daglcmvz9v2g1hnrq8k8g5x2w"; }; preConfigure = '' From cbf09c69362023abe0c6f3775de88ebbddf260d7 Mon Sep 17 00:00:00 2001 From: Marius Bakke Date: Tue, 1 Mar 2016 19:41:31 +0000 Subject: [PATCH 13/25] zathura: 0.3.3 -> 0.3.5 --- pkgs/applications/misc/zathura/core/default.nix | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/pkgs/applications/misc/zathura/core/default.nix b/pkgs/applications/misc/zathura/core/default.nix index cab6423b77e..3a88409999f 100644 --- a/pkgs/applications/misc/zathura/core/default.nix +++ b/pkgs/applications/misc/zathura/core/default.nix @@ -1,15 +1,17 @@ -{ stdenv, fetchurl, pkgconfig, gtk, girara, ncurses, gettext, docutils, file, makeWrapper, zathura_icon, sqlite }: +{ stdenv, fetchurl, pkgconfig, gtk, girara, ncurses, gettext, docutils, file, makeWrapper, zathura_icon, sqlite, glib }: stdenv.mkDerivation rec { - version = "0.3.3"; + version = "0.3.5"; name = "zathura-core-${version}"; src = fetchurl { url = "http://pwmt.org/projects/zathura/download/zathura-${version}.tar.gz"; - sha256 = "1rywx09qn6ap5hb1z31wxby4lzdrqdbldm51pjk1ifflr37xwirk"; + sha256 = "031kdr10065q14nixc4p58c4rgvrqcmn9x39b19h2357kzabaw9a"; }; - buildInputs = [ pkgconfig file gtk girara gettext makeWrapper sqlite ]; + buildInputs = [ pkgconfig file gtk girara gettext makeWrapper sqlite glib ]; + + NIX_CFLAGS_COMPILE = "-I${glib}/include/gio-unix-2.0"; makeFlags = [ "PREFIX=$(out)" From 18a4ca2d052c49d97d900c217d68f08eb7ffc18c Mon Sep 17 00:00:00 2001 From: Marius Bakke Date: Tue, 1 Mar 2016 19:50:23 +0000 Subject: [PATCH 14/25] zathura-ps: 0.2.2 -> 0.2.3 --- pkgs/applications/misc/zathura/ps/default.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/applications/misc/zathura/ps/default.nix b/pkgs/applications/misc/zathura/ps/default.nix index 31ffbf628dd..630f45a1e41 100644 --- a/pkgs/applications/misc/zathura/ps/default.nix +++ b/pkgs/applications/misc/zathura/ps/default.nix @@ -1,11 +1,11 @@ { stdenv, lib, fetchurl, pkgconfig, gtk, zathura_core, girara, libspectre, gettext }: stdenv.mkDerivation rec { - name = "zathura-ps-0.2.2"; + name = "zathura-ps-0.2.3"; src = fetchurl { url = "http://pwmt.org/projects/zathura/plugins/download/${name}.tar.gz"; - sha256 = "1a6ps5v1wk18qvslbkjln6w8wfzzr6fi13ls96vbdc03vdhn4m76"; + sha256 = "18wsfy8pqficdgj8wy2aws7j4fy8z78157rhqk17mj5f295zgvm9"; }; buildInputs = [ pkgconfig libspectre gettext zathura_core gtk girara ]; From 7ad9370f0863c0c995b6dd102ea7ce6cbc738430 Mon Sep 17 00:00:00 2001 From: Marius Bakke Date: Tue, 1 Mar 2016 19:49:27 +0000 Subject: [PATCH 15/25] zathura-djvu: 0.2.4 -> 0.2.5 --- pkgs/applications/misc/zathura/djvu/default.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/applications/misc/zathura/djvu/default.nix b/pkgs/applications/misc/zathura/djvu/default.nix index 00c5464b7d1..21e482b1fd2 100644 --- a/pkgs/applications/misc/zathura/djvu/default.nix +++ b/pkgs/applications/misc/zathura/djvu/default.nix @@ -1,11 +1,11 @@ { stdenv, fetchurl, pkgconfig, gtk, zathura_core, girara, djvulibre, gettext }: stdenv.mkDerivation rec { - name = "zathura-djvu-0.2.4"; + name = "zathura-djvu-0.2.5"; src = fetchurl { url = "http://pwmt.org/projects/zathura/plugins/download/${name}.tar.gz"; - sha256 = "1g1lafmrjbx0xv7fljdmyqxx0k334sq4q6jy4a0q5xfrgz0bh45c"; + sha256 = "03cw54d2fipvbrnbqy0xccqkx6s77dyhyymx479aj5ryy4513dq8"; }; buildInputs = [ pkgconfig djvulibre gettext zathura_core gtk girara ]; From 9c86acc479d58785790f9292356a8344e3d70869 Mon Sep 17 00:00:00 2001 From: Marius Bakke Date: Tue, 1 Mar 2016 19:49:46 +0000 Subject: [PATCH 16/25] zathura-pdf-mupdf: 0.2.8 -> 0.3.0 --- pkgs/applications/misc/zathura/pdf-mupdf/default.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/applications/misc/zathura/pdf-mupdf/default.nix b/pkgs/applications/misc/zathura/pdf-mupdf/default.nix index ad5993cf581..2b74fc21b8c 100644 --- a/pkgs/applications/misc/zathura/pdf-mupdf/default.nix +++ b/pkgs/applications/misc/zathura/pdf-mupdf/default.nix @@ -1,12 +1,12 @@ { stdenv, lib, fetchurl, pkgconfig, zathura_core, gtk, girara, mupdf, openssl }: stdenv.mkDerivation rec { - version = "0.2.8"; + version = "0.3.0"; name = "zathura-pdf-mupdf-${version}"; src = fetchurl { url = "https://pwmt.org/projects/zathura-pdf-mupdf/download/${name}.tar.gz"; - sha256 = "0439ls8xqnq6hqa53hd0wqxh1qf0xmccfi3pb0m4mlfs5iv952wz"; + sha256 = "1j3j3wbp49walb19f0966qsnlqbd26wnsjpcxfbf021dav8vk327"; }; buildInputs = [ pkgconfig zathura_core gtk girara openssl mupdf ]; From df32c2d0c8250e8f0e6bb6ff1eb4d7130012364e Mon Sep 17 00:00:00 2001 From: Marius Bakke Date: Tue, 1 Mar 2016 19:52:16 +0000 Subject: [PATCH 17/25] zathura-pdf-poppler: 0.2.5 -> 0.2.6 --- pkgs/applications/misc/zathura/pdf-poppler/default.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/applications/misc/zathura/pdf-poppler/default.nix b/pkgs/applications/misc/zathura/pdf-poppler/default.nix index caaab9ec3c7..6c390d1ed85 100644 --- a/pkgs/applications/misc/zathura/pdf-poppler/default.nix +++ b/pkgs/applications/misc/zathura/pdf-poppler/default.nix @@ -1,12 +1,12 @@ { stdenv, lib, fetchurl, pkgconfig, zathura_core, girara, poppler }: stdenv.mkDerivation rec { - version = "0.2.5"; + version = "0.2.6"; name = "zathura-pdf-poppler-${version}"; src = fetchurl { url = "http://pwmt.org/projects/zathura/plugins/download/${name}.tar.gz"; - sha256 = "1b0chsds8iwjm4g629p6a67nb6wgra65pw2vvngd7g35dmcjgcv0"; + sha256 = "1maqiv7yv8d8hymlffa688c5z71v85kbzmx2j88i8z349xx0rsyi"; }; buildInputs = [ pkgconfig poppler zathura_core girara ]; From 32e751d61648dfc0ede626dc6e93a0f8ed77049d Mon Sep 17 00:00:00 2001 From: Tobias Pflug Date: Tue, 1 Mar 2016 20:42:09 +0100 Subject: [PATCH 18/25] sauce-connect: fix hashes and phases --- pkgs/development/tools/sauce-connect/default.nix | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkgs/development/tools/sauce-connect/default.nix b/pkgs/development/tools/sauce-connect/default.nix index cc904153baf..3818020d931 100644 --- a/pkgs/development/tools/sauce-connect/default.nix +++ b/pkgs/development/tools/sauce-connect/default.nix @@ -9,18 +9,18 @@ stdenv.mkDerivation rec { src = fetchurl ( if stdenv.system == "x86_64-linux" then { url = "https://saucelabs.com/downloads/sc-${version}-linux.tar.gz"; - sha1 = "0d7d2dc12766ac137e62a3e4dad3025b590f9782"; + sha256 = "1flhsssb7wvfbwyvhc9k2di3nd7dlq832xp6dg658xbqk7mr9rvw"; } else if stdenv.system == "i686-linux" then { url = "https://saucelabs.com/downloads/sc-${version}-linux32.tar.gz"; - sha1 = "ee2c3002eae3b29df801a2ac1db77bb5f1c97bcc"; + sha256 = "1hy0riljgjf4sf4cg7kn0hd18w393bdwhp0ajyimzvscg05nx8fq"; } else { url = "https://saucelabs.com/downloads/sc-${version}-osx.zip"; - sha1 = "ihr4ynnyi464pafgqyl5xkhfi13yi76j"; + sha256 = "1fhclbc79rk6pmf5qzc2pkz1z3nsawr9pfi5bzqs8r1514ki4m4p"; } ); buildInputs = [ unzip ]; - phases = "unpackPhase installPhase" + (if stdenv.system == "x86_64-darwin" then "" else "patchPhase"); + phases = "unpackPhase installPhase " + (if stdenv.system == "x86_64-darwin" then "" else "patchPhase"); patchPhase = '' patchelf \ From b2197b84c2d140a802cb5b6f009490f76f034010 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 1 Mar 2016 22:07:54 +0100 Subject: [PATCH 19/25] Fix NixOS eval --- nixos/modules/services/misc/octoprint.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nixos/modules/services/misc/octoprint.nix b/nixos/modules/services/misc/octoprint.nix index 150056b8ab0..9cf46345c22 100644 --- a/nixos/modules/services/misc/octoprint.nix +++ b/nixos/modules/services/misc/octoprint.nix @@ -62,7 +62,7 @@ in }; plugins = mkOption { - type = types.functionTo (types.listOf types.package); + #type = types.functionTo (types.listOf types.package); default = plugins: []; defaultText = "plugins: []"; example = literalExample "plugins: [ m3d-fio ]"; From d2e15a02d71ec8746d134d2fe5d552d3fb969e6b Mon Sep 17 00:00:00 2001 From: Pascal Wittmann Date: Tue, 1 Mar 2016 22:06:58 +0100 Subject: [PATCH 20/25] mujs: 2015-09-29 -> 2016-02-22 --- pkgs/development/interpreters/mujs/default.nix | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkgs/development/interpreters/mujs/default.nix b/pkgs/development/interpreters/mujs/default.nix index 2e8e9b4f985..c321de4dc9a 100644 --- a/pkgs/development/interpreters/mujs/default.nix +++ b/pkgs/development/interpreters/mujs/default.nix @@ -1,12 +1,12 @@ { stdenv, fetchgit, clang }: stdenv.mkDerivation rec { - name = "mujs-2015-09-29"; + name = "mujs-2016-02-22"; src = fetchgit { url = git://git.ghostscript.com/mujs.git; - rev = "08276111f575ac6142e922d62aa264dc1f30b69e"; - sha256 = "18w7yayrn5p8amack4p23wcz49x9cjh1pmzalrf16fhy3n753hbb"; + rev = "624f975aae6b451e35406d8cdde808626052ce2c"; + sha256 = "0vaskzpi84g56yjfkfri1r0lbkawhn556v0b69xjfls7ngsw346y"; }; buildInputs = [ clang ]; From 7f8d50b4435941a6895195a14739ec29b1c6aa59 Mon Sep 17 00:00:00 2001 From: Aneesh Agrawal Date: Tue, 1 Mar 2016 12:14:33 -0500 Subject: [PATCH 21/25] openssh: 7.1p2 -> 7.2p1 --- pkgs/tools/networking/openssh/default.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/tools/networking/openssh/default.nix b/pkgs/tools/networking/openssh/default.nix index a6aed5169c8..5bd9c4b7acb 100644 --- a/pkgs/tools/networking/openssh/default.nix +++ b/pkgs/tools/networking/openssh/default.nix @@ -23,11 +23,11 @@ let in with stdenv.lib; stdenv.mkDerivation rec { - name = "openssh-7.1p2"; + name = "openssh-7.2p1"; src = fetchurl { url = "mirror://openbsd/OpenSSH/portable/${name}.tar.gz"; - sha256 = "1gbbvszz74lkc7b2mqr3ccgpm65zj0k5h7a2ssh0c7pjvhjg0xfx"; + sha256 = "1hsa1f3641pdj57a55gmnvcya3wwww2fc2cvb77y95rm5xxw6g4p"; }; prePatch = optionalString hpnSupport From cc71804ab0647839ee4467763fd37397e05a52c6 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 1 Mar 2016 22:24:07 +0100 Subject: [PATCH 22/25] openssh: Fix build --- pkgs/tools/networking/openssh/default.nix | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/pkgs/tools/networking/openssh/default.nix b/pkgs/tools/networking/openssh/default.nix index 5bd9c4b7acb..4d3ffb1257f 100644 --- a/pkgs/tools/networking/openssh/default.nix +++ b/pkgs/tools/networking/openssh/default.nix @@ -37,15 +37,7 @@ stdenv.mkDerivation rec { ''; patches = - [ ./locale_archive.patch - - # Fix "HostKeyAlgoritms +...", which we need to enable DSA - # host key support. - (fetchurl { - url = "https://pkgs.fedoraproject.org/cgit/rpms/openssh.git/plain/openssh-7.1p1-hostkeyalgorithms.patch?id=c98f5597250d6f9a8e8d96960beb6306d150ef0f"; - sha256 = "029lzp9qv1af8wdm0wwj7qwjj1nimgsjj214jqm3amwz0857qgvp"; - }) - ] + [ ./locale_archive.patch ] ++ optional withGssapiPatches gssapiSrc; buildInputs = [ zlib openssl libedit pkgconfig pam ] From afa7d8452903318dd09e742e57899ba745c516cf Mon Sep 17 00:00:00 2001 From: Pascal Wittmann Date: Tue, 1 Mar 2016 22:53:49 +0100 Subject: [PATCH 23/25] instead: 2.3.0 -> 2.4.0 --- pkgs/games/instead/default.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/games/instead/default.nix b/pkgs/games/instead/default.nix index 6d55f2a2d5c..3dbda395dd6 100644 --- a/pkgs/games/instead/default.nix +++ b/pkgs/games/instead/default.nix @@ -1,7 +1,7 @@ { stdenv, fetchurl, SDL, SDL_ttf, SDL_image, SDL_mixer, pkgconfig, lua, zlib, unzip }: let - version = "2.3.0"; + version = "2.4.0"; # I took several games at random from http://instead.syscall.ru/games/ games = [ @@ -33,7 +33,7 @@ stdenv.mkDerivation rec { src = fetchurl { url = "mirror://sourceforge/project/instead/instead/${version}/instead_${version}.tar.gz"; - sha256 = "1ldisjkmmcpnmv4vsd25dc1sfiwbr9fcn3hxhl78i4jwlyqgrms8"; + sha256 = "1xxga3ppgjshxzd0p53vsbaqkpzmjnm4vw0j1v7qbqzjgi3r44ix"; }; NIX_LDFLAGS = "-llua -lgcc_s"; From e50da7ee6a44fcdb846139b2b902c202959c5f61 Mon Sep 17 00:00:00 2001 From: Maxwell Date: Sat, 30 Jan 2016 21:09:37 -0500 Subject: [PATCH 24/25] bspwm: add startThroughSession & sessionScript option Add ability to do a more traditional bspwm startup (using the bspwm-session script provided by nixpkgs.bspwm) as an alternative to directly starting sxhkd & bspwm Also added the ability to specify a custom startup script, instead of relying on the provided bspwm-session --- .../services/x11/window-managers/bspwm.nix | 33 ++++++++++++++++--- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/nixos/modules/services/x11/window-managers/bspwm.nix b/nixos/modules/services/x11/window-managers/bspwm.nix index 1edf6ba4deb..271b1b6cf5d 100644 --- a/nixos/modules/services/x11/window-managers/bspwm.nix +++ b/nixos/modules/services/x11/window-managers/bspwm.nix @@ -8,16 +8,39 @@ in { options = { - services.xserver.windowManager.bspwm.enable = mkEnableOption "bspwm"; + services.xserver.windowManager.bspwm = { + enable = mkEnableOption "bspwm"; + startThroughSession = mkOption { + type = with types; bool; + default = false; + description = " + Start the window manager through the script defined in + sessionScript. Defaults to the the bspwm-session script + provided by bspwm + "; + }; + sessionScript = mkOption { + default = "${pkgs.bspwm}/bin/bspwm-session"; + defaultText = "(pkgs.bspwm)/bin/bspwm-session"; + description = " + The start-session script to use. Defaults to the + provided bspwm-session script from the bspwm package. + + Does nothing unless `bspwm.startThroughSession` is enabled + "; + }; + }; }; config = mkIf cfg.enable { services.xserver.windowManager.session = singleton { name = "bspwm"; - start = " - SXHKD_SHELL=/bin/sh ${pkgs.sxhkd}/bin/sxhkd -f 100 & - ${pkgs.bspwm}/bin/bspwm - "; + start = if cfg.startThroughSession + then cfg.sessionScript + else '' + SXHKD_SHELL=/bin/sh ${pkgs.sxhkd}/bin/sxhkd -f 100 & + ${pkgs.bspwm}/bin/bspwm + ''; }; environment.systemPackages = [ pkgs.bspwm ]; }; From 995475944f4213ddef3382ed09ba2fdc10687e1d Mon Sep 17 00:00:00 2001 From: Robin Gloster Date: Tue, 1 Mar 2016 22:44:31 +0000 Subject: [PATCH 25/25] qt_gstreamer1: add upstream patch to build with current gstreamer --- .../libraries/gstreamer/qt-gstreamer/default.nix | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/pkgs/development/libraries/gstreamer/qt-gstreamer/default.nix b/pkgs/development/libraries/gstreamer/qt-gstreamer/default.nix index b306e737df1..3bd840dcd7e 100644 --- a/pkgs/development/libraries/gstreamer/qt-gstreamer/default.nix +++ b/pkgs/development/libraries/gstreamer/qt-gstreamer/default.nix @@ -1,4 +1,4 @@ -{ stdenv, fetchurl, gst_all_1, boost, glib, qt4, cmake +{ stdenv, fetchurl, fetchpatch, gst_all_1, boost, glib, qt4, cmake , automoc4, flex, bison, pkgconfig }: stdenv.mkDerivation rec { @@ -10,13 +10,20 @@ stdenv.mkDerivation rec { sha256 = "9f3b492b74cad9be918e4c4db96df48dab9c012f2ae5667f438b64a4d92e8fd4"; }; + patches = [ + (fetchpatch { + url = "https://cgit.freedesktop.org/gstreamer/qt-gstreamer/patch/?id=e2ca8094aa8d0eac1c3a98df66fe94ce0c754088"; + sha256 = "1qps0nlc26d74wk8h96xl5s3d9qrdx6c0ph0zpl1dnc691lgyf6s"; + }) + ]; + buildInputs = [ gst_all_1.gstreamer gst_all_1.gst-plugins-base glib qt4 ]; propagatedBuildInputs = [ boost ]; nativeBuildInputs = [ cmake automoc4 flex bison pkgconfig ]; cmakeFlags = "-DUSE_QT_PLUGIN_DIR=OFF -DUSE_GST_PLUGIN_DIR=OFF"; - meta = { + meta = { platforms = stdenv.lib.platforms.linux; }; }