Merge remote-tracking branch 'upstream/master' into hardened-stdenv

This commit is contained in:
Robin Gloster 2016-03-01 22:46:39 +00:00
commit 33f7d0b3f6
22 changed files with 801 additions and 682 deletions

View File

@ -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 ]";

View File

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

View File

@ -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
@ -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.biosCdrom)
(all nixos.tests.ipv6)
(all nixos.tests.kde4)
#(all nixos.tests.lightdm)

View File

@ -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"; };
@ -215,8 +233,9 @@ 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.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"; });
@ -232,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 {};
@ -262,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; };
@ -299,12 +291,8 @@ 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 = 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

View File

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

View File

@ -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" ''
<!DOCTYPE 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;
}

View File

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

View File

@ -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 =~ /<none>/;
};
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 =~ /<none>/;
'';
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;
'';
}

View File

@ -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 = ''

View File

@ -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)"

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,108 @@
--- ./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/scannermain.py b/giscanner/scannermain.py
index 89ec193..54f1d2e 100755
--- a/giscanner/scannermain.py
+++ b/giscanner/scannermain.py
@@ -94,6 +94,39 @@ def get_windows_option_group(parser):
return group
+def _get_default_fallback_libpath():
+ # 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
+ # 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 +233,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..ca7fc0d 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 = "(?<![A-Za-z0-9_-])(lib*%s[^A-Za-z0-9_-][^\s\(\)]*)"
- if platform.system() == 'Darwin':
- pattern = "([^\s]*lib*%s[^A-Za-z0-9_-][^\s\(\)]*)"
- return re.compile(pattern % re.escape(library_name))
+ pattern = r'''
+ (
+ (?:
+ # 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 with temporary paths that are only valid during
+ # build time in the resulting GIR file.
+ | (?<=/)
+ )
+ # And finally the library itself:
+ (?:lib%s[^A-Za-z0-9_-][^\s\(\)]*)
+ )
+ '''
+ return re.compile(pattern % (nix_store_dir, re.escape(library_name)),
+ re.VERBOSE)
# 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
+++ b/giscanner/utils.py
@@ -109,17 +109,11 @@ def extract_libtool_shlib(la_file):
if dlname is None:
return None

View File

@ -1,5 +1,7 @@
{ stdenv, fetchurl, glib, flex, bison, pkgconfig, libffi, python
, libintlOrEmpty, autoconf, automake, otool }:
, libintlOrEmpty, autoconf, automake, otool
, substituteAll, nixStoreDir ? builtins.storeDir
}:
# now that gobjectIntrospection creates large .gir files (eg gtk3 case)
# it may be worth thinking about using multiple derivation outputs
# In that case its about 6MB which could be separated
@ -33,7 +35,10 @@ stdenv.mkDerivation rec {
setupHook = ./setup-hook.sh;
patches = [ ./absolute_shlib_path.patch ];
patches = stdenv.lib.singleton (substituteAll {
src = ./absolute_shlib_path.patch;
inherit nixStoreDir;
});
meta = with stdenv.lib; {
description = "A middleware layer between C libraries and language bindings";

View File

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

View File

@ -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 \

View File

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

View File

@ -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
@ -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 ]

View File

@ -6833,7 +6833,9 @@ let
#GMP ex-satellite, so better keep it near gmp
mpfr = callPackage ../development/libraries/mpfr/default.nix { };
gobjectIntrospection = callPackage ../development/libraries/gobject-introspection { };
gobjectIntrospection = callPackage ../development/libraries/gobject-introspection {
nixStoreDir = config.nix.storeDir or builtins.storeDir;
};
goocanvas = callPackage ../development/libraries/goocanvas { };