Merging from trunk
svn path=/nixos/branches/stdenv-updates/; revision=25176
This commit is contained in:
commit
3f7751b9c2
148
doc/manual/man-nixos-build-vms.xml
Normal file
148
doc/manual/man-nixos-build-vms.xml
Normal file
@ -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>
|
135
doc/manual/man-nixos-deploy-network.xml
Normal file
135
doc/manual/man-nixos-deploy-network.xml
Normal file
@ -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-nixos-rebuild.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>
|
||||
|
@ -108,7 +108,7 @@ rec {
|
||||
|
||||
virtualisation.qemu.options =
|
||||
lib.flip lib.concatMapStrings interfacesNumbered
|
||||
({ first, second }: qemuNICFlags second first );
|
||||
({ first, second }: qemuNICFlags second first m.second);
|
||||
};
|
||||
}
|
||||
)
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
{
|
||||
|
||||
qemuNICFlags = nic: net:
|
||||
"-net nic,vlan=${toString nic},model=virtio " +
|
||||
qemuNICFlags = nic: net: machine:
|
||||
"-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
|
||||
# the same vlan, but allow it to be overriden using the
|
||||
# $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";
|
||||
}
|
||||
|
||||
my $showGraphics = defined $ENV{'DISPLAY'};
|
||||
|
||||
|
||||
sub new {
|
||||
my ($class, $args) = @_;
|
||||
|
||||
my $startCommand = $args->{startCommand};
|
||||
|
||||
my $name = $args->{name};
|
||||
if (!$name) {
|
||||
$startCommand =~ /run-(.*)-vm$/;
|
||||
$name = $1 || "machine";
|
||||
}
|
||||
|
||||
if (!$startCommand) {
|
||||
# !!! merge with qemu-vm.nix.
|
||||
$startCommand =
|
||||
@ -34,12 +43,8 @@ sub new {
|
||||
$startCommand .= "-cdrom $args->{cdrom} "
|
||||
if defined $args->{cdrom};
|
||||
$startCommand .= $args->{qemuFlags} || "";
|
||||
}
|
||||
|
||||
my $name = $args->{name};
|
||||
if (!$name) {
|
||||
$startCommand =~ /run-(.*)-vm$/;
|
||||
$name = $1 || "machine";
|
||||
} else {
|
||||
$startCommand = Cwd::abs_path $startCommand;
|
||||
}
|
||||
|
||||
my $tmpDir = $ENV{'TMPDIR'} || "/tmp";
|
||||
@ -51,7 +56,7 @@ sub new {
|
||||
pid => 0,
|
||||
connected => 0,
|
||||
socket => undef,
|
||||
stateDir => "$tmpDir/$name",
|
||||
stateDir => "$tmpDir/vm-state-$name",
|
||||
monitor => undef,
|
||||
};
|
||||
|
||||
@ -121,12 +126,14 @@ sub start {
|
||||
dup2(fileno($serialC), fileno(STDERR));
|
||||
$ENV{TMPDIR} = $self->{stateDir};
|
||||
$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_KERNEL_PARAMS} = "hostTmpDir=$ENV{TMPDIR}";
|
||||
chdir $self->{stateDir} or die;
|
||||
exec $self->{startCommand};
|
||||
die;
|
||||
die "running VM script: $!";
|
||||
}
|
||||
|
||||
# Process serial line output.
|
||||
@ -248,7 +255,8 @@ sub execute {
|
||||
my $out = "";
|
||||
|
||||
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");
|
||||
if ($line =~ /^(.*)\|\!\=EOF\s+(\d+)$/) {
|
||||
$out .= $1;
|
||||
@ -267,7 +275,7 @@ sub succeed {
|
||||
my ($status, $out) = $self->execute($command);
|
||||
if ($status != 0) {
|
||||
$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;
|
||||
}
|
||||
@ -404,7 +412,8 @@ sub unblock {
|
||||
# Take a screenshot of the X server on :0.0.
|
||||
sub screenshot {
|
||||
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";
|
||||
$self->sendMonitorCommand("screendump $tmp");
|
||||
system("convert $tmp ${filename}") == 0
|
||||
|
@ -1,8 +1,13 @@
|
||||
#! @perl@ -w -I@libDir@ -I@readline@
|
||||
|
||||
use strict;
|
||||
use Machine;
|
||||
use Term::ReadLine;
|
||||
|
||||
$SIG{PIPE} = 'IGNORE'; # because Unix domain sockets may die unexpectedly
|
||||
|
||||
$ENV{PATH} = "@extraPath@:$ENV{PATH}";
|
||||
|
||||
STDERR->autoflush(1);
|
||||
|
||||
my %vms;
|
||||
@ -26,10 +31,13 @@ sub runTests {
|
||||
eval "$context $ENV{tests}";
|
||||
die $@ if $@;
|
||||
} else {
|
||||
while (<STDIN>) {
|
||||
my $term = Term::ReadLine->new('nixos-vm-test');
|
||||
$term->ReadHistory;
|
||||
while (defined ($_ = $term->readline("> "))) {
|
||||
eval "$context $_\n";
|
||||
warn $@ if $@;
|
||||
}
|
||||
$term->WriteHistory;
|
||||
}
|
||||
|
||||
# Copy the kernel coverage data for each machine, if the kernel
|
||||
|
@ -8,6 +8,27 @@ rec {
|
||||
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.
|
||||
# `network' must be the result of a call to the
|
||||
# `buildVirtualNetwork' function. `tests' is a Perl fragment
|
||||
@ -20,15 +41,13 @@ rec {
|
||||
|
||||
inherit tests;
|
||||
|
||||
buildInputs = [ pkgs.qemu_kvm pkgs.imagemagick ];
|
||||
buildInputs = [ pkgs.qemu_kvm ];
|
||||
|
||||
buildCommand =
|
||||
''
|
||||
mkdir $out
|
||||
cp ${./test-driver/Machine.pm} Machine.pm
|
||||
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
|
||||
ensureDir $out/coverage-data
|
||||
@ -98,13 +117,38 @@ rec {
|
||||
if t ? nodes then t.nodes else
|
||||
if t ? machine then { machine = t.machine; }
|
||||
else { };
|
||||
|
||||
vms = buildVirtualNetwork { inherit nodes; };
|
||||
test = runTests vms
|
||||
|
||||
testScript =
|
||||
# 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;
|
||||
|
||||
# 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 =
|
||||
{ drv
|
||||
, machine
|
||||
@ -140,7 +184,7 @@ rec {
|
||||
export PATH=${qemu_kvm}/bin:${coreutils}/bin
|
||||
cp ${./test-driver/Machine.pm} Machine.pm
|
||||
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
|
||||
@ -152,6 +196,7 @@ rec {
|
||||
origBuilder = attrs.builder;
|
||||
});
|
||||
|
||||
|
||||
runInMachineWithX = { require ? [], ...}@args :
|
||||
let
|
||||
client =
|
||||
@ -174,6 +219,7 @@ rec {
|
||||
'' ;
|
||||
} // args );
|
||||
|
||||
|
||||
simpleTest = as: (makeTest ({ ... }: as)).test;
|
||||
|
||||
}
|
||||
|
@ -10,10 +10,15 @@ let
|
||||
''
|
||||
#! ${pkgs.stdenv.shell}
|
||||
action="$1"
|
||||
if [ "$action" = "resume" ]; then
|
||||
${cfg.resumeCommands}
|
||||
${cfg.powerUpCommands}
|
||||
fi
|
||||
case "$action" in
|
||||
hibernate|suspend)
|
||||
${cfg.powerDownCommands}
|
||||
;;
|
||||
thaw|resume)
|
||||
${cfg.resumeCommands}
|
||||
${cfg.powerUpCommands}
|
||||
;;
|
||||
esac
|
||||
'';
|
||||
|
||||
in
|
||||
@ -50,6 +55,17 @@ in
|
||||
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()
|
||||
{
|
||||
echo "Usage: $0 -n network_expr -i infrastructure_expr"
|
||||
echo "Usage: $0 network_expr"
|
||||
echo "Options:"
|
||||
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 "--show-trace Shows the output trace"
|
||||
echo "-h,--help Shows the usage of this command"
|
||||
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 "-h,--help Shows the usage of this command"
|
||||
}
|
||||
|
||||
# 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 ]
|
||||
then
|
||||
@ -30,12 +30,12 @@ eval set -- "$PARAMS"
|
||||
while [ "$1" != "--" ]
|
||||
do
|
||||
case "$1" in
|
||||
-n|--network)
|
||||
networkExpr=`readlink -f $2`
|
||||
;;
|
||||
--use-backdoor)
|
||||
useBackdoorArg="--arg useBackdoor true"
|
||||
;;
|
||||
--no-out-link)
|
||||
noOutLinkArg="--no-out-link"
|
||||
;;
|
||||
--show-trace)
|
||||
showTraceArg="--show-trace"
|
||||
;;
|
||||
@ -48,19 +48,23 @@ do
|
||||
shift
|
||||
done
|
||||
|
||||
# Validate the given options
|
||||
shift
|
||||
|
||||
if [ "$networkExpr" = "" ]
|
||||
then
|
||||
echo "ERROR: A network expression must be specified!" >&2
|
||||
exit 1
|
||||
fi
|
||||
# Validate the given options
|
||||
|
||||
if [ -z "$NIXOS" ]
|
||||
then
|
||||
NIXOS=/etc/nixos/nixos
|
||||
fi
|
||||
|
||||
if [ "$@" = "" ]
|
||||
then
|
||||
echo "ERROR: A network expression must be specified!" >&2
|
||||
exit 1
|
||||
else
|
||||
networkExpr=$(readlink -f $@)
|
||||
fi
|
||||
|
||||
# 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
|
||||
, nixpkgs ? /etc/nixos/nixpkgs
|
||||
, networkExpr
|
||||
, infrastructureExpr
|
||||
, targetProperty ? "hostname"
|
||||
, targetProperty ? "targetHost"
|
||||
}:
|
||||
|
||||
let
|
||||
@ -12,19 +11,17 @@ let
|
||||
inherit (pkgs.lib) concatMapStrings;
|
||||
|
||||
network = import networkExpr;
|
||||
infrastructure = import infrastructureExpr;
|
||||
|
||||
generateRollbackSucceededPhase = network: infrastructure: configs:
|
||||
generateRollbackSucceededPhase = network: configs:
|
||||
concatMapStrings (configurationName:
|
||||
let
|
||||
infrastructureElement = getAttr configurationName infrastructure;
|
||||
config = getAttr configurationName configs;
|
||||
in
|
||||
''
|
||||
if [ "$rollback" != "$succeeded" ]
|
||||
then
|
||||
ssh $NIX_SSHOPTS ${getAttr targetProperty infrastructureElement} 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-env -p /nix/var/nix/profiles/system --rollback
|
||||
ssh $NIX_SSHOPTS ${getAttr targetProperty (config.deployment)} /nix/var/nix/profiles/system/bin/switch-to-configuration switch
|
||||
|
||||
rollback=$((rollback + 1))
|
||||
fi
|
||||
@ -32,33 +29,31 @@ let
|
||||
) (attrNames network)
|
||||
;
|
||||
|
||||
generateDistributionPhase = network: infrastructure: configs:
|
||||
generateDistributionPhase = network: configs:
|
||||
concatMapStrings (configurationName:
|
||||
let
|
||||
infrastructureElement = getAttr configurationName infrastructure;
|
||||
config = getAttr configurationName configs;
|
||||
in
|
||||
''
|
||||
echo "=== copy system closure to ${getAttr targetProperty infrastructureElement} ==="
|
||||
nix-copy-closure --to ${getAttr targetProperty infrastructureElement} ${config.system.build.toplevel}
|
||||
echo "=== copy system closure to ${getAttr targetProperty (config.deployment)} ==="
|
||||
nix-copy-closure --to ${getAttr targetProperty (config.deployment)} ${config.system.build.toplevel}
|
||||
''
|
||||
) (attrNames network)
|
||||
;
|
||||
|
||||
generateActivationPhase = network: infrastructure: configs:
|
||||
generateActivationPhase = network: configs:
|
||||
concatMapStrings (configurationName:
|
||||
let
|
||||
infrastructureElement = getAttr configurationName infrastructure;
|
||||
config = getAttr configurationName configs;
|
||||
in
|
||||
''
|
||||
echo "=== activating system configuration on ${getAttr targetProperty infrastructureElement} ==="
|
||||
ssh $NIX_SSHOPTS ${getAttr targetProperty infrastructureElement} 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)
|
||||
echo "=== activating system configuration on ${getAttr targetProperty (config.deployment)} ==="
|
||||
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 (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 infrastructureElement} 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 ||
|
||||
( ssh $NIX_SSHOPTS ${getAttr targetProperty (config.deployment)} nix-env -p /nix/var/nix/profiles/system --rollback
|
||||
ssh $NIX_SSHOPTS ${getAttr targetProperty (config.deployment)} /nix/var/nix/profiles/system/bin/switch-to-configuration switch
|
||||
rollbackSucceeded
|
||||
)
|
||||
|
||||
@ -67,25 +62,36 @@ let
|
||||
) (attrNames network)
|
||||
;
|
||||
|
||||
evaluateMachines = network: infrastructure:
|
||||
evaluateMachines = network:
|
||||
listToAttrs (map (configurationName:
|
||||
let
|
||||
configuration = getAttr configurationName network;
|
||||
system = (getAttr configurationName infrastructure).system;
|
||||
in
|
||||
{ name = configurationName;
|
||||
value = (import "${nixos}/lib/eval-config.nix" {
|
||||
inherit nixpkgs system;
|
||||
modules = [ configuration ];
|
||||
extraArgs = evaluateMachines network infrastructure;
|
||||
inherit nixpkgs;
|
||||
modules =
|
||||
[ 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; }
|
||||
) (attrNames (network)))
|
||||
;
|
||||
) (attrNames (network)));
|
||||
|
||||
configs = evaluateMachines network infrastructure;
|
||||
configs = evaluateMachines network;
|
||||
in
|
||||
pkgs.stdenv.mkDerivation {
|
||||
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 =
|
||||
''
|
||||
ensureDir $out/bin
|
||||
@ -95,18 +101,18 @@ pkgs.stdenv.mkDerivation {
|
||||
rollbackSucceeded()
|
||||
{
|
||||
rollback=0
|
||||
${generateRollbackSucceededPhase network infrastructure configs}
|
||||
${generateRollbackSucceededPhase network configs}
|
||||
}
|
||||
|
||||
# Distribution phase
|
||||
|
||||
${generateDistributionPhase network infrastructure configs}
|
||||
${generateDistributionPhase network configs}
|
||||
|
||||
# Activation phase
|
||||
|
||||
succeeded=0
|
||||
|
||||
${generateActivationPhase network infrastructure configs}
|
||||
${generateActivationPhase network configs}
|
||||
EOF
|
||||
chmod +x $out/bin/deploy-systems
|
||||
'';
|
||||
|
@ -4,18 +4,17 @@
|
||||
|
||||
showUsage()
|
||||
{
|
||||
echo "Usage: $0 -n network_expr -i infrastructure_expr"
|
||||
echo "Usage: $0 network_expr"
|
||||
echo "Options:"
|
||||
echo
|
||||
echo "-n,--network Network Nix expression which captures properties of machines in the network"
|
||||
echo "-i,--infrastructure Infrastructure Nix expression which captures properties of machines in the network"
|
||||
echo "--show-trace Shows an output trace"
|
||||
echo "-h,--help Shows the usage of this command"
|
||||
echo "--show-trace Shows an output trace"
|
||||
echo "--no-out-link Do not create a 'result' symlink"
|
||||
echo "-h,--help Shows the usage of this command"
|
||||
}
|
||||
|
||||
# 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 ]
|
||||
then
|
||||
@ -30,15 +29,12 @@ eval set -- "$PARAMS"
|
||||
while [ "$1" != "--" ]
|
||||
do
|
||||
case "$1" in
|
||||
-n|--network)
|
||||
networkExpr=`readlink -f $2`
|
||||
;;
|
||||
-i|--infrastructure)
|
||||
infrastructureExpr=`readlink -f $2`
|
||||
;;
|
||||
--show-trace)
|
||||
showTraceArg="--show-trace"
|
||||
;;
|
||||
--no-out-link)
|
||||
noOutLinkArg="--no-out-link"
|
||||
;;
|
||||
-h|--help)
|
||||
showUsage
|
||||
exit 0
|
||||
@ -48,27 +44,24 @@ do
|
||||
shift
|
||||
done
|
||||
|
||||
shift
|
||||
|
||||
# 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" ]
|
||||
then
|
||||
NIXOS=/etc/nixos/nixos
|
||||
fi
|
||||
|
||||
if [ "$@" = "" ]
|
||||
then
|
||||
echo "ERROR: A network Nix expression must be specified!" >&2
|
||||
exit 1
|
||||
else
|
||||
networkExpr=$(readlink -f $@)
|
||||
fi
|
||||
|
||||
# Deploy the network
|
||||
|
||||
nix-build $NIXOS/modules/installer/tools/nixos-deploy-network/deploy.nix --argstr networkExpr $networkExpr --argstr infrastructureExpr $infrastructureExpr $showTraceArg
|
||||
./result/bin/deploy-systems
|
||||
rm -f result
|
||||
vms=`nix-build $NIXOS/modules/installer/tools/nixos-deploy-network/deploy.nix --argstr networkExpr $networkExpr $showTraceArg $noOutLinkArg`
|
||||
$vms/bin/deploy-systems
|
||||
|
@ -7,6 +7,7 @@ use File::Basename;
|
||||
my @attrs = ();
|
||||
my @kernelModules = ();
|
||||
my @initrdKernelModules = ();
|
||||
my @modulePackages = ();
|
||||
|
||||
|
||||
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
|
||||
# due to missing firmware. Ideally we would check modules.pcimap
|
||||
# here.
|
||||
@ -222,6 +236,7 @@ sub multiLineList {
|
||||
|
||||
my $initrdKernelModules = toNixExpr(removeDups @initrdKernelModules);
|
||||
my $kernelModules = toNixExpr(removeDups @kernelModules);
|
||||
my $modulePackages = toNixExpr(removeDups @modulePackages);
|
||||
my $attrs = multiLineList(" ", removeDups @attrs);
|
||||
|
||||
print <<EOF ;
|
||||
@ -235,8 +250,12 @@ print <<EOF ;
|
||||
"\${modulesPath}/installer/scan/not-detected.nix"
|
||||
];
|
||||
|
||||
boot.initrd.kernelModules = [ $initrdKernelModules ];
|
||||
boot.kernelModules = [ $kernelModules ];
|
||||
boot = rec {
|
||||
initrd.kernelModules = [ $initrdKernelModules ];
|
||||
kernelModules = [ $kernelModules ];
|
||||
kernelPackages = pkgs.linuxPackages;
|
||||
extraModulePackages = [ $modulePackages ];
|
||||
};
|
||||
|
||||
nix.maxJobs = $cpus;
|
||||
|
||||
|
@ -4,20 +4,12 @@ with pkgs.lib;
|
||||
|
||||
{
|
||||
options = {
|
||||
|
||||
deployment = mkOption {
|
||||
deployment.targetHost = mkOption {
|
||||
default = config.networking.hostName;
|
||||
description = ''
|
||||
This option captures various custom attributes related to the configuration of the system, which
|
||||
are not directly used for building a system configuration. Usually these attributes
|
||||
are used by external tooling, such as the nixos-deploy-network tool or the Disnix Avahi
|
||||
publisher.
|
||||
This option specifies a hostname or IP address which can be used by nixos-deploy-network
|
||||
to execute remote deployment operations.
|
||||
'';
|
||||
default = {};
|
||||
example = {
|
||||
description = "My production machine";
|
||||
hostname = "my.test.org";
|
||||
country = "NL";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -58,6 +58,8 @@ in
|
||||
foldingAtHome = 37;
|
||||
sabnzbd = 38;
|
||||
kdm = 39;
|
||||
ghostOne = 40;
|
||||
git = 41;
|
||||
# When adding a uid, make sure it doesn't match an existing gid.
|
||||
|
||||
nixbld = 30000; # start of range of uids
|
||||
@ -98,6 +100,8 @@ in
|
||||
privoxy = 32;
|
||||
disnix = 33;
|
||||
osgi = 34;
|
||||
ghostOne = 40;
|
||||
git = 41;
|
||||
# When adding a gid, make sure it doesn't match an existing uid.
|
||||
|
||||
users = 100;
|
||||
|
@ -52,6 +52,7 @@
|
||||
./services/backup/sitecopy-backup.nix
|
||||
./services/databases/mysql.nix
|
||||
./services/databases/postgresql.nix
|
||||
./services/games/ghost-one.nix
|
||||
./services/hardware/acpid.nix
|
||||
./services/hardware/bluetooth.nix
|
||||
./services/hardware/hal.nix
|
||||
@ -91,6 +92,7 @@
|
||||
./services/networking/dhcpd.nix
|
||||
./services/networking/ejabberd.nix
|
||||
./services/networking/firewall.nix
|
||||
./services/networking/git-daemon.nix
|
||||
./services/networking/gnunet.nix
|
||||
./services/networking/gvpe.nix
|
||||
./services/networking/gw6c.nix
|
||||
@ -107,6 +109,7 @@
|
||||
./services/networking/ssh/sshd.nix
|
||||
./services/networking/tftpd.nix
|
||||
./services/networking/vsftpd.nix
|
||||
./services/networking/wakeonlan.nix
|
||||
./services/networking/wicd.nix
|
||||
./services/networking/wpa_supplicant.nix
|
||||
./services/networking/xinetd.nix
|
||||
|
@ -79,7 +79,7 @@ in zipModules ([]
|
||||
|
||||
# OpenSSH
|
||||
++ 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.forwardX11" "services.openssh.forwardX11"
|
||||
++ rename obsolete "services.sshd.gatewayPorts" "services.openssh.gatewayPorts"
|
||||
|
@ -66,7 +66,7 @@ in
|
||||
|
||||
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}
|
||||
chown root ${stateDir}
|
||||
|
105
modules/services/games/ghost-one.nix
Normal file
105
modules/services/games/ghost-one.nix
Normal file
@ -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";
|
||||
};
|
||||
|
||||
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 {
|
||||
default = false;
|
||||
description = "Whether to publish capabilities/properties as a Disnix service through Avahi";
|
||||
@ -47,62 +64,79 @@ in
|
||||
###### implementation
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
environment.systemPackages = [ pkgs.disnix ] ++ optional cfg.useWebServiceInterface pkgs.DisnixWebService;
|
||||
|
||||
services.dbus.enable = true;
|
||||
services.dbus.packages = [ pkgs.disnix ];
|
||||
|
||||
services.avahi.enable = cfg.publishAvahi;
|
||||
|
||||
services.tomcat.enable = cfg.useWebServiceInterface;
|
||||
services.tomcat.extraGroups = [ "disnix" ];
|
||||
services.tomcat.javaOpts = "${optionalString cfg.useWebServiceInterface "-Djava.library.path=${pkgs.libmatthew_java}/lib/jni"} ";
|
||||
services.tomcat.sharedLibs = []
|
||||
++ optional cfg.useWebServiceInterface "${pkgs.DisnixWebService}/share/java/DisnixConnection.jar"
|
||||
services.tomcat.sharedLibs = optional cfg.useWebServiceInterface "${pkgs.DisnixWebService}/share/java/DisnixConnection.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
|
||||
{ name = "disnix";
|
||||
gid = config.ids.gids.disnix;
|
||||
};
|
||||
|
||||
jobs.disnix =
|
||||
{ description = "Disnix server";
|
||||
|
||||
services.disnix.infrastructure =
|
||||
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 HOME=/root
|
||||
|
||||
${pkgs.disnix}/bin/disnix-service --activation-modules-dir=${disnix_activation_scripts}/libexec/disnix/activation-scripts
|
||||
'';
|
||||
};
|
||||
|
||||
} //
|
||||
mkIf cfg.publishAvahi {
|
||||
|
||||
services.avahi.enable = true;
|
||||
|
||||
jobs.disnixAvahi =
|
||||
{ description = "Disnix Avahi publisher";
|
||||
};
|
||||
} // optionalAttrs cfg.publishAvahi {
|
||||
disnixAvahi =
|
||||
{ description = "Disnix Avahi publisher";
|
||||
|
||||
startOn = "started avahi-daemon";
|
||||
startOn = "started avahi-daemon";
|
||||
|
||||
exec =
|
||||
''
|
||||
${pkgs.avahi}/bin/avahi-publish-service disnix-$(${pkgs.nettools}/bin/hostname) _disnix._tcp 22 \
|
||||
"hostname=\"$(${pkgs.nettools}/bin/hostname)\"" \
|
||||
"system=\"$(uname -m)-linux\"" \
|
||||
"mem=$(grep 'MemTotal:' /proc/meminfo | sed -e 's/kB//' -e 's/MemTotal://' -e 's/ //g')" \
|
||||
${optionalString (cfg.useWebServiceInterface) ''"targetEPR=\"http://(${pkgs.nettools}/bin/hostname):8080/DisnixWebService/services/DisnixWebService\""''} \
|
||||
${optionalString (config.services.httpd.enable) ''"documentRoot=\"${config.services.httpd.documentRoot}\""''} \
|
||||
${optionalString (config.services.mysql.enable) ''"mysqlPort=3306"''} \
|
||||
${optionalString (config.services.tomcat.enable) ''"tomcatPort=8080"''} \
|
||||
"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))}
|
||||
'';
|
||||
};
|
||||
exec =
|
||||
''
|
||||
${pkgs.avahi}/bin/avahi-publish-service disnix-${config.networking.hostName} _disnix._tcp 22 \
|
||||
"mem=$(grep 'MemTotal:' /proc/meminfo | sed -e 's/kB//' -e 's/MemTotal://' -e 's/ //g')" \
|
||||
"supportedTypes=[$(for i in ${disnix_activation_scripts}/libexec/disnix/activation-scripts/*; do echo -n " \"$(basename $i)\""; done) ]" \
|
||||
${concatMapStrings (infrastructureAttrName:
|
||||
let infrastructureAttrValue = getAttr infrastructureAttrName (cfg.infrastructure);
|
||||
in
|
||||
if builtins.isInt infrastructureAttrValue then
|
||||
''${infrastructureAttrName}=${infrastructureAttrValue} \
|
||||
''
|
||||
else
|
||||
''${infrastructureAttrName}=\"${infrastructureAttrValue}\" \
|
||||
''
|
||||
) (attrNames (cfg.infrastructure))}
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -5,6 +5,8 @@ with pkgs.lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.zabbixServer;
|
||||
|
||||
stateDir = "/var/run/zabbix";
|
||||
|
||||
logDir = "/var/log/zabbix";
|
||||
@ -19,9 +21,15 @@ let
|
||||
|
||||
PidFile = ${pidFile}
|
||||
|
||||
DBHost = ${cfg.dbServer}
|
||||
|
||||
DBName = zabbix
|
||||
|
||||
DBUser = zabbix
|
||||
|
||||
${optionalString (cfg.dbPassword != "") ''
|
||||
DBPassword = ${cfg.dbPassword}
|
||||
''}
|
||||
'';
|
||||
|
||||
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
|
||||
|
||||
config = mkIf config.services.zabbixServer.enable {
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
services.postgresql.enable = true;
|
||||
|
||||
|
@ -80,10 +80,10 @@ in
|
||||
# Only run dhclient on interfaces of type ARPHRD_ETHER
|
||||
# (1), i.e. Ethernet. Ignore peth* devices; on Xen,
|
||||
# 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 ! 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
|
||||
echo "Running dhclient on $i"
|
||||
interfaces="$interfaces $i"
|
||||
|
112
modules/services/networking/git-daemon.nix
Normal file
112
modules/services/networking/git-daemon.nix
Normal file
@ -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;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
56
modules/services/networking/wakeonlan.nix
Normal file
56
modules/services/networking/wakeonlan.nix
Normal file
@ -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";
|
||||
builder = pkgs.writeScript "additional-backends-builder.sh" ''
|
||||
PATH=${pkgs.coreutils}/bin
|
||||
mkdir -p $out
|
||||
mkdir -pv $out
|
||||
if [ ! -e ${pkgs.samba}/lib/cups/backend/smb ]; then
|
||||
mkdir -p $out/lib/cups/backend
|
||||
ln -s ${pkgs.samba}/bin/smbspool $out/lib/cups/backend/smb
|
||||
mkdir -pv $out/lib/cups/backend
|
||||
ln -sv ${pkgs.samba}/bin/smbspool $out/lib/cups/backend/smb
|
||||
fi
|
||||
|
||||
# Provide support for printing via HTTPS.
|
||||
if [ ! -e ${pkgs.cups}/lib/cups/backend/https ]; then
|
||||
mkdir -p $out/lib/cups/backend
|
||||
ln -s ${pkgs.cups}/lib/cups/backend/ipp $out/lib/cups/backend/https
|
||||
mkdir -pv $out/lib/cups/backend
|
||||
ln -sv ${pkgs.cups}/lib/cups/backend/ipp $out/lib/cups/backend/https
|
||||
fi
|
||||
'';
|
||||
};
|
||||
@ -147,7 +147,7 @@ in
|
||||
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 =
|
||||
''
|
||||
LogLevel info
|
||||
|
@ -57,17 +57,22 @@ let
|
||||
$wgArticlePath = "${config.articleUrlPrefix}/$1";
|
||||
''}
|
||||
|
||||
${optionalString config.enableUploads ''
|
||||
$wgEnableUploads = true;
|
||||
$wgUploadDirectory = "${config.uploadDir}";
|
||||
''}
|
||||
|
||||
${config.extraConfig}
|
||||
?>
|
||||
'';
|
||||
|
||||
# Unpack Mediawiki and put the config file in its root directory.
|
||||
mediawikiRoot = pkgs.stdenv.mkDerivation rec {
|
||||
name= "mediawiki-1.15.4";
|
||||
name= "mediawiki-1.15.5";
|
||||
|
||||
src = pkgs.fetchurl {
|
||||
url = "http://download.wikimedia.org/mediawiki/1.15/${name}.tar.gz";
|
||||
sha256 = "1blf79lhnaxixc8z96f9z4xi2jlg906ps3kd4x8b9ipg2dgl3vy9";
|
||||
sha256 = "1d8afbdh3lsg54b69mnh6a47psb3lg978xpp277qs08yz15cjf7q";
|
||||
};
|
||||
|
||||
buildPhase = "true";
|
||||
@ -96,6 +101,16 @@ in
|
||||
|
||||
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}
|
||||
|
||||
<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 {
|
||||
default = "";
|
||||
example =
|
||||
|
@ -29,9 +29,11 @@ with pkgs.lib;
|
||||
echo "[1;32m<<< System shutdown >>>[0m"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
${config.powerManagement.powerDownCommands}
|
||||
|
||||
export PATH=${pkgs.utillinux}/bin:${pkgs.utillinux}/sbin:$PATH
|
||||
|
||||
|
||||
|
||||
# Do an initial sync just in case.
|
||||
sync
|
||||
|
@ -185,7 +185,7 @@ let
|
||||
-m ${toString config.virtualisation.memorySize} \
|
||||
-net nic,vlan=0,model=virtio \
|
||||
-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.useBootLoader then ''
|
||||
-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.
|
||||
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 =
|
||||
[ "loglvl=all" "guest_loglvl=all" ] ++
|
||||
optional (cfg.domain0MemorySize != 0) "dom0_mem=${toString cfg.domain0MemorySize}M";
|
||||
|
@ -93,7 +93,7 @@ let
|
||||
''
|
||||
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;
|
||||
|
||||
${optionalString testChannel ''
|
||||
|
@ -4,7 +4,7 @@ let
|
||||
|
||||
client =
|
||||
{ config, pkgs, ... }:
|
||||
{ fileSystems = pkgs.lib.mkOverrideTemplate 50 {}
|
||||
{ fileSystems = pkgs.lib.mkOverride 50
|
||||
[ { mountPoint = "/data";
|
||||
device = "server:/data";
|
||||
fsType = "nfs";
|
||||
|
Loading…
Reference in New Issue
Block a user