Merge remote-tracking branch 'upstream/master' into gcc-6

This commit is contained in:
Robin Gloster 2017-01-20 16:37:16 +01:00
commit c273823585
No known key found for this signature in database
GPG Key ID: 5E4C836C632C2882
1071 changed files with 27996 additions and 14851 deletions

View File

@ -22,3 +22,7 @@ indent_size = 2
[*.{sh,py,pl}] [*.{sh,py,pl}]
indent_style = space indent_style = space
indent_size = 4 indent_size = 4
# Match diffs, avoid to trim trailing whitespace
[*.{diff,patch}]
trim_trailing_whitespace = false

View File

@ -1,4 +1,4 @@
Copyright (c) 2003-2016 Eelco Dolstra and the Nixpkgs/NixOS contributors Copyright (c) 2003-2017 Eelco Dolstra and the Nixpkgs/NixOS contributors
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the a copy of this software and associated documentation files (the

View File

@ -17,66 +17,6 @@
derivations or even the whole package set. derivations or even the whole package set.
</para> </para>
<section xml:id="sec-pkgs-overridePackages">
<title>pkgs.overridePackages</title>
<para>
This function inside the nixpkgs expression (<varname>pkgs</varname>)
can be used to override the set of packages itself.
</para>
<para>
Warning: this function is expensive and must not be used from within
the nixpkgs repository.
</para>
<para>
Example usage:
<programlisting>let
pkgs = import &lt;nixpkgs&gt; {};
newpkgs = pkgs.overridePackages (self: super: {
foo = super.foo.override { ... };
};
in ...</programlisting>
</para>
<para>
The resulting <varname>newpkgs</varname> will have the new <varname>foo</varname>
expression, and all other expressions depending on <varname>foo</varname> will also
use the new <varname>foo</varname> expression.
</para>
<para>
The behavior of this function is similar to <link
linkend="sec-modify-via-packageOverrides">config.packageOverrides</link>.
</para>
<para>
The <varname>self</varname> parameter refers to the final package set with the
applied overrides. Using this parameter may lead to infinite recursion if not
used consciously.
</para>
<para>
The <varname>super</varname> parameter refers to the old package set.
It's equivalent to <varname>pkgs</varname> in the above example.
</para>
<para>
Note that in previous versions of nixpkgs, this method replaced any changes from <link
linkend="sec-modify-via-packageOverrides">config.packageOverrides</link>,
along with that from previous calls if this function was called repeatedly.
Now those previous changes will be preserved so this function can be "chained" meaningfully.
To recover the old behavior, make sure <varname>config.packageOverrides</varname> is unset,
and call this only once off a "freshly" imported nixpkgs:
<programlisting>let
pkgs = import &lt;nixpkgs&gt; { config: {}; };
newpkgs = pkgs.overridePackages ...;
in ...</programlisting>
</para>
</section>
<section xml:id="sec-pkg-override"> <section xml:id="sec-pkg-override">
<title>&lt;pkg&gt;.override</title> <title>&lt;pkg&gt;.override</title>
@ -91,12 +31,12 @@
Example usages: Example usages:
<programlisting>pkgs.foo.override { arg1 = val1; arg2 = val2; ... }</programlisting> <programlisting>pkgs.foo.override { arg1 = val1; arg2 = val2; ... }</programlisting>
<programlisting>pkgs.overridePackages (self: super: { <programlisting>import pkgs.path { overlays = [ (self: super: {
foo = super.foo.override { barSupport = true ; }; foo = super.foo.override { barSupport = true ; };
})</programlisting> })]};</programlisting>
<programlisting>mypkg = pkgs.callPackage ./mypkg.nix { <programlisting>mypkg = pkgs.callPackage ./mypkg.nix {
mydep = pkgs.mydep.override { ... }; mydep = pkgs.mydep.override { ... };
})</programlisting> }</programlisting>
</para> </para>
<para> <para>

View File

@ -737,18 +737,18 @@ in (pkgs.python35.override {inherit packageOverrides;}).withPackages (ps: [ps.bl
``` ```
The requested package `blaze` depends on `pandas` which itself depends on `scipy`. The requested package `blaze` depends on `pandas` which itself depends on `scipy`.
If you want the whole of Nixpkgs to use your modifications, then you can use `pkgs.overridePackages` If you want the whole of Nixpkgs to use your modifications, then you can use `overlays`
as explained in this manual. In the following example we build a `inkscape` using a different version of `numpy`. as explained in this manual. In the following example we build a `inkscape` using a different version of `numpy`.
``` ```
let let
pkgs = import <nixpkgs> {}; pkgs = import <nixpkgs> {};
newpkgs = pkgs.overridePackages ( pkgsself: pkgssuper: { newpkgs = import pkgs.path { overlays = [ (pkgsself: pkgssuper: {
python27 = let python27 = let
packageOverrides = self: super: { packageOverrides = self: super: {
numpy = super.numpy_1_10; numpy = super.numpy_1_10;
}; };
in pkgssuper.python27.override {inherit packageOverrides;}; in pkgssuper.python27.override {inherit packageOverrides;};
} ); } ) ]; };
in newpkgs.inkscape in newpkgs.inkscape
``` ```
@ -804,6 +804,55 @@ If you want to create a Python environment for development, then the recommended
method is to use `nix-shell`, either with or without the `python.buildEnv` method is to use `nix-shell`, either with or without the `python.buildEnv`
function. function.
### How to consume python modules using pip in a virtualenv like I am used to on other Operating Systems ?
This is an example of a `default.nix` for a `nix-shell`, which allows to consume a `virtualenv` environment,
and install python modules through `pip` the traditional way.
Create this `default.nix` file, together with a `requirements.txt` and simply execute `nix-shell`.
```
with import <nixpkgs> {};
with pkgs.python27Packages;
stdenv.mkDerivation {
name = "impurePythonEnv";
buildInputs = [
# these packages are required for virtualenv and pip to work:
#
python27Full
python27Packages.virtualenv
python27Packages.pip
# the following packages are related to the dependencies of your python
# project.
# In this particular example the python modules listed in the
# requirements.tx require the following packages to be installed locally
# in order to compile any binary extensions they may require.
#
taglib
openssl
git
libxml2
libxslt
libzip
stdenv
zlib ];
src = null;
shellHook = ''
# set SOURCE_DATE_EPOCH so that we can use python wheels
SOURCE_DATE_EPOCH=$(date +%s)
virtualenv --no-setuptools venv
export PATH=$PWD/venv/bin:$PATH
pip install -r requirements.txt
'';
}
```
Note that the `pip install` is an imperative action. So every time `nix-shell`
is executed it will attempt to download the python modules listed in
requirements.txt. However these will be cached locally within the `virtualenv`
folder and not downloaded again.
## Contributing ## Contributing

View File

@ -26,9 +26,8 @@ bundlerEnv rec {
version = (import gemset).sensu.version; version = (import gemset).sensu.version;
inherit ruby; inherit ruby;
gemfile = ./Gemfile; # expects Gemfile, Gemfile.lock and gemset.nix in the same directory
lockfile = ./Gemfile.lock; gemdir = ./.;
gemset = ./gemset.nix;
meta = with lib; { meta = with lib; {
description = "A monitoring framework that aims to be simple, malleable, and scalable"; description = "A monitoring framework that aims to be simple, malleable, and scalable";

View File

@ -18,6 +18,7 @@
<xi:include href="meta.xml" /> <xi:include href="meta.xml" />
<xi:include href="languages-frameworks/index.xml" /> <xi:include href="languages-frameworks/index.xml" />
<xi:include href="package-notes.xml" /> <xi:include href="package-notes.xml" />
<xi:include href="overlays.xml" />
<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="reviewing-contributions.xml" /> <xi:include href="reviewing-contributions.xml" />

99
doc/overlays.xml Normal file
View File

@ -0,0 +1,99 @@
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="chap-overlays">
<title>Overlays</title>
<para>This chapter describes how to extend and change Nixpkgs packages using
overlays. Overlays are used to add layers in the fix-point used by Nixpkgs
to compose the set of all packages.</para>
<!--============================================================-->
<section xml:id="sec-overlays-install">
<title>Installing Overlays</title>
<para>The set of overlays is looked for in the following places. The
first one present is considered, and all the rest are ignored:
<orderedlist>
<listitem>
<para>As an argument of the imported attribute set. When importing Nixpkgs,
the <varname>overlays</varname> attribute argument can be set to a list of
functions, which is described in <xref linkend="sec-overlays-layout"/>.</para>
</listitem>
<listitem>
<para>In the directory pointed by the environment variable
<varname>NIXPKGS_OVERLAYS</varname>.</para>
</listitem>
<listitem>
<para>In the directory <filename>~/.nixpkgs/overlays/</filename>.</para>
</listitem>
</orderedlist>
</para>
<para>For the second and third options, the directory should contain Nix expressions defining the
overlays. Each overlay can be a file, a directory containing a
<filename>default.nix</filename>, or a symlink to one of those. The expressions should follow
the syntax described in <xref linkend="sec-overlays-layout"/>.</para>
<para>The order of the overlay layers can influence the recipe of packages if multiple layers override
the same recipe. In the case where overlays are loaded from a directory, they are loaded in
alphabetical order.</para>
<para>To install an overlay using the last option, you can clone the overlay's repository and add
a symbolic link to it in <filename>~/.nixpkgs/overlays/</filename> directory.</para>
</section>
<!--============================================================-->
<section xml:id="sec-overlays-layout">
<title>Overlays Layout</title>
<para>Overlays are expressed as Nix functions which accept 2 arguments and return a set of
packages.</para>
<programlisting>
self: super:
{
boost = super.boost.override {
python = self.python3;
};
rr = super.callPackage ./pkgs/rr {
stdenv = self.stdenv_32bit;
};
}
</programlisting>
<para>The first argument, usually named <varname>self</varname>, corresponds to the final package
set. You should use this set for the dependencies of all packages specified in your
overlay. For example, all the dependencies of <varname>rr</varname> in the example above come
from <varname>self</varname>, as well as the overriden dependencies used in the
<varname>boost</varname> override.</para>
<para>The second argument, usually named <varname>super</varname>,
corresponds to the result of the evaluation of the previous stages of
Nixpkgs. It does not contain any of the packages added by the current
overlay nor any of the following overlays. This set should be used either
to refer to packages you wish to override, or to access functions defined
in Nixpkgs. For example, the original recipe of <varname>boost</varname>
in the above example, comes from <varname>super</varname>, as well as the
<varname>callPackage</varname> function.</para>
<para>The value returned by this function should be a set similar to
<filename>pkgs/top-level/all-packages.nix</filename>, which contains
overridden and/or new packages.</para>
</section>
</chapter>

View File

@ -449,6 +449,12 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
fullName = "Sleepycat License"; fullName = "Sleepycat License";
}; };
smail = {
shortName = "smail";
fullName = "SMAIL General Public License";
url = http://metadata.ftp-master.debian.org/changelogs/main/d/debianutils/debianutils_4.8.1_copyright;
};
tcltk = spdx { tcltk = spdx {
spdxId = "TCL"; spdxId = "TCL";
fullName = "TCL/TK License"; fullName = "TCL/TK License";

View File

@ -109,6 +109,7 @@
cwoac = "Oliver Matthews <oliver@codersoffortune.net>"; cwoac = "Oliver Matthews <oliver@codersoffortune.net>";
DamienCassou = "Damien Cassou <damien@cassou.me>"; DamienCassou = "Damien Cassou <damien@cassou.me>";
danbst = "Danylo Hlynskyi <abcz2.uprola@gmail.com>"; danbst = "Danylo Hlynskyi <abcz2.uprola@gmail.com>";
danielfullmer = "Daniel Fullmer <danielrf12@gmail.com>";
dasuxullebt = "Christoph-Simon Senjak <christoph.senjak@googlemail.com>"; dasuxullebt = "Christoph-Simon Senjak <christoph.senjak@googlemail.com>";
davidak = "David Kleuker <post@davidak.de>"; davidak = "David Kleuker <post@davidak.de>";
davidrusu = "David Rusu <davidrusu.me@gmail.com>"; davidrusu = "David Rusu <davidrusu.me@gmail.com>";
@ -129,6 +130,7 @@
dochang = "Desmond O. Chang <dochang@gmail.com>"; dochang = "Desmond O. Chang <dochang@gmail.com>";
domenkozar = "Domen Kozar <domen@dev.si>"; domenkozar = "Domen Kozar <domen@dev.si>";
doublec = "Chris Double <chris.double@double.co.nz>"; doublec = "Chris Double <chris.double@double.co.nz>";
dpaetzel = "David Pätzel <david.a.paetzel@gmail.com>";
drets = "Dmytro Rets <dmitryrets@gmail.com>"; drets = "Dmytro Rets <dmitryrets@gmail.com>";
drewkett = "Andrew Burkett <burkett.andrew@gmail.com>"; drewkett = "Andrew Burkett <burkett.andrew@gmail.com>";
dtzWill = "Will Dietz <nix@wdtz.org>"; dtzWill = "Will Dietz <nix@wdtz.org>";
@ -200,22 +202,26 @@
ianwookim = "Ian-Woo Kim <ianwookim@gmail.com>"; ianwookim = "Ian-Woo Kim <ianwookim@gmail.com>";
igsha = "Igor Sharonov <igor.sharonov@gmail.com>"; igsha = "Igor Sharonov <igor.sharonov@gmail.com>";
ikervagyok = "Balázs Lengyel <ikervagyok@gmail.com>"; ikervagyok = "Balázs Lengyel <ikervagyok@gmail.com>";
ivan-tkatchev = "Ivan Tkatchev <tkatchev@gmail.com>";
j-keck = "Jürgen Keck <jhyphenkeck@gmail.com>"; j-keck = "Jürgen Keck <jhyphenkeck@gmail.com>";
jagajaga = "Arseniy Seroka <ars.seroka@gmail.com>"; jagajaga = "Arseniy Seroka <ars.seroka@gmail.com>";
javaguirre = "Javier Aguirre <contacto@javaguirre.net>"; javaguirre = "Javier Aguirre <contacto@javaguirre.net>";
jb55 = "William Casarin <bill@casarin.me>"; jb55 = "William Casarin <bill@casarin.me>";
jbedo = "Justin Bedő <cu@cua0.org>"; jbedo = "Justin Bedő <cu@cua0.org>";
jcumming = "Jack Cummings <jack@mudshark.org>"; jcumming = "Jack Cummings <jack@mudshark.org>";
jdagilliland = "Jason Gilliland <jdagilliland@gmail.com>";
jefdaj = "Jeffrey David Johnson <jefdaj@gmail.com>"; jefdaj = "Jeffrey David Johnson <jefdaj@gmail.com>";
jerith666 = "Matt McHenry <github@matt.mchenryfamily.org>"; jerith666 = "Matt McHenry <github@matt.mchenryfamily.org>";
jfb = "James Felix Black <james@yamtime.com>"; jfb = "James Felix Black <james@yamtime.com>";
jgeerds = "Jascha Geerds <jascha@jgeerds.name>"; jgeerds = "Jascha Geerds <jascha@jgeerds.name>";
jgertm = "Tim Jaeger <jger.tm@gmail.com>";
jgillich = "Jakob Gillich <jakob@gillich.me>"; jgillich = "Jakob Gillich <jakob@gillich.me>";
jirkamarsik = "Jirka Marsik <jiri.marsik89@gmail.com>"; jirkamarsik = "Jirka Marsik <jiri.marsik89@gmail.com>";
joachifm = "Joachim Fasting <joachifm@fastmail.fm>"; joachifm = "Joachim Fasting <joachifm@fastmail.fm>";
joamaki = "Jussi Maki <joamaki@gmail.com>"; joamaki = "Jussi Maki <joamaki@gmail.com>";
joelmo = "Joel Moberg <joel.moberg@gmail.com>"; joelmo = "Joel Moberg <joel.moberg@gmail.com>";
joelteon = "Joel Taylor <me@joelt.io>"; joelteon = "Joel Taylor <me@joelt.io>";
johbo = "Johannes Bornhold <johannes@bornhold.name>";
joko = "Ioannis Koutras <ioannis.koutras@gmail.com>"; joko = "Ioannis Koutras <ioannis.koutras@gmail.com>";
jonafato = "Jon Banafato <jon@jonafato.com>"; jonafato = "Jon Banafato <jon@jonafato.com>";
jpbernardy = "Jean-Philippe Bernardy <jeanphilippe.bernardy@gmail.com>"; jpbernardy = "Jean-Philippe Bernardy <jeanphilippe.bernardy@gmail.com>";
@ -232,6 +238,7 @@
KibaFox = "Kiba Fox <kiba.fox@foxypossibilities.com>"; KibaFox = "Kiba Fox <kiba.fox@foxypossibilities.com>";
kierdavis = "Kier Davis <kierdavis@gmail.com>"; kierdavis = "Kier Davis <kierdavis@gmail.com>";
kkallio = "Karn Kallio <tierpluspluslists@gmail.com>"; kkallio = "Karn Kallio <tierpluspluslists@gmail.com>";
knedlsepp = "Josef Kemetmüller <josef.kemetmueller@gmail.com>";
koral = "Koral <koral@mailoo.org>"; koral = "Koral <koral@mailoo.org>";
kovirobi = "Kovacsics Robert <kovirobi@gmail.com>"; kovirobi = "Kovacsics Robert <kovirobi@gmail.com>";
kragniz = "Louis Taylor <louis@kragniz.eu>"; kragniz = "Louis Taylor <louis@kragniz.eu>";
@ -239,7 +246,9 @@
lassulus = "Lassulus <lassulus@gmail.com>"; lassulus = "Lassulus <lassulus@gmail.com>";
layus = "Guillaume Maudoux <layus.on@gmail.com>"; layus = "Guillaume Maudoux <layus.on@gmail.com>";
ldesgoui = "Lucas Desgouilles <ldesgoui@gmail.com>"; ldesgoui = "Lucas Desgouilles <ldesgoui@gmail.com>";
league = "Christopher League <league@contrapunctus.net>";
lebastr = "Alexander Lebedev <lebastr@gmail.com>"; lebastr = "Alexander Lebedev <lebastr@gmail.com>";
leemachin = "Lee Machin <me@mrl.ee>";
leenaars = "Michiel Leenaars <ml.software@leenaa.rs>"; leenaars = "Michiel Leenaars <ml.software@leenaa.rs>";
leonardoce = "Leonardo Cecchi <leonardo.cecchi@gmail.com>"; leonardoce = "Leonardo Cecchi <leonardo.cecchi@gmail.com>";
lethalman = "Luca Bruno <lucabru@src.gnome.org>"; lethalman = "Luca Bruno <lucabru@src.gnome.org>";
@ -313,6 +322,7 @@
mudri = "James Wood <lamudri@gmail.com>"; mudri = "James Wood <lamudri@gmail.com>";
muflax = "Stefan Dorn <mail@muflax.com>"; muflax = "Stefan Dorn <mail@muflax.com>";
myrl = "Myrl Hex <myrl.0xf@gmail.com>"; myrl = "Myrl Hex <myrl.0xf@gmail.com>";
namore = "Roman Naumann <namor@hemio.de>";
nand0p = "Fernando Jose Pando <nando@hex7.com>"; nand0p = "Fernando Jose Pando <nando@hex7.com>";
Nate-Devv = "Nathan Moore <natedevv@gmail.com>"; Nate-Devv = "Nathan Moore <natedevv@gmail.com>";
nathan-gs = "Nathan Bijnens <nathan@nathan.gs>"; nathan-gs = "Nathan Bijnens <nathan@nathan.gs>";
@ -323,6 +333,7 @@
nicknovitski = "Nick Novitski <nixpkgs@nicknovitski.com>"; nicknovitski = "Nick Novitski <nixpkgs@nicknovitski.com>";
nico202 = "Nicolò Balzarotti <anothersms@gmail.com>"; nico202 = "Nicolò Balzarotti <anothersms@gmail.com>";
NikolaMandic = "Ratko Mladic <nikola@mandic.email>"; NikolaMandic = "Ratko Mladic <nikola@mandic.email>";
nixy = "Andrew R. M. <andrewmiller237@gmail.com>";
notthemessiah = "Brian Cohen <brian.cohen.88@gmail.com>"; notthemessiah = "Brian Cohen <brian.cohen.88@gmail.com>";
np = "Nicolas Pouillard <np.nix@nicolaspouillard.fr>"; np = "Nicolas Pouillard <np.nix@nicolaspouillard.fr>";
nslqqq = "Nikita Mikhailov <nslqqq@gmail.com>"; nslqqq = "Nikita Mikhailov <nslqqq@gmail.com>";
@ -330,6 +341,7 @@
ocharles = "Oliver Charles <ollie@ocharles.org.uk>"; ocharles = "Oliver Charles <ollie@ocharles.org.uk>";
odi = "Oliver Dunkl <oliver.dunkl@gmail.com>"; odi = "Oliver Dunkl <oliver.dunkl@gmail.com>";
offline = "Jaka Hudoklin <jakahudoklin@gmail.com>"; offline = "Jaka Hudoklin <jakahudoklin@gmail.com>";
oida = "oida <oida@posteo.de>";
okasu = "Okasu <oka.sux@gmail.com>"; okasu = "Okasu <oka.sux@gmail.com>";
olcai = "Erik Timan <dev@timan.info>"; olcai = "Erik Timan <dev@timan.info>";
olejorgenb = "Ole Jørgen Brønner <olejorgenb@yahoo.no>"; olejorgenb = "Ole Jørgen Brønner <olejorgenb@yahoo.no>";
@ -361,6 +373,7 @@
plcplc = "Philip Lykke Carlsen <plcplc@gmail.com>"; plcplc = "Philip Lykke Carlsen <plcplc@gmail.com>";
pmahoney = "Patrick Mahoney <pat@polycrystal.org>"; pmahoney = "Patrick Mahoney <pat@polycrystal.org>";
pmiddend = "Philipp Middendorf <pmidden@secure.mailbox.org>"; pmiddend = "Philipp Middendorf <pmidden@secure.mailbox.org>";
polyrod = "Maurizio Di Pietro <dc1mdp@gmail.com>";
prikhi = "Pavan Rikhi <pavan.rikhi@gmail.com>"; prikhi = "Pavan Rikhi <pavan.rikhi@gmail.com>";
primeos = "Michael Weiss <dev.primeos@gmail.com>"; primeos = "Michael Weiss <dev.primeos@gmail.com>";
profpatsch = "Profpatsch <mail@profpatsch.de>"; profpatsch = "Profpatsch <mail@profpatsch.de>";
@ -435,6 +448,7 @@
spinus = "Tomasz Czyż <tomasz.czyz@gmail.com>"; spinus = "Tomasz Czyż <tomasz.czyz@gmail.com>";
sprock = "Roger Mason <rmason@mun.ca>"; sprock = "Roger Mason <rmason@mun.ca>";
spwhitt = "Spencer Whitt <sw@swhitt.me>"; spwhitt = "Spencer Whitt <sw@swhitt.me>";
srhb = "Sarah Brofeldt <sbrofeldt@gmail.com>";
SShrike = "Severen Redwood <severen@shrike.me>"; SShrike = "Severen Redwood <severen@shrike.me>";
stephenmw = "Stephen Weinberg <stephen@q5comm.com>"; stephenmw = "Stephen Weinberg <stephen@q5comm.com>";
sternenseemann = "Lukas Epple <post@lukasepple.de>"; sternenseemann = "Lukas Epple <post@lukasepple.de>";
@ -501,8 +515,10 @@
yurrriq = "Eric Bailey <eric@ericb.me>"; yurrriq = "Eric Bailey <eric@ericb.me>";
z77z = "Marco Maggesi <maggesi@math.unifi.it>"; z77z = "Marco Maggesi <maggesi@math.unifi.it>";
zagy = "Christian Zagrodnick <cz@flyingcircus.io>"; zagy = "Christian Zagrodnick <cz@flyingcircus.io>";
zauberpony = "Elmar Athmer <elmar@athmer.org>";
zef = "Zef Hemel <zef@zef.me>"; zef = "Zef Hemel <zef@zef.me>";
zimbatm = "zimbatm <zimbatm@zimbatm.com>"; zimbatm = "zimbatm <zimbatm@zimbatm.com>";
zohl = "Al Zohali <zohl@fmap.me>"; zohl = "Al Zohali <zohl@fmap.me>";
zoomulator = "Kim Simmons <zoomulator@gmail.com>"; zoomulator = "Kim Simmons <zoomulator@gmail.com>";
zraexy = "David Mell <zraexy@gmail.com>";
} }

View File

@ -11,7 +11,9 @@ has the following highlights: </para>
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para></para> <para>Nixpkgs is now extensible through overlays. See the <link
xlink:href="https://nixos.org/nixpkgs/manual/#sec-overlays-install">Nixpkgs
manual</link> for more information.</para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
@ -28,6 +30,14 @@ has the following highlights: </para>
following incompatible changes:</para> following incompatible changes:</para>
<itemizedlist> <itemizedlist>
<listitem>
<para>
<literal>stdenv.overrides</literal> is now expected to take <literal>self</literal>
and <literal>super</literal> arguments. See <literal>lib.trivial.extends</literal>
for what those parameters represent.
</para>
</listitem>
<listitem> <listitem>
<para> <para>
<literal>gnome</literal> alias has been removed along with <literal>gnome</literal> alias has been removed along with
@ -88,6 +98,32 @@ following incompatible changes:</para>
<literal>networking.timeServers</literal>. <literal>networking.timeServers</literal>.
</para> </para>
</listitem> </listitem>
<listitem>
<para><literal>overridePackages</literal> function no longer exists.
It is replaced by <link
xlink:href="https://nixos.org/nixpkgs/manual/#sec-overlays-install">
overlays</link>. For example, the following code:
<programlisting>
let
pkgs = import &lt;nixpkgs&gt; {};
in
pkgs.overridePackages (self: super: ...)
</programlisting>
should be replaced by:
<programlisting>
let
pkgs = import &lt;nixpkgs&gt; {};
in
import pkgs.path { overlays = [(self: super: ...)] }
</programlisting>
</para>
</listitem>
</itemizedlist> </itemizedlist>

View File

@ -1,4 +1,4 @@
# From an end-user configuration file (`configuration'), build a NixOS # From an end-user configuration file (`configuration.nix'), build a NixOS
# configuration object (`config') from which we can retrieve option # configuration object (`config') from which we can retrieve option
# values. # values.

View File

@ -25,6 +25,6 @@ stdenv.mkDerivation {
# Generate the squashfs image. # Generate the squashfs image.
mksquashfs nix-path-registration $storePaths $out \ mksquashfs nix-path-registration $storePaths $out \
-keep-as-directory -all-root -comp xz -keep-as-directory -all-root -b 1048576 -comp xz -Xdict-size 100%
''; '';
} }

View File

@ -54,7 +54,7 @@ mkdir -p $out/tarball
rm env-vars rm env-vars
tar --sort=name --mtime='1970-01-01' -cvJf $out/tarball/$fileName.tar.xz * $extraArgs tar --sort=name --mtime='@1' --owner=0 --group=0 --numeric-owner -cvJf $out/tarball/$fileName.tar.xz * $extraArgs
mkdir -p $out/nix-support mkdir -p $out/nix-support
echo $system > $out/nix-support/system echo $system > $out/nix-support/system

View File

@ -611,11 +611,37 @@ sub copyFileFromHost {
} }
my %charToKey = (
'!' => "shift-0x02",
'@' => "shift-0x03",
'#' => "shift-0x04",
'$' => "shift-0x05",
'%' => "shift-0x06",
'^' => "shift-0x07",
'&' => "shift-0x08",
'*' => "shift-0x09",
'(' => "shift-0x0A",
')' => "shift-0x0B",
'-' => "0x0C", '_' => "shift-0x0C",
'=' => "0x0D", '+' => "shift-0x0D",
'[' => "0x1A", '{' => "shift-0x1A",
']' => "0x1B", '}' => "shift-0x1B",
';' => "0x27", ':' => "shift-0x27",
'\'' => "0x28", '"' => "shift-0x28",
'`' => "0x29", '~' => "shift-0x29",
'\\' => "0x2B", '|' => "shift-0x2B",
',' => "0x33", '<' => "shift-0x33",
'.' => "0x34", '>' => "shift-0x34",
'/' => "0x35", '?' => "shift-0x35",
' ' => "spc",
"\n" => "ret",
);
sub sendKeys { sub sendKeys {
my ($self, @keys) = @_; my ($self, @keys) = @_;
foreach my $key (@keys) { foreach my $key (@keys) {
$key = "spc" if $key eq " "; $key = $charToKey{$key} if exists $charToKey{$key};
$key = "ret" if $key eq "\n";
$self->sendMonitorCommand("sendkey $key"); $self->sendMonitorCommand("sendkey $key");
} }
} }

View File

@ -8,6 +8,7 @@ use IO::Pty;
use Logger; use Logger;
use Cwd; use Cwd;
use POSIX qw(_exit dup2); use POSIX qw(_exit dup2);
use Time::HiRes qw(clock_gettime CLOCK_MONOTONIC);
$SIG{PIPE} = 'IGNORE'; # because Unix domain sockets may die unexpectedly $SIG{PIPE} = 'IGNORE'; # because Unix domain sockets may die unexpectedly
@ -179,7 +180,12 @@ END {
$log->close(); $log->close();
} }
my $now1 = clock_gettime(CLOCK_MONOTONIC);
runTests; runTests;
my $now2 = clock_gettime(CLOCK_MONOTONIC);
printf STDERR "test script finished in %.2fs\n", $now2 - $now1;
exit ($nrSucceeded < $nrTests ? 1 : 0); exit ($nrSucceeded < $nrTests ? 1 : 0);

View File

@ -19,7 +19,7 @@ rm -f ec2-amis.nix
types="hvm pv" types="hvm pv"
stores="ebs s3" stores="ebs s3"
regions="eu-west-1 eu-central-1 us-east-1 us-east-2 us-west-1 us-west-2 ap-southeast-1 ap-southeast-2 ap-northeast-1 ap-northeast-2 sa-east-1 ap-south-1" regions="eu-west-1 eu-west-2 eu-central-1 us-east-1 us-east-2 us-west-1 us-west-2 ap-southeast-1 ap-southeast-2 ap-northeast-1 ap-northeast-2 sa-east-1 ap-south-1"
for type in $types; do for type in $types; do
link=$stateDir/$type link=$stateDir/$type

View File

@ -57,7 +57,7 @@ in
networking.dnsExtensionMechanism = lib.mkOption { networking.dnsExtensionMechanism = lib.mkOption {
type = types.bool; type = types.bool;
default = false; default = true;
description = '' description = ''
Enable the <code>edns0</code> option in <filename>resolv.conf</filename>. With Enable the <code>edns0</code> option in <filename>resolv.conf</filename>. With
that option set, <code>glibc</code> supports use of the extension mechanisms for that option set, <code>glibc</code> supports use of the extension mechanisms for

View File

@ -9,6 +9,7 @@ let
inherit (config.services.avahi) nssmdns; inherit (config.services.avahi) nssmdns;
inherit (config.services.samba) nsswins; inherit (config.services.samba) nsswins;
ldap = (config.users.ldap.enable && config.users.ldap.nsswitch); ldap = (config.users.ldap.enable && config.users.ldap.nsswitch);
sssd = config.services.sssd.enable;
hostArray = [ "files" "mymachines" ] hostArray = [ "files" "mymachines" ]
++ optionals nssmdns [ "mdns_minimal [!UNAVAIL=return]" ] ++ optionals nssmdns [ "mdns_minimal [!UNAVAIL=return]" ]
@ -18,12 +19,17 @@ let
++ ["myhostname" ]; ++ ["myhostname" ];
passwdArray = [ "files" ] passwdArray = [ "files" ]
++ optional sssd "sss"
++ optionals ldap [ "ldap" ] ++ optionals ldap [ "ldap" ]
++ [ "mymachines" ]; ++ [ "mymachines" ];
shadowArray = [ "files" ] shadowArray = [ "files" ]
++ optional sssd "sss"
++ optionals ldap [ "ldap" ]; ++ optionals ldap [ "ldap" ];
servicesArray = [ "files" ]
++ optional sssd "sss";
in { in {
options = { options = {
@ -60,7 +66,7 @@ in {
networks: files networks: files
ethers: files ethers: files
services: files services: ${concatStringsSep " " servicesArray}
protocols: files protocols: files
rpc: files rpc: files
''; '';

View File

@ -69,7 +69,7 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
# FIXME: Implement powersave governor for sandy bridge or later Intel CPUs # Leftover for old setups, should be set by nixos-generate-config now
powerManagement.cpuFreqGovernor = mkDefault "ondemand"; powerManagement.cpuFreqGovernor = mkDefault "ondemand";
systemd.targets.post-resume = { systemd.targets.post-resume = {

View File

@ -160,6 +160,13 @@ in {
if activated. if activated.
''; '';
}; };
config = mkOption {
type = types.attrsOf types.unspecified;
default = {};
description = ''Config of the pulse daemon. See <literal>man pulse-daemon.conf</literal>.'';
example = literalExample ''{ flat-volumes = "no"; }'';
};
}; };
zeroconf = { zeroconf = {
@ -204,14 +211,18 @@ in {
(mkIf cfg.enable { (mkIf cfg.enable {
environment.systemPackages = [ overriddenPackage ]; environment.systemPackages = [ overriddenPackage ];
environment.etc = singleton { environment.etc = [
target = "asound.conf"; { target = "asound.conf";
source = alsaConf; source = alsaConf; }
};
{ target = "pulse/daemon.conf";
source = writeText "daemon.conf" (lib.generators.toKeyValue {} cfg.daemon.config); }
];
# Allow PulseAudio to get realtime priority using rtkit. # Allow PulseAudio to get realtime priority using rtkit.
security.rtkit.enable = true; security.rtkit.enable = true;
systemd.packages = [ cfg.package ];
}) })
(mkIf hasZeroconf { (mkIf hasZeroconf {
@ -227,31 +238,14 @@ in {
target = "pulse/default.pa"; target = "pulse/default.pa";
source = myConfigFile; source = myConfigFile;
}; };
systemd.user = { systemd.user = {
services.pulseaudio = { services.pulseaudio = {
description = "PulseAudio Server";
# NixOS doesn't support "Also" so we bring it in manually
wantedBy = [ "default.target" ];
serviceConfig = { serviceConfig = {
Type = "notify";
ExecStart = binaryNoDaemon;
Restart = "on-failure";
RestartSec = "500ms"; RestartSec = "500ms";
}; };
environment = { DISPLAY = ":${toString config.services.xserver.display}"; }; environment = { DISPLAY = ":${toString config.services.xserver.display}"; };
restartIfChanged = true; restartIfChanged = true;
}; };
sockets.pulseaudio = {
description = "PulseAudio Socket";
wantedBy = [ "sockets.target" ];
socketConfig = {
Priority = 6;
Backlog = 5;
ListenStream = "%t/pulse/native";
};
};
}; };
}) })

View File

@ -0,0 +1,40 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.hardware.ckb;
in
{
options.hardware.ckb = {
enable = mkEnableOption "the Corsair keyboard/mouse driver";
package = mkOption {
type = types.package;
default = pkgs.ckb;
defaultText = "pkgs.ckb";
description = ''
The package implementing the Corsair keyboard/mouse driver.
'';
};
};
config = mkIf cfg.enable {
environment.systemPackages = [ cfg.package ];
systemd.services.ckb = {
description = "Corsair Keyboard Daemon";
wantedBy = ["multi-user.target"];
script = "${cfg.package}/bin/ckb-daemon";
serviceConfig = {
Restart = "always";
StandardOutput = "syslog";
};
};
};
meta = {
maintainers = with lib.maintainers; [ kierdavis ];
};
}

View File

@ -96,7 +96,7 @@ in
example = literalExample "with pkgs; [ vaapiIntel libvdpau-va-gl vaapiVdpau ]"; example = literalExample "with pkgs; [ vaapiIntel libvdpau-va-gl vaapiVdpau ]";
description = '' description = ''
Additional packages to add to OpenGL drivers. This can be used Additional packages to add to OpenGL drivers. This can be used
to add additional VA-API/VDPAU drivers. to add OpenCL drivers, VA-API/VDPAU drivers etc.
''; '';
}; };
@ -107,7 +107,7 @@ in
description = '' description = ''
Additional packages to add to 32-bit OpenGL drivers on Additional packages to add to 32-bit OpenGL drivers on
64-bit systems. Used when <option>driSupport32Bit</option> is 64-bit systems. Used when <option>driSupport32Bit</option> is
set. This can be used to add additional VA-API/VDPAU drivers. set. This can be used to add OpenCL drivers, VA-API/VDPAU drivers etc.
''; '';
}; };

View File

@ -1,11 +1,10 @@
# This module defines a small NixOS installation CD. It does not # This module defines a small NixOS installation CD. It does not
# contain any graphical stuff. # contain any graphical stuff.
{ config, lib, ... }: { config, lib, pkgs, ... }:
{ {
imports = imports =
[ ./installation-cd-base.nix [ ./installation-cd-base.nix
../../profiles/minimal.nix
]; ];
} }

View File

@ -178,7 +178,7 @@ in
image. It significantly increases image size. Use that when image. It significantly increases image size. Use that when
you want to be able to keep all the sources needed to build your you want to be able to keep all the sources needed to build your
system or when you are going to install the system on a computer system or when you are going to install the system on a computer
with slow on non-existent network connection. with slow or non-existent network connection.
''; '';
}; };
@ -232,8 +232,6 @@ in
system.boot.loader.kernelFile = "bzImage"; system.boot.loader.kernelFile = "bzImage";
environment.systemPackages = [ pkgs.grub2 pkgs.grub2_efi pkgs.syslinux ]; environment.systemPackages = [ pkgs.grub2 pkgs.grub2_efi pkgs.syslinux ];
boot.consoleLogLevel = mkDefault 7;
# In stage 1 of the boot, mount the CD as the root FS by label so # In stage 1 of the boot, mount the CD as the root FS by label so
# that we don't need to know its device. We pass the label of the # that we don't need to know its device. We pass the label of the
# root filesystem on the kernel command line, rather than in # root filesystem on the kernel command line, rather than in

View File

@ -27,7 +27,6 @@ in
boot.kernelPackages = pkgs.linuxPackages_latest; boot.kernelPackages = pkgs.linuxPackages_latest;
boot.kernelParams = ["console=ttyS0,115200n8" "console=ttymxc0,115200n8" "console=ttyAMA0,115200n8" "console=ttyO0,115200n8" "console=tty0"]; boot.kernelParams = ["console=ttyS0,115200n8" "console=ttymxc0,115200n8" "console=ttyAMA0,115200n8" "console=ttyO0,115200n8" "console=tty0"];
boot.consoleLogLevel = 7;
# FIXME: this probably should be in installation-device.nix # FIXME: this probably should be in installation-device.nix
users.extraUsers.root.initialHashedPassword = ""; users.extraUsers.root.initialHashedPassword = "";

View File

@ -26,7 +26,6 @@ in
boot.loader.generic-extlinux-compatible.enable = true; boot.loader.generic-extlinux-compatible.enable = true;
boot.kernelPackages = pkgs.linuxPackages_rpi; boot.kernelPackages = pkgs.linuxPackages_rpi;
boot.consoleLogLevel = 7;
# FIXME: this probably should be in installation-device.nix # FIXME: this probably should be in installation-device.nix
users.extraUsers.root.initialHashedPassword = ""; users.extraUsers.root.initialHashedPassword = "";

View File

@ -30,8 +30,6 @@ with lib;
system.boot.loader.kernelFile = "bzImage"; system.boot.loader.kernelFile = "bzImage";
environment.systemPackages = [ pkgs.grub2 pkgs.grub2_efi pkgs.syslinux ]; environment.systemPackages = [ pkgs.grub2 pkgs.grub2_efi pkgs.syslinux ];
boot.consoleLogLevel = mkDefault 7;
fileSystems."/" = fileSystems."/" =
{ fsType = "tmpfs"; { fsType = "tmpfs";
options = [ "mode=0755" ]; options = [ "mode=0755" ];

View File

@ -1,5 +1,5 @@
{ {
x86_64-linux = "/nix/store/i4mwf2gpvar7dqvlpp5m86llbq3ahbvb-nix-1.11.4"; x86_64-linux = "/nix/store/qdkzm17csr24snk247a1s0c47ikq5sl6-nix-1.11.6";
i686-linux = "/nix/store/a3gjrbspb0q4hs3sv5g1y2nza43i8nzv-nix-1.11.4"; i686-linux = "/nix/store/hiwp53747lxlniqy5wpbql5izjrs8z0z-nix-1.11.6";
x86_64-darwin = "/nix/store/7v21yd3qpv0nclcy5cqr5njj9bril12s-nix-1.11.4"; x86_64-darwin = "/nix/store/hca2hqcvwncf23hiqyqgwbsdy8vvl9xv-nix-1.11.6";
} }

View File

@ -94,6 +94,21 @@ sub hasCPUFeature {
my $cpus = scalar (grep {/^processor\s*:/} (split '\n', $cpuinfo)); my $cpus = scalar (grep {/^processor\s*:/} (split '\n', $cpuinfo));
# Determine CPU governor to use
if (-e "/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors") {
my $governors = read_file("/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors");
# ondemand governor is not available on sandy bridge or later Intel CPUs
my @desired_governors = ("ondemand", "powersave");
my $e;
foreach $e (@desired_governors) {
if (index($governors, $e) != -1) {
last if (push @attrs, "powerManagement.cpuFreqGovernor = \"$e\";");
}
}
}
# Virtualization support? # Virtualization support?
push @kernelModules, "kvm-intel" if hasCPUFeature "vmx"; push @kernelModules, "kvm-intel" if hasCPUFeature "vmx";
push @kernelModules, "kvm-amd" if hasCPUFeature "svm"; push @kernelModules, "kvm-amd" if hasCPUFeature "svm";

View File

@ -281,6 +281,8 @@
riak-cs = 263; riak-cs = 263;
infinoted = 264; infinoted = 264;
keystone = 265; keystone = 265;
glance = 266;
couchpotato = 267;
# 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!
@ -467,7 +469,7 @@
ihaskell = 189; ihaskell = 189;
i2p = 190; i2p = 190;
lambdabot = 191; lambdabot = 191;
#asterisk = 192; # unused asterisk = 192;
plex = 193; plex = 193;
sabnzbd = 194; sabnzbd = 194;
#grafana = 196; #unused #grafana = 196; #unused
@ -532,6 +534,8 @@
riak-cs = 263; riak-cs = 263;
infinoted = 264; infinoted = 264;
keystone = 265; keystone = 265;
glance = 266;
couchpotato = 267;
# 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

@ -15,6 +15,15 @@ in {
''; '';
}; };
locate = mkOption {
type = types.package;
default = pkgs.findutils;
example = "pkgs.mlocate";
description = ''
The locate implementation to use
'';
};
interval = mkOption { interval = mkOption {
type = types.str; type = types.str;
default = "02:15"; default = "02:15";
@ -77,7 +86,7 @@ in {
script = script =
'' ''
mkdir -m 0755 -p $(dirname ${toString cfg.output}) mkdir -m 0755 -p $(dirname ${toString cfg.output})
exec updatedb \ exec ${cfg.locate}/bin/updatedb \
--localuser=${cfg.localuser} \ --localuser=${cfg.localuser} \
${optionalString (!cfg.includeStore) "--prunepaths='/nix/store'"} \ ${optionalString (!cfg.includeStore) "--prunepaths='/nix/store'"} \
--output=${toString cfg.output} ${concatStringsSep " " cfg.extraFlags} --output=${toString cfg.output} ${concatStringsSep " " cfg.extraFlags}

View File

@ -29,11 +29,19 @@ let
}; };
configType = mkOptionType { configType = mkOptionType {
name = "nixpkgs config"; name = "nixpkgs-config";
description = "nixpkgs config";
check = traceValIfNot isConfig; check = traceValIfNot isConfig;
merge = args: fold (def: mergeConfig def.value) {}; merge = args: fold (def: mergeConfig def.value) {};
}; };
overlayType = mkOptionType {
name = "nixpkgs-overlay";
description = "nixpkgs overlay";
check = builtins.isFunction;
merge = lib.mergeOneOption;
};
in in
{ {
@ -43,23 +51,37 @@ in
default = {}; default = {};
example = literalExample example = literalExample
'' ''
{ firefox.enableGeckoMediaPlayer = true; { firefox.enableGeckoMediaPlayer = true; }
packageOverrides = pkgs: {
firefox60Pkgs = pkgs.firefox60Pkgs.override {
enableOfficialBranding = true;
};
};
}
''; '';
type = configType; type = configType;
description = '' description = ''
The configuration of the Nix Packages collection. (For The configuration of the Nix Packages collection. (For
details, see the Nixpkgs documentation.) It allows you to set details, see the Nixpkgs documentation.) It allows you to set
package configuration options, and to override packages package configuration options.
globally through the <varname>packageOverrides</varname> '';
option. The latter is a function that takes as an argument };
the <emphasis>original</emphasis> Nixpkgs, and must evaluate
to a set of new or overridden packages. nixpkgs.overlays = mkOption {
default = [];
example = literalExample
''
[ (self: super: {
openssh = super.openssh.override {
hpnSupport = true;
withKerberos = true;
kerberos = self.libkrb5;
};
};
) ]
'';
type = types.listOf overlayType;
description = ''
List of overlays to use with the Nix Packages collection.
(For details, see the Nixpkgs documentation.) It allows
you to override packages globally. This is a function that
takes as an argument the <emphasis>original</emphasis> Nixpkgs.
The first argument should be used for finding dependencies, and
the second should be used for overriding recipes.
''; '';
}; };

View File

@ -99,7 +99,7 @@ in
}; };
# Generate /etc/os-release. See # Generate /etc/os-release. See
# http://0pointer.de/public/systemd-man/os-release.html for the # https://www.freedesktop.org/software/systemd/man/os-release.html for the
# format. # format.
environment.etc."os-release".text = environment.etc."os-release".text =
'' ''

View File

@ -26,6 +26,7 @@
./config/vpnc.nix ./config/vpnc.nix
./config/zram.nix ./config/zram.nix
./hardware/all-firmware.nix ./hardware/all-firmware.nix
./hardware/ckb.nix
./hardware/cpu/amd-microcode.nix ./hardware/cpu/amd-microcode.nix
./hardware/cpu/intel-microcode.nix ./hardware/cpu/intel-microcode.nix
./hardware/ksm.nix ./hardware/ksm.nix
@ -66,11 +67,13 @@
./programs/bash/bash.nix ./programs/bash/bash.nix
./programs/blcr.nix ./programs/blcr.nix
./programs/cdemu.nix ./programs/cdemu.nix
./programs/chromium.nix
./programs/command-not-found/command-not-found.nix ./programs/command-not-found/command-not-found.nix
./programs/dconf.nix ./programs/dconf.nix
./programs/environment.nix ./programs/environment.nix
./programs/fish.nix ./programs/fish.nix
./programs/freetds.nix ./programs/freetds.nix
./programs/gphoto2.nix
./programs/info.nix ./programs/info.nix
./programs/java.nix ./programs/java.nix
./programs/kbdlight.nix ./programs/kbdlight.nix
@ -240,6 +243,7 @@
./services/misc/cpuminer-cryptonight.nix ./services/misc/cpuminer-cryptonight.nix
./services/misc/cgminer.nix ./services/misc/cgminer.nix
./services/misc/confd.nix ./services/misc/confd.nix
./services/misc/couchpotato.nix
./services/misc/devmon.nix ./services/misc/devmon.nix
./services/misc/dictd.nix ./services/misc/dictd.nix
./services/misc/dysnomia.nix ./services/misc/dysnomia.nix
@ -284,6 +288,7 @@
./services/misc/siproxd.nix ./services/misc/siproxd.nix
./services/misc/sonarr.nix ./services/misc/sonarr.nix
./services/misc/spice-vdagentd.nix ./services/misc/spice-vdagentd.nix
./services/misc/sssd.nix
./services/misc/subsonic.nix ./services/misc/subsonic.nix
./services/misc/sundtek.nix ./services/misc/sundtek.nix
./services/misc/svnserve.nix ./services/misc/svnserve.nix
@ -292,6 +297,7 @@
./services/misc/uhub.nix ./services/misc/uhub.nix
./services/misc/zookeeper.nix ./services/misc/zookeeper.nix
./services/monitoring/apcupsd.nix ./services/monitoring/apcupsd.nix
./services/monitoring/arbtt.nix
./services/monitoring/bosun.nix ./services/monitoring/bosun.nix
./services/monitoring/cadvisor.nix ./services/monitoring/cadvisor.nix
./services/monitoring/collectd.nix ./services/monitoring/collectd.nix
@ -306,8 +312,13 @@
./services/monitoring/munin.nix ./services/monitoring/munin.nix
./services/monitoring/nagios.nix ./services/monitoring/nagios.nix
./services/monitoring/prometheus/default.nix ./services/monitoring/prometheus/default.nix
./services/monitoring/prometheus/node-exporter.nix
./services/monitoring/prometheus/alertmanager.nix ./services/monitoring/prometheus/alertmanager.nix
./services/monitoring/prometheus/blackbox-exporter.nix
./services/monitoring/prometheus/json-exporter.nix
./services/monitoring/prometheus/nginx-exporter.nix
./services/monitoring/prometheus/node-exporter.nix
./services/monitoring/prometheus/snmp-exporter.nix
./services/monitoring/prometheus/varnish-exporter.nix
./services/monitoring/riemann.nix ./services/monitoring/riemann.nix
./services/monitoring/riemann-dash.nix ./services/monitoring/riemann-dash.nix
./services/monitoring/riemann-tools.nix ./services/monitoring/riemann-tools.nix
@ -392,6 +403,7 @@
./services/networking/minidlna.nix ./services/networking/minidlna.nix
./services/networking/miniupnpd.nix ./services/networking/miniupnpd.nix
./services/networking/mosquitto.nix ./services/networking/mosquitto.nix
./services/networking/miredo.nix
./services/networking/mstpd.nix ./services/networking/mstpd.nix
./services/networking/murmur.nix ./services/networking/murmur.nix
./services/networking/namecoind.nix ./services/networking/namecoind.nix
@ -632,4 +644,5 @@
./virtualisation/xen-dom0.nix ./virtualisation/xen-dom0.nix
./virtualisation/xe-guest-utilities.nix ./virtualisation/xe-guest-utilities.nix
./virtualisation/openstack/keystone.nix ./virtualisation/openstack/keystone.nix
./virtualisation/openstack/glance.nix
] ]

View File

@ -45,7 +45,7 @@
]; ];
# Include support for various filesystems. # Include support for various filesystems.
boot.supportedFilesystems = [ "btrfs" "reiserfs" "vfat" "f2fs" "xfs" "zfs" "ntfs" "cifs" ]; boot.supportedFilesystems = [ "btrfs" "reiserfs" "vfat" "f2fs" "xfs" "ntfs" "cifs" ];
# Configure host id for ZFS to work # Configure host id for ZFS to work
networking.hostId = lib.mkDefault "8425e349"; networking.hostId = lib.mkDefault "8425e349";

View File

@ -70,5 +70,12 @@ with lib;
# the initrd builder. # the initrd builder.
system.extraDependencies = [ pkgs.stdenv pkgs.busybox pkgs.perlPackages.ArchiveCpio ]; system.extraDependencies = [ pkgs.stdenv pkgs.busybox pkgs.perlPackages.ArchiveCpio ];
# Show all debug messages from the kernel but don't log refused packets
# because we have the firewall enabled. This makes installs from the
# console less cumbersome if the machine has a public IP.
boot.consoleLogLevel = mkDefault 7;
networking.firewall.logRefusedConnections = mkDefault false;
environment.systemPackages = [ pkgs.vim ];
}; };
} }

View File

@ -0,0 +1,85 @@
{ config, lib, ... }:
with lib;
let
cfg = config.programs.chromium;
defaultProfile = filterAttrs (k: v: v != null) {
HomepageLocation = cfg.homepageLocation;
DefaultSearchProviderSearchURL = cfg.defaultSearchProviderSearchURL;
DefaultSearchProviderSuggestURL = cfg.defaultSearchProviderSuggestURL;
ExtensionInstallForcelist = map (extension:
"${extension};https://clients2.google.com/service/update2/crx"
) cfg.extensions;
};
in
{
###### interface
options = {
programs.chromium = {
enable = mkEnableOption "<command>chromium</command> policies";
extensions = mkOption {
type = types.listOf types.str;
description = ''
List of chromium extensions to install.
For list of plugins ids see id in url of extensions on
<link xlink:href="https://chrome.google.com/webstore/category/extensions">chrome web store</link>
page.
'';
default = [];
example = literalExample ''
[
"chlffgpmiacpedhhbkiomidkjlcfhogd" # pushbullet
"mbniclmhobmnbdlbpiphghaielnnpgdp" # lightshot
"gcbommkclmclpchllfjekcdonpmejbdp" # https everywhere
]
'';
};
homepageLocation = mkOption {
type = types.nullOr types.str;
description = "Chromium default homepage";
default = null;
example = "https://nixos.org";
};
defaultSearchProviderSearchURL = mkOption {
type = types.nullOr types.str;
description = "Chromium default search provider url.";
default = null;
example =
"https://encrypted.google.com/search?q={searchTerms}&{google:RLZ}{google:originalQueryForSuggestion}{google:assistedQueryStats}{google:searchFieldtrialParameter}{google:
searchClient}{google:sourceId}{google:instantExtendedEnabledParameter}ie={inputEncoding}";
};
defaultSearchProviderSuggestURL = mkOption {
type = types.nullOr types.str;
description = "Chromium default search provider url for suggestions.";
default = null;
example =
"https://encrypted.google.com/complete/search?output=chrome&q={searchTerms}";
};
extraOpts = mkOption {
type = types.attrs;
description = ''
Extra chromium policy options, see
<link xlink:href="https://www.chromium.org/administrators/policy-list-3">https://www.chromium.org/administrators/policy-list-3</link>
for a list of avalible options
'';
default = {};
};
};
};
###### implementation
config = lib.mkIf cfg.enable {
environment.etc."chromium/policies/managed/default.json".text = builtins.toJSON defaultProfile;
environment.etc."chromium/policies/managed/extra.json".text = builtins.toJSON cfg.extraOpts;
};
}

View File

@ -0,0 +1,31 @@
{ config, lib, pkgs, ... }:
with lib;
{
meta.maintainers = [ maintainers.league ];
###### interface
options = {
programs.gphoto2 = {
enable = mkOption {
default = false;
example = true;
type = types.bool;
description = ''
Whether to configure system to use gphoto2.
To grant digital camera access to a user, the user must
be part of the camera group:
<code>users.extraUsers.alice.extraGroups = ["camera"];</code>
'';
};
};
};
###### implementation
config = mkIf config.programs.gphoto2.enable {
services.udev.packages = [ pkgs.libgphoto2 ];
environment.systemPackages = [ pkgs.gphoto2 ];
users.extraGroups.camera = {};
};
}

View File

@ -1,4 +1,4 @@
{ config, lib, ... }: { config, lib, pkgs, ... }:
let let
cfg = config.programs.nano; cfg = config.programs.nano;
@ -20,16 +20,22 @@ in
example = '' example = ''
set nowrap set nowrap
set tabstospaces set tabstospaces
set tabsize 4 set tabsize 2
''; '';
}; };
syntaxHighlight = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Whether to enable syntax highlight for various languages.";
};
}; };
}; };
###### implementation ###### implementation
config = lib.mkIf (cfg.nanorc != "") { config = lib.mkIf (cfg.nanorc != "") {
environment.etc."nanorc".text = cfg.nanorc; environment.etc."nanorc".text = lib.concatStrings [ cfg.nanorc
(lib.optionalString cfg.syntaxHighlight ''include "${pkgs.nano}/share/nano/*.nanorc"'') ];
}; };
} }

View File

@ -92,6 +92,13 @@ in
type = types.bool; type = types.bool;
}; };
enableAutosuggestions = mkOption {
default = false;
description = ''
Enable zsh-autosuggestions
'';
};
}; };
}; };
@ -116,11 +123,6 @@ in
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)
@ -132,6 +134,16 @@ in
"source ${pkgs.zsh-syntax-highlighting}/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" "source ${pkgs.zsh-syntax-highlighting}/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh"
} }
${optionalString (cfg.enableAutosuggestions)
"source ${pkgs.zsh-autosuggestions}/share/zsh-autosuggestions/zsh-autosuggestions.zsh"
}
${zshAliases}
${cfg.promptInit}
${cfge.interactiveShellInit}
HELPDIR="${pkgs.zsh}/share/zsh/$ZSH_VERSION/help" HELPDIR="${pkgs.zsh}/share/zsh/$ZSH_VERSION/help"
''; '';

View File

@ -150,6 +150,23 @@ with lib;
# tarsnap # tarsnap
(mkRemovedOptionModule [ "services" "tarsnap" "cachedir" ] "Use services.tarsnap.archives.<name>.cachedir") (mkRemovedOptionModule [ "services" "tarsnap" "cachedir" ] "Use services.tarsnap.archives.<name>.cachedir")
# alsa
(mkRenamedOptionModule [ "sound" "enableMediaKeys" ] [ "sound" "mediaKeys" "enable" ])
# postgrey
(mkMergedOptionModule [ [ "services" "postgrey" "inetAddr" ] [ "services" "postgrey" "inetPort" ] ] [ "services" "postgrey" "socket" ] (config: let
value = p: getAttrFromPath p config;
inetAddr = [ "services" "postgrey" "inetAddr" ];
inetPort = [ "services" "postgrey" "inetPort" ];
in
if value inetAddr == null
then { path = "/var/run/postgrey.sock"; }
else { addr = value inetAddr; port = value inetPort; }
))
# dhcpd
(mkRenamedOptionModule [ "services" "dhcpd" ] [ "services" "dhcpd4" ])
# Options that are obsolete and have no replacement. # Options that are obsolete and have no replacement.
(mkRemovedOptionModule [ "boot" "initrd" "luks" "enable" ] "") (mkRemovedOptionModule [ "boot" "initrd" "luks" "enable" ] "")
(mkRemovedOptionModule [ "programs" "bash" "enable" ] "") (mkRemovedOptionModule [ "programs" "bash" "enable" ] "")

View File

@ -67,52 +67,30 @@ options for the <literal>security.acme</literal> module.</para>
</section> </section>
<section><title>Using ACME certificates in Nginx</title> <section><title>Using ACME certificates in Nginx</title>
<para>In practice ACME is mostly used for retrieval and renewal of <para>NixOS supports fetching ACME certificates for you by setting
certificates that will be used in a webserver like Nginx. A configuration for <literal>enableACME = true;</literal> in a virtualHost config. We
Nginx that uses the certificates from ACME for first create self-signed placeholder certificates in place of the
<literal>foo.example.com</literal> will look similar to: real ACME certs. The placeholder certs are overwritten when the ACME
certs arrive. For <literal>foo.example.com</literal> the config would
look like.
</para> </para>
<programlisting> <programlisting>
security.acme.certs."foo.example.com" = { services.nginx = {
webroot = config.security.acme.directory + "/acme-challenge"; enable = true;
email = "foo@example.com"; virtualHosts = {
user = "nginx"; "foo.example.com" = {
group = "nginx"; forceSSL = true;
postRun = "systemctl restart nginx.service"; enableACME = true;
locations."/" = {
root = "/var/www";
};
};
}; };
services.nginx.httpConfig = ''
server {
server_name foo.example.com;
listen 80;
listen [::]:80;
location /.well-known/acme-challenge {
root /var/www/challenges;
} }
location / {
return 301 https://$host$request_uri;
}
}
server {
server_name foo.example.com;
listen 443 ssl;
ssl_certificate ${config.security.acme.directory}/foo.example.com/fullchain.pem;
ssl_certificate_key ${config.security.acme.directory}/foo.example.com/key.pem;
root /var/www/foo.example.com/;
}
'';
</programlisting> </programlisting>
<para>Now Nginx will try to use the certificates that will be retrieved by ACME. <para>At the moment you still have to restart Nginx after the ACME
ACME needs Nginx (or any other webserver) to function and Nginx needs certs arrive.</para>
the certificates to actually start. For this reason the ACME module
automatically generates self-signed certificates that will be used by Nginx to
start. After that Nginx is used by ACME to retrieve the actual ACME
certificates. <literal>security.acme.preliminarySelfsigned</literal> can be
used to control whether to generate the self-signed certificates.
</para>
</section> </section>
</chapter> </chapter>

View File

@ -18,22 +18,30 @@ in
default = []; default = [];
description = "List of files containing AppArmor profiles."; description = "List of files containing AppArmor profiles.";
}; };
packages = mkOption {
type = types.listOf types.package;
default = [];
description = "List of packages to be added to apparmor's include path";
};
}; };
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
environment.systemPackages = [ pkgs.apparmor-utils ]; environment.systemPackages = [ pkgs.apparmor-utils ];
systemd.services.apparmor = { systemd.services.apparmor = let
paths = concatMapStrings (s: " -I ${s}/etc/apparmor.d")
([ pkgs.apparmor-profiles ] ++ cfg.packages);
in {
wantedBy = [ "local-fs.target" ]; wantedBy = [ "local-fs.target" ];
serviceConfig = { serviceConfig = {
Type = "oneshot"; Type = "oneshot";
RemainAfterExit = "yes"; RemainAfterExit = "yes";
ExecStart = concatMapStrings (p: ExecStart = map (p:
''${pkgs.apparmor-parser}/bin/apparmor_parser -rKv -I ${pkgs.apparmor-profiles}/etc/apparmor.d "${p}" ; '' ''${pkgs.apparmor-parser}/bin/apparmor_parser -rKv ${paths} "${p}"''
) cfg.profiles; ) cfg.profiles;
ExecStop = concatMapStrings (p: ExecStop = map (p:
''${pkgs.apparmor-parser}/bin/apparmor_parser -Rv "${p}" ; '' ''${pkgs.apparmor-parser}/bin/apparmor_parser -Rv "${p}"''
) cfg.profiles; ) cfg.profiles;
}; };
}; };

View File

@ -233,6 +233,8 @@ let
account sufficient pam_unix.so account sufficient pam_unix.so
${optionalString use_ldap ${optionalString use_ldap
"account sufficient ${pam_ldap}/lib/security/pam_ldap.so"} "account sufficient ${pam_ldap}/lib/security/pam_ldap.so"}
${optionalString config.services.sssd.enable
"account sufficient ${pkgs.sssd}/lib/security/pam_sss.so"}
${optionalString config.krb5.enable ${optionalString config.krb5.enable
"account sufficient ${pam_krb5}/lib/security/pam_krb5.so"} "account sufficient ${pam_krb5}/lib/security/pam_krb5.so"}
@ -273,6 +275,8 @@ let
"auth sufficient ${pkgs.oathToolkit}/lib/security/pam_oath.so window=${toString oath.window} usersfile=${toString oath.usersFile} digits=${toString oath.digits}"} "auth sufficient ${pkgs.oathToolkit}/lib/security/pam_oath.so window=${toString oath.window} usersfile=${toString oath.usersFile} digits=${toString oath.digits}"}
${optionalString use_ldap ${optionalString use_ldap
"auth sufficient ${pam_ldap}/lib/security/pam_ldap.so use_first_pass"} "auth sufficient ${pam_ldap}/lib/security/pam_ldap.so use_first_pass"}
${optionalString config.services.sssd.enable
"auth sufficient ${pkgs.sssd}/lib/security/pam_sss.so use_first_pass"}
${optionalString config.krb5.enable '' ${optionalString config.krb5.enable ''
auth [default=ignore success=1 service_err=reset] ${pam_krb5}/lib/security/pam_krb5.so use_first_pass auth [default=ignore success=1 service_err=reset] ${pam_krb5}/lib/security/pam_krb5.so use_first_pass
auth [default=die success=done] ${pam_ccreds}/lib/security/pam_ccreds.so action=validate use_first_pass auth [default=die success=done] ${pam_ccreds}/lib/security/pam_ccreds.so action=validate use_first_pass
@ -288,6 +292,8 @@ let
"password optional ${pkgs.pam_mount}/lib/security/pam_mount.so"} "password optional ${pkgs.pam_mount}/lib/security/pam_mount.so"}
${optionalString use_ldap ${optionalString use_ldap
"password sufficient ${pam_ldap}/lib/security/pam_ldap.so"} "password sufficient ${pam_ldap}/lib/security/pam_ldap.so"}
${optionalString config.services.sssd.enable
"password sufficient ${pkgs.sssd}/lib/security/pam_sss.so use_authtok"}
${optionalString config.krb5.enable ${optionalString config.krb5.enable
"password sufficient ${pam_krb5}/lib/security/pam_krb5.so use_first_pass"} "password sufficient ${pam_krb5}/lib/security/pam_krb5.so use_first_pass"}
${optionalString config.services.samba.syncPasswordsByPam ${optionalString config.services.samba.syncPasswordsByPam
@ -303,13 +309,15 @@ let
if config.boot.isContainer then "optional" else "required" if config.boot.isContainer then "optional" else "required"
} pam_loginuid.so"} } pam_loginuid.so"}
${optionalString cfg.makeHomeDir ${optionalString cfg.makeHomeDir
"session required ${pkgs.pam}/lib/security/pam_mkhomedir.so silent skel=/etc/skel umask=0022"} "session required ${pkgs.pam}/lib/security/pam_mkhomedir.so silent skel=${config.security.pam.makeHomeDir.skelDirectory} umask=0022"}
${optionalString cfg.updateWtmp ${optionalString cfg.updateWtmp
"session required ${pkgs.pam}/lib/security/pam_lastlog.so silent"} "session required ${pkgs.pam}/lib/security/pam_lastlog.so silent"}
${optionalString config.security.pam.enableEcryptfs ${optionalString config.security.pam.enableEcryptfs
"session optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so"} "session optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so"}
${optionalString use_ldap ${optionalString use_ldap
"session optional ${pam_ldap}/lib/security/pam_ldap.so"} "session optional ${pam_ldap}/lib/security/pam_ldap.so"}
${optionalString config.services.sssd.enable
"session optional ${pkgs.sssd}/lib/security/pam_sss.so"}
${optionalString config.krb5.enable ${optionalString config.krb5.enable
"session optional ${pam_krb5}/lib/security/pam_krb5.so"} "session optional ${pam_krb5}/lib/security/pam_krb5.so"}
${optionalString cfg.otpwAuth ${optionalString cfg.otpwAuth
@ -397,6 +405,16 @@ in
''; '';
}; };
security.pam.makeHomeDir.skelDirectory = mkOption {
type = types.str;
default = "/var/empty";
example = "/etc/skel";
description = ''
Path to skeleton directory whose contents are copied to home
directories newly created by <literal>pam_mkhomedir</literal>.
'';
};
security.pam.enableSSHAgentAuth = mkOption { security.pam.enableSSHAgentAuth = mkOption {
default = false; default = false;
description = description =
@ -447,6 +465,7 @@ in
# Include the PAM modules in the system path mostly for the manpages. # Include the PAM modules in the system path mostly for the manpages.
[ pkgs.pam ] [ pkgs.pam ]
++ optional config.users.ldap.enable pam_ldap ++ optional config.users.ldap.enable pam_ldap
++ optional config.services.sssd.enable pkgs.sssd
++ optionals config.krb5.enable [pam_krb5 pam_ccreds] ++ optionals config.krb5.enable [pam_krb5 pam_ccreds]
++ optionals config.security.pam.enableOTPW [ pkgs.otpw ] ++ optionals config.security.pam.enableOTPW [ pkgs.otpw ]
++ optionals config.security.pam.oath.enable [ pkgs.oathToolkit ] ++ optionals config.security.pam.oath.enable [ pkgs.oathToolkit ]

View File

@ -33,16 +33,6 @@ in
''; '';
}; };
enableMediaKeys = mkOption {
type = types.bool;
default = false;
description = ''
Whether to enable volume and capture control with keyboard media keys.
Enabling this will turn on <option>services.actkbd</option>.
'';
};
extraConfig = mkOption { extraConfig = mkOption {
type = types.lines; type = types.lines;
default = ""; default = "";
@ -54,6 +44,31 @@ in
''; '';
}; };
mediaKeys = {
enable = mkOption {
type = types.bool;
default = false;
description = ''
Whether to enable volume and capture control with keyboard media keys.
Enabling this will turn on <option>services.actkbd</option>.
'';
};
volumeStep = mkOption {
type = types.string;
default = "1";
example = "1%";
description = ''
The value by which to increment/decrement volume on media keys.
See amixer(1) for allowed values.
'';
};
};
}; };
}; };
@ -90,17 +105,17 @@ in
}; };
}; };
services.actkbd = mkIf config.sound.enableMediaKeys { services.actkbd = mkIf config.sound.mediaKeys.enable {
enable = true; enable = true;
bindings = [ bindings = [
# "Mute" media key # "Mute" media key
{ keys = [ 113 ]; events = [ "key" ]; command = "${alsaUtils}/bin/amixer -q set Master toggle"; } { keys = [ 113 ]; events = [ "key" ]; command = "${alsaUtils}/bin/amixer -q set Master toggle"; }
# "Lower Volume" media key # "Lower Volume" media key
{ keys = [ 114 ]; events = [ "key" "rep" ]; command = "${alsaUtils}/bin/amixer -q set Master 1- unmute"; } { keys = [ 114 ]; events = [ "key" "rep" ]; command = "${alsaUtils}/bin/amixer -q set Master ${config.sound.mediaKeys.volumeStep}- unmute"; }
# "Raise Volume" media key # "Raise Volume" media key
{ keys = [ 115 ]; events = [ "key" "rep" ]; command = "${alsaUtils}/bin/amixer -q set Master 1+ unmute"; } { keys = [ 115 ]; events = [ "key" "rep" ]; command = "${alsaUtils}/bin/amixer -q set Master ${config.sound.mediaKeys.volumeStep}+ unmute"; }
# "Mic Mute" media key # "Mic Mute" media key
{ keys = [ 190 ]; events = [ "key" ]; command = "${alsaUtils}/bin/amixer -q set Capture toggle"; } { keys = [ 190 ]; events = [ "key" ]; command = "${alsaUtils}/bin/amixer -q set Capture toggle"; }

View File

@ -83,11 +83,11 @@ in {
listenAddress = mkOption { listenAddress = mkOption {
type = types.str; type = types.str;
default = "any"; default = "127.0.0.1";
example = "any";
description = '' description = ''
This setting sets the address for the daemon to listen on. Careful attention The address for the daemon to listen on.
should be paid if this is assigned to anything other then the default, any. Use <literal>any</literal> to listen on all addresses.
This setting can deny access to control of the daemon.
''; '';
}; };

View File

@ -737,6 +737,8 @@ in {
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
after = [ "kube-apiserver.service" ]; after = [ "kube-apiserver.service" ];
serviceConfig = { serviceConfig = {
RestartSec = "30s";
Restart = "on-failure";
ExecStart = ''${cfg.package}/bin/kube-controller-manager \ ExecStart = ''${cfg.package}/bin/kube-controller-manager \
--address=${cfg.controllerManager.address} \ --address=${cfg.controllerManager.address} \
--port=${toString cfg.controllerManager.port} \ --port=${toString cfg.controllerManager.port} \

View File

@ -2,7 +2,9 @@
with lib; with lib;
{ let cfg = config.services.hardware.pommed;
defaultConf = "${pkgs.pommed_light}/etc/pommed.conf.mactel";
in {
options = { options = {
@ -12,37 +14,37 @@ with lib;
type = types.bool; type = types.bool;
default = false; default = false;
description = '' description = ''
Whether to use the pommed tool to handle Apple laptop keyboard hotkeys. Whether to use the pommed tool to handle Apple laptop
keyboard hotkeys.
''; '';
}; };
configFile = mkOption { configFile = mkOption {
type = types.path; type = types.nullOr types.path;
default = null;
description = '' description = ''
The path to the <filename>pommed.conf</filename> file. The path to the <filename>pommed.conf</filename> file. Leave
to null to use the default config file
(<filename>/etc/pommed.conf.mactel</filename>). See the
files <filename>/etc/pommed.conf.mactel</filename> and
<filename>/etc/pommed.conf.pmac</filename> for examples to
build on.
''; '';
}; };
}; };
}; };
config = mkIf config.services.hardware.pommed.enable { config = mkIf cfg.enable {
environment.systemPackages = [ pkgs.polkit ]; environment.systemPackages = [ pkgs.polkit pkgs.pommed_light ];
environment.etc."pommed.conf".source = config.services.hardware.pommed.configFile; environment.etc."pommed.conf".source =
if cfg.configFile == null then defaultConf else cfg.configFile;
services.hardware.pommed.configFile = "${pkgs.pommed}/etc/pommed.conf";
services.dbus.packages = [ pkgs.pommed ];
systemd.services.pommed = { systemd.services.pommed = {
description = "Pommed hotkey management"; description = "Pommed Apple Hotkeys Daemon";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
after = [ "dbus.service" ]; script = "${pkgs.pommed_light}/bin/pommed -f";
postStop = "rm -f /var/run/pommed.pid";
script = "${pkgs.pommed}/bin/pommed";
serviceConfig.Type = "forking";
path = [ pkgs.eject ];
}; };
}; };
} }

View File

@ -143,7 +143,10 @@ let
done done
echo "Generating hwdb database..." echo "Generating hwdb database..."
${udev}/bin/udevadm hwdb --update --root=$(pwd) # hwdb --update doesn't return error code even on errors!
res="$(${udev}/bin/udevadm hwdb --update --root=$(pwd) 2>&1)"
echo "$res"
[ -z "$(echo "$res" | egrep '^Error')" ]
mv etc/udev/hwdb.bin $out mv etc/udev/hwdb.bin $out
''; '';

View File

@ -241,6 +241,9 @@ in
RuntimeDirectory = [ "dovecot2" ]; RuntimeDirectory = [ "dovecot2" ];
}; };
# When copying sieve scripts preserve the original time stamp
# (should be 0) so that the compiled sieve script is newer than
# the source file and Dovecot won't try to compile it.
preStart = '' preStart = ''
rm -rf ${stateDir}/sieve rm -rf ${stateDir}/sieve
'' + optionalString (cfg.sieveScripts != {}) '' '' + optionalString (cfg.sieveScripts != {}) ''
@ -248,9 +251,9 @@ in
${concatStringsSep "\n" (mapAttrsToList (to: from: '' ${concatStringsSep "\n" (mapAttrsToList (to: from: ''
if [ -d '${from}' ]; then if [ -d '${from}' ]; then
mkdir '${stateDir}/sieve/${to}' mkdir '${stateDir}/sieve/${to}'
cp "${from}/"*.sieve '${stateDir}/sieve/${to}' cp -p "${from}/"*.sieve '${stateDir}/sieve/${to}'
else else
cp '${from}' '${stateDir}/sieve/${to}' cp -p '${from}' '${stateDir}/sieve/${to}'
fi fi
${pkgs.dovecot_pigeonhole}/bin/sievec '${stateDir}/sieve/${to}' ${pkgs.dovecot_pigeonhole}/bin/sievec '${stateDir}/sieve/${to}'
'') cfg.sieveScripts)} '') cfg.sieveScripts)}

View File

@ -4,6 +4,43 @@ with lib; let
cfg = config.services.postgrey; cfg = config.services.postgrey;
natural = with types; addCheck int (x: x >= 0);
natural' = with types; addCheck int (x: x > 0);
socket = with types; addCheck (either (submodule unixSocket) (submodule inetSocket)) (x: x ? "path" || x ? "port");
inetSocket = with types; {
options = {
addr = mkOption {
type = nullOr string;
default = null;
example = "127.0.0.1";
description = "The address to bind to. Localhost if null";
};
port = mkOption {
type = natural';
default = 10030;
description = "Tcp port to bind to";
};
};
};
unixSocket = with types; {
options = {
path = mkOption {
type = path;
default = "/var/run/postgrey.sock";
description = "Path of the unix socket";
};
mode = mkOption {
type = string;
default = "0777";
description = "Mode of the unix socket";
};
};
};
in { in {
options = { options = {
@ -13,21 +50,83 @@ in {
default = false; default = false;
description = "Whether to run the Postgrey daemon"; description = "Whether to run the Postgrey daemon";
}; };
inetAddr = mkOption { socket = mkOption {
type = nullOr string; type = socket;
default = null; default = {
example = "127.0.0.1"; path = "/var/run/postgrey.sock";
description = "The inet address to bind to. If none given, bind to /var/run/postgrey.sock"; mode = "0777";
}; };
inetPort = mkOption { example = {
type = int; addr = "127.0.0.1";
default = 10030; port = 10030;
description = "The tcp port to bind to"; };
description = "Socket to bind to";
}; };
greylistText = mkOption { greylistText = mkOption {
type = string; type = string;
default = "Greylisted for %%s seconds"; default = "Greylisted for %%s seconds";
description = "Response status text for greylisted messages"; description = "Response status text for greylisted messages; use %%s for seconds left until greylisting is over and %%r for mail domain of recipient";
};
greylistAction = mkOption {
type = string;
default = "DEFER_IF_PERMIT";
description = "Response status for greylisted messages (see access(5))";
};
greylistHeader = mkOption {
type = string;
default = "X-Greylist: delayed %%t seconds by postgrey-%%v at %%h; %%d";
description = "Prepend header to greylisted mails; use %%t for seconds delayed due to greylisting, %%v for the version of postgrey, %%d for the date, and %%h for the host";
};
delay = mkOption {
type = natural;
default = 300;
description = "Greylist for N seconds";
};
maxAge = mkOption {
type = natural;
default = 35;
description = "Delete entries from whitelist if they haven't been seen for N days";
};
retryWindow = mkOption {
type = either string natural;
default = 2;
example = "12h";
description = "Allow N days for the first retry. Use string with appended 'h' to specify time in hours";
};
lookupBySubnet = mkOption {
type = bool;
default = true;
description = "Strip the last N bits from IP addresses, determined by IPv4CIDR and IPv6CIDR";
};
IPv4CIDR = mkOption {
type = natural;
default = 24;
description = "Strip N bits from IPv4 addresses if lookupBySubnet is true";
};
IPv6CIDR = mkOption {
type = natural;
default = 64;
description = "Strip N bits from IPv6 addresses if lookupBySubnet is true";
};
privacy = mkOption {
type = bool;
default = true;
description = "Store data using one-way hash functions (SHA1)";
};
autoWhitelist = mkOption {
type = nullOr natural';
default = 5;
description = "Whitelist clients after successful delivery of N messages";
};
whitelistClients = mkOption {
type = listOf path;
default = [];
description = "Client address whitelist files (see postgrey(8))";
};
whitelistRecipients = mkOption {
type = listOf path;
default = [];
description = "Recipient address whitelist files (see postgrey(8))";
}; };
}; };
}; };
@ -52,10 +151,10 @@ in {
}; };
systemd.services.postgrey = let systemd.services.postgrey = let
bind-flag = if isNull cfg.inetAddr then bind-flag = if cfg.socket ? "path" then
"--unix=/var/run/postgrey.sock" ''--unix=${cfg.socket.path} --socketmode=${cfg.socket.mode}''
else else
"--inet=${cfg.inetAddr}:${cfg.inetPort}"; ''--inet=${optionalString (cfg.socket.addr != null) (cfg.socket.addr + ":")}${toString cfg.socket.port}'';
in { in {
description = "Postfix Greylisting Service"; description = "Postfix Greylisting Service";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
@ -67,7 +166,23 @@ in {
''; '';
serviceConfig = { serviceConfig = {
Type = "simple"; Type = "simple";
ExecStart = ''${pkgs.postgrey}/bin/postgrey ${bind-flag} --pidfile=/var/run/postgrey.pid --group=postgrey --user=postgrey --dbdir=/var/postgrey --greylist-text="${cfg.greylistText}"''; ExecStart = ''${pkgs.postgrey}/bin/postgrey \
${bind-flag} \
--group=postgrey --user=postgrey \
--dbdir=/var/postgrey \
--delay=${toString cfg.delay} \
--max-age=${toString cfg.maxAge} \
--retry-window=${toString cfg.retryWindow} \
${if cfg.lookupBySubnet then "--lookup-by-subnet" else "--lookup-by-host"} \
--ipv4cidr=${toString cfg.IPv4CIDR} --ipv6cidr=${toString cfg.IPv6CIDR} \
${optionalString cfg.privacy "--privacy"} \
--auto-whitelist-clients=${toString (if cfg.autoWhitelist == null then 0 else cfg.autoWhitelist)} \
--greylist-action=${cfg.greylistAction} \
--greylist-text="${cfg.greylistText}" \
--x-greylist-header="${cfg.greylistHeader}" \
${concatMapStringsSep " " (x: "--whitelist-clients=" + x) cfg.whitelistClients} \
${concatMapStringsSep " " (x: "--whitelist-recipients=" + x) cfg.whitelistRecipients}
'';
Restart = "always"; Restart = "always";
RestartSec = 5; RestartSec = 5;
TimeoutSec = 10; TimeoutSec = 10;

View File

@ -0,0 +1,50 @@
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.services.couchpotato;
in
{
options = {
services.couchpotato = {
enable = mkEnableOption "CouchPotato Server";
};
};
config = mkIf cfg.enable {
systemd.services.couchpotato = {
description = "CouchPotato Server";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
preStart = ''
mkdir -p /var/lib/couchpotato
chown -R couchpotato:couchpotato /var/lib/couchpotato
'';
serviceConfig = {
Type = "simple";
User = "couchpotato";
Group = "couchpotato";
PermissionsStartOnly = "true";
ExecStart = "${pkgs.couchpotato}/bin/couchpotato";
Restart = "on-failure";
};
};
users.extraUsers = singleton
{ name = "couchpotato";
group = "couchpotato";
home = "/var/lib/couchpotato/";
description = "CouchPotato daemon user";
uid = config.ids.uids.couchpotato;
};
users.extraGroups = singleton
{ name = "couchpotato";
gid = config.ids.gids.couchpotato;
};
};
}

View File

@ -105,7 +105,9 @@ in
If set, Nix will perform builds in a sandboxed environment that it If set, Nix will perform builds in a sandboxed environment that it
will set up automatically for each build. This prevents will set up automatically for each build. This prevents
impurities in builds by disallowing access to dependencies impurities in builds by disallowing access to dependencies
outside of the Nix store. outside of the Nix store. This isn't enabled by default for
performance. It doesn't affect derivation hashes, so changing
this option will not trigger a rebuild of packages.
"; ";
}; };

View File

@ -0,0 +1,36 @@
server-user nscd
threads 1
paranoia no
debug-level 0
enable-cache passwd yes
positive-time-to-live passwd 0
negative-time-to-live passwd 0
suggested-size passwd 211
check-files passwd yes
persistent passwd no
shared passwd yes
enable-cache group yes
positive-time-to-live group 0
negative-time-to-live group 0
suggested-size group 211
check-files group yes
persistent group no
shared group yes
enable-cache hosts yes
positive-time-to-live hosts 600
negative-time-to-live hosts 5
suggested-size hosts 211
check-files hosts yes
persistent hosts no
shared hosts yes
enable-cache services yes
positive-time-to-live services 0
negative-time-to-live services 0
suggested-size services 211
check-files services yes
persistent services no
shared services yes

View File

@ -19,6 +19,14 @@ in
description = "The directory where Plex stores its data files."; description = "The directory where Plex stores its data files.";
}; };
openFirewall = mkOption {
type = types.bool;
default = false;
description = ''
Open ports in the firewall for the media server
'';
};
user = mkOption { user = mkOption {
type = types.str; type = types.str;
default = "plex"; default = "plex";
@ -127,7 +135,7 @@ in
User = cfg.user; User = cfg.user;
Group = cfg.group; Group = cfg.group;
PermissionsStartOnly = "true"; PermissionsStartOnly = "true";
ExecStart = "/bin/sh -c '${cfg.package}/usr/lib/plexmediaserver/Plex\\ Media\\ Server'"; ExecStart = "/bin/sh -c ${cfg.package}/usr/lib/plexmediaserver/Plex\\ Media\\ Server";
Restart = "on-failure"; Restart = "on-failure";
}; };
environment = { environment = {
@ -141,6 +149,11 @@ in
}; };
}; };
networking.firewall = mkIf cfg.openFirewall {
allowedTCPPorts = [ 32400 3005 8324 32469 ];
allowedUDPPorts = [ 1900 5353 32410 32412 32413 32414 ];
};
users.extraUsers = mkIf (cfg.user == "plex") { users.extraUsers = mkIf (cfg.user == "plex") {
plex = { plex = {
group = cfg.group; group = cfg.group;

View File

@ -0,0 +1,97 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.sssd;
nscd = config.services.nscd;
in {
options = {
services.sssd = {
enable = mkEnableOption "the System Security Services Daemon.";
config = mkOption {
type = types.lines;
description = "Contents of <filename>sssd.conf</filename>.";
default = ''
[sssd]
config_file_version = 2
services = nss, pam
domains = shadowutils
[nss]
[pam]
[domain/shadowutils]
id_provider = proxy
proxy_lib_name = files
auth_provider = proxy
proxy_pam_target = sssd-shadowutils
proxy_fast_alias = True
'';
};
sshAuthorizedKeysIntegration = mkOption {
type = types.bool;
default = false;
description = ''
Whether to make sshd look up authorized keys from SSS.
For this to work, the <literal>ssh</literal> SSS service must be enabled in the sssd configuration.
'';
};
};
};
config = mkMerge [
(mkIf cfg.enable {
assertions = singleton {
assertion = nscd.enable;
message = "nscd must be enabled through `services.nscd.enable` for SSSD to work.";
};
systemd.services.sssd = {
description = "System Security Services Daemon";
wantedBy = [ "multi-user.target" ];
before = [ "systemd-user-sessions.service" "nss-user-lookup.target" ];
after = [ "network-online.target" "nscd.service" ];
requires = [ "network-online.target" "nscd.service" ];
wants = [ "nss-user-lookup.target" ];
restartTriggers = [
config.environment.etc."nscd.conf".source
config.environment.etc."sssd/sssd.conf".source
];
script = ''
export LDB_MODULES_PATH+="''${LDB_MODULES_PATH+:}${pkgs.ldb}/modules/ldb:${pkgs.sssd}/modules/ldb"
mkdir -p /var/lib/sss/{pubconf,db,mc,pipes,gpo_cache,secrets} /var/lib/sss/pipes/private /var/lib/sss/pubconf/krb5.include.d
${pkgs.sssd}/bin/sssd -D
'';
serviceConfig = {
Type = "forking";
PIDFile = "/run/sssd.pid";
};
};
environment.etc."sssd/sssd.conf" = {
text = cfg.config;
mode = "0400";
};
system.nssModules = optional cfg.enable pkgs.sssd;
services.nscd.config = builtins.readFile ./nscd-sssd.conf;
services.dbus.packages = [ pkgs.sssd ];
})
(mkIf cfg.sshAuthorizedKeysIntegration {
# Ugly: sshd refuses to start if a store path is given because /nix/store is group-writable.
# So indirect by a symlink.
environment.etc."ssh/authorized_keys_command" = {
mode = "0755";
text = ''
#!/bin/sh
exec ${pkgs.sssd}/bin/sss_ssh_authorizedkeys "$@"
'';
};
services.openssh.extraConfig = ''
AuthorizedKeysCommand /etc/ssh/authorized_keys_command
AuthorizedKeysCommandUser nobody
'';
})];
}

View File

@ -0,0 +1,63 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.arbtt;
in {
options = {
services.arbtt = {
enable = mkOption {
type = types.bool;
default = false;
example = true;
description = ''
Enable the arbtt statistics capture service.
'';
};
package = mkOption {
type = types.package;
default = pkgs.haskellPackages.arbtt;
defaultText = "pkgs.haskellPackages.arbtt";
example = literalExample "pkgs.haskellPackages.arbtt";
description = ''
The package to use for the arbtt binaries.
'';
};
logFile = mkOption {
type = types.str;
default = "%h/.arbtt/capture.log";
example = "/home/username/.arbtt-capture.log";
description = ''
The log file for captured samples.
'';
};
sampleRate = mkOption {
type = types.int;
default = 60;
example = 120;
description = ''
The sampling interval in seconds.
'';
};
};
};
config = mkIf cfg.enable {
systemd.user.services.arbtt = {
description = "arbtt statistics capture service";
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "simple";
ExecStart = "${cfg.package}/bin/arbtt-capture --logfile=${cfg.logFile} --sample-rate=${toString cfg.sampleRate}";
Restart = "always";
};
};
};
meta.maintainers = [ maintainers.michaelpj ];
}

View File

@ -585,7 +585,7 @@ in {
serviceConfig = { serviceConfig = {
ExecStart = '' ExecStart = ''
${pkgs.pythonPackages.graphite_beacon}/bin/graphite-beacon \ ${pkgs.pythonPackages.graphite_beacon}/bin/graphite-beacon \
--config ${pkgs.writeText "graphite-beacon.json" (builtins.toJSON cfg.beacon.config)} --config=${pkgs.writeText "graphite-beacon.json" (builtins.toJSON cfg.beacon.config)}
''; '';
User = "graphite"; User = "graphite";
Group = "graphite"; Group = "graphite";

View File

@ -5,6 +5,10 @@ with lib;
let let
cfg = config.services.prometheus.alertmanager; cfg = config.services.prometheus.alertmanager;
mkConfigFile = pkgs.writeText "alertmanager.yml" (builtins.toJSON cfg.configuration); mkConfigFile = pkgs.writeText "alertmanager.yml" (builtins.toJSON cfg.configuration);
alertmanagerYml =
if cfg.configText != null then
pkgs.writeText "alertmanager.yml" cfg.configText
else mkConfigFile;
in { in {
options = { options = {
services.prometheus.alertmanager = { services.prometheus.alertmanager = {
@ -34,6 +38,17 @@ in {
''; '';
}; };
configText = mkOption {
type = types.nullOr types.lines;
default = null;
description = ''
Alertmanager configuration as YAML text. If non-null, this option
defines the text that is written to alertmanager.yml. If null, the
contents of alertmanager.yml is generated from the structured config
options.
'';
};
logFormat = mkOption { logFormat = mkOption {
type = types.nullOr types.str; type = types.nullOr types.str;
default = null; default = null;
@ -62,8 +77,8 @@ in {
}; };
listenAddress = mkOption { listenAddress = mkOption {
type = types.nullOr types.str; type = types.str;
default = null; default = "";
description = '' description = ''
Address to listen on for the web interface and API. Address to listen on for the web interface and API.
''; '';
@ -96,7 +111,7 @@ in {
after = [ "network.target" ]; after = [ "network.target" ];
script = '' script = ''
${pkgs.prometheus-alertmanager.bin}/bin/alertmanager \ ${pkgs.prometheus-alertmanager.bin}/bin/alertmanager \
-config.file ${mkConfigFile} \ -config.file ${alertmanagerYml} \
-web.listen-address ${cfg.listenAddress}:${toString cfg.port} \ -web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
-log.level ${cfg.logLevel} \ -log.level ${cfg.logLevel} \
${optionalString (cfg.webExternalUrl != null) ''-web.external-url ${cfg.webExternalUrl} \''} ${optionalString (cfg.webExternalUrl != null) ''-web.external-url ${cfg.webExternalUrl} \''}

View File

@ -0,0 +1,67 @@
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.services.prometheus.blackboxExporter;
in {
options = {
services.prometheus.blackboxExporter = {
enable = mkEnableOption "prometheus blackbox exporter";
configFile = mkOption {
type = types.path;
description = ''
Path to configuration file.
'';
};
port = mkOption {
type = types.int;
default = 9115;
description = ''
Port to listen on.
'';
};
extraFlags = mkOption {
type = types.listOf types.str;
default = [];
description = ''
Extra commandline options when launching the blackbox exporter.
'';
};
openFirewall = mkOption {
type = types.bool;
default = false;
description = ''
Open port in firewall for incoming connections.
'';
};
};
};
config = mkIf cfg.enable {
networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.port;
systemd.services.prometheus-blackbox-exporter = {
description = "Prometheus exporter for blackbox probes";
unitConfig.Documentation = "https://github.com/prometheus/blackbox_exporter";
wantedBy = [ "multi-user.target" ];
serviceConfig = {
User = "nobody";
Restart = "always";
PrivateTmp = true;
WorkingDirectory = /tmp;
ExecStart = ''
${pkgs.prometheus-blackbox-exporter}/bin/blackbox_exporter \
-web.listen-address :${toString cfg.port} \
-config.file ${cfg.configFile} \
${concatStringsSep " \\\n " cfg.extraFlags}
'';
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
};
};
};
}

View File

@ -191,6 +191,7 @@ let
}; };
labels = mkOption { labels = mkOption {
type = types.attrsOf types.str; type = types.attrsOf types.str;
default = {};
description = '' description = ''
Labels assigned to all metrics scraped from the targets. Labels assigned to all metrics scraped from the targets.
''; '';

View File

@ -0,0 +1,74 @@
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.services.prometheus.jsonExporter;
in {
options = {
services.prometheus.jsonExporter = {
enable = mkEnableOption "prometheus JSON exporter";
url = mkOption {
type = types.str;
description = ''
URL to scrape JSON from.
'';
};
configFile = mkOption {
type = types.path;
description = ''
Path to configuration file.
'';
};
port = mkOption {
type = types.int;
default = 7979;
description = ''
Port to listen on.
'';
};
extraFlags = mkOption {
type = types.listOf types.str;
default = [];
description = ''
Extra commandline options when launching the JSON exporter.
'';
};
openFirewall = mkOption {
type = types.bool;
default = false;
description = ''
Open port in firewall for incoming connections.
'';
};
};
};
config = mkIf cfg.enable {
networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.port;
systemd.services.prometheus-json-exporter = {
description = "Prometheus exporter for JSON over HTTP";
unitConfig.Documentation = "https://github.com/kawamuray/prometheus-json-exporter";
wantedBy = [ "multi-user.target" ];
serviceConfig = {
User = "nobody";
Restart = "always";
PrivateTmp = true;
WorkingDirectory = /tmp;
ExecStart = ''
${pkgs.prometheus-json-exporter}/bin/prometheus-json-exporter \
--port ${toString cfg.port} \
${cfg.url} ${cfg.configFile} \
${concatStringsSep " \\\n " cfg.extraFlags}
'';
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
};
};
};
}

View File

@ -0,0 +1,78 @@
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.services.prometheus.nginxExporter;
in {
options = {
services.prometheus.nginxExporter = {
enable = mkEnableOption "prometheus nginx exporter";
port = mkOption {
type = types.int;
default = 9113;
description = ''
Port to listen on.
'';
};
listenAddress = mkOption {
type = types.string;
default = "0.0.0.0";
description = ''
Address to listen on.
'';
};
scrapeUri = mkOption {
type = types.string;
default = "http://localhost/nginx_status";
description = ''
Address to access the nginx status page.
Can be enabled with services.nginx.statusPage = true.
'';
};
extraFlags = mkOption {
type = types.listOf types.str;
default = [];
description = ''
Extra commandline options when launching the nginx exporter.
'';
};
openFirewall = mkOption {
type = types.bool;
default = false;
description = ''
Open port in firewall for incoming connections.
'';
};
};
};
config = mkIf cfg.enable {
networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.port;
systemd.services.prometheus-nginx-exporter = {
after = [ "network.target" "nginx.service" ];
description = "Prometheus exporter for nginx metrics";
unitConfig.Documentation = "https://github.com/discordianfish/nginx_exporter";
wantedBy = [ "multi-user.target" ];
serviceConfig = {
User = "nobody";
Restart = "always";
PrivateTmp = true;
WorkingDirectory = /tmp;
ExecStart = ''
${pkgs.prometheus-nginx-exporter}/bin/nginx_exporter \
-nginx.scrape_uri '${cfg.scrapeUri}' \
-telemetry.address ${cfg.listenAddress}:${toString cfg.port} \
${concatStringsSep " \\\n " cfg.extraFlags}
'';
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
};
};
};
}

View File

@ -44,10 +44,20 @@ in {
Extra commandline options when launching the node exporter. Extra commandline options when launching the node exporter.
''; '';
}; };
openFirewall = mkOption {
type = types.bool;
default = false;
description = ''
Open port in firewall for incoming connections.
'';
};
}; };
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.port;
systemd.services.prometheus-node-exporter = { systemd.services.prometheus-node-exporter = {
description = "Prometheus exporter for machine metrics"; description = "Prometheus exporter for machine metrics";
unitConfig.Documentation = "https://github.com/prometheus/node_exporter"; unitConfig.Documentation = "https://github.com/prometheus/node_exporter";

View File

@ -0,0 +1,127 @@
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.services.prometheus.snmpExporter;
mkConfigFile = pkgs.writeText "snmp.yml" (if cfg.configurationPath == null then builtins.toJSON cfg.configuration else builtins.readFile cfg.configurationPath);
in {
options = {
services.prometheus.snmpExporter = {
enable = mkEnableOption "Prometheus snmp exporter";
user = mkOption {
type = types.str;
default = "nobody";
description = ''
User name under which snmp exporter shall be run.
'';
};
group = mkOption {
type = types.str;
default = "nogroup";
description = ''
Group under which snmp exporter shall be run.
'';
};
port = mkOption {
type = types.int;
default = 9116;
description = ''
Port to listen on.
'';
};
listenAddress = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
Address to listen on for web interface and telemetry.
'';
};
configurationPath = mkOption {
type = types.nullOr types.path;
default = null;
description = ''
Path to a snmp exporter configuration file. Mutually exclusive with 'configuration' option.
'';
example = "./snmp.yml";
};
configuration = mkOption {
type = types.nullOr types.attrs;
default = {};
description = ''
Snmp exporter configuration as nix attribute set. Mutually exclusive with 'configurationPath' option.
'';
example = ''
{
"default" = {
"version" = 2;
"auth" = {
"community" = "public";
};
};
};
'';
};
logFormat = mkOption {
type = types.str;
default = "logger:stderr";
description = ''
Set the log target and format.
'';
};
logLevel = mkOption {
type = types.enum ["debug" "info" "warn" "error" "fatal"];
default = "info";
description = ''
Only log messages with the given severity or above.
'';
};
openFirewall = mkOption {
type = types.bool;
default = false;
description = ''
Open port in firewall for incoming connections.
'';
};
};
};
config = mkIf cfg.enable {
networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.port;
assertions = singleton
{
assertion = (cfg.configurationPath == null) != (cfg.configuration == null);
message = "Please ensure you have either 'configuration' or 'configurationPath' set!";
};
systemd.services.prometheus-snmp-exporter = {
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
script = ''
${pkgs.prometheus-snmp-exporter.bin}/bin/snmp_exporter \
-config.file ${mkConfigFile} \
-log.format ${cfg.logFormat} \
-log.level ${cfg.logLevel} \
-web.listen-address ${optionalString (cfg.listenAddress != null) cfg.listenAddress}:${toString cfg.port}
'';
serviceConfig = {
User = cfg.user;
Group = cfg.group;
Restart = "always";
PrivateTmp = true;
WorkingDirectory = "/tmp";
};
};
};
}

View File

@ -0,0 +1,61 @@
{ config, pkgs, lib, ... }:
# Shamelessly cribbed from nginx-exporter.nix. ~ C.
with lib;
let
cfg = config.services.prometheus.varnishExporter;
in {
options = {
services.prometheus.varnishExporter = {
enable = mkEnableOption "prometheus Varnish exporter";
port = mkOption {
type = types.int;
default = 9131;
description = ''
Port to listen on.
'';
};
extraFlags = mkOption {
type = types.listOf types.str;
default = [];
description = ''
Extra commandline options when launching the Varnish exporter.
'';
};
openFirewall = mkOption {
type = types.bool;
default = false;
description = ''
Open port in firewall for incoming connections.
'';
};
};
};
config = mkIf cfg.enable {
networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.port;
systemd.services.prometheus-varnish-exporter = {
description = "Prometheus exporter for Varnish metrics";
unitConfig.Documentation = "https://github.com/jonnenauha/prometheus_varnish_exporter";
wantedBy = [ "multi-user.target" ];
path = [ pkgs.varnish ];
script = ''
exec ${pkgs.prometheus-varnish-exporter}/bin/prometheus_varnish_exporter \
-web.listen-address :${toString cfg.port} \
${concatStringsSep " \\\n " cfg.extraFlags}
'';
serviceConfig = {
User = "nobody";
Restart = "always";
PrivateTmp = true;
WorkingDirectory = /tmp;
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
};
};
};
}

View File

@ -67,6 +67,14 @@ in
''; '';
}; };
emptyRepo = mkOption {
type = types.bool;
default = false;
description = ''
If set to true, the repo won't be initialized with help files
'';
};
extraFlags = mkOption { extraFlags = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
description = "Extra flags passed to the IPFS daemon"; description = "Extra flags passed to the IPFS daemon";
@ -103,15 +111,16 @@ in
after = [ "network.target" "local-fs.target" ]; after = [ "network.target" "local-fs.target" ];
path = [ pkgs.ipfs pkgs.su pkgs.bash ]; path = [ pkgs.ipfs pkgs.su pkgs.bash ];
preStart = preStart = ''
''
install -m 0755 -o ${cfg.user} -g ${cfg.group} -d ${cfg.dataDir} install -m 0755 -o ${cfg.user} -g ${cfg.group} -d ${cfg.dataDir}
if [[ ! -d ${cfg.dataDir}/.ipfs ]]; then if [[ ! -d ${cfg.dataDir}/.ipfs ]]; then
cd ${cfg.dataDir} cd ${cfg.dataDir}
${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c "${ipfs}/bin/ipfs init" ${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c \
"${ipfs}/bin/ipfs init ${if cfg.emptyRepo then "-e" else ""}"
fi fi
${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c "${ipfs}/bin/ipfs config Addresses.API ${cfg.apiAddress}" ${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c \
${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c "${ipfs}/bin/ipfs config Addresses.Gateway ${cfg.gatewayAddress}" "${ipfs}/bin/ipfs --local config Addresses.API ${cfg.apiAddress} && \
${ipfs}/bin/ipfs --local config Addresses.Gateway ${cfg.gatewayAddress}"
''; '';
serviceConfig = { serviceConfig = {

View File

@ -6,29 +6,38 @@ let
cfg = config.services.asterisk; cfg = config.services.asterisk;
asteriskUser = "asterisk"; asteriskUser = "asterisk";
asteriskGroup = "asterisk";
varlibdir = "/var/lib/asterisk"; varlibdir = "/var/lib/asterisk";
spooldir = "/var/spool/asterisk"; spooldir = "/var/spool/asterisk";
logdir = "/var/log/asterisk"; logdir = "/var/log/asterisk";
# Add filecontents from files of useTheseDefaultConfFiles to confFiles, do not override
defaultConfFiles = subtractLists (attrNames cfg.confFiles) cfg.useTheseDefaultConfFiles;
allConfFiles =
cfg.confFiles //
builtins.listToAttrs (map (x: { name = x;
value = builtins.readFile (pkgs.asterisk + "/etc/asterisk/" + x); })
defaultConfFiles);
asteriskEtc = pkgs.stdenv.mkDerivation asteriskEtc = pkgs.stdenv.mkDerivation
((mapAttrs' (name: value: nameValuePair ((mapAttrs' (name: value: nameValuePair
# Fudge the names to make bash happy # Fudge the names to make bash happy
((replaceChars ["."] ["_"] name) + "_") ((replaceChars ["."] ["_"] name) + "_")
(value) (value)
) cfg.confFiles) // ) allConfFiles) //
{ {
confFilesString = concatStringsSep " " ( confFilesString = concatStringsSep " " (
attrNames cfg.confFiles attrNames allConfFiles
); );
name = "asterisk.etc"; name = "asterisk-etc";
# Default asterisk.conf file # Default asterisk.conf file
# (Notice that astetcdir will be set to the path of this derivation) # (Notice that astetcdir will be set to the path of this derivation)
asteriskConf = '' asteriskConf = ''
[directories] [directories]
astetcdir => @out@ astetcdir => /etc/asterisk
astmoddir => ${pkgs.asterisk}/lib/asterisk/modules astmoddir => ${pkgs.asterisk}/lib/asterisk/modules
astvarlibdir => /var/lib/asterisk astvarlibdir => /var/lib/asterisk
astdbdir => /var/lib/asterisk astdbdir => /var/lib/asterisk
@ -169,6 +178,16 @@ in
''; '';
}; };
useTheseDefaultConfFiles = mkOption {
default = [ "ari.conf" "acl.conf" "agents.conf" "amd.conf" "calendar.conf" "cdr.conf" "cdr_syslog.conf" "cdr_custom.conf" "cel.conf" "cel_custom.conf" "cli_aliases.conf" "confbridge.conf" "dundi.conf" "features.conf" "hep.conf" "iax.conf" "pjsip.conf" "pjsip_wizard.conf" "phone.conf" "phoneprov.conf" "queues.conf" "res_config_sqlite3.conf" "res_parking.conf" "statsd.conf" "udptl.conf" "unistim.conf" ];
type = types.listOf types.str;
example = [ "sip.conf" "dundi.conf" ];
description = ''Sets these config files to the default content. The default value for
this option contains all necesscary files to avoid errors at startup.
This does not override settings via <option>services.asterisk.confFiles</option>.
'';
};
extraArguments = mkOption { extraArguments = mkOption {
default = []; default = [];
type = types.listOf types.str; type = types.listOf types.str;
@ -182,13 +201,23 @@ in
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
users.extraUsers = singleton environment.systemPackages = [ pkgs.asterisk ];
environment.etc.asterisk.source = asteriskEtc;
users.extraUsers.asterisk =
{ name = asteriskUser; { name = asteriskUser;
group = asteriskGroup;
uid = config.ids.uids.asterisk; uid = config.ids.uids.asterisk;
description = "Asterisk daemon user"; description = "Asterisk daemon user";
home = varlibdir; home = varlibdir;
}; };
users.extraGroups.asterisk =
{ name = asteriskGroup;
gid = config.ids.gids.asterisk;
};
systemd.services.asterisk = { systemd.services.asterisk = {
description = '' description = ''
Asterisk PBX server Asterisk PBX server
@ -196,14 +225,17 @@ in
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
# Do not restart, to avoid disruption of running calls. Restart unit by yourself!
restartIfChanged = false;
preStart = '' preStart = ''
# Copy skeleton directory tree to /var # Copy skeleton directory tree to /var
for d in '${varlibdir}' '${spooldir}' '${logdir}'; do for d in '${varlibdir}' '${spooldir}' '${logdir}'; do
# TODO: Make exceptions for /var directories that likely should be updated # TODO: Make exceptions for /var directories that likely should be updated
if [ ! -e "$d" ]; then if [ ! -e "$d" ]; then
mkdir -p "$d" mkdir -p "$d"
cp --recursive ${pkgs.asterisk}/"$d" "$d" cp --recursive ${pkgs.asterisk}/"$d"/* "$d"/
chown --recursive ${asteriskUser} "$d" chown --recursive ${asteriskUser}:${asteriskGroup} "$d"
find "$d" -type d | xargs chmod 0755 find "$d" -type d | xargs chmod 0755
fi fi
done done
@ -215,7 +247,9 @@ in
# FIXME: This doesn't account for arguments with spaces # FIXME: This doesn't account for arguments with spaces
argString = concatStringsSep " " cfg.extraArguments; argString = concatStringsSep " " cfg.extraArguments;
in in
"${pkgs.asterisk}/bin/asterisk -U ${asteriskUser} -C ${asteriskEtc}/asterisk.conf ${argString} -F"; "${pkgs.asterisk}/bin/asterisk -U ${asteriskUser} -C /etc/asterisk/asterisk.conf ${argString} -F";
ExecReload = ''${pkgs.asterisk}/bin/asterisk -x "core reload"
'';
Type = "forking"; Type = "forking";
PIDFile = "/var/run/asterisk/asterisk.pid"; PIDFile = "/var/run/asterisk/asterisk.pid";
}; };

View File

@ -155,7 +155,7 @@ in
chown ${bindUser} /var/run/named chown ${bindUser} /var/run/named
''; '';
script = "${pkgs.bind.bin}/sbin/named -u ${bindUser} ${optionalString cfg.ipv4Only "-4"} -c ${cfg.configFile} -f"; script = "${pkgs.bind.out}/sbin/named -u ${bindUser} ${optionalString cfg.ipv4Only "-4"} -c ${cfg.configFile} -f";
unitConfig.Documentation = "man:named(8)"; unitConfig.Documentation = "man:named(8)";
}; };
}; };

View File

@ -34,6 +34,7 @@ let
###### implementation ###### implementation
config = mkIf cfg.enable { config = mkIf cfg.enable {
environment.systemPackages = [ pkg ];
systemd.services.${variant} = { systemd.services.${variant} = {
description = "BIRD Internet Routing Daemon"; description = "BIRD Internet Routing Daemon";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];

View File

@ -19,21 +19,30 @@ let
type = types.str; type = types.str;
description = "Public key at the opposite end of the tunnel."; description = "Public key at the opposite end of the tunnel.";
}; };
hostname = mkOption {
default = "";
example = "foobar.hype";
type = types.str;
description = "Optional hostname to add to /etc/hosts; prevents reverse lookup failures.";
};
}; };
}; };
# check for the required attributes, otherwise # Additional /etc/hosts entries for peers with an associated hostname
# permit attributes not undefined here cjdnsExtraHosts = import (pkgs.runCommand "cjdns-hosts" {}
checkPeers = x: # Generate a builder that produces an output usable as a Nix string value
x // { ''
connectTo = mapAttrs exec >$out
(name: value: echo \'\'
if !hasAttr "publicKey" value then abort "cjdns peer ${name} missing a publicKey" else ${concatStringsSep "\n" (mapAttrsToList (k: v:
if !hasAttr "password" value then abort "cjdns peer ${name} missing a password" else optionalString (v.hostname != "")
value "echo $(${pkgs.cjdns}/bin/publictoip6 ${v.publicKey}) ${v.hostname}")
) (cfg.ETHInterface.connectTo // cfg.UDPInterface.connectTo))}
x.connectTo; echo \'\'
}; '');
parseModules = x:
x // { connectTo = mapAttrs (name: value: { inherit (value) password publicKey; }) x.connectTo; };
# would be nice to merge 'cfg' with a //, # would be nice to merge 'cfg' with a //,
# but the json nesting is wacky. # but the json nesting is wacky.
@ -44,8 +53,8 @@ let
}; };
authorizedPasswords = map (p: { password = p; }) cfg.authorizedPasswords; authorizedPasswords = map (p: { password = p; }) cfg.authorizedPasswords;
interfaces = { interfaces = {
ETHInterface = if (cfg.ETHInterface.bind != "") then [ (checkPeers cfg.ETHInterface) ] else [ ]; ETHInterface = if (cfg.ETHInterface.bind != "") then [ (parseModules cfg.ETHInterface) ] else [ ];
UDPInterface = if (cfg.UDPInterface.bind != "") then [ (checkPeers cfg.UDPInterface) ] else [ ]; UDPInterface = if (cfg.UDPInterface.bind != "") then [ (parseModules cfg.UDPInterface) ] else [ ];
}; };
privateKey = "@CJDNS_PRIVATE_KEY@"; privateKey = "@CJDNS_PRIVATE_KEY@";
@ -125,11 +134,11 @@ in
''; '';
}; };
connectTo = mkOption { connectTo = mkOption {
type = types.attrsOf (types.attrsOf types.str); type = types.attrsOf ( types.submodule ( connectToSubmodule ) );
default = { }; default = { };
example = { example = {
"192.168.1.1:27313" = { "192.168.1.1:27313" = {
user = "foobar"; hostname = "homer.hype";
password = "5kG15EfpdcKNX3f2GSQ0H1HC7yIfxoCoImnO5FHM"; password = "5kG15EfpdcKNX3f2GSQ0H1HC7yIfxoCoImnO5FHM";
publicKey = "371zpkgs8ss387tmr81q04mp0hg1skb51hw34vk1cq644mjqhup0.k"; publicKey = "371zpkgs8ss387tmr81q04mp0hg1skb51hw34vk1cq644mjqhup0.k";
}; };
@ -170,11 +179,11 @@ in
}; };
connectTo = mkOption { connectTo = mkOption {
type = types.attrsOf (types.attrsOf types.str); type = types.attrsOf ( types.submodule ( connectToSubmodule ) );
default = { }; default = { };
example = { example = {
"01:02:03:04:05:06" = { "01:02:03:04:05:06" = {
user = "foobar"; hostname = "homer.hype";
password = "5kG15EfpdcKNX3f2GSQ0H1HC7yIfxoCoImnO5FHM"; password = "5kG15EfpdcKNX3f2GSQ0H1HC7yIfxoCoImnO5FHM";
publicKey = "371zpkgs8ss387tmr81q04mp0hg1skb51hw34vk1cq644mjqhup0.k"; publicKey = "371zpkgs8ss387tmr81q04mp0hg1skb51hw34vk1cq644mjqhup0.k";
}; };
@ -186,6 +195,16 @@ in
}; };
}; };
addExtraHosts = mkOption {
type = types.bool;
default = false;
description = ''
Whether to add cjdns peers with an associated hostname to
<filename>/etc/hosts</filename>. Beware that enabling this
incurs heavy eval-time costs.
'';
};
}; };
}; };
@ -248,6 +267,8 @@ in
}; };
}; };
networking.extraHosts = mkIf cfg.addExtraHosts cjdnsExtraHosts;
assertions = [ assertions = [
{ assertion = ( cfg.ETHInterface.bind != "" || cfg.UDPInterface.bind != "" || cfg.confFile != null ); { assertion = ( cfg.ETHInterface.bind != "" || cfg.UDPInterface.bind != "" || cfg.confFile != null );
message = "Neither cjdns.ETHInterface.bind nor cjdns.UDPInterface.bind defined."; message = "Neither cjdns.ETHInterface.bind nor cjdns.UDPInterface.bind defined.";

View File

@ -120,7 +120,7 @@ in
}; };
environment.etc."ddclient.conf" = { environment.etc."ddclient.conf" = {
enable = config.services.ddclient.configFile == /etc/ddclient.conf; enable = config.services.ddclient.configFile == "/etc/ddclient.conf";
uid = config.ids.uids.ddclient; uid = config.ids.uids.ddclient;
mode = "0600"; mode = "0600";
text = '' text = ''
@ -132,7 +132,8 @@ in
login=${config.services.ddclient.username} login=${config.services.ddclient.username}
password=${config.services.ddclient.password} password=${config.services.ddclient.password}
protocol=${config.services.ddclient.protocol} protocol=${config.services.ddclient.protocol}
server=${config.services.ddclient.server} ${let server = config.services.ddclient.server; in
lib.optionalString (server != "") "server=${server}"}
ssl=${if config.services.ddclient.ssl then "yes" else "no"} ssl=${if config.services.ddclient.ssl then "yes" else "no"}
wildcard=YES wildcard=YES
${config.services.ddclient.domain} ${config.services.ddclient.domain}

View File

@ -4,11 +4,10 @@ with lib;
let let
cfg = config.services.dhcpd; cfg4 = config.services.dhcpd4;
cfg6 = config.services.dhcpd6;
stateDir = "/var/lib/dhcp"; # Don't use /var/state/dhcp; not FHS-compliant. writeConfig = cfg: pkgs.writeText "dhcpd.conf"
configFile = if cfg.configFile != null then cfg.configFile else pkgs.writeText "dhcpd.conf"
'' ''
default-lease-time 600; default-lease-time 600;
max-lease-time 7200; max-lease-time 7200;
@ -29,21 +28,85 @@ let
} }
''; '';
in dhcpdService = postfix: cfg: optionalAttrs cfg.enable {
"dhcpd${postfix}" = {
description = "DHCPv${postfix} server";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
{ preStart = ''
mkdir -m 755 -p ${cfg.stateDir}
touch ${cfg.stateDir}/dhcpd.leases
'';
###### interface serviceConfig =
let
configFile = if cfg.configFile != null then cfg.configFile else writeConfig cfg;
args = [ "@${pkgs.dhcp}/sbin/dhcpd" "dhcpd${postfix}" "-${postfix}"
"-pf" "/run/dhcpd${postfix}/dhcpd.pid"
"-cf" "${configFile}"
"-lf" "${cfg.stateDir}/dhcpd.leases"
"-user" "dhcpd" "-group" "nogroup"
] ++ cfg.extraFlags
++ cfg.interfaces;
options = { in {
ExecStart = concatMapStringsSep " " escapeShellArg args;
Type = "forking";
Restart = "always";
RuntimeDirectory = [ "dhcpd${postfix}" ];
PIDFile = "/run/dhcpd${postfix}/dhcpd.pid";
};
};
};
services.dhcpd = { machineOpts = {...}: {
config = {
hostName = mkOption {
type = types.str;
example = "foo";
description = ''
Hostname which is assigned statically to the machine.
'';
};
ethernetAddress = mkOption {
type = types.str;
example = "00:16:76:9a:32:1d";
description = ''
MAC address of the machine.
'';
};
ipAddress = mkOption {
type = types.str;
example = "192.168.1.10";
description = ''
IP address of the machine.
'';
};
};
};
dhcpConfig = postfix: {
enable = mkOption { enable = mkOption {
type = types.bool;
default = false; default = false;
description = " description = ''
Whether to enable the DHCP server. Whether to enable the DHCPv${postfix} server.
"; '';
};
stateDir = mkOption {
type = types.path;
# We use /var/lib/dhcp for DHCPv4 to save backwards compatibility.
default = "/var/lib/dhcp${if postfix == "4" then "" else postfix}";
description = ''
State directory for the DHCP server.
'';
}; };
extraConfig = mkOption { extraConfig = mkOption {
@ -59,38 +122,41 @@ in
range 192.168.1.100 192.168.1.200; range 192.168.1.100 192.168.1.200;
} }
''; '';
description = " description = ''
Extra text to be appended to the DHCP server configuration Extra text to be appended to the DHCP server configuration
file. Currently, you almost certainly need to specify file. Currently, you almost certainly need to specify something
something here, such as the options specifying the subnet there, such as the options specifying the subnet mask, DNS servers,
mask, DNS servers, etc. etc.
"; '';
}; };
extraFlags = mkOption { extraFlags = mkOption {
default = ""; type = types.listOf types.str;
example = "-6"; default = [];
description = " description = ''
Additional command line flags to be passed to the dhcpd daemon. Additional command line flags to be passed to the dhcpd daemon.
"; '';
}; };
configFile = mkOption { configFile = mkOption {
type = types.nullOr types.path;
default = null; default = null;
description = " description = ''
The path of the DHCP server configuration file. If no file The path of the DHCP server configuration file. If no file
is specified, a file is generated using the other options. is specified, a file is generated using the other options.
"; '';
}; };
interfaces = mkOption { interfaces = mkOption {
type = types.listOf types.str;
default = ["eth0"]; default = ["eth0"];
description = " description = ''
The interfaces on which the DHCP server should listen. The interfaces on which the DHCP server should listen.
"; '';
}; };
machines = mkOption { machines = mkOption {
type = types.listOf (types.submodule machineOpts);
default = []; default = [];
example = [ example = [
{ hostName = "foo"; { hostName = "foo";
@ -102,20 +168,31 @@ in
ipAddress = "192.168.1.11"; ipAddress = "192.168.1.11";
} }
]; ];
description = " description = ''
A list mapping ethernet addresses to IP addresses for the A list mapping Ethernet addresses to IPv${postfix} addresses for the
DHCP server. DHCP server.
"; '';
}; };
}; };
in
{
###### interface
options = {
services.dhcpd4 = dhcpConfig "4";
services.dhcpd6 = dhcpConfig "6";
}; };
###### implementation ###### implementation
config = mkIf config.services.dhcpd.enable { config = mkIf (cfg4.enable || cfg6.enable) {
users = { users = {
extraUsers.dhcpd = { extraUsers.dhcpd = {
@ -124,36 +201,7 @@ in
}; };
}; };
systemd.services.dhcpd = systemd.services = dhcpdService "4" cfg4 // dhcpdService "6" cfg6;
{ description = "DHCP server";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
path = [ pkgs.dhcp ];
preStart =
''
mkdir -m 755 -p ${stateDir}
touch ${stateDir}/dhcpd.leases
mkdir -m 755 -p /run/dhcpd
chown dhcpd /run/dhcpd
'';
serviceConfig =
{ ExecStart = "@${pkgs.dhcp}/sbin/dhcpd dhcpd"
+ " -pf /run/dhcpd/dhcpd.pid -cf ${configFile}"
+ " -lf ${stateDir}/dhcpd.leases -user dhcpd -group nogroup"
+ " ${cfg.extraFlags}"
+ " ${toString cfg.interfaces}";
Restart = "always";
Type = "forking";
PIDFile = "/run/dhcpd/dhcpd.pid";
};
};
}; };

View File

@ -263,6 +263,8 @@ in
systemd.services.dnscrypt-proxy = { systemd.services.dnscrypt-proxy = {
description = "dnscrypt-proxy daemon"; description = "dnscrypt-proxy daemon";
before = [ "nss-lookup.target" ];
after = [ "network.target" ] after = [ "network.target" ]
++ optional apparmorEnabled "apparmor.service" ++ optional apparmorEnabled "apparmor.service"
++ optional useUpstreamResolverList "init-dnscrypt-proxy-statedir.service"; ++ optional useUpstreamResolverList "init-dnscrypt-proxy-statedir.service";

View File

@ -4,17 +4,29 @@
networking.firewall.extraCommands. For modularity, the firewall networking.firewall.extraCommands. For modularity, the firewall
uses several chains: uses several chains:
- nixos-fw-input is the main chain for input packet processing. - nixos-fw is the main chain for input packet processing.
- nixos-fw-accept is called for accepted packets. If you want
additional logging, or want to reject certain packets anyway, you
can insert rules at the start of this chain.
- nixos-fw-log-refuse and nixos-fw-refuse are called for - nixos-fw-log-refuse and nixos-fw-refuse are called for
refused packets. (The former jumps to the latter after logging refused packets. (The former jumps to the latter after logging
the packet.) If you want additional logging, or want to accept the packet.) If you want additional logging, or want to accept
certain packets anyway, you can insert rules at the start of certain packets anyway, you can insert rules at the start of
these chain. this chain.
- nixos-fw-accept is called for accepted packets. If you want - nixos-fw-rpfilter is used as the main chain in the raw table,
additional logging, or want to reject certain packets anyway, you called from the built-in PREROUTING chain. If the kernel
can insert rules at the start of this chain. supports it and `cfg.checkReversePath` is set this chain will
perform a reverse path filter test.
- nixos-drop is used while reloading the firewall in order to drop
all traffic. Since reloading isn't implemented in an atomic way
this'll prevent any traffic from leaking through while reloading
the firewall. However, if the reloading fails, the firewall-stop
script will be called which in return will effectively disable the
complete firewall (in the default configuration).
*/ */
@ -26,6 +38,11 @@ let
cfg = config.networking.firewall; cfg = config.networking.firewall;
kernelPackages = config.boot.kernelPackages;
kernelHasRPFilter = kernelPackages.kernel.features.netfilterRPFilter or false;
kernelCanDisableHelpers = kernelPackages.kernel.features.canDisableNetfilterConntrackHelpers or false;
helpers = helpers =
'' ''
# Helper command to manipulate both the IPv4 and IPv6 tables. # Helper command to manipulate both the IPv4 and IPv6 tables.
@ -49,7 +66,7 @@ let
# firewall would be atomic. Apparently that's possible # firewall would be atomic. Apparently that's possible
# with iptables-restore. # with iptables-restore.
ip46tables -D INPUT -j nixos-fw 2> /dev/null || true ip46tables -D INPUT -j nixos-fw 2> /dev/null || true
for chain in nixos-fw nixos-fw-accept nixos-fw-log-refuse nixos-fw-refuse FW_REFUSE; do for chain in nixos-fw nixos-fw-accept nixos-fw-log-refuse nixos-fw-refuse; do
ip46tables -F "$chain" 2> /dev/null || true ip46tables -F "$chain" 2> /dev/null || true
ip46tables -X "$chain" 2> /dev/null || true ip46tables -X "$chain" 2> /dev/null || true
done done
@ -172,13 +189,16 @@ let
}-j nixos-fw-accept }-j nixos-fw-accept
''} ''}
${optionalString config.networking.enableIPv6 ''
# Accept all ICMPv6 messages except redirects and node # Accept all ICMPv6 messages except redirects and node
# information queries (type 139). See RFC 4890, section # information queries (type 139). See RFC 4890, section
# 4.4. # 4.4.
${optionalString config.networking.enableIPv6 ''
ip6tables -A nixos-fw -p icmpv6 --icmpv6-type redirect -j DROP ip6tables -A nixos-fw -p icmpv6 --icmpv6-type redirect -j DROP
ip6tables -A nixos-fw -p icmpv6 --icmpv6-type 139 -j DROP ip6tables -A nixos-fw -p icmpv6 --icmpv6-type 139 -j DROP
ip6tables -A nixos-fw -p icmpv6 -j nixos-fw-accept ip6tables -A nixos-fw -p icmpv6 -j nixos-fw-accept
# Allow this host to act as a DHCPv6 client
ip6tables -A nixos-fw -d fe80::/64 -p udp --dport 546 -j nixos-fw-accept
''} ''}
${cfg.extraCommands} ${cfg.extraCommands}
@ -228,11 +248,6 @@ let
fi fi
''; '';
kernelPackages = config.boot.kernelPackages;
kernelHasRPFilter = kernelPackages.kernel.features.netfilterRPFilter or false;
kernelCanDisableHelpers = kernelPackages.kernel.features.canDisableNetfilterConntrackHelpers or false;
in in
{ {
@ -290,26 +305,30 @@ in
default = false; default = false;
description = description =
'' ''
If set, forbidden packets are rejected rather than dropped If set, refused packets are rejected rather than dropped
(ignored). This means that an ICMP "port unreachable" error (ignored). This means that an ICMP "port unreachable" error
message is sent back to the client. Rejecting packets makes message is sent back to the client (or a TCP RST packet in
case of an existing connection). Rejecting packets makes
port scanning somewhat easier. port scanning somewhat easier.
''; '';
}; };
networking.firewall.trustedInterfaces = mkOption { networking.firewall.trustedInterfaces = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = [ ];
example = [ "enp0s2" ];
description = description =
'' ''
Traffic coming in from these interfaces will be accepted Traffic coming in from these interfaces will be accepted
unconditionally. unconditionally. Traffic from the loopback (lo) interface
will always be accepted.
''; '';
}; };
networking.firewall.allowedTCPPorts = mkOption { networking.firewall.allowedTCPPorts = mkOption {
type = types.listOf types.int;
default = [ ]; default = [ ];
example = [ 22 80 ]; example = [ 22 80 ];
type = types.listOf types.int;
description = description =
'' ''
List of TCP ports on which incoming connections are List of TCP ports on which incoming connections are
@ -318,9 +337,9 @@ in
}; };
networking.firewall.allowedTCPPortRanges = mkOption { networking.firewall.allowedTCPPortRanges = mkOption {
type = types.listOf (types.attrsOf types.int);
default = [ ]; default = [ ];
example = [ { from = 8999; to = 9003; } ]; example = [ { from = 8999; to = 9003; } ];
type = types.listOf (types.attrsOf types.int);
description = description =
'' ''
A range of TCP ports on which incoming connections are A range of TCP ports on which incoming connections are
@ -329,9 +348,9 @@ in
}; };
networking.firewall.allowedUDPPorts = mkOption { networking.firewall.allowedUDPPorts = mkOption {
type = types.listOf types.int;
default = [ ]; default = [ ];
example = [ 53 ]; example = [ 53 ];
type = types.listOf types.int;
description = description =
'' ''
List of open UDP ports. List of open UDP ports.
@ -339,9 +358,9 @@ in
}; };
networking.firewall.allowedUDPPortRanges = mkOption { networking.firewall.allowedUDPPortRanges = mkOption {
type = types.listOf (types.attrsOf types.int);
default = [ ]; default = [ ];
example = [ { from = 60000; to = 61000; } ]; example = [ { from = 60000; to = 61000; } ];
type = types.listOf (types.attrsOf types.int);
description = description =
'' ''
Range of open UDP ports. Range of open UDP ports.
@ -349,8 +368,8 @@ in
}; };
networking.firewall.allowPing = mkOption { networking.firewall.allowPing = mkOption {
default = true;
type = types.bool; type = types.bool;
default = true;
description = description =
'' ''
Whether to respond to incoming ICMPv4 echo requests Whether to respond to incoming ICMPv4 echo requests
@ -361,36 +380,43 @@ in
}; };
networking.firewall.pingLimit = mkOption { networking.firewall.pingLimit = mkOption {
default = null;
type = types.nullOr (types.separatedString " "); type = types.nullOr (types.separatedString " ");
default = null;
example = "--limit 1/minute --limit-burst 5";
description = description =
'' ''
If pings are allowed, this allows setting rate limits If pings are allowed, this allows setting rate limits
on them. If non-null, this option should be in the form on them. If non-null, this option should be in the form of
of flags like "--limit 1/minute --limit-burst 5" flags like "--limit 1/minute --limit-burst 5"
''; '';
}; };
networking.firewall.checkReversePath = mkOption { networking.firewall.checkReversePath = mkOption {
default = kernelHasRPFilter;
type = types.either types.bool (types.enum ["strict" "loose"]); type = types.either types.bool (types.enum ["strict" "loose"]);
default = kernelHasRPFilter;
example = "loose";
description = description =
'' ''
Performs a reverse path filter test on a packet. Performs a reverse path filter test on a packet. If a reply
If a reply to the packet would not be sent via the same interface to the packet would not be sent via the same interface that
that the packet arrived on, it is refused. the packet arrived on, it is refused.
If using asymmetric routing or other complicated routing, If using asymmetric routing or other complicated routing, set
set this option to loose mode or disable it and setup your this option to loose mode or disable it and setup your own
own counter-measures. counter-measures.
This option can be either true (or "strict"), "loose" (only
drop the packet if the source address is not reachable via any
interface) or false. Defaults to the value of
kernelHasRPFilter.
(needs kernel 3.3+) (needs kernel 3.3+)
''; '';
}; };
networking.firewall.logReversePathDrops = mkOption { networking.firewall.logReversePathDrops = mkOption {
default = false;
type = types.bool; type = types.bool;
default = false;
description = description =
'' ''
Logs dropped packets failing the reverse path filter test if Logs dropped packets failing the reverse path filter test if
@ -399,9 +425,9 @@ in
}; };
networking.firewall.connectionTrackingModules = mkOption { networking.firewall.connectionTrackingModules = mkOption {
type = types.listOf types.str;
default = [ "ftp" ]; default = [ "ftp" ];
example = [ "ftp" "irc" "sane" "sip" "tftp" "amanda" "h323" "netbios_sn" "pptp" "snmp" ]; example = [ "ftp" "irc" "sane" "sip" "tftp" "amanda" "h323" "netbios_sn" "pptp" "snmp" ];
type = types.listOf types.str;
description = description =
'' ''
List of connection-tracking helpers that are auto-loaded. List of connection-tracking helpers that are auto-loaded.
@ -418,8 +444,8 @@ in
}; };
networking.firewall.autoLoadConntrackHelpers = mkOption { networking.firewall.autoLoadConntrackHelpers = mkOption {
default = true;
type = types.bool; type = types.bool;
default = true;
description = description =
'' ''
Whether to auto-load connection-tracking helpers. Whether to auto-load connection-tracking helpers.
@ -461,7 +487,8 @@ in
'' ''
Additional shell commands executed as part of the firewall Additional shell commands executed as part of the firewall
shutdown script. These are executed just after the removal shutdown script. These are executed just after the removal
of the nixos input rule, or if the service enters a failed state. of the NixOS input rule, or if the service enters a failed
state.
''; '';
}; };

View File

@ -147,7 +147,7 @@ let
host = ${tun.address} host = ${tun.address}
port = ${tun.port} port = ${tun.port}
inport = ${tun.inPort} inport = ${tun.inPort}
accesslist = ${concatStringSep "," tun.accessList} accesslist = ${builtins.concatStringsSep "," tun.accessList}
'') '')
} }
''; '';

View File

@ -0,0 +1,92 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.miredo;
pidFile = "/run/miredo.pid";
miredoConf = pkgs.writeText "miredo.conf" ''
InterfaceName ${cfg.interfaceName}
ServerAddress ${cfg.serverAddress}
${optionalString (cfg.bindAddress != null) "BindAddress ${cfg.bindAddress}"}
${optionalString (cfg.bindPort != null) "BindPort ${cfg.bindPort}"}
'';
in
{
###### interface
options = {
services.miredo = {
enable = mkEnableOption "Whether miredo should be run on startup.";
package = mkOption {
type = types.package;
default = pkgs.miredo;
defaultText = "pkgs.miredo";
description = ''
The package to use for the miredo daemon's binary.
'';
};
serverAddress = mkOption {
default = "teredo.remlab.net";
type = types.str;
description = ''
The hostname or primary IPv4 address of the Teredo server.
This setting is required if Miredo runs as a Teredo client.
"teredo.remlab.net" is an experimental service for testing only.
Please use another server for production and/or large scale deployments.
'';
};
interfaceName = mkOption {
default = "teredo";
type = types.str;
description = ''
Name of the network tunneling interface.
'';
};
bindAddress = mkOption {
default = null;
type = types.nullOr types.str;
description = ''
Depending on the local firewall/NAT rules, you might need to force
Miredo to use a fixed UDP port and or IPv4 address.
'';
};
bindPort = mkOption {
default = null;
type = types.nullOr types.str;
description = ''
Depending on the local firewall/NAT rules, you might need to force
Miredo to use a fixed UDP port and or IPv4 address.
'';
};
};
};
###### implementation
config = mkIf cfg.enable {
systemd.services.miredo = {
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
description = "Teredo IPv6 Tunneling Daemon";
serviceConfig = {
Restart = "always";
RestartSec = "5s";
ExecStart = "${cfg.package}/bin/miredo -c ${miredoConf} -p ${pidFile} -f";
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
};
};
};
}

View File

@ -11,17 +11,17 @@ let
then then
'' ''
*** General *** *** General ***
owner = ${cfg.owner} cgiurl = ${cfg.cgiUrl}
contact = ${cfg.ownerEmail} contact = ${cfg.ownerEmail}
${lib.optionalString (cfg.mailHost != "") "mailhost = ${cfg.mailHost}"}
${lib.optionalString (cfg.sendmail != null) "sendmail = ${cfg.sendmail}"}
imgcache = ${smokepingHome}/cache
imgurl = http://${cfg.hostName}:${builtins.toString cfg.port}/cache
datadir = ${smokepingHome}/data datadir = ${smokepingHome}/data
imgcache = ${smokepingHome}/cache
imgurl = ${cfg.imgUrl}
linkstyle = ${cfg.linkStyle}
${lib.optionalString (cfg.mailHost != "") "mailhost = ${cfg.mailHost}"}
owner = ${cfg.owner}
pagedir = ${smokepingHome}/cache pagedir = ${smokepingHome}/cache
piddir = ${smokepingPidDir} piddir = ${smokepingPidDir}
cgiurl = http://${cfg.hostName}:${builtins.toString cfg.port}/smokeping.cgi ${lib.optionalString (cfg.sendmail != null) "sendmail = ${cfg.sendmail}"}
linkstyle = ${cfg.linkStyle}
smokemail = ${cfg.smokeMailTemplate} smokemail = ${cfg.smokeMailTemplate}
*** Presentation *** *** Presentation ***
template = ${cfg.presentationTemplate} template = ${cfg.presentationTemplate}
@ -54,72 +54,36 @@ in
default = false; default = false;
description = "Enable the smokeping service"; description = "Enable the smokeping service";
}; };
webService = mkOption { alertConfig = mkOption {
type = types.bool; type = types.string;
default = true; default = ''
description = "Enable a smokeping web interface"; to = root@localhost
}; from = smokeping@localhost
'';
example = literalExample ''
to = alertee@address.somewhere
from = smokealert@company.xy
user = mkOption { +someloss
type = types.string; type = loss
default = "smokeping"; # in percent
description = "User that runs smokeping and (optionally) thttpd"; pattern = >0%,*12*,>0%,*12*,>0%
comment = loss 3 times in a row;
'';
description = "Configuration for alerts.";
}; };
mailHost = mkOption { cgiUrl = mkOption {
type = types.string; type = types.string;
default = ""; default = "http://${cfg.hostName}:${builtins.toString cfg.port}/smokeping.cgi";
example = "localhost"; example = "https://somewhere.example.com/smokeping.cgi";
description = "Use this SMTP server to send alerts"; description = "URL to the smokeping cgi.";
}; };
sendmail = mkOption { config = mkOption {
type = types.nullOr types.path; type = types.nullOr types.string;
default = null; default = null;
example = "/var/setuid-wrappers/sendmail"; description = "Full smokeping config supplied by the user. Overrides " +
description = "Use this sendmail compatible script to deliver alerts"; "and replaces any other configuration supplied.";
}; };
smokeMailTemplate = mkOption {
type = types.string;
default = "${cfg.package}/etc/smokemail.dist";
description = "Specify the smokemail template for alerts.";
};
package = mkOption {
type = types.package;
default = pkgs.smokeping;
defaultText = "pkgs.smokeping";
description = "Specify a custom smokeping package";
};
owner = mkOption {
type = types.string;
default = "nobody";
example = "Joe Admin";
description = "Real name of the owner of the instance";
};
hostName = mkOption {
type = types.string;
default = config.networking.hostName;
example = "somewhere.example.com";
description = "DNS name for the urls generated in the cgi.";
};
linkStyle = mkOption {
type = types.enum ["original" "absolute" "relative"];
default = "relative";
example = "absolute";
description = "DNS name for the urls generated in the cgi.";
};
port = mkOption {
type = types.int;
default = 8081;
example = 8081;
description = "TCP port to use for the web server.";
};
ownerEmail = mkOption {
type = types.string;
default = "no-reply@${cfg.hostName}";
example = "no-reply@yourdomain.com";
description = "Email contact for owner";
};
databaseConfig = mkOption { databaseConfig = mkOption {
type = types.string; type = types.string;
default = '' default = ''
@ -152,30 +116,59 @@ in
Once set, changing the interval will require deletion or migration of all Once set, changing the interval will require deletion or migration of all
the collected data.''; the collected data.'';
}; };
alertConfig = mkOption { extraConfig = mkOption {
type = types.string; type = types.lines;
default = '' default = "";
to = root@localhost description = "Any additional customization not already included.";
from = smokeping@localhost
'';
example = literalExample ''
to = alertee@address.somewhere
from = smokealert@company.xy
+someloss
type = loss
# in percent
pattern = >0%,*12*,>0%,*12*,>0%
comment = loss 3 times in a row;
'';
description = "Configuration for alerts.";
}; };
presentationTemplate = mkOption { hostName = mkOption {
type = types.string; type = types.string;
default = "${pkgs.smokeping}/etc/basepage.html.dist"; default = config.networking.hostName;
description = "Default page layout for the web UI."; example = "somewhere.example.com";
description = "DNS name for the urls generated in the cgi.";
};
imgUrl = mkOption {
type = types.string;
default = "http://${cfg.hostName}:${builtins.toString cfg.port}/cache";
example = "https://somewhere.example.com/cache";
description = "Base url for images generated in the cgi.";
};
linkStyle = mkOption {
type = types.enum ["original" "absolute" "relative"];
default = "relative";
example = "absolute";
description = "DNS name for the urls generated in the cgi.";
};
mailHost = mkOption {
type = types.string;
default = "";
example = "localhost";
description = "Use this SMTP server to send alerts";
};
owner = mkOption {
type = types.string;
default = "nobody";
example = "Joe Admin";
description = "Real name of the owner of the instance";
};
ownerEmail = mkOption {
type = types.string;
default = "no-reply@${cfg.hostName}";
example = "no-reply@yourdomain.com";
description = "Email contact for owner";
};
package = mkOption {
type = types.package;
default = pkgs.smokeping;
defaultText = "pkgs.smokeping";
description = "Specify a custom smokeping package";
};
port = mkOption {
type = types.int;
default = 8081;
example = 8081;
description = "TCP port to use for the web server.";
}; };
presentationConfig = mkOption { presentationConfig = mkOption {
type = types.string; type = types.string;
default = '' default = ''
@ -217,6 +210,11 @@ in
''; '';
description = "presentation graph style"; description = "presentation graph style";
}; };
presentationTemplate = mkOption {
type = types.string;
default = "${pkgs.smokeping}/etc/basepage.html.dist";
description = "Default page layout for the web UI.";
};
probeConfig = mkOption { probeConfig = mkOption {
type = types.string; type = types.string;
default = '' default = ''
@ -225,6 +223,17 @@ in
''; '';
description = "Probe configuration"; description = "Probe configuration";
}; };
sendmail = mkOption {
type = types.nullOr types.path;
default = null;
example = "/var/setuid-wrappers/sendmail";
description = "Use this sendmail compatible script to deliver alerts";
};
smokeMailTemplate = mkOption {
type = types.string;
default = "${cfg.package}/etc/smokemail.dist";
description = "Specify the smokemail template for alerts.";
};
targetConfig = mkOption { targetConfig = mkOption {
type = types.string; type = types.string;
default = '' default = ''
@ -243,18 +252,16 @@ in
''; '';
description = "Target configuration"; description = "Target configuration";
}; };
extraConfig = mkOption { user = mkOption {
type = types.lines; type = types.string;
default = ""; default = "smokeping";
description = "Any additional customization not already included."; description = "User that runs smokeping and (optionally) thttpd";
}; };
config = mkOption { webService = mkOption {
type = types.nullOr types.string; type = types.bool;
default = null; default = true;
description = "Full smokeping config supplied by the user. Overrides " + description = "Enable a smokeping web interface";
"and replaces any other configuration supplied.";
}; };
}; };
}; };

View File

@ -264,8 +264,7 @@ in
StandardInput = "socket"; StandardInput = "socket";
} else { } else {
Restart = "always"; Restart = "always";
Type = "forking"; Type = "simple";
PIDFile = "/run/sshd.pid";
}); });
}; };
@ -322,8 +321,6 @@ in
services.openssh.extraConfig = mkOrder 0 services.openssh.extraConfig = mkOrder 0
'' ''
PidFile /run/sshd.pid
Protocol 2 Protocol 2
UsePAM yes UsePAM yes

View File

@ -12,11 +12,13 @@ let
psk = if networkConfig.psk != null psk = if networkConfig.psk != null
then ''"${networkConfig.psk}"'' then ''"${networkConfig.psk}"''
else networkConfig.pskRaw; else networkConfig.pskRaw;
priority = networkConfig.priority;
in '' in ''
network={ network={
ssid="${ssid}" ssid="${ssid}"
${optionalString (psk != null) ''psk=${psk}''} ${optionalString (psk != null) ''psk=${psk}''}
${optionalString (psk == null) ''key_mgmt=NONE''} ${optionalString (psk == null) ''key_mgmt=NONE''}
${optionalString (priority != null) ''priority=${toString priority}''}
} }
'') cfg.networks)} '') cfg.networks)}
'' else "/etc/wpa_supplicant.conf"; '' else "/etc/wpa_supplicant.conf";
@ -68,6 +70,19 @@ in {
Mutually exclusive with <varname>psk</varname>. Mutually exclusive with <varname>psk</varname>.
''; '';
}; };
priority = mkOption {
type = types.nullOr types.int;
default = null;
description = ''
By default, all networks will get same priority group (0). If some of the
networks are more desirable, this field can be used to change the order in
which wpa_supplicant goes through the networks when selecting a BSS. The
priority groups will be iterated in decreasing priority (i.e., the larger the
priority value, the sooner the network is matched against the scan results).
Within each priority group, networks will be selected based on security
policy, signal strength, etc.
'';
};
}; };
}); });
description = '' description = ''

View File

@ -81,6 +81,7 @@ in
users.extraUsers = singleton { users.extraUsers = singleton {
name = clamavUser; name = clamavUser;
uid = config.ids.uids.clamav; uid = config.ids.uids.clamav;
group = clamavGroup;
description = "ClamAV daemon user"; description = "ClamAV daemon user";
home = stateDir; home = stateDir;
}; };

View File

@ -9,8 +9,6 @@ let
inherit (lib) singleton; inherit (lib) singleton;
cfgFile = pkgs.writeText "nscd.conf" cfg.config;
in in
{ {
@ -41,6 +39,7 @@ in
###### implementation ###### implementation
config = mkIf cfg.enable { config = mkIf cfg.enable {
environment.etc."nscd.conf".text = cfg.config;
users.extraUsers.nscd = users.extraUsers.nscd =
{ isSystemUser = true; { isSystemUser = true;
@ -61,10 +60,14 @@ in
mkdir -m 0755 -p /var/db/nscd mkdir -m 0755 -p /var/db/nscd
''; '';
restartTriggers = [ config.environment.etc.hosts.source config.environment.etc."nsswitch.conf".source ]; restartTriggers = [
config.environment.etc.hosts.source
config.environment.etc."nsswitch.conf".source
config.environment.etc."nscd.conf".source
];
serviceConfig = serviceConfig =
{ ExecStart = "@${pkgs.glibc.bin}/sbin/nscd nscd -f ${cfgFile}"; { ExecStart = "@${pkgs.glibc.bin}/sbin/nscd nscd";
Type = "forking"; Type = "forking";
PIDFile = "/run/nscd/nscd.pid"; PIDFile = "/run/nscd/nscd.pid";
Restart = "always"; Restart = "always";
@ -79,7 +82,7 @@ in
# its pid. So wait until it's ready. # its pid. So wait until it's ready.
postStart = postStart =
'' ''
while ! ${pkgs.glibc.bin}/sbin/nscd -g -f ${cfgFile} > /dev/null; do while ! ${pkgs.glibc.bin}/sbin/nscd -g > /dev/null; do
sleep 0.2 sleep 0.2
done done
''; '';

View File

@ -4,7 +4,7 @@ with lib;
let let
cfg = config.services.flexget; cfg = config.services.flexget;
pkg = pkgs.python27Packages.flexget; pkg = pkgs.flexget;
ymlFile = pkgs.writeText "flexget.yml" '' ymlFile = pkgs.writeText "flexget.yml" ''
${cfg.config} ${cfg.config}
@ -54,12 +54,12 @@ in {
config = mkIf cfg.enable { config = mkIf cfg.enable {
environment.systemPackages = [ pkgs.python27Packages.flexget ]; environment.systemPackages = [ pkg ];
systemd.services = { systemd.services = {
flexget = { flexget = {
description = "FlexGet Daemon"; description = "FlexGet Daemon";
path = [ pkgs.pythonPackages.flexget ]; path = [ pkg ];
serviceConfig = { serviceConfig = {
User = cfg.user; User = cfg.user;
Environment = "TZ=${config.time.timeZone}"; Environment = "TZ=${config.time.timeZone}";

View File

@ -6,7 +6,12 @@ let
cfg = config.services.crowd; cfg = config.services.crowd;
pkg = pkgs.atlassian-crowd; pkg = pkgs.atlassian-crowd.override {
home = cfg.home;
port = cfg.listenPort;
proxyUrl = "${cfg.proxy.scheme}://${cfg.proxy.name}:${toString cfg.proxy.port}";
openidPassword = cfg.openidPassword;
};
in in
@ -45,6 +50,11 @@ in
description = "Port to listen on."; description = "Port to listen on.";
}; };
openidPassword = mkOption {
type = types.str;
description = "Application password for OpenID server.";
};
catalinaOptions = mkOption { catalinaOptions = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = []; default = [];
@ -119,10 +129,10 @@ in
}; };
preStart = '' preStart = ''
mkdir -p ${cfg.home}/{logs,work} mkdir -p ${cfg.home}/{logs,work,database}
mkdir -p /run/atlassian-crowd mkdir -p /run/atlassian-crowd
ln -sf ${cfg.home}/{work,server.xml} /run/atlassian-crowd ln -sf ${cfg.home}/{database,work,server.xml} /run/atlassian-crowd
chown -R ${cfg.user} ${cfg.home} chown -R ${cfg.user} ${cfg.home}
@ -134,7 +144,6 @@ in
''; '';
script = "${pkg}/start_crowd.sh"; script = "${pkg}/start_crowd.sh";
#stopScript = "${pkg}/bin/stop_crowd.sh";
serviceConfig = { serviceConfig = {
User = cfg.user; User = cfg.user;

View File

@ -16,6 +16,8 @@ let
phpMajorVersion = head (splitString "." php.version); phpMajorVersion = head (splitString "." php.version);
mod_perl = pkgs.mod_perl.override { apacheHttpd = httpd; };
defaultListen = cfg: if cfg.enableSSL defaultListen = cfg: if cfg.enableSSL
then [{ip = "*"; port = 443;}] then [{ip = "*"; port = 443;}]
else [{ip = "*"; port = 80;}]; else [{ip = "*"; port = 80;}];
@ -76,6 +78,7 @@ let
robotsEntries = ""; robotsEntries = "";
startupScript = ""; startupScript = "";
enablePHP = false; enablePHP = false;
enablePerl = false;
phpOptions = ""; phpOptions = "";
options = {}; options = {};
documentRoot = null; documentRoot = null;
@ -355,6 +358,7 @@ let
++ map (name: {inherit name; path = "${httpd}/modules/mod_${name}.so";}) apacheModules ++ map (name: {inherit name; path = "${httpd}/modules/mod_${name}.so";}) apacheModules
++ optional mainCfg.enableMellon { name = "auth_mellon"; path = "${pkgs.apacheHttpdPackages.mod_auth_mellon}/modules/mod_auth_mellon.so"; } ++ optional mainCfg.enableMellon { name = "auth_mellon"; path = "${pkgs.apacheHttpdPackages.mod_auth_mellon}/modules/mod_auth_mellon.so"; }
++ optional enablePHP { name = "php${phpMajorVersion}"; path = "${php}/modules/libphp${phpMajorVersion}.so"; } ++ optional enablePHP { name = "php${phpMajorVersion}"; path = "${php}/modules/libphp${phpMajorVersion}.so"; }
++ optional enablePerl { name = "perl"; path = "${mod_perl}/modules/mod_perl.so"; }
++ concatMap (svc: svc.extraModules) allSubservices ++ concatMap (svc: svc.extraModules) allSubservices
++ extraForeignModules; ++ extraForeignModules;
in concatMapStrings load allModules in concatMapStrings load allModules
@ -415,6 +419,8 @@ let
enablePHP = mainCfg.enablePHP || any (svc: svc.enablePHP) allSubservices; enablePHP = mainCfg.enablePHP || any (svc: svc.enablePHP) allSubservices;
enablePerl = mainCfg.enablePerl || any (svc: svc.enablePerl) allSubservices;
# Generate the PHP configuration file. Should probably be factored # Generate the PHP configuration file. Should probably be factored
# out into a separate module. # out into a separate module.
@ -579,6 +585,12 @@ in
''; '';
}; };
enablePerl = mkOption {
type = types.bool;
default = false;
description = "Whether to enable the Perl module (mod_perl).";
};
phpOptions = mkOption { phpOptions = mkOption {
type = types.lines; type = types.lines;
default = ""; default = "";
@ -697,13 +709,6 @@ in
''} ''}
mkdir -m 0700 -p ${mainCfg.logDir} mkdir -m 0700 -p ${mainCfg.logDir}
${optionalString (mainCfg.documentRoot != null)
''
# Create the document root directory if does not exists yet
mkdir -p ${mainCfg.documentRoot}
''
}
# Get rid of old semaphores. These tend to accumulate across # Get rid of old semaphores. These tend to accumulate across
# server restarts, eventually preventing it from restarting # server restarts, eventually preventing it from restarting
# successfully. # successfully.

View File

@ -99,7 +99,7 @@ in
makeSearchPathOutput "lib" "lib/${pkgs.python.libPrefix}/site-packages" makeSearchPathOutput "lib" "lib/${pkgs.python.libPrefix}/site-packages"
[ pkgs.mod_python [ pkgs.mod_python
pkgs.pythonPackages.trac pkgs.pythonPackages.trac
pkgs.setuptools pkgs.pythonPackages.setuptools
pkgs.pythonPackages.genshi pkgs.pythonPackages.genshi
pkgs.pythonPackages.psycopg2 pkgs.pythonPackages.psycopg2
subversion subversion

View File

@ -6,7 +6,7 @@ with lib;
let let
# Upgrading? We have a test! nix-build ./nixos/tests/wordpress.nix # Upgrading? We have a test! nix-build ./nixos/tests/wordpress.nix
version = "4.6.1"; version = "4.7.1";
fullversion = "${version}"; fullversion = "${version}";
# Our bare-bones wp-config.php file using the above settings # Our bare-bones wp-config.php file using the above settings
@ -75,7 +75,7 @@ let
owner = "WordPress"; owner = "WordPress";
repo = "WordPress"; repo = "WordPress";
rev = "${fullversion}"; rev = "${fullversion}";
sha256 = "0n82xgjg1ry2p73hhgpslnkdzrma5n6hxxq76s7qskkzj0qjfvpn"; sha256 = "1wb4f4zn55d23qi0whsfpbpcd4sjvzswgmni6f5rzrmlawq9ssgr";
}; };
installPhase = '' installPhase = ''
mkdir -p $out mkdir -p $out

View File

@ -39,6 +39,13 @@ in
type = types.path; type = types.path;
description = "The data directory, for storing certificates."; description = "The data directory, for storing certificates.";
}; };
package = mkOption {
default = pkgs.caddy;
defaultText = "pkgs.caddy";
type = types.package;
description = "Caddy package to use.";
};
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
@ -47,7 +54,7 @@ in
after = [ "network.target" ]; after = [ "network.target" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
serviceConfig = { serviceConfig = {
ExecStart = ''${pkgs.caddy.bin}/bin/caddy -conf=${configFile} \ ExecStart = ''${cfg.package.bin}/bin/caddy -conf=${configFile} \
-ca=${cfg.ca} -email=${cfg.email} ${optionalString cfg.agree "-agree"} -ca=${cfg.ca} -email=${cfg.email} ${optionalString cfg.agree "-agree"}
''; '';
Type = "simple"; Type = "simple";

View File

@ -191,9 +191,8 @@ in
virtualisation.docker = { virtualisation.docker = {
enable = true; enable = true;
# We need docker to listen on port 2375. # We need docker to listen on port 2375.
extraOptions = "-H tcp://127.0.0.1:2375 -H unix:///var/run/docker.sock"; listenOptions = ["127.0.0.1:2375" "/var/run/docker.sock"];
storageDriver = mkDefault "overlay"; storageDriver = mkDefault "overlay";
socketActivation = false;
}; };
users.extraUsers."lighttpd".extraGroups = [ "docker" ]; users.extraUsers."lighttpd".extraGroups = [ "docker" ];

View File

@ -10,6 +10,7 @@ let
sslCertificateKey = "/var/lib/acme/${vhostName}/key.pem"; sslCertificateKey = "/var/lib/acme/${vhostName}/key.pem";
}) })
) cfg.virtualHosts; ) cfg.virtualHosts;
enableIPv6 = config.networking.enableIPv6;
configFile = pkgs.writeText "nginx.conf" '' configFile = pkgs.writeText "nginx.conf" ''
user ${cfg.user} ${cfg.group}; user ${cfg.user} ${cfg.group};
@ -84,7 +85,7 @@ let
${optionalString cfg.statusPage '' ${optionalString cfg.statusPage ''
server { server {
listen 80; listen 80;
listen [::]:80; ${optionalString enableIPv6 "listen [::]:80;" }
server_name localhost; server_name localhost;
@ -92,7 +93,7 @@ let
stub_status on; stub_status on;
access_log off; access_log off;
allow 127.0.0.1; allow 127.0.0.1;
allow ::1; ${optionalString enableIPv6 "allow ::1;"}
deny all; deny all;
} }
} }
@ -116,7 +117,7 @@ let
ssl = vhost.enableSSL || vhost.forceSSL; ssl = vhost.enableSSL || vhost.forceSSL;
port = if vhost.port != null then vhost.port else (if ssl then 443 else 80); port = if vhost.port != null then vhost.port else (if ssl then 443 else 80);
listenString = toString port + optionalString ssl " ssl http2" listenString = toString port + optionalString ssl " ssl http2"
+ optionalString vhost.default " default"; + optionalString vhost.default " default_server";
acmeLocation = optionalString vhost.enableACME ('' acmeLocation = optionalString vhost.enableACME (''
location /.well-known/acme-challenge { location /.well-known/acme-challenge {
${optionalString (vhost.acmeFallbackHost != null) "try_files $uri @acme-fallback;"} ${optionalString (vhost.acmeFallbackHost != null) "try_files $uri @acme-fallback;"}
@ -132,8 +133,10 @@ let
in '' in ''
${optionalString vhost.forceSSL '' ${optionalString vhost.forceSSL ''
server { server {
listen 80 ${optionalString vhost.default "default"}; listen 80 ${optionalString vhost.default "default_server"};
listen [::]:80 ${optionalString vhost.default "default"}; ${optionalString enableIPv6
''listen [::]:80 ${optionalString vhost.default "default_server"};''
}
server_name ${serverName} ${concatStringsSep " " vhost.serverAliases}; server_name ${serverName} ${concatStringsSep " " vhost.serverAliases};
${acmeLocation} ${acmeLocation}
@ -145,7 +148,7 @@ let
server { server {
listen ${listenString}; listen ${listenString};
listen [::]:${listenString}; ${optionalString enableIPv6 "listen [::]:${listenString};"}
server_name ${serverName} ${concatStringsSep " " vhost.serverAliases}; server_name ${serverName} ${concatStringsSep " " vhost.serverAliases};
${acmeLocation} ${acmeLocation}

View File

@ -123,6 +123,7 @@ in {
services.packagekit.enable = mkDefault true; services.packagekit.enable = mkDefault true;
hardware.bluetooth.enable = mkDefault true; hardware.bluetooth.enable = mkDefault true;
services.xserver.libinput.enable = mkDefault true; # for controlling touchpad settings via gnome control center services.xserver.libinput.enable = mkDefault true; # for controlling touchpad settings via gnome control center
services.udev.packages = [ pkgs.gnome3.gnome_settings_daemon ];
fonts.fonts = [ pkgs.dejavu_fonts pkgs.cantarell_fonts ]; fonts.fonts = [ pkgs.dejavu_fonts pkgs.cantarell_fonts ];

View File

@ -31,12 +31,25 @@ in
''; '';
}; };
extraPackages = mkOption {
type = types.listOf types.package;
default = [];
description = ''
KDE packages that need to be installed system-wide.
'';
};
}; };
}; };
config = mkIf (xcfg.enable && cfg.enable) { config = mkMerge [
(mkIf (cfg.extraPackages != []) {
environment.systemPackages = [ (kde5.kdeWrapper cfg.extraPackages) ];
})
(mkIf (xcfg.enable && cfg.enable) {
warnings = optional config.services.xserver.desktopManager.kde4.enable warnings = optional config.services.xserver.desktopManager.kde4.enable
"KDE 4 should not be enabled at the same time as KDE 5"; "KDE 4 should not be enabled at the same time as KDE 5";
@ -120,7 +133,6 @@ in
kde5.kdecoration kde5.kdecoration
kde5.kdeplasma-addons kde5.kdeplasma-addons
kde5.kgamma5 kde5.kgamma5
kde5.khelpcenter
kde5.khotkeys kde5.khotkeys
kde5.kinfocenter kde5.kinfocenter
kde5.kmenuedit kde5.kmenuedit
@ -133,7 +145,6 @@ in
kde5.libkscreen kde5.libkscreen
kde5.libksysguard kde5.libksysguard
kde5.milou kde5.milou
kde5.oxygen
kde5.plasma-integration kde5.plasma-integration
kde5.polkit-kde-agent kde5.polkit-kde-agent
kde5.systemsettings kde5.systemsettings
@ -142,12 +153,10 @@ in
kde5.plasma-workspace kde5.plasma-workspace
kde5.plasma-workspace-wallpapers kde5.plasma-workspace-wallpapers
kde5.dolphin
kde5.dolphin-plugins kde5.dolphin-plugins
kde5.ffmpegthumbs kde5.ffmpegthumbs
kde5.kdegraphics-thumbnailers kde5.kdegraphics-thumbnailers
kde5.kio-extras kde5.kio-extras
kde5.konsole
kde5.print-manager kde5.print-manager
# Install Breeze icons if available # Install Breeze icons if available
@ -179,6 +188,15 @@ in
++ lib.optional config.services.colord.enable pkgs.colord-kde ++ lib.optional config.services.colord.enable pkgs.colord-kde
++ lib.optionals config.services.samba.enable [ kde5.kdenetwork-filesharing pkgs.samba ]; ++ lib.optionals config.services.samba.enable [ kde5.kdenetwork-filesharing pkgs.samba ];
services.xserver.desktopManager.kde5.extraPackages =
[
kde5.khelpcenter
kde5.oxygen
kde5.dolphin
kde5.konsole
];
environment.pathsToLink = [ "/share" ]; environment.pathsToLink = [ "/share" ];
environment.etc = singleton { environment.etc = singleton {
@ -186,9 +204,9 @@ in
target = "X11/xkb"; target = "X11/xkb";
}; };
# Enable GTK applications to load SVG icons
environment.variables = environment.variables =
{ {
# Enable GTK applications to load SVG icons
GST_PLUGIN_SYSTEM_PATH_1_0 = GST_PLUGIN_SYSTEM_PATH_1_0 =
lib.makeSearchPath "/lib/gstreamer-1.0" lib.makeSearchPath "/lib/gstreamer-1.0"
(builtins.map (pkg: pkg.out) (with pkgs.gst_all_1; [ (builtins.map (pkg: pkg.out) (with pkgs.gst_all_1; [
@ -211,6 +229,8 @@ in
# Enable helpful DBus services. # Enable helpful DBus services.
services.udisks2.enable = true; services.udisks2.enable = true;
services.upower.enable = config.powerManagement.enable; services.upower.enable = config.powerManagement.enable;
services.dbus.packages =
mkIf config.services.printing.enable [ pkgs.system-config-printer ];
# Extra UDEV rules used by Solid # Extra UDEV rules used by Solid
services.udev.packages = [ services.udev.packages = [
@ -229,6 +249,7 @@ in
security.pam.services.kde = { allowNullPassword = true; }; security.pam.services.kde = { allowNullPassword = true; };
}; })
];
} }

View File

@ -19,7 +19,7 @@ let cfg = config.services.xserver.synaptics;
Option "TapButton3" "0" Option "TapButton3" "0"
''; '';
pkg = pkgs.xorg.xf86inputsynaptics; pkg = pkgs.xorg.xf86inputsynaptics;
etcFile = "X11/xorg.conf.d/50-synaptics.conf"; etcFile = "X11/xorg.conf.d/70-synaptics.conf";
in { in {
options = { options = {
@ -172,7 +172,7 @@ in {
services.xserver.modules = [ pkg.out ]; services.xserver.modules = [ pkg.out ];
environment.etc."${etcFile}".source = environment.etc."${etcFile}".source =
"${pkg.out}/share/X11/xorg.conf.d/50-synaptics.conf"; "${pkg.out}/share/X11/xorg.conf.d/70-synaptics.conf";
environment.systemPackages = [ pkg ]; environment.systemPackages = [ pkg ];

View File

@ -22,7 +22,7 @@ in
which will make Xorg reconfigure the device ? which will make Xorg reconfigure the device ?
If you're not satisfied by the default behaviour you can override If you're not satisfied by the default behaviour you can override
<option>environment.etc."X11/xorg.conf.d/50-wacom.conf"</option> in <option>environment.etc."X11/xorg.conf.d/70-wacom.conf"</option> in
configuration.nix easily. configuration.nix easily.
''; '';
}; };
@ -40,7 +40,7 @@ in
services.udev.packages = [ pkgs.xf86_input_wacom ]; services.udev.packages = [ pkgs.xf86_input_wacom ];
environment.etc."X11/xorg.conf.d/50-wacom.conf".source = "${pkgs.xf86_input_wacom}/share/X11/xorg.conf.d/50-wacom.conf"; environment.etc."X11/xorg.conf.d/70-wacom.conf".source = "${pkgs.xf86_input_wacom}/share/X11/xorg.conf.d/70-wacom.conf";
}; };

View File

@ -41,7 +41,7 @@ with lib;
{ description = "Terminal Server"; { description = "Terminal Server";
path = path =
[ pkgs.xorgserver.out pkgs.gawk pkgs.which pkgs.openssl pkgs.xorg.xauth [ pkgs.xorg.xorgserver.out pkgs.gawk pkgs.which pkgs.openssl pkgs.xorg.xauth
pkgs.nettools pkgs.shadow pkgs.procps pkgs.utillinux pkgs.bash pkgs.nettools pkgs.shadow pkgs.procps pkgs.utillinux pkgs.bash
]; ];

View File

@ -318,6 +318,8 @@ mountFS() {
[ "$mountPoint" == "/" ] && [ "$mountPoint" == "/" ] &&
[ -f "/mnt-root/etc/NIXOS_LUSTRATE" ] && [ -f "/mnt-root/etc/NIXOS_LUSTRATE" ] &&
lustrateRoot "/mnt-root" lustrateRoot "/mnt-root"
true
} }
lustrateRoot () { lustrateRoot () {

View File

@ -22,12 +22,18 @@ let
kernel = config.boot.kernelPackages; kernel = config.boot.kernelPackages;
splKernelPkg = kernel.spl; packages = if config.boot.zfs.enableUnstable then {
zfsKernelPkg = kernel.zfs; spl = kernel.splUnstable;
zfsUserPkg = pkgs.zfs; zfs = kernel.zfsUnstable;
zfsUser = pkgs.zfsUnstable;
} else {
spl = kernel.spl;
zfs = kernel.zfs;
zfsUser = pkgs.zfs;
};
autosnapPkg = pkgs.zfstools.override { autosnapPkg = pkgs.zfstools.override {
zfs = zfsUserPkg; zfs = packages.zfsUser;
}; };
zfsAutoSnap = "${autosnapPkg}/bin/zfs-auto-snapshot"; zfsAutoSnap = "${autosnapPkg}/bin/zfs-auto-snapshot";
@ -54,6 +60,18 @@ in
options = { options = {
boot.zfs = { boot.zfs = {
enableUnstable = mkOption {
type = types.bool;
default = false;
description = ''
Use the unstable zfs package. This might be an option, if the latest
kernel is not yet supported by a published release of ZFS. Enabling
this option will install a development version of ZFS on Linux. The
version will have already passed an extensive test suite, but it is
more likely to hit an undiscovered bug compared to running a released
version of ZFS on Linux.
'';
};
extraPools = mkOption { extraPools = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
@ -218,16 +236,16 @@ in
boot = { boot = {
kernelModules = [ "spl" "zfs" ] ; kernelModules = [ "spl" "zfs" ] ;
extraModulePackages = [ splKernelPkg zfsKernelPkg ]; extraModulePackages = with packages; [ spl zfs ];
}; };
boot.initrd = mkIf inInitrd { boot.initrd = mkIf inInitrd {
kernelModules = [ "spl" "zfs" ]; kernelModules = [ "spl" "zfs" ];
extraUtilsCommands = extraUtilsCommands =
'' ''
copy_bin_and_libs ${zfsUserPkg}/sbin/zfs copy_bin_and_libs ${packages.zfsUser}/sbin/zfs
copy_bin_and_libs ${zfsUserPkg}/sbin/zdb copy_bin_and_libs ${packages.zfsUser}/sbin/zdb
copy_bin_and_libs ${zfsUserPkg}/sbin/zpool copy_bin_and_libs ${packages.zfsUser}/sbin/zpool
''; '';
extraUtilsCommandsTest = mkIf inInitrd extraUtilsCommandsTest = mkIf inInitrd
'' ''
@ -264,14 +282,14 @@ in
zfsSupport = true; zfsSupport = true;
}; };
environment.etc."zfs/zed.d".source = "${zfsUserPkg}/etc/zfs/zed.d/*"; environment.etc."zfs/zed.d".source = "${packages.zfsUser}/etc/zfs/zed.d/*";
system.fsPackages = [ zfsUserPkg ]; # XXX: needed? zfs doesn't have (need) a fsck system.fsPackages = [ packages.zfsUser ]; # XXX: needed? zfs doesn't have (need) a fsck
environment.systemPackages = [ zfsUserPkg ] environment.systemPackages = [ packages.zfsUser ]
++ optional enableAutoSnapshots autosnapPkg; # so the user can run the command to see flags ++ optional enableAutoSnapshots autosnapPkg; # so the user can run the command to see flags
services.udev.packages = [ zfsUserPkg ]; # to hook zvol naming, etc. services.udev.packages = [ packages.zfsUser ]; # to hook zvol naming, etc.
systemd.packages = [ zfsUserPkg ]; systemd.packages = [ packages.zfsUser ];
systemd.services = let systemd.services = let
getPoolFilesystems = pool: getPoolFilesystems = pool:
@ -298,7 +316,7 @@ in
RemainAfterExit = true; RemainAfterExit = true;
}; };
script = '' script = ''
zpool_cmd="${zfsUserPkg}/sbin/zpool" zpool_cmd="${packages.zfsUser}/sbin/zpool"
("$zpool_cmd" list "${pool}" >/dev/null) || "$zpool_cmd" import -d ${cfgZfs.devNodes} -N ${optionalString cfgZfs.forceImportAll "-f"} "${pool}" ("$zpool_cmd" list "${pool}" >/dev/null) || "$zpool_cmd" import -d ${cfgZfs.devNodes} -N ${optionalString cfgZfs.forceImportAll "-f"} "${pool}"
''; '';
}; };
@ -314,7 +332,7 @@ in
RemainAfterExit = true; RemainAfterExit = true;
}; };
script = '' script = ''
${zfsUserPkg}/sbin/zfs set nixos:shutdown-time="$(date)" "${pool}" ${packages.zfsUser}/sbin/zfs set nixos:shutdown-time="$(date)" "${pool}"
''; '';
}; };

View File

@ -910,11 +910,8 @@ in
domainname "${cfg.domain}" domainname "${cfg.domain}"
''; '';
environment.etc = mkIf (cfg.hostId != null) environment.etc."hostid" = mkIf (cfg.hostId != null)
[ { source = pkgs.runCommand "gen-hostid" {} ''
{
target = "hostid";
source = pkgs.runCommand "gen-hostid" {} ''
hi="${cfg.hostId}" hi="${cfg.hostId}"
${if pkgs.stdenv.isBigEndian then '' ${if pkgs.stdenv.isBigEndian then ''
echo -ne "\x''${hi:0:2}\x''${hi:2:2}\x''${hi:4:2}\x''${hi:6:2}" > $out echo -ne "\x''${hi:0:2}\x''${hi:2:2}\x''${hi:4:2}\x''${hi:6:2}" > $out
@ -922,8 +919,14 @@ in
echo -ne "\x''${hi:6:2}\x''${hi:4:2}\x''${hi:2:2}\x''${hi:0:2}" > $out echo -ne "\x''${hi:6:2}\x''${hi:4:2}\x''${hi:2:2}\x''${hi:0:2}" > $out
''} ''}
''; '';
} };
];
# static hostname configuration needed for hostnamectl and the
# org.freedesktop.hostname1 dbus service (both provided by systemd)
environment.etc."hostname" = mkIf (cfg.hostName != "")
{
text = cfg.hostName + "\n";
};
environment.systemPackages = environment.systemPackages =
[ pkgs.host [ pkgs.host

View File

@ -94,7 +94,6 @@ let cfg = config.ec2; in
elif [ "$fsType" = ext3 ]; then elif [ "$fsType" = ext3 ]; then
mp="/disk$diskNr" mp="/disk$diskNr"
diskNr=$((diskNr + 1)) diskNr=$((diskNr + 1))
echo "mounting $device on $mp..."
if mountFS "$device" "$mp" "" ext3; then if mountFS "$device" "$mp" "" ext3; then
if [ -z "$diskForUnionfs" ]; then diskForUnionfs="$mp"; fi if [ -z "$diskForUnionfs" ]; then diskForUnionfs="$mp"; fi
fi fi

View File

@ -28,16 +28,42 @@ in
<command>docker</command> command line tool. <command>docker</command> command line tool.
''; '';
}; };
socketActivation =
listenOptions =
mkOption {
type = types.listOf types.str;
default = ["/var/run/docker.sock"];
description =
''
A list of unix and tcp docker should listen to. The format follows
ListenStream as described in systemd.socket(5).
'';
};
enableOnBoot =
mkOption { mkOption {
type = types.bool; type = types.bool;
default = true; default = true;
description = description =
'' ''
This option enables docker with socket activation. I.e. docker will When enabled dockerd is started on boot. This is required for
start when first called by client. container, which are created with the
<literal>--restart=always</literal> flag, to work. If this option is
disabled, docker might be started on demand by socket activation.
''; '';
}; };
liveRestore =
mkOption {
type = types.bool;
default = true;
description =
''
Allow dockerd to be restarted without affecting running container.
This option is incompatible with docker swarm.
'';
};
storageDriver = storageDriver =
mkOption { mkOption {
type = types.nullOr (types.enum ["aufs" "btrfs" "devicemapper" "overlay" "overlay2" "zfs"]); type = types.nullOr (types.enum ["aufs" "btrfs" "devicemapper" "overlay" "overlay2" "zfs"]);
@ -69,69 +95,43 @@ in
<command>docker</command> daemon. <command>docker</command> daemon.
''; '';
}; };
postStart =
mkOption {
type = types.lines;
default = ''
while ! [ -e /var/run/docker.sock ]; do
sleep 0.1
done
'';
description = ''
The postStart phase of the systemd service. You may need to
override this if you are passing in flags to docker which
don't cause the socket file to be created. This option is ignored
if socket activation is used.
'';
};
}; };
###### implementation ###### implementation
config = mkIf cfg.enable (mkMerge [ config = mkIf cfg.enable (mkMerge [{
{ environment.systemPackages = [ pkgs.docker ]; environment.systemPackages = [ pkgs.docker ];
users.extraGroups.docker.gid = config.ids.gids.docker; users.extraGroups.docker.gid = config.ids.gids.docker;
systemd.packages = [ pkgs.docker ];
systemd.services.docker = { systemd.services.docker = {
description = "Docker Application Container Engine"; wantedBy = optional cfg.enableOnBoot "multi-user.target";
wantedBy = optional (!cfg.socketActivation) "multi-user.target";
after = [ "network.target" ] ++ (optional cfg.socketActivation "docker.socket") ;
requires = optional cfg.socketActivation "docker.socket";
serviceConfig = { serviceConfig = {
ExecStart = ''${pkgs.docker}/bin/dockerd \ ExecStart = [
--group=docker --log-driver=${cfg.logDriver} \ ""
''
${pkgs.docker}/bin/dockerd \
--group=docker \
--host=fd:// \
--log-driver=${cfg.logDriver} \
${optionalString (cfg.storageDriver != null) "--storage-driver=${cfg.storageDriver}"} \ ${optionalString (cfg.storageDriver != null) "--storage-driver=${cfg.storageDriver}"} \
${optionalString cfg.socketActivation "--host=fd://"} \ ${optionalString cfg.liveRestore "--live-restore" } \
${cfg.extraOptions} ${cfg.extraOptions}
''; ''];
# I'm not sure if that limits aren't too high, but it's what ExecReload=[
# goes in config bundled with docker itself ""
LimitNOFILE = 1048576; "${pkgs.procps}/bin/kill -s HUP $MAINPID"
LimitNPROC = 1048576; ];
} // proxy_env; } // proxy_env;
path = [ pkgs.kmod ] ++ (optional (cfg.storageDriver == "zfs") pkgs.zfs); path = [ pkgs.kmod ] ++ (optional (cfg.storageDriver == "zfs") pkgs.zfs);
postStart = if cfg.socketActivation then "" else cfg.postStart;
# Presumably some containers are running we don't want to interrupt
restartIfChanged = false;
}; };
systemd.sockets.docker.socketConfig.ListenStream = cfg.listenOptions;
} }
(mkIf cfg.socketActivation {
systemd.sockets.docker = {
description = "Docker Socket for the API";
wantedBy = [ "sockets.target" ];
socketConfig = {
ListenStream = "/var/run/docker.sock";
SocketMode = "0660";
SocketUser = "root";
SocketGroup = "docker";
};
};
})
]); ]);
imports = [
(mkRemovedOptionModule ["virtualisation" "docker" "socketActivation"] "This option was removed in favor of starting docker at boot")
];
} }

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