Merge branch 'master' of github.com:NixOS/nixos into systemd

wip/yesman
Eelco Dolstra 12 years ago
commit 08f14b33c1
  1. 4
      lib/build-vms.nix
  2. 10
      lib/test-driver/Machine.pm
  3. 4
      lib/testing.nix
  4. 6
      modules/config/swap.nix
  5. 11
      modules/config/users-groups.nix
  6. 6
      modules/hardware/network/ralink.nix
  7. 2
      modules/installer/cd-dvd/system-tarball-fuloong2f.nix
  8. 2
      modules/installer/cd-dvd/system-tarball-sheevaplug.nix
  9. 2
      modules/installer/scan/not-detected.nix
  10. 2
      modules/misc/ids.nix
  11. 3
      modules/module-list.nix
  12. 10
      modules/programs/bash/bashrc.sh
  13. 1
      modules/rename.nix
  14. 11
      modules/security/sudo.nix
  15. 9
      modules/services/databases/postgresql.nix
  16. 5
      modules/services/hardware/udev.nix
  17. 45
      modules/services/mail/spamassassin.nix
  18. 12
      modules/services/web-servers/apache-httpd/default.nix
  19. 1
      modules/system/activation/top-level.nix
  20. 66
      modules/system/boot/kernel.nix
  21. 98
      modules/system/boot/loader/efi-boot-stub/efi-boot-stub.nix
  22. 8
      modules/system/boot/stage-1-init.sh
  23. 5
      modules/system/boot/stage-1.nix
  24. 2
      modules/system/boot/stage-2-init.sh
  25. 6
      modules/tasks/filesystems/nfs.nix
  26. 28
      modules/testing/minimal-kernel.nix
  27. 8
      modules/testing/test-instrumentation.nix
  28. 38
      modules/virtualisation/qemu-vm.nix
  29. 1
      release.nix
  30. 4
      tests/default.nix

@ -1,4 +1,4 @@
{ system }:
{ system, minimal ? false }:
let pkgs = import <nixpkgs> { config = {}; inherit system; }; in
@ -27,7 +27,7 @@ rec {
[ ../modules/virtualisation/qemu-vm.nix
../modules/testing/test-instrumentation.nix # !!! should only get added for automated test runs
{ key = "no-manual"; services.nixosManual.enable = false; }
];
] ++ lib.optional minimal ../modules/testing/minimal-kernel.nix;
extraArgs = { inherit nodes; };
};

@ -8,10 +8,13 @@ use POSIX qw(dup2);
use FileHandle;
use Cwd;
use File::Basename;
use File::Path qw(make_path);
my $showGraphics = defined $ENV{'DISPLAY'};
my $sharedDir;
sub new {
my ($class, $args) = @_;
@ -40,7 +43,11 @@ sub new {
}
my $tmpDir = $ENV{'TMPDIR'} || "/tmp";
unless (defined $sharedDir) {
$sharedDir = $tmpDir . "/xchg-shared";
make_path($sharedDir, { mode => 0700, owner => $< });
}
my $self = {
startCommand => $startCommand,
name => $name,
@ -126,6 +133,7 @@ sub start {
dup2(fileno($serialC), fileno(STDERR));
}
$ENV{TMPDIR} = $self->{stateDir};
$ENV{SHARED_DIR} = $sharedDir;
$ENV{USE_TMPDIR} = 1;
$ENV{QEMU_OPTS} =
"-no-reboot -monitor unix:./monitor -chardev socket,id=shell,path=./shell " .

@ -1,6 +1,6 @@
{ system }:
{ system, minimal ? false }:
with import ./build-vms.nix { inherit system; };
with import ./build-vms.nix { inherit system minimal; };
with pkgs;
rec {

@ -73,4 +73,10 @@ with pkgs.lib;
};
config = mkIf ((length config.swapDevices) != 0) {
system.requiredKernelConfig = with config.lib.kernelConfig; [
(isYes "SWAP")
];
};
}

@ -266,15 +266,11 @@ in
oldIFS="$IFS"; IFS=:; set -- $curEnt; IFS="$oldIFS"
prevUid=$3
prevHome=$6
# Don't change the UID if it's the same, otherwise usermod
# will complain.
if test "$prevUid" = "$uid"; then unset uid; fi
# Don't change the home directory if it's the same to prevent
# unnecessary warnings about logged in users.
if test "$prevHome" = "$home"; then unset home; fi
usermod \
--comment "$description" \
''${uid:+--uid $uid} \
--gid "$group" \
--groups "$extraGroups" \
''${home:+--home "$home"} \
@ -297,13 +293,6 @@ in
groupadd --system \
''${gid:+--gid $gid} \
"$name"
else
#echo "updating group $name..."
oldIFS="$IFS"; IFS=:; set -- $curEnt; IFS="$oldIFS"
prevGid=$3
if test -n "$gid" -a "$prevGid" != "$gid"; then
groupmod --gid $gid "$name"
fi
fi
}

@ -6,7 +6,7 @@
options = {
networking.enableRT73Firmware = pkgs.lib.mkOption {
networking.enableRalinkFirmware = pkgs.lib.mkOption {
default = false;
type = pkgs.lib.types.bool;
description = ''
@ -19,8 +19,8 @@
###### implementation
config = pkgs.lib.mkIf config.networking.enableRT73Firmware {
hardware.firmware = [ pkgs.rt73fw ];
config = pkgs.lib.mkIf config.networking.enableRalinkFirmware {
hardware.firmware = [ pkgs.ralink_fw ];
};
}

@ -128,7 +128,7 @@ in
'';
# Include the firmware for various wireless cards.
networking.enableRT73Firmware = true;
networking.enableRalinkFirmware = true;
networking.enableIntel2200BGFirmware = true;
# To speed up further installation of packages, include the complete stdenv

@ -152,7 +152,7 @@ in
services.nixosManual.enable = false;
# Include the firmware for various wireless cards.
networking.enableRT73Firmware = true;
networking.enableRalinkFirmware = true;
networking.enableIntel2200BGFirmware = true;
# To speed up further installation of packages, include the complete stdenv

@ -19,6 +19,6 @@ with pkgs.lib;
config = mkDefault {
# That wireless card firmware not enabled because the corresponding
# build expression 'rt73fw' is broken.
networking.enableRT73Firmware = false;
networking.enableRalinkFirmware = false;
};
}

@ -72,6 +72,7 @@ in
clamav = 51;
fprot = 52;
bind = 53;
wwwrun = 54;
# When adding a uid, make sure it doesn't match an existing gid.
@ -123,6 +124,7 @@ in
mpd = 50;
clamav = 51;
fprot = 52;
wwwrun = 54;
adm = 55;
# When adding a gid, make sure it doesn't match an existing uid.

@ -20,7 +20,7 @@
./hardware/network/intel-2100bg.nix
./hardware/network/intel-2200bg.nix
./hardware/network/intel-3945abg.nix
./hardware/network/rt73.nix
./hardware/network/ralink.nix
./hardware/network/rtl8192c.nix
./hardware/pcmcia.nix
./installer/tools/nixos-checkout.nix
@ -85,6 +85,7 @@
./services/mail/freepops.nix
./services/mail/mail.nix
./services/mail/postfix.nix
./services/mail/spamassassin.nix
./services/misc/autofs.nix
./services/misc/disnix.nix
./services/misc/felix.nix

@ -31,13 +31,9 @@ fi
# programmable completion. If we do, and if the current user has
# installed the package 'bash-completion' in her $HOME/.nix-profile,
# then completion is enabled automatically.
if [ -f "$HOME/.nix-profile/etc/bash_completion" ]; then
if [ -d "$HOME/.nix-profile/etc/bash_completion.d" ]; then
if shopt -q progcomp &>/dev/null; then
BASH_COMPLETION_DIR="$HOME/.nix-profile/etc/bash_completion.d"
BASH_COMPLETION="$HOME/.nix-profile/etc/bash_completion"
. "$BASH_COMPLETION"
fi
if [ -f "$HOME/.nix-profile/etc/profile.d/bash_completion.sh" ]; then
if shopt -q progcomp &>/dev/null; then
. "$HOME/.nix-profile/etc/profile.d/bash_completion.sh"
fi
fi

@ -69,6 +69,7 @@ in zipModules ([]
++ rename obsolete "security.extraSetuidPrograms" "security.setuidPrograms"
++ rename obsolete "networking.enableWLAN" "networking.wireless.enable"
++ rename obsolete "networking.enableRT73Firmware" "networking.enableRalinkFirmware"
# Old Grub-related options.
++ rename obsolete "boot.copyKernels" "boot.loader.grub.copyKernels"

@ -25,6 +25,15 @@ in
'';
};
security.sudo.wheelNeedsPassword = mkOption {
default = true;
description =
''
Whether users of the <code>wheel</code> group can execute
commands as super user without entering a password.
'';
};
security.sudo.configFile = mkOption {
# Note: if syntax errors are detected in this file, the NixOS
# configuration will fail to build.
@ -45,7 +54,7 @@ in
root ALL=(ALL) SETENV: ALL
# Users in the "wheel" group can do anything.
%wheel ALL=(ALL) SETENV: ALL
%wheel ALL=(ALL) ${if cfg.wheelNeedsPassword then "" else "NOPASSWD: ALL, "}SETENV: ALL
'';
description =
''

@ -20,7 +20,7 @@ let
'';
};
postgresql = postgresqlAndPlugins pkgs.postgresql;
postgresql = postgresqlAndPlugins cfg.package;
run = "su -s ${pkgs.stdenv.shell} postgres";
@ -54,6 +54,13 @@ in
'';
};
package = mkOption {
default = pkgs.postgresql;
description = ''
PostgreSQL package to use.
'';
};
port = mkOption {
default = "5432";
description = ''

@ -195,6 +195,11 @@ in
}
];
system.requiredKernelConfig = with config.lib.kernelConfig; [
(isEnabled "UNIX")
(isYes "INOTIFY_USER")
(isYes "NET")
];
};
}

@ -0,0 +1,45 @@
{ config, pkgs, ... }:
with pkgs.lib;
let
cfg = config.services.spamassassin;
in
{
###### interface
options = {
services.spamassassin = {
enable = mkOption {
default = false;
description = "Whether to run the SpamAssassin daemon.";
};
};
};
###### implementation
config = mkIf cfg.enable {
# Allow users to run 'spamc'.
environment.systemPackages = [ pkgs.spamassassin ];
jobs.spamd = {
description = "Spam Assassin Server";
startOn = "started networking and filesystem";
environment.TZ = config.time.timeZone;
exec = "${pkgs.spamassassin}/bin/spamd -C /etc/spamassassin/init.pre --siteconfigpath=/etc/spamassassin --debug --pidfile=/var/run/spamd.pid";
};
};
}

@ -557,14 +557,16 @@ in
config = mkIf config.services.httpd.enable {
users.extraUsers = singleton
{ name = mainCfg.user;
group = mainCfg.group;
users.extraUsers = optionalAttrs (mainCfg.user == "wwwrun") singleton
{ name = "wwwrun";
group = "wwwrun";
description = "Apache httpd user";
uid = config.ids.uids.wwwrun;
};
users.extraGroups = singleton
{ name = mainCfg.group;
users.extraGroups = optionalAttrs (mainCfg.group == "wwwrun") singleton
{ name = "wwwrun";
gid = config.ids.gids.wwwrun;
};
environment.systemPackages = [httpd] ++ concatMap (svc: svc.extraPath) allSubservices;

@ -37,6 +37,7 @@ let
system.boot.loader.kernelFile = mkOption {
default = pkgs.stdenv.platform.kernelTarget;
type = types.uniq types.string;
description = ''
Name of the kernel file to be passed to the bootloader.
'';

@ -108,6 +108,24 @@ let kernel = config.boot.kernelPackages.kernel; in
apply = pkgs.aggregateModules;
};
system.requiredKernelConfig = mkOption {
default = [];
example = literalExample ''
with config.lib.kernelConfig; [
(isYes "MODULES")
(isEnabled "FB_CON_DECOR")
(isEnabled "BLK_DEV_INITRD")
]
'';
internal = true;
type = types.listOf types.attrs;
description = ''
This option allows modules to specify the kernel config options that
must be set (or unset) for the module to work. Please use the
lib.kernelConfig functions to build list elements.
'';
};
};
@ -185,6 +203,54 @@ let kernel = config.boot.kernelPackages.kernel; in
'';
};
lib.kernelConfig = {
isYes = option: {
assertion = config: config.isYes option;
message = "CONFIG_${option} is not yes!";
configLine = "CONFIG_${option}=y";
};
isNo = option: {
assertion = config: config.isNo option;
message = "CONFIG_${option} is not no!";
configLine = "CONFIG_${option}=n";
};
isModule = option: {
assertion = config: config.isModule option;
message = "CONFIG_${option} is not built as a module!";
configLine = "CONFIG_${option}=m";
};
### Usually you will just want to use these two
# True if yes or module
isEnabled = option: {
assertion = config: config.isEnabled option;
message = "CONFIG_${option} is not enabled!";
configLine = "CONFIG_${option}=y";
};
# True if no or omitted
isDisabled = option: {
assertion = config: config.isDisabled option;
message = "CONFIG_${option} is not disabled!";
configLine = "CONFIG_${option}=n";
};
};
# The config options that all modules can depend upon
system.requiredKernelConfig = with config.lib.kernelConfig; [
# !!! Should this really be needed?
(isYes "MODULES")
(isYes "BINFMT_ELF")
];
# nixpkgs kernels are assumed to have all required features
assertions = if config.boot.kernelPackages.kernel ? features then [] else
let cfg = config.boot.kernelPackages.kernel.config; in map (attrs:
{ assertion = attrs.assertion cfg; inherit (attrs) message; }
) config.system.requiredKernelConfig;
};
}

@ -1,9 +1,42 @@
{pkgs, config, ...}:
###### interface
with pkgs.lib;
let
inherit (pkgs.lib) mkOption mkIf;
efiBootStubBuilder = pkgs.substituteAll {
src = ./efi-boot-stub-builder.sh;
isExecutable = true;
inherit (pkgs) bash;
path = [pkgs.coreutils pkgs.gnused pkgs.gnugrep pkgs.glibc] ++ (pkgs.stdenv.lib.optionals config.boot.loader.efiBootStub.runEfibootmgr [pkgs.efibootmgr pkgs.module_init_tools]);
inherit (config.boot.loader.efiBootStub) efiSysMountPoint runEfibootmgr installStartupNsh efiDisk efiPartition;
efiShell = if config.boot.loader.efiBootStub.installShell then
if pkgs.stdenv.isi686 then
pkgs.fetchurl {
url = "https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2/EdkShellBinPkg/FullShell/Ia32/Shell_Full.efi";
sha256 = "1gv6kyaspczdp7x8qnx5x76ilriaygkfs99ay7ihhdi6riclkhfl";
}
else
pkgs.fetchurl {
url = "https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2/EdkShellBinPkg/FullShell/X64/Shell_Full.efi";
sha256 = "1g18z84rlavxr5gsrh2g942rfr6znv9fs3fqww5m7dhmnysgyv8p";
}
else
null;
kernelFile = platform.kernelTarget;
targetArch = if pkgs.stdenv.isi686 then
"IA32"
else if pkgs.stdenv.isx86_64 then
"X64"
else
throw "Unsupported architecture";
};
# Temporary check, for nixos to cope both with nixpkgs stdenv-updates and trunk
platform = pkgs.stdenv.platform;
in
{
options = {
boot = {
loader = {
@ -75,56 +108,17 @@ let
};
};
in
###### implementation
let
efiBootStubBuilder = pkgs.substituteAll {
src = ./efi-boot-stub-builder.sh;
isExecutable = true;
inherit (pkgs) bash;
path = [pkgs.coreutils pkgs.gnused pkgs.gnugrep pkgs.glibc] ++ (pkgs.stdenv.lib.optionals config.boot.loader.efiBootStub.runEfibootmgr [pkgs.efibootmgr pkgs.module_init_tools]);
inherit (config.boot.loader.efiBootStub) efiSysMountPoint runEfibootmgr installStartupNsh efiDisk efiPartition;
efiShell = if config.boot.loader.efiBootStub.installShell then
if pkgs.stdenv.isi686 then
pkgs.fetchurl {
url = "https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2/EdkShellBinPkg/FullShell/Ia32/Shell_Full.efi";
sha256 = "1gv6kyaspczdp7x8qnx5x76ilriaygkfs99ay7ihhdi6riclkhfl";
}
else
pkgs.fetchurl {
url = "https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2/EdkShellBinPkg/FullShell/X64/Shell_Full.efi";
sha256 = "1g18z84rlavxr5gsrh2g942rfr6znv9fs3fqww5m7dhmnysgyv8p";
}
else
null;
kernelFile = platform.kernelTarget;
targetArch = if pkgs.stdenv.isi686 then
"IA32"
else if pkgs.stdenv.isx86_64 then
"X64"
else
throw "Unsupported architecture";
config = mkIf config.boot.loader.efiBootStub.enable {
assertions = [ { assertion = ! config.boot.kernelPackages.kernel ? features || config.boot.kernelPackages.kernel.features ? efiBootStub; message = "This kernel does not support the EFI boot stub"; } ];
system = {
build.installBootLoader = efiBootStubBuilder;
boot.loader.id = "efiBootStub";
boot.loader.kernelFile = platform.kernelTarget;
requiredKernelConfig = with config.lib.kernelConfig; [
(isYes "EFI_STUB")
];
};
};
# Temporary check, for nixos to cope both with nixpkgs stdenv-updates and trunk
platform = pkgs.stdenv.platform;
in
{
require = [
options
# config.system.build
# ../system/system-options.nix
];
system = mkIf (config.boot.loader.efiBootStub.enable && (assert
(config.boot.kernelPackages.kernel.features ? efiBootStub &&
config.boot.kernelPackages.kernel.features.efiBootStub); true)) {
build.installBootLoader = efiBootStubBuilder;
boot.loader.id = "efiBootStub";
boot.loader.kernelFile = platform.kernelTarget;
};
}

@ -255,11 +255,7 @@ mountFS() {
# For CIFS mounts, retry a few times before giving up.
local n=0
while true; do
if [ "$fsType" = "nfs" ]; then
nfsmount "$device" "/mnt-root$mountPoint" && break
else
mount "/mnt-root$mountPoint" && break
fi
mount "/mnt-root$mountPoint" && break
if [ "$fsType" != cifs -o "$n" -ge 10 ]; then fail; break; fi
echo "retrying..."
n=$((n + 1))
@ -322,6 +318,8 @@ while read -u 3 mountPoint; do
mountFS "$device" "$mountPoint" "$options" "$fsType"
done
exec 3>&-
@postMountCommands@

@ -239,6 +239,7 @@ let
--replace ata_id ${extraUtils}/bin/ata_id \
--replace scsi_id ${extraUtils}/bin/scsi_id \
--replace cdrom_id ${extraUtils}/bin/cdrom_id \
--replace ${pkgs.utillinux}/sbin/blkid ${extraUtils}/bin/blkid \
--replace /sbin/blkid ${extraUtils}/bin/blkid \
--replace ${pkgs.lvm2}/sbin ${extraUtils}/bin \
--replace /sbin/mdadm ${extraUtils}/bin/mdadm
@ -314,4 +315,8 @@ in {
system.build.initialRamdisk = initialRamdisk;
system.build.extraUtils = extraUtils;
system.requiredKernelConfig = with config.lib.kernelConfig; [
(isYes "TMPFS")
(isYes "BLK_DEV_INITRD")
];
}

@ -28,7 +28,7 @@ setPath "@path@"
# However, in some environments (such as Amazon EC2), stage 2 is
# executed directly, and the root is read-only. So make it writable
# here.
mount -n -o remount,rw none /
mount -n -o remount,rw /
# Likewise, stage 1 mounts /proc, /dev and /sys, so if we don't have a

@ -40,12 +40,6 @@ in
boot.initrd.kernelModules = mkIf inInitrd [ "nfs" ];
boot.initrd.extraUtilsCommands = mkIf inInitrd
''
# !!! Uh, why don't we just install mount.nfs?
cp -v ${pkgs.klibc}/lib/klibc/bin.static/nfsmount $out/bin
'';
# Ensure that statd and idmapd are started before mountall.
jobs.mountall.preStart =
''

@ -0,0 +1,28 @@
{ config, pkgs, ... }:
let
configfile = builtins.storePath (builtins.toFile "config" (pkgs.lib.concatStringsSep "\n"
(map (builtins.getAttr "configLine") config.system.requiredKernelConfig))
);
origKernel = pkgs.linuxManualConfig {
inherit (pkgs.linux) src version;
inherit configfile;
allowImportFromDerivation = true;
kernelPatches = [ pkgs.kernelPatches.cifs_timeout_2_6_38 ];
};
kernel = origKernel // (derivation (origKernel.drvAttrs // {
configurePhase = ''
runHook preConfigure
mkdir ../build
make $makeFlags "''${makeFlagsArray[@]}" mrproper
make $makeFlags "''${makeFlagsArray[@]}" KCONFIG_ALLCONFIG=${configfile} allnoconfig
runHook postConfigure
'';
}));
kernelPackages = pkgs.linuxPackagesFor kernel kernelPackages;
in {
boot.kernelPackages = kernelPackages;
}

@ -5,6 +5,8 @@
with pkgs.lib;
let kernel = config.boot.kernelPackages.kernel; in
{
config = {
@ -75,6 +77,12 @@ with pkgs.lib;
system.upstartEnvironment.GCOV_PREFIX = "/tmp/xchg/coverage-data";
system.requiredKernelConfig = with config.lib.kernelConfig; [
(isYes "SERIAL_8250_CONSOLE")
(isYes "SERIAL_8250")
(isEnabled "VIRTIO_CONSOLE")
];
};
}

@ -155,6 +155,14 @@ let
cd $TMPDIR
mkdir -p $TMPDIR/xchg
EXTRA_SAMBA_CONF="
[shared]
force user = $WHO
path = ''${SHARED_DIR:-$TMPDIR/xchg}
read only = no
guest ok = yes
"
${pkgs.vmTools.startSamba}
# Start QEMU.
@ -211,7 +219,7 @@ let
. /sys/class/block/vda1/uevent
mknod /dev/vda1 b $MAJOR $MINOR
. /sys/class/block/vda/uevent
${pkgs.e2fsprogs}/sbin/mkfs.ext3 -L boot /dev/vda1
${pkgs.e2fsprogs}/sbin/mkfs.ext4 -L boot /dev/vda1
${pkgs.e2fsprogs}/sbin/tune2fs -c 0 -i 0 /dev/vda1
# Mount /boot.
@ -264,7 +272,7 @@ in
# initialise.
FSTYPE=$(blkid -o value -s TYPE /dev/vda || true)
if test -z "$FSTYPE"; then
mke2fs -t ext3 /dev/vda
mke2fs -t ext4 /dev/vda
fi
'';
@ -328,10 +336,16 @@ in
options = "guest,sec=none,noperm,noacl";
neededForBoot = true;
}
{ mountPoint = "/tmp/shared";
device = "//10.0.2.4/shared";
fsType = "cifs";
options = "guest,sec=none,noperm,noacl";
neededForBoot = true;
}
] ++ optional cfg.useBootLoader
{ mountPoint = "/boot";
device = "/dev/disk/by-label/boot";
fsType = "ext3";
fsType = "ext4";
options = "ro";
noCheck = true; # fsck fails on a r/o filesystem
});
@ -385,4 +399,22 @@ in
# Wireless won't work in the VM.
networking.wireless.enable = mkOverride 50 false;
system.requiredKernelConfig = with config.lib.kernelConfig;
[ (isEnabled "VIRTIO_BLK")
(isEnabled "VIRTIO_PCI")
(isEnabled "VIRTIO_NET")
(isEnabled "EXT4_FS")
(isEnabled "CIFS")
(isYes "BLK_DEV")
(isYes "PCI")
(isYes "EXPERIMENTAL")
(isYes "NETDEVICES")
(isYes "NET_CORE")
(isYes "INET")
(isYes "NETWORK_FILESYSTEMS")
] ++ optional (!cfg.graphics) [
(isYes "SERIAL_8250_CONSOLE")
(isYes "SERIAL_8250")
];
}

@ -1,5 +1,6 @@
{ nixosSrc ? {outPath = ./.; revCount = 1234; shortRev = "abcdef"; }
, nixpkgs ? {outPath = <nixpkgs>; revCount = 5678; shortRev = "fedcba"; }
#, minimal ? false
}:
let

@ -1,6 +1,6 @@
{ system ? builtins.currentSystem }:
{ system ? builtins.currentSystem, minimal ? false }:
with import ../lib/testing.nix { inherit system; };
with import ../lib/testing.nix { inherit system minimal; };
{
avahi = makeTest (import ./avahi.nix);

Loading…
Cancel
Save