Merge branch 'master' into staging

This commit is contained in:
Vladimír Čunát 2016-01-15 13:43:57 +01:00
commit 2d0893088f
769 changed files with 57706 additions and 23625 deletions

View File

@ -291,4 +291,340 @@ c = lib.makeOverridable f { a = 1; b = 2; }</programlisting>
</para> </para>
</section> </section>
<section xml:id="sec-pkgs-dockerTools">
<title>pkgs.dockerTools</title>
<para>
<varname>pkgs.dockerTools</varname> is a set of functions for creating and
manipulating Docker images according to the
<link xlink:href="https://github.com/docker/docker/blob/master/image/spec/v1.md#docker-image-specification-v100">
Docker Image Specification v1.0.0
</link>. Docker itself is not used to perform any of the operations done by these
functions.
</para>
<warning>
<para>
The <varname>dockerTools</varname> API is unstable and may be subject to
backwards-incompatible changes in the future.
</para>
</warning>
<section xml:id="ssec-pkgs-dockerTools-buildImage">
<title>buildImage</title>
<para>
This function is analogous to the <command>docker build</command> command,
in that can used to build a Docker-compatible repository tarball containing
a single image with one or multiple layers. As such, the result
is suitable for being loaded in Docker with <command>docker load</command>.
</para>
<para>
The parameters of <varname>buildImage</varname> with relative example values are
described below:
</para>
<example xml:id='ex-dockerTools-buildImage'><title>Docker build</title>
<programlisting>
buildImage {
name = "redis"; <co xml:id='ex-dockerTools-buildImage-1' />
tag = "latest"; <co xml:id='ex-dockerTools-buildImage-2' />
fromImage = someBaseImage; <co xml:id='ex-dockerTools-buildImage-3' />
fromImageName = null; <co xml:id='ex-dockerTools-buildImage-4' />
fromImageTag = "latest"; <co xml:id='ex-dockerTools-buildImage-5' />
contents = pkgs.redis; <co xml:id='ex-dockerTools-buildImage-6' />
runAsRoot = '' <co xml:id='ex-dockerTools-buildImage-runAsRoot' />
#!${stdenv.shell}
mkdir -p /data
'';
config = { <co xml:id='ex-dockerTools-buildImage-8' />
Cmd = [ "/bin/redis-server" ];
WorkingDir = "/data";
Volumes = {
"/data" = {};
};
};
}
</programlisting>
</example>
<para>The above example will build a Docker image <literal>redis/latest</literal>
from the given base image. Loading and running this image in Docker results in
<literal>redis-server</literal> being started automatically.
</para>
<calloutlist>
<callout arearefs='ex-dockerTools-buildImage-1'>
<para>
<varname>name</varname> specifies the name of the resulting image.
This is the only required argument for <varname>buildImage</varname>.
</para>
</callout>
<callout arearefs='ex-dockerTools-buildImage-2'>
<para>
<varname>tag</varname> specifies the tag of the resulting image.
By default it's <literal>latest</literal>.
</para>
</callout>
<callout arearefs='ex-dockerTools-buildImage-3'>
<para>
<varname>fromImage</varname> is the repository tarball containing the base image.
It must be a valid Docker image, such as exported by <command>docker save</command>.
By default it's <literal>null</literal>, which can be seen as equivalent
to <literal>FROM scratch</literal> of a <filename>Dockerfile</filename>.
</para>
</callout>
<callout arearefs='ex-dockerTools-buildImage-4'>
<para>
<varname>fromImageName</varname> can be used to further specify
the base image within the repository, in case it contains multiple images.
By default it's <literal>null</literal>, in which case
<varname>buildImage</varname> will peek the first image available
in the repository.
</para>
</callout>
<callout arearefs='ex-dockerTools-buildImage-5'>
<para>
<varname>fromImageTag</varname> can be used to further specify the tag
of the base image within the repository, in case an image contains multiple tags.
By default it's <literal>null</literal>, in which case
<varname>buildImage</varname> will peek the first tag available for the base image.
</para>
</callout>
<callout arearefs='ex-dockerTools-buildImage-6'>
<para>
<varname>contents</varname> is a derivation that will be copied in the new
layer of the resulting image. This can be similarly seen as
<command>ADD contents/ /</command> in a <filename>Dockerfile</filename>.
By default it's <literal>null</literal>.
</para>
</callout>
<callout arearefs='ex-dockerTools-buildImage-runAsRoot'>
<para>
<varname>runAsRoot</varname> is a bash script that will run as root
in an environment that overlays the existing layers of the base image with
the new resulting layer, including the previously copied
<varname>contents</varname> derivation.
This can be similarly seen as
<command>RUN ...</command> in a <filename>Dockerfile</filename>.
<note>
<para>
Using this parameter requires the <literal>kvm</literal>
device to be available.
</para>
</note>
</para>
</callout>
<callout arearefs='ex-dockerTools-buildImage-8'>
<para>
<varname>config</varname> is used to specify the configuration of the
containers that will be started off the built image in Docker.
The available options are listed in the
<link xlink:href="https://github.com/docker/docker/blob/master/image/spec/v1.md#container-runconfig-field-descriptions">
Docker Image Specification v1.0.0
</link>.
</para>
</callout>
</calloutlist>
<para>
After the new layer has been created, its closure
(to which <varname>contents</varname>, <varname>config</varname> and
<varname>runAsRoot</varname> contribute) will be copied in the layer itself.
Only new dependencies that are not already in the existing layers will be copied.
</para>
<para>
At the end of the process, only one new single layer will be produced and
added to the resulting image.
</para>
<para>
The resulting repository will only list the single image
<varname>image/tag</varname>. In the case of <xref linkend='ex-dockerTools-buildImage'/>
it would be <varname>redis/latest</varname>.
</para>
<para>
It is possible to inspect the arguments with which an image was built
using its <varname>buildArgs</varname> attribute.
</para>
</section>
<section xml:id="ssec-pkgs-dockerTools-fetchFromRegistry">
<title>pullImage</title>
<para>
This function is analogous to the <command>docker pull</command> command,
in that can be used to fetch a Docker image from a Docker registry.
Currently only registry <literal>v1</literal> is supported.
By default <link xlink:href="https://hub.docker.com/">Docker Hub</link>
is used to pull images.
</para>
<para>
Its parameters are described in the example below:
</para>
<example xml:id='ex-dockerTools-pullImage'><title>Docker pull</title>
<programlisting>
pullImage {
imageName = "debian"; <co xml:id='ex-dockerTools-pullImage-1' />
imageTag = "jessie"; <co xml:id='ex-dockerTools-pullImage-2' />
imageId = null; <co xml:id='ex-dockerTools-pullImage-3' />
sha256 = "1bhw5hkz6chrnrih0ymjbmn69hyfriza2lr550xyvpdrnbzr4gk2"; <co xml:id='ex-dockerTools-pullImage-4' />
indexUrl = "https://index.docker.io"; <co xml:id='ex-dockerTools-pullImage-5' />
registryUrl = "https://registry-1.docker.io";
registryVersion = "v1";
}
</programlisting>
</example>
<calloutlist>
<callout arearefs='ex-dockerTools-pullImage-1'>
<para>
<varname>imageName</varname> specifies the name of the image to be downloaded,
which can also include the registry namespace (e.g. <literal>library/debian</literal>).
This argument is required.
</para>
</callout>
<callout arearefs='ex-dockerTools-pullImage-2'>
<para>
<varname>imageTag</varname> specifies the tag of the image to be downloaded.
By default it's <literal>latest</literal>.
</para>
</callout>
<callout arearefs='ex-dockerTools-pullImage-3'>
<para>
<varname>imageId</varname>, if specified this exact image will be fetched, instead
of <varname>imageName/imageTag</varname>. However, the resulting repository
will still be named <varname>imageName/imageTag</varname>.
By default it's <literal>null</literal>.
</para>
</callout>
<callout arearefs='ex-dockerTools-pullImage-4'>
<para>
<varname>sha256</varname> is the checksum of the whole fetched image.
This argument is required.
</para>
<note>
<para>The checksum is computed on the unpacked directory, not on the final tarball.</para>
</note>
</callout>
<callout arearefs='ex-dockerTools-pullImage-5'>
<para>
In the above example the default values are shown for the variables <varname>indexUrl</varname>,
<varname>registryUrl</varname> and <varname>registryVersion</varname>.
Hence by default the Docker.io registry is used to pull the images.
</para>
</callout>
</calloutlist>
</section>
<section xml:id="ssec-pkgs-dockerTools-exportImage">
<title>exportImage</title>
<para>
This function is analogous to the <command>docker export</command> command,
in that can used to flatten a Docker image that contains multiple layers.
It is in fact the result of the merge of all the layers of the image.
As such, the result is suitable for being imported in Docker
with <command>docker import</command>.
</para>
<note>
<para>
Using this function requires the <literal>kvm</literal>
device to be available.
</para>
</note>
<para>
The parameters of <varname>exportImage</varname> are the following:
</para>
<example xml:id='ex-dockerTools-exportImage'><title>Docker export</title>
<programlisting>
exportImage {
fromImage = someLayeredImage;
fromImageName = null;
fromImageTag = null;
name = someLayeredImage.name;
}
</programlisting>
</example>
<para>
The parameters relative to the base image have the same synopsis as
described in <xref linkend='ssec-pkgs-dockerTools-buildImage'/>, except that
<varname>fromImage</varname> is the only required argument in this case.
</para>
<para>
The <varname>name</varname> argument is the name of the derivation output,
which defaults to <varname>fromImage.name</varname>.
</para>
</section>
<section xml:id="ssec-pkgs-dockerTools-shadowSetup">
<title>shadowSetup</title>
<para>
This constant string is a helper for setting up the base files for managing
users and groups, only if such files don't exist already.
It is suitable for being used in a
<varname>runAsRoot</varname> <xref linkend='ex-dockerTools-buildImage-runAsRoot'/> script for cases like
in the example below:
</para>
<example xml:id='ex-dockerTools-shadowSetup'><title>Shadow base files</title>
<programlisting>
buildImage {
name = "shadow-basic";
runAsRoot = ''
#!${stdenv.shell}
${shadowSetup}
groupadd -r redis
useradd -r -g redis redis
mkdir /data
chown redis:redis /data
'';
}
</programlisting>
</example>
<para>
Creating base files like <literal>/etc/passwd</literal> or
<literal>/etc/login.defs</literal> are necessary for shadow-utils to
manipulate users and groups.
</para>
</section>
</section>
</chapter> </chapter>

View File

@ -112,11 +112,6 @@ meta-attributes</title>
package.</para></listitem> package.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><varname>version</varname></term>
<listitem><para>Package version.</para></listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><varname>branch</varname></term> <term><varname>branch</varname></term>
<listitem><para>Release branch. Used to specify that a package is not <listitem><para>Release branch. Used to specify that a package is not

View File

@ -125,7 +125,7 @@ $ make menuconfig ARCH=<replaceable>arch</replaceable></screen>
<listitem> <listitem>
<para>It may be that the new kernel requires updating the external <para>It may be that the new kernel requires updating the external
kernel modules and kernel-dependent packages listed in the kernel modules and kernel-dependent packages listed in the
<varname>kernelPackagesFor</varname> function in <varname>linuxPackagesFor</varname> function in
<filename>all-packages.nix</filename> (such as the NVIDIA drivers, <filename>all-packages.nix</filename> (such as the NVIDIA drivers,
AUFS, etc.). If the updated packages arent backwards compatible AUFS, etc.). If the updated packages arent backwards compatible
with older kernels, you may need to keep the older versions with older kernels, you may need to keep the older versions

View File

@ -38,6 +38,7 @@
aycanirican = "Aycan iRiCAN <iricanaycan@gmail.com>"; aycanirican = "Aycan iRiCAN <iricanaycan@gmail.com>";
badi = "Badi' Abdul-Wahid <abdulwahidc@gmail.com>"; badi = "Badi' Abdul-Wahid <abdulwahidc@gmail.com>";
balajisivaraman = "Balaji Sivaraman<sivaraman.balaji@gmail.com>"; balajisivaraman = "Balaji Sivaraman<sivaraman.balaji@gmail.com>";
Baughn = "Svein Ove Aas <sveina@gmail.com>";
bbenoist = "Baptist BENOIST <return_0@live.com>"; bbenoist = "Baptist BENOIST <return_0@live.com>";
bcarrell = "Brandon Carrell <brandoncarrell@gmail.com>"; bcarrell = "Brandon Carrell <brandoncarrell@gmail.com>";
bcdarwin = "Ben Darwin <bcdarwin@gmail.com>"; bcdarwin = "Ben Darwin <bcdarwin@gmail.com>";
@ -264,7 +265,6 @@
robbinch = "Robbin C. <robbinch33@gmail.com>"; robbinch = "Robbin C. <robbinch33@gmail.com>";
robgssp = "Rob Glossop <robgssp@gmail.com>"; robgssp = "Rob Glossop <robgssp@gmail.com>";
roconnor = "Russell O'Connor <roconnor@theorem.ca>"; roconnor = "Russell O'Connor <roconnor@theorem.ca>";
roelof = "Roelof Wobben <rwobben@hotmail.com>";
romildo = "José Romildo Malaquias <malaquias@gmail.com>"; romildo = "José Romildo Malaquias <malaquias@gmail.com>";
rszibele = "Richard Szibele <richard_szibele@hotmail.com>"; rszibele = "Richard Szibele <richard_szibele@hotmail.com>";
rushmorem = "Rushmore Mushambi <rushmore@webenchanter.com>"; rushmorem = "Rushmore Mushambi <rushmore@webenchanter.com>";

View File

@ -189,9 +189,13 @@ rec {
versionAtLeast = v1: v2: !versionOlder v1 v2; versionAtLeast = v1: v2: !versionOlder v1 v2;
# Get the version of the specified derivation, as specified in its # This function takes an argument that's either a derivation or a
# name attribute. # derivation's "name" attribute and extracts the version part from that
getVersion = drv: (builtins.parseDrvName drv.name).version; # argument. For example:
#
# lib.getVersion "youtube-dl-2016.01.01" ==> "2016.01.01"
# lib.getVersion pkgs.youtube-dl ==> "2016.01.01"
getVersion = x: (builtins.parseDrvName (x.name or x)).version;
# Extract name with version from URL. Ask for separator which is # Extract name with version from URL. Ask for separator which is

View File

@ -18,8 +18,20 @@ NixOS will start wpa_supplicant for you if you enable this setting:
networking.wireless.enable = true; networking.wireless.enable = true;
</programlisting> </programlisting>
NixOS currently does not generate wpa_supplicant's NixOS lets you specify networks for wpa_supplicant declaratively:
configuration file, <literal>/etc/wpa_supplicant.conf</literal>. You should edit this file <programlisting>
networking.wireless.networks = {
echelon = {
psk = "abcdefgh";
};
"free.wifi" = {};
}
</programlisting>
Be aware that keys will be written to the nix store in plaintext!
When no networks are set, it will default to using a configuration file at
<literal>/etc/wpa_supplicant.conf</literal>. You should edit this file
yourself to define wireless networks, WPA keys and so on (see yourself to define wireless networks, WPA keys and so on (see
wpa_supplicant.conf(5)). wpa_supplicant.conf(5)).
</para> </para>

View File

@ -24,6 +24,17 @@ nixos.path = ./nixpkgs-unstable-2015-12-06/nixos;
<xref linkend="module-misc-nixos" /></para> <xref linkend="module-misc-nixos" /></para>
</listitem> </listitem>
<listitem>
<para>Firefox and similar browsers are now <emphasis>wrapped by default</emphasis>.
The package and attribute names are plain <literal>firefox</literal>
or <literal>midori</literal>, etc. Backward-compatibility attributes were set up,
but note that <command>nix-env -u</command> will <emphasis>not</emphasis> update
your current <literal>firefox-with-plugins</literal>;
you have to uninstall it and install <literal>firefox</literal> instead.
More discussion is <link xlink:href="https://github.com/NixOS/nixpkgs/pull/12299">
on the PR</link>. </para>
</listitem>
</itemizedlist> </itemizedlist>
<para>The following new services were added since the last release: <para>The following new services were added since the last release:
@ -47,6 +58,12 @@ following incompatible changes:</para>
</para> </para>
</listitem> </listitem>
<listitem>
<para><literal>jobs</literal> NixOS option has been removed. It served as
compatibility layer between Upstart jobs and SystemD services. All services
have been rewritten to use <literal>systemd.services</literal></para>
</listitem>
<listitem> <listitem>
<para><command>wmiimenu</command> is removed, as it has been <para><command>wmiimenu</command> is removed, as it has been
removed by the developers upstream. Use <command>wimenu</command> removed by the developers upstream. Use <command>wimenu</command>
@ -130,4 +147,17 @@ nginx.override {
</listitem> </listitem>
</itemizedlist> </itemizedlist>
<para>Other notable improvements:
<itemizedlist>
<listitem>
<para>The <command>command-not-found</command> hook was extended.
Apart from <literal>$NIX_AUTO_INSTALL</literal> variable,
it newly also checks for <literal>$NIX_AUTO_RUN</literal>
which causes it to directly run the missing commands via
<command>nix-shell</command> (without installing anything). </para>
</listitem>
</itemizedlist></para>
</section> </section>

View File

@ -128,6 +128,7 @@ in
wantedBy = [ "${realDevice'}.swap" ]; wantedBy = [ "${realDevice'}.swap" ];
before = [ "${realDevice'}.swap" ]; before = [ "${realDevice'}.swap" ];
path = [ pkgs.utillinux ] ++ optional sw.randomEncryption pkgs.cryptsetup; path = [ pkgs.utillinux ] ++ optional sw.randomEncryption pkgs.cryptsetup;
script = script =
'' ''
${optionalString (sw.size != null) '' ${optionalString (sw.size != null) ''
@ -145,11 +146,13 @@ in
mkswap ${sw.realDevice} mkswap ${sw.realDevice}
''} ''}
''; '';
unitConfig.RequiresMountsFor = [ "${dirOf sw.device}" ]; unitConfig.RequiresMountsFor = [ "${dirOf sw.device}" ];
unitConfig.DefaultDependencies = false; # needed to prevent a cycle unitConfig.DefaultDependencies = false; # needed to prevent a cycle
serviceConfig.Type = "oneshot"; serviceConfig.Type = "oneshot";
serviceConfig.RemainAfterExit = sw.randomEncryption; serviceConfig.RemainAfterExit = sw.randomEncryption;
serviceConfig.ExecStop = optionalString sw.randomEncryption "cryptsetup luksClose ${sw.deviceName}"; serviceConfig.ExecStop = optionalString sw.randomEncryption "${pkgs.cryptsetup}/bin/cryptsetup luksClose ${sw.deviceName}";
restartIfChanged = false;
}; };
in listToAttrs (map createSwapDevice (filter (sw: sw.size != null || sw.randomEncryption) config.swapDevices)); in listToAttrs (map createSwapDevice (filter (sw: sw.size != null || sw.randomEncryption) config.swapDevices));

View File

@ -1,15 +0,0 @@
{pkgs, config, ...}:
let
wis_go7007 = config.boot.kernelPackages.wis_go7007;
in
{
boot.extraModulePackages = [ wis_go7007 ];
environment.systemPackages = [ wis_go7007 ];
hardware.firmware = [ wis_go7007 ];
services.udev.packages = [ wis_go7007 ];
}

View File

@ -16,7 +16,7 @@ with lib;
]; ];
# ISO naming. # ISO naming.
isoImage.isoName = "${config.isoImage.isoBaseName}-${config.system.nixosVersion}-${pkgs.stdenv.system}.iso"; isoImage.isoName = "${config.isoImage.isoBaseName}-${config.system.nixosLabel}-${pkgs.stdenv.system}.iso";
isoImage.volumeID = substring 0 11 "NIXOS_ISO"; isoImage.volumeID = substring 0 11 "NIXOS_ISO";

View File

@ -39,7 +39,7 @@ let
DEFAULT boot DEFAULT boot
LABEL boot LABEL boot
MENU LABEL NixOS ${config.system.nixosVersion}${config.isoImage.appendToMenuLabel} MENU LABEL NixOS ${config.system.nixosLabel}${config.isoImage.appendToMenuLabel}
LINUX /boot/bzImage LINUX /boot/bzImage
APPEND init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams} APPEND init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}
INITRD /boot/initrd INITRD /boot/initrd

View File

@ -149,8 +149,7 @@ in
# not be started by default on the installation CD because the # not be started by default on the installation CD because the
# default root password is empty. # default root password is empty.
services.openssh.enable = true; services.openssh.enable = true;
systemd.services.openssh.wantedBy = lib.mkOverride 50 [];
jobs.openssh.startOn = lib.mkOverride 50 "";
boot.loader.grub.enable = false; boot.loader.grub.enable = false;
boot.loader.generationsDir.enable = false; boot.loader.generationsDir.enable = false;

View File

@ -164,7 +164,7 @@ in
# not be started by default on the installation CD because the # not be started by default on the installation CD because the
# default root password is empty. # default root password is empty.
services.openssh.enable = true; services.openssh.enable = true;
jobs.openssh.startOn = lib.mkOverride 50 ""; systemd.services.openssh.wantedBy = lib.mkOverride 50 [];
# cpufrequtils fails to build on non-pc # cpufrequtils fails to build on non-pc
powerManagement.enable = false; powerManagement.enable = false;

View File

@ -19,8 +19,6 @@ rollback=
upgrade= upgrade=
repair= repair=
profile=/nix/var/nix/profiles/system profile=/nix/var/nix/profiles/system
buildHost=
targetHost=
while [ "$#" -gt 0 ]; do while [ "$#" -gt 0 ]; do
i="$1"; shift 1 i="$1"; shift 1
@ -75,14 +73,6 @@ while [ "$#" -gt 0 ]; do
fi fi
shift 1 shift 1
;; ;;
--build-host|h)
buildHost="$1"
shift 1
;;
--target-host|t)
targetHost="$1"
shift 1
;;
*) *)
echo "$0: unknown option \`$i'" echo "$0: unknown option \`$i'"
exit 1 exit 1
@ -90,90 +80,6 @@ while [ "$#" -gt 0 ]; do
esac esac
done done
if [ -z "$buildHost" -a -n "$targetHost" ]; then
buildHost="$targetHost"
fi
if [ "$targetHost" = localhost ]; then
targetHost=
fi
if [ "$buildHost" = localhost ]; then
buildHost=
fi
buildHostCmd() {
if [ -z "$buildHost" ]; then
"$@"
elif [ -n "$remoteNix" ]; then
ssh $SSHOPTS "$buildHost" PATH="$remoteNix:$PATH" "$@"
else
ssh $SSHOPTS "$buildHost" "$@"
fi
}
targetHostCmd() {
if [ -z "$targetHost" ]; then
"$@"
else
ssh $SSHOPTS "$targetHost" "$@"
fi
}
copyToTarget() {
if ! [ "$targetHost" = "$buildHost" ]; then
if [ -z "$targetHost" ]; then
NIX_SSHOPTS=$SSH_OPTS nix-copy-closure --from "$buildHost" "$1"
elif [ -z "$buildHost" ]; then
NIX_SSHOPTS=$SSH_OPTS nix-copy-closure --to "$targetHost" "$1"
else
buildHostCmd nix-copy-closure --to "$targetHost" "$1"
fi
fi
}
nixBuild() {
if [ -z "$buildHost" ]; then
nix-build "$@"
else
local instArgs=()
local buildArgs=()
while [ "$#" -gt 0 ]; do
local i="$1"; shift 1
case "$i" in
-o)
local out="$1"; shift 1
buildArgs+=("--add-root" "$out" "--indirect")
;;
-A)
local j="$1"; shift 1
instArgs+=("$i" "$j")
;;
-I)
# We don't want this in buildArgs
shift 1
;;
"<"*) # nix paths
instArgs+=("$i")
;;
*)
buildArgs+=("$i")
;;
esac
done
local drv="$(nix-instantiate "${instArgs[@]}" "${extraBuildFlags[@]}")"
if [ -a "$drv" ]; then
NIX_SSHOPTS=$SSH_OPTS nix-copy-closure --to "$buildHost" "$drv"
buildHostCmd nix-store -r "$drv" "${buildArgs[@]}"
else
echo "nix-instantiate failed"
exit 1
fi
fi
}
if [ -z "$action" ]; then showSyntax; fi if [ -z "$action" ]; then showSyntax; fi
# Only run shell scripts from the Nixpkgs tree if the action is # Only run shell scripts from the Nixpkgs tree if the action is
@ -222,16 +128,7 @@ fi
tmpDir=$(mktemp -t -d nixos-rebuild.XXXXXX) tmpDir=$(mktemp -t -d nixos-rebuild.XXXXXX)
SSHOPTS="$NIX_SSHOPTS -o ControlMaster=auto -o ControlPath=$tmpDir/ssh-%n -o ControlPersist=60" trap 'rm -rf "$tmpDir"' EXIT
cleanup() {
for ctrl in "$tmpDir"/ssh-*; do
ssh -o ControlPath="$ctrl" -O exit dummyhost 2>/dev/null || true
done
rm -rf "$tmpDir"
}
trap cleanup EXIT
# If the Nix daemon is running, then use it. This allows us to use # If the Nix daemon is running, then use it. This allows us to use
@ -253,56 +150,30 @@ if [ -n "$rollback" -o "$action" = dry-build ]; then
buildNix= buildNix=
fi fi
prebuiltNix() {
machine="$1"
if [ "$machine" = x86_64 ]; then
return /nix/store/xryr9g56h8yjddp89d6dw12anyb4ch7c-nix-1.10
elif [[ "$machine" =~ i.86 ]]; then
return /nix/store/2w92k5wlpspf0q2k9mnf2z42prx3bwmv-nix-1.10
else
echo "$0: unsupported platform"
exit 1
fi
}
remotePATH=
if [ -n "$buildNix" ]; then if [ -n "$buildNix" ]; then
echo "building Nix..." >&2 echo "building Nix..." >&2
nixDrv= if ! nix-build '<nixpkgs/nixos>' -A config.nix.package -o $tmpDir/nix "${extraBuildFlags[@]}" > /dev/null; then
if ! nixDrv="$(nix-instantiate '<nixpkgs/nixos>' --add-root $tmpDir/nixdrv --indirect -A config.nix.package "${extraBuildFlags[@]}")"; then if ! nix-build '<nixpkgs/nixos>' -A nixFallback -o $tmpDir/nix "${extraBuildFlags[@]}" > /dev/null; then
if ! nixDrv="$(nix-instantiate '<nixpkgs/nixos>' --add-root $tmpDir/nixdrv --indirect -A nixFallback "${extraBuildFlags[@]}")"; then if ! nix-build '<nixpkgs>' -A nix -o $tmpDir/nix "${extraBuildFlags[@]}" > /dev/null; then
if ! nixDrv="$(nix-instantiate '<nixpkgs>' --add-root $tmpDir/nixdrv --indirect -A nix "${extraBuildFlags[@]}")"; then machine="$(uname -m)"
nixStorePath="$(prebuiltNix "$(uname -m)")" if [ "$machine" = x86_64 ]; then
nixStorePath=/nix/store/xryr9g56h8yjddp89d6dw12anyb4ch7c-nix-1.10
elif [[ "$machine" =~ i.86 ]]; then
nixStorePath=/nix/store/2w92k5wlpspf0q2k9mnf2z42prx3bwmv-nix-1.10
else
echo "$0: unsupported platform"
exit 1
fi
if ! nix-store -r $nixStorePath --add-root $tmpDir/nix --indirect \ if ! nix-store -r $nixStorePath --add-root $tmpDir/nix --indirect \
--option extra-binary-caches https://cache.nixos.org/; then --option extra-binary-caches https://cache.nixos.org/; then
echo "warning: don't know how to get latest Nix" >&2 echo "warning: don't know how to get latest Nix" >&2
fi fi
# Older version of nix-store -r don't support --add-root. # Older version of nix-store -r don't support --add-root.
[ -e $tmpDir/nix ] || ln -sf $nixStorePath $tmpDir/nix [ -e $tmpDir/nix ] || ln -sf $nixStorePath $tmpDir/nix
if [ -n "$buildHost" ]; then
remoteNixStorePath="$(prebuiltNix "$(buildHostCmd uname -m)")"
remoteNix="$remoteNixStorePath/bin"
if ! buildHostCmd nix-store -r $remoteNixStorePath \
--option extra-binary-caches https://cache.nixos.org/ >/dev/null; then
remoteNix=
echo "warning: don't know how to get latest Nix" >&2
fi
fi
fi fi
fi fi
fi fi
if [ -a "$nixDrv" ]; then PATH=$tmpDir/nix/bin:$PATH
nix-store -r "$nixDrv" --add-root $tmpDir/nix --indirect >/dev/null
if [ -n "$buildHost" ]; then
nix-copy-closure --to "$buildHost" "$nixDrv"
# The nix build produces multiple outputs, we add them all to the remote path
for p in $(buildHostCmd nix-store -r "$(readlink "$nixDrv")" "${buildArgs[@]}"); do
remoteNix="$remoteNix${remoteNix:+:}$p/bin"
done
fi
fi
PATH="$tmpDir/nix/bin:$PATH"
fi fi
@ -329,35 +200,31 @@ fi
if [ -z "$rollback" ]; then if [ -z "$rollback" ]; then
echo "building the system configuration..." >&2 echo "building the system configuration..." >&2
if [ "$action" = switch -o "$action" = boot ]; then if [ "$action" = switch -o "$action" = boot ]; then
pathToConfig="$(nixBuild '<nixpkgs/nixos>' -A system "${extraBuildFlags[@]}")" nix-env "${extraBuildFlags[@]}" -p "$profile" -f '<nixpkgs/nixos>' --set -A system
copyToTarget "$pathToConfig" pathToConfig="$profile"
targetHostCmd nix-env -p "$profile" --set "$pathToConfig"
elif [ "$action" = test -o "$action" = build -o "$action" = dry-build -o "$action" = dry-activate ]; then elif [ "$action" = test -o "$action" = build -o "$action" = dry-build -o "$action" = dry-activate ]; then
pathToConfig="$(nixBuild '<nixpkgs/nixos>' -A system -k "${extraBuildFlags[@]}")" nix-build '<nixpkgs/nixos>' -A system -k "${extraBuildFlags[@]}" > /dev/null
pathToConfig=./result
elif [ "$action" = build-vm ]; then elif [ "$action" = build-vm ]; then
pathToConfig="$(nixBuild '<nixpkgs/nixos>' -A vm -k "${extraBuildFlags[@]}")" nix-build '<nixpkgs/nixos>' -A vm -k "${extraBuildFlags[@]}" > /dev/null
pathToConfig=./result
elif [ "$action" = build-vm-with-bootloader ]; then elif [ "$action" = build-vm-with-bootloader ]; then
pathToConfig="$(nixBuild '<nixpkgs/nixos>' -A vmWithBootLoader -k "${extraBuildFlags[@]}")" nix-build '<nixpkgs/nixos>' -A vmWithBootLoader -k "${extraBuildFlags[@]}" > /dev/null
pathToConfig=./result
else else
showSyntax showSyntax
fi fi
# Copy build to target host if we haven't already done it
if ! [ "$action" = switch -o "$action" = boot ]; then
copyToTarget "$pathToConfig"
fi
else # [ -n "$rollback" ] else # [ -n "$rollback" ]
if [ "$action" = switch -o "$action" = boot ]; then if [ "$action" = switch -o "$action" = boot ]; then
targetHostCmd nix-env --rollback -p "$profile" nix-env --rollback -p "$profile"
pathToConfig="$profile" pathToConfig="$profile"
elif [ "$action" = test -o "$action" = build ]; then elif [ "$action" = test -o "$action" = build ]; then
systemNumber=$( systemNumber=$(
targetHostCmd nix-env -p "$profile" --list-generations | nix-env -p "$profile" --list-generations |
sed -n '/current/ {g; p;}; s/ *\([0-9]*\).*/\1/; h' sed -n '/current/ {g; p;}; s/ *\([0-9]*\).*/\1/; h'
) )
pathToConfig="$profile"-${systemNumber}-link ln -sT "$profile"-${systemNumber}-link ./result
if [ -z "$targetHost" ]; then pathToConfig=./result
ln -sT "$pathToConfig" ./result
fi
else else
showSyntax showSyntax
fi fi
@ -367,7 +234,7 @@ fi
# If we're not just building, then make the new configuration the boot # If we're not just building, then make the new configuration the boot
# default and/or activate it now. # default and/or activate it now.
if [ "$action" = switch -o "$action" = boot -o "$action" = test -o "$action" = dry-activate ]; then if [ "$action" = switch -o "$action" = boot -o "$action" = test -o "$action" = dry-activate ]; then
if ! targetHostCmd $pathToConfig/bin/switch-to-configuration "$action"; then if ! $pathToConfig/bin/switch-to-configuration "$action"; then
echo "warning: error(s) occurred while switching to the new configuration" >&2 echo "warning: error(s) occurred while switching to the new configuration" >&2
exit 1 exit 1
fi fi

View File

@ -136,7 +136,7 @@
kippo = 108; kippo = 108;
jenkins = 109; jenkins = 109;
systemd-journal-gateway = 110; systemd-journal-gateway = 110;
notbit = 111; #notbit = 111; # unused
ngircd = 112; ngircd = 112;
btsync = 113; btsync = 113;
minecraft = 114; minecraft = 114;
@ -240,6 +240,11 @@
pumpio = 216; pumpio = 216;
nm-openvpn = 217; nm-openvpn = 217;
mathics = 218; mathics = 218;
ejabberd = 219;
postsrsd = 220;
opendkim = 221;
dspam = 222;
gale = 223;
# When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399! # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
@ -356,7 +361,7 @@
kippo = 108; kippo = 108;
jenkins = 109; jenkins = 109;
systemd-journal-gateway = 110; systemd-journal-gateway = 110;
notbit = 111; #notbit = 111; # unused
#ngircd = 112; # unused #ngircd = 112; # unused
btsync = 113; btsync = 113;
#minecraft = 114; # unused #minecraft = 114; # unused
@ -457,6 +462,11 @@
pumpio = 216; pumpio = 216;
nm-openvpn = 217; nm-openvpn = 217;
mathics = 218; mathics = 218;
ejabberd = 219;
postsrsd = 220;
opendkim = 221;
dspam = 222;
gale = 223;
# When adding a gid, make sure it doesn't match an existing # When adding a gid, make sure it doesn't match an existing
# uid. Users and groups with the same name should have equal # uid. Users and groups with the same name should have equal

View File

@ -2,13 +2,21 @@
with lib; with lib;
let
cfg = config.system;
releaseFile = "${toString pkgs.path}/.version";
suffixFile = "${toString pkgs.path}/.version-suffix";
revisionFile = "${toString pkgs.path}/.git-revision";
in
{ {
options = { options.system = {
system.stateVersion = mkOption { stateVersion = mkOption {
type = types.str; type = types.str;
default = config.system.nixosRelease; default = cfg.nixosRelease;
description = '' description = ''
Every once in a while, a new NixOS release may change Every once in a while, a new NixOS release may change
configuration defaults in a way incompatible with stateful configuration defaults in a way incompatible with stateful
@ -22,38 +30,63 @@ with lib;
''; '';
}; };
system.nixosVersion = mkOption { nixosLabel = mkOption {
type = types.str;
description = ''
NixOS version name to be used in the names of generated
outputs and boot labels.
If you ever wanted to influence the labels in your GRUB menu,
this is option is for you.
Can be set directly or with <envar>NIXOS_LABEL</envar>
environment variable for <command>nixos-rebuild</command>,
e.g.:
<screen>
#!/bin/sh
today=`date +%Y%m%d`
branch=`(cd nixpkgs ; git branch 2>/dev/null | sed -n '/^\* / { s|^\* ||; p; }')`
revision=`(cd nixpkgs ; git rev-parse HEAD)`
export NIXOS_LABEL="$today.$branch-''${revision:0:7}"
nixos-rebuild switch</screen>
'';
};
nixosVersion = mkOption {
internal = true; internal = true;
type = types.str; type = types.str;
description = "NixOS version."; description = "NixOS version.";
}; };
system.nixosRelease = mkOption { nixosRelease = mkOption {
readOnly = true; readOnly = true;
type = types.str; type = types.str;
default = readFile "${toString pkgs.path}/.version"; default = readFile releaseFile;
description = "NixOS release."; description = "NixOS release.";
}; };
system.nixosVersionSuffix = mkOption { nixosVersionSuffix = mkOption {
internal = true; internal = true;
type = types.str; type = types.str;
default = if pathExists suffixFile then readFile suffixFile else "pre-git";
description = "NixOS version suffix."; description = "NixOS version suffix.";
}; };
system.nixosRevision = mkOption { nixosRevision = mkOption {
internal = true; internal = true;
type = types.str; type = types.str;
default = if pathExists revisionFile then readFile revisionFile else "master";
description = "NixOS Git revision hash."; description = "NixOS Git revision hash.";
}; };
system.nixosCodeName = mkOption { nixosCodeName = mkOption {
readOnly = true; readOnly = true;
type = types.str; type = types.str;
description = "NixOS release code name."; description = "NixOS release code name.";
}; };
system.defaultChannel = mkOption { defaultChannel = mkOption {
internal = true; internal = true;
type = types.str; type = types.str;
default = https://nixos.org/channels/nixos-unstable; default = https://nixos.org/channels/nixos-unstable;
@ -64,18 +97,15 @@ with lib;
config = { config = {
system.nixosVersion = mkDefault (config.system.nixosRelease + config.system.nixosVersionSuffix); system = {
# These defaults are set here rather than up there so that
# changing them would not rebuild the manual
nixosLabel = mkDefault (maybeEnv "NIXOS_LABEL" cfg.nixosVersion);
nixosVersion = mkDefault (maybeEnv "NIXOS_VERSION" (cfg.nixosRelease + cfg.nixosVersionSuffix));
system.nixosVersionSuffix = # Note: code names must only increase in alphabetical order.
let suffixFile = "${toString pkgs.path}/.version-suffix"; in nixosCodeName = "Emu";
mkDefault (if pathExists suffixFile then readFile suffixFile else "pre-git"); };
system.nixosRevision =
let fn = "${toString pkgs.path}/.git-revision"; in
mkDefault (if pathExists fn then readFile fn else "master");
# Note: code names must only increase in alphabetical order.
system.nixosCodeName = "Emu";
# Generate /etc/os-release. See # Generate /etc/os-release. See
# http://0pointer.de/public/systemd-man/os-release.html for the # http://0pointer.de/public/systemd-man/os-release.html for the

View File

@ -64,6 +64,7 @@
./programs/dconf.nix ./programs/dconf.nix
./programs/environment.nix ./programs/environment.nix
./programs/freetds.nix ./programs/freetds.nix
./programs/fish.nix
./programs/ibus.nix ./programs/ibus.nix
./programs/kbdlight.nix ./programs/kbdlight.nix
./programs/light.nix ./programs/light.nix
@ -83,6 +84,7 @@
./security/acme.nix ./security/acme.nix
./security/apparmor.nix ./security/apparmor.nix
./security/apparmor-suid.nix ./security/apparmor-suid.nix
./security/audit.nix
./security/ca.nix ./security/ca.nix
./security/duosec.nix ./security/duosec.nix
./security/grsecurity.nix ./security/grsecurity.nix
@ -98,8 +100,6 @@
./services/amqp/activemq/default.nix ./services/amqp/activemq/default.nix
./services/amqp/rabbitmq.nix ./services/amqp/rabbitmq.nix
./services/audio/alsa.nix ./services/audio/alsa.nix
# Disabled as fuppes no longer builds.
# ./services/audio/fuppes.nix
./services/audio/icecast.nix ./services/audio/icecast.nix
./services/audio/liquidsoap.nix ./services/audio/liquidsoap.nix
./services/audio/mpd.nix ./services/audio/mpd.nix
@ -162,6 +162,7 @@
./services/hardware/bluetooth.nix ./services/hardware/bluetooth.nix
./services/hardware/brltty.nix ./services/hardware/brltty.nix
./services/hardware/freefall.nix ./services/hardware/freefall.nix
./services/hardware/irqbalance.nix
./services/hardware/nvidia-optimus.nix ./services/hardware/nvidia-optimus.nix
./services/hardware/pcscd.nix ./services/hardware/pcscd.nix
./services/hardware/pommed.nix ./services/hardware/pommed.nix
@ -182,12 +183,15 @@
./services/logging/syslogd.nix ./services/logging/syslogd.nix
./services/logging/syslog-ng.nix ./services/logging/syslog-ng.nix
./services/mail/dovecot.nix ./services/mail/dovecot.nix
./services/mail/dspam.nix
./services/mail/exim.nix ./services/mail/exim.nix
./services/mail/freepops.nix ./services/mail/freepops.nix
./services/mail/mail.nix ./services/mail/mail.nix
./services/mail/mlmmj.nix ./services/mail/mlmmj.nix
./services/mail/opendkim.nix
./services/mail/opensmtpd.nix ./services/mail/opensmtpd.nix
./services/mail/postfix.nix ./services/mail/postfix.nix
./services/mail/postsrsd.nix
./services/mail/spamassassin.nix ./services/mail/spamassassin.nix
./services/misc/apache-kafka.nix ./services/misc/apache-kafka.nix
./services/misc/autofs.nix ./services/misc/autofs.nix
@ -297,6 +301,7 @@
./services/networking/firewall.nix ./services/networking/firewall.nix
./services/networking/flashpolicyd.nix ./services/networking/flashpolicyd.nix
./services/networking/freenet.nix ./services/networking/freenet.nix
./services/networking/gale.nix
./services/networking/gateone.nix ./services/networking/gateone.nix
./services/networking/git-daemon.nix ./services/networking/git-daemon.nix
./services/networking/gnunet.nix ./services/networking/gnunet.nix
@ -322,7 +327,6 @@
./services/networking/networkmanager.nix ./services/networking/networkmanager.nix
./services/networking/ngircd.nix ./services/networking/ngircd.nix
./services/networking/nix-serve.nix ./services/networking/nix-serve.nix
./services/networking/notbit.nix
./services/networking/nsd.nix ./services/networking/nsd.nix
./services/networking/ntopng.nix ./services/networking/ntopng.nix
./services/networking/ntpd.nix ./services/networking/ntpd.nix
@ -331,6 +335,7 @@
./services/networking/openfire.nix ./services/networking/openfire.nix
./services/networking/openntpd.nix ./services/networking/openntpd.nix
./services/networking/openvpn.nix ./services/networking/openvpn.nix
./services/networking/ostinato.nix
./services/networking/polipo.nix ./services/networking/polipo.nix
./services/networking/prayer.nix ./services/networking/prayer.nix
./services/networking/privoxy.nix ./services/networking/privoxy.nix
@ -475,7 +480,6 @@
./system/boot/timesyncd.nix ./system/boot/timesyncd.nix
./system/boot/tmp.nix ./system/boot/tmp.nix
./system/etc/etc.nix ./system/etc/etc.nix
./system/upstart/upstart.nix
./tasks/bcache.nix ./tasks/bcache.nix
./tasks/cpu-freq.nix ./tasks/cpu-freq.nix
./tasks/encrypted-devices.nix ./tasks/encrypted-devices.nix

View File

@ -51,7 +51,7 @@ with lib;
# Enable wpa_supplicant, but don't start it by default. # Enable wpa_supplicant, but don't start it by default.
networking.wireless.enable = mkDefault true; networking.wireless.enable = mkDefault true;
jobs.wpa_supplicant.startOn = mkOverride 50 ""; systemd.services.wpa_supplicant.wantedBy = mkOverride 50 [];
# Tell the Nix evaluator to garbage collect more aggressively. # Tell the Nix evaluator to garbage collect more aggressively.
# This is desirable in memory-constrained environments that don't # This is desirable in memory-constrained environments that don't

View File

@ -38,7 +38,7 @@ in {
config = mkIf cfg.enable { config = mkIf cfg.enable {
boot = { boot = {
extraModulePackages = [ pkgs.linuxPackages.vhba ]; extraModulePackages = [ config.boot.kernelPackages.vhba ];
kernelModules = [ "vhba" ]; kernelModules = [ "vhba" ];
}; };

View File

@ -0,0 +1,114 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfge = config.environment;
cfg = config.programs.fish;
fishAliases = concatStringsSep "\n" (
mapAttrsFlatten (k: v: "alias ${k} '${v}'") cfg.shellAliases
);
in
{
options = {
programs.fish = {
enable = mkOption {
default = false;
description = ''
Whether to configure fish as an interactive shell.
'';
type = types.bool;
};
shellAliases = mkOption {
default = config.environment.shellAliases;
description = ''
Set of aliases for fish shell. See <option>environment.shellAliases</option>
for an option format description.
'';
type = types.attrs;
};
shellInit = mkOption {
default = "";
description = ''
Shell script code called during fish shell initialisation.
'';
type = types.lines;
};
loginShellInit = mkOption {
default = "";
description = ''
Shell script code called during fish login shell initialisation.
'';
type = types.lines;
};
interactiveShellInit = mkOption {
default = "";
description = ''
Shell script code called during interactive fish shell initialisation.
'';
type = types.lines;
};
promptInit = mkOption {
default = "";
description = ''
Shell script code used to initialise fish prompt.
'';
type = types.lines;
};
};
};
config = mkIf cfg.enable {
environment.etc."fish/foreign-env/shellInit".text = cfge.shellInit;
environment.etc."fish/foreign-env/loginShellInit".text = cfge.loginShellInit;
environment.etc."fish/foreign-env/interactiveShellInit".text = cfge.interactiveShellInit;
environment.etc."fish/config.fish".text = ''
# /etc/fish/config.fish: DO NOT EDIT -- this file has been generated automatically.
set fish_function_path $fish_function_path ${pkgs.fish-foreign-env}/share/fish-foreign-env/functions
fenv source ${config.system.build.setEnvironment} 1> /dev/null
fenv source /etc/fish/foreign-env/shellInit 1> /dev/null
${cfg.shellInit}
if builtin status --is-login
fenv source /etc/fish/foreign-env/loginShellInit 1> /dev/null
${cfg.loginShellInit}
end
if builtin status --is-interactive
${fishAliases}
fenv source /etc/fish/foreign-env/interactiveShellInit 1> /dev/null
${cfg.interactiveShellInit}
end
'';
environment.systemPackages = [ pkgs.fish ];
environment.shells = [
"/run/current-system/sw/bin/fish"
"/var/run/current-system/sw/bin/fish"
"${pkgs.fish}/bin/fish"
];
};
}

View File

@ -14,6 +14,20 @@ with lib;
(mkRenamedOptionModule [ "networking" "enableWLAN" ] [ "networking" "wireless" "enable" ]) (mkRenamedOptionModule [ "networking" "enableWLAN" ] [ "networking" "wireless" "enable" ])
(mkRenamedOptionModule [ "networking" "enableRT73Firmware" ] [ "networking" "enableRalinkFirmware" ]) (mkRenamedOptionModule [ "networking" "enableRT73Firmware" ] [ "networking" "enableRalinkFirmware" ])
(mkRenamedOptionModule [ "services" "cadvisor" "host" ] [ "services" "cadvisor" "listenAddress" ])
(mkRenamedOptionModule [ "services" "dockerRegistry" "host" ] [ "services" "dockerRegistry" "listenAddress" ])
(mkRenamedOptionModule [ "services" "elasticsearch" "host" ] [ "services" "elasticsearch" "listenAddress" ])
(mkRenamedOptionModule [ "services" "graphite" "api" "host" ] [ "services" "graphite" "api" "listenAddress" ])
(mkRenamedOptionModule [ "services" "graphite" "web" "host" ] [ "services" "graphite" "web" "listenAddress" ])
(mkRenamedOptionModule [ "services" "kibana" "host" ] [ "services" "kibana" "listenAddress" ])
(mkRenamedOptionModule [ "services" "mpd" "network" "host" ] [ "services" "mpd" "network" "listenAddress" ])
(mkRenamedOptionModule [ "services" "neo4j" "host" ] [ "services" "neo4j" "listenAddress" ])
(mkRenamedOptionModule [ "services" "shout" "host" ] [ "services" "shout" "listenAddress" ])
(mkRenamedOptionModule [ "services" "sslh" "host" ] [ "services" "sslh" "listenAddress" ])
(mkRenamedOptionModule [ "services" "statsd" "host" ] [ "services" "statsd" "listenAddress" ])
(mkRenamedOptionModule [ "services" "subsonic" "host" ] [ "services" "subsonic" "listenAddress" ])
(mkRenamedOptionModule [ "jobs" ] [ "systemd" "services" ])
# Old Grub-related options. # Old Grub-related options.
(mkRenamedOptionModule [ "boot" "initrd" "extraKernelModules" ] [ "boot" "initrd" "kernelModules" ]) (mkRenamedOptionModule [ "boot" "initrd" "extraKernelModules" ] [ "boot" "initrd" "kernelModules" ])
(mkRenamedOptionModule [ "boot" "extraKernelParams" ] [ "boot" "kernelParams" ]) (mkRenamedOptionModule [ "boot" "extraKernelParams" ] [ "boot" "kernelParams" ])

View File

@ -37,6 +37,12 @@ let
description = "Group running the ACME client."; description = "Group running the ACME client.";
}; };
allowKeysForGroup = mkOption {
type = types.bool;
default = false;
description = "Give read permissions to the specified group to read SSL private certificates.";
};
postRun = mkOption { postRun = mkOption {
type = types.lines; type = types.lines;
default = ""; default = "";
@ -137,6 +143,7 @@ in
systemd.services = flip mapAttrs' cfg.certs (cert: data: systemd.services = flip mapAttrs' cfg.certs (cert: data:
let let
cpath = "${cfg.directory}/${cert}"; cpath = "${cfg.directory}/${cert}";
rights = if data.allowKeysForGroup then "750" else "700";
cmdline = [ "-v" "-d" cert "--default_root" data.webroot "--valid_min" cfg.validMin ] cmdline = [ "-v" "-d" cert "--default_root" data.webroot "--valid_min" cfg.validMin ]
++ optionals (data.email != null) [ "--email" data.email ] ++ optionals (data.email != null) [ "--email" data.email ]
++ concatMap (p: [ "-f" p ]) data.plugins ++ concatMap (p: [ "-f" p ]) data.plugins
@ -159,9 +166,10 @@ in
preStart = '' preStart = ''
mkdir -p '${cfg.directory}' mkdir -p '${cfg.directory}'
if [ ! -d '${cpath}' ]; then if [ ! -d '${cpath}' ]; then
mkdir -m 700 '${cpath}' mkdir '${cpath}'
chown '${data.user}:${data.group}' '${cpath}'
fi fi
chmod ${rights} '${cpath}'
chown -R '${data.user}:${data.group}' '${cpath}'
''; '';
script = '' script = ''
cd '${cpath}' cd '${cpath}'

View File

@ -0,0 +1,109 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.security.audit;
failureModes = {
silent = 0;
printk = 1;
panic = 2;
};
# TODO: it seems like people like their rules to be somewhat secret, yet they will not be if
# put in the store like this. At the same time, it doesn't feel like a huge deal and working
# around that is a pain so I'm leaving it like this for now.
startScript = pkgs.writeScript "audit-start" ''
#!${pkgs.stdenv.shell} -eu
# Clear out any rules we may start with
auditctl -D
# Put the rules in a temporary file owned and only readable by root
rulesfile="$(mktemp)"
${concatMapStrings (x: "echo '${x}' >> $rulesfile\n") cfg.rules}
# Apply the requested rules
auditctl -R "$rulesfile"
# Enable and configure auditing
auditctl \
-e ${if cfg.enable == "lock" then "2" else "1"} \
-b ${toString cfg.backlogLimit} \
-f ${toString failureModes.${cfg.failureMode}} \
-r ${toString cfg.rateLimit}
'';
stopScript = pkgs.writeScript "audit-stop" ''
#!${pkgs.stdenv.shell} -eu
# Clear the rules
auditctl -D
# Disable auditing
auditctl -e 0
'';
in {
options = {
security.audit = {
enable = mkOption {
type = types.enum [ false true "lock" ];
default = true; # The kernel seems to enable it by default with no rules anyway
description = ''
Whether to enable the Linux audit system. The special `lock' value can be used to
enable auditing and prevent disabling it until a restart. Be careful about locking
this, as it will prevent you from changing your audit configuration until you
restart. If possible, test your configuration using build-vm beforehand.
'';
};
failureMode = mkOption {
type = types.enum [ "silent" "printk" "panic" ];
default = "printk";
description = "How to handle critical errors in the auditing system";
};
backlogLimit = mkOption {
type = types.int;
default = 64; # Apparently the kernel default
description = ''
The maximum number of outstanding audit buffers allowed; exceeding this is
considered a failure and handled in a manner specified by failureMode.
'';
};
rateLimit = mkOption {
type = types.int;
default = 0;
description = ''
The maximum messages per second permitted before triggering a failure as
specified by failureMode. Setting it to zero disables the limit.
'';
};
rules = mkOption {
type = types.listOf types.str; # (types.either types.str (types.submodule rule));
default = [];
example = [ "-a exit,always -F arch=b64 -S execve" ];
description = ''
The ordered audit rules, with each string appearing as one line of the audit.rules file.
'';
};
};
};
config = mkIf (cfg.enable == "lock" || cfg.enable) {
systemd.services.audit = {
description = "pseudo-service representing the kernel audit state";
wantedBy = [ "basic.target" ];
path = [ pkgs.audit ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
ExecStart = "@${startScript} audit-start";
ExecStop = "@${stopScript} audit-stop";
};
};
};
}

View File

@ -1,115 +0,0 @@
{ config, lib, pkgs, ... }:
let
cfg = config.services.fuppesd;
in
with lib;
{
options = {
services.fuppesd = {
enable = mkOption {
default = false;
type = with types; bool;
description = ''
Enables Fuppes (UPnP A/V Media Server). Can be used to watch
photos, video and listen to music from a phone/tv connected to the
local network.
'';
};
name = mkOption {
example = "Media Center";
type = types.str;
description = ''
Enables Fuppes (UPnP A/V Media Server). Can be used to watch
photos, video and listen to music from a phone/tv connected to the
local network.
'';
};
log = {
level = mkOption {
default = 0;
example = 3;
type = with types; uniq int;
description = ''
Logging level of fuppes, An integer between 0 and 3.
'';
};
file = mkOption {
default = "/var/log/fuppes.log";
type = types.str;
description = ''
File which will contains the log produced by the daemon.
'';
};
};
config = mkOption {
example = "/etc/fuppes/fuppes.cfg";
type = types.str;
description = ''
Mutable configuration file which can be edited with the web
interface. Due to possible modification, double quote the full
path of the filename stored in your filesystem to avoid attempts
to modify the content of the nix store.
'';
};
vfolder = mkOption {
example = literalExample "/etc/fuppes/vfolder.cfg";
description = ''
XML file describing the layout of virtual folder visible by the
client.
'';
};
database = mkOption {
default = "/var/lib/fuppes/fuppes.db";
type = types.str;
description = ''
Database file which index all shared files.
'';
};
## At the moment, no plugins are packaged.
/*
plugins = mkOption {
type = with types; listOf package;
description = ''
List of Fuppes plugins.
'';
};
*/
user = mkOption {
default = "root"; # The default is not secure.
example = "fuppes";
type = types.str;
description = ''
Name of the user which own the configuration files and under which
the fuppes daemon will be executed.
'';
};
};
};
config = mkIf cfg.enable {
jobs.fuppesd = {
description = "UPnP A/V Media Server. (${cfg.name})";
startOn = "ip-up";
daemonType = "fork";
exec = ''/var/setuid-wrappers/sudo -u ${cfg.user} -- ${pkgs.fuppes}/bin/fuppesd --friendly-name ${cfg.name} --log-level ${toString cfg.log.level} --log-file ${cfg.log.file} --config-file ${cfg.config} --vfolder-config-file ${cfg.vfolder} --database-file ${cfg.database}'';
};
services.fuppesd.name = mkDefault config.networking.hostName;
services.fuppesd.vfolder = mkDefault ./fuppes/vfolder.cfg;
security.sudo.enable = true;
};
}

View File

@ -1,155 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<fuppes_vfolder_config version="0.2">
<vfolder_layout device="default" enabled="false">
<vfolder name="Genre">
<vfolders property="genre">
<items type="audioItem" />
</vfolders>
</vfolder>
<vfolder name="Genre/Artists">
<vfolders property="genre">
<vfolders property="artist">
<items type="audioItem" />
</vfolders>
</vfolders>
</vfolder>
<vfolder name="Artists/Albums">
<vfolders property="artist">
<vfolders property="album">
<items type="audioItem" />
</vfolders>
</vfolders>
</vfolder>
<vfolder name="ABC/Artists/Albums">
<vfolders split="ABC">
<vfolders property="artist">
<vfolders property="album">
<items type="audioItem" />
</vfolders>
</vfolders>
</vfolders>
</vfolder>
<vfolder name="Photos">
<vfolder name="All">
<items type="imageItem" />
</vfolder>
<vfolder name="Folders">
<folders filter="contains(imageItem)" />
</vfolder>
</vfolder>
<vfolder name="Videos">
<vfolder name="All">
<items type="videoItem" />
</vfolder>
<vfolder name="Folders">
<folders filter="contains(videoItem)" />
</vfolder>
</vfolder>
<vfolder name="shared dirs">
<shared_dirs full_extend="true" />
</vfolder>
</vfolder_layout>
<vfolder_layout device="Xbox 360" enabled="false">
<vfolder name="Music" id="1">
<vfolder name="Album" id="7">
<vfolders property="album">
<items type="audioItem" />
</vfolders>
</vfolder>
<vfolder name="All Music" id="4">
<items type="audioItem" />
</vfolder>
<vfolder name="Artist" id="6">
<vfolders property="artist">
<items type="audioItem" />
</vfolders>
</vfolder>
<vfolder name="Folders" id="20">
<folders filter="contains(audioItem)" />
</vfolder>
<vfolder name="Genre" id="5">
<vfolders property="genre">
<items type="audioItem" />
</vfolders>
</vfolder>
<vfolder name="Playlist" id="15" />
</vfolder>
<vfolder name="Pictures" id="3">
<vfolder name="Album" id="13" />
<vfolder name="All Pictures" id="11">
<items type="imageItem" />
</vfolder>
<vfolder name="Date Taken" id="12" />
<vfolder name="Folders" id="22">
<folders filter="contains(imageItem)" />
</vfolder>
</vfolder>
<vfolder name="Playlists" id="18">
<vfolder name="All Playlists" id="19" />
<vfolder name="Folders" id="23" />
</vfolder>
<vfolder name="Video" id="2">
<vfolder name="Actor" id="10" />
<vfolder name="Album" id="14" />
<vfolder name="All Video" id="8">
<items type="videoItem" />
</vfolder>
<vfolder name="Folders" id="21">
<folders filter="contains(videoItem)" />
</vfolder>
<vfolder name="Genre" id="9" />
</vfolder>
</vfolder_layout>
<vfolder_layout device="Yamaha" enabled="false" create_references="true" >
<vfolder name="Playlists" />
<vfolder name="Artists">
<vfolders property="artist">
<items type="audioItem" />
</vfolders>
</vfolder>
<vfolder name="Albums">
<vfolders property="album">
<items type="audioItem" />
</vfolders>
</vfolder>
<vfolder name="Songs">
<items type="audioItem" />
</vfolder>
<vfolder name="Genres">
<vfolders property="genre">
<items type="audioItem" />
</vfolders>
</vfolder>
</vfolder_layout>
</fuppes_vfolder_config>

View File

@ -18,7 +18,7 @@ let
user "${cfg.user}" user "${cfg.user}"
group "${cfg.group}" group "${cfg.group}"
${optionalString (cfg.network.host != "any") ''bind_to_address "${cfg.network.host}"''} ${optionalString (cfg.network.listenAddress != "any") ''bind_to_address "${cfg.network.listenAddress}"''}
${optionalString (cfg.network.port != 6600) ''port "${toString cfg.network.port}"''} ${optionalString (cfg.network.port != 6600) ''port "${toString cfg.network.port}"''}
${cfg.extraConfig} ${cfg.extraConfig}
@ -75,7 +75,7 @@ in {
network = { network = {
host = mkOption { listenAddress = mkOption {
default = "any"; default = "any";
description = '' description = ''
This setting sets the address for the daemon to listen on. Careful attention This setting sets the address for the daemon to listen on. Careful attention

View File

@ -242,9 +242,16 @@ in
systemd.services."tarsnap@" = { systemd.services."tarsnap@" = {
description = "Tarsnap archive '%i'"; description = "Tarsnap archive '%i'";
requires = [ "network.target" ]; requires = [ "network-online.target" ];
after = [ "network-online.target" ];
path = [ pkgs.tarsnap pkgs.coreutils ]; path = [ pkgs.iputils pkgs.tarsnap pkgs.coreutils ];
# In order for the persistent tarsnap timer to work reliably, we have to
# make sure that the tarsnap server is reachable after systemd starts up
# the service - therefore we sleep in a loop until we can ping the
# endpoint.
preStart = "while ! ping -q -c 1 betatest-server.tarsnap.com &> /dev/null; do sleep 3; done";
scriptArgs = "%i"; scriptArgs = "%i";
script = '' script = ''
mkdir -p -m 0755 ${dirOf cfg.cachedir} mkdir -p -m 0755 ${dirOf cfg.cachedir}
@ -259,11 +266,15 @@ in
IOSchedulingClass = "idle"; IOSchedulingClass = "idle";
NoNewPrivileges = "true"; NoNewPrivileges = "true";
CapabilityBoundingSet = "CAP_DAC_READ_SEARCH"; CapabilityBoundingSet = "CAP_DAC_READ_SEARCH";
PermissionsStartOnly = "true";
}; };
}; };
# Note: the timer must be Persistent=true, so that systemd will start it even
# if e.g. your laptop was asleep while the latest interval occurred.
systemd.timers = mapAttrs' (name: cfg: nameValuePair "tarsnap@${name}" systemd.timers = mapAttrs' (name: cfg: nameValuePair "tarsnap@${name}"
{ timerConfig.OnCalendar = cfg.period; { timerConfig.OnCalendar = cfg.period;
timerConfig.Persistent = "true";
wantedBy = [ "timers.target" ]; wantedBy = [ "timers.target" ];
}) cfg.archives; }) cfg.archives;

View File

@ -60,11 +60,9 @@ with lib;
services.avahi.enable = true; services.avahi.enable = true;
jobs.fourStoreEndpoint = { systemd.services."4store-endpoint" = {
name = "4store-endpoint"; wantedBy = [ "ip-up.target" ];
startOn = "ip-up"; script = ''
exec = ''
${run} '${pkgs.rdf4store}/bin/4s-httpd -D ${cfg.options} ${if cfg.listenAddress!=null then "-H ${cfg.listenAddress}" else "" } -p ${toString cfg.port} ${cfg.database}' ${run} '${pkgs.rdf4store}/bin/4s-httpd -D ${cfg.options} ${if cfg.listenAddress!=null then "-H ${cfg.listenAddress}" else "" } -p ${toString cfg.port} ${cfg.database}'
''; '';
}; };

View File

@ -52,9 +52,8 @@ with lib;
services.avahi.enable = true; services.avahi.enable = true;
jobs.fourStore = { systemd.services."4store" = {
name = "4store"; wantedBy = [ "ip-up.target" ];
startOn = "ip-up";
preStart = '' preStart = ''
mkdir -p ${stateDir}/ mkdir -p ${stateDir}/
@ -64,11 +63,9 @@ with lib;
fi fi
''; '';
exec = '' script = ''
${run} -c '${pkgs.rdf4store}/bin/4s-backend -D ${cfg.options} ${cfg.database}' ${run} -c '${pkgs.rdf4store}/bin/4s-backend -D ${cfg.options} ${cfg.database}'
''; '';
}; };
}; };
} }

View File

@ -7,7 +7,7 @@ let
serverConfig = pkgs.writeText "neo4j-server.properties" '' serverConfig = pkgs.writeText "neo4j-server.properties" ''
org.neo4j.server.database.location=${cfg.dataDir}/data/graph.db org.neo4j.server.database.location=${cfg.dataDir}/data/graph.db
org.neo4j.server.webserver.address=${cfg.host} org.neo4j.server.webserver.address=${cfg.listenAddress}
org.neo4j.server.webserver.port=${toString cfg.port} org.neo4j.server.webserver.port=${toString cfg.port}
${optionalString cfg.enableHttps '' ${optionalString cfg.enableHttps ''
org.neo4j.server.webserver.https.enabled=true org.neo4j.server.webserver.https.enabled=true
@ -52,7 +52,7 @@ in {
type = types.package; type = types.package;
}; };
host = mkOption { listenAddress = mkOption {
description = "Neo4j listen address."; description = "Neo4j listen address.";
default = "127.0.0.1"; default = "127.0.0.1";
type = types.str; type = types.str;

View File

@ -122,8 +122,8 @@ in
example = literalExample "[ (pkgs.postgis.override { postgresql = pkgs.postgresql94; }).v_2_1_4 ]"; example = literalExample "[ (pkgs.postgis.override { postgresql = pkgs.postgresql94; }).v_2_1_4 ]";
description = '' description = ''
When this list contains elements a new store path is created. When this list contains elements a new store path is created.
PostgreSQL and the elments are symlinked into it. Then pg_config, PostgreSQL and the elements are symlinked into it. Then pg_config,
postgres and pc_ctl are copied to make them use the new postgres and pg_ctl are copied to make them use the new
$out/lib directory as pkglibdir. This makes it possible to use postgis $out/lib directory as pkglibdir. This makes it possible to use postgis
without patching the .sql files which reference $libdir/postgis-1.5. without patching the .sql files which reference $libdir/postgis-1.5.
''; '';

View File

@ -29,20 +29,20 @@ with lib;
}; };
listenAddress = mkOption { listenAddress = mkOption {
default = "1111"; default = "1111";
example = "myserver:1323"; example = "myserver:1323";
description = "ip:port or port to listen on."; description = "ip:port or port to listen on.";
}; };
httpListenAddress = mkOption { httpListenAddress = mkOption {
default = null; default = null;
example = "myserver:8080"; example = "myserver:8080";
description = "ip:port or port for Virtuoso HTTP server to listen on."; description = "ip:port or port for Virtuoso HTTP server to listen on.";
}; };
dirsAllowed = mkOption { dirsAllowed = mkOption {
default = null; default = null;
example = "/www, /home/"; example = "/www, /home/";
description = "A list of directories Virtuoso is allowed to access"; description = "A list of directories Virtuoso is allowed to access";
}; };
}; };
@ -61,18 +61,17 @@ with lib;
home = stateDir; home = stateDir;
}; };
jobs.virtuoso = { systemd.services.virtuoso = {
name = "virtuoso"; wantedBy = [ "ip-up.target" ];
startOn = "ip-up";
preStart = '' preStart = ''
mkdir -p ${stateDir} mkdir -p ${stateDir}
chown ${virtuosoUser} ${stateDir} chown ${virtuosoUser} ${stateDir}
''; '';
script = '' script = ''
cd ${stateDir} cd ${stateDir}
${pkgs.virtuoso}/bin/virtuoso-t +foreground +configfile ${pkgs.writeText "virtuoso.ini" cfg.config} ${pkgs.virtuoso}/bin/virtuoso-t +foreground +configfile ${pkgs.writeText "virtuoso.ini" cfg.config}
''; '';
}; };

View File

@ -78,8 +78,8 @@ in
bot_replaypath = replays bot_replaypath = replays
''; '';
jobs.ghostOne = { systemd.services."ghost-one" = {
name = "ghost-one"; wantedBy = [ "multi-user.target" ];
script = '' script = ''
mkdir -p ${stateDir} mkdir -p ${stateDir}
cd ${stateDir} cd ${stateDir}

View File

@ -98,22 +98,26 @@ in
config = mkIf config.services.acpid.enable { config = mkIf config.services.acpid.enable {
jobs.acpid = systemd.services.acpid = {
{ description = "ACPI Daemon"; description = "ACPI Daemon";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
after = [ "systemd-udev-settle.service" ]; after = [ "systemd-udev-settle.service" ];
path = [ pkgs.acpid ]; path = [ pkgs.acpid ];
daemonType = "fork"; serviceConfig = {
Type = "forking";
exec = "acpid --confdir ${acpiConfDir}";
unitConfig.ConditionVirtualization = "!systemd-nspawn";
unitConfig.ConditionPathExists = [ "/proc/acpi" ];
}; };
unitConfig = {
ConditionVirtualization = "!systemd-nspawn";
ConditionPathExists = [ "/proc/acpi" ];
};
script = "acpid --confdir ${acpiConfDir}";
};
}; };
} }

View File

@ -0,0 +1,30 @@
#
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.irqbalance;
in
{
options.services.irqbalance.enable = mkEnableOption "irqbalance daemon";
config = mkIf cfg.enable {
systemd.services = {
irqbalance = {
description = "irqbalance daemon";
path = [ pkgs.irqbalance ];
serviceConfig =
{ ExecStart = "${pkgs.irqbalance}/bin/irqbalance --foreground"; };
wantedBy = [ "multi-user.target" ];
};
};
environment.systemPackages = [ pkgs.irqbalance ];
};
}

View File

@ -35,18 +35,13 @@ with lib;
services.dbus.packages = [ pkgs.pommed ]; services.dbus.packages = [ pkgs.pommed ];
jobs.pommed = { name = "pommed"; systemd.services.pommed = {
description = "Pommed hotkey management"; description = "Pommed hotkey management";
wantedBy = [ "multi-user.target" ];
startOn = "started dbus"; after = [ "dbus.service" ];
postStop = "rm -f /var/run/pommed.pid"; postStop = "rm -f /var/run/pommed.pid";
script = "${pkgs.pommed}/bin/pommed";
exec = "${pkgs.pommed}/bin/pommed"; serviceConfig.Type = "forking";
daemonType = "fork";
path = [ pkgs.eject ]; path = [ pkgs.eject ];
}; };
}; };

View File

@ -24,21 +24,14 @@ with lib;
###### implementation ###### implementation
config = mkIf config.services.klogd.enable { config = mkIf config.services.klogd.enable {
systemd.services.klogd = {
jobs.klogd = description = "Kernel Log Daemon";
{ description = "Kernel Log Daemon"; wantedBy = [ "multi-user.target" ];
path = [ pkgs.sysklogd ];
wantedBy = [ "multi-user.target" ]; unitConfig.ConditionVirtualization = "!systemd-nspawn";
script =
path = [ pkgs.sysklogd ]; "klogd -c 1 -2 -n " +
"-k $(dirname $(readlink -f /run/booted-system/kernel))/System.map";
unitConfig.ConditionVirtualization = "!systemd-nspawn"; };
exec =
"klogd -c 1 -2 -n " +
"-k $(dirname $(readlink -f /run/booted-system/kernel))/System.map";
};
}; };
} }

View File

@ -0,0 +1,147 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.dspam;
dspam = pkgs.dspam;
defaultSock = "/run/dspam/dspam.sock";
cfgfile = pkgs.writeText "dspam.conf" ''
Home /var/lib/dspam
StorageDriver ${dspam}/lib/dspam/lib${cfg.storageDriver}_drv.so
Trust root
Trust ${cfg.user}
SystemLog on
UserLog on
${optionalString (cfg.domainSocket != null) ''ServerDomainSocketPath "${cfg.domainSocket}"''}
${cfg.extraConfig}
'';
in {
###### interface
options = {
services.dspam = {
enable = mkOption {
type = types.bool;
default = false;
description = "Whether to enable the dspam spam filter.";
};
user = mkOption {
type = types.str;
default = "dspam";
description = "User for the dspam daemon.";
};
group = mkOption {
type = types.str;
default = "dspam";
description = "Group for the dspam daemon.";
};
storageDriver = mkOption {
type = types.str;
default = "hash";
description = "Storage driver backend to use for dspam.";
};
domainSocket = mkOption {
type = types.nullOr types.path;
default = defaultSock;
description = "Path to local domain socket which is used for communication with the daemon. Set to null to disable UNIX socket.";
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = "Additional dspam configuration.";
};
maintenanceInterval = mkOption {
type = types.nullOr types.str;
default = null;
description = "If set, maintenance script will be run at specified (in systemd.timer format) interval";
};
};
};
###### implementation
config = mkIf cfg.enable (mkMerge [
{
users.extraUsers = optionalAttrs (cfg.user == "dspam") (singleton
{ name = "dspam";
group = cfg.group;
uid = config.ids.uids.dspam;
});
users.extraGroups = optionalAttrs (cfg.group == "dspam") (singleton
{ name = "dspam";
gid = config.ids.gids.dspam;
});
environment.systemPackages = [ dspam ];
environment.etc."dspam/dspam.conf".source = cfgfile;
systemd.services.dspam = {
description = "dspam spam filtering daemon";
wantedBy = [ "multi-user.target" ];
restartTriggers = [ cfgfile ];
serviceConfig = {
ExecStart = "${dspam}/bin/dspam --daemon --nofork";
User = cfg.user;
Group = cfg.group;
RuntimeDirectory = optional (cfg.domainSocket == defaultSock) "dspam";
PermissionsStartOnly = true;
};
preStart = ''
mkdir -m750 -p /var/lib/dspam
chown -R "${cfg.user}:${cfg.group}" /var/lib/dspam
mkdir -m750 -p /var/log/dspam
chown -R "${cfg.user}:${cfg.group}" /var/log/dspam
'';
};
}
(mkIf (cfg.maintenanceInterval != null) {
systemd.timers.dspam-maintenance = {
description = "Timer for dspam maintenance script";
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = cfg.maintenanceInterval;
Unit = "dspam-maintenance.service";
};
};
systemd.services.dspam-maintenance = {
description = "dspam maintenance script";
restartTriggers = [ cfgfile ];
serviceConfig = {
ExecStart = "${dspam}/bin/dspam_maintenance";
Type = "oneshot";
User = cfg.user;
Group = cfg.group;
};
};
})
]);
}

View File

@ -72,15 +72,16 @@ in
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
jobs.freepopsd = { systemd.services.freepopsd = {
description = "Freepopsd (webmail over POP3)"; description = "Freepopsd (webmail over POP3)";
startOn = "ip-up"; wantedBy = [ "ip-up.target" ];
exec = ''${pkgs.freepops}/bin/freepopsd \ script = ''
-p ${toString cfg.port} \ ${pkgs.freepops}/bin/freepopsd \
-t ${toString cfg.threads} \ -p ${toString cfg.port} \
-b ${cfg.bind} \ -t ${toString cfg.threads} \
-vv -l ${cfg.logFile} \ -b ${cfg.bind} \
-s ${cfg.suid.user}.${cfg.suid.group} -vv -l ${cfg.logFile} \
-s ${cfg.suid.user}.${cfg.suid.group}
''; '';
}; };
}; };

View File

@ -0,0 +1,109 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.opendkim;
defaultSock = "local:/run/opendkim/opendkim.sock";
args = [ "-f" "-l"
"-p" cfg.socket
"-d" cfg.domains
"-k" cfg.keyFile
"-s" cfg.selector
] ++ optionals (cfg.configFile != null) [ "-x" cfg.configFile ];
in {
###### interface
options = {
services.opendkim = {
enable = mkOption {
type = types.bool;
default = false;
description = "Whether to enable the OpenDKIM sender authentication system.";
};
socket = mkOption {
type = types.str;
default = defaultSock;
description = "Socket which is used for communication with OpenDKIM.";
};
user = mkOption {
type = types.str;
default = "opendkim";
description = "User for the daemon.";
};
group = mkOption {
type = types.str;
default = "opendkim";
description = "Group for the daemon.";
};
domains = mkOption {
type = types.str;
description = "Local domains set; messages from them are signed, not verified.";
};
keyFile = mkOption {
type = types.path;
description = "Secret key file used for signing messages.";
};
selector = mkOption {
type = types.str;
description = "Selector to use when signing.";
};
configFile = mkOption {
type = types.nullOr types.path;
default = null;
description = "Additional opendkim configuration.";
};
};
};
###### implementation
config = mkIf cfg.enable {
services.opendkim.domains = mkDefault "csl:${config.networking.hostName}";
users.extraUsers = optionalAttrs (cfg.user == "opendkim") (singleton
{ name = "opendkim";
group = cfg.group;
uid = config.ids.uids.opendkim;
});
users.extraGroups = optionalAttrs (cfg.group == "opendkim") (singleton
{ name = "opendkim";
gid = config.ids.gids.opendkim;
});
environment.systemPackages = [ pkgs.opendkim ];
systemd.services.opendkim = {
description = "OpenDKIM signing and verification daemon";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
ExecStart = "${pkgs.opendkim}/bin/opendkim ${concatMapStringsSep " " escapeShellArg args}";
User = cfg.user;
Group = cfg.group;
RuntimeDirectory = optional (cfg.socket == defaultSock) "opendkim";
};
};
};
}

View File

@ -9,14 +9,14 @@ let
group = cfg.group; group = cfg.group;
setgidGroup = cfg.setgidGroup; setgidGroup = cfg.setgidGroup;
haveAliases = cfg.postmasterAlias != "" || cfg.rootAlias != "" || cfg.extraAliases != "";
haveTransport = cfg.transport != "";
haveVirtual = cfg.virtual != "";
mainCf = mainCf =
'' ''
compatibility_level = 2 compatibility_level = 2
queue_directory = /var/postfix/queue
command_directory = ${pkgs.postfix}/sbin
daemon_directory = ${pkgs.postfix}/libexec/postfix
mail_owner = ${user} mail_owner = ${user}
default_privs = nobody default_privs = nobody
@ -57,8 +57,6 @@ let
else else
"[" + cfg.relayHost + "]"} "[" + cfg.relayHost + "]"}
alias_maps = hash:/var/postfix/conf/aliases
mail_spool_directory = /var/spool/mail/ mail_spool_directory = /var/spool/mail/
setgid_group = ${setgidGroup} setgid_group = ${setgidGroup}
@ -80,7 +78,13 @@ let
+ optionalString (cfg.recipientDelimiter != "") '' + optionalString (cfg.recipientDelimiter != "") ''
recipient_delimiter = ${cfg.recipientDelimiter} recipient_delimiter = ${cfg.recipientDelimiter}
'' ''
+ optionalString (cfg.virtual != "") '' + optionalString haveAliases ''
alias_maps = hash:/etc/postfix/aliases
''
+ optionalString haveTransport ''
transport_maps = hash:/etc/postfix/transport
''
+ optionalString haveVirtual ''
virtual_alias_maps = hash:/etc/postfix/virtual virtual_alias_maps = hash:/etc/postfix/virtual
'' ''
+ cfg.extraConfig; + cfg.extraConfig;
@ -108,10 +112,14 @@ let
flush unix n - n 1000? 0 flush flush unix n - n 1000? 0 flush
proxymap unix - - n - - proxymap proxymap unix - - n - - proxymap
proxywrite unix - - n - 1 proxymap proxywrite unix - - n - 1 proxymap
''
+ optionalString cfg.enableSmtp ''
smtp unix - - n - - smtp smtp unix - - n - - smtp
relay unix - - n - - smtp relay unix - - n - - smtp
-o smtp_fallback_relay= -o smtp_fallback_relay=
# -o smtp_helo_timeout=5 -o smtp_connect_timeout=5 # -o smtp_helo_timeout=5 -o smtp_connect_timeout=5
''
+ ''
showq unix n - n - - showq showq unix n - n - - showq
error unix - - n - - error error unix - - n - - error
retry unix - - n - - error retry unix - - n - - error
@ -138,6 +146,7 @@ let
virtualFile = pkgs.writeText "postfix-virtual" cfg.virtual; virtualFile = pkgs.writeText "postfix-virtual" cfg.virtual;
mainCfFile = pkgs.writeText "postfix-main.cf" mainCf; mainCfFile = pkgs.writeText "postfix-main.cf" mainCf;
masterCfFile = pkgs.writeText "postfix-master.cf" masterCf; masterCfFile = pkgs.writeText "postfix-master.cf" masterCf;
transportFile = pkgs.writeText "postfix-transport" cfg.transport;
in in
@ -150,26 +159,36 @@ in
services.postfix = { services.postfix = {
enable = mkOption { enable = mkOption {
type = types.bool;
default = false; default = false;
description = "Whether to run the Postfix mail server."; description = "Whether to run the Postfix mail server.";
}; };
enableSmtp = mkOption {
default = true;
description = "Whether to enable smtp in master.cf.";
};
setSendmail = mkOption { setSendmail = mkOption {
type = types.bool;
default = true; default = true;
description = "Whether to set the system sendmail to postfix's."; description = "Whether to set the system sendmail to postfix's.";
}; };
user = mkOption { user = mkOption {
type = types.str;
default = "postfix"; default = "postfix";
description = "What to call the Postfix user (must be used only for postfix)."; description = "What to call the Postfix user (must be used only for postfix).";
}; };
group = mkOption { group = mkOption {
type = types.str;
default = "postfix"; default = "postfix";
description = "What to call the Postfix group (must be used only for postfix)."; description = "What to call the Postfix group (must be used only for postfix).";
}; };
setgidGroup = mkOption { setgidGroup = mkOption {
type = types.str;
default = "postdrop"; default = "postdrop";
description = " description = "
How to call postfix setgid group (for postdrop). Should How to call postfix setgid group (for postdrop). Should
@ -178,6 +197,7 @@ in
}; };
networks = mkOption { networks = mkOption {
type = types.nullOr (types.listOf types.str);
default = null; default = null;
example = ["192.168.0.1/24"]; example = ["192.168.0.1/24"];
description = " description = "
@ -188,6 +208,7 @@ in
}; };
networksStyle = mkOption { networksStyle = mkOption {
type = types.str;
default = ""; default = "";
description = " description = "
Name of standard way of trusted network specification to use, Name of standard way of trusted network specification to use,
@ -197,6 +218,7 @@ in
}; };
hostname = mkOption { hostname = mkOption {
type = types.str;
default = ""; default = "";
description =" description ="
Hostname to use. Leave blank to use just the hostname of machine. Hostname to use. Leave blank to use just the hostname of machine.
@ -205,6 +227,7 @@ in
}; };
domain = mkOption { domain = mkOption {
type = types.str;
default = ""; default = "";
description =" description ="
Domain to use. Leave blank to use hostname minus first component. Domain to use. Leave blank to use hostname minus first component.
@ -212,6 +235,7 @@ in
}; };
origin = mkOption { origin = mkOption {
type = types.str;
default = ""; default = "";
description =" description ="
Origin to use in outgoing e-mail. Leave blank to use hostname. Origin to use in outgoing e-mail. Leave blank to use hostname.
@ -219,6 +243,7 @@ in
}; };
destination = mkOption { destination = mkOption {
type = types.nullOr (types.listOf types.str);
default = null; default = null;
example = ["localhost"]; example = ["localhost"];
description = " description = "
@ -228,6 +253,7 @@ in
}; };
relayDomains = mkOption { relayDomains = mkOption {
type = types.nullOr (types.listOf types.str);
default = null; default = null;
example = ["localdomain"]; example = ["localdomain"];
description = " description = "
@ -236,6 +262,7 @@ in
}; };
relayHost = mkOption { relayHost = mkOption {
type = types.str;
default = ""; default = "";
description = " description = "
Mail relay for outbound mail. Mail relay for outbound mail.
@ -243,6 +270,7 @@ in
}; };
lookupMX = mkOption { lookupMX = mkOption {
type = types.bool;
default = false; default = false;
description = " description = "
Whether relay specified is just domain whose MX must be used. Whether relay specified is just domain whose MX must be used.
@ -250,11 +278,13 @@ in
}; };
postmasterAlias = mkOption { postmasterAlias = mkOption {
type = types.str;
default = "root"; default = "root";
description = "Who should receive postmaster e-mail."; description = "Who should receive postmaster e-mail.";
}; };
rootAlias = mkOption { rootAlias = mkOption {
type = types.str;
default = ""; default = "";
description = " description = "
Who should receive root e-mail. Blank for no redirection. Who should receive root e-mail. Blank for no redirection.
@ -262,6 +292,7 @@ in
}; };
extraAliases = mkOption { extraAliases = mkOption {
type = types.lines;
default = ""; default = "";
description = " description = "
Additional entries to put verbatim into aliases file, cf. man-page aliases(8). Additional entries to put verbatim into aliases file, cf. man-page aliases(8).
@ -269,6 +300,7 @@ in
}; };
extraConfig = mkOption { extraConfig = mkOption {
type = types.str;
default = ""; default = "";
description = " description = "
Extra lines to be added verbatim to the main.cf configuration file. Extra lines to be added verbatim to the main.cf configuration file.
@ -276,21 +308,25 @@ in
}; };
sslCert = mkOption { sslCert = mkOption {
type = types.str;
default = ""; default = "";
description = "SSL certificate to use."; description = "SSL certificate to use.";
}; };
sslCACert = mkOption { sslCACert = mkOption {
type = types.str;
default = ""; default = "";
description = "SSL certificate of CA."; description = "SSL certificate of CA.";
}; };
sslKey = mkOption { sslKey = mkOption {
type = types.str;
default = ""; default = "";
description = "SSL key to use."; description = "SSL key to use.";
}; };
recipientDelimiter = mkOption { recipientDelimiter = mkOption {
type = types.str;
default = ""; default = "";
example = "+"; example = "+";
description = " description = "
@ -299,18 +335,39 @@ in
}; };
virtual = mkOption { virtual = mkOption {
type = types.lines;
default = ""; default = "";
description = " description = "
Entries for the virtual alias map, cf. man-page virtual(8). Entries for the virtual alias map, cf. man-page virtual(8).
"; ";
}; };
transport = mkOption {
default = "";
description = "
Entries for the transport map, cf. man-page transport(8).
";
};
extraMasterConf = mkOption { extraMasterConf = mkOption {
type = types.lines;
default = ""; default = "";
example = "submission inet n - n - - smtpd"; example = "submission inet n - n - - smtpd";
description = "Extra lines to append to the generated master.cf file."; description = "Extra lines to append to the generated master.cf file.";
}; };
aliasFiles = mkOption {
type = types.attrsOf types.path;
default = {};
description = "Aliases' tables to be compiled and placed into /var/lib/postfix/conf.";
};
mapFiles = mkOption {
type = types.attrsOf types.path;
default = {};
description = "Maps to be compiled and placed into /var/lib/postfix/conf.";
};
}; };
}; };
@ -318,90 +375,104 @@ in
###### implementation ###### implementation
config = mkIf config.services.postfix.enable { config = mkIf config.services.postfix.enable (mkMerge [
{
environment = { environment = {
etc = singleton etc = singleton
{ source = "/var/postfix/conf"; { source = "/var/lib/postfix/conf";
target = "postfix"; target = "postfix";
}; };
# This makes comfortable for root to run 'postqueue' for example. # This makes comfortable for root to run 'postqueue' for example.
systemPackages = [ pkgs.postfix ]; systemPackages = [ pkgs.postfix ];
};
services.mail.sendmailSetuidWrapper = mkIf config.services.postfix.setSendmail {
program = "sendmail";
source = "${pkgs.postfix}/bin/sendmail";
owner = "nobody";
group = "postdrop";
setuid = false;
setgid = true;
};
users.extraUsers = singleton
{ name = user;
description = "Postfix mail server user";
uid = config.ids.uids.postfix;
group = group;
}; };
users.extraGroups = services.mail.sendmailSetuidWrapper = mkIf config.services.postfix.setSendmail {
[ { name = group; program = "sendmail";
source = "${pkgs.postfix}/bin/sendmail";
group = setgidGroup;
setuid = false;
setgid = true;
};
users.extraUsers = optional (user == "postfix")
{ name = "postfix";
description = "Postfix mail server user";
uid = config.ids.uids.postfix;
group = group;
};
users.extraGroups =
optional (group == "postfix")
{ name = group;
gid = config.ids.gids.postfix; gid = config.ids.gids.postfix;
} }
++ optional (setgidGroup == "postdrop")
{ name = setgidGroup; { name = setgidGroup;
gid = config.ids.gids.postdrop; gid = config.ids.gids.postdrop;
}
];
systemd.services.postfix =
{ description = "Postfix mail server";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
serviceConfig = {
Type = "forking";
Restart = "always";
PIDFile = "/var/postfix/queue/pid/master.pid";
}; };
preStart = '' systemd.services.postfix =
${pkgs.coreutils}/bin/mkdir -p /var/spool/mail /var/postfix/conf /var/postfix/queue { description = "Postfix mail server";
${pkgs.coreutils}/bin/chown -R ${user}:${group} /var/postfix wantedBy = [ "multi-user.target" ];
${pkgs.coreutils}/bin/chown -R ${user}:${setgidGroup} /var/postfix/queue after = [ "network.target" ];
${pkgs.coreutils}/bin/chmod -R ug+rwX /var/postfix/queue path = [ pkgs.postfix ];
${pkgs.coreutils}/bin/chown root:root /var/spool/mail
${pkgs.coreutils}/bin/chmod a+rwxt /var/spool/mail
${pkgs.coreutils}/bin/ln -sf /var/spool/mail /var/
ln -sf ${pkgs.postfix}/etc/postfix/postfix-files /var/postfix/conf serviceConfig = {
Type = "forking";
Restart = "always";
PIDFile = "/var/lib/postfix/queue/pid/master.pid";
ExecStart = "${pkgs.postfix}/bin/postfix start";
ExecStop = "${pkgs.postfix}/bin/postfix stop";
ExecReload = "${pkgs.postfix}/bin/postfix reload";
};
ln -sf ${aliasesFile} /var/postfix/conf/aliases preStart = ''
ln -sf ${virtualFile} /var/postfix/conf/virtual # Backwards compatibility
ln -sf ${mainCfFile} /var/postfix/conf/main.cf if [ ! -d /var/lib/postfix ] && [ -d /var/postfix ]; then
ln -sf ${masterCfFile} /var/postfix/conf/master.cf mkdir -p /var/lib
mv /var/postfix /var/lib/postfix
fi
mkdir -p /var/lib/postfix/data /var/lib/postfix/queue/{pid,public,maildrop}
${pkgs.postfix}/sbin/postalias -c /var/postfix/conf /var/postfix/conf/aliases chown -R ${user}:${group} /var/lib/postfix
${pkgs.postfix}/sbin/postmap -c /var/postfix/conf /var/postfix/conf/virtual chown root /var/lib/postfix/queue
''; chown root /var/lib/postfix/queue/pid
chgrp -R ${setgidGroup} /var/lib/postfix/queue/{public,maildrop}
chmod 770 /var/lib/postfix/queue/{public,maildrop}
script = '' rm -rf /var/lib/postfix/conf
${pkgs.postfix}/sbin/postfix -c /var/postfix/conf start mkdir -p /var/lib/postfix/conf
''; ln -sf ${mainCfFile} /var/lib/postfix/conf/main.cf
ln -sf ${masterCfFile} /var/lib/postfix/conf/master.cf
${concatStringsSep "\n" (mapAttrsToList (to: from: ''
ln -sf ${from} /var/lib/postfix/conf/${to}
postalias /var/lib/postfix/conf/${to}
'') cfg.aliasFiles)}
${concatStringsSep "\n" (mapAttrsToList (to: from: ''
ln -sf ${from} /var/lib/postfix/conf/${to}
postmap /var/lib/postfix/conf/${to}
'') cfg.mapFiles)}
reload = '' mkdir -p /var/spool/mail
${pkgs.postfix}/sbin/postfix -c /var/postfix/conf reload chown root:root /var/spool/mail
''; chmod a+rwxt /var/spool/mail
ln -sf /var/spool/mail /var/
'';
};
}
preStop = '' (mkIf haveAliases {
${pkgs.postfix}/sbin/postfix -c /var/postfix/conf stop services.postfix.aliasFiles."aliases" = aliasesFile;
''; })
(mkIf haveTransport {
}; services.postfix.mapFiles."transport" = transportFile;
})
}; (mkIf haveVirtual {
services.postfix.mapFiles."virtual" = virtualFile;
})
]);
} }

View File

@ -0,0 +1,107 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.postsrsd;
in {
###### interface
options = {
services.postsrsd = {
enable = mkOption {
type = types.bool;
default = false;
description = "Whether to enable the postsrsd SRS server for Postfix.";
};
domain = mkOption {
type = types.str;
description = "Domain name for rewrite";
};
secretsFile = mkOption {
type = types.path;
default = "/var/lib/postsrsd/postsrsd.secret";
description = "Secret keys used for signing and verification";
};
forwardPort = mkOption {
type = types.int;
default = 10001;
description = "Port for the forward SRS lookup";
};
reversePort = mkOption {
type = types.int;
default = 10002;
description = "Port for the reverse SRS lookup";
};
user = mkOption {
type = types.str;
default = "postsrsd";
description = "User for the daemon";
};
group = mkOption {
type = types.str;
default = "postsrsd";
description = "Group for the daemon";
};
};
};
###### implementation
config = mkIf cfg.enable {
services.postsrsd.domain = mkDefault config.networking.hostName;
users.extraUsers = optionalAttrs (cfg.user == "postsrsd") (singleton
{ name = "postsrsd";
group = cfg.group;
uid = config.ids.uids.postsrsd;
});
users.extraGroups = optionalAttrs (cfg.group == "postsrsd") (singleton
{ name = "postsrsd";
gid = config.ids.gids.postsrsd;
});
systemd.services.postsrsd = {
description = "PostSRSd SRS rewriting server";
after = [ "network.target" ];
before = [ "postfix.service" ];
wantedBy = [ "multi-user.target" ];
path = [ pkgs.coreutils ];
serviceConfig = {
ExecStart = ''${pkgs.postsrsd}/sbin/postsrsd "-s${cfg.secretsFile}" "-d${cfg.domain}" -f${toString cfg.forwardPort} -r${toString cfg.reversePort}'';
User = cfg.user;
Group = cfg.group;
PermissionsStartOnly = true;
};
preStart = ''
if [ ! -e "${cfg.secretsFile}" ]; then
echo "WARNING: secrets file not found, autogenerating!"
mkdir -p -m750 "$(dirname "${cfg.secretsFile}")"
dd if=/dev/random bs=18 count=1 | base64 > "${cfg.secretsFile}"
chmod 600 "${cfg.secretsFile}"
fi
chown "${cfg.user}:${cfg.group}" "${cfg.secretsFile}"
'';
};
};
}

View File

@ -50,15 +50,13 @@ in
gid = config.ids.gids.spamd; gid = config.ids.gids.spamd;
}; };
jobs.spamd = { systemd.services.spamd = {
description = "Spam Assassin Server"; description = "Spam Assassin Server";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
after = [ "network.target" ]; after = [ "network.target" ];
exec = "${pkgs.spamassassin}/bin/spamd ${optionalString cfg.debug "-D"} --username=spamd --groupname=spamd --nouser-config --virtual-config-dir=/var/lib/spamassassin/user-%u --allow-tell --pidfile=/var/run/spamd.pid"; script = "${pkgs.spamassassin}/bin/spamd ${optionalString cfg.debug "-D"} --username=spamd --groupname=spamd --nouser-config --virtual-config-dir=/var/lib/spamassassin/user-%u --allow-tell --pidfile=/var/run/spamd.pid";
}; };
}; };
} }

View File

@ -51,13 +51,12 @@ with lib;
gid = config.ids.gids.dictd; gid = config.ids.gids.dictd;
}; };
jobs.dictd = systemd.services.dictd = {
{ description = "DICT.org Dictionary Server"; description = "DICT.org Dictionary Server";
startOn = "startup"; wantedBy = [ "multi-user.target" ];
environment = { LOCALE_ARCHIVE = "/run/current-system/sw/lib/locale/locale-archive"; }; environment = { LOCALE_ARCHIVE = "/run/current-system/sw/lib/locale/locale-archive"; };
daemonType = "fork"; serviceConfig.Type = "forking";
exec = "${pkgs.dict}/sbin/dictd -s -c ${dictdb}/share/dictd/dictd.conf --locale en_US.UTF-8"; script = "${pkgs.dict}/sbin/dictd -s -c ${dictdb}/share/dictd/dictd.conf --locale en_US.UTF-8";
}; };
}; };
} }

View File

@ -91,7 +91,7 @@ in
( { hostname = config.networking.hostName; ( { hostname = config.networking.hostName;
#targetHost = config.deployment.targetHost; #targetHost = config.deployment.targetHost;
system = if config.nixpkgs.system == "" then builtins.currentSystem else config.nixpkgs.system; system = if config.nixpkgs.system == "" then builtins.currentSystem else config.nixpkgs.system;
supportedTypes = (import "${pkgs.stdenv.mkDerivation { supportedTypes = (import "${pkgs.stdenv.mkDerivation {
name = "supportedtypes"; name = "supportedtypes";
buildCommand = '' buildCommand = ''
@ -117,63 +117,61 @@ in
services.disnix.publishInfrastructure.enable = cfg.publishAvahi; services.disnix.publishInfrastructure.enable = cfg.publishAvahi;
jobs = { systemd.services = {
disnix = disnix = {
{ description = "Disnix server"; description = "Disnix server";
wants = [ "dysnomia.target" ];
wants = [ "dysnomia.target" ]; wantedBy = [ "multi-user.target" ];
wantedBy = [ "multi-user.target" ]; after = [ "dbus.service" ]
after = [ "dbus.service" ] ++ optional config.services.httpd.enable "httpd.service"
++ optional config.services.httpd.enable "httpd.service" ++ optional config.services.mysql.enable "mysql.service"
++ optional config.services.mysql.enable "mysql.service" ++ optional config.services.postgresql.enable "postgresql.service"
++ optional config.services.postgresql.enable "postgresql.service" ++ optional config.services.tomcat.enable "tomcat.service"
++ optional config.services.tomcat.enable "tomcat.service" ++ optional config.services.svnserve.enable "svnserve.service"
++ optional config.services.svnserve.enable "svnserve.service" ++ optional config.services.mongodb.enable "mongodb.service";
++ optional config.services.mongodb.enable "mongodb.service";
restartIfChanged = false; restartIfChanged = false;
path = [ pkgs.nix pkgs.disnix dysnomia "/run/current-system/sw" ];
environment = {
HOME = "/root";
};
preStart = ''
mkdir -p /etc/systemd-mutable/system
if [ ! -f /etc/systemd-mutable/system/dysnomia.target ]
then
( echo "[Unit]"
echo "Description=Services that are activated and deactivated by Dysnomia"
echo "After=final.target"
) > /etc/systemd-mutable/system/dysnomia.target
fi
'';
exec = "disnix-service"; path = [ pkgs.nix pkgs.disnix dysnomia "/run/current-system/sw" ];
environment = {
HOME = "/root";
}; };
preStart = ''
mkdir -p /etc/systemd-mutable/system
if [ ! -f /etc/systemd-mutable/system/dysnomia.target ]
then
( echo "[Unit]"
echo "Description=Services that are activated and deactivated by Dysnomia"
echo "After=final.target"
) > /etc/systemd-mutable/system/dysnomia.target
fi
'';
script = "disnix-service";
};
} // optionalAttrs cfg.publishAvahi { } // optionalAttrs cfg.publishAvahi {
disnixAvahi = disnixAvahi = {
{ description = "Disnix Avahi publisher"; description = "Disnix Avahi publisher";
wants = [ "avahi-daemon.service" ];
wantedBy = [ "multi-user.target" ];
startOn = "started avahi-daemon"; script = ''
${pkgs.avahi}/bin/avahi-publish-service disnix-${config.networking.hostName} _disnix._tcp 22 \
exec = "mem=$(grep 'MemTotal:' /proc/meminfo | sed -e 's/kB//' -e 's/MemTotal://' -e 's/ //g')" \
'' ${concatMapStrings (infrastructureAttrName:
${pkgs.avahi}/bin/avahi-publish-service disnix-${config.networking.hostName} _disnix._tcp 22 \ let infrastructureAttrValue = getAttr infrastructureAttrName (cfg.infrastructure);
"mem=$(grep 'MemTotal:' /proc/meminfo | sed -e 's/kB//' -e 's/MemTotal://' -e 's/ //g')" \ in
${concatMapStrings (infrastructureAttrName: if isInt infrastructureAttrValue then
let infrastructureAttrValue = getAttr infrastructureAttrName (cfg.infrastructure); ''${infrastructureAttrName}=${toString infrastructureAttrValue} \
in ''
if isInt infrastructureAttrValue then else
''${infrastructureAttrName}=${toString infrastructureAttrValue} \ ''${infrastructureAttrName}=\"${infrastructureAttrValue}\" \
'' ''
else ) (attrNames (cfg.infrastructure))}
''${infrastructureAttrName}=\"${infrastructureAttrValue}\" \ '';
'' };
) (attrNames (cfg.infrastructure))}
'';
};
}; };
}; };
} }

View File

@ -15,7 +15,7 @@ in {
type = types.bool; type = types.bool;
}; };
host = mkOption { listenAddress = mkOption {
description = "Docker registry host or ip to bind to."; description = "Docker registry host or ip to bind to.";
default = "127.0.0.1"; default = "127.0.0.1";
type = types.str; type = types.str;
@ -50,7 +50,7 @@ in {
after = [ "network.target" ]; after = [ "network.target" ];
environment = { environment = {
REGISTRY_HOST = cfg.host; REGISTRY_HOST = cfg.listenAddress;
REGISTRY_PORT = toString cfg.port; REGISTRY_PORT = toString cfg.port;
GUNICORN_OPTS = "[--preload]"; # see https://github.com/docker/docker-registry#sqlalchemy GUNICORN_OPTS = "[--preload]"; # see https://github.com/docker/docker-registry#sqlalchemy
STORAGE_PATH = cfg.storagePath; STORAGE_PATH = cfg.storagePath;
@ -65,7 +65,7 @@ in {
}; };
postStart = '' postStart = ''
until ${pkgs.curl}/bin/curl -s -o /dev/null 'http://${cfg.host}:${toString cfg.port}/'; do until ${pkgs.curl}/bin/curl -s -o /dev/null 'http://${cfg.listenAddress}:${toString cfg.port}/'; do
sleep 1; sleep 1;
done done
''; '';

View File

@ -57,54 +57,51 @@ in
home = "/homeless-shelter"; home = "/homeless-shelter";
}; };
jobs.felix = systemd.services.felix = {
{ description = "Felix server"; description = "Felix server";
wantedBy = [ "multi-user.target" ];
preStart = preStart = ''
'' # Initialise felix instance on first startup
# Initialise felix instance on first startup if [ ! -d /var/felix ]
if [ ! -d /var/felix ] then
then # Symlink system files
# Symlink system files
mkdir -p /var/felix mkdir -p /var/felix
chown ${cfg.user}:${cfg.group} /var/felix chown ${cfg.user}:${cfg.group} /var/felix
for i in ${pkgs.felix}/* for i in ${pkgs.felix}/*
do do
if [ "$i" != "${pkgs.felix}/bundle" ] if [ "$i" != "${pkgs.felix}/bundle" ]
then then
ln -sfn $i /var/felix/$(basename $i) ln -sfn $i /var/felix/$(basename $i)
fi fi
done done
# Symlink bundles # Symlink bundles
mkdir -p /var/felix/bundle mkdir -p /var/felix/bundle
chown ${cfg.user}:${cfg.group} /var/felix/bundle chown ${cfg.user}:${cfg.group} /var/felix/bundle
for i in ${pkgs.felix}/bundle/* ${toString cfg.bundles} for i in ${pkgs.felix}/bundle/* ${toString cfg.bundles}
do do
if [ -f $i ] if [ -f $i ]
then then
ln -sfn $i /var/felix/bundle/$(basename $i) ln -sfn $i /var/felix/bundle/$(basename $i)
elif [ -d $i ] elif [ -d $i ]
then then
for j in $i/bundle/* for j in $i/bundle/*
do do
ln -sfn $j /var/felix/bundle/$(basename $j) ln -sfn $j /var/felix/bundle/$(basename $j)
done done
fi fi
done done
fi fi
''; '';
script =
''
cd /var/felix
${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c '${pkgs.jre}/bin/java -jar bin/felix.jar'
'';
};
script = ''
cd /var/felix
${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c '${pkgs.jre}/bin/java -jar bin/felix.jar'
'';
};
}; };
} }

View File

@ -49,26 +49,20 @@ in {
home = stateDir; home = stateDir;
}; };
jobs.foldingAtHome = systemd.services.foldingathome = {
{ name = "foldingathome"; after = [ "network-interfaces.target" ];
wantedBy = [ "multi-user.target" ];
startOn = "started network-interfaces"; preStart = ''
stopOn = "stopping network-interfaces"; mkdir -m 0755 -p ${stateDir}
chown ${fahUser} ${stateDir}
preStart = cp -f ${pkgs.writeText "client.cfg" cfg.config} ${stateDir}/client.cfg
''
mkdir -m 0755 -p ${stateDir}
chown ${fahUser} ${stateDir}
cp -f ${pkgs.writeText "client.cfg" cfg.config} ${stateDir}/client.cfg
'';
exec = "${pkgs.su}/bin/su -s ${pkgs.stdenv.shell} ${fahUser} -c 'cd ${stateDir}; ${pkgs.foldingathome}/bin/fah6'";
};
services.foldingAtHome.config = ''
[settings]
username=${cfg.nickname}
''; '';
script = "${pkgs.su}/bin/su -s ${pkgs.stdenv.shell} ${fahUser} -c 'cd ${stateDir}; ${pkgs.foldingathome}/bin/fah6'";
};
services.foldingAtHome.config = ''
[settings]
username=${cfg.nickname}
'';
}; };
} }

View File

@ -21,7 +21,7 @@ in
''; '';
}; };
host = mkOption { listenAddress = mkOption {
type = types.string; type = types.string;
default = "0.0.0.0"; default = "0.0.0.0";
description = '' description = ''
@ -115,7 +115,7 @@ in
ExecStart = '' ExecStart = ''
${pkgs.jre}/bin/java -Xmx${toString cfg.maxMemory}m \ ${pkgs.jre}/bin/java -Xmx${toString cfg.maxMemory}m \
-Dsubsonic.home=${cfg.home} \ -Dsubsonic.home=${cfg.home} \
-Dsubsonic.host=${cfg.host} \ -Dsubsonic.host=${cfg.listenAddress} \
-Dsubsonic.port=${toString cfg.port} \ -Dsubsonic.port=${toString cfg.port} \
-Dsubsonic.httpsPort=${toString cfg.httpsPort} \ -Dsubsonic.httpsPort=${toString cfg.httpsPort} \
-Dsubsonic.contextPath=${cfg.contextPath} \ -Dsubsonic.contextPath=${cfg.contextPath} \

View File

@ -34,13 +34,11 @@ in
###### implementation ###### implementation
config = mkIf cfg.enable { config = mkIf cfg.enable {
jobs.svnserve = { systemd.services.svnserve = {
startOn = "started network-interfaces"; after = [ "network-interfaces.target" ];
stopOn = "stopping network-interfaces"; wantedBy = [ "multi-user.target" ];
preStart = "mkdir -p ${cfg.svnBaseDir}"; preStart = "mkdir -p ${cfg.svnBaseDir}";
script = "${pkgs.subversion}/bin/svnserve -r ${cfg.svnBaseDir} -d --foreground --pid-file=/var/run/svnserve.pid";
exec = "${pkgs.subversion}/bin/svnserve -r ${cfg.svnBaseDir} -d --foreground --pid-file=/var/run/svnserve.pid";
}; };
}; };
} }

View File

@ -14,7 +14,7 @@ in {
description = "Whether to enable cadvisor service."; description = "Whether to enable cadvisor service.";
}; };
host = mkOption { listenAddress = mkOption {
default = "127.0.0.1"; default = "127.0.0.1";
type = types.str; type = types.str;
description = "Cadvisor listening host"; description = "Cadvisor listening host";
@ -71,7 +71,7 @@ in {
after = [ "network.target" "docker.service" "influxdb.service" ]; after = [ "network.target" "docker.service" "influxdb.service" ];
postStart = mkBefore '' postStart = mkBefore ''
until ${pkgs.curl}/bin/curl -s -o /dev/null 'http://${cfg.host}:${toString cfg.port}/containers/'; do until ${pkgs.curl}/bin/curl -s -o /dev/null 'http://${cfg.listenAddress}:${toString cfg.port}/containers/'; do
sleep 1; sleep 1;
done done
''; '';
@ -79,7 +79,7 @@ in {
serviceConfig = { serviceConfig = {
ExecStart = ''${pkgs.cadvisor}/bin/cadvisor \ ExecStart = ''${pkgs.cadvisor}/bin/cadvisor \
-logtostderr=true \ -logtostderr=true \
-listen_ip=${cfg.host} \ -listen_ip=${cfg.listenAddress} \
-port=${toString cfg.port} \ -port=${toString cfg.port} \
${optionalString (cfg.storageDriver != null) '' ${optionalString (cfg.storageDriver != null) ''
-storage_driver ${cfg.storageDriver} \ -storage_driver ${cfg.storageDriver} \

View File

@ -77,7 +77,7 @@ in {
type = types.bool; type = types.bool;
}; };
host = mkOption { listenAddress = mkOption {
description = "Graphite web frontend listen address."; description = "Graphite web frontend listen address.";
default = "127.0.0.1"; default = "127.0.0.1";
type = types.str; type = types.str;
@ -121,7 +121,7 @@ in {
type = types.listOf types.str; type = types.listOf types.str;
}; };
host = mkOption { listenAddress = mkOption {
description = "Graphite web service listen address."; description = "Graphite web service listen address.";
default = "127.0.0.1"; default = "127.0.0.1";
type = types.str; type = types.str;
@ -292,7 +292,7 @@ in {
}; };
graphiteUrl = mkOption { graphiteUrl = mkOption {
default = "http://${cfg.web.host}:${toString cfg.web.port}"; default = "http://${cfg.web.listenAddress}:${toString cfg.web.port}";
description = "Host where graphite service runs."; description = "Host where graphite service runs.";
type = types.str; type = types.str;
}; };
@ -337,7 +337,7 @@ in {
graphiteUrl = mkOption { graphiteUrl = mkOption {
description = "URL to your graphite service."; description = "URL to your graphite service.";
default = "http://${cfg.web.host}:${toString cfg.web.port}"; default = "http://${cfg.web.listenAddress}:${toString cfg.web.port}";
type = types.str; type = types.str;
}; };
@ -452,7 +452,7 @@ in {
serviceConfig = { serviceConfig = {
ExecStart = '' ExecStart = ''
${pkgs.python27Packages.waitress}/bin/waitress-serve \ ${pkgs.python27Packages.waitress}/bin/waitress-serve \
--host=${cfg.web.host} --port=${toString cfg.web.port} \ --host=${cfg.web.listenAddress} --port=${toString cfg.web.port} \
--call django.core.handlers.wsgi:WSGIHandler''; --call django.core.handlers.wsgi:WSGIHandler'';
User = "graphite"; User = "graphite";
Group = "graphite"; Group = "graphite";
@ -494,7 +494,7 @@ in {
serviceConfig = { serviceConfig = {
ExecStart = '' ExecStart = ''
${pkgs.python27Packages.waitress}/bin/waitress-serve \ ${pkgs.python27Packages.waitress}/bin/waitress-serve \
--host=${cfg.api.host} --port=${toString cfg.api.port} \ --host=${cfg.api.listenAddress} --port=${toString cfg.api.port} \
graphite_api.app:app graphite_api.app:app
''; '';
User = "graphite"; User = "graphite";

View File

@ -19,10 +19,6 @@ in
default = ""; default = "";
description = "monit.conf content"; description = "monit.conf content";
}; };
startOn = mkOption {
default = "started network-interfaces";
description = "What Monit supposes to be already present";
};
}; };
}; };
@ -39,14 +35,12 @@ in
} }
]; ];
jobs.monit = { systemd.services.monit = {
description = "Monit system watcher"; description = "Monit system watcher";
after = [ "network-interfaces.target" ];
startOn = config.services.monit.startOn; wantedBy = [ "multi-user.target" ];
script = "${pkgs.monit}/bin/monit -I -c /etc/monit.conf";
exec = "${pkgs.monit}/bin/monit -I -c /etc/monit.conf"; serviceConfig.Restart = "always";
respawn = true;
}; };
}; };
} }

View File

@ -11,7 +11,7 @@ let
configFile = pkgs.writeText "statsd.conf" '' configFile = pkgs.writeText "statsd.conf" ''
{ {
address: "${cfg.host}", address: "${cfg.listenAddress}",
port: "${toString cfg.port}", port: "${toString cfg.port}",
mgmt_address: "${cfg.mgmt_address}", mgmt_address: "${cfg.mgmt_address}",
mgmt_port: "${toString cfg.mgmt_port}", mgmt_port: "${toString cfg.mgmt_port}",
@ -48,7 +48,7 @@ in
type = types.bool; type = types.bool;
}; };
host = mkOption { listenAddress = mkOption {
description = "Address that statsd listens on over UDP"; description = "Address that statsd listens on over UDP";
default = "127.0.0.1"; default = "127.0.0.1";
type = types.str; type = types.str;

View File

@ -180,31 +180,36 @@ in
environment.systemPackages = [ pkgs.nut ]; environment.systemPackages = [ pkgs.nut ];
jobs.upsmon = { systemd.services.upsmon = {
description = "Uninterruptible Power Supplies (Monitor)"; description = "Uninterruptible Power Supplies (Monitor)";
startOn = "ip-up"; wantedBy = [ "ip-up.target" ];
daemonType = "fork"; serviceConfig.Type = "forking";
exec = ''${pkgs.nut}/sbin/upsmon''; script = "${pkgs.nut}/sbin/upsmon";
environment.NUT_CONFPATH = "/etc/nut/"; environment.NUT_CONFPATH = "/etc/nut/";
environment.NUT_STATEPATH = "/var/lib/nut/"; environment.NUT_STATEPATH = "/var/lib/nut/";
}; };
jobs.upsd = { systemd.services.upsd = {
description = "Uninterruptible Power Supplies (Daemon)"; description = "Uninterruptible Power Supplies (Daemon)";
startOn = "started network-interfaces and started upsmon"; wantedBy = [ "multi-user.target" ];
daemonType = "fork"; after = [ "network-interfaces.target" "upsmon.service" ];
serviceConfig.Type = "forking";
# TODO: replace 'root' by another username. # TODO: replace 'root' by another username.
exec = ''${pkgs.nut}/sbin/upsd -u root''; script = "${pkgs.nut}/sbin/upsd -u root";
environment.NUT_CONFPATH = "/etc/nut/"; environment.NUT_CONFPATH = "/etc/nut/";
environment.NUT_STATEPATH = "/var/lib/nut/"; environment.NUT_STATEPATH = "/var/lib/nut/";
}; };
jobs.upsdrv = { systemd.services.upsdrv = {
description = "Uninterruptible Power Supplies (Register all UPS)"; description = "Uninterruptible Power Supplies (Register all UPS)";
startOn = "started upsd"; wantedBy = [ "multi-user.target" ];
after = [ "upsd.service" ];
# TODO: replace 'root' by another username. # TODO: replace 'root' by another username.
exec = ''${pkgs.nut}/bin/upsdrvctl -u root start''; script = ''${pkgs.nut}/bin/upsdrvctl -u root start'';
task = true; serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
environment.NUT_CONFPATH = "/etc/nut/"; environment.NUT_CONFPATH = "/etc/nut/";
environment.NUT_STATEPATH = "/var/lib/nut/"; environment.NUT_STATEPATH = "/var/lib/nut/";
}; };

View File

@ -31,13 +31,13 @@ let cfg = config.services.drbd; in
}; };
###### implementation ###### implementation
config = mkIf cfg.enable { config = mkIf cfg.enable {
environment.systemPackages = [ pkgs.drbd ]; environment.systemPackages = [ pkgs.drbd ];
services.udev.packages = [ pkgs.drbd ]; services.udev.packages = [ pkgs.drbd ];
boot.kernelModules = [ "drbd" ]; boot.kernelModules = [ "drbd" ];
@ -52,26 +52,16 @@ let cfg = config.services.drbd; in
target = "drbd.conf"; target = "drbd.conf";
}; };
jobs.drbd_up = systemd.services.drbd = {
{ name = "drbd-up"; after = [ "systemd-udev.settle.service" ];
startOn = "stopped udevtrigger or ip-up"; wants = [ "systemd-udev.settle.service" ];
task = true; wantedBy = [ "ip-up.target" ];
script = script = ''
'' ${pkgs.drbd}/sbin/drbdadm up all
${pkgs.drbd}/sbin/drbdadm up all '';
''; serviceConfig.ExecStop = ''
}; ${pkgs.drbd}/sbin/drbdadm down all
'';
jobs.drbd_down = };
{ name = "drbd-down";
startOn = "starting shutdown";
task = true;
script =
''
${pkgs.drbd}/sbin/drbdadm down all
'';
};
}; };
} }

View File

@ -72,34 +72,28 @@ in
} }
]; ];
jobs.openafsClient = systemd.services.afsd = {
{ name = "afsd"; description = "AFS client";
wantedBy = [ "multi-user.target" ];
after = [ "network-interfaces.target" ];
description = "AFS client"; preStart = ''
mkdir -p -m 0755 /afs
startOn = "started network-interfaces"; mkdir -m 0700 -p ${cfg.cacheDirectory}
stopOn = "stopping network-interfaces"; ${pkgs.module_init_tools}/sbin/insmod ${openafsPkgs}/lib/openafs/libafs-*.ko || true
${openafsPkgs}/sbin/afsd -confdir ${afsConfig} -cachedir ${cfg.cacheDirectory} ${if cfg.sparse then "-dynroot-sparse" else "-dynroot"} -fakestat -afsdb
preStart = '' ${openafsPkgs}/bin/fs setcrypt ${if cfg.crypt then "on" else "off"}
mkdir -p -m 0755 /afs '';
mkdir -m 0700 -p ${cfg.cacheDirectory}
${pkgs.module_init_tools}/sbin/insmod ${openafsPkgs}/lib/openafs/libafs-*.ko || true
${openafsPkgs}/sbin/afsd -confdir ${afsConfig} -cachedir ${cfg.cacheDirectory} ${if cfg.sparse then "-dynroot-sparse" else "-dynroot"} -fakestat -afsdb
${openafsPkgs}/bin/fs setcrypt ${if cfg.crypt then "on" else "off"}
'';
# Doing this in preStop, because after these commands AFS is basically
# stopped, so systemd has nothing to do, just noticing it. If done in
# postStop, then we get a hang + kernel oops, because AFS can't be
# stopped simply by sending signals to processes.
preStop = ''
${pkgs.utillinux}/bin/umount /afs
${openafsPkgs}/sbin/afsd -shutdown
${pkgs.module_init_tools}/sbin/rmmod libafs
'';
};
# Doing this in preStop, because after these commands AFS is basically
# stopped, so systemd has nothing to do, just noticing it. If done in
# postStop, then we get a hang + kernel oops, because AFS can't be
# stopped simply by sending signals to processes.
preStop = ''
${pkgs.utillinux}/bin/umount /afs
${openafsPkgs}/sbin/afsd -shutdown
${pkgs.module_init_tools}/sbin/rmmod libafs
'';
};
}; };
} }

View File

@ -57,22 +57,19 @@ in
gid = config.ids.gids.amule; gid = config.ids.gids.amule;
} ]; } ];
jobs.amuled = systemd.services.amuled = {
{ description = "AMule daemon"; description = "AMule daemon";
wantedBy = [ "ip-up.target" ];
startOn = "ip-up"; preStart = ''
mkdir -p ${cfg.dataDir}
preStart = '' chown ${user} ${cfg.dataDir}
mkdir -p ${cfg.dataDir} '';
chown ${user} ${cfg.dataDir}
'';
exec = ''
${pkgs.su}/bin/su -s ${pkgs.stdenv.shell} ${user} \
-c 'HOME="${cfg.dataDir}" ${pkgs.amuleDaemon}/bin/amuled'
'';
};
script = ''
${pkgs.su}/bin/su -s ${pkgs.stdenv.shell} ${user} \
-c 'HOME="${cfg.dataDir}" ${pkgs.amuleDaemon}/bin/amuled'
'';
};
}; };
} }

View File

@ -142,20 +142,17 @@ in
description = "BIND daemon user"; description = "BIND daemon user";
}; };
jobs.bind = systemd.services.bind = {
{ description = "BIND name server job"; description = "BIND name server job";
after = [ "network-interfaces.target" ];
wantedBy = [ "multi-user.target" ];
startOn = "started network-interfaces"; preStart = ''
${pkgs.coreutils}/bin/mkdir -p /var/run/named
preStart = chown ${bindUser} /var/run/named
'' '';
${pkgs.coreutils}/bin/mkdir -p /var/run/named
chown ${bindUser} /var/run/named
'';
exec = "${pkgs.bind}/sbin/named -u ${bindUser} ${optionalString cfg.ipv4Only "-4"} -c ${cfg.configFile} -f";
};
script = "${pkgs.bind}/sbin/named -u ${bindUser} ${optionalString cfg.ipv4Only "-4"} -c ${cfg.configFile} -f";
};
}; };
} }

View File

@ -16,9 +16,10 @@ let
'' ''
"webui": "webui":
{ {
${optionalEmptyStr cfg.httpLogin "\"login\": \"${cfg.httpLogin}\","} ${optionalEmptyStr cfg.httpLogin "\"login\": \"${cfg.httpLogin}\","}
${optionalEmptyStr cfg.httpPass "\"password\": \"${cfg.httpPass}\","} ${optionalEmptyStr cfg.httpPass "\"password\": \"${cfg.httpPass}\","}
${optionalEmptyStr cfg.apiKey "\"api_key\": \"${cfg.apiKey}\","} ${optionalEmptyStr cfg.apiKey "\"api_key\": \"${cfg.apiKey}\","}
${optionalEmptyStr cfg.directoryRoot "\"directory_root\": \"${cfg.directoryRoot}\","}
"listen": "${listenAddr}" "listen": "${listenAddr}"
} }
''; '';
@ -82,15 +83,13 @@ in
type = types.bool; type = types.bool;
default = false; default = false;
description = '' description = ''
If enabled, start the Bittorrent Sync daemon. Once enabled, If enabled, start the Bittorrent Sync daemon. Once enabled, you can
you can interact with the service through the Web UI, or interact with the service through the Web UI, or configure it in your
configure it in your NixOS configuration. Enabling the NixOS configuration. Enabling the <literal>btsync</literal> service
<literal>btsync</literal> service also installs a also installs a systemd user unit which can be used to start
multi-instance systemd unit which can be used to start user-specific copies of the daemon. Once installed, you can use
user-specific copies of the daemon. Once installed, you can <literal>systemctl --user start btsync</literal> as your user to start
use <literal>systemctl start btsync@user</literal> to start the daemon using the configuration file located at
the daemon only for user <literal>user</literal>, using the
configuration file located at
<literal>$HOME/.config/btsync.conf</literal>. <literal>$HOME/.config/btsync.conf</literal>.
''; '';
}; };
@ -211,7 +210,9 @@ in
default = "/var/lib/btsync/"; default = "/var/lib/btsync/";
example = "/var/lib/btsync/"; example = "/var/lib/btsync/";
description = '' description = ''
Where to store the bittorrent sync files. Where BitTorrent Sync will store it's database files (containing
things like username info and licenses). Generally, you should not
need to ever change this.
''; '';
}; };
@ -221,6 +222,13 @@ in
description = "API key, which enables the developer API."; description = "API key, which enables the developer API.";
}; };
directoryRoot = mkOption {
type = types.str;
default = "";
example = "/media";
description = "Default directory to add folders in the web UI.";
};
sharedFolders = mkOption { sharedFolders = mkOption {
default = []; default = [];
example = example =
@ -303,12 +311,11 @@ in
}; };
}; };
systemd.services."btsync@" = with pkgs; { systemd.user.services.btsync = with pkgs; {
description = "Bittorrent Sync Service for %i"; description = "Bittorrent Sync user service";
after = [ "network.target" "local-fs.target" ]; after = [ "network.target" "local-fs.target" ];
serviceConfig = { serviceConfig = {
Restart = "on-abort"; Restart = "on-abort";
User = "%i";
ExecStart = ExecStart =
"${bittorrentSync}/bin/btsync --nodaemon --config %h/.config/btsync.conf"; "${bittorrentSync}/bin/btsync --nodaemon --config %h/.config/btsync.conf";
}; };

View File

@ -7,7 +7,7 @@ let
cfg = config.services.consul; cfg = config.services.consul;
configOptions = { data_dir = dataDir; } // configOptions = { data_dir = dataDir; } //
(if cfg.webUi then { ui_dir = "${pkgs.consul.ui}"; } else { }) // (if cfg.webUi then { ui_dir = "${cfg.package.ui}"; } else { }) //
cfg.extraConfig; cfg.extraConfig;
configFiles = [ "/etc/consul.json" "/etc/consul-addrs.json" ] configFiles = [ "/etc/consul.json" "/etc/consul-addrs.json" ]
@ -30,6 +30,15 @@ in
''; '';
}; };
package = mkOption {
type = types.package;
default = pkgs.consul;
description = ''
The package used for the Consul agent and CLI.
'';
};
webUi = mkOption { webUi = mkOption {
type = types.bool; type = types.bool;
default = false; default = false;
@ -155,7 +164,7 @@ in
etc."consul.json".text = builtins.toJSON configOptions; etc."consul.json".text = builtins.toJSON configOptions;
# We need consul.d to exist for consul to start # We need consul.d to exist for consul to start
etc."consul.d/dummy.json".text = "{ }"; etc."consul.d/dummy.json".text = "{ }";
systemPackages = with pkgs; [ consul ]; systemPackages = [ cfg.package ];
}; };
systemd.services.consul = { systemd.services.consul = {
@ -167,14 +176,14 @@ in
(filterAttrs (n: _: hasPrefix "consul.d/" n) config.environment.etc); (filterAttrs (n: _: hasPrefix "consul.d/" n) config.environment.etc);
serviceConfig = { serviceConfig = {
ExecStart = "@${pkgs.consul}/bin/consul consul agent -config-dir /etc/consul.d" ExecStart = "@${cfg.package}/bin/consul consul agent -config-dir /etc/consul.d"
+ concatMapStrings (n: " -config-file ${n}") configFiles; + concatMapStrings (n: " -config-file ${n}") configFiles;
ExecReload = "${pkgs.consul}/bin/consul reload"; ExecReload = "${cfg.package}/bin/consul reload";
PermissionsStartOnly = true; PermissionsStartOnly = true;
User = if cfg.dropPrivileges then "consul" else null; User = if cfg.dropPrivileges then "consul" else null;
TimeoutStartSec = "0"; TimeoutStartSec = "0";
} // (optionalAttrs (cfg.leaveOnStop) { } // (optionalAttrs (cfg.leaveOnStop) {
ExecStop = "${pkgs.consul}/bin/consul leave"; ExecStop = "${cfg.package}/bin/consul leave";
}); });
path = with pkgs; [ iproute gnugrep gawk consul ]; path = with pkgs; [ iproute gnugrep gawk consul ];
@ -221,7 +230,7 @@ in
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
after = [ "consul.service" ]; after = [ "consul.service" ];
path = [ pkgs.consul ]; path = [ cfg.package ];
serviceConfig = { serviceConfig = {
ExecStart = '' ExecStart = ''

View File

@ -6,9 +6,16 @@ let
cfg = config.services.ejabberd; cfg = config.services.ejabberd;
in ctlcfg = pkgs.writeText "ejabberdctl.cfg" ''
ERL_EPMD_ADDRESS=127.0.0.1
${cfg.ctlConfig}
'';
{ ectl = ''${cfg.package}/bin/ejabberdctl ${if cfg.configFile == null then "" else "--config ${cfg.configFile}"} --ctl-config "${ctlcfg}" --spool "${cfg.spoolDir}" --logs "${cfg.logsDir}"'';
dumps = lib.concatMapStringsSep " " lib.escapeShellArg cfg.loadDumps;
in {
###### interface ###### interface
@ -17,33 +24,57 @@ in
services.ejabberd = { services.ejabberd = {
enable = mkOption { enable = mkOption {
type = types.bool;
default = false; default = false;
description = "Whether to enable ejabberd server"; description = "Whether to enable ejabberd server";
}; };
package = mkOption {
type = types.package;
default = pkgs.ejabberd;
description = "ejabberd server package to use";
};
user = mkOption {
type = types.str;
default = "ejabberd";
description = "User under which ejabberd is ran";
};
group = mkOption {
type = types.str;
default = "ejabberd";
description = "Group under which ejabberd is ran";
};
spoolDir = mkOption { spoolDir = mkOption {
type = types.path;
default = "/var/lib/ejabberd"; default = "/var/lib/ejabberd";
description = "Location of the spooldir of ejabberd"; description = "Location of the spooldir of ejabberd";
}; };
logsDir = mkOption { logsDir = mkOption {
type = types.path;
default = "/var/log/ejabberd"; default = "/var/log/ejabberd";
description = "Location of the logfile directory of ejabberd"; description = "Location of the logfile directory of ejabberd";
}; };
confDir = mkOption { configFile = mkOption {
default = "/var/ejabberd"; type = types.nullOr types.path;
description = "Location of the config directory of ejabberd"; description = "Configuration file for ejabberd in YAML format";
default = null;
}; };
virtualHosts = mkOption { ctlConfig = mkOption {
default = "\"localhost\""; type = types.lines;
description = "Virtualhosts that ejabberd should host. Hostnames are surrounded with doublequotes and separated by commas"; default = "";
description = "Configuration of ejabberdctl";
}; };
loadDumps = mkOption { loadDumps = mkOption {
type = types.listOf types.path;
default = []; default = [];
description = "Configuration dump that should be loaded on the first startup"; description = "Configuration dumps that should be loaded on the first startup";
example = literalExample "[ ./myejabberd.dump ]"; example = literalExample "[ ./myejabberd.dump ]";
}; };
}; };
@ -54,84 +85,75 @@ in
###### implementation ###### implementation
config = mkIf cfg.enable { config = mkIf cfg.enable {
environment.systemPackages = [ pkgs.ejabberd ]; environment.systemPackages = [ cfg.package ];
jobs.ejabberd = users.extraUsers = optionalAttrs (cfg.user == "ejabberd") (singleton
{ description = "EJabberd server"; { name = "ejabberd";
group = cfg.group;
home = cfg.spoolDir;
createHome = true;
uid = config.ids.uids.ejabberd;
});
startOn = "started network-interfaces"; users.extraGroups = optionalAttrs (cfg.group == "ejabberd") (singleton
stopOn = "stopping network-interfaces"; { name = "ejabberd";
gid = config.ids.gids.ejabberd;
});
environment = { systemd.services.ejabberd = {
PATH = "$PATH:${pkgs.ejabberd}/sbin:${pkgs.ejabberd}/bin:${pkgs.coreutils}/bin:${pkgs.bash}/bin:${pkgs.gnused}/bin"; description = "ejabberd server";
}; wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
path = [ pkgs.findutils pkgs.coreutils ];
preStart = serviceConfig = {
'' Type = "forking";
PATH="$PATH:${pkgs.ejabberd}/sbin:${pkgs.ejabberd}/bin:${pkgs.coreutils}/bin:${pkgs.bash}/bin:${pkgs.gnused}/bin"; # FIXME: runit is used for `chpst` -- can we get rid of this?
ExecStop = ''${pkgs.runit}/bin/chpst -u "${cfg.user}:${cfg.group}" ${ectl} stop'';
# Initialise state data ExecReload = ''${pkgs.runit}/bin/chpst -u "${cfg.user}:${cfg.group}" ${ectl} reload_config'';
mkdir -p ${cfg.logsDir} User = cfg.user;
Group = cfg.group;
if ! test -d ${cfg.spoolDir} PermissionsStartOnly = true;
then
initialize=1
cp -av ${pkgs.ejabberd}/var/lib/ejabberd /var/lib
fi
if ! test -d ${cfg.confDir}
then
mkdir -p ${cfg.confDir}
cp ${pkgs.ejabberd}/etc/ejabberd/* ${cfg.confDir}
sed -e 's|{hosts, \["localhost"\]}.|{hosts, \[${cfg.virtualHosts}\]}.|' ${pkgs.ejabberd}/etc/ejabberd/ejabberd.cfg > ${cfg.confDir}/ejabberd.cfg
fi
ejabberdctl --config-dir ${cfg.confDir} --logs ${cfg.logsDir} --spool ${cfg.spoolDir} start
${if cfg.loadDumps == [] then "" else
''
if [ "$initialize" = "1" ]
then
# Wait until the ejabberd server is available for use
count=0
while ! ejabberdctl --config-dir ${cfg.confDir} --logs ${cfg.logsDir} --spool ${cfg.spoolDir} status
do
if [ $count -eq 30 ]
then
echo "Tried 30 times, giving up..."
exit 1
fi
echo "Ejabberd daemon not yet started. Waiting for 1 second..."
count=$((count++))
sleep 1
done
${concatMapStrings (dump:
''
echo "Importing dump: ${dump}"
if [ -f ${dump} ]
then
ejabberdctl --config-dir ${cfg.confDir} --logs ${cfg.logsDir} --spool ${cfg.spoolDir} load ${dump}
elif [ -d ${dump} ]
then
for i in ${dump}/ejabberd-dump/*
do
ejabberdctl --config-dir ${cfg.confDir} --logs ${cfg.logsDir} --spool ${cfg.spoolDir} load $i
done
fi
'') cfg.loadDumps}
fi
''}
'';
postStop =
''
ejabberdctl --config-dir ${cfg.confDir} --logs ${cfg.logsDir} --spool ${cfg.spoolDir} stop
'';
}; };
preStart = ''
mkdir -p -m750 "${cfg.logsDir}"
chown "${cfg.user}:${cfg.group}" "${cfg.logsDir}"
mkdir -p -m750 "/var/lock/ejabberdctl"
chown "${cfg.user}:${cfg.group}" "/var/lock/ejabberdctl"
mkdir -p -m750 "${cfg.spoolDir}"
chown -R "${cfg.user}:${cfg.group}" "${cfg.spoolDir}"
'';
script = ''
[ -z "$(ls -A '${cfg.spoolDir}')" ] && firstRun=1
${ectl} start
count=0
while ! ${ectl} status >/dev/null 2>&1; do
if [ $count -eq 30 ]; then
echo "ejabberd server hasn't started in 30 seconds, giving up"
exit 1
fi
count=$((count++))
sleep 1
done
if [ -n "$firstRun" ]; then
for src in ${dumps}; do
find "$src" -type f | while read dump; do
echo "Loading configuration dump at $dump"
${ectl} load "$dump"
done
done
fi
'';
};
security.pam.services.ejabberd = {}; security.pam.services.ejabberd = {};
}; };

View File

@ -0,0 +1,182 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.gale;
# we convert the path to a string to avoid it being copied to the nix store,
# otherwise users could read the private key as all files in the store are
# world-readable
keyPath = toString cfg.keyPath;
# ...but we refer to the pubkey file using a path so that we can ensure the
# config gets rebuilt if the public key changes (we can assume the private key
# will never change without the public key having changed)
gpubFile = cfg.keyPath + "/${cfg.domain}.gpub";
home = "/var/lib/gale";
keysPrepared = cfg.keyPath != null && lib.pathExists cfg.keyPath;
in
{
options = {
services.gale = {
enable = mkEnableOption "the Gale messaging daemon";
user = mkOption {
default = "gale";
type = types.str;
description = "Username for the Gale daemon.";
};
group = mkOption {
default = "gale";
type = types.str;
description = "Group name for the Gale daemon.";
};
setuidWrapper = mkOption {
default = null;
description = "Configuration for the Gale gksign setuid wrapper.";
};
domain = mkOption {
default = "";
type = types.str;
description = "Domain name for the Gale system.";
};
keyPath = mkOption {
default = null;
type = types.nullOr types.path;
description = ''
Directory containing the key pair for this Gale domain. The expected
filename will be taken from the domain option with ".gpri" and ".gpub"
appended.
'';
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = ''
Additional text to be added to <filename>/etc/gale/conf</filename>.
'';
};
};
};
config = mkMerge [
(mkIf cfg.enable {
assertions = [{
assertion = cfg.domain != "";
message = "A domain must be set for Gale.";
}];
warnings = mkIf (!keysPrepared) [
"You must run gale-install in order to generate a domain key."
];
system.activationScripts.gale = mkIf cfg.enable (
stringAfter [ "users" "groups" ] ''
chmod -R 755 ${home}
mkdir -m 0777 -p ${home}/auth/cache
mkdir -m 1777 -p ${home}/auth/local # GALE_DOMAIN.gpub
mkdir -m 0700 -p ${home}/auth/private # ROOT.gpub
mkdir -m 0755 -p ${home}/auth/trusted # ROOT
mkdir -m 0700 -p ${home}/.gale
mkdir -m 0700 -p ${home}/.gale/auth
mkdir -m 0700 -p ${home}/.gale/auth/private # GALE_DOMAIN.gpri
ln -sf ${pkgs.gale}/etc/gale/auth/trusted/ROOT "${home}/auth/trusted/ROOT"
chown -R ${cfg.user}:${cfg.group} ${home}
''
);
environment = {
etc = {
"gale/auth".source = home + "/auth"; # symlink /var/lib/gale/auth
"gale/conf".text = ''
GALE_USER ${cfg.user}
GALE_DOMAIN ${cfg.domain}
${cfg.extraConfig}
'';
};
systemPackages = [ pkgs.gale ];
};
users.extraUsers = [{
name = cfg.user;
description = "Gale daemon";
uid = config.ids.uids.gale;
group = cfg.group;
home = home;
createHome = true;
}];
users.extraGroups = [{
name = cfg.group;
gid = config.ids.gids.gale;
}];
})
(mkIf (cfg.enable && keysPrepared) {
assertions = [
{
assertion = cfg.keyPath != null
&& lib.pathExists (cfg.keyPath + "/${cfg.domain}.gpub");
message = "Couldn't find a Gale public key for ${cfg.domain}.";
}
{
assertion = cfg.keyPath != null
&& lib.pathExists (cfg.keyPath + "/${cfg.domain}.gpri");
message = "Couldn't find a Gale private key for ${cfg.domain}.";
}
];
services.gale.setuidWrapper = {
program = "gksign";
source = "${pkgs.gale}/bin/gksign";
owner = cfg.user;
group = cfg.group;
setuid = true;
setgid = false;
};
security.setuidOwners = [ cfg.setuidWrapper ];
systemd.services.gale-galed = {
description = "Gale messaging daemon";
wantedBy = [ "multi-user.target" ];
wants = [ "gale-gdomain.service" ];
after = [ "network.target" ];
preStart = ''
install -m 0640 ${keyPath}/${cfg.domain}.gpri "${home}/.gale/auth/private/"
install -m 0644 ${gpubFile} "${home}/.gale/auth/private/${cfg.domain}.gpub"
install -m 0644 ${gpubFile} "${home}/auth/local/${cfg.domain}.gpub"
chown -R ${cfg.user}:${cfg.group} ${home}
'';
serviceConfig = {
Type = "forking";
ExecStart = "@${pkgs.gale}/bin/galed galed";
User = cfg.user;
Group = cfg.group;
PermissionsStartOnly = true;
};
};
systemd.services.gale-gdomain = {
description = "Gale AKD daemon";
wantedBy = [ "multi-user.target" ];
requires = [ "gale-galed.service" ];
after = [ "gale-galed.service" ];
serviceConfig = {
Type = "forking";
ExecStart = "@${pkgs.gale}/bin/gdomain gdomain";
User = cfg.user;
Group = cfg.group;
};
};
})
];
}

View File

@ -16,7 +16,7 @@ in
type = types.bool; type = types.bool;
default = false; default = false;
description = '' description = ''
Enable Git daemon, which allows public hosting of git repositories Enable Git daemon, which allows public hosting of git repositories
without any access controls. This is mostly intended for read-only access. without any access controls. This is mostly intended for read-only access.
You can allow write access by setting daemon.receivepack configuration You can allow write access by setting daemon.receivepack configuration
@ -115,10 +115,9 @@ in
gid = config.ids.gids.git; gid = config.ids.gids.git;
}; };
jobs.gitDaemon = { systemd.services."git-daemon" = {
name = "git-daemon"; wantedBy = [ "ip-up.target" ];
startOn = "ip-up"; script = "${pkgs.git}/bin/git daemon --reuseaddr "
exec = "${pkgs.git}/bin/git daemon --reuseaddr "
+ (optionalString (cfg.basePath != "") "--base-path=${cfg.basePath} ") + (optionalString (cfg.basePath != "") "--base-path=${cfg.basePath} ")
+ (optionalString (cfg.listenAddress != "") "--listen=${cfg.listenAddress} ") + (optionalString (cfg.listenAddress != "") "--listen=${cfg.listenAddress} ")
+ "--port=${toString cfg.port} --user=${cfg.user} --group=${cfg.group} ${cfg.options} " + "--port=${toString cfg.port} --user=${cfg.user} --group=${cfg.group} ${cfg.options} "

View File

@ -37,13 +37,6 @@ let
''; '';
executable = true; executable = true;
}); });
exec = "${pkgs.gvpe}/sbin/gvpe -c /var/gvpe -D ${cfg.nodename} "
+ " ${cfg.nodename}.pid-file=/var/gvpe/gvpe.pid"
+ " ${cfg.nodename}.if-up=if-up"
+ " &> /var/log/gvpe";
inherit (cfg) startOn stopOn;
in in
{ {
@ -55,18 +48,6 @@ in
Whether to run gvpe Whether to run gvpe
''; '';
}; };
startOn = mkOption {
default = "started network-interfaces";
description = ''
Condition to start GVPE
'';
};
stopOn = mkOption {
default = "stopping network-interfaces";
description = ''
Condition to stop GVPE
'';
};
nodename = mkOption { nodename = mkOption {
default = null; default = null;
description ='' description =''
@ -122,10 +103,10 @@ in
}; };
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
jobs.gvpe = { systemd.services.gvpe = {
description = "GNU Virtual Private Ethernet node"; description = "GNU Virtual Private Ethernet node";
after = [ "network-interfaces.target" ];
inherit startOn stopOn; wantedBy = [ "multi-user.target" ];
preStart = '' preStart = ''
mkdir -p /var/gvpe mkdir -p /var/gvpe
@ -136,9 +117,12 @@ in
cp ${ifupScript} /var/gvpe/if-up cp ${ifupScript} /var/gvpe/if-up
''; '';
inherit exec; script = "${pkgs.gvpe}/sbin/gvpe -c /var/gvpe -D ${cfg.nodename} "
+ " ${cfg.nodename}.pid-file=/var/gvpe/gvpe.pid"
+ " ${cfg.nodename}.if-up=if-up"
+ " &> /var/log/gvpe";
respawn = true; serviceConfig.Restart = "always";
}; };
}; };
} }

View File

@ -66,23 +66,17 @@ in
###### implementation ###### implementation
config = mkIf cfg.enable { config = mkIf cfg.enable {
systemd.services.ifplugd = {
jobs.ifplugd = description = "Network interface connectivity monitor";
{ description = "Network interface connectivity monitor"; after = [ "network-interfaces.target" ];
wantedBy = [ "multi-user.target" ];
startOn = "started network-interfaces"; script = ''
stopOn = "stopping network-interfaces"; ${ifplugd}/sbin/ifplugd --no-daemon --no-startup --no-shutdown \
${if config.networking.interfaceMonitor.beep then "" else "--no-beep"} \
exec = --run ${plugScript}
'' '';
${ifplugd}/sbin/ifplugd --no-daemon --no-startup --no-shutdown \ };
${if config.networking.interfaceMonitor.beep then "" else "--no-beep"} \
--run ${plugScript}
'';
};
environment.systemPackages = [ ifplugd ]; environment.systemPackages = [ ifplugd ];
}; };
} }

View File

@ -121,17 +121,11 @@ in
users.extraGroups.ircd.gid = config.ids.gids.ircd; users.extraGroups.ircd.gid = config.ids.gids.ircd;
jobs.ircd_hybrid = systemd.services."ircd-hybrid" = {
{ name = "ircd-hybrid"; description = "IRCD Hybrid server";
after = [ "started networking" ];
description = "IRCD Hybrid server"; wantedBy = [ "multi-user.target" ];
script = "${ircdService}/bin/control start";
startOn = "started networking"; };
stopOn = "stopping networking";
exec = "${ircdService}/bin/control start";
};
}; };
} }

View File

@ -1,130 +0,0 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.notbit;
varDir = "/var/lib/notbit";
sendmail = pkgs.stdenv.mkDerivation {
name = "notbit-wrapper";
buildInputs = [ pkgs.makeWrapper ];
propagatedBuildInputs = [ pkgs.notbit ];
buildCommand = ''
mkdir -p $out/bin
makeWrapper ${pkgs.notbit}/bin/notbit-sendmail $out/bin/notbit-system-sendmail \
--set XDG_RUNTIME_DIR ${varDir}
'';
};
opts = "${optionalString cfg.allowPrivateAddresses "-L"} ${optionalString cfg.noBootstrap "-b"} ${optionalString cfg.specifiedPeersOnly "-e"}";
peers = concatStringsSep " " (map (str: "-P \"${str}\"") cfg.peers);
listen = if cfg.listenAddress == [] then "-p ${toString cfg.port}" else
concatStringsSep " " (map (addr: "-a \"${addr}:${toString cfg.port}\"") cfg.listenAddress);
in
with lib;
{
### configuration
options = {
services.notbit = {
enable = mkOption {
type = types.bool;
default = false;
description = ''
Enables the notbit daemon and provides a sendmail binary named `notbit-system-sendmail` for sending mail over the system instance of notbit. Users must be in the notbit group in order to send mail over the system notbit instance. Currently mail recipt is not supported.
'';
};
port = mkOption {
type = types.int;
default = 8444;
description = "The port which the daemon listens for other bitmessage clients";
};
nice = mkOption {
type = types.int;
default = 10;
description = "Set the nice level for the notbit daemon";
};
listenAddress = mkOption {
type = types.listOf types.str;
default = [ ];
example = [ "localhost" "myhostname" ];
description = "The addresses which notbit will use to listen for incoming connections. These addresses are advertised to connecting clients.";
};
peers = mkOption {
type = types.listOf types.str;
default = [ ];
example = [ "bitmessage.org:8877" ];
description = "The initial set of peers notbit will connect to.";
};
specifiedPeersOnly = mkOption {
type = types.bool;
default = false;
description = "If true, notbit will only connect to peers specified by the peers option.";
};
allowPrivateAddresses = mkOption {
type = types.bool;
default = false;
description = "If true, notbit will allow connections to to RFC 1918 addresses.";
};
noBootstrap = mkOption {
type = types.bool;
default = false;
description = "If true, notbit will not bootstrap an initial peerlist from bitmessage.org servers";
};
};
};
### implementation
config = mkIf cfg.enable {
environment.systemPackages = [ sendmail ];
systemd.services.notbit = {
description = "Notbit daemon";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
path = [ pkgs.notbit ];
environment = { XDG_RUNTIME_DIR = varDir; };
postStart = ''
[ ! -f "${varDir}/addr" ] && notbit-keygen > ${varDir}/addr
chmod 0640 ${varDir}/{addr,notbit/notbit-ipc.lock}
chmod 0750 ${varDir}/notbit/{,notbit-ipc}
'';
serviceConfig = {
Type = "forking";
ExecStart = "${pkgs.notbit}/bin/notbit -d ${listen} ${peers} ${opts}";
User = "notbit";
Group = "notbit";
UMask = "0077";
WorkingDirectory = varDir;
Nice = cfg.nice;
};
};
users.extraUsers.notbit = {
group = "notbit";
description = "Notbit daemon user";
home = varDir;
createHome = true;
uid = config.ids.uids.notbit;
};
users.extraGroups.notbit.gid = config.ids.gids.notbit;
};
}

View File

@ -20,18 +20,17 @@ with lib;
}; };
###### implementation ###### implementation
config = mkIf config.services.oidentd.enable { config = mkIf config.services.oidentd.enable {
systemd.services.oidentd = {
jobs.oidentd = after = [ "network-interfaces.target" ];
{ startOn = "started network-interfaces"; wantedBy = [ "multi-user.target" ];
daemonType = "fork"; serviceConfig.Type = "forking";
exec = "${pkgs.oidentd}/sbin/oidentd -u oidentd -g nogroup" + script = "${pkgs.oidentd}/sbin/oidentd -u oidentd -g nogroup" +
optionalString config.networking.enableIPv6 " -a ::" optionalString config.networking.enableIPv6 " -a ::";
; };
};
users.extraUsers.oidentd = { users.extraUsers.oidentd = {
description = "Ident Protocol daemon user"; description = "Ident Protocol daemon user";

View File

@ -2,17 +2,7 @@
with lib; with lib;
let
inherit (pkgs) jre openfire coreutils which gnugrep gawk gnused;
extraStartDependency =
if config.services.openfire.usePostgreSQL then "and started postgresql" else "";
in
{ {
###### interface ###### interface
options = { options = {
@ -47,26 +37,24 @@ in
message = "OpenFire assertion failed."; message = "OpenFire assertion failed.";
}; };
jobs.openfire = systemd.services.openfire = {
{ description = "OpenFire XMPP server"; description = "OpenFire XMPP server";
wantedBy = [ "multi-user.target" ];
startOn = "started networking ${extraStartDependency}"; after = [ "networking.target" ] ++
optional config.services.openfire.usePostgreSQL "postgresql.service";
script = path = with pkgs; [ jre openfire coreutils which gnugrep gawk gnused ];
'' script = ''
export PATH=${jre}/bin:${openfire}/bin:${coreutils}/bin:${which}/bin:${gnugrep}/bin:${gawk}/bin:${gnused}/bin export HOME=/tmp
export HOME=/tmp mkdir /var/log/openfire || true
mkdir /var/log/openfire || true mkdir /etc/openfire || true
mkdir /etc/openfire || true for i in ${openfire}/conf.inst/*; do
for i in ${openfire}/conf.inst/*; do if ! test -f /etc/openfire/$(basename $i); then
if ! test -f /etc/openfire/$(basename $i); then cp $i /etc/openfire/
cp $i /etc/openfire/ fi
fi done
done openfire start
openfire start ''; # */
''; # */ };
};
}; };
} }

View File

@ -0,0 +1,104 @@
{ config, lib, pkgs, ... }:
with lib;
let
pkg = pkgs.ostinato;
cfg = config.services.ostinato;
configFile = pkgs.writeText "drone.ini" ''
[General]
RateAccuracy=${cfg.rateAccuracy}
[RpcServer]
Address=${cfg.rpcServer.address}
[PortList]
Include=${concatStringsSep "," cfg.portList.include}
Exclude=${concatStringsSep "," cfg.portList.exclude}
'';
in
{
###### interface
options = {
services.ostinato = {
enable = mkEnableOption "Ostinato agent-controller (Drone)";
port = mkOption {
type = types.int;
default = 7878;
description = ''
Port to listen on.
'';
};
rateAccuracy = mkOption {
type = types.enum [ "High" "Low" ];
default = "High";
description = ''
To ensure that the actual transmit rate is as close as possible to
the configured transmit rate, Drone runs a busy-wait loop.
While this provides the maximum accuracy possible, the CPU
utilization is 100% while the transmit is on. You can however,
sacrifice the accuracy to reduce the CPU load.
'';
};
rpcServer = {
address = mkOption {
type = types.string;
default = "0.0.0.0";
description = ''
By default, the Drone RPC server will listen on all interfaces and
local IPv4 adresses for incoming connections from clients. Specify
a single IPv4 or IPv6 address if you want to restrict that.
To listen on any IPv6 address, use ::
'';
};
};
portList = {
include = mkOption {
type = types.listOf types.string;
default = [];
example = ''[ "eth*" "lo*" ]'';
description = ''
For a port to pass the filter and appear on the port list managed
by drone, it be allowed by this include list.
'';
};
exclude = mkOption {
type = types.listOf types.str;
default = [];
example = ''[ "usbmon*" "eth0" ]'';
description = ''
A list of ports does not appear on the port list managed by drone.
'';
};
};
};
};
###### implementation
config = mkIf cfg.enable {
environment.systemPackages = [ pkg ];
systemd.services.drone = {
description = "Ostinato agent-controller";
wantedBy = [ "multi-user.target" ];
script = ''
${pkg}/bin/drone ${toString cfg.port} ${configFile}
'';
};
};
}

View File

@ -83,21 +83,14 @@ in
gid = config.ids.gids.prayer; gid = config.ids.gids.prayer;
}; };
jobs.prayer = systemd.services.prayer = {
{ name = "prayer"; wantedBy = [ "multi-user.target" ];
serviceConfig.Type = "forking";
startOn = "startup"; preStart = ''
mkdir -m 0755 -p ${stateDir}
preStart = chown ${prayerUser}.${prayerGroup} ${stateDir}
'' '';
mkdir -m 0755 -p ${stateDir} script = "${prayer}/sbin/prayer --config-file=${prayerCfg}";
chown ${prayerUser}.${prayerGroup} ${stateDir} };
'';
daemonType = "daemon";
exec = "${prayer}/sbin/prayer --config-file=${prayerCfg}";
};
}; };
} }

View File

@ -33,16 +33,14 @@ in
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
environment.systemPackages = [ pkgs.pythonPackages.radicale ]; environment.systemPackages = [ pkgs.pythonPackages.radicale ];
jobs.radicale = { systemd.services.radicale = {
description = "A Simple Calendar and Contact Server"; description = "A Simple Calendar and Contact Server";
startOn = "started network-interfaces"; after = [ "network-interfaces.target" ];
exec = "${pkgs.pythonPackages.radicale}/bin/radicale -C ${confFile} -d"; wantedBy = [ "multi-user.target" ];
daemonType = "fork"; script = "${pkgs.pythonPackages.radicale}/bin/radicale -C ${confFile} -d";
serviceConfig.Type = "forking";
}; };
}; };
} }

View File

@ -19,7 +19,7 @@ in {
''; '';
}; };
host = mkOption { listenAddress = mkOption {
type = types.string; type = types.string;
default = "0.0.0.0"; default = "0.0.0.0";
description = "IP interface to listen on for http connections."; description = "IP interface to listen on for http connections.";
@ -66,7 +66,7 @@ in {
"${pkgs.shout}/bin/shout" "${pkgs.shout}/bin/shout"
(if cfg.private then "--private" else "--public") (if cfg.private then "--private" else "--public")
"--port" (toString cfg.port) "--port" (toString cfg.port)
"--host" (toString cfg.host) "--host" (toString cfg.listenAddress)
"--home" shoutHome "--home" shoutHome
]; ];
serviceConfig = { serviceConfig = {

View File

@ -61,9 +61,10 @@ in
dataDir = cfg.dataDir; dataDir = cfg.dataDir;
})) }))
]; ];
jobs.softether = { systemd.services.softether = {
description = "SoftEther VPN services initial job"; description = "SoftEther VPN services initial job";
startOn = "started network-interfaces"; after = [ "network-interfaces.target" ];
wantedBy = [ "multi-user.target" ];
preStart = '' preStart = ''
for d in vpnserver vpnbridge vpnclient vpncmd; do for d in vpnserver vpnbridge vpnclient vpncmd; do
if ! test -e ${cfg.dataDir}/$d; then if ! test -e ${cfg.dataDir}/$d; then
@ -74,7 +75,6 @@ in
rm -rf ${cfg.dataDir}/vpncmd/vpncmd rm -rf ${cfg.dataDir}/vpncmd/vpncmd
ln -s ${pkg}${cfg.dataDir}/vpncmd/vpncmd ${cfg.dataDir}/vpncmd/vpncmd ln -s ${pkg}${cfg.dataDir}/vpncmd/vpncmd ${cfg.dataDir}/vpncmd/vpncmd
''; '';
exec = "true";
}; };
} }

View File

@ -117,62 +117,60 @@ in
services.lshd.subsystems = [ ["sftp" "${pkgs.lsh}/sbin/sftp-server"] ]; services.lshd.subsystems = [ ["sftp" "${pkgs.lsh}/sbin/sftp-server"] ];
jobs.lshd = systemd.services.lshd = {
{ description = "GNU lshd SSH2 daemon"; description = "GNU lshd SSH2 daemon";
startOn = "started network-interfaces"; after = [ "network-interfaces.target" ];
stopOn = "stopping network-interfaces";
environment = wantedBy = [ "multi-user.target" ];
{ LD_LIBRARY_PATH = config.system.nssModules.path; };
preStart = environment = {
'' LD_LIBRARY_PATH = config.system.nssModules.path;
test -d /etc/lsh || mkdir -m 0755 -p /etc/lsh
test -d /var/spool/lsh || mkdir -m 0755 -p /var/spool/lsh
if ! test -f /var/spool/lsh/yarrow-seed-file
then
# XXX: It would be nice to provide feedback to the
# user when this fails, so that they can retry it
# manually.
${lsh}/bin/lsh-make-seed --sloppy \
-o /var/spool/lsh/yarrow-seed-file
fi
if ! test -f "${cfg.hostKey}"
then
${lsh}/bin/lsh-keygen --server | \
${lsh}/bin/lsh-writekey --server -o "${cfg.hostKey}"
fi
'';
exec = with cfg;
''
${lsh}/sbin/lshd --daemonic \
--password-helper="${lsh}/sbin/lsh-pam-checkpw" \
-p ${toString portNumber} \
${if interfaces == [] then ""
else (concatStrings (map (i: "--interface=\"${i}\"")
interfaces))} \
-h "${hostKey}" \
${if !syslog then "--no-syslog" else ""} \
${if passwordAuthentication then "--password" else "--no-password" } \
${if publicKeyAuthentication then "--publickey" else "--no-publickey" } \
${if rootLogin then "--root-login" else "--no-root-login" } \
${if loginShell != null then "--login-shell=\"${loginShell}\"" else "" } \
${if srpKeyExchange then "--srp-keyexchange" else "--no-srp-keyexchange" } \
${if !tcpForwarding then "--no-tcpip-forward" else "--tcpip-forward"} \
${if x11Forwarding then "--x11-forward" else "--no-x11-forward" } \
--subsystems=${concatStringsSep ","
(map (pair: (head pair) + "=" +
(head (tail pair)))
subsystems)}
'';
}; };
preStart = ''
test -d /etc/lsh || mkdir -m 0755 -p /etc/lsh
test -d /var/spool/lsh || mkdir -m 0755 -p /var/spool/lsh
if ! test -f /var/spool/lsh/yarrow-seed-file
then
# XXX: It would be nice to provide feedback to the
# user when this fails, so that they can retry it
# manually.
${lsh}/bin/lsh-make-seed --sloppy \
-o /var/spool/lsh/yarrow-seed-file
fi
if ! test -f "${cfg.hostKey}"
then
${lsh}/bin/lsh-keygen --server | \
${lsh}/bin/lsh-writekey --server -o "${cfg.hostKey}"
fi
'';
script = with cfg; ''
${lsh}/sbin/lshd --daemonic \
--password-helper="${lsh}/sbin/lsh-pam-checkpw" \
-p ${toString portNumber} \
${if interfaces == [] then ""
else (concatStrings (map (i: "--interface=\"${i}\"")
interfaces))} \
-h "${hostKey}" \
${if !syslog then "--no-syslog" else ""} \
${if passwordAuthentication then "--password" else "--no-password" } \
${if publicKeyAuthentication then "--publickey" else "--no-publickey" } \
${if rootLogin then "--root-login" else "--no-root-login" } \
${if loginShell != null then "--login-shell=\"${loginShell}\"" else "" } \
${if srpKeyExchange then "--srp-keyexchange" else "--no-srp-keyexchange" } \
${if !tcpForwarding then "--no-tcpip-forward" else "--tcpip-forward"} \
${if x11Forwarding then "--x11-forward" else "--no-x11-forward" } \
--subsystems=${concatStringsSep ","
(map (pair: (head pair) + "=" +
(head (tail pair)))
subsystems)}
'';
};
security.pam.services.lshd = {}; security.pam.services.lshd = {};
}; };
} }

View File

@ -16,7 +16,7 @@ let
listen: listen:
( (
{ host: "${cfg.host}"; port: "${toString cfg.port}"; } { host: "${cfg.listenAddress}"; port: "${toString cfg.port}"; }
); );
${cfg.appendConfig} ${cfg.appendConfig}
@ -56,7 +56,7 @@ in
description = "PID file path for sslh daemon."; description = "PID file path for sslh daemon.";
}; };
host = mkOption { listenAddress = mkOption {
type = types.str; type = types.str;
default = config.networking.hostName; default = config.networking.hostName;
description = "Listening hostname."; description = "Listening hostname.";

View File

@ -35,11 +35,11 @@ in
description = "tcpcrypt daemon user"; description = "tcpcrypt daemon user";
}; };
jobs.tcpcrypt = { systemd.services.tcpcrypt = {
description = "tcpcrypt"; description = "tcpcrypt";
wantedBy = ["multi-user.target"]; wantedBy = [ "multi-user.target" ];
after = ["network-interfaces.target"]; after = [ "network-interfaces.target" ];
path = [ pkgs.iptables pkgs.tcpcrypt pkgs.procps ]; path = [ pkgs.iptables pkgs.tcpcrypt pkgs.procps ];
@ -58,7 +58,7 @@ in
iptables -t mangle -I POSTROUTING -j nixos-tcpcrypt iptables -t mangle -I POSTROUTING -j nixos-tcpcrypt
''; '';
exec = "tcpcryptd -x 0x10"; script = "tcpcryptd -x 0x10";
postStop = '' postStop = ''
if [ -f /run/pre-tcpcrypt-ecn-state ]; then if [ -f /run/pre-tcpcrypt-ecn-state ]; then

View File

@ -43,6 +43,14 @@ in
''; '';
}; };
ed25519PrivateKeyFile = mkOption {
default = null;
type = types.nullOr types.path;
description = ''
Path of the private ed25519 keyfile.
'';
};
debugLevel = mkOption { debugLevel = mkOption {
default = 0; default = 0;
type = types.addCheck types.int (l: l >= 0 && l <= 5); type = types.addCheck types.int (l: l >= 0 && l <= 5);
@ -70,6 +78,14 @@ in
''; '';
}; };
listenAddress = mkOption {
default = null;
type = types.nullOr types.str;
description = ''
The ip adress to bind to.
'';
};
package = mkOption { package = mkOption {
default = pkgs.tinc_pre; default = pkgs.tinc_pre;
description = '' description = ''
@ -99,6 +115,8 @@ in
text = '' text = ''
Name = ${if data.name == null then "$HOST" else data.name} Name = ${if data.name == null then "$HOST" else data.name}
DeviceType = ${data.interfaceType} DeviceType = ${data.interfaceType}
${optionalString (data.ed25519PrivateKeyFile != null) "Ed25519PrivateKeyFile = ${data.ed25519PrivateKeyFile}"}
${optionalString (data.listenAddress != null) "BindToAddress = ${data.listenAddress}"}
Device = /dev/net/tun Device = /dev/net/tun
Interface = tinc.${network} Interface = tinc.${network}
${data.extraConfig} ${data.extraConfig}
@ -134,10 +152,10 @@ in
# Determine how we should generate our keys # Determine how we should generate our keys
if type tinc >/dev/null 2>&1; then if type tinc >/dev/null 2>&1; then
# Tinc 1.1+ uses the tinc helper application for key generation # Tinc 1.1+ uses the tinc helper application for key generation
${if data.ed25519PrivateKeyFile != null then " # Keyfile managed by nix" else ''
# Prefer ED25519 keys (only in 1.1+) # Prefer ED25519 keys (only in 1.1+)
[ -f "/etc/tinc/${network}/ed25519_key.priv" ] || tinc -n ${network} generate-ed25519-keys [ -f "/etc/tinc/${network}/ed25519_key.priv" ] || tinc -n ${network} generate-ed25519-keys
''}
# Otherwise use RSA keys # Otherwise use RSA keys
[ -f "/etc/tinc/${network}/rsa_key.priv" ] || tinc -n ${network} generate-rsa-keys 4096 [ -f "/etc/tinc/${network}/rsa_key.priv" ] || tinc -n ${network} generate-rsa-keys 4096
else else

View File

@ -25,17 +25,13 @@ with lib;
environment.systemPackages = [pkgs.wicd]; environment.systemPackages = [pkgs.wicd];
jobs.wicd = systemd.services.wicd = {
{ startOn = "started network-interfaces"; after = [ "network-interfaces.target" ];
stopOn = "stopping network-interfaces"; wantedBy = [ "multi-user.target" ];
script = "${pkgs.wicd}/sbin/wicd -f";
script = };
"${pkgs.wicd}/sbin/wicd -f";
};
services.dbus.enable = true; services.dbus.enable = true;
services.dbus.packages = [pkgs.wicd]; services.dbus.packages = [pkgs.wicd];
}; };
} }

View File

@ -3,51 +3,30 @@
with lib; with lib;
let let
cfg = config.networking.wireless; cfg = config.networking.wireless;
configFile = "/etc/wpa_supplicant.conf"; configFile = if cfg.networks != {} then pkgs.writeText "wpa_supplicant.conf" ''
${optionalString cfg.userControlled.enable ''
ifaces = ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=${cfg.userControlled.group}
cfg.interfaces ++ update_config=1''}
optional (config.networking.WLANInterface != "") config.networking.WLANInterface; ${concatStringsSep "\n" (mapAttrsToList (ssid: networkConfig: ''
network={
in ssid="${ssid}"
${optionalString (networkConfig.psk != null) ''psk="${networkConfig.psk}"''}
{ ${optionalString (networkConfig.psk == null) ''key_mgmt=NONE''}
}
###### interface '') cfg.networks)}
'' else "/etc/wpa_supplicant.conf";
in {
options = { options = {
networking.WLANInterface = mkOption {
default = "";
description = "Obsolete. Use <option>networking.wireless.interfaces</option> instead.";
};
networking.wireless = { networking.wireless = {
enable = mkOption { enable = mkEnableOption "wpa_supplicant";
type = types.bool;
default = false;
description = ''
Whether to start <command>wpa_supplicant</command> to scan for
and associate with wireless networks. Note: NixOS currently
does not manage <command>wpa_supplicant</command>'s
configuration file, <filename>${configFile}</filename>. You
should edit this file yourself to define wireless networks,
WPA keys and so on (see
<citerefentry><refentrytitle>wpa_supplicant.conf</refentrytitle>
<manvolnum>5</manvolnum></citerefentry>), or use
networking.wireless.userControlled.* to allow users to add entries
through <command>wpa_cli</command> and <command>wpa_gui</command>.
'';
};
interfaces = mkOption { interfaces = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = []; default = [];
example = [ "wlan0" "wlan1" ]; example = [ "wlan0" "wlan1" ];
description = '' description = ''
The interfaces <command>wpa_supplicant</command> will use. If empty, it will The interfaces <command>wpa_supplicant</command> will use. If empty, it will
automatically use all wireless interfaces. automatically use all wireless interfaces.
''; '';
}; };
@ -58,6 +37,37 @@ in
description = "Force a specific wpa_supplicant driver."; description = "Force a specific wpa_supplicant driver.";
}; };
networks = mkOption {
type = types.attrsOf (types.submodule {
options = {
psk = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
The network's pre-shared key in plaintext defaulting
to being a network without any authentication.
Be aware that these will be written to the nix store
in plaintext!
'';
};
};
});
description = ''
The network definitions to automatically connect to when
<command>wpa_supplicant</command> is running. If this
parameter is left empty wpa_supplicant will use
/etc/wpa_supplicant.conf as the configuration file.
'';
default = {};
example = literalExample ''
echelon = {
psk = "abcdefgh";
};
"free.wifi" = {};
'';
};
userControlled = { userControlled = {
enable = mkOption { enable = mkOption {
type = types.bool; type = types.bool;
@ -68,10 +78,8 @@ in
to depend on a large package such as NetworkManager just to pick nearby to depend on a large package such as NetworkManager just to pick nearby
access points. access points.
When you want to use this, make sure ${configFile} doesn't exist. When using a declarative network specification you cannot persist any
It will be created for you. settings via wpa_gui or wpa_cli.
Currently it is also necessary to explicitly specify networking.wireless.interfaces.
''; '';
}; };
@ -85,64 +93,49 @@ in
}; };
}; };
config = mkMerge [
(mkIf cfg.enable {
environment.systemPackages = [ pkgs.wpa_supplicant ];
###### implementation services.dbus.packages = [ pkgs.wpa_supplicant ];
config = mkIf cfg.enable { # FIXME: start a separate wpa_supplicant instance per interface.
systemd.services.wpa_supplicant = let
environment.systemPackages = [ pkgs.wpa_supplicant ]; ifaces = cfg.interfaces;
in {
services.dbus.packages = [ pkgs.wpa_supplicant ]; description = "WPA Supplicant";
# FIXME: start a separate wpa_supplicant instance per interface.
jobs.wpa_supplicant =
{ description = "WPA Supplicant";
wantedBy = [ "network.target" ]; wantedBy = [ "network.target" ];
path = [ pkgs.wpa_supplicant ]; path = [ pkgs.wpa_supplicant ];
preStart = '' script = ''
touch -a ${configFile} ${if ifaces == [] then ''
chmod 600 ${configFile} for i in $(cd /sys/class/net && echo *); do
'' + optionalString cfg.userControlled.enable '' DEVTYPE=
if [ ! -s ${configFile} ]; then source /sys/class/net/$i/uevent
echo "ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=${cfg.userControlled.group}" >> ${configFile} if [ "$DEVTYPE" = "wlan" -o -e /sys/class/net/$i/wireless ]; then
echo "update_config=1" >> ${configFile} ifaces="$ifaces''${ifaces:+ -N} -i$i"
fi fi
done
'' else ''
ifaces="${concatStringsSep " -N " (map (i: "-i${i}") ifaces)}"
''}
exec wpa_supplicant -s -u -D${cfg.driver} -c ${configFile} $ifaces
''; '';
script =
''
${if ifaces == [] then ''
for i in $(cd /sys/class/net && echo *); do
DEVTYPE=
source /sys/class/net/$i/uevent
if [ "$DEVTYPE" = "wlan" -o -e /sys/class/net/$i/wireless ]; then
ifaces="$ifaces''${ifaces:+ -N} -i$i"
fi
done
'' else ''
ifaces="${concatStringsSep " -N " (map (i: "-i${i}") ifaces)}"
''}
exec wpa_supplicant -s -u -D${cfg.driver} -c ${configFile} $ifaces
'';
}; };
powerManagement.resumeCommands = powerManagement.resumeCommands = ''
''
${config.systemd.package}/bin/systemctl try-restart wpa_supplicant ${config.systemd.package}/bin/systemctl try-restart wpa_supplicant
''; '';
assertions = [{ assertion = !cfg.userControlled.enable || cfg.interfaces != []; # Restart wpa_supplicant when a wlan device appears or disappears.
message = "user controlled wpa_supplicant needs explicit networking.wireless.interfaces";}]; services.udev.extraRules = ''
# Restart wpa_supplicant when a wlan device appears or disappears.
services.udev.extraRules =
''
ACTION=="add|remove", SUBSYSTEM=="net", ENV{DEVTYPE}=="wlan", RUN+="${config.systemd.package}/bin/systemctl try-restart wpa_supplicant.service" ACTION=="add|remove", SUBSYSTEM=="net", ENV{DEVTYPE}=="wlan", RUN+="${config.systemd.package}/bin/systemctl try-restart wpa_supplicant.service"
''; '';
})
}; {
meta.maintainers = with lib.maintainers; [ globin ];
}
];
} }

View File

@ -6,8 +6,6 @@ let
cfg = config.services.xinetd; cfg = config.services.xinetd;
inherit (pkgs) xinetd;
configFile = pkgs.writeText "xinetd.conf" configFile = pkgs.writeText "xinetd.conf"
'' ''
defaults defaults
@ -141,18 +139,12 @@ in
###### implementation ###### implementation
config = mkIf cfg.enable { config = mkIf cfg.enable {
systemd.services.xinetd = {
jobs.xinetd = description = "xinetd server";
{ description = "xinetd server"; after = [ "network-interfaces.target" ];
wantedBy = [ "multi-user.target" ];
startOn = "started network-interfaces"; path = [ pkgs.xinetd ];
stopOn = "stopping network-interfaces"; script = "xinetd -syslog daemon -dontfork -stayalive -f ${configFile}";
};
path = [ xinetd ];
exec = "xinetd -syslog daemon -dontfork -stayalive -f ${configFile}";
};
}; };
} }

View File

@ -66,49 +66,47 @@ in
gid = config.ids.gids.atd; gid = config.ids.gids.atd;
}; };
jobs.atd = systemd.services.atd = {
{ description = "Job Execution Daemon (atd)"; description = "Job Execution Daemon (atd)";
after = [ "systemd-udev-settle.service" ];
wants = [ "systemd-udev-settle.service" ];
wantedBy = [ "multi-user.target" ];
startOn = "stopped udevtrigger"; path = [ at ];
path = [ at ]; preStart = ''
# Snippets taken and adapted from the original `install' rule of
# the makefile.
preStart = # We assume these values are those actually used in Nixpkgs for
'' # `at'.
# Snippets taken and adapted from the original `install' rule of spooldir=/var/spool/atspool
# the makefile. jobdir=/var/spool/atjobs
etcdir=/etc/at
# We assume these values are those actually used in Nixpkgs for for dir in "$spooldir" "$jobdir" "$etcdir"; do
# `at'. if [ ! -d "$dir" ]; then
spooldir=/var/spool/atspool mkdir -p "$dir"
jobdir=/var/spool/atjobs chown atd:atd "$dir"
etcdir=/etc/at fi
done
chmod 1770 "$spooldir" "$jobdir"
${if cfg.allowEveryone then ''chmod a+rwxt "$spooldir" "$jobdir" '' else ""}
if [ ! -f "$etcdir"/at.deny ]; then
touch "$etcdir"/at.deny
chown root:atd "$etcdir"/at.deny
chmod 640 "$etcdir"/at.deny
fi
if [ ! -f "$jobdir"/.SEQ ]; then
touch "$jobdir"/.SEQ
chown atd:atd "$jobdir"/.SEQ
chmod 600 "$jobdir"/.SEQ
fi
'';
for dir in "$spooldir" "$jobdir" "$etcdir"; do script = "atd";
if [ ! -d "$dir" ]; then
mkdir -p "$dir"
chown atd:atd "$dir"
fi
done
chmod 1770 "$spooldir" "$jobdir"
${if cfg.allowEveryone then ''chmod a+rwxt "$spooldir" "$jobdir" '' else ""}
if [ ! -f "$etcdir"/at.deny ]; then
touch "$etcdir"/at.deny
chown root:atd "$etcdir"/at.deny
chmod 640 "$etcdir"/at.deny
fi
if [ ! -f "$jobdir"/.SEQ ]; then
touch "$jobdir"/.SEQ
chown atd:atd "$jobdir"/.SEQ
chmod 600 "$jobdir"/.SEQ
fi
'';
exec = "atd";
daemonType = "fork";
};
serviceConfig.Type = "forking";
};
}; };
} }

View File

@ -108,29 +108,25 @@ in
security.setuidPrograms = [ "fcrontab" ]; security.setuidPrograms = [ "fcrontab" ];
jobs.fcron = systemd.services.fcron = {
{ description = "fcron daemon"; description = "fcron daemon";
after = [ "local-fs.target" ];
wantedBy = [ "multi-user.target" ];
startOn = "startup"; # FIXME use specific path
environment = {
after = [ "local-fs.target" ]; PATH = "/run/current-system/sw/bin";
environment =
{ PATH = "/run/current-system/sw/bin";
};
preStart =
''
${pkgs.coreutils}/bin/mkdir -m 0700 -p /var/spool/fcron
# load system crontab file
${pkgs.fcron}/bin/fcrontab -u systab ${pkgs.writeText "systab" cfg.systab}
'';
daemonType = "fork";
exec = "${pkgs.fcron}/sbin/fcron -m ${toString cfg.maxSerialJobs} ${queuelen}";
}; };
}; preStart = ''
${pkgs.coreutils}/bin/mkdir -m 0700 -p /var/spool/fcron
# load system crontab file
${pkgs.fcron}/bin/fcrontab -u systab ${pkgs.writeText "systab" cfg.systab}
'';
serviceConfig.Type = "forking";
script = "${pkgs.fcron}/sbin/fcron -m ${toString cfg.maxSerialJobs} ${queuelen}";
};
};
} }

View File

@ -6,7 +6,7 @@ let
cfg = config.services.elasticsearch; cfg = config.services.elasticsearch;
esConfig = '' esConfig = ''
network.host: ${cfg.host} network.host: ${cfg.listenAddress}
network.port: ${toString cfg.port} network.port: ${toString cfg.port}
network.tcp.port: ${toString cfg.tcp_port} network.tcp.port: ${toString cfg.tcp_port}
cluster.name: ${cfg.cluster_name} cluster.name: ${cfg.cluster_name}
@ -43,7 +43,7 @@ in {
type = types.package; type = types.package;
}; };
host = mkOption { listenAddress = mkOption {
description = "Elasticsearch listen address."; description = "Elasticsearch listen address.";
default = "127.0.0.1"; default = "127.0.0.1";
type = types.str; type = types.str;
@ -142,7 +142,7 @@ in {
ln -s ${esPlugins}/plugins ${cfg.dataDir}/plugins ln -s ${esPlugins}/plugins ${cfg.dataDir}/plugins
''; '';
postStart = mkBefore '' postStart = mkBefore ''
until ${pkgs.curl}/bin/curl -s -o /dev/null ${cfg.host}:${toString cfg.port}; do until ${pkgs.curl}/bin/curl -s -o /dev/null ${cfg.listenAddress}:${toString cfg.port}; do
sleep 1 sleep 1
done done
''; '';

View File

@ -8,7 +8,7 @@ let
cfgFile = pkgs.writeText "kibana.json" (builtins.toJSON ( cfgFile = pkgs.writeText "kibana.json" (builtins.toJSON (
(filterAttrsRecursive (n: v: v != null) ({ (filterAttrsRecursive (n: v: v != null) ({
server = { server = {
host = cfg.host; host = cfg.listenAddress;
port = cfg.port; port = cfg.port;
ssl = { ssl = {
cert = cfg.cert; cert = cfg.cert;
@ -44,7 +44,7 @@ in {
options.services.kibana = { options.services.kibana = {
enable = mkEnableOption "enable kibana service"; enable = mkEnableOption "enable kibana service";
host = mkOption { listenAddress = mkOption {
description = "Kibana listening host"; description = "Kibana listening host";
default = "127.0.0.1"; default = "127.0.0.1";
type = types.str; type = types.str;

View File

@ -67,24 +67,22 @@ in {
services.cron.systemCronJobs = [ "*/${toString cfg.updater.frequency} * * * * root start fprot-updater" ]; services.cron.systemCronJobs = [ "*/${toString cfg.updater.frequency} * * * * root start fprot-updater" ];
jobs = { systemd.services."fprot-updater" = {
fprot_updater = { serviceConfig = {
name = "fprot-updater"; Type = "oneshot";
task = true; RemainAfterExit = false;
# have to copy fpupdate executable because it insists on storing the virus database in the same dir
preStart = ''
mkdir -m 0755 -p ${stateDir}
chown ${fprotUser}:${fprotGroup} ${stateDir}
cp ${pkgs.fprot}/opt/f-prot/fpupdate ${stateDir}
ln -sf ${cfg.updater.productData} ${stateDir}/product.data
'';
#setuid = fprotUser;
#setgid = fprotGroup;
exec = "/var/lib/fprot/fpupdate --keyfile ${cfg.updater.licenseKeyfile}";
}; };
wantedBy = [ "multi-user.target" ];
# have to copy fpupdate executable because it insists on storing the virus database in the same dir
preStart = ''
mkdir -m 0755 -p ${stateDir}
chown ${fprotUser}:${fprotGroup} ${stateDir}
cp ${pkgs.fprot}/opt/f-prot/fpupdate ${stateDir}
ln -sf ${cfg.updater.productData} ${stateDir}/product.data
'';
script = "/var/lib/fprot/fpupdate --keyfile ${cfg.updater.licenseKeyfile}";
}; };
}; };
} }

View File

@ -45,27 +45,20 @@ in
serverArgs = "${pkgs.heimdal}/sbin/kadmind"; serverArgs = "${pkgs.heimdal}/sbin/kadmind";
}; };
jobs.kdc = systemd.services.kdc = {
{ description = "Kerberos Domain Controller daemon"; description = "Kerberos Domain Controller daemon";
wantedBy = [ "multi-user.target" ];
preStart = ''
mkdir -m 0755 -p ${stateDir}
'';
script = "${heimdal}/sbin/kdc";
};
startOn = "ip-up"; systemd.services.kpasswdd = {
description = "Kerberos Domain Controller daemon";
preStart = wantedBy = [ "multi-user.target" ];
'' script = "${heimdal}/sbin/kpasswdd";
mkdir -m 0755 -p ${stateDir} };
'';
exec = "${heimdal}/sbin/kdc";
};
jobs.kpasswdd =
{ description = "Kerberos Domain Controller daemon";
startOn = "ip-up";
exec = "${heimdal}/sbin/kpasswdd";
};
}; };
} }

View File

@ -45,23 +45,21 @@ in
home = stateDir; home = stateDir;
}; };
jobs.uptimed = systemd.services.uptimed = {
{ description = "Uptimed daemon"; description = "Uptimed daemon";
wantedBy = [ "multi-user.target" ];
startOn = "startup"; preStart = ''
mkdir -m 0755 -p ${stateDir}
chown ${uptimedUser} ${stateDir}
preStart = if ! test -f ${stateDir}/bootid ; then
'' ${uptimed}/sbin/uptimed -b
mkdir -m 0755 -p ${stateDir} fi
chown ${uptimedUser} ${stateDir} '';
if ! test -f ${stateDir}/bootid ; then script = "${uptimed}/sbin/uptimed";
${uptimed}/sbin/uptimed -b };
fi
'';
exec = "${uptimed}/sbin/uptimed";
};
}; };

View File

@ -2,6 +2,13 @@
with lib; with lib;
let
autologinArg = optionalString (config.services.mingetty.autologinUser != null) "--autologin ${config.services.mingetty.autologinUser}";
gettyCmd = extraArgs: "@${pkgs.utillinux}/sbin/agetty agetty --login-program ${pkgs.shadow}/bin/login ${autologinArg} ${extraArgs}";
in
{ {
###### interface ###### interface
@ -21,9 +28,9 @@ with lib;
greetingLine = mkOption { greetingLine = mkOption {
type = types.str; type = types.str;
default = ''<<< Welcome to NixOS ${config.system.nixosVersion} (\m) - \l >>>'';
description = '' description = ''
Welcome line printed by mingetty. Welcome line printed by mingetty.
The default shows current NixOS version label, machine type and tty.
''; '';
}; };
@ -55,10 +62,11 @@ with lib;
###### implementation ###### implementation
config = let config = {
autologinArg = optionalString (config.services.mingetty.autologinUser != null) "--autologin ${config.services.mingetty.autologinUser}"; # Note: this is set here rather than up there so that changing
gettyCmd = extraArgs: "@${pkgs.utillinux}/sbin/agetty agetty --login-program ${pkgs.shadow}/bin/login ${autologinArg} ${extraArgs}"; # nixosLabel would not rebuild manual pages
in { services.mingetty.greetingLine = mkDefault ''<<< Welcome to NixOS ${config.system.nixosLabel} (\m) - \l >>>'';
systemd.services."getty@" = systemd.services."getty@" =
{ serviceConfig.ExecStart = gettyCmd "--noclear --keep-baud %I 115200,38400,9600 $TERM"; { serviceConfig.ExecStart = gettyCmd "--noclear --keep-baud %I 115200,38400,9600 $TERM";
restartIfChanged = false; restartIfChanged = false;
@ -81,7 +89,7 @@ with lib;
{ serviceConfig.ExecStart = gettyCmd "--noclear --keep-baud console 115200,38400,9600 $TERM"; { serviceConfig.ExecStart = gettyCmd "--noclear --keep-baud console 115200,38400,9600 $TERM";
serviceConfig.Restart = "always"; serviceConfig.Restart = "always";
restartIfChanged = false; restartIfChanged = false;
enable = mkDefault config.boot.isContainer; enable = mkDefault config.boot.isContainer;
}; };
environment.etc = singleton environment.etc = singleton

View File

@ -71,13 +71,10 @@ in
###### implementation ###### implementation
config = mkIf config.services.jboss.enable { config = mkIf config.services.jboss.enable {
systemd.services.jboss = {
jobs.jboss = description = "JBoss server";
{ description = "JBoss server"; script = "${jbossService}/bin/control start";
wantedBy = [ "multi-user.target" ];
exec = "${jbossService}/bin/control start"; };
};
}; };
} }

View File

@ -127,124 +127,206 @@ in
extraGroups = cfg.extraGroups; extraGroups = cfg.extraGroups;
}; };
jobs.tomcat = systemd.services.tomcat = {
{ description = "Apache Tomcat server"; description = "Apache Tomcat server";
wantedBy = [ "multi-user.target" ];
after = [ "network-interfaces.target" ];
serviceConfig.Type = "oneshot";
serviceConfig.RemainAfterExit = true;
startOn = "started network-interfaces"; preStart = ''
stopOn = "stopping network-interfaces"; # Create the base directory
mkdir -p ${cfg.baseDir}
daemonType = "daemon"; # Create a symlink to the bin directory of the tomcat component
ln -sfn ${tomcat}/bin ${cfg.baseDir}/bin
# Create a conf/ directory
mkdir -p ${cfg.baseDir}/conf
chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/conf
# Symlink the config files in the conf/ directory (except for catalina.properties and server.xml)
for i in $(ls ${tomcat}/conf | grep -v catalina.properties | grep -v server.xml)
do
ln -sfn ${tomcat}/conf/$i ${cfg.baseDir}/conf/`basename $i`
done
# Create subdirectory for virtual hosts
mkdir -p ${cfg.baseDir}/virtualhosts
# Create a modified catalina.properties file
# Change all references from CATALINA_HOME to CATALINA_BASE and add support for shared libraries
sed -e 's|''${catalina.home}|''${catalina.base}|g' \
-e 's|shared.loader=|shared.loader=''${catalina.base}/shared/lib/*.jar|' \
${tomcat}/conf/catalina.properties > ${cfg.baseDir}/conf/catalina.properties
# Create a modified server.xml which also includes all virtual hosts
sed -e "/<Engine name=\"Catalina\" defaultHost=\"localhost\">/a\ ${
toString (map (virtualHost: ''<Host name=\"${virtualHost.name}\" appBase=\"virtualhosts/${virtualHost.name}/webapps\" unpackWARs=\"true\" autoDeploy=\"true\" xmlValidation=\"false\" xmlNamespaceAware=\"false\" >${if cfg.logPerVirtualHost then ''<Valve className=\"org.apache.catalina.valves.AccessLogValve\" directory=\"logs/${virtualHost.name}\" prefix=\"${virtualHost.name}_access_log.\" pattern=\"combined\" resolveHosts=\"false\"/>'' else ""}</Host>'') cfg.virtualHosts)}" \
${tomcat}/conf/server.xml > ${cfg.baseDir}/conf/server.xml
# Create a logs/ directory
mkdir -p ${cfg.baseDir}/logs
chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/logs
${if cfg.logPerVirtualHost then
toString (map (h: ''
mkdir -p ${cfg.baseDir}/logs/${h.name}
chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/logs/${h.name}
'') cfg.virtualHosts) else ''''}
# Create a temp/ directory
mkdir -p ${cfg.baseDir}/temp
chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/temp
# Create a lib/ directory
mkdir -p ${cfg.baseDir}/lib
chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/lib
# Create a shared/lib directory
mkdir -p ${cfg.baseDir}/shared/lib
chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/shared/lib
# Create a webapps/ directory
mkdir -p ${cfg.baseDir}/webapps
chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/webapps
# Symlink all the given common libs files or paths into the lib/ directory
for i in ${tomcat} ${toString cfg.commonLibs}
do
if [ -f $i ]
then
# If the given web application is a file, symlink it into the common/lib/ directory
ln -sfn $i ${cfg.baseDir}/lib/`basename $i`
elif [ -d $i ]
then
# If the given web application is a directory, then iterate over the files
# in the special purpose directories and symlink them into the tomcat tree
for j in $i/lib/*
do
ln -sfn $j ${cfg.baseDir}/lib/`basename $j`
done
fi
done
# Symlink all the given shared libs files or paths into the shared/lib/ directory
for i in ${toString cfg.sharedLibs}
do
if [ -f $i ]
then
# If the given web application is a file, symlink it into the common/lib/ directory
ln -sfn $i ${cfg.baseDir}/shared/lib/`basename $i`
elif [ -d $i ]
then
# If the given web application is a directory, then iterate over the files
# in the special purpose directories and symlink them into the tomcat tree
for j in $i/shared/lib/*
do
ln -sfn $j ${cfg.baseDir}/shared/lib/`basename $j`
done
fi
done
# Symlink all the given web applications files or paths into the webapps/ directory
for i in ${toString cfg.webapps}
do
if [ -f $i ]
then
# If the given web application is a file, symlink it into the webapps/ directory
ln -sfn $i ${cfg.baseDir}/webapps/`basename $i`
elif [ -d $i ]
then
# If the given web application is a directory, then iterate over the files
# in the special purpose directories and symlink them into the tomcat tree
for j in $i/webapps/*
do
ln -sfn $j ${cfg.baseDir}/webapps/`basename $j`
done
# Also symlink the configuration files if they are included
if [ -d $i/conf/Catalina ]
then
for j in $i/conf/Catalina/*
do
mkdir -p ${cfg.baseDir}/conf/Catalina/localhost
ln -sfn $j ${cfg.baseDir}/conf/Catalina/localhost/`basename $j`
done
fi
fi
done
${toString (map (virtualHost: ''
# Create webapps directory for the virtual host
mkdir -p ${cfg.baseDir}/virtualhosts/${virtualHost.name}/webapps
# Modify ownership
chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/virtualhosts/${virtualHost.name}/webapps
# Symlink all the given web applications files or paths into the webapps/ directory
# of this virtual host
for i in "${if virtualHost ? webapps then toString virtualHost.webapps else ""}"
do
if [ -f $i ]
then
# If the given web application is a file, symlink it into the webapps/ directory
ln -sfn $i ${cfg.baseDir}/virtualhosts/${virtualHost.name}/webapps/`basename $i`
elif [ -d $i ]
then
# If the given web application is a directory, then iterate over the files
# in the special purpose directories and symlink them into the tomcat tree
for j in $i/webapps/*
do
ln -sfn $j ${cfg.baseDir}/virtualhosts/${virtualHost.name}/webapps/`basename $j`
done
# Also symlink the configuration files if they are included
if [ -d $i/conf/Catalina ]
then
for j in $i/conf/Catalina/*
do
mkdir -p ${cfg.baseDir}/conf/Catalina/${virtualHost.name}
ln -sfn $j ${cfg.baseDir}/conf/Catalina/${virtualHost.name}/`basename $j`
done
fi
fi
done
preStart =
'' ''
# Create the base directory ) cfg.virtualHosts) }
mkdir -p ${cfg.baseDir}
# Create a symlink to the bin directory of the tomcat component # Create a work/ directory
ln -sfn ${tomcat}/bin ${cfg.baseDir}/bin mkdir -p ${cfg.baseDir}/work
chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/work
# Create a conf/ directory ${if cfg.axis2.enable then
mkdir -p ${cfg.baseDir}/conf ''
chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/conf # Copy the Axis2 web application
cp -av ${pkgs.axis2}/webapps/axis2 ${cfg.baseDir}/webapps
# Symlink the config files in the conf/ directory (except for catalina.properties and server.xml) # Turn off addressing, which causes many errors
for i in $(ls ${tomcat}/conf | grep -v catalina.properties | grep -v server.xml) sed -i -e 's%<module ref="addressing"/>%<!-- <module ref="addressing"/> -->%' ${cfg.baseDir}/webapps/axis2/WEB-INF/conf/axis2.xml
do
ln -sfn ${tomcat}/conf/$i ${cfg.baseDir}/conf/`basename $i`
done
# Create subdirectory for virtual hosts # Modify permissions on the Axis2 application
mkdir -p ${cfg.baseDir}/virtualhosts chown -R ${cfg.user}:${cfg.group} ${cfg.baseDir}/webapps/axis2
# Create a modified catalina.properties file # Symlink all the given web service files or paths into the webapps/axis2/WEB-INF/services directory
# Change all references from CATALINA_HOME to CATALINA_BASE and add support for shared libraries for i in ${toString cfg.axis2.services}
sed -e 's|''${catalina.home}|''${catalina.base}|g' \
-e 's|shared.loader=|shared.loader=''${catalina.base}/shared/lib/*.jar|' \
${tomcat}/conf/catalina.properties > ${cfg.baseDir}/conf/catalina.properties
# Create a modified server.xml which also includes all virtual hosts
sed -e "/<Engine name=\"Catalina\" defaultHost=\"localhost\">/a\ ${
toString (map (virtualHost: ''<Host name=\"${virtualHost.name}\" appBase=\"virtualhosts/${virtualHost.name}/webapps\" unpackWARs=\"true\" autoDeploy=\"true\" xmlValidation=\"false\" xmlNamespaceAware=\"false\" >${if cfg.logPerVirtualHost then ''<Valve className=\"org.apache.catalina.valves.AccessLogValve\" directory=\"logs/${virtualHost.name}\" prefix=\"${virtualHost.name}_access_log.\" pattern=\"combined\" resolveHosts=\"false\"/>'' else ""}</Host>'') cfg.virtualHosts)}" \
${tomcat}/conf/server.xml > ${cfg.baseDir}/conf/server.xml
# Create a logs/ directory
mkdir -p ${cfg.baseDir}/logs
chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/logs
${if cfg.logPerVirtualHost then
toString (map (h: ''
mkdir -p ${cfg.baseDir}/logs/${h.name}
chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/logs/${h.name}
'') cfg.virtualHosts) else ''''}
# Create a temp/ directory
mkdir -p ${cfg.baseDir}/temp
chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/temp
# Create a lib/ directory
mkdir -p ${cfg.baseDir}/lib
chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/lib
# Create a shared/lib directory
mkdir -p ${cfg.baseDir}/shared/lib
chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/shared/lib
# Create a webapps/ directory
mkdir -p ${cfg.baseDir}/webapps
chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/webapps
# Symlink all the given common libs files or paths into the lib/ directory
for i in ${tomcat} ${toString cfg.commonLibs}
do do
if [ -f $i ] if [ -f $i ]
then then
# If the given web application is a file, symlink it into the common/lib/ directory # If the given web service is a file, symlink it into the webapps/axis2/WEB-INF/services
ln -sfn $i ${cfg.baseDir}/lib/`basename $i` ln -sfn $i ${cfg.baseDir}/webapps/axis2/WEB-INF/services/`basename $i`
elif [ -d $i ] elif [ -d $i ]
then then
# If the given web application is a directory, then iterate over the files # If the given web application is a directory, then iterate over the files
# in the special purpose directories and symlink them into the tomcat tree # in the special purpose directories and symlink them into the tomcat tree
for j in $i/lib/* for j in $i/webapps/axis2/WEB-INF/services/*
do do
ln -sfn $j ${cfg.baseDir}/lib/`basename $j` ln -sfn $j ${cfg.baseDir}/webapps/axis2/WEB-INF/services/`basename $j`
done
fi
done
# Symlink all the given shared libs files or paths into the shared/lib/ directory
for i in ${toString cfg.sharedLibs}
do
if [ -f $i ]
then
# If the given web application is a file, symlink it into the common/lib/ directory
ln -sfn $i ${cfg.baseDir}/shared/lib/`basename $i`
elif [ -d $i ]
then
# If the given web application is a directory, then iterate over the files
# in the special purpose directories and symlink them into the tomcat tree
for j in $i/shared/lib/*
do
ln -sfn $j ${cfg.baseDir}/shared/lib/`basename $j`
done
fi
done
# Symlink all the given web applications files or paths into the webapps/ directory
for i in ${toString cfg.webapps}
do
if [ -f $i ]
then
# If the given web application is a file, symlink it into the webapps/ directory
ln -sfn $i ${cfg.baseDir}/webapps/`basename $i`
elif [ -d $i ]
then
# If the given web application is a directory, then iterate over the files
# in the special purpose directories and symlink them into the tomcat tree
for j in $i/webapps/*
do
ln -sfn $j ${cfg.baseDir}/webapps/`basename $j`
done done
# Also symlink the configuration files if they are included # Also symlink the configuration files if they are included
@ -252,110 +334,25 @@ in
then then
for j in $i/conf/Catalina/* for j in $i/conf/Catalina/*
do do
mkdir -p ${cfg.baseDir}/conf/Catalina/localhost
ln -sfn $j ${cfg.baseDir}/conf/Catalina/localhost/`basename $j` ln -sfn $j ${cfg.baseDir}/conf/Catalina/localhost/`basename $j`
done done
fi fi
fi fi
done done
''
else ""}
'';
${toString (map (virtualHost: '' script = ''
# Create webapps directory for the virtual host ${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c 'CATALINA_BASE=${cfg.baseDir} JAVA_HOME=${cfg.jdk} JAVA_OPTS="${cfg.javaOpts}" CATALINA_OPTS="${cfg.catalinaOpts}" ${tomcat}/bin/startup.sh'
mkdir -p ${cfg.baseDir}/virtualhosts/${virtualHost.name}/webapps '';
# Modify ownership postStop = ''
chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/virtualhosts/${virtualHost.name}/webapps echo "Stopping tomcat..."
CATALINA_BASE=${cfg.baseDir} JAVA_HOME=${cfg.jdk} ${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c ${tomcat}/bin/shutdown.sh
'';
# Symlink all the given web applications files or paths into the webapps/ directory };
# of this virtual host
for i in "${if virtualHost ? webapps then toString virtualHost.webapps else ""}"
do
if [ -f $i ]
then
# If the given web application is a file, symlink it into the webapps/ directory
ln -sfn $i ${cfg.baseDir}/virtualhosts/${virtualHost.name}/webapps/`basename $i`
elif [ -d $i ]
then
# If the given web application is a directory, then iterate over the files
# in the special purpose directories and symlink them into the tomcat tree
for j in $i/webapps/*
do
ln -sfn $j ${cfg.baseDir}/virtualhosts/${virtualHost.name}/webapps/`basename $j`
done
# Also symlink the configuration files if they are included
if [ -d $i/conf/Catalina ]
then
for j in $i/conf/Catalina/*
do
mkdir -p ${cfg.baseDir}/conf/Catalina/${virtualHost.name}
ln -sfn $j ${cfg.baseDir}/conf/Catalina/${virtualHost.name}/`basename $j`
done
fi
fi
done
''
) cfg.virtualHosts) }
# Create a work/ directory
mkdir -p ${cfg.baseDir}/work
chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/work
${if cfg.axis2.enable then
''
# Copy the Axis2 web application
cp -av ${pkgs.axis2}/webapps/axis2 ${cfg.baseDir}/webapps
# Turn off addressing, which causes many errors
sed -i -e 's%<module ref="addressing"/>%<!-- <module ref="addressing"/> -->%' ${cfg.baseDir}/webapps/axis2/WEB-INF/conf/axis2.xml
# Modify permissions on the Axis2 application
chown -R ${cfg.user}:${cfg.group} ${cfg.baseDir}/webapps/axis2
# Symlink all the given web service files or paths into the webapps/axis2/WEB-INF/services directory
for i in ${toString cfg.axis2.services}
do
if [ -f $i ]
then
# If the given web service is a file, symlink it into the webapps/axis2/WEB-INF/services
ln -sfn $i ${cfg.baseDir}/webapps/axis2/WEB-INF/services/`basename $i`
elif [ -d $i ]
then
# If the given web application is a directory, then iterate over the files
# in the special purpose directories and symlink them into the tomcat tree
for j in $i/webapps/axis2/WEB-INF/services/*
do
ln -sfn $j ${cfg.baseDir}/webapps/axis2/WEB-INF/services/`basename $j`
done
# Also symlink the configuration files if they are included
if [ -d $i/conf/Catalina ]
then
for j in $i/conf/Catalina/*
do
ln -sfn $j ${cfg.baseDir}/conf/Catalina/localhost/`basename $j`
done
fi
fi
done
''
else ""}
'';
script = ''
${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c 'CATALINA_BASE=${cfg.baseDir} JAVA_HOME=${cfg.jdk} JAVA_OPTS="${cfg.javaOpts}" CATALINA_OPTS="${cfg.catalinaOpts}" ${tomcat}/bin/startup.sh'
'';
postStop =
''
echo "Stopping tomcat..."
CATALINA_BASE=${cfg.baseDir} JAVA_HOME=${cfg.jdk} ${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c ${tomcat}/bin/shutdown.sh
'';
};
}; };

View File

@ -102,6 +102,7 @@ in
kde5.gwenview kde5.gwenview
kde5.kate kde5.kate
kde5.kdegraphics-thumbnailers kde5.kdegraphics-thumbnailers
kde5.kio-extras
kde5.konsole kde5.konsole
kde5.okular kde5.okular
kde5.print-manager kde5.print-manager
@ -125,6 +126,7 @@ in
++ lib.optional config.networking.networkmanager.enable kde5.plasma-nm ++ lib.optional config.networking.networkmanager.enable kde5.plasma-nm
++ lib.optional config.hardware.pulseaudio.enable kde5.plasma-pa ++ lib.optional config.hardware.pulseaudio.enable kde5.plasma-pa
++ lib.optional config.powerManagement.enable kde5.powerdevil ++ lib.optional config.powerManagement.enable kde5.powerdevil
++ lib.optionals config.services.samba.enable [ kde5.kdenetwork-filesharing pkgs.samba ]
++ lib.optionals cfg.phonon.gstreamer.enable ++ lib.optionals cfg.phonon.gstreamer.enable
[ [

View File

@ -57,6 +57,7 @@ let
kdmrc = pkgs.stdenv.mkDerivation { kdmrc = pkgs.stdenv.mkDerivation {
name = "kdmrc"; name = "kdmrc";
config = defaultConfig + cfg.extraConfig; config = defaultConfig + cfg.extraConfig;
preferLocalBuild = true;
buildCommand = buildCommand =
'' ''
echo "$config" > $out echo "$config" > $out

View File

@ -30,20 +30,17 @@ in
###### implementation ###### implementation
config = mkIf config.services.xfs.enable { config = mkIf config.services.xfs.enable {
assertions = singleton assertions = singleton
{ assertion = config.fonts.enableFontDir; { assertion = config.fonts.enableFontDir;
message = "Please enable fonts.enableFontDir to use the X Font Server."; message = "Please enable fonts.enableFontDir to use the X Font Server.";
}; };
jobs.xfs = systemd.services.xfs = {
{ description = "X Font Server"; description = "X Font Server";
after = [ "network.target" ];
startOn = "started networking"; wantedBy = [ "multi-user.target" ];
path = [ pkgs.xorg.xfs ];
exec = "${pkgs.xorg.xfs}/bin/xfs -config ${configFile}"; script = "xfs -config ${configFile}";
}; };
}; };
} }

View File

@ -13,7 +13,6 @@ let
# Map video driver names to driver packages. FIXME: move into card-specific modules. # Map video driver names to driver packages. FIXME: move into card-specific modules.
knownVideoDrivers = { knownVideoDrivers = {
unichrome = { modules = [ pkgs.xorgVideoUnichrome ]; };
virtualbox = { modules = [ kernelPackages.virtualboxGuestAdditions ]; driverName = "vboxvideo"; }; virtualbox = { modules = [ kernelPackages.virtualboxGuestAdditions ]; driverName = "vboxvideo"; };
ati = { modules = [ pkgs.xorg.xf86videoati pkgs.xorg.glamoregl ]; }; ati = { modules = [ pkgs.xorg.xf86videoati pkgs.xorg.glamoregl ]; };
intel-testing = { modules = with pkgs.xorg; [ xf86videointel-testing glamoregl ]; driverName = "intel"; }; intel-testing = { modules = with pkgs.xorg; [ xf86videointel-testing glamoregl ]; driverName = "intel"; };
@ -503,7 +502,7 @@ in
systemd.services.display-manager = systemd.services.display-manager =
{ description = "X11 Server"; { description = "X11 Server";
after = [ "systemd-udev-settle.service" "local-fs.target" "acpid.service" ]; after = [ "systemd-udev-settle.service" "local-fs.target" "acpid.service" "systemd-logind.service" ];
restartIfChanged = false; restartIfChanged = false;

View File

@ -67,7 +67,7 @@ let
echo -n "$configurationName" > $out/configuration-name echo -n "$configurationName" > $out/configuration-name
echo -n "systemd ${toString config.systemd.package.interfaceVersion}" > $out/init-interface-version echo -n "systemd ${toString config.systemd.package.interfaceVersion}" > $out/init-interface-version
echo -n "$nixosVersion" > $out/nixos-version echo -n "$nixosLabel" > $out/nixos-version
echo -n "$system" > $out/system echo -n "$system" > $out/system
mkdir $out/fine-tune mkdir $out/fine-tune
@ -101,7 +101,7 @@ let
if [] == failed then pkgs.stdenv.mkDerivation { if [] == failed then pkgs.stdenv.mkDerivation {
name = let hn = config.networking.hostName; name = let hn = config.networking.hostName;
nn = if (hn != "") then hn else "unnamed"; nn = if (hn != "") then hn else "unnamed";
in "nixos-system-${nn}-${config.system.nixosVersion}"; in "nixos-system-${nn}-${config.system.nixosLabel}";
preferLocalBuild = true; preferLocalBuild = true;
allowSubstitutes = false; allowSubstitutes = false;
buildCommand = systemBuilder; buildCommand = systemBuilder;
@ -115,7 +115,7 @@ let
config.system.build.installBootLoader config.system.build.installBootLoader
or "echo 'Warning: do not know how to make this configuration bootable; please enable a boot loader.' 1>&2; true"; or "echo 'Warning: do not know how to make this configuration bootable; please enable a boot loader.' 1>&2; true";
activationScript = config.system.activationScripts.script; activationScript = config.system.activationScripts.script;
nixosVersion = config.system.nixosVersion; nixosLabel = config.system.nixosLabel;
configurationName = config.boot.loader.grub.configurationName; configurationName = config.boot.loader.grub.configurationName;

View File

@ -197,9 +197,6 @@ in
"hid_generic" "hid_lenovo" "hid_generic" "hid_lenovo"
"hid_apple" "hid_logitech_dj" "hid_lenovo_tpkbd" "hid_roccat" "hid_apple" "hid_logitech_dj" "hid_lenovo_tpkbd" "hid_roccat"
# Unix domain sockets (needed by udev).
"unix"
# Misc. stuff. # Misc. stuff.
"pcips2" "atkbd" "pcips2" "atkbd"

View File

@ -83,7 +83,7 @@ addEntry() {
timestampEpoch=$(stat -L -c '%Z' $path) timestampEpoch=$(stat -L -c '%Z' $path)
timestamp=$(date "+%Y-%m-%d %H:%M" -d @$timestampEpoch) timestamp=$(date "+%Y-%m-%d %H:%M" -d @$timestampEpoch)
nixosVersion="$(cat $path/nixos-version)" nixosLabel="$(cat $path/nixos-version)"
extraParams="$(cat $path/kernel-params)" extraParams="$(cat $path/kernel-params)"
echo echo
@ -91,7 +91,7 @@ addEntry() {
if [ "$tag" = "default" ]; then if [ "$tag" = "default" ]; then
echo " MENU LABEL NixOS - Default" echo " MENU LABEL NixOS - Default"
else else
echo " MENU LABEL NixOS - Configuration $tag ($timestamp - $nixosVersion)" echo " MENU LABEL NixOS - Configuration $tag ($timestamp - $nixosLabel)"
fi fi
echo " LINUX ../nixos/$(basename $kernel)" echo " LINUX ../nixos/$(basename $kernel)"
echo " INITRD ../nixos/$(basename $initrd)" echo " INITRD ../nixos/$(basename $initrd)"

View File

@ -179,8 +179,9 @@ let
]; ];
makeJobScript = name: text: makeJobScript = name: text:
let x = pkgs.writeTextFile { name = "unit-script"; executable = true; destination = "/bin/${shellEscape name}"; inherit text; }; let mkScriptName = s: (replaceChars [ "\\" ] [ "-" ] (shellEscape s) );
in "${x}/bin/${shellEscape name}"; x = pkgs.writeTextFile { name = "unit-script"; executable = true; destination = "/bin/${mkScriptName name}"; inherit text; };
in "${x}/bin/${mkScriptName name}";
unitConfig = { name, config, ... }: { unitConfig = { name, config, ... }: {
config = { config = {

Some files were not shown because too many files have changed in this diff Show More