Merge branch 'staging' into closure-size

This commit is contained in:
Vladimír Čunát 2016-01-19 09:55:31 +01:00
commit 716aac2519
1293 changed files with 75245 additions and 28520 deletions

View File

@ -1,8 +1,8 @@
[<img src="http://nixos.org/logo/nixos-hires.png" width="500px" alt="logo" />](https://nixos.org/nixos) [<img src="http://nixos.org/logo/nixos-hires.png" width="500px" alt="logo" />](https://nixos.org/nixos)
[![Build Status](https://travis-ci.org/NixOS/nixpkgs.svg?branch=master)](https://travis-ci.org/NixOS/nixpkgs) [![Build Status](https://travis-ci.org/NixOS/nixpkgs.svg?branch=master)](https://travis-ci.org/NixOS/nixpkgs)
[![Issue Stats](http://www.issuestats.com/github/nixos/nixpkgs/badge/pr)](http://www.issuestats.com/github/nixos/nixpkgs) [![Issue Stats](http://www.issuestats.com/github/nixos/nixpkgs/badge/pr?style=flat)](http://www.issuestats.com/github/nixos/nixpkgs)
[![Issue Stats](http://www.issuestats.com/github/nixos/nixpkgs/badge/issue)](http://www.issuestats.com/github/nixos/nixpkgs) [![Issue Stats](http://www.issuestats.com/github/nixos/nixpkgs/badge/issue?style=flat)](http://www.issuestats.com/github/nixos/nixpkgs)
Nixpkgs is a collection of packages for the [Nix](https://nixos.org/nix/) package Nixpkgs is a collection of packages for the [Nix](https://nixos.org/nix/) package
manager. It is periodically built and tested by the [hydra](http://hydra.nixos.org/) manager. It is periodically built and tested by the [hydra](http://hydra.nixos.org/)

288
doc/erlang-users-guide.xml Normal file
View File

@ -0,0 +1,288 @@
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="users-guide-to-the-erlang-infrastructure">
<title>User's Guide to the Erlang Infrastructure</title>
<section xml:id="how-to-install-erlang-packages">
<title>How to install Erlang packages</title>
<para>
Erlang packages are not registered in the top level simply because
they are not relevant to the vast majority of Nix users. They are
installable using the <literal>erlangPackages</literal> attribute set.
You can list the avialable packages in the
<literal>erlangPackages</literal> with the following command:
</para>
<programlisting>
$ nix-env -f &quot;&lt;nixpkgs&gt;&quot; -qaP -A erlangPackages
erlangPackages.esqlite esqlite-0.2.1
erlangPackages.goldrush goldrush-0.1.7
erlangPackages.ibrowse ibrowse-4.2.2
erlangPackages.jiffy jiffy-0.14.5
erlangPackages.lager lager-3.0.2
erlangPackages.meck meck-0.8.3
erlangPackages.rebar3-pc pc-1.1.0
</programlisting>
<para>
To install any of those packages into your profile, refer to them by
their attribute path (first column):
</para>
<programlisting>
$ nix-env -f &quot;&lt;nixpkgs&gt;&quot; -iA erlangPackages.ibrowse
</programlisting>
<para>
The attribute path of any Erlang packages corresponds to the name
of that particular package in Hex or its OTP Application/Release name.
</para>
</section>
<section xml:id="packaging-erlang-applications">
<title>Packaging Erlang Applications</title>
<section xml:id="rebar3-packages">
<title>Rebar3 Packages</title>
<para>
There is a Nix functional called
<literal>buildRebar3</literal>. We use this function to make a
derivation that understands how to build the rebar3 project. For
example, the epression we use to build the <link
xlink:href="https://github.com/erlang-nix/hex2nix">hex2nix</link>
project follows.
</para>
<programlisting>
{stdenv, fetchFromGitHub, buildRebar3, ibrowse, jsx, erlware_commons }:
buildRebar3 rec {
name = "hex2nix";
version = "0.0.1";
src = fetchFromGitHub {
owner = "ericbmerritt";
repo = "hex2nix";
rev = "${version}";
sha256 = "1w7xjidz1l5yjmhlplfx7kphmnpvqm67w99hd2m7kdixwdxq0zqg";
};
erlangDeps = [ ibrowse jsx erlware_commons ];
}
</programlisting>
<para>
The only visible difference between this derivation and
something like <literal>stdenv.mkDerivation</literal> is that we
have added <literal>erlangDeps</literal> to the derivation. If
you add your Erlang dependencies here they will be correctly
handled by the system.
</para>
<para>
If your package needs to compile native code via Rebar's port
compilation mechenism. You should add <literal>compilePort =
true;</literal> to the derivation.
</para>
</section>
<section xml:id="hex-packages">
<title>Hex Packages</title>
<para>
Hex packages are based on Rebar packages. In fact, at the moment
we can only compile Hex packages that are buildable with
Rebar3. Packages that use Mix and other build systems are not
supported. That being said, we know a lot more about Hex and can
do more for you.
</para>
<programlisting>
{ buildHex }:
buildHex {
name = "esqlite";
version = "0.2.1";
sha256 = "1296fn1lz4lz4zqzn4dwc3flgkh0i6n4sydg501faabfbv8d3wkr";
compilePort = true;
}
</programlisting>
<para>
For Hex packages you need to provide the name, the version, and
the Sha 256 digest of the package and use
<literal>buildHex</literal> to build it. Obviously, the package
needs to have already been published to Hex.
</para>
</section>
</section>
<section xml:id="how-to-develop">
<title>How to develop</title>
<section xml:id="accessing-an-environment">
<title>Accessing an Environment</title>
<para>
Often, all you want to do is be able to access a valid
environment that contains a specific package and its
dependencies. we can do that with the <literal>env</literal>
part of a derivation. For example, lets say we want to access an
erlang repl with ibrowse loaded up. We could do the following.
</para>
<programlisting>
~/w/nixpkgs nix-shell -A erlangPackages.ibrowse.env --run "erl"
Erlang/OTP 18 [erts-7.0] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V7.0 (abort with ^G)
1> m(ibrowse).
Module: ibrowse
MD5: 3b3e0137d0cbb28070146978a3392945
Compiled: January 10 2016, 23:34
Object file: /nix/store/g1rlf65rdgjs4abbyj4grp37ry7ywivj-ibrowse-4.2.2/lib/erlang/lib/ibrowse-4.2.2/ebin/ibrowse.beam
Compiler options: [{outdir,"/tmp/nix-build-ibrowse-4.2.2.drv-0/hex-source-ibrowse-4.2.2/_build/default/lib/ibrowse/ebin"},
debug_info,debug_info,nowarn_shadow_vars,
warn_unused_import,warn_unused_vars,warnings_as_errors,
{i,"/tmp/nix-build-ibrowse-4.2.2.drv-0/hex-source-ibrowse-4.2.2/_build/default/lib/ibrowse/include"}]
Exports:
add_config/1 send_req_direct/7
all_trace_off/0 set_dest/3
code_change/3 set_max_attempts/3
get_config_value/1 set_max_pipeline_size/3
get_config_value/2 set_max_sessions/3
get_metrics/0 show_dest_status/0
get_metrics/2 show_dest_status/1
handle_call/3 show_dest_status/2
handle_cast/2 spawn_link_worker_process/1
handle_info/2 spawn_link_worker_process/2
init/1 spawn_worker_process/1
module_info/0 spawn_worker_process/2
module_info/1 start/0
rescan_config/0 start_link/0
rescan_config/1 stop/0
send_req/3 stop_worker_process/1
send_req/4 stream_close/1
send_req/5 stream_next/1
send_req/6 terminate/2
send_req_direct/4 trace_off/0
send_req_direct/5 trace_off/2
send_req_direct/6 trace_on/0
trace_on/2
ok
2>
</programlisting>
<para>
Notice the <literal>-A erlangPackages.ibrowse.env</literal>.That
is the key to this functionality.
</para>
</section>
<section xml:id="creating-a-shell">
<title>Creating a Shell</title>
<para>
Getting access to an environment often isn't enough to do real
development. Many times we need to create a
<literal>shell.nix</literal> file and do our development inside
of the environment specified by that file. This file looks a lot
like the packageing described above. The main difference is that
<literal>src</literal> points to project root and we call the
package directly.
</para>
<programlisting>
{ pkgs ? import &quot;&lt;nixpkgs&quot;&gt; {} }:
with pkgs;
let
f = { buildHex, ibrowse, jsx, erlware_commons }:
buildHex {
name = "hex2nix";
version = "0.1.0";
src = ./.;
erlangDeps = [ ibrowse jsx erlware_commons ];
};
drv = erlangPackages.callPackage f {};
in
drv
</programlisting>
<section xml:id="building-in-a-shell">
<title>Building in a shell</title>
<para>
Unfortunatly for us users of Nix, Rebar isn't very cooperative
with us from the standpoint of building a hermetic
environment. When building the rebar3 support we had to do some
sneaky things to get it not to go out and pull packages on its
own. Also unfortunately, you have to do some of the same things
when building a project inside of a Nix shell.
<orderedlist numeration="arabic">
<listitem>
<para>Run <literal>rebar3-nix-bootstrap</literal> every time
dependencies change</para>
</listitem>
<listitem>
<para>Set Home to the current directory.</para>
</listitem>
</orderedlist>
If you do these two things then Rebar will be happy with you. I
codify these into a makefile. Forunately, rebar3-nix-bootstrap
is idempotent and fairly quick. so you can run it as often as
you like.
</para>
<programlisting>
# =============================================================================
# Rules
# =============================================================================
.PHONY= all test clean repl shell build test analyze bootstrap
all: test
clean:
rm -rf _build
rm -rf .cache
repl:
nix-shell --run "erl"
shell:
nix-shell --run "bash"
bootstrap:
nix-shell --pure --run "rebar3-nix-bootstrap"
build: bootstrap
nix-shell --pure --run "HOME=$(CURDIR) rebar3 compile"
analyze: bootstrap
nix-shell --pure --run "HOME=$(CURDIR) rebar3 do compile,dialyzer"
test: bootstrap
nix-shell --pure --run "HOME=$(CURDIR) rebar3 do compile,dialyzer,eunit"
</programlisting>
<para>
If you add the <literal>shell.nix</literal> as described and
user rebar as follows things should simply work.
</para>
</section>
</section>
</section>
<section xml:id="generating-packages-from-hex-with-hex2nix">
<title>Generating Packages from Hex with Hex2Nix</title>
<para>
Updating the Hex packages requires the use of the
<literal>hex2nix</literal> tool. Given the path to the Erlang
modules (usually
<literal>pkgs/development/erlang-modules</literal>). It will
happily dump a file called
<literal>hex-packages.nix</literal>. That file will contain all
the packages that use a recognized build system in Hex. However,
it can't know whether or not all those packages are buildable.
</para>
<para>
To make life easier for our users, it makes good sense to go
ahead and attempt to build all those packages and remove the
ones that don't build. To do that, simply run the command (in
the root of your <literal>nixpkgs</literal> repository). that follows.
</para>
<programlisting>
$ nix-build -A erlangPackages
</programlisting>
<para>
That will build every package in
<literal>erlangPackages</literal>. Then you can go through and
manually remove the ones that fail. Hopefully, someone will
improve <literal>hex2nix</literal> in the future to automate
that.
</para>
</section>
</chapter>

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

@ -20,6 +20,7 @@
<xi:include href="coding-conventions.xml" /> <xi:include href="coding-conventions.xml" />
<xi:include href="submitting-changes.xml" /> <xi:include href="submitting-changes.xml" />
<xi:include href="haskell-users-guide.xml" /> <xi:include href="haskell-users-guide.xml" />
<xi:include href="erlang-users-guide.xml" />
<xi:include href="contributing.xml" /> <xi:include href="contributing.xml" />
</book> </book>

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>";
@ -231,7 +232,7 @@
palo = "Ingolf Wanger <palipalo9@googlemail.com>"; palo = "Ingolf Wanger <palipalo9@googlemail.com>";
pashev = "Igor Pashev <pashev.igor@gmail.com>"; pashev = "Igor Pashev <pashev.igor@gmail.com>";
pesterhazy = "Paulus Esterhazy <pesterhazy@gmail.com>"; pesterhazy = "Paulus Esterhazy <pesterhazy@gmail.com>";
phausmann = "Philipp Hausmann <nix@314.ch>"; phile314 = "Philipp Hausmann <nix@314.ch>";
philandstuff = "Philip Potter <philip.g.potter@gmail.com>"; philandstuff = "Philip Potter <philip.g.potter@gmail.com>";
phreedom = "Evgeny Egorochkin <phreedom@yandex.ru>"; phreedom = "Evgeny Egorochkin <phreedom@yandex.ru>";
phunehehe = "Hoang Xuan Phu <phunehehe@gmail.com>"; phunehehe = "Hoang Xuan Phu <phunehehe@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>";
@ -294,6 +294,7 @@
steveej = "Stefan Junker <mail@stefanjunker.de>"; steveej = "Stefan Junker <mail@stefanjunker.de>";
szczyp = "Szczyp <qb@szczyp.com>"; szczyp = "Szczyp <qb@szczyp.com>";
sztupi = "Attila Sztupak <attila.sztupak@gmail.com>"; sztupi = "Attila Sztupak <attila.sztupak@gmail.com>";
taeer = "Taeer Bar-Yam <taeer@necsi.edu>";
tailhook = "Paul Colomiets <paul@colomiets.name>"; tailhook = "Paul Colomiets <paul@colomiets.name>";
taktoa = "Remy Goldschmidt <taktoa@gmail.com>"; taktoa = "Remy Goldschmidt <taktoa@gmail.com>";
telotortium = "Robert Irelan <rirelan@gmail.com>"; telotortium = "Robert Irelan <rirelan@gmail.com>";
@ -334,6 +335,7 @@
wyvie = "Elijah Rum <elijahrum@gmail.com>"; wyvie = "Elijah Rum <elijahrum@gmail.com>";
yarr = "Dmitry V. <savraz@gmail.com>"; yarr = "Dmitry V. <savraz@gmail.com>";
z77z = "Marco Maggesi <maggesi@math.unifi.it>"; z77z = "Marco Maggesi <maggesi@math.unifi.it>";
zagy = "Christian Zagrodnick <cz@flyingcircus.io>";
zef = "Zef Hemel <zef@zef.me>"; zef = "Zef Hemel <zef@zef.me>";
zimbatm = "zimbatm <zimbatm@zimbatm.com>"; zimbatm = "zimbatm <zimbatm@zimbatm.com>";
zoomulator = "Kim Simmons <zoomulator@gmail.com>"; zoomulator = "Kim Simmons <zoomulator@gmail.com>";

View File

@ -191,9 +191,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

@ -281,6 +281,51 @@ $ nixos-rebuild switch -p test -I nixos-config=./test.nix
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><option>--build-host</option></term>
<listitem>
<para>Instead of building the new configuration locally, use the
specified host to perform the build. The host needs to be accessible
with ssh, and must be able to perform Nix builds. If the option
<option>--target-host</option> is not set, the build will be copied back
to the local machine when done.</para>
<para>Note that, if <option>--no-build-nix</option> is not specified,
Nix will be built both locally and remotely. This is because the
configuration will always be evaluated locally even though the building
might be performed remotely.</para>
<para>You can include a remote user name in
the host name (<replaceable>user@host</replaceable>). You can also set
ssh options by defining the <envar>NIX_SSHOPTS</envar> environment
variable.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--target-host</option></term>
<listitem>
<para>Specifies the NixOS target host. By setting this to something other
than <replaceable>localhost</replaceable>, the system activation will
happen on the remote host instead of the local machine. The remote host
needs to be accessible over ssh, and for the commands
<option>switch</option>, <option>boot</option> and <option>test</option>
you need root access.</para>
<para>If <option>--build-host</option> is not explicitly
specified, <option>--build-host</option> will implicitly be set to the
same value as <option>--target-host</option>. So, if you only specify
<option>--target-host</option> both building and activation will take
place remotely (and no build artifacts will be copied to the local
machine).</para>
<para>You can include a remote user name in
the host name (<replaceable>user@host</replaceable>). You can also set
ssh options by defining the <envar>NIX_SSHOPTS</envar> environment
variable.</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
<para>In addition, <command>nixos-rebuild</command> accepts various <para>In addition, <command>nixos-rebuild</command> accepts various
@ -305,6 +350,13 @@ the Nix manual for details.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry><term><envar>NIX_SSHOPTS</envar></term>
<listitem><para>Additional options to be passed to
<command>ssh</command> on the command line.</para></listitem>
</varlistentry>
</variablelist> </variablelist>
</refsection> </refsection>

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

@ -381,6 +381,11 @@ sub waitForUnit {
my $info = $self->getUnitInfo($unit); my $info = $self->getUnitInfo($unit);
my $state = $info->{ActiveState}; my $state = $info->{ActiveState};
die "unit $unit reached state $state\n" if $state eq "failed"; die "unit $unit reached state $state\n" if $state eq "failed";
if ($state eq "inactive") {
my ($status, $jobs) = $self->execute("systemctl list-jobs --full 2>&1");
die "unit $unit is inactive and there are no pending jobs\n"
if $jobs =~ /No jobs/; # FIXME: fragile
}
return 1 if $state eq "active"; return 1 if $state eq "active";
}; };
}); });

View File

@ -57,6 +57,7 @@ in
users.ldap = { users.ldap = {
enable = mkOption { enable = mkOption {
type = types.bool;
default = false; default = false;
description = "Whether to enable authentication against an LDAP server."; description = "Whether to enable authentication against an LDAP server.";
}; };

View File

@ -99,6 +99,7 @@ in {
package = mkOption { package = mkOption {
type = types.package; type = types.package;
default = pulseaudioLight; default = pulseaudioLight;
defaultText = "pkgs.pulseaudioLight";
example = literalExample "pkgs.pulseaudioFull"; example = literalExample "pkgs.pulseaudioFull";
description = '' description = ''
The PulseAudio derivation to use. This can be used to enable The PulseAudio derivation to use. This can be used to enable

View File

@ -119,6 +119,7 @@ in
environment.binsh = mkOption { environment.binsh = mkOption {
default = "${config.system.build.binsh}/bin/sh"; default = "${config.system.build.binsh}/bin/sh";
defaultText = "\${config.system.build.binsh}/bin/sh";
example = literalExample '' example = literalExample ''
"''${pkgs.dash}/bin/dash" "''${pkgs.dash}/bin/dash"
''; '';

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

@ -22,10 +22,9 @@ in
boot.kernel.sysctl = mkOption { boot.kernel.sysctl = mkOption {
default = {}; default = {};
example = { example = literalExample ''
"net.ipv4.tcp_syncookies" = false; { "net.ipv4.tcp_syncookies" = false; "vm.swappiness" = 60; }
"vm.swappiness" = 60; '';
};
type = types.attrsOf sysctlOption; type = types.attrsOf sysctlOption;
description = '' description = ''
Runtime parameters of the Linux kernel, as set by Runtime parameters of the Linux kernel, as set by

View File

@ -10,8 +10,9 @@ with lib;
options = { options = {
environment.unixODBCDrivers = mkOption { environment.unixODBCDrivers = mkOption {
type = types.listOf types.package;
default = []; default = [];
example = literalExample "map (x : x.ini) (with pkgs.unixODBCDrivers; [ mysql psql psqlng ] )"; example = literalExample "with pkgs.unixODBCDrivers; [ mysql psql psqlng ]";
description = '' description = ''
Specifies Unix ODBC drivers to be registered in Specifies Unix ODBC drivers to be registered in
<filename>/etc/odbcinst.ini</filename>. You may also want to <filename>/etc/odbcinst.ini</filename>. You may also want to
@ -26,7 +27,7 @@ with lib;
config = mkIf (config.environment.unixODBCDrivers != []) { config = mkIf (config.environment.unixODBCDrivers != []) {
environment.etc."odbcinst.ini".text = environment.etc."odbcinst.ini".text =
let inis = config.environment.unixODBCDrivers; let inis = map (x : x.ini) config.environment.unixODBCDrivers;
in lib.concatStringsSep "\n" inis; in lib.concatStringsSep "\n" inis;
}; };

View File

@ -26,7 +26,7 @@ let
''; '';
hashedPasswordDescription = '' hashedPasswordDescription = ''
To generate hashed password install <literal>mkpassword</literal> To generate hashed password install <literal>mkpasswd</literal>
package and run <literal>mkpasswd -m sha-512</literal>. package and run <literal>mkpasswd -m sha-512</literal>.
''; '';

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

@ -17,7 +17,9 @@ let
mkdir -p $out mkdir -p $out
cp -prd ${pkgs.path} $out/nixos cp -prd ${pkgs.path} $out/nixos
chmod -R u+w $out/nixos chmod -R u+w $out/nixos
if [ ! -e $out/nixos/nixpkgs ]; then
ln -s . $out/nixos/nixpkgs ln -s . $out/nixos/nixpkgs
fi
rm -rf $out/nixos/.git rm -rf $out/nixos/.git
echo -n ${config.system.nixosVersionSuffix} > $out/nixos/.version-suffix echo -n ${config.system.nixosVersionSuffix} > $out/nixos/.version-suffix
''; '';

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

@ -74,7 +74,7 @@ in
# Tools to create / manipulate filesystems. # Tools to create / manipulate filesystems.
pkgs.ntfsprogs # for resizing NTFS partitions pkgs.ntfsprogs # for resizing NTFS partitions
pkgs.btrfsProgs pkgs.btrfs-progs
pkgs.jfsutils pkgs.jfsutils
# Some compression/archiver tools. # Some compression/archiver tools.
@ -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

@ -109,7 +109,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 [];
# To be able to use the systemTarball to catch troubles. # To be able to use the systemTarball to catch troubles.
boot.crashDump = { boot.crashDump = {

View File

@ -67,7 +67,7 @@ in
pkgs.dmraid pkgs.dmraid
# Tools to create / manipulate filesystems. # Tools to create / manipulate filesystems.
pkgs.btrfsProgs pkgs.btrfs-progs
# Some compression/archiver tools. # Some compression/archiver tools.
pkgs.unzip pkgs.unzip
@ -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

@ -38,7 +38,7 @@ let
nixos-generate-config = makeProg { nixos-generate-config = makeProg {
name = "nixos-generate-config"; name = "nixos-generate-config";
src = ./nixos-generate-config.pl; src = ./nixos-generate-config.pl;
path = [ pkgs.btrfsProgs ]; path = [ pkgs.btrfs-progs ];
perl = "${pkgs.perl}/bin/perl -I${pkgs.perlPackages.FileSlurp}/lib/perl5/site_perl"; perl = "${pkgs.perl}/bin/perl -I${pkgs.perlPackages.FileSlurp}/lib/perl5/site_perl";
inherit (config.system) nixosRelease; inherit (config.system) nixosRelease;
}; };

View File

@ -24,6 +24,7 @@ in
''; '';
}; };
kernelPackages = mkOption { kernelPackages = mkOption {
type = types.package;
default = pkgs.linuxPackages; default = pkgs.linuxPackages;
# We don't want to evaluate all of linuxPackages for the manual # We don't want to evaluate all of linuxPackages for the manual
# - some of it might not even evaluate correctly. # - some of it might not even evaluate correctly.

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;
@ -239,6 +239,15 @@
bepasty = 215; bepasty = 215;
pumpio = 216; pumpio = 216;
nm-openvpn = 217; nm-openvpn = 217;
mathics = 218;
ejabberd = 219;
postsrsd = 220;
opendkim = 221;
dspam = 222;
gale = 223;
matrix-synapse = 224;
rspamd = 225;
rmilter = 226;
# 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!
@ -355,7 +364,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
@ -455,6 +464,15 @@
bepasty = 215; bepasty = 215;
pumpio = 216; pumpio = 216;
nm-openvpn = 217; nm-openvpn = 217;
mathics = 218;
ejabberd = 219;
postsrsd = 220;
opendkim = 221;
dspam = 222;
gale = 223;
matrix-synapse = 224;
rspamd = 225;
rmilter = 226;
# 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

@ -37,8 +37,8 @@ with lib;
nixos.extraModules = mkOption { nixos.extraModules = mkOption {
default = []; default = [];
example = literalExample "mkIf config.services.openssh.enable [ ./sshd-config.nix ]"; example = literalExample "[ ./sshd-config.nix ]";
type = types.listOf types.unspecified; type = types.listOf (types.either (types.submodule ({...}:{options={};})) types.path);
description = '' description = ''
Define additional modules which would be loaded to evaluate the Define additional modules which would be loaded to evaluate the
configuration. configuration.

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
system.nixosVersionSuffix = # changing them would not rebuild the manual
let suffixFile = "${toString pkgs.path}/.version-suffix"; in nixosLabel = mkDefault (maybeEnv "NIXOS_LABEL" cfg.nixosVersion);
mkDefault (if pathExists suffixFile then readFile suffixFile else "pre-git"); nixosVersion = mkDefault (maybeEnv "NIXOS_VERSION" (cfg.nixosRelease + cfg.nixosVersionSuffix));
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. # Note: code names must only increase in alphabetical order.
system.nixosCodeName = "Emu"; 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,13 +183,18 @@
./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/mail/rspamd.nix
./services/mail/rmilter.nix
./services/misc/apache-kafka.nix ./services/misc/apache-kafka.nix
./services/misc/autofs.nix ./services/misc/autofs.nix
./services/misc/bepasty.nix ./services/misc/bepasty.nix
@ -209,6 +215,8 @@
./services/misc/gitolite.nix ./services/misc/gitolite.nix
./services/misc/gpsd.nix ./services/misc/gpsd.nix
./services/misc/ihaskell.nix ./services/misc/ihaskell.nix
./services/misc/mathics.nix
./services/misc/matrix-synapse.nix
./services/misc/mbpfan.nix ./services/misc/mbpfan.nix
./services/misc/mediatomb.nix ./services/misc/mediatomb.nix
./services/misc/mesos-master.nix ./services/misc/mesos-master.nix
@ -296,6 +304,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
@ -321,7 +330,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
@ -330,6 +338,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
@ -441,6 +450,7 @@
./services/x11/window-managers/metacity.nix ./services/x11/window-managers/metacity.nix
./services/x11/window-managers/none.nix ./services/x11/window-managers/none.nix
./services/x11/window-managers/twm.nix ./services/x11/window-managers/twm.nix
./services/x11/window-managers/windowlab.nix
./services/x11/window-managers/wmii.nix ./services/x11/window-managers/wmii.nix
./services/x11/window-managers/xmonad.nix ./services/x11/window-managers/xmonad.nix
./services/x11/xfs.nix ./services/x11/xfs.nix
@ -473,7 +483,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

@ -8,6 +8,7 @@
enable = true; enable = true;
displayManager.kdm.enable = true; displayManager.kdm.enable = true;
desktopManager.kde4.enable = true; desktopManager.kde4.enable = true;
synaptics.enable = true; # for touchpad support on many laptops
}; };
environment.systemPackages = [ pkgs.glxinfo ]; environment.systemPackages = [ pkgs.glxinfo ];

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

@ -16,7 +16,7 @@ let
isExecutable = true; isExecutable = true;
inherit (pkgs) perl; inherit (pkgs) perl;
perlFlags = concatStrings (map (path: "-I ${path}/lib/perl5/site_perl ") perlFlags = concatStrings (map (path: "-I ${path}/lib/perl5/site_perl ")
[ pkgs.perlPackages.DBI pkgs.perlPackages.DBDSQLite ]); [ pkgs.perlPackages.DBI pkgs.perlPackages.DBDSQLite pkgs.perlPackages.StringShellQuote ]);
}; };
in in
@ -30,7 +30,7 @@ in
local p=/run/current-system/sw/bin/command-not-found local p=/run/current-system/sw/bin/command-not-found
if [ -x $p -a -f /nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite ]; then if [ -x $p -a -f /nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite ]; then
# Run the helper program. # Run the helper program.
$p "$1" $p "$@"
# Retry the command if we just installed it. # Retry the command if we just installed it.
if [ $? = 126 ]; then if [ $? = 126 ]; then
"$@" "$@"
@ -51,7 +51,7 @@ in
local p=/run/current-system/sw/bin/command-not-found local p=/run/current-system/sw/bin/command-not-found
if [ -x $p -a -f /nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite ]; then if [ -x $p -a -f /nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite ]; then
# Run the helper program. # Run the helper program.
$p "$1" $p "$@"
# Retry the command if we just installed it. # Retry the command if we just installed it.
if [ $? = 126 ]; then if [ $? = 126 ]; then

View File

@ -3,6 +3,7 @@
use strict; use strict;
use DBI; use DBI;
use DBD::SQLite; use DBD::SQLite;
use String::ShellQuote;
use Config; use Config;
my $program = $ARGV[0]; my $program = $ARGV[0];
@ -31,6 +32,8 @@ the package $package, which I will now install for you.
EOF EOF
; ;
exit 126 if system("nix-env", "-iA", "nixos.$package") == 0; exit 126 if system("nix-env", "-iA", "nixos.$package") == 0;
} elsif ($ENV{"NIX_AUTO_RUN"} // "") {
exec("nix-shell", "-p", $package, "--run", shell_quote("exec", @ARGV));
} else { } else {
print STDERR <<EOF; print STDERR <<EOF;
The program $program is currently not installed. You can install it by typing: The program $program is currently not installed. You can install it by typing:

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

@ -93,7 +93,9 @@ in
}; };
package = mkOption { package = mkOption {
type = types.package;
default = pkgs.openssh; default = pkgs.openssh;
defaultText = "pkgs.openssh";
description = '' description = ''
The package used for the openssh client and daemon. The package used for the openssh client and daemon.
''; '';
@ -142,16 +144,18 @@ in
description = '' description = ''
The set of system-wide known SSH hosts. The set of system-wide known SSH hosts.
''; '';
example = [ example = literalExample ''
[
{ {
hostNames = [ "myhost" "myhost.mydomain.com" "10.10.1.4" ]; hostNames = [ "myhost" "myhost.mydomain.com" "10.10.1.4" ];
publicKeyFile = literalExample "./pubkeys/myhost_ssh_host_dsa_key.pub"; publicKeyFile = "./pubkeys/myhost_ssh_host_dsa_key.pub";
} }
{ {
hostNames = [ "myhost2" ]; hostNames = [ "myhost2" ];
publicKeyFile = literalExample "./pubkeys/myhost2_ssh_host_dsa_key.pub"; publicKeyFile = "./pubkeys/myhost2_ssh_host_dsa_key.pub";
} }
]; ]
'';
}; };
}; };

View File

@ -98,18 +98,18 @@ in
loginShellInit = cfge.loginShellInit; loginShellInit = cfge.loginShellInit;
interactiveShellInit = '' interactiveShellInit = ''
${cfge.interactiveShellInit} # history defaults
${cfg.promptInit}
${zshAliases}
# Some sane history defaults
export SAVEHIST=2000 export SAVEHIST=2000
export HISTSIZE=2000 export HISTSIZE=2000
export HISTFILE=$HOME/.zsh_history export HISTFILE=$HOME/.zsh_history
setopt HIST_IGNORE_DUPS SHARE_HISTORY HIST_FCNTL_LOCK setopt HIST_IGNORE_DUPS SHARE_HISTORY HIST_FCNTL_LOCK
${cfge.interactiveShellInit}
${cfg.promptInit}
${zshAliases}
# Tell zsh how to find installed completions # Tell zsh how to find installed completions
for p in ''${(z)NIX_PROFILES}; do for p in ''${(z)NIX_PROFILES}; do
fpath+=($p/share/zsh/site-functions $p/share/zsh/$ZSH_VERSION/functions) fpath+=($p/share/zsh/site-functions $p/share/zsh/$ZSH_VERSION/functions)

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

@ -46,7 +46,7 @@ in
example = { example = {
myStream1 = literalExample "\"/etc/liquidsoap/myStream1.liq\""; myStream1 = literalExample "\"/etc/liquidsoap/myStream1.liq\"";
myStream2 = literalExample "./myStream2.liq"; myStream2 = literalExample "./myStream2.liq";
myStream3 = literalExample "\"out(playlist(\"/srv/music/\"))\""; myStream3 = literalExample "\"out(playlist(\\\"/srv/music/\\\"))\"";
}; };
type = types.attrsOf (types.either types.path types.str); type = types.attrsOf (types.either types.path types.str);

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

@ -207,7 +207,7 @@ in {
description = '' description = ''
Extra configuration to be passed in Client directive. Extra configuration to be passed in Client directive.
''; '';
example = literalExample '' example = ''
Maximum Concurrent Jobs = 20; Maximum Concurrent Jobs = 20;
Heartbeat Interval = 30; Heartbeat Interval = 30;
''; '';
@ -218,7 +218,7 @@ in {
description = '' description = ''
Extra configuration to be passed in Messages directive. Extra configuration to be passed in Messages directive.
''; '';
example = literalExample '' example = ''
console = all console = all
''; '';
}; };

View File

@ -43,6 +43,7 @@ in
package = mkOption { package = mkOption {
type = types.package; type = types.package;
default = pkgs.rsnapshot; default = pkgs.rsnapshot;
defaultText = "pkgs.rsnapshot";
example = literalExample "pkgs.rsnapshotGit"; example = literalExample "pkgs.rsnapshotGit";
description = '' description = ''
RSnapshot package to use. RSnapshot package to use.

View File

@ -5,9 +5,9 @@ with lib;
let let
cfg = config.services.tarsnap; cfg = config.services.tarsnap;
configFile = cfg: '' configFile = name: cfg: ''
cachedir ${config.services.tarsnap.cachedir} cachedir ${config.services.tarsnap.cachedir}/${name}
keyfile ${config.services.tarsnap.keyfile} keyfile ${cfg.keyfile}
${optionalString cfg.nodump "nodump"} ${optionalString cfg.nodump "nodump"}
${optionalString cfg.printStats "print-stats"} ${optionalString cfg.printStats "print-stats"}
${optionalString cfg.printStats "humanize-numbers"} ${optionalString cfg.printStats "humanize-numbers"}
@ -41,6 +41,20 @@ in
account. account.
Create the keyfile with <command>tarsnap-keygen</command>. Create the keyfile with <command>tarsnap-keygen</command>.
Note that each individual archive (specified below) may also have its
own individual keyfile specified. Tarsnap does not allow multiple
concurrent backups with the same cache directory and key (starting a
new backup will cause another one to fail). If you have multiple
archives specified, you should either spread out your backups to be
far apart, or specify a separate key for each archive. By default
every archive defaults to using
<literal>"/root/tarsnap.key"</literal>.
It's recommended for backups that you generate a key for every archive
using <literal>tarsnap-keygen(1)</literal>, and then generate a
write-only tarsnap key using <literal>tarsnap-keymgmt(1)</literal>,
and keep your master key(s) for a particular machine off-site.
The keyfile name should be given as a string and not a path, to The keyfile name should be given as a string and not a path, to
avoid the key being copied into the Nix store. avoid the key being copied into the Nix store.
''; '';
@ -57,6 +71,12 @@ in
will refuse to run until you manually rebuild the cache with will refuse to run until you manually rebuild the cache with
<command>tarsnap --fsck</command>. <command>tarsnap --fsck</command>.
Note that each individual archive (specified below) has its own cache
directory specified under <literal>cachedir</literal>; this is because
tarsnap locks the cache during backups, meaning multiple services
archives cannot be backed up concurrently or overlap with a shared
cache.
Set to <literal>null</literal> to disable caching. Set to <literal>null</literal> to disable caching.
''; '';
}; };
@ -65,6 +85,28 @@ in
type = types.attrsOf (types.submodule ( type = types.attrsOf (types.submodule (
{ {
options = { options = {
keyfile = mkOption {
type = types.str;
default = config.services.tarsnap.keyfile;
description = ''
Set a specific keyfile for this archive. This defaults to
<literal>"/root/tarsnap.key"</literal> if left unspecified.
Use this option if you want to run multiple backups
concurrently - each archive must have a unique key. You can
generate a write-only key derived from your master key (which
is recommended) using <literal>tarsnap-keymgmt(1)</literal>.
Note: every archive must have an individual master key. You
must generate multiple keys with
<literal>tarsnap-keygen(1)</literal>, and then generate write
only keys from those.
The keyfile name should be given as a string and not a path, to
avoid the key being copied into the Nix store.
'';
};
nodump = mkOption { nodump = mkOption {
type = types.bool; type = types.bool;
default = true; default = true;
@ -242,15 +284,23 @@ 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}
mkdir -p -m 0700 ${cfg.cachedir} mkdir -p -m 0700 ${cfg.cachedir}
chown root:root ${cfg.cachedir} chown root:root ${cfg.cachedir}
chmod 0700 ${cfg.cachedir} chmod 0700 ${cfg.cachedir}
mkdir -p -m 0700 ${cfg.cachedir}/$1
DIRS=`cat /etc/tarsnap/$1.dirs` DIRS=`cat /etc/tarsnap/$1.dirs`
exec tarsnap --configfile /etc/tarsnap/$1.conf -c -f $1-$(date +"%Y%m%d%H%M%S") $DIRS exec tarsnap --configfile /etc/tarsnap/$1.conf -c -f $1-$(date +"%Y%m%d%H%M%S") $DIRS
''; '';
@ -259,17 +309,21 @@ 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;
environment.etc = environment.etc =
(mapAttrs' (name: cfg: nameValuePair "tarsnap/${name}.conf" (mapAttrs' (name: cfg: nameValuePair "tarsnap/${name}.conf"
{ text = configFile cfg; { text = configFile name cfg;
}) cfg.archives) // }) cfg.archives) //
(mapAttrs' (name: cfg: nameValuePair "tarsnap/${name}.dirs" (mapAttrs' (name: cfg: nameValuePair "tarsnap/${name}.dirs"
{ text = concatStringsSep " " cfg.directories; { text = concatStringsSep " " cfg.directories;

View File

@ -80,6 +80,7 @@ in {
packages = mkOption { packages = mkOption {
default = [ pkgs.stdenv pkgs.git pkgs.jdk config.programs.ssh.package pkgs.nix ]; default = [ pkgs.stdenv pkgs.git pkgs.jdk config.programs.ssh.package pkgs.nix ];
defaultText = "[ pkgs.stdenv pkgs.git pkgs.jdk config.programs.ssh.package pkgs.nix ]";
type = types.listOf types.package; type = types.listOf types.package;
description = '' description = ''
Packages to add to PATH for the jenkins process. Packages to add to PATH for the jenkins process.

View File

@ -74,7 +74,7 @@ in {
]; ];
}; };
} }
]; ]
''; '';
description = '' description = ''
Job descriptions for Jenkins Job Builder in Nix format. Job descriptions for Jenkins Job Builder in Nix format.

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

@ -38,6 +38,7 @@ in {
package = mkOption { package = mkOption {
type = types.package; type = types.package;
default = pkgs.couchdb; default = pkgs.couchdb;
defaultText = "pkgs.couchdb";
example = literalExample "pkgs.couchdb"; example = literalExample "pkgs.couchdb";
description = '' description = ''
CouchDB package to use. CouchDB package to use.

View File

@ -49,6 +49,7 @@ in
package = mkOption { package = mkOption {
default = pkgs.firebirdSuper; default = pkgs.firebirdSuper;
defaultText = "pkgs.firebirdSuper";
type = types.package; type = types.package;
/* /*
Example: <code>package = pkgs.firebirdSuper.override { icu = Example: <code>package = pkgs.firebirdSuper.override { icu =

View File

@ -44,6 +44,7 @@ in {
package = mkOption { package = mkOption {
type = types.package; type = types.package;
default = pkgs.hbase; default = pkgs.hbase;
defaultText = "pkgs.hbase";
example = literalExample "pkgs.hbase"; example = literalExample "pkgs.hbase";
description = '' description = ''
HBase package to use. HBase package to use.

View File

@ -120,6 +120,7 @@ in
package = mkOption { package = mkOption {
default = pkgs.influxdb; default = pkgs.influxdb;
defaultText = "pkgs.influxdb";
description = "Which influxdb derivation to use"; description = "Which influxdb derivation to use";
type = types.package; type = types.package;
}; };

View File

@ -41,6 +41,7 @@ in
package = mkOption { package = mkOption {
default = pkgs.mongodb; default = pkgs.mongodb;
defaultText = "pkgs.mongodb";
type = types.package; type = types.package;
description = " description = "
Which MongoDB derivation to use. Which MongoDB derivation to use.

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
@ -49,10 +49,11 @@ in {
package = mkOption { package = mkOption {
description = "Neo4j package to use."; description = "Neo4j package to use.";
default = pkgs.neo4j; default = pkgs.neo4j;
defaultText = "pkgs.neo4j";
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

@ -25,22 +25,7 @@ in
description = " description = "
Whether to enable the ldap server. Whether to enable the ldap server.
"; ";
example = literalExample '' example = true;
openldap.enable = true;
openldap.extraConfig = '''
include ''${pkgs.openldap.out}/etc/openldap/schema/core.schema
include ''${pkgs.openldap.out}/etc/openldap/schema/cosine.schema
include ''${pkgs.openldap.out}/etc/openldap/schema/inetorgperson.schema
include ''${pkgs.openldap.out}/etc/openldap/schema/nis.schema
database bdb
suffix dc=example,dc=org
rootdn cn=admin,dc=example,dc=org
# NOTE: change after first start
rootpw secret
directory /var/db/openldap
''';
'';
}; };
user = mkOption { user = mkOption {
@ -67,6 +52,19 @@ in
description = " description = "
sldapd.conf configuration sldapd.conf configuration
"; ";
example = ''
include ''${pkgs.openldap}/etc/openldap/schema/core.schema
include ''${pkgs.openldap}/etc/openldap/schema/cosine.schema
include ''${pkgs.openldap}/etc/openldap/schema/inetorgperson.schema
include ''${pkgs.openldap}/etc/openldap/schema/nis.schema
database bdb
suffix dc=example,dc=org
rootdn cn=admin,dc=example,dc=org
# NOTE: change after first start
rootpw secret
directory /var/db/openldap
'';
}; };
}; };

View File

@ -26,6 +26,7 @@ in {
package = mkOption { package = mkOption {
type = types.package; type = types.package;
default = pkgs.opentsdb; default = pkgs.opentsdb;
defaultText = "pkgs.opentsdb";
example = literalExample "pkgs.opentsdb"; example = literalExample "pkgs.opentsdb";
description = '' description = ''
OpenTSDB package to use. OpenTSDB package to use.

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

@ -46,6 +46,7 @@ in
package = mkOption { package = mkOption {
type = types.package; type = types.package;
default = pkgs.redis; default = pkgs.redis;
defaultText = "pkgs.redis";
description = "Which Redis derivation to use."; description = "Which Redis derivation to use.";
}; };

View File

@ -61,9 +61,8 @@ 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}

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

@ -20,7 +20,7 @@ let
} }
''; '';
events = [powerEvent lidEvent acEvent]; events = [powerEvent lidEvent acEvent muteEvent volumeDownEvent volumeUpEvent cdPlayEvent cdNextEvent cdPrevEvent];
# Called when the power button is pressed. # Called when the power button is pressed.
powerEvent = powerEvent =
@ -55,6 +55,61 @@ let
''; '';
}; };
muteEvent = {
name = "mute";
event = "button/mute.*";
action = ''
#! ${pkgs.bash}/bin/sh
${config.services.acpid.muteCommands}
'';
};
volumeDownEvent = {
name = "volume-down";
event = "button/volumedown.*";
action = ''
#! ${pkgs.bash}/bin/sh
${config.services.acpid.volumeDownEventCommands}
'';
};
volumeUpEvent = {
name = "volume-up";
event = "button/volumeup.*";
action = ''
#! ${pkgs.bash}/bin/sh
${config.services.acpid.volumeUpEventCommands}
'';
};
cdPlayEvent = {
name = "cd-play";
event = "cd/play.*";
action = ''
#! ${pkgs.bash}/bin/sh
${config.services.acpid.cdPlayEventCommands}
'';
};
cdNextEvent = {
name = "cd-next";
event = "cd/next.*";
action = ''
#! ${pkgs.bash}/bin/sh
${config.services.acpid.cdNextEventCommands}
'';
};
cdPrevEvent = {
name = "cd-prev";
event = "cd/prev.*";
action = ''
#! ${pkgs.bash}/bin/sh
${config.services.acpid.cdPrevEventCommands}
'';
};
in in
{ {
@ -89,6 +144,42 @@ in
description = "Shell commands to execute on an ac_adapter.* event."; description = "Shell commands to execute on an ac_adapter.* event.";
}; };
muteCommands = mkOption {
type = types.lines;
default = "";
description = "Shell commands to execute on an button/mute.* event.";
};
volumeDownEventCommands = mkOption {
type = types.lines;
default = "";
description = "Shell commands to execute on an button/volumedown.* event.";
};
volumeUpEventCommands = mkOption {
type = types.lines;
default = "";
description = "Shell commands to execute on an button/volumeup.* event.";
};
cdPlayEventCommands = mkOption {
type = types.lines;
default = "";
description = "Shell commands to execute on an cd/play.* event.";
};
cdNextEventCommands = mkOption {
type = types.lines;
default = "";
description = "Shell commands to execute on an cd/next.* event.";
};
cdPrevEventCommands = mkOption {
type = types.lines;
default = "";
description = "Shell commands to execute on an cd/prev.* event.";
};
}; };
}; };
@ -98,20 +189,24 @@ 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";
ConditionPathExists = [ "/proc/acpi" ];
};
unitConfig.ConditionVirtualization = "!systemd-nspawn"; script = "acpid --confdir ${acpiConfDir}";
unitConfig.ConditionPathExists = [ "/proc/acpi" ];
}; };
}; };

View File

@ -21,6 +21,7 @@ in {
package = mkOption { package = mkOption {
type = types.package; type = types.package;
default = pkgs.freefall; default = pkgs.freefall;
defaultText = "pkgs.freefall";
description = '' description = ''
freefall derivation to use. freefall derivation to use.
''; '';

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

@ -4,7 +4,9 @@ with lib;
let let
pkg = if config.hardware.sane.snapshot then pkgs.saneBackendsGit else pkgs.saneBackends; pkg = if config.hardware.sane.snapshot
then pkgs.sane-backends-git
else pkgs.sane-backends;
backends = [ pkg ] ++ config.hardware.sane.extraBackends; backends = [ pkg ] ++ config.hardware.sane.extraBackends;
saneConfig = pkgs.mkSaneConfig { paths = backends; }; saneConfig = pkgs.mkSaneConfig { paths = backends; };

View File

@ -43,13 +43,7 @@ let
sensor ${cfg.sensor} (0, 10, 15, 2, 10, 5, 0, 3, 0, 3) sensor ${cfg.sensor} (0, 10, 15, 2, 10, 5, 0, 3, 0, 3)
(0, 0, 55) ${cfg.levels}
(1, 48, 60)
(2, 50, 61)
(3, 52, 63)
(6, 56, 65)
(7, 60, 85)
(127, 80, 32767)
''; '';
in { in {
@ -72,6 +66,22 @@ in {
''; '';
}; };
levels = mkOption {
default = ''
(0, 0, 55)
(1, 48, 60)
(2, 50, 61)
(3, 52, 63)
(6, 56, 65)
(7, 60, 85)
(127, 80, 32767)
'';
description =''
Sensor used by thinkfan
'';
};
}; };
}; };

View File

@ -27,6 +27,7 @@ in
package = mkOption { package = mkOption {
type = types.package; type = types.package;
default = pkgs.upower; default = pkgs.upower;
defaultText = "pkgs.upower";
example = lib.literalExample "pkgs.upower"; example = lib.literalExample "pkgs.upower";
description = '' description = ''
Which upower package to use. Which upower package to use.

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" ]; wantedBy = [ "multi-user.target" ];
path = [ pkgs.sysklogd ]; path = [ pkgs.sysklogd ];
unitConfig.ConditionVirtualization = "!systemd-nspawn"; unitConfig.ConditionVirtualization = "!systemd-nspawn";
script =
exec =
"klogd -c 1 -2 -n " + "klogd -c 1 -2 -n " +
"-k $(dirname $(readlink -f /run/booted-system/kernel))/System.map"; "-k $(dirname $(readlink -f /run/booted-system/kernel))/System.map";
}; };
}; };
} }

View File

@ -13,6 +13,7 @@ in
options = { options = {
services.logrotate = { services.logrotate = {
enable = mkOption { enable = mkOption {
type = lib.types.bool;
default = false; default = false;
description = '' description = ''
Enable the logrotate cron job Enable the logrotate cron job

View File

@ -33,6 +33,7 @@ in
package = mkOption { package = mkOption {
type = types.package; type = types.package;
default = pkgs.logstash; default = pkgs.logstash;
defaultText = "pkgs.logstash";
example = literalExample "pkgs.logstash"; example = literalExample "pkgs.logstash";
description = "Logstash package to use."; description = "Logstash package to use.";
}; };
@ -84,7 +85,7 @@ in
type = types.lines; type = types.lines;
default = ''stdin { type => "example" }''; default = ''stdin { type => "example" }'';
description = "Logstash input configuration."; description = "Logstash input configuration.";
example = literalExample '' example = ''
# Read from journal # Read from journal
pipe { pipe {
command => "''${pkgs.systemd}/bin/journalctl -f -o json" command => "''${pkgs.systemd}/bin/journalctl -f -o json"

View File

@ -39,6 +39,7 @@ in {
package = mkOption { package = mkOption {
type = types.package; type = types.package;
default = pkgs.syslogng; default = pkgs.syslogng;
defaultText = "pkgs.syslogng";
description = '' description = ''
The package providing syslog-ng binaries. The package providing syslog-ng binaries.
''; '';

View File

@ -90,6 +90,7 @@ in
package = mkOption { package = mkOption {
type = types.package; type = types.package;
default = pkgs.dovecot22; default = pkgs.dovecot22;
defaultText = "pkgs.dovecot22";
description = "Dovecot package to use."; description = "Dovecot package to use.";
}; };
@ -131,7 +132,7 @@ in
modules = mkOption { modules = mkOption {
type = types.listOf types.package; type = types.listOf types.package;
default = []; default = [];
example = [ pkgs.dovecot_pigeonhole ]; example = literalExample "[ pkgs.dovecot_pigeonhole ]";
description = '' description = ''
Symlinks the contents of lib/dovecot of every given package into Symlinks the contents of lib/dovecot of every given package into
/var/lib/dovecot/modules. This will make the given modules available /var/lib/dovecot/modules. This will make the given modules available

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,10 +72,11 @@ 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 = ''
${pkgs.freepops}/bin/freepopsd \
-p ${toString cfg.port} \ -p ${toString cfg.port} \
-t ${toString cfg.threads} \ -t ${toString cfg.threads} \
-b ${cfg.bind} \ -b ${cfg.bind} \

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.lines;
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,11 +375,12 @@ 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";
}; };
@ -333,75 +391,88 @@ in
services.mail.sendmailSetuidWrapper = mkIf config.services.postfix.setSendmail { services.mail.sendmailSetuidWrapper = mkIf config.services.postfix.setSendmail {
program = "sendmail"; program = "sendmail";
source = "${pkgs.postfix}/bin/sendmail"; source = "${pkgs.postfix}/bin/sendmail";
owner = "nobody"; group = setgidGroup;
group = "postdrop";
setuid = false; setuid = false;
setgid = true; setgid = true;
}; };
users.extraUsers = singleton users.extraUsers = optional (user == "postfix")
{ name = user; { name = "postfix";
description = "Postfix mail server user"; description = "Postfix mail server user";
uid = config.ids.uids.postfix; uid = config.ids.uids.postfix;
group = group; group = group;
}; };
users.extraGroups = users.extraGroups =
[ { name = group; 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 = systemd.services.postfix =
{ description = "Postfix mail server"; { description = "Postfix mail server";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
after = [ "network.target" ]; after = [ "network.target" ];
path = [ pkgs.postfix ];
serviceConfig = { serviceConfig = {
Type = "forking"; Type = "forking";
Restart = "always"; Restart = "always";
PIDFile = "/var/postfix/queue/pid/master.pid"; 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";
}; };
preStart = '' preStart = ''
${pkgs.coreutils}/bin/mkdir -p /var/spool/mail /var/postfix/conf /var/postfix/queue # Backwards compatibility
if [ ! -d /var/lib/postfix ] && [ -d /var/postfix ]; then
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.coreutils}/bin/chown -R ${user}:${group} /var/postfix chown -R ${user}:${group} /var/lib/postfix
${pkgs.coreutils}/bin/chown -R ${user}:${setgidGroup} /var/postfix/queue chown root /var/lib/postfix/queue
${pkgs.coreutils}/bin/chmod -R ug+rwX /var/postfix/queue chown root /var/lib/postfix/queue/pid
${pkgs.coreutils}/bin/chown root:root /var/spool/mail chgrp -R ${setgidGroup} /var/lib/postfix/queue/{public,maildrop}
${pkgs.coreutils}/bin/chmod a+rwxt /var/spool/mail chmod 770 /var/lib/postfix/queue/{public,maildrop}
${pkgs.coreutils}/bin/ln -sf /var/spool/mail /var/
ln -sf ${pkgs.postfix}/etc/postfix/postfix-files /var/postfix/conf rm -rf /var/lib/postfix/conf
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)}
ln -sf ${aliasesFile} /var/postfix/conf/aliases mkdir -p /var/spool/mail
ln -sf ${virtualFile} /var/postfix/conf/virtual chown root:root /var/spool/mail
ln -sf ${mainCfFile} /var/postfix/conf/main.cf chmod a+rwxt /var/spool/mail
ln -sf ${masterCfFile} /var/postfix/conf/master.cf ln -sf /var/spool/mail /var/
${pkgs.postfix}/sbin/postalias -c /var/postfix/conf /var/postfix/conf/aliases
${pkgs.postfix}/sbin/postmap -c /var/postfix/conf /var/postfix/conf/virtual
''; '';
script = ''
${pkgs.postfix}/sbin/postfix -c /var/postfix/conf start
'';
reload = ''
${pkgs.postfix}/sbin/postfix -c /var/postfix/conf reload
'';
preStop = ''
${pkgs.postfix}/sbin/postfix -c /var/postfix/conf stop
'';
}; };
}
}; (mkIf haveAliases {
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

@ -0,0 +1,189 @@
{ config, lib, pkgs, ... }:
with lib;
let
rspamdCfg = config.services.rspamd;
cfg = config.services.rmilter;
rmilterConf = ''
pidfile = /run/rmilter/rmilter.pid;
bind_socket = ${cfg.bindSocket};
tempdir = /tmp;
'' + (with cfg.rspamd; if enable then ''
spamd {
servers = ${concatStringsSep ", " servers};
connect_timeout = 1s;
results_timeout = 20s;
error_time = 10;
dead_time = 300;
maxerrors = 10;
reject_message = "${rejectMessage}";
${optionalString (length whitelist != 0) "whitelist = ${concatStringsSep ", " whitelist};"}
# rspamd_metric - metric for using with rspamd
# Default: "default"
rspamd_metric = "default";
${extraConfig}
};
'' else "") + cfg.extraConfig;
rmilterConfigFile = pkgs.writeText "rmilter.conf" rmilterConf;
in
{
###### interface
options = {
services.rmilter = {
enable = mkOption {
default = cfg.rspamd.enable;
description = "Whether to run the rmilter daemon.";
};
debug = mkOption {
default = false;
description = "Whether to run the rmilter daemon in debug mode.";
};
user = mkOption {
type = types.string;
default = "rmilter";
description = ''
User to use when no root privileges are required.
'';
};
group = mkOption {
type = types.string;
default = "rmilter";
description = ''
Group to use when no root privileges are required.
'';
};
bindSocket = mkOption {
type = types.string;
default = "unix:/run/rmilter/rmilter.sock";
description = "Socket to listed for MTA requests";
example = ''
"unix:/run/rmilter/rmilter.sock" or
"inet:11990@127.0.0.1"
'';
};
rspamd = {
enable = mkOption {
default = rspamdCfg.enable;
description = "Whether to use rspamd to filter mails";
};
servers = mkOption {
type = types.listOf types.str;
default = ["r:0.0.0.0:11333"];
description = ''
Spamd socket definitions.
Is server name is prefixed with r: it is rspamd server.
'';
};
whitelist = mkOption {
type = types.listOf types.str;
default = [ ];
description = "list of ips or nets that should be not checked with spamd";
};
rejectMessage = mkOption {
type = types.str;
default = "Spam message rejected; If this is not spam contact abuse";
description = "reject message for spam";
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = "Custom snippet to append to end of `spamd' section";
};
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = "Custom snippet to append to rmilter config";
};
postfix = {
enable = mkOption {
type = types.bool;
default = false;
description = "Add rmilter to postfix main.conf";
};
configFragment = mkOption {
type = types.str;
description = "Addon to postfix configuration";
default = ''
smtpd_milters = ${cfg.bindSocket}
# or for TCP socket
# # smtpd_milters = inet:localhost:9900
milter_protocol = 6
milter_mail_macros = i {mail_addr} {client_addr} {client_name} {auth_authen}
# skip mail without checks if milter will die
milter_default_action = accept
'';
};
};
};
};
###### implementation
config = mkIf cfg.enable {
users.extraUsers = singleton {
name = cfg.user;
description = "rspamd daemon";
uid = config.ids.uids.rmilter;
group = cfg.group;
};
users.extraGroups = singleton {
name = cfg.group;
gid = config.ids.gids.rmilter;
};
systemd.services.rmilter = {
description = "Rmilter Service";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
serviceConfig = {
ExecStart = "${pkgs.rmilter}/bin/rmilter ${optionalString cfg.debug "-d"} -n -c ${rmilterConfigFile}";
User = cfg.user;
Group = cfg.group;
PermissionsStartOnly = true;
Restart = "always";
};
preStart = ''
${pkgs.coreutils}/bin/mkdir -p /run/rmilter
${pkgs.coreutils}/bin/chown ${cfg.user}:${cfg.group} /run/rmilter
'';
};
services.postfix.extraConfig = optionalString cfg.postfix.enable cfg.postfix.configFragment;
};
}

View File

@ -0,0 +1,90 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.rspamd;
in
{
###### interface
options = {
services.rspamd = {
enable = mkOption {
default = false;
description = "Whether to run the rspamd daemon.";
};
debug = mkOption {
default = false;
description = "Whether to run the rspamd daemon in debug mode.";
};
user = mkOption {
type = types.string;
default = "rspamd";
description = ''
User to use when no root privileges are required.
'';
};
group = mkOption {
type = types.string;
default = "rspamd";
description = ''
Group to use when no root privileges are required.
'';
};
};
};
###### implementation
config = mkIf cfg.enable {
# Allow users to run 'rspamc' and 'rspamadm'.
environment.systemPackages = [ pkgs.rspamd ];
users.extraUsers = singleton {
name = cfg.user;
description = "rspamd daemon";
uid = config.ids.uids.rspamd;
group = cfg.group;
};
users.extraGroups = singleton {
name = cfg.group;
gid = config.ids.gids.spamd;
};
systemd.services.rspamd = {
description = "Rspamd Service";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
serviceConfig = {
ExecStart = "${pkgs.rspamd}/bin/rspamd ${optionalString cfg.debug "-d"} --user=${cfg.user} --group=${cfg.group} --pid=/run/rspamd.pid -f";
RuntimeDirectory = "/var/lib/rspamd";
PermissionsStartOnly = true;
Restart = "always";
};
preStart = ''
${pkgs.coreutils}/bin/mkdir -p /var/{lib,log}/rspamd
${pkgs.coreutils}/bin/chown ${cfg.user}:${cfg.group} /var/lib/rspamd
'';
};
};
}

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

@ -118,9 +118,8 @@ in {
package = mkOption { package = mkOption {
description = "The kafka package to use"; description = "The kafka package to use";
default = pkgs.apacheKafka; default = pkgs.apacheKafka;
defaultText = "pkgs.apacheKafka";
type = types.package; type = types.package;
}; };

View File

@ -27,8 +27,9 @@ in
}; };
autoMaster = mkOption { autoMaster = mkOption {
type = types.str;
example = literalExample '' example = literalExample ''
autoMaster = let let
mapConf = pkgs.writeText "auto" ''' mapConf = pkgs.writeText "auto" '''
kernel -ro,soft,intr ftp.kernel.org:/pub/linux kernel -ro,soft,intr ftp.kernel.org:/pub/linux
boot -fstype=ext2 :/dev/hda1 boot -fstype=ext2 :/dev/hda1

View File

@ -41,6 +41,7 @@ in
package = mkOption { package = mkOption {
default = pkgs.cgminer; default = pkgs.cgminer;
defaultText = "pkgs.cgminer";
description = "Which cgminer derivation to use."; description = "Which cgminer derivation to use.";
type = types.package; type = types.package;
}; };

View File

@ -64,6 +64,7 @@ in {
package = mkOption { package = mkOption {
description = "Confd package to use."; description = "Confd package to use.";
default = pkgs.confd; default = pkgs.confd;
defaultText = "pkgs.confd";
type = types.package; type = types.package;
}; };
}; };

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

@ -110,6 +110,7 @@ in
// optionalAttrs (config.services.mysql.enable) { mysqlPort = config.services.mysql.port; } // optionalAttrs (config.services.mysql.enable) { mysqlPort = config.services.mysql.port; }
// optionalAttrs (config.services.tomcat.enable) { tomcatPort = 8080; } // optionalAttrs (config.services.tomcat.enable) { tomcatPort = 8080; }
// optionalAttrs (config.services.svnserve.enable) { svnBaseDir = config.services.svnserve.svnBaseDir; } // optionalAttrs (config.services.svnserve.enable) { svnBaseDir = config.services.svnserve.svnBaseDir; }
// optionalAttrs (config.services.ejabberd.enable) { ejabberdUser = config.services.ejabberd.user; }
// optionalAttrs (cfg.publishInfrastructure.enableAuthentication) ( // optionalAttrs (cfg.publishInfrastructure.enableAuthentication) (
optionalAttrs (config.services.mysql.enable) { mysqlUsername = "root"; mysqlPassword = readFile config.services.mysql.rootPassword; }) optionalAttrs (config.services.mysql.enable) { mysqlUsername = "root"; mysqlPassword = readFile config.services.mysql.rootPassword; })
) )
@ -117,10 +118,9 @@ 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" ]
@ -150,16 +150,15 @@ in
fi fi
''; '';
exec = "disnix-service"; 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 = ''
exec =
''
${pkgs.avahi}/bin/avahi-publish-service disnix-${config.networking.hostName} _disnix._tcp 22 \ ${pkgs.avahi}/bin/avahi-publish-service disnix-${config.networking.hostName} _disnix._tcp 22 \
"mem=$(grep 'MemTotal:' /proc/meminfo | sed -e 's/kB//' -e 's/MemTotal://' -e 's/ //g')" \ "mem=$(grep 'MemTotal:' /proc/meminfo | sed -e 's/kB//' -e 's/MemTotal://' -e 's/ //g')" \
${concatMapStrings (infrastructureAttrName: ${concatMapStrings (infrastructureAttrName:

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}/bin/curl -s -o /dev/null 'http://${cfg.host}:${toString cfg.port}/'; do until ${pkgs.curl.bin}/bin/curl -s -o /dev/null 'http://${cfg.listenAddress}:${toString cfg.port}/'; do
sleep 1; sleep 1;
done done
''; '';

View File

@ -77,11 +77,11 @@ in {
default = {}; default = {};
example = literalExample '' example = literalExample ''
{ {
"CORS": "*", "CORS" = "*";
"NAME": "default-name", "NAME" = "default-name";
"MAX_RESULT_BUFFER": "1024", "MAX_RESULT_BUFFER" = "1024";
"MAX_CLUSTER_SIZE": "9", "MAX_CLUSTER_SIZE" = "9";
"MAX_RETRY_ATTEMPTS": "3" "MAX_RETRY_ATTEMPTS" = "3";
} }
''; '';
}; };

View File

@ -23,7 +23,9 @@ in
}; };
bundles = mkOption { bundles = mkOption {
type = types.listOf types.package;
default = [ pkgs.felix_remoteshell ]; default = [ pkgs.felix_remoteshell ];
defaultText = "[ pkgs.felix_remoteshell ]";
description = "List of bundles that should be activated on startup"; description = "List of bundles that should be activated on startup";
}; };
@ -57,11 +59,11 @@ 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
@ -98,13 +100,10 @@ in
fi fi
''; '';
script = script = ''
''
cd /var/felix cd /var/felix
${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c '${pkgs.jre}/bin/java -jar bin/felix.jar' ${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";
preStart =
''
mkdir -m 0755 -p ${stateDir} mkdir -m 0755 -p ${stateDir}
chown ${fahUser} ${stateDir} chown ${fahUser} ${stateDir}
cp -f ${pkgs.writeText "client.cfg" cfg.config} ${stateDir}/client.cfg 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'"; script = "${pkgs.su}/bin/su -s ${pkgs.stdenv.shell} ${fahUser} -c 'cd ${stateDir}; ${pkgs.foldingathome}/bin/fah6'";
}; };
services.foldingAtHome.config = '' services.foldingAtHome.config = ''
[settings] [settings]
username=${cfg.nickname} username=${cfg.nickname}
''; '';
}; };
} }

View File

@ -35,6 +35,7 @@ let
}; };
haskellPackages = mkOption { haskellPackages = mkOption {
type = types.attrsOf types.package;
default = pkgs.haskellPackages; default = pkgs.haskellPackages;
defaultText = "pkgs.haskellPackages"; defaultText = "pkgs.haskellPackages";
example = literalExample "pkgs.haskell.packages.ghc784"; example = literalExample "pkgs.haskell.packages.ghc784";

View File

@ -22,6 +22,7 @@ in
}; };
haskellPackages = mkOption { haskellPackages = mkOption {
type = types.attrsOf types.package;
default = pkgs.haskellPackages; default = pkgs.haskellPackages;
defaultText = "pkgs.haskellPackages"; defaultText = "pkgs.haskellPackages";
example = literalExample "pkgs.haskell.packages.ghc784"; example = literalExample "pkgs.haskell.packages.ghc784";

View File

@ -0,0 +1,54 @@
{ pkgs, lib, config, ... }:
with lib;
let
cfg = config.services.mathics;
in {
options = {
services.mathics = {
enable = mkEnableOption "Mathics notebook service";
external = mkOption {
type = types.bool;
default = false;
description = "Listen on all interfaces, rather than just localhost?";
};
port = mkOption {
type = types.int;
default = 8000;
description = "TCP port to listen on.";
};
};
};
config = mkIf cfg.enable {
users.extraUsers.mathics = {
group = config.users.extraGroups.mathics.name;
description = "Mathics user";
home = "/var/lib/mathics";
createHome = true;
uid = config.ids.uids.mathics;
};
users.extraGroups.mathics.gid = config.ids.gids.mathics;
systemd.services.mathics = {
description = "Mathics notebook server";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
serviceConfig = {
User = config.users.extraUsers.mathics.name;
Group = config.users.extraGroups.mathics.name;
ExecStart = concatStringsSep " " [
"${pkgs.mathics}/bin/mathicsserver"
"--port" (toString cfg.port)
(if cfg.external then "--external" else "")
];
};
};
};
}

View File

@ -0,0 +1,25 @@
version: 1
# In systemd's journal, loglevel is implicitly stored, so let's omit it
# from the message text.
formatters:
journal_fmt:
format: '%(name)s: [%(request)s] %(message)s'
filters:
context:
(): synapse.util.logcontext.LoggingContextFilter
request: ""
handlers:
journal:
class: systemd.journal.JournalHandler
formatter: journal_fmt
filters: [context]
SYSLOG_IDENTIFIER: synapse
root:
level: INFO
handlers: [journal]
disable_existing_loggers: False

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