Merging from trunk
svn path=/nixos/branches/stdenv-updates/; revision=25176
This commit is contained in:
commit
3f7751b9c2
|
@ -0,0 +1,148 @@
|
||||||
|
<refentry xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||||
|
|
||||||
|
<refmeta>
|
||||||
|
<refentrytitle><command>nixos-build-vms</command></refentrytitle>
|
||||||
|
<manvolnum>8</manvolnum>
|
||||||
|
<refmiscinfo class="source">NixOS</refmiscinfo>
|
||||||
|
<!-- <refmiscinfo class="version"><xi:include href="version.txt" parse="text"/></refmiscinfo> -->
|
||||||
|
</refmeta>
|
||||||
|
|
||||||
|
<refnamediv>
|
||||||
|
<refname><command>nixos-build-vms</command></refname>
|
||||||
|
<refpurpose>build a network of virtual machines from a network of NixOS configurations</refpurpose>
|
||||||
|
</refnamediv>
|
||||||
|
|
||||||
|
<refsynopsisdiv>
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>nixos-build-vms</command>
|
||||||
|
<arg><option>--use-backdoor</option></arg>
|
||||||
|
<arg><option>--show-trace</option></arg>
|
||||||
|
<arg><option>--no-out-link</option></arg>
|
||||||
|
<arg><option>--help</option></arg>
|
||||||
|
<arg choice="plain"><replaceable>network.nix</replaceable></arg>
|
||||||
|
</cmdsynopsis>
|
||||||
|
</refsynopsisdiv>
|
||||||
|
|
||||||
|
<refsection><title>Description</title>
|
||||||
|
|
||||||
|
<para>This command builds a network of QEMU-KVM virtual machines of a Nix expression
|
||||||
|
specifying a network of NixOS machines. The virtual network can be started by
|
||||||
|
executing the <filename>bin/run-vms</filename> shell script that is generated by
|
||||||
|
this command. By default, a <filename>result</filename> symlink is produced that
|
||||||
|
points to the generated virtual network.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>This command also provides the <option>--use-backdoor</option> option,
|
||||||
|
which spawns UNIX domain sockets in the current working directory by using the
|
||||||
|
<command>socat</command> command. This allows
|
||||||
|
users to remotely script a generated virtual machine.</para>
|
||||||
|
|
||||||
|
<para>A network Nix expression has the following structure:
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
{
|
||||||
|
test1 = {pkgs, config, ...}:
|
||||||
|
{
|
||||||
|
services.openssh.enable = true;
|
||||||
|
nixpkgs.system = "i686-linux";
|
||||||
|
deployment.targetHost = "test1.example.net";
|
||||||
|
|
||||||
|
# Other NixOS options
|
||||||
|
};
|
||||||
|
|
||||||
|
test2 = {pkgs, config, ...}:
|
||||||
|
{
|
||||||
|
services.openssh.enable = true;
|
||||||
|
services.httpd.enable = true;
|
||||||
|
environment.systemPackages = [ pkgs.lynx ];
|
||||||
|
nixpkgs.system = "x86_64-linux";
|
||||||
|
deployment.targetHost = "test2.example.net";
|
||||||
|
|
||||||
|
# Other NixOS options
|
||||||
|
};
|
||||||
|
}
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
Each attribute in the expression represents a machine in the network
|
||||||
|
(e.g. <varname>test1</varname> and <varname>test2</varname>)
|
||||||
|
referring to a function defining a NixOS configuration.
|
||||||
|
In each NixOS configuration, two attributes have a special meaning.
|
||||||
|
The <varname>deployment.targetHost</varname> specifies the address
|
||||||
|
(domain name or IP address)
|
||||||
|
of the system which is used by <command>ssh</command> to perform
|
||||||
|
remote deployment operations. The <varname>nixpkgs.system</varname>
|
||||||
|
attribute can be used to specify an architecture for the target machine,
|
||||||
|
such as <varname>i686-linux</varname> which builds a 32-bit NixOS
|
||||||
|
configuration. Omitting this property will build the configuration
|
||||||
|
for the same architecture as the host system.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
</refsection>
|
||||||
|
|
||||||
|
<refsection><title>Options</title>
|
||||||
|
|
||||||
|
<para>This command accepts the following options:</para>
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--use-backdoor</option></term>
|
||||||
|
<listitem>
|
||||||
|
<para>Indicates that the backdoor must be enabled so that the VMs can be
|
||||||
|
accessed through a UNIX domain socket. The UNIX domain sockets are
|
||||||
|
created in the current working directory.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--show-trace</option></term>
|
||||||
|
<listitem>
|
||||||
|
<para>Shows a trace of the output.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--no-out-link</option></term>
|
||||||
|
<listitem>
|
||||||
|
<para>Do not create a 'result' symlink.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>-h</option>, <option>--help</option></term>
|
||||||
|
<listitem>
|
||||||
|
<para>Shows the usage of this command to the user.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
</variablelist>
|
||||||
|
|
||||||
|
</refsection>
|
||||||
|
|
||||||
|
|
||||||
|
<refsection><title>Environment variables</title>
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><envar>NIXOS</envar></term>
|
||||||
|
<listitem>
|
||||||
|
<para>Path to the NixOS source tree. Defaults to
|
||||||
|
<filename>/etc/nixos/nixos</filename>.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><envar>NIXPKGS_ALL</envar></term>
|
||||||
|
<listitem>
|
||||||
|
<para>Path to the Nixpkgs source tree. Defaults to
|
||||||
|
<filename>/etc/nixos/nixpkgs</filename>.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
|
||||||
|
</refsection>
|
||||||
|
|
||||||
|
</refentry>
|
|
@ -0,0 +1,135 @@
|
||||||
|
<refentry xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||||
|
|
||||||
|
<refmeta>
|
||||||
|
<refentrytitle><command>nixos-deploy-network</command></refentrytitle>
|
||||||
|
<manvolnum>8</manvolnum>
|
||||||
|
<refmiscinfo class="source">NixOS</refmiscinfo>
|
||||||
|
<!-- <refmiscinfo class="version"><xi:include href="version.txt" parse="text"/></refmiscinfo> -->
|
||||||
|
</refmeta>
|
||||||
|
|
||||||
|
<refnamediv>
|
||||||
|
<refname><command>nixos-deploy-network</command></refname>
|
||||||
|
<refpurpose>deploy a network of NixOS configurations into a network of machines</refpurpose>
|
||||||
|
</refnamediv>
|
||||||
|
|
||||||
|
<refsynopsisdiv>
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>nixos-deploy-network</command>
|
||||||
|
<arg><option>--show-trace</option></arg>
|
||||||
|
<arg><option>--no-out-link</option></arg>
|
||||||
|
<arg><option>--help</option></arg>
|
||||||
|
<arg choice="plain"><replaceable>network.nix</replaceable></arg>
|
||||||
|
</cmdsynopsis>
|
||||||
|
</refsynopsisdiv>
|
||||||
|
|
||||||
|
<refsection><title>Description</title>
|
||||||
|
|
||||||
|
<para>This command automatically deploys a network of NixOS
|
||||||
|
configurations into a network of machines.
|
||||||
|
First, it tries to build all the system derivations defined
|
||||||
|
in the network expression. Then it efficiently transfers
|
||||||
|
the closures to the machines in the network. Finally, the configurations
|
||||||
|
are activated. In case of a failure, a rollback is performed,
|
||||||
|
which brings all the updated configurations back into the previous
|
||||||
|
state.</para>
|
||||||
|
|
||||||
|
<para>A network Nix expression has the following structure:
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
{
|
||||||
|
test1 = {pkgs, config, ...}:
|
||||||
|
{
|
||||||
|
services.openssh.enable = true;
|
||||||
|
nixpkgs.system = "i686-linux";
|
||||||
|
deployment.targetHost = "test1.example.net";
|
||||||
|
|
||||||
|
# Other NixOS options
|
||||||
|
};
|
||||||
|
|
||||||
|
test2 = {pkgs, config, ...}:
|
||||||
|
{
|
||||||
|
services.openssh.enable = true;
|
||||||
|
services.httpd.enable = true;
|
||||||
|
environment.systemPackages = [ pkgs.lynx ];
|
||||||
|
nixpkgs.system = "x86_64-linux";
|
||||||
|
deployment.targetHost = "test2.example.net";
|
||||||
|
|
||||||
|
# Other NixOS options
|
||||||
|
};
|
||||||
|
}
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
Each attribute in the expression represents a machine in the network
|
||||||
|
(e.g. <varname>test1</varname> and <varname>test2</varname>)
|
||||||
|
referring to a function defining a NixOS configuration.
|
||||||
|
In each NixOS configuration, two attributes have a special meaning.
|
||||||
|
The <varname>deployment.targetHost</varname> specifies the address
|
||||||
|
(domain name or IP address)
|
||||||
|
of the system which is used by <command>ssh</command> to perform
|
||||||
|
remote deployment operations. The <varname>nixpkgs.system</varname>
|
||||||
|
attribute can be used to specify an architecture for the target machine,
|
||||||
|
such as <varname>i686-linux</varname> which builds a 32-bit NixOS
|
||||||
|
configuration. Omitting this property will build the configuration
|
||||||
|
for the same architecture as the host system.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
</refsection>
|
||||||
|
|
||||||
|
<refsection><title>Options</title>
|
||||||
|
|
||||||
|
<para>This command accepts the following options:</para>
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--show-trace</option></term>
|
||||||
|
<listitem>
|
||||||
|
<para>Shows a trace of the output.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--no-out-link</option></term>
|
||||||
|
<listitem>
|
||||||
|
<para>Do not create a 'result' symlink.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>-h</option>, <option>--help</option></term>
|
||||||
|
<listitem>
|
||||||
|
<para>Shows the usage of this command to the user.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
</variablelist>
|
||||||
|
|
||||||
|
</refsection>
|
||||||
|
|
||||||
|
|
||||||
|
<refsection><title>Environment variables</title>
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><envar>NIXOS</envar></term>
|
||||||
|
<listitem>
|
||||||
|
<para>Path to the NixOS source tree. Defaults to
|
||||||
|
<filename>/etc/nixos/nixos</filename>.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><envar>NIXPKGS_ALL</envar></term>
|
||||||
|
<listitem>
|
||||||
|
<para>Path to the Nixpkgs source tree. Defaults to
|
||||||
|
<filename>/etc/nixos/nixpkgs</filename>.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
|
||||||
|
</refsection>
|
||||||
|
|
||||||
|
</refentry>
|
|
@ -26,5 +26,6 @@
|
||||||
<xi:include href="man-configuration.xml" />
|
<xi:include href="man-configuration.xml" />
|
||||||
<xi:include href="man-nixos-rebuild.xml" />
|
<xi:include href="man-nixos-rebuild.xml" />
|
||||||
<xi:include href="man-nixos-option.xml" />
|
<xi:include href="man-nixos-option.xml" />
|
||||||
|
<xi:include href="man-nixos-deploy-network.xml" />
|
||||||
|
<xi:include href="man-nixos-build-vms.xml" />
|
||||||
</reference>
|
</reference>
|
||||||
|
|
|
@ -108,7 +108,7 @@ rec {
|
||||||
|
|
||||||
virtualisation.qemu.options =
|
virtualisation.qemu.options =
|
||||||
lib.flip lib.concatMapStrings interfacesNumbered
|
lib.flip lib.concatMapStrings interfacesNumbered
|
||||||
({ first, second }: qemuNICFlags second first );
|
({ first, second }: qemuNICFlags second first m.second);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
qemuNICFlags = nic: net:
|
qemuNICFlags = nic: net: machine:
|
||||||
"-net nic,vlan=${toString nic},model=virtio " +
|
"-net nic,vlan=${toString nic},macaddr=52:54:00:12:${toString net}:${toString machine},model=virtio " +
|
||||||
# Use 232.0.1.<vlan> as the multicast address to connect VMs on
|
# Use 232.0.1.<vlan> as the multicast address to connect VMs on
|
||||||
# the same vlan, but allow it to be overriden using the
|
# the same vlan, but allow it to be overriden using the
|
||||||
# $QEMU_MCAST_ADDR_<vlan> environment variable. The test driver
|
# $QEMU_MCAST_ADDR_<vlan> environment variable. The test driver
|
||||||
|
|
|
@ -19,11 +19,20 @@ for (my $n = 0; $n < 256; $n++) {
|
||||||
$ENV{"QEMU_MCAST_ADDR_$n"} = "$mcastPrefix.$n.$mcastSuffix";
|
$ENV{"QEMU_MCAST_ADDR_$n"} = "$mcastPrefix.$n.$mcastSuffix";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
my $showGraphics = defined $ENV{'DISPLAY'};
|
||||||
|
|
||||||
|
|
||||||
sub new {
|
sub new {
|
||||||
my ($class, $args) = @_;
|
my ($class, $args) = @_;
|
||||||
|
|
||||||
my $startCommand = $args->{startCommand};
|
my $startCommand = $args->{startCommand};
|
||||||
|
|
||||||
|
my $name = $args->{name};
|
||||||
|
if (!$name) {
|
||||||
|
$startCommand =~ /run-(.*)-vm$/;
|
||||||
|
$name = $1 || "machine";
|
||||||
|
}
|
||||||
|
|
||||||
if (!$startCommand) {
|
if (!$startCommand) {
|
||||||
# !!! merge with qemu-vm.nix.
|
# !!! merge with qemu-vm.nix.
|
||||||
$startCommand =
|
$startCommand =
|
||||||
|
@ -34,12 +43,8 @@ sub new {
|
||||||
$startCommand .= "-cdrom $args->{cdrom} "
|
$startCommand .= "-cdrom $args->{cdrom} "
|
||||||
if defined $args->{cdrom};
|
if defined $args->{cdrom};
|
||||||
$startCommand .= $args->{qemuFlags} || "";
|
$startCommand .= $args->{qemuFlags} || "";
|
||||||
}
|
} else {
|
||||||
|
$startCommand = Cwd::abs_path $startCommand;
|
||||||
my $name = $args->{name};
|
|
||||||
if (!$name) {
|
|
||||||
$startCommand =~ /run-(.*)-vm$/;
|
|
||||||
$name = $1 || "machine";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
my $tmpDir = $ENV{'TMPDIR'} || "/tmp";
|
my $tmpDir = $ENV{'TMPDIR'} || "/tmp";
|
||||||
|
@ -51,7 +56,7 @@ sub new {
|
||||||
pid => 0,
|
pid => 0,
|
||||||
connected => 0,
|
connected => 0,
|
||||||
socket => undef,
|
socket => undef,
|
||||||
stateDir => "$tmpDir/$name",
|
stateDir => "$tmpDir/vm-state-$name",
|
||||||
monitor => undef,
|
monitor => undef,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -121,12 +126,14 @@ sub start {
|
||||||
dup2(fileno($serialC), fileno(STDERR));
|
dup2(fileno($serialC), fileno(STDERR));
|
||||||
$ENV{TMPDIR} = $self->{stateDir};
|
$ENV{TMPDIR} = $self->{stateDir};
|
||||||
$ENV{USE_TMPDIR} = 1;
|
$ENV{USE_TMPDIR} = 1;
|
||||||
$ENV{QEMU_OPTS} = "-nographic -no-reboot -monitor unix:./monitor -chardev socket,id=shell,path=./shell";
|
$ENV{QEMU_OPTS} =
|
||||||
|
"-no-reboot -monitor unix:./monitor -chardev socket,id=shell,path=./shell " .
|
||||||
|
($showGraphics ? "-serial stdio" : "-nographic");
|
||||||
$ENV{QEMU_NET_OPTS} = "guestfwd=tcp:10.0.2.6:23-chardev:shell";
|
$ENV{QEMU_NET_OPTS} = "guestfwd=tcp:10.0.2.6:23-chardev:shell";
|
||||||
$ENV{QEMU_KERNEL_PARAMS} = "hostTmpDir=$ENV{TMPDIR}";
|
$ENV{QEMU_KERNEL_PARAMS} = "hostTmpDir=$ENV{TMPDIR}";
|
||||||
chdir $self->{stateDir} or die;
|
chdir $self->{stateDir} or die;
|
||||||
exec $self->{startCommand};
|
exec $self->{startCommand};
|
||||||
die;
|
die "running VM script: $!";
|
||||||
}
|
}
|
||||||
|
|
||||||
# Process serial line output.
|
# Process serial line output.
|
||||||
|
@ -248,7 +255,8 @@ sub execute {
|
||||||
my $out = "";
|
my $out = "";
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
my $line = readline($self->{socket}) or die "connection to VM lost unexpectedly";
|
my $line = readline($self->{socket});
|
||||||
|
die "connection to VM lost unexpectedly" unless defined $line;
|
||||||
#$self->log("got line: $line");
|
#$self->log("got line: $line");
|
||||||
if ($line =~ /^(.*)\|\!\=EOF\s+(\d+)$/) {
|
if ($line =~ /^(.*)\|\!\=EOF\s+(\d+)$/) {
|
||||||
$out .= $1;
|
$out .= $1;
|
||||||
|
@ -267,7 +275,7 @@ sub succeed {
|
||||||
my ($status, $out) = $self->execute($command);
|
my ($status, $out) = $self->execute($command);
|
||||||
if ($status != 0) {
|
if ($status != 0) {
|
||||||
$self->log("output: $out");
|
$self->log("output: $out");
|
||||||
die "command `$command' did not succeed (exit code $status)";
|
die "command `$command' did not succeed (exit code $status)\n";
|
||||||
}
|
}
|
||||||
$res .= $out;
|
$res .= $out;
|
||||||
}
|
}
|
||||||
|
@ -404,7 +412,8 @@ sub unblock {
|
||||||
# Take a screenshot of the X server on :0.0.
|
# Take a screenshot of the X server on :0.0.
|
||||||
sub screenshot {
|
sub screenshot {
|
||||||
my ($self, $filename) = @_;
|
my ($self, $filename) = @_;
|
||||||
$filename = "$ENV{'out'}/${filename}.png" if $filename =~ /^\w+$/;
|
my $dir = $ENV{'out'} || Cwd::abs_path(".");
|
||||||
|
$filename = "$dir/${filename}.png" if $filename =~ /^\w+$/;
|
||||||
my $tmp = "${filename}.ppm";
|
my $tmp = "${filename}.ppm";
|
||||||
$self->sendMonitorCommand("screendump $tmp");
|
$self->sendMonitorCommand("screendump $tmp");
|
||||||
system("convert $tmp ${filename}") == 0
|
system("convert $tmp ${filename}") == 0
|
||||||
|
|
|
@ -1,8 +1,13 @@
|
||||||
|
#! @perl@ -w -I@libDir@ -I@readline@
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use Machine;
|
use Machine;
|
||||||
|
use Term::ReadLine;
|
||||||
|
|
||||||
$SIG{PIPE} = 'IGNORE'; # because Unix domain sockets may die unexpectedly
|
$SIG{PIPE} = 'IGNORE'; # because Unix domain sockets may die unexpectedly
|
||||||
|
|
||||||
|
$ENV{PATH} = "@extraPath@:$ENV{PATH}";
|
||||||
|
|
||||||
STDERR->autoflush(1);
|
STDERR->autoflush(1);
|
||||||
|
|
||||||
my %vms;
|
my %vms;
|
||||||
|
@ -26,10 +31,13 @@ sub runTests {
|
||||||
eval "$context $ENV{tests}";
|
eval "$context $ENV{tests}";
|
||||||
die $@ if $@;
|
die $@ if $@;
|
||||||
} else {
|
} else {
|
||||||
while (<STDIN>) {
|
my $term = Term::ReadLine->new('nixos-vm-test');
|
||||||
|
$term->ReadHistory;
|
||||||
|
while (defined ($_ = $term->readline("> "))) {
|
||||||
eval "$context $_\n";
|
eval "$context $_\n";
|
||||||
warn $@ if $@;
|
warn $@ if $@;
|
||||||
}
|
}
|
||||||
|
$term->WriteHistory;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Copy the kernel coverage data for each machine, if the kernel
|
# Copy the kernel coverage data for each machine, if the kernel
|
||||||
|
|
|
@ -8,6 +8,27 @@ rec {
|
||||||
inherit pkgs;
|
inherit pkgs;
|
||||||
|
|
||||||
|
|
||||||
|
testDriver = stdenv.mkDerivation {
|
||||||
|
name = "nixos-test-driver";
|
||||||
|
buildCommand =
|
||||||
|
''
|
||||||
|
mkdir -p $out/bin
|
||||||
|
cp ${./test-driver/test-driver.pl} $out/bin/nixos-test-driver
|
||||||
|
chmod u+x $out/bin/nixos-test-driver
|
||||||
|
|
||||||
|
libDir=$out/lib/perl5/site_perl
|
||||||
|
mkdir -p $libDir
|
||||||
|
cp ${./test-driver/Machine.pm} $libDir/Machine.pm
|
||||||
|
|
||||||
|
substituteInPlace $out/bin/nixos-test-driver \
|
||||||
|
--subst-var-by perl "${perl}/bin/perl" \
|
||||||
|
--subst-var-by readline "${perlPackages.TermReadLineGnu}/lib/perl5/site_perl" \
|
||||||
|
--subst-var-by extraPath "${imagemagick}/bin" \
|
||||||
|
--subst-var libDir
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
# Run an automated test suite in the given virtual network.
|
# Run an automated test suite in the given virtual network.
|
||||||
# `network' must be the result of a call to the
|
# `network' must be the result of a call to the
|
||||||
# `buildVirtualNetwork' function. `tests' is a Perl fragment
|
# `buildVirtualNetwork' function. `tests' is a Perl fragment
|
||||||
|
@ -20,15 +41,13 @@ rec {
|
||||||
|
|
||||||
inherit tests;
|
inherit tests;
|
||||||
|
|
||||||
buildInputs = [ pkgs.qemu_kvm pkgs.imagemagick ];
|
buildInputs = [ pkgs.qemu_kvm ];
|
||||||
|
|
||||||
buildCommand =
|
buildCommand =
|
||||||
''
|
''
|
||||||
mkdir $out
|
|
||||||
cp ${./test-driver/Machine.pm} Machine.pm
|
|
||||||
ensureDir $out/nix-support
|
ensureDir $out/nix-support
|
||||||
|
|
||||||
${perl}/bin/perl ${./test-driver/test-driver.pl} ${network}/vms/*/bin/run-*-vm
|
${testDriver}/bin/nixos-test-driver ${network}/vms/*/bin/run-*-vm
|
||||||
|
|
||||||
for i in */coverage-data; do
|
for i in */coverage-data; do
|
||||||
ensureDir $out/coverage-data
|
ensureDir $out/coverage-data
|
||||||
|
@ -98,13 +117,38 @@ rec {
|
||||||
if t ? nodes then t.nodes else
|
if t ? nodes then t.nodes else
|
||||||
if t ? machine then { machine = t.machine; }
|
if t ? machine then { machine = t.machine; }
|
||||||
else { };
|
else { };
|
||||||
|
|
||||||
vms = buildVirtualNetwork { inherit nodes; };
|
vms = buildVirtualNetwork { inherit nodes; };
|
||||||
test = runTests vms
|
|
||||||
|
testScript =
|
||||||
# Call the test script with the computed nodes.
|
# Call the test script with the computed nodes.
|
||||||
(if builtins.isFunction t.testScript then t.testScript { inherit (vms) nodes; } else t.testScript);
|
if builtins.isFunction t.testScript
|
||||||
|
then t.testScript { inherit (vms) nodes; }
|
||||||
|
else t.testScript;
|
||||||
|
|
||||||
|
test = runTests vms testScript;
|
||||||
|
|
||||||
report = makeReport test;
|
report = makeReport test;
|
||||||
|
|
||||||
|
# Generate a convenience wrapper for running the test driver
|
||||||
|
# interactively with the specified network.
|
||||||
|
driver = runCommand "nixos-test-driver"
|
||||||
|
{ buildInputs = [ makeWrapper];
|
||||||
|
inherit testScript;
|
||||||
|
}
|
||||||
|
''
|
||||||
|
mkdir -p $out/bin
|
||||||
|
ln -s ${vms}/bin/* $out/bin/
|
||||||
|
ln -s ${testDriver}/bin/* $out/bin/
|
||||||
|
wrapProgram $out/bin/nixos-test-driver \
|
||||||
|
--add-flags "${vms}/vms/*/bin/run-*-vm" \
|
||||||
|
--run "testScript=\"\$(cat $out/test-script)\"" \
|
||||||
|
--set testScript '"$testScript"'
|
||||||
|
echo "$testScript" > $out/test-script
|
||||||
|
''; # "
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
runInMachine =
|
runInMachine =
|
||||||
{ drv
|
{ drv
|
||||||
, machine
|
, machine
|
||||||
|
@ -140,7 +184,7 @@ rec {
|
||||||
export PATH=${qemu_kvm}/bin:${coreutils}/bin
|
export PATH=${qemu_kvm}/bin:${coreutils}/bin
|
||||||
cp ${./test-driver/Machine.pm} Machine.pm
|
cp ${./test-driver/Machine.pm} Machine.pm
|
||||||
export tests='${testscript}'
|
export tests='${testscript}'
|
||||||
${perl}/bin/perl ${./test-driver/test-driver.pl} ${vms}/vms/*/bin/run-*-vm
|
${testDriver}/bin/nixos-test-driver ${vms}/vms/*/bin/run-*-vm
|
||||||
''; # */
|
''; # */
|
||||||
|
|
||||||
in
|
in
|
||||||
|
@ -152,6 +196,7 @@ rec {
|
||||||
origBuilder = attrs.builder;
|
origBuilder = attrs.builder;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
runInMachineWithX = { require ? [], ...}@args :
|
runInMachineWithX = { require ? [], ...}@args :
|
||||||
let
|
let
|
||||||
client =
|
client =
|
||||||
|
@ -174,6 +219,7 @@ rec {
|
||||||
'' ;
|
'' ;
|
||||||
} // args );
|
} // args );
|
||||||
|
|
||||||
|
|
||||||
simpleTest = as: (makeTest ({ ... }: as)).test;
|
simpleTest = as: (makeTest ({ ... }: as)).test;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,10 +10,15 @@ let
|
||||||
''
|
''
|
||||||
#! ${pkgs.stdenv.shell}
|
#! ${pkgs.stdenv.shell}
|
||||||
action="$1"
|
action="$1"
|
||||||
if [ "$action" = "resume" ]; then
|
case "$action" in
|
||||||
${cfg.resumeCommands}
|
hibernate|suspend)
|
||||||
${cfg.powerUpCommands}
|
${cfg.powerDownCommands}
|
||||||
fi
|
;;
|
||||||
|
thaw|resume)
|
||||||
|
${cfg.resumeCommands}
|
||||||
|
${cfg.powerUpCommands}
|
||||||
|
;;
|
||||||
|
esac
|
||||||
'';
|
'';
|
||||||
|
|
||||||
in
|
in
|
||||||
|
@ -50,6 +55,17 @@ in
|
||||||
it resumes from suspend or hibernation.
|
it resumes from suspend or hibernation.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
powerDownCommands = mkOption {
|
||||||
|
default = "";
|
||||||
|
example = "${pkgs.hdparm}/sbin/hdparm -B 255 /dev/sda";
|
||||||
|
description =
|
||||||
|
''
|
||||||
|
Commands executed when the machine powers down. That is,
|
||||||
|
they're executed both when the system shuts down and when
|
||||||
|
it goes to suspend or hibernation.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -4,18 +4,18 @@
|
||||||
|
|
||||||
showUsage()
|
showUsage()
|
||||||
{
|
{
|
||||||
echo "Usage: $0 -n network_expr -i infrastructure_expr"
|
echo "Usage: $0 network_expr"
|
||||||
echo "Options:"
|
echo "Options:"
|
||||||
echo
|
echo
|
||||||
echo "-n,--network Network Nix expression which captures properties of machines in the network"
|
echo "--use-backdoor Indicates that the backdoor must be enabled so that the VMs can be accessed through a UNIX domain socket"
|
||||||
echo "--use-backdoor Indicates that the backdoor must be enabled so that the VMs can be accessed through a UNIX domain socket"
|
echo "--no-out-link Do not create a 'result' symlink"
|
||||||
echo "--show-trace Shows the output trace"
|
echo "--show-trace Shows the output trace"
|
||||||
echo "-h,--help Shows the usage of this command"
|
echo "-h,--help Shows the usage of this command"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Parse valid argument options
|
# Parse valid argument options
|
||||||
|
|
||||||
PARAMS=`getopt -n $0 -o n:h -l network:,use-backdoor,show-trace,help -- "$@"`
|
PARAMS=`getopt -n $0 -o h -l use-backdoor,no-out-link,show-trace,help -- "$@"`
|
||||||
|
|
||||||
if [ $? != 0 ]
|
if [ $? != 0 ]
|
||||||
then
|
then
|
||||||
|
@ -30,12 +30,12 @@ eval set -- "$PARAMS"
|
||||||
while [ "$1" != "--" ]
|
while [ "$1" != "--" ]
|
||||||
do
|
do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
-n|--network)
|
|
||||||
networkExpr=`readlink -f $2`
|
|
||||||
;;
|
|
||||||
--use-backdoor)
|
--use-backdoor)
|
||||||
useBackdoorArg="--arg useBackdoor true"
|
useBackdoorArg="--arg useBackdoor true"
|
||||||
;;
|
;;
|
||||||
|
--no-out-link)
|
||||||
|
noOutLinkArg="--no-out-link"
|
||||||
|
;;
|
||||||
--show-trace)
|
--show-trace)
|
||||||
showTraceArg="--show-trace"
|
showTraceArg="--show-trace"
|
||||||
;;
|
;;
|
||||||
|
@ -48,19 +48,23 @@ do
|
||||||
shift
|
shift
|
||||||
done
|
done
|
||||||
|
|
||||||
# Validate the given options
|
shift
|
||||||
|
|
||||||
if [ "$networkExpr" = "" ]
|
# Validate the given options
|
||||||
then
|
|
||||||
echo "ERROR: A network expression must be specified!" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$NIXOS" ]
|
if [ -z "$NIXOS" ]
|
||||||
then
|
then
|
||||||
NIXOS=/etc/nixos/nixos
|
NIXOS=/etc/nixos/nixos
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "$@" = "" ]
|
||||||
|
then
|
||||||
|
echo "ERROR: A network expression must be specified!" >&2
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
networkExpr=$(readlink -f $@)
|
||||||
|
fi
|
||||||
|
|
||||||
# Build a network of VMs
|
# Build a network of VMs
|
||||||
|
|
||||||
nix-build $NIXOS/modules/installer/tools/nixos-build-vms/build-vms.nix --argstr networkExpr $networkExpr --argstr nixos $NIXOS --argstr nixpkgs $NIXPKGS_ALL $useBackdoorArg $showTraceArg
|
nix-build $NIXOS/modules/installer/tools/nixos-build-vms/build-vms.nix --argstr networkExpr $networkExpr --argstr nixos $NIXOS --argstr nixpkgs $NIXPKGS_ALL $useBackdoorArg $noOutLinkArg $showTraceArg
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
{ nixos ? /etc/nixos/nixos
|
{ nixos ? /etc/nixos/nixos
|
||||||
, nixpkgs ? /etc/nixos/nixpkgs
|
, nixpkgs ? /etc/nixos/nixpkgs
|
||||||
, networkExpr
|
, networkExpr
|
||||||
, infrastructureExpr
|
, targetProperty ? "targetHost"
|
||||||
, targetProperty ? "hostname"
|
|
||||||
}:
|
}:
|
||||||
|
|
||||||
let
|
let
|
||||||
|
@ -12,19 +11,17 @@ let
|
||||||
inherit (pkgs.lib) concatMapStrings;
|
inherit (pkgs.lib) concatMapStrings;
|
||||||
|
|
||||||
network = import networkExpr;
|
network = import networkExpr;
|
||||||
infrastructure = import infrastructureExpr;
|
|
||||||
|
|
||||||
generateRollbackSucceededPhase = network: infrastructure: configs:
|
generateRollbackSucceededPhase = network: configs:
|
||||||
concatMapStrings (configurationName:
|
concatMapStrings (configurationName:
|
||||||
let
|
let
|
||||||
infrastructureElement = getAttr configurationName infrastructure;
|
|
||||||
config = getAttr configurationName configs;
|
config = getAttr configurationName configs;
|
||||||
in
|
in
|
||||||
''
|
''
|
||||||
if [ "$rollback" != "$succeeded" ]
|
if [ "$rollback" != "$succeeded" ]
|
||||||
then
|
then
|
||||||
ssh $NIX_SSHOPTS ${getAttr targetProperty infrastructureElement} nix-env -p /nix/var/nix/profiles/system --rollback
|
ssh $NIX_SSHOPTS ${getAttr targetProperty (config.deployment)} nix-env -p /nix/var/nix/profiles/system --rollback
|
||||||
ssh $NIX_SSHOPTS ${getAttr targetProperty infrastructureElement} /nix/var/nix/profiles/bin/switch-to-configuration switch
|
ssh $NIX_SSHOPTS ${getAttr targetProperty (config.deployment)} /nix/var/nix/profiles/system/bin/switch-to-configuration switch
|
||||||
|
|
||||||
rollback=$((rollback + 1))
|
rollback=$((rollback + 1))
|
||||||
fi
|
fi
|
||||||
|
@ -32,33 +29,31 @@ let
|
||||||
) (attrNames network)
|
) (attrNames network)
|
||||||
;
|
;
|
||||||
|
|
||||||
generateDistributionPhase = network: infrastructure: configs:
|
generateDistributionPhase = network: configs:
|
||||||
concatMapStrings (configurationName:
|
concatMapStrings (configurationName:
|
||||||
let
|
let
|
||||||
infrastructureElement = getAttr configurationName infrastructure;
|
|
||||||
config = getAttr configurationName configs;
|
config = getAttr configurationName configs;
|
||||||
in
|
in
|
||||||
''
|
''
|
||||||
echo "=== copy system closure to ${getAttr targetProperty infrastructureElement} ==="
|
echo "=== copy system closure to ${getAttr targetProperty (config.deployment)} ==="
|
||||||
nix-copy-closure --to ${getAttr targetProperty infrastructureElement} ${config.system.build.toplevel}
|
nix-copy-closure --to ${getAttr targetProperty (config.deployment)} ${config.system.build.toplevel}
|
||||||
''
|
''
|
||||||
) (attrNames network)
|
) (attrNames network)
|
||||||
;
|
;
|
||||||
|
|
||||||
generateActivationPhase = network: infrastructure: configs:
|
generateActivationPhase = network: configs:
|
||||||
concatMapStrings (configurationName:
|
concatMapStrings (configurationName:
|
||||||
let
|
let
|
||||||
infrastructureElement = getAttr configurationName infrastructure;
|
|
||||||
config = getAttr configurationName configs;
|
config = getAttr configurationName configs;
|
||||||
in
|
in
|
||||||
''
|
''
|
||||||
echo "=== activating system configuration on ${getAttr targetProperty infrastructureElement} ==="
|
echo "=== activating system configuration on ${getAttr targetProperty (config.deployment)} ==="
|
||||||
ssh $NIX_SSHOPTS ${getAttr targetProperty infrastructureElement} nix-env -p /nix/var/nix/profiles/system --set ${config.system.build.toplevel} ||
|
ssh $NIX_SSHOPTS ${getAttr targetProperty (config.deployment)} nix-env -p /nix/var/nix/profiles/system --set ${config.system.build.toplevel} ||
|
||||||
(ssh $NIX_SSHOPTS ${getAttr targetProperty infrastructureElement} nix-env -p /nix/var/nix/profiles/system --rollback; rollbackSucceeded)
|
(ssh $NIX_SSHOPTS ${getAttr targetProperty (config.deployment)} nix-env -p /nix/var/nix/profiles/system --rollback; rollbackSucceeded)
|
||||||
|
|
||||||
ssh $NIX_SSHOPTS ${getAttr targetProperty infrastructureElement} /nix/var/nix/profiles/bin/switch-to-configuration switch ||
|
ssh $NIX_SSHOPTS ${getAttr targetProperty (config.deployment)} /nix/var/nix/profiles/system/bin/switch-to-configuration switch ||
|
||||||
( ssh $NIX_SSHOPTS ${getAttr targetProperty infrastructureElement} nix-env -p /nix/var/nix/profiles/system --rollback
|
( ssh $NIX_SSHOPTS ${getAttr targetProperty (config.deployment)} nix-env -p /nix/var/nix/profiles/system --rollback
|
||||||
ssh $NIX_SSHOPTS ${getAttr targetProperty infrastructureElement} /nix/var/nix/profiles/bin/switch-to-configuration switch
|
ssh $NIX_SSHOPTS ${getAttr targetProperty (config.deployment)} /nix/var/nix/profiles/system/bin/switch-to-configuration switch
|
||||||
rollbackSucceeded
|
rollbackSucceeded
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -67,25 +62,36 @@ let
|
||||||
) (attrNames network)
|
) (attrNames network)
|
||||||
;
|
;
|
||||||
|
|
||||||
evaluateMachines = network: infrastructure:
|
evaluateMachines = network:
|
||||||
listToAttrs (map (configurationName:
|
listToAttrs (map (configurationName:
|
||||||
let
|
let
|
||||||
configuration = getAttr configurationName network;
|
configuration = getAttr configurationName network;
|
||||||
system = (getAttr configurationName infrastructure).system;
|
|
||||||
in
|
in
|
||||||
{ name = configurationName;
|
{ name = configurationName;
|
||||||
value = (import "${nixos}/lib/eval-config.nix" {
|
value = (import "${nixos}/lib/eval-config.nix" {
|
||||||
inherit nixpkgs system;
|
inherit nixpkgs;
|
||||||
modules = [ configuration ];
|
modules =
|
||||||
extraArgs = evaluateMachines network infrastructure;
|
[ configuration
|
||||||
|
# Provide a default hostname and deployment target equal
|
||||||
|
# to the attribute name of the machine in the model.
|
||||||
|
{ key = "set-default-hostname";
|
||||||
|
networking.hostName = pkgs.lib.mkOverride 900 configurationName;
|
||||||
|
deployment.targetHost = pkgs.lib.mkOverride 900 configurationName;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
extraArgs = evaluateMachines network;
|
||||||
}).config; }
|
}).config; }
|
||||||
) (attrNames (network)))
|
) (attrNames (network)));
|
||||||
;
|
|
||||||
|
|
||||||
configs = evaluateMachines network infrastructure;
|
configs = evaluateMachines network;
|
||||||
in
|
in
|
||||||
pkgs.stdenv.mkDerivation {
|
pkgs.stdenv.mkDerivation {
|
||||||
name = "deploy-script";
|
name = "deploy-script";
|
||||||
|
|
||||||
|
# This script has a zillion dependencies and is trivial to build, so
|
||||||
|
# we don't want to build it remotely.
|
||||||
|
preferLocalBuild = true;
|
||||||
|
|
||||||
buildCommand =
|
buildCommand =
|
||||||
''
|
''
|
||||||
ensureDir $out/bin
|
ensureDir $out/bin
|
||||||
|
@ -95,18 +101,18 @@ pkgs.stdenv.mkDerivation {
|
||||||
rollbackSucceeded()
|
rollbackSucceeded()
|
||||||
{
|
{
|
||||||
rollback=0
|
rollback=0
|
||||||
${generateRollbackSucceededPhase network infrastructure configs}
|
${generateRollbackSucceededPhase network configs}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Distribution phase
|
# Distribution phase
|
||||||
|
|
||||||
${generateDistributionPhase network infrastructure configs}
|
${generateDistributionPhase network configs}
|
||||||
|
|
||||||
# Activation phase
|
# Activation phase
|
||||||
|
|
||||||
succeeded=0
|
succeeded=0
|
||||||
|
|
||||||
${generateActivationPhase network infrastructure configs}
|
${generateActivationPhase network configs}
|
||||||
EOF
|
EOF
|
||||||
chmod +x $out/bin/deploy-systems
|
chmod +x $out/bin/deploy-systems
|
||||||
'';
|
'';
|
||||||
|
|
|
@ -4,18 +4,17 @@
|
||||||
|
|
||||||
showUsage()
|
showUsage()
|
||||||
{
|
{
|
||||||
echo "Usage: $0 -n network_expr -i infrastructure_expr"
|
echo "Usage: $0 network_expr"
|
||||||
echo "Options:"
|
echo "Options:"
|
||||||
echo
|
echo
|
||||||
echo "-n,--network Network Nix expression which captures properties of machines in the network"
|
echo "--show-trace Shows an output trace"
|
||||||
echo "-i,--infrastructure Infrastructure Nix expression which captures properties of machines in the network"
|
echo "--no-out-link Do not create a 'result' symlink"
|
||||||
echo "--show-trace Shows an output trace"
|
echo "-h,--help Shows the usage of this command"
|
||||||
echo "-h,--help Shows the usage of this command"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Parse valid argument options
|
# Parse valid argument options
|
||||||
|
|
||||||
PARAMS=`getopt -n $0 -o n:i:h -l network:,infrastructure:,show-trace,help -- "$@"`
|
PARAMS=`getopt -n $0 -o h -l show-trace,no-out-link,help -- "$@"`
|
||||||
|
|
||||||
if [ $? != 0 ]
|
if [ $? != 0 ]
|
||||||
then
|
then
|
||||||
|
@ -30,15 +29,12 @@ eval set -- "$PARAMS"
|
||||||
while [ "$1" != "--" ]
|
while [ "$1" != "--" ]
|
||||||
do
|
do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
-n|--network)
|
|
||||||
networkExpr=`readlink -f $2`
|
|
||||||
;;
|
|
||||||
-i|--infrastructure)
|
|
||||||
infrastructureExpr=`readlink -f $2`
|
|
||||||
;;
|
|
||||||
--show-trace)
|
--show-trace)
|
||||||
showTraceArg="--show-trace"
|
showTraceArg="--show-trace"
|
||||||
;;
|
;;
|
||||||
|
--no-out-link)
|
||||||
|
noOutLinkArg="--no-out-link"
|
||||||
|
;;
|
||||||
-h|--help)
|
-h|--help)
|
||||||
showUsage
|
showUsage
|
||||||
exit 0
|
exit 0
|
||||||
|
@ -48,27 +44,24 @@ do
|
||||||
shift
|
shift
|
||||||
done
|
done
|
||||||
|
|
||||||
|
shift
|
||||||
|
|
||||||
# Validate the given options
|
# Validate the given options
|
||||||
|
|
||||||
if [ "$infrastructureExpr" = "" ]
|
|
||||||
then
|
|
||||||
echo "ERROR: A infrastructure expression must be specified!" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$networkExpr" = "" ]
|
|
||||||
then
|
|
||||||
echo "ERROR: A network expression must be specified!" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$NIXOS" ]
|
if [ -z "$NIXOS" ]
|
||||||
then
|
then
|
||||||
NIXOS=/etc/nixos/nixos
|
NIXOS=/etc/nixos/nixos
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "$@" = "" ]
|
||||||
|
then
|
||||||
|
echo "ERROR: A network Nix expression must be specified!" >&2
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
networkExpr=$(readlink -f $@)
|
||||||
|
fi
|
||||||
|
|
||||||
# Deploy the network
|
# Deploy the network
|
||||||
|
|
||||||
nix-build $NIXOS/modules/installer/tools/nixos-deploy-network/deploy.nix --argstr networkExpr $networkExpr --argstr infrastructureExpr $infrastructureExpr $showTraceArg
|
vms=`nix-build $NIXOS/modules/installer/tools/nixos-deploy-network/deploy.nix --argstr networkExpr $networkExpr $showTraceArg $noOutLinkArg`
|
||||||
./result/bin/deploy-systems
|
$vms/bin/deploy-systems
|
||||||
rm -f result
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ use File::Basename;
|
||||||
my @attrs = ();
|
my @attrs = ();
|
||||||
my @kernelModules = ();
|
my @kernelModules = ();
|
||||||
my @initrdKernelModules = ();
|
my @initrdKernelModules = ();
|
||||||
|
my @modulePackages = ();
|
||||||
|
|
||||||
|
|
||||||
sub debug {
|
sub debug {
|
||||||
|
@ -93,6 +94,19 @@ sub pciCheck {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# broadcom STA driver (wl.ko)
|
||||||
|
# list taken from http://www.broadcom.com/docs/linux_sta/README.txt
|
||||||
|
if ($vendor eq "0x14e4" &&
|
||||||
|
($device eq "0x4311" || $device eq "0x4312" || $device eq "0x4313" ||
|
||||||
|
$device eq "0x4315" || $device eq "0x4327" || $device eq "0x4328" ||
|
||||||
|
$device eq "0x4329" || $device eq "0x432a" || $device eq "0x432b" ||
|
||||||
|
$device eq "0x432c" || $device eq "0x432d" || $device eq "0x4353" ||
|
||||||
|
$device eq "0x4357") )
|
||||||
|
{
|
||||||
|
push @modulePackages, "kernelPackages.broadcom_sta";
|
||||||
|
push @kernelModules, "wl";
|
||||||
|
}
|
||||||
|
|
||||||
# Can't rely on $module here, since the module may not be loaded
|
# Can't rely on $module here, since the module may not be loaded
|
||||||
# due to missing firmware. Ideally we would check modules.pcimap
|
# due to missing firmware. Ideally we would check modules.pcimap
|
||||||
# here.
|
# here.
|
||||||
|
@ -222,6 +236,7 @@ sub multiLineList {
|
||||||
|
|
||||||
my $initrdKernelModules = toNixExpr(removeDups @initrdKernelModules);
|
my $initrdKernelModules = toNixExpr(removeDups @initrdKernelModules);
|
||||||
my $kernelModules = toNixExpr(removeDups @kernelModules);
|
my $kernelModules = toNixExpr(removeDups @kernelModules);
|
||||||
|
my $modulePackages = toNixExpr(removeDups @modulePackages);
|
||||||
my $attrs = multiLineList(" ", removeDups @attrs);
|
my $attrs = multiLineList(" ", removeDups @attrs);
|
||||||
|
|
||||||
print <<EOF ;
|
print <<EOF ;
|
||||||
|
@ -235,8 +250,12 @@ print <<EOF ;
|
||||||
"\${modulesPath}/installer/scan/not-detected.nix"
|
"\${modulesPath}/installer/scan/not-detected.nix"
|
||||||
];
|
];
|
||||||
|
|
||||||
boot.initrd.kernelModules = [ $initrdKernelModules ];
|
boot = rec {
|
||||||
boot.kernelModules = [ $kernelModules ];
|
initrd.kernelModules = [ $initrdKernelModules ];
|
||||||
|
kernelModules = [ $kernelModules ];
|
||||||
|
kernelPackages = pkgs.linuxPackages;
|
||||||
|
extraModulePackages = [ $modulePackages ];
|
||||||
|
};
|
||||||
|
|
||||||
nix.maxJobs = $cpus;
|
nix.maxJobs = $cpus;
|
||||||
|
|
||||||
|
|
|
@ -4,20 +4,12 @@ with pkgs.lib;
|
||||||
|
|
||||||
{
|
{
|
||||||
options = {
|
options = {
|
||||||
|
deployment.targetHost = mkOption {
|
||||||
deployment = mkOption {
|
default = config.networking.hostName;
|
||||||
description = ''
|
description = ''
|
||||||
This option captures various custom attributes related to the configuration of the system, which
|
This option specifies a hostname or IP address which can be used by nixos-deploy-network
|
||||||
are not directly used for building a system configuration. Usually these attributes
|
to execute remote deployment operations.
|
||||||
are used by external tooling, such as the nixos-deploy-network tool or the Disnix Avahi
|
|
||||||
publisher.
|
|
||||||
'';
|
'';
|
||||||
default = {};
|
|
||||||
example = {
|
|
||||||
description = "My production machine";
|
|
||||||
hostname = "my.test.org";
|
|
||||||
country = "NL";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,8 @@ in
|
||||||
foldingAtHome = 37;
|
foldingAtHome = 37;
|
||||||
sabnzbd = 38;
|
sabnzbd = 38;
|
||||||
kdm = 39;
|
kdm = 39;
|
||||||
|
ghostOne = 40;
|
||||||
|
git = 41;
|
||||||
# When adding a uid, make sure it doesn't match an existing gid.
|
# When adding a uid, make sure it doesn't match an existing gid.
|
||||||
|
|
||||||
nixbld = 30000; # start of range of uids
|
nixbld = 30000; # start of range of uids
|
||||||
|
@ -98,6 +100,8 @@ in
|
||||||
privoxy = 32;
|
privoxy = 32;
|
||||||
disnix = 33;
|
disnix = 33;
|
||||||
osgi = 34;
|
osgi = 34;
|
||||||
|
ghostOne = 40;
|
||||||
|
git = 41;
|
||||||
# When adding a gid, make sure it doesn't match an existing uid.
|
# When adding a gid, make sure it doesn't match an existing uid.
|
||||||
|
|
||||||
users = 100;
|
users = 100;
|
||||||
|
|
|
@ -52,6 +52,7 @@
|
||||||
./services/backup/sitecopy-backup.nix
|
./services/backup/sitecopy-backup.nix
|
||||||
./services/databases/mysql.nix
|
./services/databases/mysql.nix
|
||||||
./services/databases/postgresql.nix
|
./services/databases/postgresql.nix
|
||||||
|
./services/games/ghost-one.nix
|
||||||
./services/hardware/acpid.nix
|
./services/hardware/acpid.nix
|
||||||
./services/hardware/bluetooth.nix
|
./services/hardware/bluetooth.nix
|
||||||
./services/hardware/hal.nix
|
./services/hardware/hal.nix
|
||||||
|
@ -91,6 +92,7 @@
|
||||||
./services/networking/dhcpd.nix
|
./services/networking/dhcpd.nix
|
||||||
./services/networking/ejabberd.nix
|
./services/networking/ejabberd.nix
|
||||||
./services/networking/firewall.nix
|
./services/networking/firewall.nix
|
||||||
|
./services/networking/git-daemon.nix
|
||||||
./services/networking/gnunet.nix
|
./services/networking/gnunet.nix
|
||||||
./services/networking/gvpe.nix
|
./services/networking/gvpe.nix
|
||||||
./services/networking/gw6c.nix
|
./services/networking/gw6c.nix
|
||||||
|
@ -107,6 +109,7 @@
|
||||||
./services/networking/ssh/sshd.nix
|
./services/networking/ssh/sshd.nix
|
||||||
./services/networking/tftpd.nix
|
./services/networking/tftpd.nix
|
||||||
./services/networking/vsftpd.nix
|
./services/networking/vsftpd.nix
|
||||||
|
./services/networking/wakeonlan.nix
|
||||||
./services/networking/wicd.nix
|
./services/networking/wicd.nix
|
||||||
./services/networking/wpa_supplicant.nix
|
./services/networking/wpa_supplicant.nix
|
||||||
./services/networking/xinetd.nix
|
./services/networking/xinetd.nix
|
||||||
|
|
|
@ -79,7 +79,7 @@ in zipModules ([]
|
||||||
|
|
||||||
# OpenSSH
|
# OpenSSH
|
||||||
++ rename obsolete "services.sshd.ports" "services.openssh.ports"
|
++ rename obsolete "services.sshd.ports" "services.openssh.ports"
|
||||||
++ rename obsolete "services.sshd.enable" "services.openssh.enable"
|
++ rename alias "services.sshd.enable" "services.openssh.enable"
|
||||||
++ rename obsolete "services.sshd.allowSFTP" "services.openssh.allowSFTP"
|
++ rename obsolete "services.sshd.allowSFTP" "services.openssh.allowSFTP"
|
||||||
++ rename obsolete "services.sshd.forwardX11" "services.openssh.forwardX11"
|
++ rename obsolete "services.sshd.forwardX11" "services.openssh.forwardX11"
|
||||||
++ rename obsolete "services.sshd.gatewayPorts" "services.openssh.gatewayPorts"
|
++ rename obsolete "services.sshd.gatewayPorts" "services.openssh.gatewayPorts"
|
||||||
|
|
|
@ -66,7 +66,7 @@ in
|
||||||
|
|
||||||
services.cron.systemCronJobs = map sitecopyCron config.services.sitecopy.backups;
|
services.cron.systemCronJobs = map sitecopyCron config.services.sitecopy.backups;
|
||||||
|
|
||||||
system.activationScripts.sitecopyBackup = stringAfter [ "stdio" "systemConfig" "users" ]
|
system.activationScripts.sitecopyBackup = stringAfter [ "stdio" "users" ]
|
||||||
''
|
''
|
||||||
mkdir -m 0700 -p ${stateDir}
|
mkdir -m 0700 -p ${stateDir}
|
||||||
chown root ${stateDir}
|
chown root ${stateDir}
|
||||||
|
|
|
@ -0,0 +1,105 @@
|
||||||
|
{pkgs, config, ...}:
|
||||||
|
with pkgs.lib;
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.services.ghostOne;
|
||||||
|
ghostUser = "ghostone";
|
||||||
|
stateDir = "/var/lib/ghost-one";
|
||||||
|
|
||||||
|
in
|
||||||
|
{
|
||||||
|
|
||||||
|
###### interface
|
||||||
|
|
||||||
|
options = {
|
||||||
|
services.ghostOne = {
|
||||||
|
|
||||||
|
enable = mkOption {
|
||||||
|
default = false;
|
||||||
|
description = "Enable Ghost-One Warcraft3 game hosting server.";
|
||||||
|
};
|
||||||
|
|
||||||
|
language = mkOption {
|
||||||
|
default = "English";
|
||||||
|
check = lang: elem lang [ "English" "Spanish" "Russian" "Serbian" "Turkish" ];
|
||||||
|
description = "The language of bot messages: English, Spanish, Russian, Serbian or Turkish.";
|
||||||
|
};
|
||||||
|
|
||||||
|
war3path = mkOption {
|
||||||
|
default = "";
|
||||||
|
description = ''
|
||||||
|
The path to your local Warcraft III directory, which must contain war3.exe, storm.dll, and game.dll.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
mappath = mkOption {
|
||||||
|
default = "";
|
||||||
|
description = ''
|
||||||
|
The path to the directory where you keep your map files. GHost One doesn't require
|
||||||
|
map files but if it has access to them it can send them to players and automatically
|
||||||
|
calculate most map config values. GHost One will search [bot_mappath + map_localpath]
|
||||||
|
for the map file (map_localpath is set in each map's config file).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkOption {
|
||||||
|
default = "";
|
||||||
|
description = "Extra configuration options.";
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
###### implementation
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
|
||||||
|
users.extraUsers = singleton
|
||||||
|
{ name = ghostUser;
|
||||||
|
uid = config.ids.uids.ghostOne;
|
||||||
|
description = "Ghost One game server user";
|
||||||
|
home = stateDir;
|
||||||
|
};
|
||||||
|
|
||||||
|
users.extraGroups = singleton
|
||||||
|
{ name = ghostUser;
|
||||||
|
gid = config.ids.gids.ghostOne;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.ghostOne.config = ''
|
||||||
|
# bot_log = /dev/stderr
|
||||||
|
bot_language = ${pkgs.ghostOne}/share/ghost-one/languages/${cfg.language}.cfg
|
||||||
|
bot_war3path = ${cfg.war3path}
|
||||||
|
|
||||||
|
bot_mapcfgpath = mapcfgs
|
||||||
|
bot_savegamepath = savegames
|
||||||
|
bot_mappath = ${cfg.mappath}
|
||||||
|
bot_replaypath = replays
|
||||||
|
'';
|
||||||
|
|
||||||
|
jobs.ghostOne = {
|
||||||
|
name = "ghost-one";
|
||||||
|
script = ''
|
||||||
|
mkdir -p ${stateDir}
|
||||||
|
cd ${stateDir}
|
||||||
|
chown ${ghostUser}:${ghostUser} .
|
||||||
|
|
||||||
|
mkdir -p mapcfgs
|
||||||
|
chown ${ghostUser}:${ghostUser} mapcfgs
|
||||||
|
|
||||||
|
mkdir -p replays
|
||||||
|
chown ${ghostUser}:${ghostUser} replays
|
||||||
|
|
||||||
|
mkdir -p savegames
|
||||||
|
chown ${ghostUser}:${ghostUser} savegames
|
||||||
|
|
||||||
|
ln -sf ${pkgs.writeText "ghost.cfg" cfg.config} ghost.cfg
|
||||||
|
ln -sf ${pkgs.ghostOne}/share/ghost-one/ip-to-country.csv
|
||||||
|
${pkgs.su}/bin/su -s ${pkgs.stdenv.shell} ${ghostUser} \
|
||||||
|
-c "LANG=C ${pkgs.ghostOne}/bin/ghost++"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -34,6 +34,23 @@ in
|
||||||
description = "Whether to enable the DisnixWebService interface running on Apache Tomcat";
|
description = "Whether to enable the DisnixWebService interface running on Apache Tomcat";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
publishInfrastructure = {
|
||||||
|
enable = mkOption {
|
||||||
|
default = false;
|
||||||
|
description = "Whether to publish capabilities/properties of this machine in as attributes in the infrastructure option";
|
||||||
|
};
|
||||||
|
|
||||||
|
enableAuthentication = mkOption {
|
||||||
|
default = false;
|
||||||
|
description = "Whether to publish authentication credentials through the infrastructure attribute (not recommended in combination with Avahi)";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
infrastructure = mkOption {
|
||||||
|
default = {};
|
||||||
|
description = "List of name value pairs containing properties for the infrastructure model";
|
||||||
|
};
|
||||||
|
|
||||||
publishAvahi = mkOption {
|
publishAvahi = mkOption {
|
||||||
default = false;
|
default = false;
|
||||||
description = "Whether to publish capabilities/properties as a Disnix service through Avahi";
|
description = "Whether to publish capabilities/properties as a Disnix service through Avahi";
|
||||||
|
@ -47,62 +64,79 @@ in
|
||||||
###### implementation
|
###### implementation
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
|
|
||||||
environment.systemPackages = [ pkgs.disnix ] ++ optional cfg.useWebServiceInterface pkgs.DisnixWebService;
|
environment.systemPackages = [ pkgs.disnix ] ++ optional cfg.useWebServiceInterface pkgs.DisnixWebService;
|
||||||
|
|
||||||
services.dbus.enable = true;
|
services.dbus.enable = true;
|
||||||
services.dbus.packages = [ pkgs.disnix ];
|
services.dbus.packages = [ pkgs.disnix ];
|
||||||
|
|
||||||
|
services.avahi.enable = cfg.publishAvahi;
|
||||||
|
|
||||||
services.tomcat.enable = cfg.useWebServiceInterface;
|
services.tomcat.enable = cfg.useWebServiceInterface;
|
||||||
services.tomcat.extraGroups = [ "disnix" ];
|
services.tomcat.extraGroups = [ "disnix" ];
|
||||||
services.tomcat.javaOpts = "${optionalString cfg.useWebServiceInterface "-Djava.library.path=${pkgs.libmatthew_java}/lib/jni"} ";
|
services.tomcat.javaOpts = "${optionalString cfg.useWebServiceInterface "-Djava.library.path=${pkgs.libmatthew_java}/lib/jni"} ";
|
||||||
services.tomcat.sharedLibs = []
|
services.tomcat.sharedLibs = optional cfg.useWebServiceInterface "${pkgs.DisnixWebService}/share/java/DisnixConnection.jar"
|
||||||
++ optional cfg.useWebServiceInterface "${pkgs.DisnixWebService}/share/java/DisnixConnection.jar"
|
|
||||||
++ optional cfg.useWebServiceInterface "${pkgs.dbus_java}/share/java/dbus.jar";
|
++ optional cfg.useWebServiceInterface "${pkgs.dbus_java}/share/java/dbus.jar";
|
||||||
services.tomcat.webapps = [] ++ optional cfg.useWebServiceInterface pkgs.DisnixWebService;
|
services.tomcat.webapps = optional cfg.useWebServiceInterface pkgs.DisnixWebService;
|
||||||
|
|
||||||
users.extraGroups = singleton
|
users.extraGroups = singleton
|
||||||
{ name = "disnix";
|
{ name = "disnix";
|
||||||
gid = config.ids.gids.disnix;
|
gid = config.ids.gids.disnix;
|
||||||
};
|
};
|
||||||
|
|
||||||
jobs.disnix =
|
services.disnix.infrastructure =
|
||||||
{ description = "Disnix server";
|
optionalAttrs (cfg.publishInfrastructure.enable)
|
||||||
|
( { hostname = config.networking.hostName;
|
||||||
|
targetHost = config.deployment.targetHost;
|
||||||
|
system = if config.nixpkgs.system == "" then builtins.currentSystem else config.nixpkgs.system;
|
||||||
|
}
|
||||||
|
// optionalAttrs (cfg.useWebServiceInterface) { targetEPR = "http://${config.deployment.targetHost}:8080/DisnixWebService/services/DisnixWebService"; }
|
||||||
|
// optionalAttrs (config.services.httpd.enable) { documentRoot = config.services.httpd.documentRoot; }
|
||||||
|
// optionalAttrs (config.services.mysql.enable) { mysqlPort = config.services.mysql.port; }
|
||||||
|
// optionalAttrs (config.services.tomcat.enable) { tomcatPort = 8080; }
|
||||||
|
// optionalAttrs (cfg.publishInfrastructure.enableAuthentication) (
|
||||||
|
optionalAttrs (config.services.mysql.enable) { mysqlUsername = "root"; mysqlPassword = builtins.readFile config.services.mysql.rootPassword; })
|
||||||
|
)
|
||||||
|
;
|
||||||
|
|
||||||
|
services.disnix.publishInfrastructure.enable = cfg.publishAvahi;
|
||||||
|
|
||||||
|
jobs = {
|
||||||
|
disnix =
|
||||||
|
{ description = "Disnix server";
|
||||||
|
|
||||||
startOn = "started dbus";
|
startOn = "started dbus";
|
||||||
|
|
||||||
script =
|
script =
|
||||||
''
|
''
|
||||||
export PATH=/var/run/current-system/sw/bin:/var/run/current-system/sw/sbin
|
export PATH=/var/run/current-system/sw/bin:/var/run/current-system/sw/sbin
|
||||||
export HOME=/root
|
export HOME=/root
|
||||||
|
|
||||||
${pkgs.disnix}/bin/disnix-service --activation-modules-dir=${disnix_activation_scripts}/libexec/disnix/activation-scripts
|
${pkgs.disnix}/bin/disnix-service --activation-modules-dir=${disnix_activation_scripts}/libexec/disnix/activation-scripts
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
} // optionalAttrs cfg.publishAvahi {
|
||||||
} //
|
disnixAvahi =
|
||||||
mkIf cfg.publishAvahi {
|
{ description = "Disnix Avahi publisher";
|
||||||
|
|
||||||
services.avahi.enable = true;
|
|
||||||
|
|
||||||
jobs.disnixAvahi =
|
|
||||||
{ description = "Disnix Avahi publisher";
|
|
||||||
|
|
||||||
startOn = "started avahi-daemon";
|
startOn = "started avahi-daemon";
|
||||||
|
|
||||||
exec =
|
exec =
|
||||||
''
|
''
|
||||||
${pkgs.avahi}/bin/avahi-publish-service disnix-$(${pkgs.nettools}/bin/hostname) _disnix._tcp 22 \
|
${pkgs.avahi}/bin/avahi-publish-service disnix-${config.networking.hostName} _disnix._tcp 22 \
|
||||||
"hostname=\"$(${pkgs.nettools}/bin/hostname)\"" \
|
"mem=$(grep 'MemTotal:' /proc/meminfo | sed -e 's/kB//' -e 's/MemTotal://' -e 's/ //g')" \
|
||||||
"system=\"$(uname -m)-linux\"" \
|
"supportedTypes=[$(for i in ${disnix_activation_scripts}/libexec/disnix/activation-scripts/*; do echo -n " \"$(basename $i)\""; done) ]" \
|
||||||
"mem=$(grep 'MemTotal:' /proc/meminfo | sed -e 's/kB//' -e 's/MemTotal://' -e 's/ //g')" \
|
${concatMapStrings (infrastructureAttrName:
|
||||||
${optionalString (cfg.useWebServiceInterface) ''"targetEPR=\"http://(${pkgs.nettools}/bin/hostname):8080/DisnixWebService/services/DisnixWebService\""''} \
|
let infrastructureAttrValue = getAttr infrastructureAttrName (cfg.infrastructure);
|
||||||
${optionalString (config.services.httpd.enable) ''"documentRoot=\"${config.services.httpd.documentRoot}\""''} \
|
in
|
||||||
${optionalString (config.services.mysql.enable) ''"mysqlPort=3306"''} \
|
if builtins.isInt infrastructureAttrValue then
|
||||||
${optionalString (config.services.tomcat.enable) ''"tomcatPort=8080"''} \
|
''${infrastructureAttrName}=${infrastructureAttrValue} \
|
||||||
"supportedTypes=[$(for i in ${disnix_activation_scripts}/libexec/disnix/activation-scripts/*; do echo -n " \"$(basename $i)\""; done) ]" \
|
''
|
||||||
${concatMapStrings (deploymentAttrName: let deploymentAttrValue = getAttr deploymentAttrName (config.deployment); in ''${deploymentAttrName}=\"${deploymentAttrValue}\" '' ) (attrNames (config.deployment))}
|
else
|
||||||
'';
|
''${infrastructureAttrName}=\"${infrastructureAttrValue}\" \
|
||||||
};
|
''
|
||||||
|
) (attrNames (cfg.infrastructure))}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@ with pkgs.lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
|
|
||||||
|
cfg = config.services.zabbixServer;
|
||||||
|
|
||||||
stateDir = "/var/run/zabbix";
|
stateDir = "/var/run/zabbix";
|
||||||
|
|
||||||
logDir = "/var/log/zabbix";
|
logDir = "/var/log/zabbix";
|
||||||
|
@ -19,9 +21,15 @@ let
|
||||||
|
|
||||||
PidFile = ${pidFile}
|
PidFile = ${pidFile}
|
||||||
|
|
||||||
|
DBHost = ${cfg.dbServer}
|
||||||
|
|
||||||
DBName = zabbix
|
DBName = zabbix
|
||||||
|
|
||||||
DBUser = zabbix
|
DBUser = zabbix
|
||||||
|
|
||||||
|
${optionalString (cfg.dbPassword != "") ''
|
||||||
|
DBPassword = ${cfg.dbPassword}
|
||||||
|
''}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
in
|
in
|
||||||
|
@ -39,11 +47,21 @@ in
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
services.zabbixServer.dbServer = mkOption {
|
||||||
|
default = "localhost";
|
||||||
|
description = "Hostname or IP address of the database server.";
|
||||||
|
};
|
||||||
|
|
||||||
|
services.zabbixServer.dbPassword = mkOption {
|
||||||
|
default = "";
|
||||||
|
description = "Password used to connect to the database server.";
|
||||||
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
###### implementation
|
###### implementation
|
||||||
|
|
||||||
config = mkIf config.services.zabbixServer.enable {
|
config = mkIf cfg.enable {
|
||||||
|
|
||||||
services.postgresql.enable = true;
|
services.postgresql.enable = true;
|
||||||
|
|
||||||
|
|
|
@ -80,10 +80,10 @@ in
|
||||||
# Only run dhclient on interfaces of type ARPHRD_ETHER
|
# Only run dhclient on interfaces of type ARPHRD_ETHER
|
||||||
# (1), i.e. Ethernet. Ignore peth* devices; on Xen,
|
# (1), i.e. Ethernet. Ignore peth* devices; on Xen,
|
||||||
# they're renamed physical Ethernet cards used for
|
# they're renamed physical Ethernet cards used for
|
||||||
# bridging.
|
# bridging. Likewise for vif* and tap*.
|
||||||
if [ "$(cat /sys/class/net/$i/type)" = 1 ]; then
|
if [ "$(cat /sys/class/net/$i/type)" = 1 ]; then
|
||||||
if ! for j in ${toString ignoredInterfaces}; do echo $j; done | grep -F -x -q "$i" &&
|
if ! for j in ${toString ignoredInterfaces}; do echo $j; done | grep -F -x -q "$i" &&
|
||||||
! echo "$i" | grep -x -q "peth.*";
|
! echo "$i" | grep -x -q "peth.*\|vif.*\|tap.*";
|
||||||
then
|
then
|
||||||
echo "Running dhclient on $i"
|
echo "Running dhclient on $i"
|
||||||
interfaces="$interfaces $i"
|
interfaces="$interfaces $i"
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
{pkgs, config, ...}:
|
||||||
|
with pkgs.lib;
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.services.gitDaemon;
|
||||||
|
gitUser = "git";
|
||||||
|
|
||||||
|
in
|
||||||
|
{
|
||||||
|
|
||||||
|
###### interface
|
||||||
|
|
||||||
|
options = {
|
||||||
|
services.gitDaemon = {
|
||||||
|
|
||||||
|
enable = mkOption {
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Enable Git daemon, which allows public hosting of git repositories
|
||||||
|
without any access controls. This is mostly intended for read-only access.
|
||||||
|
|
||||||
|
You can allow write access by setting daemon.receivepack configuration
|
||||||
|
item of the repository to true. This is solely meant for a closed LAN setting
|
||||||
|
where everybody is friendly.
|
||||||
|
|
||||||
|
If you need any access controls, use something else.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
basePath = mkOption {
|
||||||
|
default = "";
|
||||||
|
example = "/srv/git/";
|
||||||
|
description = ''
|
||||||
|
Remap all the path requests as relative to the given path. For example,
|
||||||
|
if you set base-path to /srv/git, then if you later try to pull
|
||||||
|
git://example.com/hello.git, Git daemon will interpret the path as /srv/git/hello.git.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
exportAll = mkOption {
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Publish all directories that look like Git repositories (have the objects
|
||||||
|
and refs subdirectories), even if they do not have the git-daemon-export-ok file.
|
||||||
|
|
||||||
|
If disabled, you need to touch .git/git-daemon-export-ok in each repository
|
||||||
|
you want the daemon to publish.
|
||||||
|
|
||||||
|
Warning: enabling this without a repository whitelist or basePath
|
||||||
|
publishes every git repository you have.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
repositories = mkOption {
|
||||||
|
default = [];
|
||||||
|
example = [ "/srv/git" "/home/user/git/repo2" ];
|
||||||
|
description = ''
|
||||||
|
A whitelist of paths of git repositories, or directories containing repositories
|
||||||
|
all of which would be published. Paths must not end in "/".
|
||||||
|
|
||||||
|
Warning: leaving this empty and enabling exportAll publishes all
|
||||||
|
repositories in your filesystem or basePath if specified.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
listenAddress = mkOption {
|
||||||
|
default = "";
|
||||||
|
example = "example.com";
|
||||||
|
description = "Listen on a specific IP address or hostname.";
|
||||||
|
};
|
||||||
|
|
||||||
|
port = mkOption {
|
||||||
|
default = 9418;
|
||||||
|
description = "Port to listen on.";
|
||||||
|
};
|
||||||
|
|
||||||
|
options = mkOption {
|
||||||
|
default = "";
|
||||||
|
description = "Extra configuration options to be passed to Git daemon.";
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
###### implementation
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
|
||||||
|
users.extraUsers = singleton
|
||||||
|
{ name = gitUser;
|
||||||
|
uid = config.ids.uids.git;
|
||||||
|
description = "Git daemon user";
|
||||||
|
};
|
||||||
|
|
||||||
|
users.extraGroups = singleton
|
||||||
|
{ name = gitUser;
|
||||||
|
gid = config.ids.gids.git;
|
||||||
|
};
|
||||||
|
|
||||||
|
jobs.gitDaemon = {
|
||||||
|
name = "git-daemon";
|
||||||
|
startOn = "ip-up";
|
||||||
|
exec = "${pkgs.git}/bin/git daemon --reuseaddr "
|
||||||
|
+ (optionalString (cfg.basePath != "") "--basepath=${cfg.basePath} ")
|
||||||
|
+ (optionalString (cfg.listenAddress != "") "--listen=${cfg.listenAddress} ")
|
||||||
|
+ "--port=${toString cfg.port} --user=${gitUser} --group=${gitUser} ${cfg.options} "
|
||||||
|
+ "--verbose " + (optionalString cfg.exportAll "--export-all") + concatStringsSep " " cfg.repositories;
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
|
with pkgs.lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
interfaces = config.services.wakeonlan.interfaces;
|
||||||
|
|
||||||
|
ethtool = "${pkgs.ethtool}/sbin/ethtool";
|
||||||
|
|
||||||
|
passwordParameter = password : if (password == "") then "" else
|
||||||
|
"sopass ${password}";
|
||||||
|
|
||||||
|
methodParameter = {method, password} :
|
||||||
|
if method == "magicpacket" then "wol g"
|
||||||
|
else if method == "password" then "wol s so ${passwordParameter password}"
|
||||||
|
else throw "Wake-On-Lan method not supported";
|
||||||
|
|
||||||
|
line = { interface, method ? "magicpacket", password ? "" }: ''
|
||||||
|
${ethtool} -s ${interface} ${methodParameter {inherit method password;}}
|
||||||
|
'';
|
||||||
|
|
||||||
|
concatStrings = fold (x: y: x + y) "";
|
||||||
|
lines = concatStrings (map (l: line l) interfaces);
|
||||||
|
|
||||||
|
in
|
||||||
|
{
|
||||||
|
|
||||||
|
###### interface
|
||||||
|
|
||||||
|
options = {
|
||||||
|
|
||||||
|
services.wakeonlan.interfaces = mkOption {
|
||||||
|
default = [ ];
|
||||||
|
example = [
|
||||||
|
{
|
||||||
|
interface = "eth0";
|
||||||
|
method = "password";
|
||||||
|
password = "00:11:22:33:44:55";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
description = ''
|
||||||
|
Interfaces where to enable Wake-On-LAN, and how. Two methods available:
|
||||||
|
"magickey" and "password". The password has the shape of six bytes
|
||||||
|
in hexadecimal separated by a colon each. For more information,
|
||||||
|
check the ethtool manual.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
###### implementation
|
||||||
|
|
||||||
|
config.powerManagement.powerDownCommands = lines;
|
||||||
|
|
||||||
|
}
|
|
@ -16,16 +16,16 @@ let
|
||||||
name = "additional-cups-backends";
|
name = "additional-cups-backends";
|
||||||
builder = pkgs.writeScript "additional-backends-builder.sh" ''
|
builder = pkgs.writeScript "additional-backends-builder.sh" ''
|
||||||
PATH=${pkgs.coreutils}/bin
|
PATH=${pkgs.coreutils}/bin
|
||||||
mkdir -p $out
|
mkdir -pv $out
|
||||||
if [ ! -e ${pkgs.samba}/lib/cups/backend/smb ]; then
|
if [ ! -e ${pkgs.samba}/lib/cups/backend/smb ]; then
|
||||||
mkdir -p $out/lib/cups/backend
|
mkdir -pv $out/lib/cups/backend
|
||||||
ln -s ${pkgs.samba}/bin/smbspool $out/lib/cups/backend/smb
|
ln -sv ${pkgs.samba}/bin/smbspool $out/lib/cups/backend/smb
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Provide support for printing via HTTPS.
|
# Provide support for printing via HTTPS.
|
||||||
if [ ! -e ${pkgs.cups}/lib/cups/backend/https ]; then
|
if [ ! -e ${pkgs.cups}/lib/cups/backend/https ]; then
|
||||||
mkdir -p $out/lib/cups/backend
|
mkdir -pv $out/lib/cups/backend
|
||||||
ln -s ${pkgs.cups}/lib/cups/backend/ipp $out/lib/cups/backend/https
|
ln -sv ${pkgs.cups}/lib/cups/backend/ipp $out/lib/cups/backend/https
|
||||||
fi
|
fi
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
@ -147,7 +147,7 @@ in
|
||||||
exec = "${cups}/sbin/cupsd -c ${pkgs.writeText "cupsd.conf" cfg.cupsdConf} -F";
|
exec = "${cups}/sbin/cupsd -c ${pkgs.writeText "cupsd.conf" cfg.cupsdConf} -F";
|
||||||
};
|
};
|
||||||
|
|
||||||
services.printing.drivers = [ pkgs.cups pkgs.ghostscript additionalBackends ];
|
services.printing.drivers = [ pkgs.cups pkgs.cups_pdf_filter pkgs.ghostscript additionalBackends ];
|
||||||
services.printing.cupsdConf =
|
services.printing.cupsdConf =
|
||||||
''
|
''
|
||||||
LogLevel info
|
LogLevel info
|
||||||
|
|
|
@ -57,17 +57,22 @@ let
|
||||||
$wgArticlePath = "${config.articleUrlPrefix}/$1";
|
$wgArticlePath = "${config.articleUrlPrefix}/$1";
|
||||||
''}
|
''}
|
||||||
|
|
||||||
|
${optionalString config.enableUploads ''
|
||||||
|
$wgEnableUploads = true;
|
||||||
|
$wgUploadDirectory = "${config.uploadDir}";
|
||||||
|
''}
|
||||||
|
|
||||||
${config.extraConfig}
|
${config.extraConfig}
|
||||||
?>
|
?>
|
||||||
'';
|
'';
|
||||||
|
|
||||||
# Unpack Mediawiki and put the config file in its root directory.
|
# Unpack Mediawiki and put the config file in its root directory.
|
||||||
mediawikiRoot = pkgs.stdenv.mkDerivation rec {
|
mediawikiRoot = pkgs.stdenv.mkDerivation rec {
|
||||||
name= "mediawiki-1.15.4";
|
name= "mediawiki-1.15.5";
|
||||||
|
|
||||||
src = pkgs.fetchurl {
|
src = pkgs.fetchurl {
|
||||||
url = "http://download.wikimedia.org/mediawiki/1.15/${name}.tar.gz";
|
url = "http://download.wikimedia.org/mediawiki/1.15/${name}.tar.gz";
|
||||||
sha256 = "1blf79lhnaxixc8z96f9z4xi2jlg906ps3kd4x8b9ipg2dgl3vy9";
|
sha256 = "1d8afbdh3lsg54b69mnh6a47psb3lg978xpp277qs08yz15cjf7q";
|
||||||
};
|
};
|
||||||
|
|
||||||
buildPhase = "true";
|
buildPhase = "true";
|
||||||
|
@ -96,6 +101,16 @@ in
|
||||||
|
|
||||||
extraConfig =
|
extraConfig =
|
||||||
''
|
''
|
||||||
|
${optionalString config.enableUploads ''
|
||||||
|
Alias ${config.urlPrefix}/images ${config.uploadDir}
|
||||||
|
|
||||||
|
<Directory ${config.uploadDir}>
|
||||||
|
Order allow,deny
|
||||||
|
Allow from all
|
||||||
|
Options -Indexes
|
||||||
|
</Directory>
|
||||||
|
''}
|
||||||
|
|
||||||
Alias ${config.urlPrefix} ${mediawikiRoot}
|
Alias ${config.urlPrefix} ${mediawikiRoot}
|
||||||
|
|
||||||
<Directory ${mediawikiRoot}>
|
<Directory ${mediawikiRoot}>
|
||||||
|
@ -205,6 +220,17 @@ in
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enableUploads = mkOption {
|
||||||
|
default = false;
|
||||||
|
description = "Whether to enable file uploads.";
|
||||||
|
};
|
||||||
|
|
||||||
|
uploadDir = mkOption {
|
||||||
|
default = throw "You must specify `uploadDir'.";
|
||||||
|
example = "/data/mediawiki-upload";
|
||||||
|
description = "The directory that stores uploaded files.";
|
||||||
|
};
|
||||||
|
|
||||||
extraConfig = mkOption {
|
extraConfig = mkOption {
|
||||||
default = "";
|
default = "";
|
||||||
example =
|
example =
|
||||||
|
|
|
@ -29,9 +29,11 @@ with pkgs.lib;
|
||||||
echo "[1;32m<<< System shutdown >>>[0m"
|
echo "[1;32m<<< System shutdown >>>[0m"
|
||||||
fi
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
|
${config.powerManagement.powerDownCommands}
|
||||||
|
|
||||||
export PATH=${pkgs.utillinux}/bin:${pkgs.utillinux}/sbin:$PATH
|
export PATH=${pkgs.utillinux}/bin:${pkgs.utillinux}/sbin:$PATH
|
||||||
|
|
||||||
|
|
||||||
# Do an initial sync just in case.
|
# Do an initial sync just in case.
|
||||||
sync
|
sync
|
||||||
|
|
|
@ -185,7 +185,7 @@ let
|
||||||
-m ${toString config.virtualisation.memorySize} \
|
-m ${toString config.virtualisation.memorySize} \
|
||||||
-net nic,vlan=0,model=virtio \
|
-net nic,vlan=0,model=virtio \
|
||||||
-chardev socket,id=samba,path=./samba \
|
-chardev socket,id=samba,path=./samba \
|
||||||
-net user,vlan=0,guestfwd=tcp:10.0.2.4:139-chardev:samba${if cfg.useBackdoor then ",guestfwd=tcp:10.0.2.6:23-chardev:shell" else ""}''${QEMU_NET_OPTS:+,$QEMU_NET_OPTS} \
|
-net user,vlan=0,guestfwd=tcp:10.0.2.4:445-chardev:samba${if cfg.useBackdoor then ",guestfwd=tcp:10.0.2.6:23-chardev:shell" else ""}''${QEMU_NET_OPTS:+,$QEMU_NET_OPTS} \
|
||||||
${if cfg.useBackdoor then "-chardev socket,id=shell,path=./shell" else ""} \
|
${if cfg.useBackdoor then "-chardev socket,id=shell,path=./shell" else ""} \
|
||||||
${if cfg.useBootLoader then ''
|
${if cfg.useBootLoader then ''
|
||||||
-drive index=0,file=$NIX_DISK_IMAGE,if=virtio,cache=writeback,werror=report \
|
-drive index=0,file=$NIX_DISK_IMAGE,if=virtio,cache=writeback,werror=report \
|
||||||
|
|
|
@ -79,6 +79,14 @@ in
|
||||||
# as it's loaded, so don't load it.
|
# as it's loaded, so don't load it.
|
||||||
boot.blacklistedKernelModules = [ "radeonfb" ];
|
boot.blacklistedKernelModules = [ "radeonfb" ];
|
||||||
|
|
||||||
|
# Increase the number of loopback devices from the default (8),
|
||||||
|
# which is way too small because every VM virtual disk requires a
|
||||||
|
# loopback device.
|
||||||
|
boot.extraModprobeConfig =
|
||||||
|
''
|
||||||
|
options loop max_loop=64
|
||||||
|
'';
|
||||||
|
|
||||||
virtualisation.xen.bootParams =
|
virtualisation.xen.bootParams =
|
||||||
[ "loglvl=all" "guest_loglvl=all" ] ++
|
[ "loglvl=all" "guest_loglvl=all" ] ++
|
||||||
optional (cfg.domain0MemorySize != 0) "dom0_mem=${toString cfg.domain0MemorySize}M";
|
optional (cfg.domain0MemorySize != 0) "dom0_mem=${toString cfg.domain0MemorySize}M";
|
||||||
|
|
|
@ -93,7 +93,7 @@ let
|
||||||
''
|
''
|
||||||
createDisk("harddisk", 4 * 1024);
|
createDisk("harddisk", 4 * 1024);
|
||||||
|
|
||||||
my $machine = Machine->new({ hda => "harddisk", cdrom => glob("${iso}/iso/*.iso"), qemuFlags => '${qemuNICFlags 1 1}' });
|
my $machine = Machine->new({ hda => "harddisk", cdrom => glob("${iso}/iso/*.iso"), qemuFlags => '${qemuNICFlags 1 1 1}' });
|
||||||
$machine->start;
|
$machine->start;
|
||||||
|
|
||||||
${optionalString testChannel ''
|
${optionalString testChannel ''
|
||||||
|
|
|
@ -4,7 +4,7 @@ let
|
||||||
|
|
||||||
client =
|
client =
|
||||||
{ config, pkgs, ... }:
|
{ config, pkgs, ... }:
|
||||||
{ fileSystems = pkgs.lib.mkOverrideTemplate 50 {}
|
{ fileSystems = pkgs.lib.mkOverride 50
|
||||||
[ { mountPoint = "/data";
|
[ { mountPoint = "/data";
|
||||||
device = "server:/data";
|
device = "server:/data";
|
||||||
fsType = "nfs";
|
fsType = "nfs";
|
||||||
|
|
Loading…
Reference in New Issue