Merge branch 'master' of https://github.com/nixos/nixpkgs into tarball-closureinfo

This commit is contained in:
Ding Xiang Fei 2018-11-14 12:32:28 +08:00
commit ceececbd04
1221 changed files with 32193 additions and 19482 deletions

31
.github/CODEOWNERS vendored
View File

@ -12,7 +12,7 @@
# Libraries # Libraries
/lib @edolstra @nbp /lib @edolstra @nbp
/lib/systems @nbp @ericson2314 /lib/systems @nbp @ericson2314 @matthewbauer
/lib/generators.nix @edolstra @nbp @Profpatsch /lib/generators.nix @edolstra @nbp @Profpatsch
/lib/debug.nix @edolstra @nbp @Profpatsch /lib/debug.nix @edolstra @nbp @Profpatsch
@ -20,9 +20,11 @@
/default.nix @nbp /default.nix @nbp
/pkgs/top-level/default.nix @nbp @Ericson2314 /pkgs/top-level/default.nix @nbp @Ericson2314
/pkgs/top-level/impure.nix @nbp @Ericson2314 /pkgs/top-level/impure.nix @nbp @Ericson2314
/pkgs/top-level/stage.nix @nbp @Ericson2314 /pkgs/top-level/stage.nix @nbp @Ericson2314 @matthewbauer
/pkgs/stdenv/generic @Ericson2314 /pkgs/top-level/splice.nix @Ericson2314 @matthewbauer
/pkgs/stdenv/cross @Ericson2314 /pkgs/top-level/release-cross.nix @Ericson2314 @matthewbauer
/pkgs/stdenv/generic @Ericson2314 @matthewbauer
/pkgs/stdenv/cross @Ericson2314 @matthewbauer
/pkgs/build-support/cc-wrapper @Ericson2314 @orivej /pkgs/build-support/cc-wrapper @Ericson2314 @orivej
/pkgs/build-support/bintools-wrapper @Ericson2314 @orivej /pkgs/build-support/bintools-wrapper @Ericson2314 @orivej
/pkgs/build-support/setup-hooks @Ericson2314 /pkgs/build-support/setup-hooks @Ericson2314
@ -45,6 +47,9 @@
/nixos/doc/manual/man-nixos-option.xml @nbp /nixos/doc/manual/man-nixos-option.xml @nbp
/nixos/modules/installer/tools/nixos-option.sh @nbp /nixos/modules/installer/tools/nixos-option.sh @nbp
# NixOS modules
/nixos/modules @Infinisil
# Python-related code and docs # Python-related code and docs
/maintainers/scripts/update-python-libraries @FRidh /maintainers/scripts/update-python-libraries @FRidh
/pkgs/top-level/python-packages.nix @FRidh /pkgs/top-level/python-packages.nix @FRidh
@ -74,6 +79,14 @@
/pkgs/stdenv/darwin @NixOS/darwin-maintainers /pkgs/stdenv/darwin @NixOS/darwin-maintainers
/pkgs/os-specific/darwin @NixOS/darwin-maintainers /pkgs/os-specific/darwin @NixOS/darwin-maintainers
# C compilers
/pkgs/development/compilers/gcc @matthewbauer
/pkgs/development/compilers/llvm @matthewbauer
# Compatibility stuff
/pkgs/top-level/unix-tools.nix @matthewbauer
/pkgs/development/tools/xcbuild @matthewbauer
# Beam-related (Erlang, Elixir, LFE, etc) # Beam-related (Erlang, Elixir, LFE, etc)
/pkgs/development/beam-modules @gleber /pkgs/development/beam-modules @gleber
/pkgs/development/interpreters/erlang @gleber /pkgs/development/interpreters/erlang @gleber
@ -97,3 +110,13 @@
/pkgs/desktops/plasma-5 @ttuegel /pkgs/desktops/plasma-5 @ttuegel
/pkgs/development/libraries/kde-frameworks @ttuegel /pkgs/development/libraries/kde-frameworks @ttuegel
/pkgs/development/libraries/qt-5 @ttuegel /pkgs/development/libraries/qt-5 @ttuegel
# PostgreSQL and related stuff
/pkgs/servers/sql/postgresql @thoughtpolice
/nixos/modules/services/databases/postgresql.xml @thoughtpolice
/nixos/modules/services/databases/postgresql.nix @thoughtpolice
/nixos/tests/postgresql.nix @thoughtpolice
# Dhall
/pkgs/development/dhall-modules @Gabriel439 @Profpatsch
/pkgs/development/interpreters/dhall @Gabriel439 @Profpatsch

View File

@ -842,9 +842,12 @@ src = fetchFromGitHub {
owner = "NixOS"; owner = "NixOS";
repo = "nix"; repo = "nix";
rev = "1f795f9f44607cc5bec70d1300150bfefcef2aae"; rev = "1f795f9f44607cc5bec70d1300150bfefcef2aae";
sha256 = "04yri911rj9j19qqqn6m82266fl05pz98inasni0vxr1cf1gdgv9"; sha256 = "1i2yxndxb6yc9l6c99pypbd92lfq5aac4klq7y2v93c9qvx2cgpc";
} }
</programlisting> </programlisting>
Find the value to put as <literal>sha256</literal> by running
<literal>nix run -f '&lt;nixpkgs&gt;' nix-prefetch-github -c nix-prefetch-github --rev 1f795f9f44607cc5bec70d1300150bfefcef2aae NixOS nix</literal>
or <literal>nix-prefetch-url --unpack https://github.com/NixOS/nix/archive/1f795f9f44607cc5bec70d1300150bfefcef2aae.tar.gz</literal>.
</para> </para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>

View File

@ -19,6 +19,7 @@
<xi:include href="java.xml" /> <xi:include href="java.xml" />
<xi:include href="lua.xml" /> <xi:include href="lua.xml" />
<xi:include href="node.section.xml" /> <xi:include href="node.section.xml" />
<xi:include href="ocaml.xml" />
<xi:include href="perl.xml" /> <xi:include href="perl.xml" />
<xi:include href="python.section.xml" /> <xi:include href="python.section.xml" />
<xi:include href="qt.xml" /> <xi:include href="qt.xml" />

View File

@ -0,0 +1,99 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="sec-language-ocaml">
<title>OCaml</title>
<para>
OCaml libraries should be installed in
<literal>$(out)/lib/ocaml/${ocaml.version}/site-lib/</literal>. Such
directories are automatically added to the <literal>$OCAMLPATH</literal>
environment variable when building another package that depends on them
or when opening a <literal>nix-shell</literal>.
</para>
<para>
Given that most of the OCaml ecosystem is now built with dune,
nixpkgs includes a convenience build support function called
<literal>buildDunePackage</literal> that will build an OCaml package
using dune, OCaml and findlib and any additional dependencies provided
as <literal>buildInputs</literal> or <literal>propagatedBuildInputs</literal>.
</para>
<para>
Here is a simple package example. It defines an (optional) attribute
<literal>minimumOCamlVersion</literal> that will be used to throw a
descriptive evaluation error if building with an older OCaml is attempted.
It uses the <literal>fetchFromGitHub</literal> fetcher to get its source.
It sets the <literal>doCheck</literal> (optional) attribute to
<literal>true</literal> which means that tests will be run with
<literal>dune runtest -p angstrom</literal> after the build
(<literal>dune build -p angstrom</literal>) is complete.
It uses <literal>alcotest</literal> as a build input (because it is needed
to run the tests) and <literal>bigstringaf</literal> and
<literal>result</literal> as propagated build inputs (thus they will also
be available to libraries depending on this library).
The library will be installed using the <literal>angstrom.install</literal>
file that dune generates.
</para>
<programlisting>
{ stdenv, fetchFromGitHub, buildDunePackage, alcotest, result, bigstringaf }:
buildDunePackage rec {
pname = "angstrom";
version = "0.10.0";
minimumOCamlVersion = "4.03";
src = fetchFromGitHub {
owner = "inhabitedtype";
repo = pname;
rev = version;
sha256 = "0lh6024yf9ds0nh9i93r9m6p5psi8nvrqxl5x7jwl13zb0r9xfpw";
};
buildInputs = [ alcotest ];
propagatedBuildInputs = [ bigstringaf result ];
doCheck = true;
meta = {
homepage = https://github.com/inhabitedtype/angstrom;
description = "OCaml parser combinators built for speed and memory efficiency";
license = stdenv.lib.licenses.bsd3;
maintainers = with stdenv.lib.maintainers; [ sternenseemann ];
};
}
</programlisting>
<para>
Here is a second example, this time using a source archive generated with
<literal>dune-release</literal>. It is a good idea to use this archive when
it is available as it will usually contain substituted variables such as a
<literal>%%VERSION%%</literal> field. This library does not depend
on any other OCaml library and no tests are run after building it.
</para>
<programlisting>
{ stdenv, fetchurl, buildDunePackage }:
buildDunePackage rec {
pname = "wtf8";
version = "1.0.1";
minimumOCamlVersion = "4.01";
src = fetchurl {
url = "https://github.com/flowtype/ocaml-${pname}/releases/download/v${version}/${pname}-${version}.tbz";
sha256 = "1msg3vycd3k8qqj61sc23qks541cxpb97vrnrvrhjnqxsqnh6ygq";
};
meta = with stdenv.lib; {
homepage = https://github.com/flowtype/ocaml-wtf8;
description = "WTF-8 is a superset of UTF-8 that allows unpaired surrogates.";
license = licenses.mit;
maintainers = [ maintainers.eqyiel ];
};
}
</programlisting>
</section>

View File

@ -483,12 +483,12 @@ and in this case the `python35` interpreter is automatically used.
### Interpreters ### Interpreters
Versions 2.7, 3.4, 3.5, 3.6 and 3.7 of the CPython interpreter are available as Versions 2.7, 3.5, 3.6 and 3.7 of the CPython interpreter are available as
respectively `python27`, `python34`, `python35` and `python36`. The PyPy interpreter respectively `python27`, `python35`, `python36`, and `python37`. The PyPy
is available as `pypy`. The aliases `python2` and `python3` correspond to respectively `python27` and interpreter is available as `pypy`. The aliases `python2` and `python3`
`python35`. The default interpreter, `python`, maps to `python2`. correspond to respectively `python27` and `python36`. The default interpreter,
The Nix expressions for the interpreters can be found in `python`, maps to `python2`. The Nix expressions for the interpreters can be
`pkgs/development/interpreters/python`. found in `pkgs/development/interpreters/python`.
All packages depending on any Python interpreter get appended All packages depending on any Python interpreter get appended
`out/{python.sitePackages}` to `$PYTHONPATH` if such directory `out/{python.sitePackages}` to `$PYTHONPATH` if such directory
@ -507,7 +507,7 @@ Each interpreter has the following attributes:
- `buildEnv`. Function to build python interpreter environments with extra packages bundled together. See section *python.buildEnv function* for usage and documentation. - `buildEnv`. Function to build python interpreter environments with extra packages bundled together. See section *python.buildEnv function* for usage and documentation.
- `withPackages`. Simpler interface to `buildEnv`. See section *python.withPackages function* for usage and documentation. - `withPackages`. Simpler interface to `buildEnv`. See section *python.withPackages function* for usage and documentation.
- `sitePackages`. Alias for `lib/${libPrefix}/site-packages`. - `sitePackages`. Alias for `lib/${libPrefix}/site-packages`.
- `executable`. Name of the interpreter executable, e.g. `python3.4`. - `executable`. Name of the interpreter executable, e.g. `python3.7`.
- `pkgs`. Set of Python packages for that specific interpreter. The package set can be modified by overriding the interpreter and passing `packageOverrides`. - `pkgs`. Set of Python packages for that specific interpreter. The package set can be modified by overriding the interpreter and passing `packageOverrides`.
### Building packages and applications ### Building packages and applications
@ -529,7 +529,6 @@ attribute set is created for each available Python interpreter. The available
sets are sets are
* `pkgs.python27Packages` * `pkgs.python27Packages`
* `pkgs.python34Packages`
* `pkgs.python35Packages` * `pkgs.python35Packages`
* `pkgs.python36Packages` * `pkgs.python36Packages`
* `pkgs.python37Packages` * `pkgs.python37Packages`
@ -670,7 +669,7 @@ python3Packages.buildPythonApplication rec {
sha256 = "035w8gqql36zlan0xjrzz9j4lh9hs0qrsgnbyw07qs7lnkvbdv9x"; sha256 = "035w8gqql36zlan0xjrzz9j4lh9hs0qrsgnbyw07qs7lnkvbdv9x";
}; };
propagatedBuildInputs = with python3Packages; [ tornado_4 pythondaemon ]; propagatedBuildInputs = with python3Packages; [ tornado_4 python-daemon ];
meta = with lib; { meta = with lib; {
... ...
@ -837,7 +836,7 @@ community to help save time. No tool is preferred at the moment.
### Deterministic builds ### Deterministic builds
Python 2.7, 3.5 and 3.6 are now built deterministically and 3.4 mostly. The Python interpreters are now built deterministically.
Minor modifications had to be made to the interpreters in order to generate Minor modifications had to be made to the interpreters in order to generate
deterministic bytecode. This has security implications and is relevant for deterministic bytecode. This has security implications and is relevant for
those using Python in a `nix-shell`. those using Python in a `nix-shell`.

View File

@ -250,6 +250,60 @@ meta.platforms = stdenv.lib.platforms.linux;
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>
<varname>tests</varname>
</term>
<listitem>
<warning>
<para>
This attribute is special in that it is not actually under the
<literal>meta</literal> attribute set but rather under the
<literal>passthru</literal> attribute set. This is due to a current
limitation of Nix, and will change as soon as Nixpkgs will be able to
depend on a new enough version of Nix. See
<link xlink:href="https://github.com/NixOS/nix/issues/2532">the relevant
issue</link> for more details.
</para>
</warning>
<para>
An attribute set with as values tests. A test is a derivation, which
builds successfully when the test passes, and fails to build otherwise. A
derivation that is a test needs to have <literal>meta.timeout</literal>
defined.
</para>
<para>
The NixOS tests are available as <literal>nixosTests</literal> in
parameters of derivations. For instance, the OpenSMTPD derivation
includes lines similar to:
<programlisting>
{ /* ... */, nixosTests }:
{
# ...
passthru.tests = {
basic-functionality-and-dovecot-integration = nixosTests.opensmtpd;
};
}
</programlisting>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<varname>timeout</varname>
</term>
<listitem>
<para>
A timeout (in seconds) for building the derivation. If the derivation
takes longer than this time to build, it can fail due to breaking the
timeout. However, all computers do not have the same computing power,
hence some builders may decide to apply a multiplicative factor to this
value. When filling this value in, try to keep it approximately
consistent with other values already present in
<literal>nixpkgs</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term> <term>
<varname>hydraPlatforms</varname> <varname>hydraPlatforms</varname>

View File

@ -147,8 +147,8 @@ $ git add pkgs/development/libraries/libfoo/default.nix</screen>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
You can use <command>nix-prefetch-url</command> (or similar You can use <command>nix-prefetch-url</command>
nix-prefetch-git, etc) <replaceable>url</replaceable> to get the <replaceable>url</replaceable> to get the
SHA-256 hash of source distributions. There are similar commands as SHA-256 hash of source distributions. There are similar commands as
<command>nix-prefetch-git</command> and <command>nix-prefetch-git</command> and
<command>nix-prefetch-hg</command> available in <command>nix-prefetch-hg</command> available in

View File

@ -618,7 +618,7 @@ let f(h, h + 1, i) = i + h
</variablelist> </variablelist>
<variablelist> <variablelist>
<title>Variables affecting build properties</title> <title>Attributes affecting build properties</title>
<varlistentry> <varlistentry>
<term> <term>
<varname>enableParallelBuilding</varname> <varname>enableParallelBuilding</varname>
@ -637,21 +637,6 @@ let f(h, h + 1, i) = i + h
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>
<varname>preferLocalBuild</varname>
</term>
<listitem>
<para>
If set, specifies that the package is so lightweight in terms of build
operations (e.g. write a text file from a Nix string to the store) that
there's no need to look for it in binary caches -- it's faster to just
build it locally. It also tells Hydra and other facilities that this
package doesn't need to be exported in binary caches (noone would use it,
after all).
</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
<variablelist> <variablelist>

View File

@ -13,6 +13,11 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
* add it to this list. The URL mentioned above is a good source for inspiration. * add it to this list. The URL mentioned above is a good source for inspiration.
*/ */
abstyles = spdx {
spdxId = "Abstyles";
fullName = "Abstyles License";
};
afl21 = spdx { afl21 = spdx {
spdxId = "AFL-2.1"; spdxId = "AFL-2.1";
fullName = "Academic Free License v2.1"; fullName = "Academic Free License v2.1";
@ -400,6 +405,10 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
free = false; free = false;
}; };
jasper = spdx {
spdxId = "JasPer-2.0";
fullName = "JasPer License";
};
lgpl2 = spdx { lgpl2 = spdx {
spdxId = "LGPL-2.0"; spdxId = "LGPL-2.0";

View File

@ -73,7 +73,7 @@ rec {
# Get the commit id of a git repo # Get the commit id of a git repo
# Example: commitIdFromGitRepo <nixpkgs/.git> # Example: commitIdFromGitRepo <nixpkgs/.git>
commitIdFromGitRepo = commitIdFromGitRepo =
let readCommitFromFile = path: file: let readCommitFromFile = file: path:
with builtins; with builtins;
let fileName = toString path + "/" + file; let fileName = toString path + "/" + file;
packedRefsName = toString path + "/packed-refs"; packedRefsName = toString path + "/packed-refs";
@ -85,7 +85,7 @@ rec {
matchRef = match "^ref: (.*)$" fileContent; matchRef = match "^ref: (.*)$" fileContent;
in if isNull matchRef in if isNull matchRef
then fileContent then fileContent
else readCommitFromFile path (lib.head matchRef) else readCommitFromFile (lib.head matchRef) path
# Sometimes, the file isn't there at all and has been packed away in the # Sometimes, the file isn't there at all and has been packed away in the
# packed-refs file, so we have to grep through it: # packed-refs file, so we have to grep through it:
else if lib.pathExists packedRefsName else if lib.pathExists packedRefsName
@ -96,7 +96,7 @@ rec {
then throw ("Could not find " + file + " in " + packedRefsName) then throw ("Could not find " + file + " in " + packedRefsName)
else lib.head matchRef else lib.head matchRef
else throw ("Not a .git directory: " + path); else throw ("Not a .git directory: " + path);
in lib.flip readCommitFromFile "HEAD"; in readCommitFromFile "HEAD";
pathHasContext = builtins.hasContext or (lib.hasPrefix builtins.storeDir); pathHasContext = builtins.hasContext or (lib.hasPrefix builtins.storeDir);

View File

@ -32,6 +32,7 @@ rec {
else if final.isUClibc then "uclibc" else if final.isUClibc then "uclibc"
else if final.isAndroid then "bionic" else if final.isAndroid then "bionic"
else if final.isLinux /* default */ then "glibc" else if final.isLinux /* default */ then "glibc"
else if final.isAvr then "avrlibc"
# TODO(@Ericson2314) think more about other operating systems # TODO(@Ericson2314) think more about other operating systems
else "native/impure"; else "native/impure";
extensions = { extensions = {

View File

@ -99,6 +99,49 @@ rec {
riscv64 = riscv "64"; riscv64 = riscv "64";
riscv32 = riscv "32"; riscv32 = riscv "32";
avr = {
config = "avr";
};
arm-embedded = {
config = "arm-none-eabi";
libc = "newlib";
};
aarch64-embedded = {
config = "aarch64-none-elf";
libc = "newlib";
};
aarch64be-embedded = {
config = "aarch64_be-none-elf";
libc = "newlib";
};
ppc-embedded = {
config = "powerpc-none-eabi";
libc = "newlib";
};
ppcle-embedded = {
config = "powerpcle-none-eabi";
libc = "newlib";
};
alpha-embedded = {
config = "alpha-elf";
libc = "newlib";
};
i686-embedded = {
config = "i686-elf";
libc = "newlib";
};
x86_64-embedded = {
config = "x86_64-elf";
libc = "newlib";
};
# #
# Darwin # Darwin

View File

@ -19,6 +19,7 @@ rec {
isRiscV = { cpu = { family = "riscv"; }; }; isRiscV = { cpu = { family = "riscv"; }; };
isSparc = { cpu = { family = "sparc"; }; }; isSparc = { cpu = { family = "sparc"; }; };
isWasm = { cpu = { family = "wasm"; }; }; isWasm = { cpu = { family = "wasm"; }; };
isAvr = { cpu = { family = "avr"; }; };
is32bit = { cpu = { bits = 32; }; }; is32bit = { cpu = { bits = 32; }; };
is64bit = { cpu = { bits = 64; }; }; is64bit = { cpu = { bits = 64; }; };

View File

@ -80,6 +80,7 @@ rec {
armv8r = { bits = 32; significantByte = littleEndian; family = "arm"; version = "8"; }; armv8r = { bits = 32; significantByte = littleEndian; family = "arm"; version = "8"; };
armv8m = { bits = 32; significantByte = littleEndian; family = "arm"; version = "8"; }; armv8m = { bits = 32; significantByte = littleEndian; family = "arm"; version = "8"; };
aarch64 = { bits = 64; significantByte = littleEndian; family = "arm"; version = "8"; }; aarch64 = { bits = 64; significantByte = littleEndian; family = "arm"; version = "8"; };
aarch64_be = { bits = 64; significantByte = bigEndian; family = "arm"; version = "8"; };
i686 = { bits = 32; significantByte = littleEndian; family = "x86"; }; i686 = { bits = 32; significantByte = littleEndian; family = "x86"; };
x86_64 = { bits = 64; significantByte = littleEndian; family = "x86"; }; x86_64 = { bits = 64; significantByte = littleEndian; family = "x86"; };
@ -92,6 +93,7 @@ rec {
powerpc = { bits = 32; significantByte = bigEndian; family = "power"; }; powerpc = { bits = 32; significantByte = bigEndian; family = "power"; };
powerpc64 = { bits = 64; significantByte = bigEndian; family = "power"; }; powerpc64 = { bits = 64; significantByte = bigEndian; family = "power"; };
powerpc64le = { bits = 64; significantByte = littleEndian; family = "power"; }; powerpc64le = { bits = 64; significantByte = littleEndian; family = "power"; };
powerpcle = { bits = 32; significantByte = littleEndian; family = "power"; };
riscv32 = { bits = 32; significantByte = littleEndian; family = "riscv"; }; riscv32 = { bits = 32; significantByte = littleEndian; family = "riscv"; };
riscv64 = { bits = 64; significantByte = littleEndian; family = "riscv"; }; riscv64 = { bits = 64; significantByte = littleEndian; family = "riscv"; };
@ -101,6 +103,10 @@ rec {
wasm32 = { bits = 32; significantByte = littleEndian; family = "wasm"; }; wasm32 = { bits = 32; significantByte = littleEndian; family = "wasm"; };
wasm64 = { bits = 64; significantByte = littleEndian; family = "wasm"; }; wasm64 = { bits = 64; significantByte = littleEndian; family = "wasm"; };
alpha = { bits = 64; significantByte = littleEndian; family = "alpha"; };
avr = { bits = 8; family = "avr"; };
}; };
################################################################################ ################################################################################
@ -117,6 +123,7 @@ rec {
apple = {}; apple = {};
pc = {}; pc = {};
none = {};
unknown = {}; unknown = {};
}; };
@ -200,6 +207,7 @@ rec {
cygnus = {}; cygnus = {};
msvc = {}; msvc = {};
eabi = {}; eabi = {};
elf = {};
androideabi = {}; androideabi = {};
android = { android = {
@ -255,9 +263,16 @@ rec {
setType "system" components; setType "system" components;
mkSkeletonFromList = l: { mkSkeletonFromList = l: {
"1" = if elemAt l 0 == "avr"
then { cpu = elemAt l 0; kernel = "none"; abi = "unknown"; }
else throw "Target specification with 1 components is ambiguous";
"2" = # We only do 2-part hacks for things Nix already supports "2" = # We only do 2-part hacks for things Nix already supports
if elemAt l 1 == "cygwin" if elemAt l 1 == "cygwin"
then { cpu = elemAt l 0; kernel = "windows"; abi = "cygnus"; } then { cpu = elemAt l 0; kernel = "windows"; abi = "cygnus"; }
else if (elemAt l 1 == "eabi")
then { cpu = elemAt l 0; vendor = "none"; kernel = "none"; abi = elemAt l 1; }
else if (elemAt l 1 == "elf")
then { cpu = elemAt l 0; vendor = "none"; kernel = "none"; abi = elemAt l 1; }
else { cpu = elemAt l 0; kernel = elemAt l 1; }; else { cpu = elemAt l 0; kernel = elemAt l 1; };
"3" = # Awkwards hacks, beware! "3" = # Awkwards hacks, beware!
if elemAt l 1 == "apple" if elemAt l 1 == "apple"
@ -268,6 +283,10 @@ rec {
then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = "windows"; abi = "gnu"; } then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = "windows"; abi = "gnu"; }
else if hasPrefix "netbsd" (elemAt l 2) else if hasPrefix "netbsd" (elemAt l 2)
then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = elemAt l 2; } then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = elemAt l 2; }
else if (elemAt l 2 == "eabi")
then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = "none"; abi = elemAt l 2; }
else if (elemAt l 2 == "elf")
then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = "none"; abi = elemAt l 2; }
else throw "Target specification with 3 components is ambiguous"; else throw "Target specification with 3 components is ambiguous";
"4" = { cpu = elemAt l 0; vendor = elemAt l 1; kernel = elemAt l 2; abi = elemAt l 3; }; "4" = { cpu = elemAt l 0; vendor = elemAt l 1; kernel = elemAt l 2; abi = elemAt l 3; };
}.${toString (length l)} }.${toString (length l)}

View File

@ -471,6 +471,7 @@ rec {
"x86_64-linux" = pc64; "x86_64-linux" = pc64;
"armv5tel-linux" = sheevaplug; "armv5tel-linux" = sheevaplug;
"armv6l-linux" = raspberrypi; "armv6l-linux" = raspberrypi;
"armv7a-linux" = armv7l-hf-multiplatform;
"armv7l-linux" = armv7l-hf-multiplatform; "armv7l-linux" = armv7l-hf-multiplatform;
"aarch64-linux" = aarch64-multiplatform; "aarch64-linux" = aarch64-multiplatform;
"mipsel-linux" = fuloong2f_n32; "mipsel-linux" = fuloong2f_n32;

View File

@ -169,6 +169,9 @@ rec {
# s32 = sign 32 4294967296; # s32 = sign 32 4294967296;
}; };
# Alias of u16 for a port number
port = ints.u16;
float = mkOptionType rec { float = mkOptionType rec {
name = "float"; name = "float";
description = "floating point number"; description = "floating point number";

View File

@ -143,6 +143,11 @@
github = "ahmedtd"; github = "ahmedtd";
name = "Taahir Ahmed"; name = "Taahir Ahmed";
}; };
ahuzik = {
email = "ales.guzik@gmail.com";
github = "alesguzik";
name = "Ales Huzik";
};
aij = { aij = {
email = "aij+git@mrph.org"; email = "aij+git@mrph.org";
github = "aij"; github = "aij";
@ -211,6 +216,11 @@
github = "alunduil"; github = "alunduil";
name = "Alex Brandt"; name = "Alex Brandt";
}; };
amar1729 = {
email = "amar.paul16@gmail.com";
github = "amar1729";
name = "Amar Paul";
};
ambrop72 = { ambrop72 = {
email = "ambrop7@gmail.com"; email = "ambrop7@gmail.com";
github = "ambrop72"; github = "ambrop72";
@ -401,6 +411,11 @@
github = "AveryLychee"; github = "AveryLychee";
name = "Avery Lychee"; name = "Avery Lychee";
}; };
averelld = {
email = "averell+nixos@rxd4.com";
github = "averelld";
name = "averelld";
};
avnik = { avnik = {
email = "avn@avnik.info"; email = "avn@avnik.info";
github = "avnik"; github = "avnik";
@ -614,6 +629,11 @@
github = "bramd"; github = "bramd";
name = "Bram Duvigneau"; name = "Bram Duvigneau";
}; };
braydenjw = {
email = "nixpkgs@willenborg.ca";
github = "braydenjw";
name = "Brayden Willenborg";
};
brian-dawn = { brian-dawn = {
email = "brian.t.dawn@gmail.com"; email = "brian.t.dawn@gmail.com";
github = "brian-dawn"; github = "brian-dawn";
@ -952,6 +972,11 @@
github = "danielfullmer"; github = "danielfullmer";
name = "Daniel Fullmer"; name = "Daniel Fullmer";
}; };
das-g = {
email = "nixpkgs@raphael.dasgupta.ch";
github = "das-g";
name = "Raphael Das Gupta";
};
das_j = { das_j = {
email = "janne@hess.ooo"; email = "janne@hess.ooo";
github = "dasJ"; github = "dasJ";
@ -1507,6 +1532,11 @@
github = "ftrvxmtrx"; github = "ftrvxmtrx";
name = "Siarhei Zirukin"; name = "Siarhei Zirukin";
}; };
fuerbringer = {
email = "severin@fuerbringer.info";
github = "fuerbringer";
name = "Severin Fürbringer";
};
funfunctor = { funfunctor = {
email = "eocallaghan@alterapraxis.com"; email = "eocallaghan@alterapraxis.com";
name = "Edward O'Callaghan"; name = "Edward O'Callaghan";
@ -1516,6 +1546,11 @@
github = "fuuzetsu"; github = "fuuzetsu";
name = "Mateusz Kowalczyk"; name = "Mateusz Kowalczyk";
}; };
fuwa = {
email = "echowss@gmail.com";
github = "fuwa0529";
name = "Haruka Akiyama";
};
fuzzy-id = { fuzzy-id = {
email = "hacking+nixos@babibo.de"; email = "hacking+nixos@babibo.de";
name = "Thomas Bach"; name = "Thomas Bach";
@ -1734,6 +1769,11 @@
email = "t@larkery.com"; email = "t@larkery.com";
name = "Tom Hinton"; name = "Tom Hinton";
}; };
hlolli = {
email = "hlolli@gmail.com";
github = "hlolli";
name = "Hlodver Sigurdsson";
};
hodapp = { hodapp = {
email = "hodapp87@gmail.com"; email = "hodapp87@gmail.com";
github = "Hodapp87"; github = "Hodapp87";
@ -2214,6 +2254,11 @@
github = "knedlsepp"; github = "knedlsepp";
name = "Josef Kemetmüller"; name = "Josef Kemetmüller";
}; };
knl = {
email = "nikola@knezevic.co";
github = "knl";
name = "Nikola Knežević";
};
konimex = { konimex = {
email = "herdiansyah@netc.eu"; email = "herdiansyah@netc.eu";
github = "konimex"; github = "konimex";
@ -2661,6 +2706,11 @@
github = "melsigl"; github = "melsigl";
name = "Melanie B. Sigl"; name = "Melanie B. Sigl";
}; };
melkor333 = {
email = "samuel@ton-kunst.ch";
github = "melkor333";
name = "Samuel Ruprecht";
};
metabar = { metabar = {
email = "softs@metabarcoding.org"; email = "softs@metabarcoding.org";
name = "Celine Mercier"; name = "Celine Mercier";
@ -2670,6 +2720,11 @@
github = "mgdelacroix"; github = "mgdelacroix";
name = "Miguel de la Cruz"; name = "Miguel de la Cruz";
}; };
mgregoire = {
email = "gregoire@martinache.net";
github = "M-Gregoire";
name = "Gregoire Martinache";
};
mgttlinger = { mgttlinger = {
email = "megoettlinger@gmail.com"; email = "megoettlinger@gmail.com";
github = "mgttlinger"; github = "mgttlinger";
@ -3795,6 +3850,11 @@
github = "scolobb"; github = "scolobb";
name = "Sergiu Ivanov"; name = "Sergiu Ivanov";
}; };
screendriver = {
email = "nix@echooff.de";
github = "screendriver";
name = "Christian Rackerseder";
};
Scriptkiddi = { Scriptkiddi = {
email = "nixos@scriptkiddi.de"; email = "nixos@scriptkiddi.de";
github = "scriptkiddi"; github = "scriptkiddi";
@ -3905,6 +3965,11 @@
github = "sjagoe"; github = "sjagoe";
name = "Simon Jagoe"; name = "Simon Jagoe";
}; };
sjau = {
email = "nixos@sjau.ch";
github = "sjau";
name = "Stephan Jau";
};
sjmackenzie = { sjmackenzie = {
email = "setori88@gmail.com"; email = "setori88@gmail.com";
github = "sjmackenzie"; github = "sjmackenzie";
@ -3973,6 +4038,11 @@
github = "spacefrogg"; github = "spacefrogg";
name = "Michael Raitza"; name = "Michael Raitza";
}; };
spacekookie = {
email = "kookie@spacekookie.de";
github = "spacekookie";
name = "Katharina Fey";
};
spencerjanssen = { spencerjanssen = {
email = "spencerjanssen@gmail.com"; email = "spencerjanssen@gmail.com";
github = "spencerjanssen"; github = "spencerjanssen";
@ -4153,6 +4223,11 @@
github = "taku0"; github = "taku0";
name = "Takuo Yonezawa"; name = "Takuo Yonezawa";
}; };
talyz = {
email = "kim.lindberger@gmail.com";
github = "talyz";
name = "Kim Lindberger";
};
tari = { tari = {
email = "peter@taricorp.net"; email = "peter@taricorp.net";
github = "tari"; github = "tari";
@ -4193,6 +4268,11 @@
github = "tex"; github = "tex";
name = "Milan Svoboda"; name = "Milan Svoboda";
}; };
tg-x = {
email = "*@tg-x.net";
github = "tg-x";
name = "TG Θ";
};
thall = { thall = {
email = "niclas.thall@gmail.com"; email = "niclas.thall@gmail.com";
github = "thall"; github = "thall";

View File

@ -15,7 +15,7 @@ containers.database =
{ config = { config =
{ config, pkgs, ... }: { config, pkgs, ... }:
{ <xref linkend="opt-services.postgresql.enable"/> = true; { <xref linkend="opt-services.postgresql.enable"/> = true;
<xref linkend="opt-services.postgresql.package"/> = pkgs.postgresql96; <xref linkend="opt-services.postgresql.package"/> = pkgs.postgresql_9_6;
}; };
}; };
</programlisting> </programlisting>

View File

@ -197,10 +197,10 @@ swapDevices = [ { device = "/dev/disk/by-label/swap"; } ];
pkgs.emacs pkgs.emacs
]; ];
<xref linkend="opt-services.postgresql.package"/> = pkgs.postgresql90; <xref linkend="opt-services.postgresql.package"/> = pkgs.postgresql_10;
</programlisting> </programlisting>
The latter option definition changes the default PostgreSQL package used The latter option definition changes the default PostgreSQL package used
by NixOSs PostgreSQL service to 9.0. For more information on packages, by NixOSs PostgreSQL service to 10.x. For more information on packages,
including how to add new ones, see <xref linkend="sec-custom-packages"/>. including how to add new ones, see <xref linkend="sec-custom-packages"/>.
</para> </para>
</listitem> </listitem>

View File

@ -34,13 +34,4 @@
Similarly, UDP port ranges can be opened through Similarly, UDP port ranges can be opened through
<xref linkend="opt-networking.firewall.allowedUDPPortRanges"/>. <xref linkend="opt-networking.firewall.allowedUDPPortRanges"/>.
</para> </para>
<para>
Also of interest is
<programlisting>
<xref linkend="opt-networking.firewall.allowPing"/> = true;
</programlisting>
to allow the machine to respond to ping requests. (ICMPv6 pings are always
allowed.)
</para>
</section> </section>

View File

@ -106,7 +106,7 @@
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry xml:id='types.ints.ux'>
<term> <term>
<varname>types.ints.{u8, u16, u32}</varname> <varname>types.ints.{u8, u16, u32}</varname>
</term> </term>
@ -131,6 +131,17 @@
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>
<varname>types.port</varname>
</term>
<listitem>
<para>
A port number. This type is an alias to
<link linkend='types.ints.ux'><varname>types.ints.u16</varname></link>.
</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
<para> <para>

View File

@ -637,6 +637,11 @@ $ nix-instantiate -E '(import &lt;nixpkgsunstable&gt; {}).gitFull'
anyways for clarity. anyways for clarity.
</para> </para>
</listitem> </listitem>
<listitem>
<para>
Groups <literal>kvm</literal> and <literal>render</literal> are introduced now, as systemd requires them.
</para>
</listitem>
</itemizedlist> </itemizedlist>
</section> </section>

View File

@ -99,6 +99,16 @@
</listitem> </listitem>
</itemizedlist> </itemizedlist>
</listitem> </listitem>
<listitem>
<para>
The Syncthing state and configuration data has been moved from
<varname>services.syncthing.dataDir</varname> to the newly defined
<varname>services.syncthing.configDir</varname>, which default to
<literal>/var/lib/syncthing/.config/syncthing</literal>.
This change makes possible to share synced directories using ACLs
without Syncthing resetting the permission on every start.
</para>
</listitem>
<listitem> <listitem>
<para> <para>
Package <varname>rabbitmq_server</varname> is renamed to Package <varname>rabbitmq_server</varname> is renamed to
@ -137,6 +147,14 @@
make sure to update your configuration if you want to keep <literal>proglodyte-wasm</literal> make sure to update your configuration if you want to keep <literal>proglodyte-wasm</literal>
</para> </para>
</listitem> </listitem>
<listitem>
<para>
When the <literal>nixpkgs.pkgs</literal> option is set, NixOS will no
longer ignore the <literal>nixpkgs.overlays</literal> option. The old
behavior can be recovered by setting <literal>nixpkgs.overlays =
lib.mkForce [];</literal>.
</para>
</listitem>
<listitem> <listitem>
<para> <para>
OpenSMTPD has been upgraded to version 6.4.0p1. This release makes OpenSMTPD has been upgraded to version 6.4.0p1. This release makes
@ -145,6 +163,63 @@
format. format.
</para> </para>
</listitem> </listitem>
<listitem>
<para>
The versioned <varname>postgresql</varname> have been renamed to use
underscore number seperators. For example, <varname>postgresql96</varname>
has been renamed to <varname>postgresql_9_6</varname>.
</para>
</listitem>
<listitem>
<para>
Package <literal>consul-ui</literal> and passthrough <literal>consul.ui</literal> have been removed.
The package <literal>consul</literal> now uses upstream releases that vendor the UI into the binary.
See <link xlink:href="https://github.com/NixOS/nixpkgs/pull/48714#issuecomment-433454834">#48714</link>
for details.
</para>
</listitem>
<listitem>
<para>
Slurm introduces the new option
<literal>services.slurm.stateSaveLocation</literal>,
which is now set to <literal>/var/spool/slurm</literal> by default
(instead of <literal>/var/spool</literal>).
Make sure to move all files to the new directory or to set the option accordingly.
</para>
<para>
The slurmctld now runs as user <literal>slurm</literal> instead of <literal>root</literal>.
If you want to keep slurmctld running as <literal>root</literal>, set
<literal>services.slurm.user = root</literal>.
</para>
<para>
The options <literal>services.slurm.nodeName</literal> and
<literal>services.slurm.partitionName</literal> are now sets of
strings to correctly reflect that fact that each of these
options can occour more than once in the configuration.
</para>
</listitem>
<listitem>
<para>
The <literal>solr</literal> package has been upgraded from 4.10.3 to 7.5.0 and has undergone
some major changes. The <literal>services.solr</literal> module has been updated to reflect
these changes. Please review http://lucene.apache.org/solr/ carefully before upgrading.
</para>
</listitem>
<listitem>
<para>
Package <literal>ckb</literal> is renamed to <literal>ckb-next</literal>,
and options <literal>hardware.ckb.*</literal> are renamed to
<literal>hardware.ckb-next.*</literal>.
</para>
</listitem>
<listitem>
<para>
The option <literal>services.xserver.displayManager.job.logToFile</literal> which was
previously set to <literal>true</literal> when using the display managers
<literal>lightdm</literal>, <literal>sddm</literal> or <literal>xpra</literal> has been
reset to the default value (<literal>false</literal>).
</para>
</listitem>
</itemizedlist> </itemizedlist>
</section> </section>
@ -172,6 +247,19 @@
supports loading TrueCrypt volumes. supports loading TrueCrypt volumes.
</para> </para>
</listitem> </listitem>
<listitem>
<para>
The Kubernetes DNS addons, kube-dns, has been replaced with CoreDNS.
This change is made in accordance with Kubernetes making CoreDNS the official default
starting from
<link xlink:href="https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.11.md#sig-cluster-lifecycle">Kubernetes v1.11</link>.
Please beware that upgrading DNS-addon on existing clusters might induce
minor downtime while the DNS-addon terminates and re-initializes.
Also note that the DNS-service now runs with 2 pod replicas by default.
The desired number of replicas can be configured using:
<option>services.kubernetes.addons.dns.replicas</option>.
</para>
</listitem>
</itemizedlist> </itemizedlist>
</section> </section>
</section> </section>

View File

@ -1,6 +1,4 @@
{ system, minimal ? false, config ? {} }: { system, pkgs, minimal ? false, config ? {} }:
let pkgs = import ../.. { inherit system config; }; in
with pkgs.lib; with pkgs.lib;
with import ../lib/qemu-flags.nix { inherit pkgs; }; with import ../lib/qemu-flags.nix { inherit pkgs; };

View File

@ -1,3 +1,7 @@
/* Build a channel tarball. These contain, in addition to the nixpkgs
* expressions themselves, files that indicate the version of nixpkgs
* that they represent.
*/
{ pkgs, nixpkgs, version, versionSuffix }: { pkgs, nixpkgs, version, versionSuffix }:
pkgs.releaseTools.makeSourceTarball { pkgs.releaseTools.makeSourceTarball {

View File

@ -1,6 +1,6 @@
{ system, minimal ? false, config ? {} }: { system, pkgs, minimal ? false, config ? {} }:
with import ./build-vms.nix { inherit system minimal config; }; with import ./build-vms.nix { inherit system pkgs minimal config; };
with pkgs; with pkgs;
let let
@ -69,7 +69,7 @@ in rec {
mkdir -p $out/coverage-data mkdir -p $out/coverage-data
mv $i $out/coverage-data/$(dirname $(dirname $i)) mv $i $out/coverage-data/$(dirname $(dirname $i))
done done
''; # */ '';
}; };

View File

@ -0,0 +1,86 @@
{ config, lib, pkgs, ... }:
with lib;
{
options = {
gtk.iconCache.enable = mkOption {
type = types.bool;
default = true;
description = ''
Whether to build icon theme caches for GTK+ applications.
'';
};
};
config = mkIf config.gtk.iconCache.enable {
# (Re)build icon theme caches
# ---------------------------
# Each icon theme has its own cache. The difficult is that many
# packages may contribute with icons to the same theme by installing
# some icons.
#
# For instance, on my current NixOS system, the following packages
# (among many others) have icons installed into the hicolor icon
# theme: hicolor-icon-theme, psensor, wpa_gui, caja, etc.
#
# As another example, the mate icon theme has icons installed by the
# packages mate-icon-theme, mate-settings-daemon, and libmateweather.
#
# The HighContrast icon theme also has icons from different packages,
# like gnome-theme-extras and meld.
# When the cache is built all of its icons has to be known. How to
# implement this?
#
# I think that most themes have all icons installed by only one
# package. On my system there are 71 themes installed. Only 3 of them
# have icons installed from more than one package.
#
# If the main package of the theme provides a cache, presumably most
# of its icons will be available to applications without running this
# module. But additional icons offered by other packages will not be
# available. Therefore I think that it is good that the main theme
# package installs a cache (although it does not completely fixes the
# situation for packages installed with nix-env).
#
# The module solution presented here keeps the cache when there is
# only one package contributing with icons to the theme. Otherwise it
# rebuilds the cache taking into account the icons provided all
# packages.
environment.extraSetup = ''
# For each icon theme directory ...
find $out/share/icons -mindepth 1 -maxdepth 1 -print0 | while read -d $'\0' themedir
do
# In order to build the cache, the theme dir should be
# writable. When the theme dir is a symbolic link to somewhere
# in the nix store it is not writable and it means that only
# one package is contributing to the theme. If it already has
# a cache, no rebuild is needed. Otherwise a cache has to be
# built, and to be able to do that we first remove the
# symbolic link and make a directory, and then make symbolic
# links from the original directory into the new one.
if [ ! -w "$themedir" -a -L "$themedir" -a ! -r "$themedir"/icon-theme.cache ]; then
name=$(basename "$themedir")
path=$(readlink -f "$themedir")
rm "$themedir"
mkdir -p "$themedir"
ln -s "$path"/* "$themedir"/
fi
# (Re)build the cache if the theme dir is writable, replacing any
# existing cache for the theme
if [ -w "$themedir" ]; then
rm -f "$themedir"/icon-theme.cache
${pkgs.gtk3.out}/bin/gtk-update-icon-cache --ignore-theme-index "$themedir"
fi
done
'';
};
}

View File

@ -228,9 +228,6 @@ in
# /etc/protocols: IP protocol numbers. # /etc/protocols: IP protocol numbers.
"protocols".source = pkgs.iana-etc + "/etc/protocols"; "protocols".source = pkgs.iana-etc + "/etc/protocols";
# /etc/rpc: RPC program numbers.
"rpc".source = pkgs.glibc.out + "/etc/rpc";
# /etc/hosts: Hostname-to-IP mappings. # /etc/hosts: Hostname-to-IP mappings.
"hosts".text = let "hosts".text = let
oneToString = set: ip: ip + " " + concatStringsSep " " set.${ip}; oneToString = set: ip: ip + " " + concatStringsSep " " set.${ip};
@ -263,11 +260,14 @@ in
''; '';
} // optionalAttrs config.services.resolved.enable { } // optionalAttrs config.services.resolved.enable {
# symlink the static version of resolv.conf as recommended by upstream: # symlink the dynamic stub resolver of resolv.conf as recommended by upstream:
# https://www.freedesktop.org/software/systemd/man/systemd-resolved.html#/etc/resolv.conf # https://www.freedesktop.org/software/systemd/man/systemd-resolved.html#/etc/resolv.conf
"resolv.conf".source = "${pkgs.systemd}/lib/systemd/resolv.conf"; "resolv.conf".source = "/run/systemd/resolve/stub-resolv.conf";
} // optionalAttrs (config.services.resolved.enable && dnsmasqResolve) { } // optionalAttrs (config.services.resolved.enable && dnsmasqResolve) {
"dnsmasq-resolv.conf".source = "/run/systemd/resolve/resolv.conf"; "dnsmasq-resolv.conf".source = "/run/systemd/resolve/resolv.conf";
} // optionalAttrs (pkgs.stdenv.hostPlatform.libc == "glibc") {
# /etc/rpc: RPC program numbers.
"rpc".source = pkgs.glibc.out + "/etc/rpc";
}; };
networking.proxy.envVars = networking.proxy.envVars =

View File

@ -1,4 +1,4 @@
{ config, lib, pkgs, pkgs_i686, ... }: { config, lib, pkgs, ... }:
with pkgs; with pkgs;
with lib; with lib;
@ -19,7 +19,7 @@ let
# Forces 32bit pulseaudio and alsaPlugins to be built/supported for apps # Forces 32bit pulseaudio and alsaPlugins to be built/supported for apps
# using 32bit alsa on 64bit linux. # using 32bit alsa on 64bit linux.
enable32BitAlsaPlugins = cfg.support32Bit && stdenv.isx86_64 && (pkgs_i686.alsaLib != null && pkgs_i686.libpulseaudio != null); enable32BitAlsaPlugins = cfg.support32Bit && stdenv.isx86_64 && (pkgs.pkgsi686Linux.alsaLib != null && pkgs.pkgsi686Linux.libpulseaudio != null);
myConfigFile = myConfigFile =
@ -63,7 +63,7 @@ let
pcm_type.pulse { pcm_type.pulse {
libs.native = ${pkgs.alsaPlugins}/lib/alsa-lib/libasound_module_pcm_pulse.so ; libs.native = ${pkgs.alsaPlugins}/lib/alsa-lib/libasound_module_pcm_pulse.so ;
${lib.optionalString enable32BitAlsaPlugins ${lib.optionalString enable32BitAlsaPlugins
"libs.32Bit = ${pkgs_i686.alsaPlugins}/lib/alsa-lib/libasound_module_pcm_pulse.so ;"} "libs.32Bit = ${pkgs.pkgsi686Linux.alsaPlugins}/lib/alsa-lib/libasound_module_pcm_pulse.so ;"}
} }
pcm.!default { pcm.!default {
type pulse type pulse
@ -72,7 +72,7 @@ let
ctl_type.pulse { ctl_type.pulse {
libs.native = ${pkgs.alsaPlugins}/lib/alsa-lib/libasound_module_ctl_pulse.so ; libs.native = ${pkgs.alsaPlugins}/lib/alsa-lib/libasound_module_ctl_pulse.so ;
${lib.optionalString enable32BitAlsaPlugins ${lib.optionalString enable32BitAlsaPlugins
"libs.32Bit = ${pkgs_i686.alsaPlugins}/lib/alsa-lib/libasound_module_ctl_pulse.so ;"} "libs.32Bit = ${pkgs.pkgsi686Linux.alsaPlugins}/lib/alsa-lib/libasound_module_ctl_pulse.so ;"}
} }
ctl.!default { ctl.!default {
type pulse type pulse

View File

@ -19,7 +19,9 @@ let
pkgs.diffutils pkgs.diffutils
pkgs.findutils pkgs.findutils
pkgs.gawk pkgs.gawk
pkgs.glibc # for ldd, getent pkgs.stdenv.cc.libc
pkgs.getent
pkgs.getconf
pkgs.gnugrep pkgs.gnugrep
pkgs.gnupatch pkgs.gnupatch
pkgs.gnused pkgs.gnused
@ -133,10 +135,6 @@ in
# outputs TODO: note that the tools will often not be linked by default # outputs TODO: note that the tools will often not be linked by default
postBuild = postBuild =
'' ''
if [ -x $out/bin/gtk-update-icon-cache -a -f $out/share/icons/hicolor/index.theme ]; then
$out/bin/gtk-update-icon-cache $out/share/icons/hicolor
fi
if [ -x $out/bin/glib-compile-schemas -a -w $out/share/glib-2.0/schemas ]; then if [ -x $out/bin/glib-compile-schemas -a -w $out/share/glib-2.0/schemas ]; then
$out/bin/glib-compile-schemas $out/share/glib-2.0/schemas $out/bin/glib-compile-schemas $out/share/glib-2.0/schemas
fi fi

View File

@ -3,17 +3,17 @@
with lib; with lib;
let let
cfg = config.hardware.ckb; cfg = config.hardware.ckb-next;
in in
{ {
options.hardware.ckb = { options.hardware.ckb-next = {
enable = mkEnableOption "the Corsair keyboard/mouse driver"; enable = mkEnableOption "the Corsair keyboard/mouse driver";
package = mkOption { package = mkOption {
type = types.package; type = types.package;
default = pkgs.ckb; default = pkgs.ckb-next;
defaultText = "pkgs.ckb"; defaultText = "pkgs.ckb-next";
description = '' description = ''
The package implementing the Corsair keyboard/mouse driver. The package implementing the Corsair keyboard/mouse driver.
''; '';
@ -23,12 +23,12 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
environment.systemPackages = [ cfg.package ]; environment.systemPackages = [ cfg.package ];
systemd.services.ckb = { systemd.services.ckb-next = {
description = "Corsair Keyboard Daemon"; description = "Corsair Keyboards and Mice Daemon";
wantedBy = ["multi-user.target"]; wantedBy = ["multi-user.target"];
script = "${cfg.package}/bin/ckb-daemon"; script = "exec ${cfg.package}/bin/ckb-next-daemon";
serviceConfig = { serviceConfig = {
Restart = "always"; Restart = "on-failure";
StandardOutput = "syslog"; StandardOutput = "syslog";
}; };
}; };

View File

@ -1,4 +1,4 @@
{ config, lib, pkgs, pkgs_i686, ... }: { config, lib, pkgs, ... }:
with lib; with lib;
@ -148,7 +148,7 @@ in
[ "/run/opengl-driver/share" ] ++ optional cfg.driSupport32Bit "/run/opengl-driver-32/share"; [ "/run/opengl-driver/share" ] ++ optional cfg.driSupport32Bit "/run/opengl-driver-32/share";
hardware.opengl.package = mkDefault (makePackage pkgs); hardware.opengl.package = mkDefault (makePackage pkgs);
hardware.opengl.package32 = mkDefault (makePackage pkgs_i686); hardware.opengl.package32 = mkDefault (makePackage pkgs.pkgsi686Linux);
boot.extraModulePackages = optional (elem "virtualbox" videoDrivers) kernelPackages.virtualboxGuestAdditions; boot.extraModulePackages = optional (elem "virtualbox" videoDrivers) kernelPackages.virtualboxGuestAdditions;
}; };

View File

@ -1,6 +1,6 @@
# This module provides the proprietary AMDGPU-PRO drivers. # This module provides the proprietary AMDGPU-PRO drivers.
{ config, lib, pkgs, pkgs_i686, ... }: { config, lib, pkgs, ... }:
with lib; with lib;
@ -11,7 +11,7 @@ let
enabled = elem "amdgpu-pro" drivers; enabled = elem "amdgpu-pro" drivers;
package = config.boot.kernelPackages.amdgpu-pro; package = config.boot.kernelPackages.amdgpu-pro;
package32 = pkgs_i686.linuxPackages.amdgpu-pro.override { libsOnly = true; kernel = null; }; package32 = pkgs.pkgsi686Linux.linuxPackages.amdgpu-pro.override { libsOnly = true; kernel = null; };
opengl = config.hardware.opengl; opengl = config.hardware.opengl;

View File

@ -1,6 +1,6 @@
# This module provides the proprietary ATI X11 / OpenGL drivers. # This module provides the proprietary ATI X11 / OpenGL drivers.
{ config, lib, pkgs_i686, ... }: { config, lib, pkgs, ... }:
with lib; with lib;
@ -24,7 +24,7 @@ in
{ name = "fglrx"; modules = [ ati_x11 ]; libPath = [ "${ati_x11}/lib" ]; }; { name = "fglrx"; modules = [ ati_x11 ]; libPath = [ "${ati_x11}/lib" ]; };
hardware.opengl.package = ati_x11; hardware.opengl.package = ati_x11;
hardware.opengl.package32 = pkgs_i686.linuxPackages.ati_drivers_x11.override { libsOnly = true; kernel = null; }; hardware.opengl.package32 = pkgs.pkgsi686Linux.linuxPackages.ati_drivers_x11.override { libsOnly = true; kernel = null; };
environment.systemPackages = [ ati_x11 ]; environment.systemPackages = [ ati_x11 ];

View File

@ -1,6 +1,6 @@
# This module provides the proprietary NVIDIA X11 / OpenGL drivers. # This module provides the proprietary NVIDIA X11 / OpenGL drivers.
{ stdenv, config, lib, pkgs, pkgs_i686, ... }: { stdenv, config, lib, pkgs, ... }:
with lib; with lib;
@ -25,7 +25,7 @@ let
nvidia_x11 = nvidiaForKernel config.boot.kernelPackages; nvidia_x11 = nvidiaForKernel config.boot.kernelPackages;
nvidia_libs32 = nvidia_libs32 =
if versionOlder nvidia_x11.version "391" then if versionOlder nvidia_x11.version "391" then
((nvidiaForKernel pkgs_i686.linuxPackages).override { libsOnly = true; kernel = null; }).out ((nvidiaForKernel pkgs.pkgsi686Linux.linuxPackages).override { libsOnly = true; kernel = null; }).out
else else
(nvidiaForKernel config.boot.kernelPackages).lib32; (nvidiaForKernel config.boot.kernelPackages).lib32;

View File

@ -1,9 +1,13 @@
{ system ? builtins.currentSystem { system ? builtins.currentSystem
, config ? {}
, networkExpr , networkExpr
}: }:
let nodes = import networkExpr; in let nodes = import networkExpr; in
with import ../../../../lib/testing.nix { inherit system; }; with import ../../../../lib/testing.nix {
inherit system;
pkgs = import ../.. { inherit system config; };
};
(makeTest { inherit nodes; testScript = ""; }).driver (makeTest { inherit nodes; testScript = ""; }).driver

View File

@ -331,6 +331,11 @@
zeronet = 304; zeronet = 304;
lirc = 305; lirc = 305;
lidarr = 306; lidarr = 306;
slurm = 307;
kapacitor = 308;
solr = 309;
alerta = 310;
minetest = 311;
# 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!
@ -622,6 +627,11 @@
zeronet = 304; zeronet = 304;
lirc = 305; lirc = 305;
lidarr = 306; lidarr = 306;
slurm = 307;
kapacitor = 308;
solr = 309;
alerta = 310;
minetest = 311;
# 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

@ -1,9 +1,10 @@
{ config, lib, pkgs, ... }: { config, options, lib, pkgs, ... }:
with lib; with lib;
let let
cfg = config.nixpkgs; cfg = config.nixpkgs;
opt = options.nixpkgs;
isConfig = x: isConfig = x:
builtins.isAttrs x || lib.isFunction x; builtins.isAttrs x || lib.isFunction x;
@ -54,6 +55,12 @@ let
check = builtins.isAttrs; check = builtins.isAttrs;
}; };
defaultPkgs = import ../../../pkgs/top-level/default.nix {
inherit (cfg) config overlays localSystem crossSystem;
};
finalPkgs = if opt.pkgs.isDefined then cfg.pkgs.appendOverlays cfg.overlays else defaultPkgs;
in in
{ {
@ -61,21 +68,25 @@ in
pkgs = mkOption { pkgs = mkOption {
defaultText = literalExample defaultText = literalExample
''import "''${nixos}/.." { ''import "''${nixos}/../pkgs/top-level" {
inherit (cfg) config overlays localSystem crossSystem; inherit (cfg) config overlays localSystem crossSystem;
} }
''; '';
default = import ../../.. {
inherit (cfg) config overlays localSystem crossSystem;
};
type = pkgsType; type = pkgsType;
example = literalExample ''import <nixpkgs> {}''; example = literalExample ''import <nixpkgs> {}'';
description = '' description = ''
This is the evaluation of Nixpkgs that will be provided to If set, the pkgs argument to all NixOS modules is the value of
all NixOS modules. Defining this option has the effect of this option, extended with <code>nixpkgs.overlays</code>, if
ignoring the other options that would otherwise be used to that is also set. Either <code>nixpkgs.crossSystem</code> or
evaluate Nixpkgs, because those are arguments to the default <code>nixpkgs.localSystem</code> will be used in an assertion
value. The default value imports the Nixpkgs source files to check that the NixOS and Nixpkgs architectures match. Any
other options in <code>nixpkgs.*</code>, notably <code>config</code>,
will be ignored.
If unset, the pkgs argument to all NixOS modules is determined
as shown in the default value for this option.
The default value imports the Nixpkgs source files
relative to the location of this NixOS module, because relative to the location of this NixOS module, because
NixOS and Nixpkgs are distributed together for consistency, NixOS and Nixpkgs are distributed together for consistency,
so the <code>nixos</code> in the default value is in fact a so the <code>nixos</code> in the default value is in fact a
@ -128,12 +139,14 @@ in
description = '' description = ''
List of overlays to use with the Nix Packages collection. List of overlays to use with the Nix Packages collection.
(For details, see the Nixpkgs documentation.) It allows (For details, see the Nixpkgs documentation.) It allows
you to override packages globally. This is a function that you to override packages globally. Each function in the list
takes as an argument the <emphasis>original</emphasis> Nixpkgs. takes as an argument the <emphasis>original</emphasis> Nixpkgs.
The first argument should be used for finding dependencies, and The first argument should be used for finding dependencies, and
the second should be used for overriding recipes. the second should be used for overriding recipes.
Ignored when <code>nixpkgs.pkgs</code> is set. If <code>nixpkgs.pkgs</code> is set, overlays specified here
will be applied after the overlays that were already present
in <code>nixpkgs.pkgs</code>.
''; '';
}; };
@ -207,8 +220,26 @@ in
config = { config = {
_module.args = { _module.args = {
pkgs = cfg.pkgs; pkgs = finalPkgs;
pkgs_i686 = cfg.pkgs.pkgsi686Linux;
}; };
assertions = [
(
let
nixosExpectedSystem =
if config.nixpkgs.crossSystem != null
then config.nixpkgs.crossSystem.system
else config.nixpkgs.localSystem.system;
nixosOption =
if config.nixpkgs.crossSystem != null
then "nixpkgs.crossSystem"
else "nixpkgs.localSystem";
pkgsSystem = finalPkgs.stdenv.targetPlatform.system;
in {
assertion = nixosExpectedSystem == pkgsSystem;
message = "The NixOS nixpkgs.pkgs option was set to a Nixpkgs invocation that compiles to target system ${pkgsSystem} but NixOS was configured for system ${nixosExpectedSystem} via NixOS option ${nixosOption}. The NixOS system settings must match the Nixpkgs target system.";
}
)
];
}; };
} }

View File

@ -11,6 +11,7 @@
./config/xdg/icons.nix ./config/xdg/icons.nix
./config/xdg/menus.nix ./config/xdg/menus.nix
./config/xdg/mime.nix ./config/xdg/mime.nix
./config/gtk/gtk-icon-cache.nix
./config/gnu.nix ./config/gnu.nix
./config/i18n.nix ./config/i18n.nix
./config/iproute2.nix ./config/iproute2.nix
@ -34,7 +35,7 @@
./config/zram.nix ./config/zram.nix
./hardware/all-firmware.nix ./hardware/all-firmware.nix
./hardware/brightnessctl.nix ./hardware/brightnessctl.nix
./hardware/ckb.nix ./hardware/ckb-next.nix
./hardware/cpu/amd-microcode.nix ./hardware/cpu/amd-microcode.nix
./hardware/cpu/intel-microcode.nix ./hardware/cpu/intel-microcode.nix
./hardware/digitalbitbox.nix ./hardware/digitalbitbox.nix
@ -90,6 +91,7 @@
./programs/criu.nix ./programs/criu.nix
./programs/dconf.nix ./programs/dconf.nix
./programs/digitalbitbox/default.nix ./programs/digitalbitbox/default.nix
./programs/dmrconfig.nix
./programs/environment.nix ./programs/environment.nix
./programs/firejail.nix ./programs/firejail.nix
./programs/fish.nix ./programs/fish.nix
@ -419,6 +421,7 @@
./services/misc/weechat.nix ./services/misc/weechat.nix
./services/misc/xmr-stak.nix ./services/misc/xmr-stak.nix
./services/misc/zookeeper.nix ./services/misc/zookeeper.nix
./services/monitoring/alerta.nix
./services/monitoring/apcupsd.nix ./services/monitoring/apcupsd.nix
./services/monitoring/arbtt.nix ./services/monitoring/arbtt.nix
./services/monitoring/bosun.nix ./services/monitoring/bosun.nix
@ -429,10 +432,12 @@
./services/monitoring/dd-agent/dd-agent.nix ./services/monitoring/dd-agent/dd-agent.nix
./services/monitoring/fusion-inventory.nix ./services/monitoring/fusion-inventory.nix
./services/monitoring/grafana.nix ./services/monitoring/grafana.nix
./services/monitoring/grafana-reporter.nix
./services/monitoring/graphite.nix ./services/monitoring/graphite.nix
./services/monitoring/hdaps.nix ./services/monitoring/hdaps.nix
./services/monitoring/heapster.nix ./services/monitoring/heapster.nix
./services/monitoring/incron.nix ./services/monitoring/incron.nix
./services/monitoring/kapacitor.nix
./services/monitoring/longview.nix ./services/monitoring/longview.nix
./services/monitoring/monit.nix ./services/monitoring/monit.nix
./services/monitoring/munin.nix ./services/monitoring/munin.nix

View File

@ -63,7 +63,7 @@ with lib;
# Tell the Nix evaluator to garbage collect more aggressively. # Tell the Nix evaluator to garbage collect more aggressively.
# This is desirable in memory-constrained environments that don't # This is desirable in memory-constrained environments that don't
# (yet) have swap set up. # (yet) have swap set up.
environment.variables.GC_INITIAL_HEAP_SIZE = "100000"; environment.variables.GC_INITIAL_HEAP_SIZE = "1M";
# Make the installer more likely to succeed in low memory # Make the installer more likely to succeed in low memory
# environments. The kernel's overcommit heustistics bite us # environments. The kernel's overcommit heustistics bite us

View File

@ -16,7 +16,7 @@ let
# programmable completion. If we do, enable all modules installed in # programmable completion. If we do, enable all modules installed in
# the system and user profile in obsolete /etc/bash_completion.d/ # the system and user profile in obsolete /etc/bash_completion.d/
# directories. Bash loads completions in all # directories. Bash loads completions in all
# $XDG_DATA_DIRS/share/bash-completion/completions/ # $XDG_DATA_DIRS/bash-completion/completions/
# on demand, so they do not need to be sourced here. # on demand, so they do not need to be sourced here.
if shopt -q progcomp &>/dev/null; then if shopt -q progcomp &>/dev/null; then
. "${pkgs.bash-completion}/etc/profile.d/bash_completion.sh" . "${pkgs.bash-completion}/etc/profile.d/bash_completion.sh"

View File

@ -0,0 +1,38 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.dmrconfig;
in {
meta.maintainers = [ maintainers.etu ];
###### interface
options = {
programs.dmrconfig = {
enable = mkOption {
default = false;
type = types.bool;
description = ''
Whether to configure system to enable use of dmrconfig. This
enables the required udev rules and installs the program.
'';
relatedPackages = [ "dmrconfig" ];
};
package = mkOption {
default = pkgs.dmrconfig;
type = types.package;
defaultText = "pkgs.dmrconfig";
description = "dmrconfig derivation to use";
};
};
};
###### implementation
config = mkIf cfg.enable {
environment.systemPackages = [ cfg.package ];
services.udev.packages = [ cfg.package ];
};
}

View File

@ -13,7 +13,7 @@ with lib;
# Set up the per-user profile. # Set up the per-user profile.
mkdir -m 0755 -p "$NIX_USER_PROFILE_DIR" mkdir -m 0755 -p "$NIX_USER_PROFILE_DIR"
if [ "$(stat --printf '%u' "$NIX_USER_PROFILE_DIR")" != "$(id -u)" ]; then if [ "$(stat --printf '%u' "$NIX_USER_PROFILE_DIR")" != "$(id -u)" ]; then
echo "WARNING: bad ownership on $NIX_USER_PROFILE_DIR, should be $(id -u)" >&2 echo "WARNING: the per-user profile dir $NIX_USER_PROFILE_DIR should belong to user id $(id -u)" >&2
fi fi
if [ -w "$HOME" ]; then if [ -w "$HOME" ]; then
@ -35,7 +35,7 @@ with lib;
NIX_USER_GCROOTS_DIR="/nix/var/nix/gcroots/per-user/$USER" NIX_USER_GCROOTS_DIR="/nix/var/nix/gcroots/per-user/$USER"
mkdir -m 0755 -p "$NIX_USER_GCROOTS_DIR" mkdir -m 0755 -p "$NIX_USER_GCROOTS_DIR"
if [ "$(stat --printf '%u' "$NIX_USER_GCROOTS_DIR")" != "$(id -u)" ]; then if [ "$(stat --printf '%u' "$NIX_USER_GCROOTS_DIR")" != "$(id -u)" ]; then
echo "WARNING: bad ownership on $NIX_USER_GCROOTS_DIR, should be $(id -u)" >&2 echo "WARNING: the per-user gcroots dir $NIX_USER_GCROOTS_DIR should belong to user id $(id -u)" >&2
fi fi
# Set up a default Nix expression from which to install stuff. # Set up a default Nix expression from which to install stuff.

View File

@ -5,6 +5,15 @@ with lib;
let let
cfg = config.programs.sway-beta; cfg = config.programs.sway-beta;
swayPackage = cfg.package; swayPackage = cfg.package;
swayWrapped = pkgs.writeShellScriptBin "sway" ''
${cfg.extraSessionCommands}
exec ${pkgs.dbus.dbus-launch} --exit-with-session ${swayPackage}/bin/sway
'';
swayJoined = pkgs.symlinkJoin {
name = "sway-joined";
paths = [ swayWrapped swayPackage ];
};
in { in {
options.programs.sway-beta = { options.programs.sway-beta = {
enable = mkEnableOption '' enable = mkEnableOption ''
@ -20,13 +29,30 @@ in {
''; '';
}; };
extraSessionCommands = mkOption {
type = types.lines;
default = "";
example = ''
export SDL_VIDEODRIVER=wayland
# needs qt5.qtwayland in systemPackages
export QT_QPA_PLATFORM=wayland
export QT_WAYLAND_DISABLE_WINDOWDECORATION="1"
# Fix for some Java AWT applications (e.g. Android Studio),
# use this if they aren't displayed properly:
export _JAVA_AWT_WM_NONREPARENTING=1
'';
description = ''
Shell commands executed just before Sway is started.
'';
};
extraPackages = mkOption { extraPackages = mkOption {
type = with types; listOf package; type = with types; listOf package;
default = with pkgs; [ default = with pkgs; [
xwayland dmenu xwayland rxvt_unicode dmenu
]; ];
defaultText = literalExample '' defaultText = literalExample ''
with pkgs; [ xwayland dmenu ]; with pkgs; [ xwayland rxvt_unicode dmenu ];
''; '';
example = literalExample '' example = literalExample ''
with pkgs; [ with pkgs; [
@ -42,7 +68,7 @@ in {
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
environment.systemPackages = [ swayPackage ] ++ cfg.extraPackages; environment.systemPackages = [ swayJoined ] ++ cfg.extraPackages;
security.pam.services.swaylock = {}; security.pam.services.swaylock = {};
hardware.opengl.enable = mkDefault true; hardware.opengl.enable = mkDefault true;
fonts.enableDefaultFonts = mkDefault true; fonts.enableDefaultFonts = mkDefault true;
@ -51,4 +77,3 @@ in {
meta.maintainers = with lib.maintainers; [ gnidorah primeos colemickens ]; meta.maintainers = with lib.maintainers; [ gnidorah primeos colemickens ];
} }

View File

@ -28,7 +28,10 @@ with lib;
(config: (config:
let enabled = getAttrFromPath [ "services" "printing" "gutenprint" ] config; let enabled = getAttrFromPath [ "services" "printing" "gutenprint" ] config;
in if enabled then [ pkgs.gutenprint ] else [ ])) in if enabled then [ pkgs.gutenprint ] else [ ]))
(mkRenamedOptionModule [ "services" "ddclient" "domain" ] [ "services" "ddclient" "domains" ]) (mkChangedOptionModule [ "services" "ddclient" "domain" ] [ "services" "ddclient" "domains" ]
(config:
let value = getAttrFromPath [ "services" "ddclient" "domain" ] config;
in if value != "" then [ value ] else []))
(mkRemovedOptionModule [ "services" "ddclient" "homeDir" ] "") (mkRemovedOptionModule [ "services" "ddclient" "homeDir" ] "")
(mkRenamedOptionModule [ "services" "elasticsearch" "host" ] [ "services" "elasticsearch" "listenAddress" ]) (mkRenamedOptionModule [ "services" "elasticsearch" "host" ] [ "services" "elasticsearch" "listenAddress" ])
(mkRenamedOptionModule [ "services" "graphite" "api" "host" ] [ "services" "graphite" "api" "listenAddress" ]) (mkRenamedOptionModule [ "services" "graphite" "api" "host" ] [ "services" "graphite" "api" "listenAddress" ])
@ -279,6 +282,10 @@ with lib;
(mkRenamedOptionModule [ "programs" "man" "enable" ] [ "documentation" "man" "enable" ]) (mkRenamedOptionModule [ "programs" "man" "enable" ] [ "documentation" "man" "enable" ])
(mkRenamedOptionModule [ "services" "nixosManual" "enable" ] [ "documentation" "nixos" "enable" ]) (mkRenamedOptionModule [ "services" "nixosManual" "enable" ] [ "documentation" "nixos" "enable" ])
# ckb
(mkRenamedOptionModule [ "hardware" "ckb" "enable" ] [ "hardware" "ckb-next" "enable" ])
(mkRenamedOptionModule [ "hardware" "ckb" "package" ] [ "hardware" "ckb-next" "package" ])
] ++ (flip map [ "blackboxExporter" "collectdExporter" "fritzboxExporter" ] ++ (flip map [ "blackboxExporter" "collectdExporter" "fritzboxExporter"
"jsonExporter" "minioExporter" "nginxExporter" "nodeExporter" "jsonExporter" "minioExporter" "nginxExporter" "nodeExporter"
"snmpExporter" "unifiExporter" "varnishExporter" ] "snmpExporter" "unifiExporter" "varnishExporter" ]

View File

@ -28,7 +28,7 @@ with lib;
capability setuid, capability setuid,
network inet raw, network inet raw,
${pkgs.glibc.out}/lib/*.so mr, ${pkgs.stdenv.cc.libc.out}/lib/*.so mr,
${pkgs.libcap.lib}/lib/libcap.so* mr, ${pkgs.libcap.lib}/lib/libcap.so* mr,
${pkgs.attr.out}/lib/libattr.so* mr, ${pkgs.attr.out}/lib/libattr.so* mr,

View File

@ -170,4 +170,6 @@ in {
''; '';
}) cfg.params; }) cfg.params;
}; };
meta.maintainers = with lib.maintainers; [ ekleog ];
} }

View File

@ -29,7 +29,7 @@ with lib;
description = "Hardware RNG Entropy Gatherer Daemon"; description = "Hardware RNG Entropy Gatherer Daemon";
serviceConfig.ExecStart = "${pkgs.rng-tools}/sbin/rngd -f -v"; serviceConfig.ExecStart = "${pkgs.rng-tools}/sbin/rngd -f";
}; };
}; };
} }

View File

@ -53,6 +53,9 @@ in
Type = "notify"; Type = "notify";
NotifyAccess = "all"; NotifyAccess = "all";
}; };
restartTriggers = [
config.environment.etc."salt/master".source
];
}; };
}; };

View File

@ -15,7 +15,6 @@ let
# Default is in /etc/salt/pki/minion # Default is in /etc/salt/pki/minion
pki_dir = "/var/lib/salt/pki/minion"; pki_dir = "/var/lib/salt/pki/minion";
} cfg.configuration; } cfg.configuration;
configDir = pkgs.writeTextDir "minion" (builtins.toJSON fullConfig);
in in
@ -28,15 +27,24 @@ in
default = {}; default = {};
description = '' description = ''
Salt minion configuration as Nix attribute set. Salt minion configuration as Nix attribute set.
See <link xlink:href="https://docs.saltstack.com/en/latest/ref/configuration/minion.html"/> See <link xlink:href="https://docs.saltstack.com/en/latest/ref/configuration/minion.html"/>
for details. for details.
''; '';
}; };
}; };
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
environment.systemPackages = with pkgs; [ salt ]; environment = {
# Set this up in /etc/salt/minion so `salt-call`, etc. work.
# The alternatives are
# - passing --config-dir to all salt commands, not just the minion unit,
# - setting aglobal environment variable.
etc."salt/minion".source = pkgs.writeText "minion" (
builtins.toJSON fullConfig
);
systemPackages = with pkgs; [ salt ];
};
systemd.services.salt-minion = { systemd.services.salt-minion = {
description = "Salt Minion"; description = "Salt Minion";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
@ -45,11 +53,14 @@ in
utillinux utillinux
]; ];
serviceConfig = { serviceConfig = {
ExecStart = "${pkgs.salt}/bin/salt-minion --config-dir=${configDir}"; ExecStart = "${pkgs.salt}/bin/salt-minion";
LimitNOFILE = 8192; LimitNOFILE = 8192;
Type = "notify"; Type = "notify";
NotifyAccess = "all"; NotifyAccess = "all";
}; };
restartTriggers = [
config.environment.etc."salt/minion".source
];
}; };
}; };
} }

View File

@ -87,9 +87,19 @@ in {
} }
''; '';
description = '' description = ''
New style config options. Configuration options in RabbitMQ's new config file format,
which is a simple key-value format that can not express nested
data structures. This is known as the <literal>rabbitmq.conf</literal> file,
although outside NixOS that filename may have Erlang syntax, particularly
prior to RabbitMQ 3.7.0.
See http://www.rabbitmq.com/configure.html If you do need to express nested data structures, you can use
<literal>config</literal> option. Configuration from <literal>config</literal>
will be merged into these options by RabbitMQ at runtime to
form the final configuration.
See http://www.rabbitmq.com/configure.html#config-items
For the distinct formats, see http://www.rabbitmq.com/configure.html#config-file-formats
''; '';
}; };
@ -97,10 +107,17 @@ in {
default = ""; default = "";
type = types.str; type = types.str;
description = '' description = ''
Verbatim advanced configuration file contents. Verbatim advanced configuration file contents using the Erlang syntax.
Prefered way is to use configItems. This is also known as the <literal>advanced.config</literal> file or the old config format.
See http://www.rabbitmq.com/configure.html <literal>configItems</literal> is preferred whenever possible. However, nested
data structures can only be expressed properly using the <literal>config</literal> option.
The contents of this option will be merged into the <literal>configItems</literal>
by RabbitMQ at runtime to form the final configuration.
See the second table on http://www.rabbitmq.com/configure.html#config-items
For the distinct formats, see http://www.rabbitmq.com/configure.html#config-file-formats
''; '';
}; };

View File

@ -346,8 +346,12 @@ in {
description = "Bacula File Daemon"; description = "Bacula File Daemon";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
path = [ pkgs.bacula ]; path = [ pkgs.bacula ];
serviceConfig.ExecStart = "${pkgs.bacula}/sbin/bacula-fd -f -u root -g bacula -c ${fd_conf}"; serviceConfig = {
serviceConfig.ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; ExecStart = "${pkgs.bacula}/sbin/bacula-fd -f -u root -g bacula -c ${fd_conf}";
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
LogsDirectory = "bacula";
StateDirectory = "bacula";
};
}; };
systemd.services.bacula-sd = mkIf sd_cfg.enable { systemd.services.bacula-sd = mkIf sd_cfg.enable {
@ -355,8 +359,12 @@ in {
description = "Bacula Storage Daemon"; description = "Bacula Storage Daemon";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
path = [ pkgs.bacula ]; path = [ pkgs.bacula ];
serviceConfig.ExecStart = "${pkgs.bacula}/sbin/bacula-sd -f -u bacula -g bacula -c ${sd_conf}"; serviceConfig = {
serviceConfig.ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; ExecStart = "${pkgs.bacula}/sbin/bacula-sd -f -u bacula -g bacula -c ${sd_conf}";
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
LogsDirectory = "bacula";
StateDirectory = "bacula";
};
}; };
services.postgresql.enable = dir_cfg.enable == true; services.postgresql.enable = dir_cfg.enable == true;
@ -366,8 +374,12 @@ in {
description = "Bacula Director Daemon"; description = "Bacula Director Daemon";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
path = [ pkgs.bacula ]; path = [ pkgs.bacula ];
serviceConfig.ExecStart = "${pkgs.bacula}/sbin/bacula-dir -f -u bacula -g bacula -c ${dir_conf}"; serviceConfig = {
serviceConfig.ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; ExecStart = "${pkgs.bacula}/sbin/bacula-dir -f -u bacula -g bacula -c ${dir_conf}";
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
LogsDirectory = "bacula";
StateDirectory = "bacula";
};
preStart = '' preStart = ''
if ! test -e "${libDir}/db-created"; then if ! test -e "${libDir}/db-created"; then
${pkgs.postgresql}/bin/createuser --no-superuser --no-createdb --no-createrole bacula ${pkgs.postgresql}/bin/createuser --no-superuser --no-createdb --no-createrole bacula

View File

@ -20,6 +20,8 @@ let
''; '';
script = '' script = ''
umask 0077 # ensure backup is only readable by postgres user
if [ -e ${cfg.location}/${db}.sql.gz ]; then if [ -e ${cfg.location}/${db}.sql.gz ]; then
${pkgs.coreutils}/bin/mv ${cfg.location}/${db}.sql.gz ${cfg.location}/${db}.prev.sql.gz ${pkgs.coreutils}/bin/mv ${cfg.location}/${db}.sql.gz ${cfg.location}/${db}.prev.sql.gz
fi fi

View File

@ -3,8 +3,13 @@
with lib; with lib;
let let
version = "1.14.10"; version = "1.2.5";
cfg = config.services.kubernetes.addons.dns; cfg = config.services.kubernetes.addons.dns;
ports = {
dns = 10053;
health = 10054;
metrics = 10055;
};
in { in {
options.services.kubernetes.addons.dns = { options.services.kubernetes.addons.dns = {
enable = mkEnableOption "kubernetes dns addon"; enable = mkEnableOption "kubernetes dns addon";
@ -27,49 +32,130 @@ in {
type = types.str; type = types.str;
}; };
kube-dns = mkOption { replicas = mkOption {
description = "Docker image to seed for the kube-dns main container."; description = "Number of DNS pod replicas to deploy in the cluster.";
type = types.attrs; default = 2;
default = { type = types.int;
imageName = "k8s.gcr.io/k8s-dns-kube-dns-amd64";
imageDigest = "sha256:b99fc3eee2a9f052f7eb4cc00f15eb12fc405fa41019baa2d6b79847ae7284a8";
finalImageTag = version;
sha256 = "0x583znk9smqn0fix7ld8sm5jgaxhqhx3fq97b1wkqm7iwhvl3pj";
};
}; };
dnsmasq-nanny = mkOption { coredns = mkOption {
description = "Docker image to seed for the kube-dns dnsmasq container."; description = "Docker image to seed for the CoreDNS container.";
type = types.attrs; type = types.attrs;
default = { default = {
imageName = "k8s.gcr.io/k8s-dns-dnsmasq-nanny-amd64"; imageName = "coredns/coredns";
imageDigest = "sha256:bbb2a290a568125b3b996028958eb773f33b5b87a6b37bf38a28f8b62dddb3c8"; imageDigest = "sha256:33c8da20b887ae12433ec5c40bfddefbbfa233d5ce11fb067122e68af30291d6";
finalImageTag = version; finalImageTag = version;
sha256 = "1fihml7s2mfwgac51cbqpylkwbivc8nyhgi4vb820s83zvl8a6y1"; sha256 = "13q19rgwapv27xcs664dw502254yw4zw63insf6g2danidv2mg6i";
};
};
sidecar = mkOption {
description = "Docker image to seed for the kube-dns sidecar container.";
type = types.attrs;
default = {
imageName = "k8s.gcr.io/k8s-dns-sidecar-amd64";
imageDigest = "sha256:4f1ab957f87b94a5ec1edc26fae50da2175461f00afecf68940c4aa079bd08a4";
finalImageTag = version;
sha256 = "08l1bv5jgrhvjzpqpbinrkgvv52snc4fzyd8ya9v18ns2klyz7m0";
}; };
}; };
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
services.kubernetes.kubelet.seedDockerImages = with pkgs.dockerTools; [ services.kubernetes.kubelet.seedDockerImages =
(pullImage cfg.kube-dns) singleton (pkgs.dockerTools.pullImage cfg.coredns);
(pullImage cfg.dnsmasq-nanny)
(pullImage cfg.sidecar)
];
services.kubernetes.addonManager.addons = { services.kubernetes.addonManager.addons = {
kubedns-deployment = { coredns-sa = {
apiVersion = "v1";
kind = "ServiceAccount";
metadata = {
labels = {
"addonmanager.kubernetes.io/mode" = "Reconcile";
"k8s-app" = "kube-dns";
"kubernetes.io/cluster-service" = "true";
};
name = "coredns";
namespace = "kube-system";
};
};
coredns-cr = {
apiVersion = "rbac.authorization.k8s.io/v1beta1";
kind = "ClusterRole";
metadata = {
labels = {
"addonmanager.kubernetes.io/mode" = "Reconcile";
"k8s-app" = "kube-dns";
"kubernetes.io/cluster-service" = "true";
"kubernetes.io/bootstrapping" = "rbac-defaults";
};
name = "system:coredns";
};
rules = [
{
apiGroups = [ "" ];
resources = [ "endpoints" "services" "pods" "namespaces" ];
verbs = [ "list" "watch" ];
}
{
apiGroups = [ "" ];
resources = [ "nodes" ];
verbs = [ "get" ];
}
];
};
coredns-crb = {
apiVersion = "rbac.authorization.k8s.io/v1beta1";
kind = "ClusterRoleBinding";
metadata = {
annotations = {
"rbac.authorization.kubernetes.io/autoupdate" = "true";
};
labels = {
"addonmanager.kubernetes.io/mode" = "Reconcile";
"k8s-app" = "kube-dns";
"kubernetes.io/cluster-service" = "true";
"kubernetes.io/bootstrapping" = "rbac-defaults";
};
name = "system:coredns";
};
roleRef = {
apiGroup = "rbac.authorization.k8s.io";
kind = "ClusterRole";
name = "system:coredns";
};
subjects = [
{
kind = "ServiceAccount";
name = "coredns";
namespace = "kube-system";
}
];
};
coredns-cm = {
apiVersion = "v1";
kind = "ConfigMap";
metadata = {
labels = {
"addonmanager.kubernetes.io/mode" = "Reconcile";
"k8s-app" = "kube-dns";
"kubernetes.io/cluster-service" = "true";
};
name = "coredns";
namespace = "kube-system";
};
data = {
Corefile = ".:${toString ports.dns} {
errors
health :${toString ports.health}
kubernetes ${cfg.clusterDomain} in-addr.arpa ip6.arpa {
pods insecure
upstream
fallthrough in-addr.arpa ip6.arpa
}
prometheus :${toString ports.metrics}
proxy . /etc/resolv.conf
cache 30
loop
reload
loadbalance
}";
};
};
coredns-deploy = {
apiVersion = "extensions/v1beta1"; apiVersion = "extensions/v1beta1";
kind = "Deployment"; kind = "Deployment";
metadata = { metadata = {
@ -77,182 +163,96 @@ in {
"addonmanager.kubernetes.io/mode" = "Reconcile"; "addonmanager.kubernetes.io/mode" = "Reconcile";
"k8s-app" = "kube-dns"; "k8s-app" = "kube-dns";
"kubernetes.io/cluster-service" = "true"; "kubernetes.io/cluster-service" = "true";
"kubernetes.io/name" = "CoreDNS";
}; };
name = "kube-dns"; name = "coredns";
namespace = "kube-system"; namespace = "kube-system";
}; };
spec = { spec = {
selector.matchLabels."k8s-app" = "kube-dns"; replicas = cfg.replicas;
selector = {
matchLabels = { k8s-app = "kube-dns"; };
};
strategy = { strategy = {
rollingUpdate = { rollingUpdate = { maxUnavailable = 1; };
maxSurge = "10%"; type = "RollingUpdate";
maxUnavailable = 0;
};
}; };
template = { template = {
metadata = { metadata = {
annotations."scheduler.alpha.kubernetes.io/critical-pod" = ""; labels = {
labels.k8s-app = "kube-dns"; k8s-app = "kube-dns";
};
}; };
spec = { spec = {
priorityClassName = "system-cluster-critical";
containers = [ containers = [
{ {
name = "kubedns"; args = [ "-conf" "/etc/coredns/Corefile" ];
image = with cfg.kube-dns; "${imageName}:${finalImageTag}"; image = with cfg.coredns; "${imageName}:${finalImageTag}";
imagePullPolicy = "Never";
livenessProbe = {
failureThreshold = 5;
httpGet = {
path = "/health";
port = ports.health;
scheme = "HTTP";
};
initialDelaySeconds = 60;
successThreshold = 1;
timeoutSeconds = 5;
};
name = "coredns";
ports = [
{
containerPort = ports.dns;
name = "dns";
protocol = "UDP";
}
{
containerPort = ports.dns;
name = "dns-tcp";
protocol = "TCP";
}
{
containerPort = ports.metrics;
name = "metrics";
protocol = "TCP";
}
];
resources = { resources = {
limits.memory = "170Mi"; limits = {
memory = "170Mi";
};
requests = { requests = {
cpu = "100m"; cpu = "100m";
memory = "70Mi"; memory = "70Mi";
}; };
}; };
livenessProbe = { securityContext = {
failureThreshold = 5; allowPrivilegeEscalation = false;
httpGet = { capabilities = {
path = "/healthcheck/kubedns"; drop = [ "all" ];
port = 10054;
scheme = "HTTP";
};
initialDelaySeconds = 60;
successThreshold = 1;
timeoutSeconds = 5;
};
readinessProbe = {
httpGet = {
path = "/readiness";
port = 8081;
scheme = "HTTP";
};
initialDelaySeconds = 3;
timeoutSeconds = 5;
};
args = [
"--domain=${cfg.clusterDomain}"
"--dns-port=10053"
"--config-dir=/kube-dns-config"
"--v=2"
];
env = [
{
name = "PROMETHEUS_PORT";
value = "10055";
}
];
ports = [
{
containerPort = 10053;
name = "dns-local";
protocol = "UDP";
}
{
containerPort = 10053;
name = "dns-tcp-local";
protocol = "TCP";
}
{
containerPort = 10055;
name = "metrics";
protocol = "TCP";
}
];
volumeMounts = [
{
mountPath = "/kube-dns-config";
name = "kube-dns-config";
}
];
}
{
name = "dnsmasq";
image = with cfg.dnsmasq-nanny; "${imageName}:${finalImageTag}";
livenessProbe = {
httpGet = {
path = "/healthcheck/dnsmasq";
port = 10054;
scheme = "HTTP";
};
initialDelaySeconds = 60;
timeoutSeconds = 5;
successThreshold = 1;
failureThreshold = 5;
};
args = [
"-v=2"
"-logtostderr"
"-configDir=/etc/k8s/dns/dnsmasq-nanny"
"-restartDnsmasq=true"
"--"
"-k"
"--cache-size=1000"
"--log-facility=-"
"--server=/${cfg.clusterDomain}/127.0.0.1#10053"
"--server=/in-addr.arpa/127.0.0.1#10053"
"--server=/ip6.arpa/127.0.0.1#10053"
];
ports = [
{
containerPort = 53;
name = "dns";
protocol = "UDP";
}
{
containerPort = 53;
name = "dns-tcp";
protocol = "TCP";
}
];
resources = {
requests = {
cpu = "150m";
memory = "20Mi";
}; };
readOnlyRootFilesystem = true;
}; };
volumeMounts = [ volumeMounts = [
{ {
mountPath = "/etc/k8s/dns/dnsmasq-nanny"; mountPath = "/etc/coredns";
name = "kube-dns-config"; name = "config-volume";
readOnly = true;
} }
]; ];
} }
{
name = "sidecar";
image = with cfg.sidecar; "${imageName}:${finalImageTag}";
livenessProbe = {
httpGet = {
path = "/metrics";
port = 10054;
scheme = "HTTP";
};
initialDelaySeconds = 60;
timeoutSeconds = 5;
successThreshold = 1;
failureThreshold = 5;
};
args = [
"--v=2"
"--logtostderr"
"--probe=kubedns,127.0.0.1:10053,kubernetes.default.svc.${cfg.clusterDomain},5,A"
"--probe=dnsmasq,127.0.0.1:53,kubernetes.default.svc.${cfg.clusterDomain},5,A"
];
ports = [
{
containerPort = 10054;
name = "metrics";
protocol = "TCP";
}
];
resources = {
requests = {
cpu = "10m";
memory = "20Mi";
};
};
}
]; ];
dnsPolicy = "Default"; dnsPolicy = "Default";
serviceAccountName = "kube-dns"; nodeSelector = {
"beta.kubernetes.io/os" = "linux";
};
serviceAccountName = "coredns";
tolerations = [ tolerations = [
{
effect = "NoSchedule";
key = "node-role.kubernetes.io/master";
}
{ {
key = "CriticalAddonsOnly"; key = "CriticalAddonsOnly";
operator = "Exists"; operator = "Exists";
@ -261,10 +261,15 @@ in {
volumes = [ volumes = [
{ {
configMap = { configMap = {
name = "kube-dns"; items = [
optional = true; {
key = "Corefile";
path = "Corefile";
}
];
name = "coredns";
}; };
name = "kube-dns-config"; name = "config-volume";
} }
]; ];
}; };
@ -272,51 +277,40 @@ in {
}; };
}; };
kubedns-svc = { coredns-svc = {
apiVersion = "v1"; apiVersion = "v1";
kind = "Service"; kind = "Service";
metadata = { metadata = {
annotations = {
"prometheus.io/port" = toString ports.metrics;
"prometheus.io/scrape" = "true";
};
labels = { labels = {
"addonmanager.kubernetes.io/mode" = "Reconcile"; "addonmanager.kubernetes.io/mode" = "Reconcile";
"k8s-app" = "kube-dns"; "k8s-app" = "kube-dns";
"kubernetes.io/cluster-service" = "true"; "kubernetes.io/cluster-service" = "true";
"kubernetes.io/name" = "KubeDNS"; "kubernetes.io/name" = "CoreDNS";
}; };
name = "kube-dns"; name = "kube-dns";
namespace = "kube-system"; namespace = "kube-system";
}; };
spec = { spec = {
clusterIP = cfg.clusterIp; clusterIP = cfg.clusterIp;
ports = [ ports = [
{name = "dns"; port = 53; protocol = "UDP";} {
{name = "dns-tcp"; port = 53; protocol = "TCP";} name = "dns";
port = 53;
targetPort = ports.dns;
protocol = "UDP";
}
{
name = "dns-tcp";
port = 53;
targetPort = ports.dns;
protocol = "TCP";
}
]; ];
selector.k8s-app = "kube-dns"; selector = { k8s-app = "kube-dns"; };
};
};
kubedns-sa = {
apiVersion = "v1";
kind = "ServiceAccount";
metadata = {
name = "kube-dns";
namespace = "kube-system";
labels = {
"kubernetes.io/cluster-service" = "true";
"addonmanager.kubernetes.io/mode" = "Reconcile";
};
};
};
kubedns-cm = {
apiVersion = "v1";
kind = "ConfigMap";
metadata = {
name = "kube-dns";
namespace = "kube-system";
labels = {
"addonmanager.kubernetes.io/mode" = "EnsureExists";
};
}; };
}; };
}; };

View File

@ -6,13 +6,18 @@ let
cfg = config.services.slurm; cfg = config.services.slurm;
# configuration file can be generated by http://slurm.schedmd.com/configurator.html # configuration file can be generated by http://slurm.schedmd.com/configurator.html
defaultUser = "slurm";
configFile = pkgs.writeTextDir "slurm.conf" configFile = pkgs.writeTextDir "slurm.conf"
'' ''
ClusterName=${cfg.clusterName} ClusterName=${cfg.clusterName}
StateSaveLocation=${cfg.stateSaveLocation}
SlurmUser=${cfg.user}
${optionalString (cfg.controlMachine != null) ''controlMachine=${cfg.controlMachine}''} ${optionalString (cfg.controlMachine != null) ''controlMachine=${cfg.controlMachine}''}
${optionalString (cfg.controlAddr != null) ''controlAddr=${cfg.controlAddr}''} ${optionalString (cfg.controlAddr != null) ''controlAddr=${cfg.controlAddr}''}
${optionalString (cfg.nodeName != null) ''nodeName=${cfg.nodeName}''} ${toString (map (x: "NodeName=${x}\n") cfg.nodeName)}
${optionalString (cfg.partitionName != null) ''partitionName=${cfg.partitionName}''} ${toString (map (x: "PartitionName=${x}\n") cfg.partitionName)}
PlugStackConfig=${plugStackConfig} PlugStackConfig=${plugStackConfig}
ProctrackType=${cfg.procTrackType} ProctrackType=${cfg.procTrackType}
${cfg.extraConfig} ${cfg.extraConfig}
@ -24,12 +29,19 @@ let
${cfg.extraPlugstackConfig} ${cfg.extraPlugstackConfig}
''; '';
cgroupConfig = pkgs.writeTextDir "cgroup.conf" cgroupConfig = pkgs.writeTextDir "cgroup.conf"
'' ''
${cfg.extraCgroupConfig} ${cfg.extraCgroupConfig}
''; '';
slurmdbdConf = pkgs.writeTextDir "slurmdbd.conf"
''
DbdHost=${cfg.dbdserver.dbdHost}
SlurmUser=${cfg.user}
StorageType=accounting_storage/mysql
${cfg.dbdserver.extraConfig}
'';
# slurm expects some additional config files to be # slurm expects some additional config files to be
# in the same directory as slurm.conf # in the same directory as slurm.conf
etcSlurm = pkgs.symlinkJoin { etcSlurm = pkgs.symlinkJoin {
@ -43,6 +55,8 @@ in
###### interface ###### interface
meta.maintainers = [ maintainers.markuskowa ];
options = { options = {
services.slurm = { services.slurm = {
@ -60,6 +74,27 @@ in
}; };
}; };
dbdserver = {
enable = mkEnableOption "SlurmDBD service";
dbdHost = mkOption {
type = types.str;
default = config.networking.hostName;
description = ''
Hostname of the machine where <literal>slurmdbd</literal>
is running (i.e. name returned by <literal>hostname -s</literal>).
'';
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = ''
Extra configuration for <literal>slurmdbd.conf</literal>
'';
};
};
client = { client = {
enable = mkEnableOption "slurm client daemon"; enable = mkEnableOption "slurm client daemon";
}; };
@ -116,9 +151,9 @@ in
}; };
nodeName = mkOption { nodeName = mkOption {
type = types.nullOr types.str; type = types.listOf types.str;
default = null; default = [];
example = "linux[1-32] CPUs=1 State=UNKNOWN"; example = literalExample ''[ "linux[1-32] CPUs=1 State=UNKNOWN" ];'';
description = '' description = ''
Name that SLURM uses to refer to a node (or base partition for BlueGene Name that SLURM uses to refer to a node (or base partition for BlueGene
systems). Typically this would be the string that "/bin/hostname -s" systems). Typically this would be the string that "/bin/hostname -s"
@ -127,9 +162,9 @@ in
}; };
partitionName = mkOption { partitionName = mkOption {
type = types.nullOr types.str; type = types.listOf types.str;
default = null; default = [];
example = "debug Nodes=linux[1-32] Default=YES MaxTime=INFINITE State=UP"; example = literalExample ''[ "debug Nodes=linux[1-32] Default=YES MaxTime=INFINITE State=UP" ];'';
description = '' description = ''
Name by which the partition may be referenced. Note that now you have Name by which the partition may be referenced. Note that now you have
to write the partition's parameters after the name. to write the partition's parameters after the name.
@ -150,7 +185,7 @@ in
}; };
procTrackType = mkOption { procTrackType = mkOption {
type = types.string; type = types.str;
default = "proctrack/linuxproc"; default = "proctrack/linuxproc";
description = '' description = ''
Plugin to be used for process tracking on a job step basis. Plugin to be used for process tracking on a job step basis.
@ -159,6 +194,25 @@ in
''; '';
}; };
stateSaveLocation = mkOption {
type = types.str;
default = "/var/spool/slurmctld";
description = ''
Directory into which the Slurm controller, slurmctld, saves its state.
'';
};
user = mkOption {
type = types.str;
default = defaultUser;
description = ''
Set this option when you want to run the slurmctld daemon
as something else than the default slurm user "slurm".
Note that the UID of this user needs to be the same
on all nodes.
'';
};
extraConfig = mkOption { extraConfig = mkOption {
default = ""; default = "";
type = types.lines; type = types.lines;
@ -184,6 +238,8 @@ in
used when <literal>procTrackType=proctrack/cgroup</literal>. used when <literal>procTrackType=proctrack/cgroup</literal>.
''; '';
}; };
}; };
}; };
@ -220,12 +276,24 @@ in
''; '';
}; };
in mkIf (cfg.enableStools || cfg.client.enable || cfg.server.enable) { in mkIf ( cfg.enableStools ||
cfg.client.enable ||
cfg.server.enable ||
cfg.dbdserver.enable ) {
environment.systemPackages = [ wrappedSlurm ]; environment.systemPackages = [ wrappedSlurm ];
services.munge.enable = mkDefault true; services.munge.enable = mkDefault true;
# use a static uid as default to ensure it is the same on all nodes
users.users.slurm = mkIf (cfg.user == defaultUser) {
name = defaultUser;
group = "slurm";
uid = config.ids.uids.slurm;
};
users.groups.slurm.gid = config.ids.uids.slurm;
systemd.services.slurmd = mkIf (cfg.client.enable) { systemd.services.slurmd = mkIf (cfg.client.enable) {
path = with pkgs; [ wrappedSlurm coreutils ] path = with pkgs; [ wrappedSlurm coreutils ]
++ lib.optional cfg.enableSrunX11 slurm-spank-x11; ++ lib.optional cfg.enableSrunX11 slurm-spank-x11;
@ -261,6 +329,29 @@ in
PIDFile = "/run/slurmctld.pid"; PIDFile = "/run/slurmctld.pid";
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
}; };
preStart = ''
mkdir -p ${cfg.stateSaveLocation}
chown -R ${cfg.user}:slurm ${cfg.stateSaveLocation}
'';
};
systemd.services.slurmdbd = mkIf (cfg.dbdserver.enable) {
path = with pkgs; [ wrappedSlurm munge coreutils ];
wantedBy = [ "multi-user.target" ];
after = [ "network.target" "munged.service" "mysql.service" ];
requires = [ "munged.service" "mysql.service" ];
# slurm strips the last component off the path
environment.SLURM_CONF = "${slurmdbdConf}/slurm.conf";
serviceConfig = {
Type = "forking";
ExecStart = "${cfg.package}/bin/slurmdbd";
PIDFile = "/run/slurmdbd.pid";
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
};
}; };
}; };

View File

@ -55,7 +55,7 @@ in
package = mkOption { package = mkOption {
type = types.package; type = types.package;
example = literalExample "pkgs.postgresql96"; example = literalExample "pkgs.postgresql_9_6";
description = '' description = ''
PostgreSQL package to use. PostgreSQL package to use.
''; '';
@ -118,7 +118,7 @@ in
extraPlugins = mkOption { extraPlugins = mkOption {
type = types.listOf types.path; type = types.listOf types.path;
default = []; default = [];
example = literalExample "[ (pkgs.postgis.override { postgresql = pkgs.postgresql94; }) ]"; example = literalExample "[ (pkgs.postgis.override { postgresql = pkgs.postgresql_9_4; }) ]";
description = '' description = ''
When this list contains elements a new store path is created. When this list contains elements a new store path is created.
PostgreSQL and the elements are symlinked into it. Then pg_config, PostgreSQL and the elements are symlinked into it. Then pg_config,
@ -167,9 +167,9 @@ in
# Note: when changing the default, make it conditional on # Note: when changing the default, make it conditional on
# system.stateVersion to maintain compatibility with existing # system.stateVersion to maintain compatibility with existing
# systems! # systems!
mkDefault (if versionAtLeast config.system.stateVersion "17.09" then pkgs.postgresql96 mkDefault (if versionAtLeast config.system.stateVersion "17.09" then pkgs.postgresql_9_6
else if versionAtLeast config.system.stateVersion "16.03" then pkgs.postgresql95 else if versionAtLeast config.system.stateVersion "16.03" then pkgs.postgresql_9_5
else pkgs.postgresql94); else pkgs.postgresql_9_4);
services.postgresql.dataDir = services.postgresql.dataDir =
mkDefault (if versionAtLeast config.system.stateVersion "17.09" then "/var/lib/postgresql/${config.services.postgresql.package.psqlSchema}" mkDefault (if versionAtLeast config.system.stateVersion "17.09" then "/var/lib/postgresql/${config.services.postgresql.package.psqlSchema}"
@ -271,5 +271,5 @@ in
}; };
meta.doc = ./postgresql.xml; meta.doc = ./postgresql.xml;
meta.maintainers = with lib.maintainers; [ thoughtpolice ];
} }

View File

@ -27,12 +27,12 @@
<filename>configuration.nix</filename>: <filename>configuration.nix</filename>:
<programlisting> <programlisting>
<xref linkend="opt-services.postgresql.enable"/> = true; <xref linkend="opt-services.postgresql.enable"/> = true;
<xref linkend="opt-services.postgresql.package"/> = pkgs.postgresql94; <xref linkend="opt-services.postgresql.package"/> = pkgs.postgresql_9_4;
</programlisting> </programlisting>
Note that you are required to specify the desired version of PostgreSQL Note that you are required to specify the desired version of PostgreSQL
(e.g. <literal>pkgs.postgresql94</literal>). Since upgrading your PostgreSQL (e.g. <literal>pkgs.postgresql_9_4</literal>). Since upgrading your
version requires a database dump and reload (see below), NixOS cannot PostgreSQL version requires a database dump and reload (see below), NixOS
provide a default value for cannot provide a default value for
<xref linkend="opt-services.postgresql.package"/> such as the most recent <xref linkend="opt-services.postgresql.package"/> such as the most recent
release of PostgreSQL. release of PostgreSQL.
</para> </para>

View File

@ -145,6 +145,7 @@ in {
systemd.services.jupyter = { systemd.services.jupyter = {
description = "Jupyter development server"; description = "Jupyter development server";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
# TODO: Patch notebook so we can explicitly pass in a shell # TODO: Patch notebook so we can explicitly pass in a shell

View File

@ -84,7 +84,9 @@ in
home = "/var/lib/minetest"; home = "/var/lib/minetest";
createHome = true; createHome = true;
uid = config.ids.uids.minetest; uid = config.ids.uids.minetest;
group = "minetest";
}; };
users.groups.minetest.gid = config.ids.gids.minetest;
systemd.services.minetest-server = { systemd.services.minetest-server = {
description = "Minetest Server Service"; description = "Minetest Server Service";
@ -93,6 +95,7 @@ in
serviceConfig.Restart = "always"; serviceConfig.Restart = "always";
serviceConfig.User = "minetest"; serviceConfig.User = "minetest";
serviceConfig.Group = "minetest";
script = '' script = ''
cd /var/lib/minetest cd /var/lib/minetest

View File

@ -56,6 +56,32 @@ in
{ Type = "dbus"; { Type = "dbus";
BusName = "org.freedesktop.UPower"; BusName = "org.freedesktop.UPower";
ExecStart = "@${cfg.package}/libexec/upowerd upowerd"; ExecStart = "@${cfg.package}/libexec/upowerd upowerd";
Restart = "on-failure";
# Upstream lockdown:
# Filesystem lockdown
ProtectSystem = "strict";
# Needed by keyboard backlight support
ProtectKernelTunables = false;
ProtectControlGroups = true;
ReadWritePaths = "/var/lib/upower";
ProtectHome = true;
PrivateTmp = true;
# Network
# PrivateNetwork=true would block udev's netlink socket
RestrictAddressFamilies = "AF_UNIX AF_NETLINK";
# Execute Mappings
MemoryDenyWriteExecute = true;
# Modules
ProtectKernelModules = true;
# Real-time
RestrictRealtime = true;
# Privilege escalation
NoNewPrivileges = true;
}; };
}; };

View File

@ -176,4 +176,6 @@ in
} }
) cfg.instances); ) cfg.instances);
}; };
meta.maintainers = with lib.maintainers; [ ekleog ];
} }

View File

@ -115,4 +115,6 @@ in
}; };
}; };
}; };
meta.maintainers = with lib.maintainers; [ ekleog ];
} }

View File

@ -6,6 +6,7 @@ let
cfg = config.services.rspamd; cfg = config.services.rspamd;
opts = options.services.rspamd; opts = options.services.rspamd;
postfixCfg = config.services.postfix;
bindSocketOpts = {options, config, ... }: { bindSocketOpts = {options, config, ... }: {
options = { options = {
@ -58,7 +59,7 @@ let
}; };
type = mkOption { type = mkOption {
type = types.nullOr (types.enum [ type = types.nullOr (types.enum [
"normal" "controller" "fuzzy_storage" "proxy" "lua" "normal" "controller" "fuzzy_storage" "rspamd_proxy" "lua"
]); ]);
description = "The type of this worker"; description = "The type of this worker";
}; };
@ -99,19 +100,21 @@ let
description = "Additional entries to put verbatim into worker section of rspamd config file."; description = "Additional entries to put verbatim into worker section of rspamd config file.";
}; };
}; };
config = mkIf (name == "normal" || name == "controller" || name == "fuzzy") { config = mkIf (name == "normal" || name == "controller" || name == "fuzzy" || name == "rspamd_proxy") {
type = mkDefault name; type = mkDefault name;
includes = mkDefault [ "$CONFDIR/worker-${name}.inc" ]; includes = mkDefault [ "$CONFDIR/worker-${if name == "rspamd_proxy" then "proxy" else name}.inc" ];
bindSockets = mkDefault (if name == "normal" bindSockets =
then [{ let
socket = "/run/rspamd/rspamd.sock"; unixSocket = name: {
mode = "0660"; mode = "0660";
owner = cfg.user; socket = "/run/rspamd/${name}.sock";
group = cfg.group; owner = cfg.user;
}] group = cfg.group;
else if name == "controller" };
then [ "localhost:11334" ] in mkDefault (if name == "normal" then [(unixSocket "rspamd")]
else [] ); else if name == "controller" then [ "localhost:11334" ]
else if name == "rspamd_proxy" then [ (unixSocket "proxy") ]
else [] );
}; };
}; };
@ -127,28 +130,83 @@ let
options { options {
pidfile = "$RUNDIR/rspamd.pid"; pidfile = "$RUNDIR/rspamd.pid";
.include "$CONFDIR/options.inc" .include "$CONFDIR/options.inc"
.include(try=true; priority=1,duplicate=merge) "$LOCAL_CONFDIR/local.d/options.inc"
.include(try=true; priority=10) "$LOCAL_CONFDIR/override.d/options.inc"
} }
logging { logging {
type = "syslog"; type = "syslog";
.include "$CONFDIR/logging.inc" .include "$CONFDIR/logging.inc"
.include(try=true; priority=1,duplicate=merge) "$LOCAL_CONFDIR/local.d/logging.inc"
.include(try=true; priority=10) "$LOCAL_CONFDIR/override.d/logging.inc"
} }
${concatStringsSep "\n" (mapAttrsToList (name: value: '' ${concatStringsSep "\n" (mapAttrsToList (name: value: let
worker ${optionalString (value.name != "normal" && value.name != "controller") "${value.name}"} { includeName = if name == "rspamd_proxy" then "proxy" else name;
tryOverride = if value.extraConfig == "" then "true" else "false";
in ''
worker "${value.type}" {
type = "${value.type}"; type = "${value.type}";
${optionalString (value.enable != null) ${optionalString (value.enable != null)
"enabled = ${if value.enable != false then "yes" else "no"};"} "enabled = ${if value.enable != false then "yes" else "no"};"}
${mkBindSockets value.enable value.bindSockets} ${mkBindSockets value.enable value.bindSockets}
${optionalString (value.count != null) "count = ${toString value.count};"} ${optionalString (value.count != null) "count = ${toString value.count};"}
${concatStringsSep "\n " (map (each: ".include \"${each}\"") value.includes)} ${concatStringsSep "\n " (map (each: ".include \"${each}\"") value.includes)}
${value.extraConfig} .include(try=true; priority=1,duplicate=merge) "$LOCAL_CONFDIR/local.d/worker-${includeName}.inc"
.include(try=${tryOverride}; priority=10) "$LOCAL_CONFDIR/override.d/worker-${includeName}.inc"
} }
'') cfg.workers)} '') cfg.workers)}
${cfg.extraConfig} ${optionalString (cfg.extraConfig != "") ''
.include(priority=10) "$LOCAL_CONFDIR/override.d/extra-config.inc"
''}
''; '';
filterFiles = files: filterAttrs (n: v: v.enable) files;
rspamdDir = pkgs.linkFarm "etc-rspamd-dir" (
(mapAttrsToList (name: file: { name = "local.d/${name}"; path = file.source; }) (filterFiles cfg.locals)) ++
(mapAttrsToList (name: file: { name = "override.d/${name}"; path = file.source; }) (filterFiles cfg.overrides)) ++
(optional (cfg.localLuaRules != null) { name = "rspamd.local.lua"; path = cfg.localLuaRules; }) ++
[ { name = "rspamd.conf"; path = rspamdConfFile; } ]
);
configFileModule = prefix: { name, config, ... }: {
options = {
enable = mkOption {
type = types.bool;
default = true;
description = ''
Whether this file ${prefix} should be generated. This
option allows specific ${prefix} files to be disabled.
'';
};
text = mkOption {
default = null;
type = types.nullOr types.lines;
description = "Text of the file.";
};
source = mkOption {
type = types.path;
description = "Path of the source file.";
};
};
config = {
source = mkIf (config.text != null) (
let name' = "rspamd-${prefix}-" + baseNameOf name;
in mkDefault (pkgs.writeText name' config.text));
};
};
configOverrides =
(mapAttrs' (n: v: nameValuePair "worker-${if n == "rspamd_proxy" then "proxy" else n}.inc" {
text = v.extraConfig;
})
(filterAttrs (n: v: v.extraConfig != "") cfg.workers))
// (if cfg.extraConfig == "" then {} else {
"extra-config.inc".text = cfg.extraConfig;
});
in in
{ {
@ -167,6 +225,41 @@ in
description = "Whether to run the rspamd daemon in debug mode."; description = "Whether to run the rspamd daemon in debug mode.";
}; };
locals = mkOption {
type = with types; attrsOf (submodule (configFileModule "locals"));
default = {};
description = ''
Local configuration files, written into <filename>/etc/rspamd/local.d/{name}</filename>.
'';
example = literalExample ''
{ "redis.conf".source = "/nix/store/.../etc/dir/redis.conf";
"arc.conf".text = "allow_envfrom_empty = true;";
}
'';
};
overrides = mkOption {
type = with types; attrsOf (submodule (configFileModule "overrides"));
default = {};
description = ''
Overridden configuration files, written into <filename>/etc/rspamd/override.d/{name}</filename>.
'';
example = literalExample ''
{ "redis.conf".source = "/nix/store/.../etc/dir/redis.conf";
"arc.conf".text = "allow_envfrom_empty = true;";
}
'';
};
localLuaRules = mkOption {
default = null;
type = types.nullOr types.path;
description = ''
Path of file to link to <filename>/etc/rspamd/rspamd.local.lua</filename> for local
rules written in Lua
'';
};
workers = mkOption { workers = mkOption {
type = with types; attrsOf (submodule workerOpts); type = with types; attrsOf (submodule workerOpts);
description = '' description = ''
@ -210,7 +303,7 @@ in
description = '' description = ''
User to use when no root privileges are required. User to use when no root privileges are required.
''; '';
}; };
group = mkOption { group = mkOption {
type = types.string; type = types.string;
@ -218,7 +311,30 @@ in
description = '' description = ''
Group to use when no root privileges are required. Group to use when no root privileges are required.
''; '';
}; };
postfix = {
enable = mkOption {
type = types.bool;
default = false;
description = "Add rspamd milter to postfix main.conf";
};
config = mkOption {
type = with types; attrsOf (either bool (either str (listOf str)));
description = ''
Addon to postfix configuration
'';
default = {
smtpd_milters = ["unix:/run/rspamd/rspamd-milter.sock"];
non_smtpd_milters = ["unix:/run/rspamd/rspamd-milter.sock"];
};
example = {
smtpd_milters = ["unix:/run/rspamd/rspamd-milter.sock"];
non_smtpd_milters = ["unix:/run/rspamd/rspamd-milter.sock"];
};
};
};
}; };
}; };
@ -226,6 +342,25 @@ in
###### implementation ###### implementation
config = mkIf cfg.enable { config = mkIf cfg.enable {
services.rspamd.overrides = configOverrides;
services.rspamd.workers = mkIf cfg.postfix.enable {
controller = {};
rspamd_proxy = {
bindSockets = [ {
mode = "0660";
socket = "/run/rspamd/rspamd-milter.sock";
owner = cfg.user;
group = postfixCfg.group;
} ];
extraConfig = ''
upstream "local" {
default = yes; # Self-scan upstreams are always default
self_scan = yes; # Enable self-scan
}
'';
};
};
services.postfix.config = mkIf cfg.postfix.enable cfg.postfix.config;
# Allow users to run 'rspamc' and 'rspamadm'. # Allow users to run 'rspamc' and 'rspamadm'.
environment.systemPackages = [ pkgs.rspamd ]; environment.systemPackages = [ pkgs.rspamd ];
@ -242,16 +377,17 @@ in
gid = config.ids.gids.rspamd; gid = config.ids.gids.rspamd;
}; };
environment.etc."rspamd.conf".source = rspamdConfFile; environment.etc."rspamd".source = rspamdDir;
systemd.services.rspamd = { systemd.services.rspamd = {
description = "Rspamd Service"; description = "Rspamd Service";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
after = [ "network.target" ]; after = [ "network.target" ];
restartTriggers = [ rspamdDir ];
serviceConfig = { serviceConfig = {
ExecStart = "${pkgs.rspamd}/bin/rspamd ${optionalString cfg.debug "-d"} --user=${cfg.user} --group=${cfg.group} --pid=/run/rspamd.pid -c ${rspamdConfFile} -f"; ExecStart = "${pkgs.rspamd}/bin/rspamd ${optionalString cfg.debug "-d"} --user=${cfg.user} --group=${cfg.group} --pid=/run/rspamd.pid -c /etc/rspamd/rspamd.conf -f";
Restart = "always"; Restart = "always";
RuntimeDirectory = "rspamd"; RuntimeDirectory = "rspamd";
PrivateTmp = true; PrivateTmp = true;

View File

@ -6,6 +6,7 @@ let
cfg = config.services.gitea; cfg = config.services.gitea;
gitea = cfg.package; gitea = cfg.package;
pg = config.services.postgresql; pg = config.services.postgresql;
useMysql = cfg.database.type == "mysql";
usePostgresql = cfg.database.type == "postgres"; usePostgresql = cfg.database.type == "postgres";
configFile = pkgs.writeText "app.ini" '' configFile = pkgs.writeText "app.ini" ''
APP_NAME = ${cfg.appName} APP_NAME = ${cfg.appName}
@ -14,7 +15,7 @@ let
[database] [database]
DB_TYPE = ${cfg.database.type} DB_TYPE = ${cfg.database.type}
HOST = ${cfg.database.host}:${toString cfg.database.port} HOST = ${if cfg.database.socket != null then cfg.database.socket else cfg.database.host + ":" + toString cfg.database.port}
NAME = ${cfg.database.name} NAME = ${cfg.database.name}
USER = ${cfg.database.user} USER = ${cfg.database.user}
PASSWD = #dbpass# PASSWD = #dbpass#
@ -148,6 +149,13 @@ in
''; '';
}; };
socket = mkOption {
type = types.nullOr types.path;
default = null;
example = "/run/mysqld/mysqld.sock";
description = "Path to the unix socket file to use for authentication.";
};
path = mkOption { path = mkOption {
type = types.str; type = types.str;
default = "${cfg.stateDir}/data/gitea.db"; default = "${cfg.stateDir}/data/gitea.db";
@ -253,7 +261,7 @@ in
systemd.services.gitea = { systemd.services.gitea = {
description = "gitea"; description = "gitea";
after = [ "network.target" "postgresql.service" ]; after = [ "network.target" ] ++ lib.optional usePostgresql "postgresql.service" ++ lib.optional useMysql "mysql.service";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
path = [ gitea.bin ]; path = [ gitea.bin ];

View File

@ -14,15 +14,16 @@ let
pathUrlQuote = url: replaceStrings ["/"] ["%2F"] url; pathUrlQuote = url: replaceStrings ["/"] ["%2F"] url;
pgSuperUser = config.services.postgresql.superUser; pgSuperUser = config.services.postgresql.superUser;
databaseYml = '' databaseConfig = {
production: production = {
adapter: postgresql adapter = "postgresql";
database: ${cfg.databaseName} database = cfg.databaseName;
host: ${cfg.databaseHost} host = cfg.databaseHost;
password: ${cfg.databasePassword} password = cfg.databasePassword;
username: ${cfg.databaseUsername} username = cfg.databaseUsername;
encoding: utf8 encoding = "utf8";
''; };
};
gitalyToml = pkgs.writeText "gitaly.toml" '' gitalyToml = pkgs.writeText "gitaly.toml" ''
socket_path = "${lib.escape ["\""] gitalySocket}" socket_path = "${lib.escape ["\""] gitalySocket}"
@ -45,35 +46,31 @@ let
'') gitlabConfig.production.repositories.storages))} '') gitlabConfig.production.repositories.storages))}
''; '';
gitlabShellYml = '' gitlabShellConfig = {
user: ${cfg.user} user = cfg.user;
gitlab_url: "http+unix://${pathUrlQuote gitlabSocket}" gitlab_url = "http+unix://${pathUrlQuote gitlabSocket}";
http_settings: http_settings.self_signed_cert = false;
self_signed_cert: false repos_path = "${cfg.statePath}/repositories";
repos_path: "${cfg.statePath}/repositories" secret_file = "${cfg.statePath}/config/gitlab_shell_secret";
secret_file: "${cfg.statePath}/config/gitlab_shell_secret" log_file = "${cfg.statePath}/log/gitlab-shell.log";
log_file: "${cfg.statePath}/log/gitlab-shell.log" custom_hooks_dir = "${cfg.statePath}/custom_hooks";
custom_hooks_dir: "${cfg.statePath}/custom_hooks" redis = {
redis: bin = "${pkgs.redis}/bin/redis-cli";
bin: ${pkgs.redis}/bin/redis-cli host = "127.0.0.1";
host: 127.0.0.1 port = 6379;
port: 6379 database = 0;
database: 0 namespace = "resque:gitlab";
namespace: resque:gitlab };
''; };
redisYml = '' redisConfig.production.url = "redis://localhost:6379/";
production:
url: redis://localhost:6379/
'';
secretsYml = '' secretsConfig.production = {
production: secret_key_base = cfg.secrets.secret;
secret_key_base: ${cfg.secrets.secret} otp_key_base = cfg.secrets.otp;
otp_key_base: ${cfg.secrets.otp} db_key_base = cfg.secrets.db;
db_key_base: ${cfg.secrets.db} openid_connect_signing_key = cfg.secrets.jws;
openid_connect_signing_key: ${builtins.toJSON cfg.secrets.jws} };
'';
gitlabConfig = { gitlabConfig = {
# These are the default settings from config/gitlab.example.yml # These are the default settings from config/gitlab.example.yml
@ -115,12 +112,8 @@ let
upload_pack = true; upload_pack = true;
receive_pack = true; receive_pack = true;
}; };
workhorse = { workhorse.secret_file = "${cfg.statePath}/.gitlab_workhorse_secret";
secret_file = "${cfg.statePath}/.gitlab_workhorse_secret"; git.bin_path = "git";
};
git = {
bin_path = "git";
};
monitoring = { monitoring = {
ip_whitelist = [ "127.0.0.0/8" "::1/128" ]; ip_whitelist = [ "127.0.0.0/8" "::1/128" ];
sidekiq_exporter = { sidekiq_exporter = {
@ -138,7 +131,7 @@ let
HOME = "${cfg.statePath}/home"; HOME = "${cfg.statePath}/home";
UNICORN_PATH = "${cfg.statePath}/"; UNICORN_PATH = "${cfg.statePath}/";
GITLAB_PATH = "${cfg.packages.gitlab}/share/gitlab/"; GITLAB_PATH = "${cfg.packages.gitlab}/share/gitlab/";
GITLAB_STATE_PATH = "${cfg.statePath}"; GITLAB_STATE_PATH = cfg.statePath;
GITLAB_UPLOADS_PATH = "${cfg.statePath}/uploads"; GITLAB_UPLOADS_PATH = "${cfg.statePath}/uploads";
SCHEMA = "${cfg.statePath}/db/schema.rb"; SCHEMA = "${cfg.statePath}/db/schema.rb";
GITLAB_LOG_PATH = "${cfg.statePath}/log"; GITLAB_LOG_PATH = "${cfg.statePath}/log";
@ -146,13 +139,11 @@ let
GITLAB_SHELL_CONFIG_PATH = "${cfg.statePath}/shell/config.yml"; GITLAB_SHELL_CONFIG_PATH = "${cfg.statePath}/shell/config.yml";
GITLAB_SHELL_SECRET_PATH = "${cfg.statePath}/config/gitlab_shell_secret"; GITLAB_SHELL_SECRET_PATH = "${cfg.statePath}/config/gitlab_shell_secret";
GITLAB_SHELL_HOOKS_PATH = "${cfg.statePath}/shell/hooks"; GITLAB_SHELL_HOOKS_PATH = "${cfg.statePath}/shell/hooks";
GITLAB_REDIS_CONFIG_FILE = pkgs.writeText "gitlab-redis.yml" redisYml; GITLAB_REDIS_CONFIG_FILE = pkgs.writeText "redis.yml" (builtins.toJSON redisConfig);
prometheus_multiproc_dir = "/run/gitlab"; prometheus_multiproc_dir = "/run/gitlab";
RAILS_ENV = "production"; RAILS_ENV = "production";
}; };
unicornConfig = builtins.readFile ./defaultUnicornConfig.rb;
gitlab-rake = pkgs.stdenv.mkDerivation rec { gitlab-rake = pkgs.stdenv.mkDerivation rec {
name = "gitlab-rake"; name = "gitlab-rake";
buildInputs = [ pkgs.makeWrapper ]; buildInputs = [ pkgs.makeWrapper ];
@ -162,7 +153,6 @@ let
mkdir -p $out/bin mkdir -p $out/bin
makeWrapper ${cfg.packages.gitlab.rubyEnv}/bin/rake $out/bin/gitlab-rake \ makeWrapper ${cfg.packages.gitlab.rubyEnv}/bin/rake $out/bin/gitlab-rake \
${concatStrings (mapAttrsToList (name: value: "--set ${name} '${value}' ") gitlabEnv)} \ ${concatStrings (mapAttrsToList (name: value: "--set ${name} '${value}' ") gitlabEnv)} \
--set GITLAB_CONFIG_PATH '${cfg.statePath}/config' \
--set PATH '${lib.makeBinPath [ pkgs.nodejs pkgs.gzip pkgs.git pkgs.gnutar config.services.postgresql.package pkgs.coreutils pkgs.procps ]}:$PATH' \ --set PATH '${lib.makeBinPath [ pkgs.nodejs pkgs.gzip pkgs.git pkgs.gnutar config.services.postgresql.package pkgs.coreutils pkgs.procps ]}:$PATH' \
--set RAKEOPT '-f ${cfg.packages.gitlab}/share/gitlab/Rakefile' \ --set RAKEOPT '-f ${cfg.packages.gitlab}/share/gitlab/Rakefile' \
--run 'cd ${cfg.packages.gitlab}/share/gitlab' --run 'cd ${cfg.packages.gitlab}/share/gitlab'
@ -306,7 +296,6 @@ in {
initialRootPassword = mkOption { initialRootPassword = mkOption {
type = types.str; type = types.str;
default = "UseNixOS!";
description = '' description = ''
Initial password of the root account if this is a new install. Initial password of the root account if this is a new install.
''; '';
@ -461,10 +450,30 @@ in {
} }
]; ];
systemd.tmpfiles.rules = [
"d /run/gitlab 0755 ${cfg.user} ${cfg.group} -"
"d ${gitlabEnv.HOME} 0750 ${cfg.user} ${cfg.group} -"
"d ${cfg.backupPath} 0750 ${cfg.user} ${cfg.group} -"
"d ${cfg.statePath}/builds 0750 ${cfg.user} ${cfg.group} -"
"d ${cfg.statePath}/config 0750 ${cfg.user} ${cfg.group} -"
"d ${cfg.statePath}/db 0750 ${cfg.user} ${cfg.group} -"
"d ${cfg.statePath}/log 0750 ${cfg.user} ${cfg.group} -"
"d ${cfg.statePath}/repositories 2770 ${cfg.user} ${cfg.group} -"
"d ${cfg.statePath}/shell 0750 ${cfg.user} ${cfg.group} -"
"d ${cfg.statePath}/tmp/pids 0750 ${cfg.user} ${cfg.group} -"
"d ${cfg.statePath}/tmp/sockets 0750 ${cfg.user} ${cfg.group} -"
"d ${cfg.statePath}/uploads 0700 ${cfg.user} ${cfg.group} -"
"d ${cfg.statePath}/custom_hooks/pre-receive.d 0700 ${cfg.user} ${cfg.group} -"
"d ${cfg.statePath}/custom_hooks/post-receive.d 0700 ${cfg.user} ${cfg.group} -"
"d ${cfg.statePath}/custom_hooks/update.d 0700 ${cfg.user} ${cfg.group} -"
"d ${gitlabConfig.production.shared.path}/artifacts 0750 ${cfg.user} ${cfg.group} -"
"d ${gitlabConfig.production.shared.path}/lfs-objects 0750 ${cfg.user} ${cfg.group} -"
"d ${gitlabConfig.production.shared.path}/pages 0750 ${cfg.user} ${cfg.group} -"
];
systemd.services.gitlab-sidekiq = { systemd.services.gitlab-sidekiq = {
after = [ "network.target" "redis.service" ]; after = [ "network.target" "redis.service" "gitlab.service" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
partOf = [ "gitlab.service" ];
environment = gitlabEnv; environment = gitlabEnv;
path = with pkgs; [ path = with pkgs; [
config.services.postgresql.package config.services.postgresql.package
@ -486,10 +495,8 @@ in {
}; };
systemd.services.gitaly = { systemd.services.gitaly = {
after = [ "network.target" "gitlab.service" ]; after = [ "network.target" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
environment.HOME = gitlabEnv.HOME;
environment.GITLAB_SHELL_CONFIG_PATH = gitlabEnv.GITLAB_SHELL_CONFIG_PATH;
path = with pkgs; [ gitAndTools.git cfg.packages.gitaly.rubyEnv cfg.packages.gitaly.rubyEnv.wrappedRuby ]; path = with pkgs; [ gitAndTools.git cfg.packages.gitaly.rubyEnv cfg.packages.gitaly.rubyEnv.wrappedRuby ];
serviceConfig = { serviceConfig = {
Type = "simple"; Type = "simple";
@ -505,8 +512,6 @@ in {
systemd.services.gitlab-workhorse = { systemd.services.gitlab-workhorse = {
after = [ "network.target" ]; after = [ "network.target" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
environment.HOME = gitlabEnv.HOME;
environment.GITLAB_SHELL_CONFIG_PATH = gitlabEnv.GITLAB_SHELL_CONFIG_PATH;
path = with pkgs; [ path = with pkgs; [
gitAndTools.git gitAndTools.git
gnutar gnutar
@ -514,10 +519,6 @@ in {
openssh openssh
gitlab-workhorse gitlab-workhorse
]; ];
preStart = ''
mkdir -p /run/gitlab
chown ${cfg.user}:${cfg.group} /run/gitlab
'';
serviceConfig = { serviceConfig = {
PermissionsStartOnly = true; # preStart must be run as root PermissionsStartOnly = true; # preStart must be run as root
Type = "simple"; Type = "simple";
@ -538,7 +539,7 @@ in {
}; };
systemd.services.gitlab = { systemd.services.gitlab = {
after = [ "network.target" "postgresql.service" "redis.service" ]; after = [ "gitlab-workhorse.service" "gitaly.service" "network.target" "postgresql.service" "redis.service" ];
requires = [ "gitlab-sidekiq.service" ]; requires = [ "gitlab-sidekiq.service" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
environment = gitlabEnv; environment = gitlabEnv;
@ -551,102 +552,76 @@ in {
gnupg gnupg
]; ];
preStart = '' preStart = ''
mkdir -p ${cfg.backupPath}
mkdir -p ${cfg.statePath}/builds
mkdir -p ${cfg.statePath}/repositories
mkdir -p ${gitlabConfig.production.shared.path}/artifacts
mkdir -p ${gitlabConfig.production.shared.path}/lfs-objects
mkdir -p ${gitlabConfig.production.shared.path}/pages
mkdir -p ${cfg.statePath}/log
mkdir -p ${cfg.statePath}/tmp/pids
mkdir -p ${cfg.statePath}/tmp/sockets
mkdir -p ${cfg.statePath}/shell
mkdir -p ${cfg.statePath}/db
mkdir -p ${cfg.statePath}/uploads
mkdir -p ${cfg.statePath}/custom_hooks/pre-receive.d
mkdir -p ${cfg.statePath}/custom_hooks/post-receive.d
mkdir -p ${cfg.statePath}/custom_hooks/update.d
rm -rf ${cfg.statePath}/config ${cfg.statePath}/shell/hooks
mkdir -p ${cfg.statePath}/config
${pkgs.openssl}/bin/openssl rand -hex 32 > ${cfg.statePath}/config/gitlab_shell_secret
mkdir -p /run/gitlab
mkdir -p ${cfg.statePath}/log
[ -d /run/gitlab/log ] || ln -sf ${cfg.statePath}/log /run/gitlab/log
[ -d /run/gitlab/tmp ] || ln -sf ${cfg.statePath}/tmp /run/gitlab/tmp
[ -d /run/gitlab/uploads ] || ln -sf ${cfg.statePath}/uploads /run/gitlab/uploads
ln -sf $GITLAB_SHELL_CONFIG_PATH /run/gitlab/shell-config.yml
chown -R ${cfg.user}:${cfg.group} /run/gitlab
# Prepare home directory
mkdir -p ${gitlabEnv.HOME}/.ssh
touch ${gitlabEnv.HOME}/.ssh/authorized_keys
chown -R ${cfg.user}:${cfg.group} ${gitlabEnv.HOME}/
cp -rf ${cfg.packages.gitlab}/share/gitlab/db/* ${cfg.statePath}/db cp -rf ${cfg.packages.gitlab}/share/gitlab/db/* ${cfg.statePath}/db
cp -rf ${cfg.packages.gitlab}/share/gitlab/config.dist/* ${cfg.statePath}/config rm -rf ${cfg.statePath}/config
${optionalString cfg.smtp.enable '' mkdir ${cfg.statePath}/config
ln -sf ${smtpSettings} ${cfg.statePath}/config/initializers/smtp_settings.rb
''}
ln -sf ${cfg.statePath}/config /run/gitlab/config
if [ -e ${cfg.statePath}/lib ]; then if [ -e ${cfg.statePath}/lib ]; then
rm ${cfg.statePath}/lib rm ${cfg.statePath}/lib
fi fi
ln -sf ${pkgs.gitlab}/share/gitlab/lib ${cfg.statePath}/lib
ln -sf ${cfg.packages.gitlab}/share/gitlab/lib ${cfg.statePath}/lib
[ -L /run/gitlab/config ] || ln -sf ${cfg.statePath}/config /run/gitlab/config
[ -L /run/gitlab/log ] || ln -sf ${cfg.statePath}/log /run/gitlab/log
[ -L /run/gitlab/tmp ] || ln -sf ${cfg.statePath}/tmp /run/gitlab/tmp
[ -L /run/gitlab/uploads ] || ln -sf ${cfg.statePath}/uploads /run/gitlab/uploads
${optionalString cfg.smtp.enable ''
ln -sf ${smtpSettings} ${cfg.statePath}/config/initializers/smtp_settings.rb
''}
cp ${cfg.packages.gitlab}/share/gitlab/VERSION ${cfg.statePath}/VERSION cp ${cfg.packages.gitlab}/share/gitlab/VERSION ${cfg.statePath}/VERSION
cp -rf ${cfg.packages.gitlab}/share/gitlab/config.dist/* ${cfg.statePath}/config
${pkgs.openssl}/bin/openssl rand -hex 32 > ${cfg.statePath}/config/gitlab_shell_secret
# JSON is a subset of YAML # JSON is a subset of YAML
ln -fs ${pkgs.writeText "gitlab.yml" (builtins.toJSON gitlabConfig)} ${cfg.statePath}/config/gitlab.yml ln -sf ${pkgs.writeText "gitlab.yml" (builtins.toJSON gitlabConfig)} ${cfg.statePath}/config/gitlab.yml
ln -fs ${pkgs.writeText "database.yml" databaseYml} ${cfg.statePath}/config/database.yml ln -sf ${pkgs.writeText "database.yml" (builtins.toJSON databaseConfig)} ${cfg.statePath}/config/database.yml
ln -fs ${pkgs.writeText "secrets.yml" secretsYml} ${cfg.statePath}/config/secrets.yml ln -sf ${pkgs.writeText "secrets.yml" (builtins.toJSON secretsConfig)} ${cfg.statePath}/config/secrets.yml
ln -fs ${pkgs.writeText "unicorn.rb" unicornConfig} ${cfg.statePath}/config/unicorn.rb ln -sf ${./defaultUnicornConfig.rb} ${cfg.statePath}/config/unicorn.rb
# Install the shell required to push repositories
ln -sf ${pkgs.writeText "config.yml" (builtins.toJSON gitlabShellConfig)} /run/gitlab/shell-config.yml
[ -L ${cfg.statePath}/shell/hooks ] || ln -sf ${cfg.packages.gitlab-shell}/hooks ${cfg.statePath}/shell/hooks
${cfg.packages.gitlab-shell}/bin/install
chown -R ${cfg.user}:${cfg.group} ${cfg.statePath}/ chown -R ${cfg.user}:${cfg.group} ${cfg.statePath}/
chmod -R ug+rwX,o-rwx+X ${cfg.statePath}/ chmod -R ug+rwX,o-rwx+X ${cfg.statePath}/
chown -R ${cfg.user}:${cfg.group} /run/gitlab
# Install the shell required to push repositories if ! test -e "${cfg.statePath}/db-created"; then
ln -fs ${pkgs.writeText "config.yml" gitlabShellYml} "$GITLAB_SHELL_CONFIG_PATH" if [ "${cfg.databaseHost}" = "127.0.0.1" ]; then
ln -fs ${cfg.packages.gitlab-shell}/hooks "$GITLAB_SHELL_HOOKS_PATH"
${cfg.packages.gitlab-shell}/bin/install
if [ "${cfg.databaseHost}" = "127.0.0.1" ]; then
if ! test -e "${cfg.statePath}/db-created"; then
${pkgs.sudo}/bin/sudo -u ${pgSuperUser} psql postgres -c "CREATE ROLE ${cfg.databaseUsername} WITH LOGIN NOCREATEDB NOCREATEROLE ENCRYPTED PASSWORD '${cfg.databasePassword}'" ${pkgs.sudo}/bin/sudo -u ${pgSuperUser} psql postgres -c "CREATE ROLE ${cfg.databaseUsername} WITH LOGIN NOCREATEDB NOCREATEROLE ENCRYPTED PASSWORD '${cfg.databasePassword}'"
${pkgs.sudo}/bin/sudo -u ${pgSuperUser} ${config.services.postgresql.package}/bin/createdb --owner ${cfg.databaseUsername} ${cfg.databaseName} ${pkgs.sudo}/bin/sudo -u ${pgSuperUser} ${config.services.postgresql.package}/bin/createdb --owner ${cfg.databaseUsername} ${cfg.databaseName}
touch "${cfg.statePath}/db-created"
# enable required pg_trgm extension for gitlab
${pkgs.sudo}/bin/sudo -u ${pgSuperUser} psql ${cfg.databaseName} -c "CREATE EXTENSION IF NOT EXISTS pg_trgm"
fi fi
# enable required pg_trgm extension for gitlab ${pkgs.sudo}/bin/sudo -u ${cfg.user} -H ${gitlab-rake}/bin/gitlab-rake db:schema:load
${pkgs.sudo}/bin/sudo -u ${pgSuperUser} psql ${cfg.databaseName} -c "CREATE EXTENSION IF NOT EXISTS pg_trgm"
touch "${cfg.statePath}/db-created"
fi fi
# Always do the db migrations just to be sure the database is up-to-date # Always do the db migrations just to be sure the database is up-to-date
${gitlab-rake}/bin/gitlab-rake db:migrate RAILS_ENV=production ${pkgs.sudo}/bin/sudo -u ${cfg.user} -H ${gitlab-rake}/bin/gitlab-rake db:migrate
# The gitlab:setup task is horribly broken somehow, the db:migrate
# task above and the db:seed_fu below will do the same for setting
# up the initial database
if ! test -e "${cfg.statePath}/db-seeded"; then if ! test -e "${cfg.statePath}/db-seeded"; then
${gitlab-rake}/bin/gitlab-rake db:seed_fu RAILS_ENV=production \ ${pkgs.sudo}/bin/sudo -u ${cfg.user} ${gitlab-rake}/bin/gitlab-rake db:seed_fu \
GITLAB_ROOT_PASSWORD='${cfg.initialRootPassword}' GITLAB_ROOT_EMAIL='${cfg.initialRootEmail}' GITLAB_ROOT_PASSWORD='${cfg.initialRootPassword}' GITLAB_ROOT_EMAIL='${cfg.initialRootEmail}'
touch "${cfg.statePath}/db-seeded" touch "${cfg.statePath}/db-seeded"
fi fi
# The gitlab:shell:setup regenerates the authorized_keys file so that # The gitlab:shell:setup regenerates the authorized_keys file so that
# the store path to the gitlab-shell in it gets updated # the store path to the gitlab-shell in it gets updated
${pkgs.sudo}/bin/sudo -u ${cfg.user} force=yes ${gitlab-rake}/bin/gitlab-rake gitlab:shell:setup RAILS_ENV=production ${pkgs.sudo}/bin/sudo -u ${cfg.user} -H force=yes ${gitlab-rake}/bin/gitlab-rake gitlab:shell:setup
# The gitlab:shell:create_hooks task seems broken for fixing links # The gitlab:shell:create_hooks task seems broken for fixing links
# so we instead delete all the hooks and create them anew # so we instead delete all the hooks and create them anew
rm -f ${cfg.statePath}/repositories/**/*.git/hooks rm -f ${cfg.statePath}/repositories/**/*.git/hooks
${gitlab-rake}/bin/gitlab-rake gitlab:shell:create_hooks RAILS_ENV=production ${pkgs.sudo}/bin/sudo -u ${cfg.user} -H ${gitlab-rake}/bin/gitlab-rake gitlab:shell:create_hooks
${pkgs.sudo}/bin/sudo -u ${cfg.user} -H ${pkgs.git}/bin/git config --global core.autocrlf "input"
# Change permissions in the last step because some of the # Change permissions in the last step because some of the
# intermediary scripts like to create directories as root. # intermediary scripts like to create directories as root.
chown -R ${cfg.user}:${cfg.group} ${cfg.statePath}
chmod -R ug+rwX,o-rwx+X ${cfg.statePath}
chmod -R u+rwX,go-rwx+X ${gitlabEnv.HOME} chmod -R u+rwX,go-rwx+X ${gitlabEnv.HOME}
chmod -R ug+rwX,o-rwx ${cfg.statePath}/repositories chmod -R ug+rwX,o-rwx ${cfg.statePath}/repositories
chmod -R ug-s ${cfg.statePath}/repositories chmod -R ug-s ${cfg.statePath}/repositories

View File

@ -157,6 +157,7 @@ in {
Restart = "on-failure"; Restart = "on-failure";
ProtectSystem = "strict"; ProtectSystem = "strict";
ReadWritePaths = "${cfg.configDir}"; ReadWritePaths = "${cfg.configDir}";
KillSignal = "SIGINT";
PrivateTmp = true; PrivateTmp = true;
RemoveIPC = true; RemoveIPC = true;
}; };

View File

@ -62,11 +62,15 @@ let
''} ''}
$extraOptions $extraOptions
END END
'' + optionalString cfg.checkConfig '' '' + optionalString cfg.checkConfig (
echo "Checking that Nix can read nix.conf..." if pkgs.stdenv.hostPlatform != pkgs.stdenv.buildPlatform then ''
ln -s $out ./nix.conf echo "Ignore nix.checkConfig when cross-compiling"
NIX_CONF_DIR=$PWD ${cfg.package}/bin/nix show-config >/dev/null '' else ''
''); echo "Checking that Nix can read nix.conf..."
ln -s $out ./nix.conf
NIX_CONF_DIR=$PWD ${cfg.package}/bin/nix show-config >/dev/null
'')
);
in in

View File

@ -6,11 +6,8 @@ let
cfg = config.services.packagekit; cfg = config.services.packagekit;
backend = "nix";
packagekitConf = '' packagekitConf = ''
[Daemon] [Daemon]
DefaultBackend=${backend}
KeepCache=false KeepCache=false
''; '';

View File

@ -0,0 +1,116 @@
{ options, config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.alerta;
alertaConf = pkgs.writeTextFile {
name = "alertad.conf";
text = ''
DATABASE_URL = '${cfg.databaseUrl}'
DATABASE_NAME = '${cfg.databaseName}'
LOG_FILE = '${cfg.logDir}/alertad.log'
LOG_FORMAT = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
CORS_ORIGINS = [ ${concatMapStringsSep ", " (s: "\"" + s + "\"") cfg.corsOrigins} ];
AUTH_REQUIRED = ${if cfg.authenticationRequired then "True" else "False"}
SIGNUP_ENABLED = ${if cfg.signupEnabled then "True" else "False"}
${cfg.extraConfig}
'';
};
in
{
options.services.alerta = {
enable = mkEnableOption "alerta";
port = mkOption {
type = types.int;
default = 5000;
description = "Port of Alerta";
};
bind = mkOption {
type = types.str;
default = "0.0.0.0";
example = literalExample "0.0.0.0";
description = "Address to bind to. The default is to bind to all addresses";
};
logDir = mkOption {
type = types.path;
description = "Location where the logfiles are stored";
default = "/var/log/alerta";
};
databaseUrl = mkOption {
type = types.str;
description = "URL of the MongoDB or PostgreSQL database to connect to";
default = "mongodb://localhost";
example = "mongodb://localhost";
};
databaseName = mkOption {
type = types.str;
description = "Name of the database instance to connect to";
default = "monitoring";
example = "monitoring";
};
corsOrigins = mkOption {
type = types.listOf types.str;
description = "List of URLs that can access the API for Cross-Origin Resource Sharing (CORS)";
example = [ "http://localhost" "http://localhost:5000" ];
default = [ "http://localhost" "http://localhost:5000" ];
};
authenticationRequired = mkOption {
type = types.bool;
description = "Whether users must authenticate when using the web UI or command-line tool";
default = false;
};
signupEnabled = mkOption {
type = types.bool;
description = "Whether to prevent sign-up of new users via the web UI";
default = true;
};
extraConfig = mkOption {
description = "These lines go into alertad.conf verbatim.";
default = "";
type = types.lines;
};
};
config = mkIf cfg.enable {
systemd.services.alerta = {
description = "Alerta Monitoring System";
wantedBy = [ "multi-user.target" ];
after = [ "networking.target" ];
environment = {
ALERTA_SVR_CONF_FILE = alertaConf;
};
serviceConfig = {
ExecStart = "${pkgs.python36Packages.alerta-server}/bin/alertad run --port ${toString cfg.port} --host ${cfg.bind}";
User = "alerta";
Group = "alerta";
PermissionsStartOnly = true;
};
preStart = ''
mkdir -p ${cfg.logDir}
chown alerta:alerta ${cfg.logDir}
'';
};
environment.systemPackages = [ pkgs.python36Packages.alerta ];
users.users.alerta = {
uid = config.ids.uids.alerta;
description = "Alerta user";
};
users.groups.alerta = {
gid = config.ids.gids.alerta;
};
};
}

View File

@ -0,0 +1,66 @@
{ options, config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.grafana_reporter;
in {
options.services.grafana_reporter = {
enable = mkEnableOption "grafana_reporter";
grafana = {
protocol = mkOption {
description = "Grafana protocol.";
default = "http";
type = types.enum ["http" "https"];
};
addr = mkOption {
description = "Grafana address.";
default = "127.0.0.1";
type = types.str;
};
port = mkOption {
description = "Grafana port.";
default = 3000;
type = types.int;
};
};
addr = mkOption {
description = "Listening address.";
default = "127.0.0.1";
type = types.str;
};
port = mkOption {
description = "Listening port.";
default = 8686;
type = types.int;
};
templateDir = mkOption {
description = "Optional template directory to use custom tex templates";
default = "${pkgs.grafana_reporter}";
type = types.str;
};
};
config = mkIf cfg.enable {
systemd.services.grafana_reporter = {
description = "Grafana Reporter Service Daemon";
wantedBy = ["multi-user.target"];
after = ["network.target"];
serviceConfig = let
args = lib.concatSepString " " [
"-proto ${cfg.grafana.protocol}://"
"-ip ${cfg.grafana.addr}:${toString cfg.grafana.port}"
"-port :${toString cfg.port}"
"-templates ${cfg.templateDir}"
];
in {
ExecStart = "${pkgs.grafana_reporter.bin}/bin/grafana-reporter ${args}";
};
};
};
}

View File

@ -0,0 +1,192 @@
{ options, config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.kapacitor;
kapacitorConf = pkgs.writeTextFile {
name = "kapacitord.conf";
text = ''
hostname="${config.networking.hostName}"
data_dir="${cfg.dataDir}"
[http]
bind-address = "${cfg.bind}:${toString cfg.port}"
log-enabled = false
auth-enabled = false
[task]
dir = "${cfg.dataDir}/tasks"
snapshot-interval = "${cfg.taskSnapshotInterval}"
[replay]
dir = "${cfg.dataDir}/replay"
[storage]
boltdb = "${cfg.dataDir}/kapacitor.db"
${optionalString (cfg.loadDirectory != null) ''
[load]
enabled = true
dir = "${cfg.loadDirectory}"
''}
${optionalString (cfg.defaultDatabase.enable) ''
[[influxdb]]
name = "default"
enabled = true
default = true
urls = [ "${cfg.defaultDatabase.url}" ]
username = "${cfg.defaultDatabase.username}"
password = "${cfg.defaultDatabase.password}"
''}
${optionalString (cfg.alerta.enable) ''
[alerta]
enabled = true
url = "${cfg.alerta.url}"
token = "${cfg.alerta.token}"
environment = "${cfg.alerta.environment}"
origin = "${cfg.alerta.origin}"
''}
${cfg.extraConfig}
'';
};
in
{
options.services.kapacitor = {
enable = mkEnableOption "kapacitor";
dataDir = mkOption {
type = types.path;
example = "/var/lib/kapacitor";
default = "/var/lib/kapacitor";
description = "Location where Kapacitor stores its state";
};
port = mkOption {
type = types.int;
default = 9092;
description = "Port of Kapacitor";
};
bind = mkOption {
type = types.str;
default = "";
example = literalExample "0.0.0.0";
description = "Address to bind to. The default is to bind to all addresses";
};
extraConfig = mkOption {
description = "These lines go into kapacitord.conf verbatim.";
default = "";
type = types.lines;
};
user = mkOption {
type = types.str;
default = "kapacitor";
description = "User account under which Kapacitor runs";
};
group = mkOption {
type = types.str;
default = "kapacitor";
description = "Group under which Kapacitor runs";
};
taskSnapshotInterval = mkOption {
type = types.str;
description = "Specifies how often to snapshot the task state (in InfluxDB time units)";
default = "1m0s";
example = "1m0s";
};
loadDirectory = mkOption {
type = types.nullOr types.path;
description = "Directory where to load services from, such as tasks, templates and handlers (or null to disable service loading on startup)";
default = null;
};
defaultDatabase = {
enable = mkEnableOption "kapacitor.defaultDatabase";
url = mkOption {
description = "The URL to an InfluxDB server that serves as the default database";
example = "http://localhost:8086";
type = types.string;
};
username = mkOption {
description = "The username to connect to the remote InfluxDB server";
type = types.string;
};
password = mkOption {
description = "The password to connect to the remote InfluxDB server";
type = types.string;
};
};
alerta = {
enable = mkEnableOption "kapacitor alerta integration";
url = mkOption {
description = "The URL to the Alerta REST API";
default = "http://localhost:5000";
example = "http://localhost:5000";
type = types.string;
};
token = mkOption {
description = "Default Alerta authentication token";
type = types.str;
default = "";
};
environment = mkOption {
description = "Default Alerta environment";
type = types.str;
default = "Production";
};
origin = mkOption {
description = "Default origin of alert";
type = types.str;
default = "kapacitor";
};
};
};
config = mkIf cfg.enable {
environment.systemPackages = [ pkgs.kapacitor ];
systemd.services.kapacitor = {
description = "Kapacitor Real-Time Stream Processing Engine";
wantedBy = [ "multi-user.target" ];
after = [ "networking.target" ];
serviceConfig = {
ExecStart = "${pkgs.kapacitor}/bin/kapacitord -config ${kapacitorConf}";
User = "kapacitor";
Group = "kapacitor";
PermissionsStartOnly = true;
};
preStart = ''
mkdir -p ${cfg.dataDir}
chown ${cfg.user}:${cfg.group} ${cfg.dataDir}
'';
};
users.users.kapacitor = {
uid = config.ids.uids.kapacitor;
description = "Kapacitor user";
home = cfg.dataDir;
};
users.groups.kapacitor = {
gid = config.ids.gids.kapacitor;
};
};
}

View File

@ -1,33 +1,30 @@
# Monit system watcher
# http://mmonit.org/monit/
{config, pkgs, lib, ...}: {config, pkgs, lib, ...}:
let inherit (lib) mkOption mkIf; with lib;
let
cfg = config.services.monit;
in in
{ {
options = { options.services.monit = {
services.monit = {
enable = mkOption { enable = mkEnableOption "Monit";
default = false;
description = '' config = mkOption {
Whether to run Monit system watcher. type = types.lines;
''; default = "";
}; description = "monitrc content";
config = mkOption {
default = "";
description = "monitrc content";
};
}; };
}; };
config = mkIf config.services.monit.enable { config = mkIf cfg.enable {
environment.systemPackages = [ pkgs.monit ]; environment.systemPackages = [ pkgs.monit ];
environment.etc."monitrc" = { environment.etc."monitrc" = {
text = config.services.monit.config; text = cfg.config;
mode = "0400"; mode = "0400";
}; };

View File

@ -10,6 +10,13 @@ let
# Get a submodule without any embedded metadata: # Get a submodule without any embedded metadata:
_filter = x: filterAttrs (k: v: k != "_module") x; _filter = x: filterAttrs (k: v: k != "_module") x;
# a wrapper that verifies that the configuration is valid
promtoolCheck = what: name: file: pkgs.runCommand "${name}-${what}-checked"
{ buildInputs = [ cfg.package ]; } ''
ln -s ${file} $out
promtool ${what} $out
'';
# Pretty-print JSON to a file # Pretty-print JSON to a file
writePrettyJSON = name: x: writePrettyJSON = name: x:
pkgs.runCommand name { } '' pkgs.runCommand name { } ''
@ -19,18 +26,19 @@ let
# This becomes the main config file # This becomes the main config file
promConfig = { promConfig = {
global = cfg.globalConfig; global = cfg.globalConfig;
rule_files = cfg.ruleFiles ++ [ rule_files = map (promtoolCheck "check-rules" "rules") (cfg.ruleFiles ++ [
(pkgs.writeText "prometheus.rules" (concatStringsSep "\n" cfg.rules)) (pkgs.writeText "prometheus.rules" (concatStringsSep "\n" cfg.rules))
]; ]);
scrape_configs = cfg.scrapeConfigs; scrape_configs = cfg.scrapeConfigs;
}; };
generatedPrometheusYml = writePrettyJSON "prometheus.yml" promConfig; generatedPrometheusYml = writePrettyJSON "prometheus.yml" promConfig;
prometheusYml = prometheusYml = let
if cfg.configText != null then yml = if cfg.configText != null then
pkgs.writeText "prometheus.yml" cfg.configText pkgs.writeText "prometheus.yml" cfg.configText
else generatedPrometheusYml; else generatedPrometheusYml;
in promtoolCheck "check-config" "prometheus.yml" yml;
cmdlineArgs = cfg.extraFlags ++ [ cmdlineArgs = cfg.extraFlags ++ [
"-storage.local.path=${cfg.dataDir}/metrics" "-storage.local.path=${cfg.dataDir}/metrics"
@ -376,6 +384,15 @@ in {
''; '';
}; };
package = mkOption {
type = types.package;
default = pkgs.prometheus;
defaultText = "pkgs.prometheus";
description = ''
The prometheus package that should be used.
'';
};
listenAddress = mkOption { listenAddress = mkOption {
type = types.str; type = types.str;
default = "0.0.0.0:9090"; default = "0.0.0.0:9090";
@ -495,7 +512,7 @@ in {
after = [ "network.target" ]; after = [ "network.target" ];
script = '' script = ''
#!/bin/sh #!/bin/sh
exec ${pkgs.prometheus}/bin/prometheus \ exec ${cfg.package}/bin/prometheus \
${concatStringsSep " \\\n " cmdlineArgs} ${concatStringsSep " \\\n " cmdlineArgs}
''; '';
serviceConfig = { serviceConfig = {

View File

@ -198,6 +198,9 @@ in
install -m 0755 -d /var/log/glusterfs install -m 0755 -d /var/log/glusterfs
''; '';
# glustereventsd uses the `gluster` executable
path = [ glusterfs ];
serviceConfig = { serviceConfig = {
Type="simple"; Type="simple";
Environment="PYTHONPATH=${glusterfs}/usr/lib/python2.7/site-packages"; Environment="PYTHONPATH=${glusterfs}/usr/lib/python2.7/site-packages";

View File

@ -33,7 +33,7 @@ let
purple_plugin_path = purple_plugin_path =
lib.concatMapStringsSep ":" lib.concatMapStringsSep ":"
(plugin: "${plugin}/lib/pidgin/") (plugin: "${plugin}/lib/pidgin/:${plugin}/lib/purple-2/")
cfg.libpurple_plugins cfg.libpurple_plugins
; ;

View File

@ -93,6 +93,8 @@ in
services.timesyncd.enable = mkForce false; services.timesyncd.enable = mkForce false;
systemd.services.systemd-timedated.environment = { SYSTEMD_TIMEDATED_NTP_SERVICES = "chronyd.service"; };
systemd.services.chronyd = systemd.services.chronyd =
{ description = "chrony NTP daemon"; { description = "chrony NTP daemon";

View File

@ -6,9 +6,10 @@ let
dataDir = "/var/lib/consul"; dataDir = "/var/lib/consul";
cfg = config.services.consul; cfg = config.services.consul;
configOptions = { data_dir = dataDir; } // configOptions = {
(if cfg.webUi then { ui_dir = "${cfg.package.ui}"; } else { }) // data_dir = dataDir;
cfg.extraConfig; ui = cfg.webUi;
} // cfg.extraConfig;
configFiles = [ "/etc/consul.json" "/etc/consul-addrs.json" ] configFiles = [ "/etc/consul.json" "/etc/consul-addrs.json" ]
++ cfg.extraConfigFiles; ++ cfg.extraConfigFiles;

View File

@ -67,6 +67,8 @@ in
environment.systemPackages = [ pkgs.ntp ]; environment.systemPackages = [ pkgs.ntp ];
services.timesyncd.enable = mkForce false; services.timesyncd.enable = mkForce false;
systemd.services.systemd-timedated.environment = { SYSTEMD_TIMEDATED_NTP_SERVICES = "ntpd.service"; };
users.users = singleton users.users = singleton
{ name = ntpUser; { name = ntpUser;
uid = config.ids.uids.ntp; uid = config.ids.uids.ntp;

View File

@ -267,4 +267,6 @@ in
"ip46tables -t nat -D OUTPUT -p tcp ${redCond block} -j ${chain} 2>/dev/null || true" "ip46tables -t nat -D OUTPUT -p tcp ${redCond block} -j ${chain} 2>/dev/null || true"
) cfg.redsocks; ) cfg.redsocks;
}; };
meta.maintainers = with lib.maintainers; [ ekleog ];
} }

View File

@ -130,7 +130,7 @@ in
}; };
ports = mkOption { ports = mkOption {
type = types.listOf types.int; type = types.listOf types.port;
default = [22]; default = [22];
description = '' description = ''
Specifies on which ports the SSH daemon listens. Specifies on which ports the SSH daemon listens.

View File

@ -62,9 +62,21 @@ in {
dataDir = mkOption { dataDir = mkOption {
type = types.path; type = types.path;
default = "/var/lib/syncthing"; default = "/var/lib/syncthing";
description = ''
Path where synced directories will exist.
'';
};
configDir = mkOption {
type = types.path;
description = '' description = ''
Path where the settings and keys will exist. Path where the settings and keys will exist.
''; '';
default =
let
nixos = config.system.stateVersion;
cond = versionAtLeast nixos "19.03";
in cfg.dataDir + (optionalString cond "/.config/syncthing");
}; };
openDefaultPorts = mkOption { openDefaultPorts = mkOption {
@ -144,7 +156,7 @@ in {
${cfg.package}/bin/syncthing \ ${cfg.package}/bin/syncthing \
-no-browser \ -no-browser \
-gui-address=${cfg.guiAddress} \ -gui-address=${cfg.guiAddress} \
-home=${cfg.dataDir} -home=${cfg.configDir}
''; '';
}; };
}; };

View File

@ -39,7 +39,8 @@ in
systemd.services.zerotierone = { systemd.services.zerotierone = {
description = "ZeroTierOne"; description = "ZeroTierOne";
path = [ cfg.package ]; path = [ cfg.package ];
after = [ "network.target" ]; bindsTo = [ "network-online.target" ];
after = [ "network-online.target" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
preStart = '' preStart = ''
mkdir -p /var/lib/zerotier-one/networks.d mkdir -p /var/lib/zerotier-one/networks.d

View File

@ -6,142 +6,105 @@ let
cfg = config.services.solr; cfg = config.services.solr;
# Assemble all jars needed for solr in
solrJars = pkgs.stdenv.mkDerivation {
name = "solr-jars";
src = pkgs.fetchurl {
url = http://archive.apache.org/dist/tomcat/tomcat-5/v5.5.36/bin/apache-tomcat-5.5.36.tar.gz;
sha256 = "01mzvh53wrs1p2ym765jwd00gl6kn8f9k3nhdrnhdqr8dhimfb2p";
};
installPhase = ''
mkdir -p $out/lib
cp common/lib/*.jar $out/lib/
ln -s ${pkgs.ant}/lib/ant/lib/ant.jar $out/lib/
ln -s ${cfg.solrPackage}/lib/ext/* $out/lib/
ln -s ${pkgs.jdk.home}/lib/tools.jar $out/lib/
'' + optionalString (cfg.extraJars != []) ''
for f in ${concatStringsSep " " cfg.extraJars}; do
cp $f $out/lib
done
'';
};
in {
{
options = { options = {
services.solr = { services.solr = {
enable = mkOption { enable = mkEnableOption "Enables the solr service.";
type = types.bool;
default = false;
description = ''
Enables the solr service.
'';
};
javaPackage = mkOption { package = mkOption {
type = types.package;
default = pkgs.jre;
defaultText = "pkgs.jre";
description = ''
Which Java derivation to use for running solr.
'';
};
solrPackage = mkOption {
type = types.package; type = types.package;
default = pkgs.solr; default = pkgs.solr;
defaultText = "pkgs.solr"; defaultText = "pkgs.solr";
description = '' description = "Which Solr package to use.";
Which solr derivation to use for running solr.
'';
}; };
extraJars = mkOption { port = mkOption {
type = types.listOf types.path; type = types.int;
default = []; default = 8983;
description = '' description = "Port on which Solr is ran.";
List of paths pointing to jars. Jars are copied to commonLibFolder to be available to java/solr.
'';
}; };
log4jConfiguration = mkOption { stateDir = mkOption {
type = types.lines; type = types.path;
default = '' default = "/var/lib/solr";
log4j.rootLogger=INFO, stdout description = "The solr home directory containing config, data, and logging files.";
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
'';
description = ''
Contents of the <literal>log4j.properties</literal> used. By default,
everything is logged to stdout (picked up by systemd) with level INFO.
'';
};
user = mkOption {
type = types.str;
description = ''
The user that should run the solr process and.
the working directories.
'';
};
group = mkOption {
type = types.str;
description = ''
The group that will own the working directory.
'';
};
solrHome = mkOption {
type = types.str;
description = ''
The solr home directory. It is your own responsibility to
make sure this directory contains a working solr configuration,
and is writeable by the the user running the solr service.
Failing to do so, the solr will not start properly.
'';
}; };
extraJavaOptions = mkOption { extraJavaOptions = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = []; default = [];
description = '' description = "Extra command line options given to the java process running Solr.";
Extra command line options given to the java process running
solr.
'';
}; };
extraWinstoneOptions = mkOption { user = mkOption {
type = types.listOf types.str; type = types.str;
default = []; default = "solr";
description = '' description = "User under which Solr is ran.";
Extra command line options given to the Winstone, which is };
the servlet container hosting solr.
''; group = mkOption {
type = types.str;
default = "solr";
description = "Group under which Solr is ran.";
}; };
}; };
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
services.winstone.solr = { environment.systemPackages = [ cfg.package ];
serviceName = "solr";
inherit (cfg) user group javaPackage; systemd.services.solr = {
warFile = "${cfg.solrPackage}/lib/solr.war"; after = [ "network.target" "remote-fs.target" "nss-lookup.target" "systemd-journald-dev-log.socket" ];
extraOptions = [ wantedBy = [ "multi-user.target" ];
"--commonLibFolder=${solrJars}/lib"
"--useJasper" environment = {
] ++ cfg.extraWinstoneOptions; SOLR_HOME = "${cfg.stateDir}/data";
extraJavaOptions = [ LOG4J_PROPS = "${cfg.stateDir}/log4j2.xml";
"-Dsolr.solr.home=${cfg.solrHome}" SOLR_LOGS_DIR = "${cfg.stateDir}/logs";
"-Dlog4j.configuration=file://${pkgs.writeText "log4j.properties" cfg.log4jConfiguration}" SOLR_PORT = "${toString cfg.port}";
] ++ cfg.extraJavaOptions; };
path = with pkgs; [
gawk
procps
];
preStart = ''
mkdir -p "${cfg.stateDir}/data";
mkdir -p "${cfg.stateDir}/logs";
if ! test -e "${cfg.stateDir}/data/solr.xml"; then
install -D -m0640 ${cfg.package}/server/solr/solr.xml "${cfg.stateDir}/data/solr.xml"
install -D -m0640 ${cfg.package}/server/solr/zoo.cfg "${cfg.stateDir}/data/zoo.cfg"
fi
if ! test -e "${cfg.stateDir}/log4j2.xml"; then
install -D -m0640 ${cfg.package}/server/resources/log4j2.xml "${cfg.stateDir}/log4j2.xml"
fi
'';
serviceConfig = {
User = cfg.user;
Group = cfg.group;
ExecStart="${cfg.package}/bin/solr start -f -a \"${concatStringsSep " " cfg.extraJavaOptions}\"";
ExecStop="${cfg.package}/bin/solr stop";
};
}; };
users.users = optionalAttrs (cfg.user == "solr") (singleton
{ name = "solr";
group = cfg.group;
home = cfg.stateDir;
createHome = true;
uid = config.ids.uids.solr;
});
users.groups = optionalAttrs (cfg.group == "solr") (singleton
{ name = "solr";
gid = config.ids.gids.solr;
});
}; };
} }

View File

@ -3,13 +3,20 @@
with lib; with lib;
let cfg = config.services.cloud-init; let cfg = config.services.cloud-init;
path = with pkgs; [ cloud-init nettools utillinux e2fsprogs shadow openssh iproute ]; path = with pkgs; [
cloud-init
iproute
nettools
openssh
shadow
utillinux
] ++ optional cfg.btrfs.enable btrfs-progs
++ optional cfg.ext4.enable e2fsprogs
;
in in
{ {
options = { options = {
services.cloud-init = { services.cloud-init = {
enable = mkOption { enable = mkOption {
type = types.bool; type = types.bool;
default = false; default = false;
@ -29,6 +36,22 @@ in
''; '';
}; };
btrfs.enable = mkOption {
type = types.bool;
default = false;
description = ''
Allow the cloud-init service to operate `btrfs` filesystem.
'';
};
ext4.enable = mkOption {
type = types.bool;
default = true;
description = ''
Allow the cloud-init service to operate `ext4` filesystem.
'';
};
config = mkOption { config = mkOption {
type = types.str; type = types.str;
default = '' default = ''

View File

@ -171,7 +171,12 @@ in {
dbhost = mkOption { dbhost = mkOption {
type = types.nullOr types.str; type = types.nullOr types.str;
default = "localhost"; default = "localhost";
description = "Database host."; description = ''
Database host.
Note: for using Unix authentication with PostgreSQL, this should be
set to <literal>/tmp</literal>.
'';
}; };
dbport = mkOption { dbport = mkOption {
type = with types; nullOr (either int str); type = with types; nullOr (either int str);

View File

@ -31,10 +31,26 @@ in
''; '';
}; };
purifyOnStart = mkOption {
type = types.bool;
default = false;
description = ''
On startup, the `baseDir` directory is populated with various files,
subdirectories and symlinks. If this option is enabled, these items
(except for the `logs` and `work` subdirectories) are first removed.
This prevents interference from remainders of an old configuration
(libraries, webapps, etc.), so it's recommended to enable this option.
'';
};
baseDir = mkOption { baseDir = mkOption {
type = lib.types.path; type = lib.types.path;
default = "/var/tomcat"; default = "/var/tomcat";
description = "Location where Tomcat stores configuration files, webapplications and logfiles"; description = ''
Location where Tomcat stores configuration files, web applications
and logfiles. Note that it is partially cleared on each service startup
if `purifyOnStart` is enabled.
'';
}; };
logDirs = mkOption { logDirs = mkOption {
@ -197,6 +213,15 @@ in
after = [ "network.target" ]; after = [ "network.target" ];
preStart = '' preStart = ''
${lib.optionalString cfg.purifyOnStart ''
# Delete most directories/symlinks we create from the existing base directory,
# to get rid of remainders of an old configuration.
# The list of directories to delete is taken from the "mkdir" command below,
# excluding "logs" (because logs are valuable) and "work" (because normally
# session files are there), and additionally including "bin".
rm -rf ${cfg.baseDir}/{conf,virtualhosts,temp,lib,shared/lib,webapps,bin}
''}
# Create the base directory # Create the base directory
mkdir -p \ mkdir -p \
${cfg.baseDir}/{conf,virtualhosts,logs,temp,lib,shared/lib,webapps,work} ${cfg.baseDir}/{conf,virtualhosts,logs,temp,lib,shared/lib,webapps,work}

View File

@ -22,7 +22,7 @@ let
# This wrapper ensures that we actually get themes # This wrapper ensures that we actually get themes
makeWrapper ${pkgs.lightdm_gtk_greeter}/sbin/lightdm-gtk-greeter \ makeWrapper ${pkgs.lightdm_gtk_greeter}/sbin/lightdm-gtk-greeter \
$out/greeter \ $out/greeter \
--prefix PATH : "${pkgs.glibc.bin}/bin" \ --prefix PATH : "${lib.getBin pkgs.stdenv.cc.libc}/bin" \
--set GDK_PIXBUF_MODULE_FILE "${pkgs.librsvg.out}/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache" \ --set GDK_PIXBUF_MODULE_FILE "${pkgs.librsvg.out}/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache" \
--set GTK_PATH "${theme}:${pkgs.gtk3.out}" \ --set GTK_PATH "${theme}:${pkgs.gtk3.out}" \
--set GTK_EXE_PREFIX "${theme}" \ --set GTK_EXE_PREFIX "${theme}" \

View File

@ -208,15 +208,11 @@ in
} }
]; ];
services.xserver.displayManager.job = { # lightdm relaunches itself via just `lightdm`, so needs to be on the PATH
logToFile = true; services.xserver.displayManager.job.execCmd = ''
export PATH=${lightdm}/sbin:$PATH
# lightdm relaunches itself via just `lightdm`, so needs to be on the PATH exec ${lightdm}/sbin/lightdm
execCmd = '' '';
export PATH=${lightdm}/sbin:$PATH
exec ${lightdm}/sbin/lightdm
'';
};
environment.etc."lightdm/lightdm.conf".source = lightdmConf; environment.etc."lightdm/lightdm.conf".source = lightdmConf;
environment.etc."lightdm/users.conf".source = usersConf; environment.etc."lightdm/users.conf".source = usersConf;

View File

@ -209,8 +209,6 @@ in
]; ];
services.xserver.displayManager.job = { services.xserver.displayManager.job = {
logToFile = true;
environment = { environment = {
# Load themes from system environment # Load themes from system environment
QT_PLUGIN_PATH = "/run/current-system/sw/" + pkgs.qt5.qtbase.qtPluginPrefix; QT_PLUGIN_PATH = "/run/current-system/sw/" + pkgs.qt5.qtbase.qtPluginPrefix;

View File

@ -219,30 +219,26 @@ in
VideoRam 192000 VideoRam 192000
''; '';
services.xserver.displayManager.job = { services.xserver.displayManager.job.execCmd = ''
logToFile = true; ${optionalString (cfg.pulseaudio)
"export PULSE_COOKIE=/var/run/pulse/.config/pulse/cookie"}
execCmd = '' exec ${pkgs.xpra}/bin/xpra start \
${optionalString (cfg.pulseaudio) --daemon=off \
"export PULSE_COOKIE=/var/run/pulse/.config/pulse/cookie"} --log-dir=/var/log \
exec ${pkgs.xpra}/bin/xpra start \ --log-file=xpra.log \
--daemon=off \ --opengl=on \
--log-dir=/var/log \ --clipboard=on \
--log-file=xpra.log \ --notifications=on \
--opengl=on \ --speaker=yes \
--clipboard=on \ --mdns=no \
--notifications=on \ --pulseaudio=no \
--speaker=yes \ ${optionalString (cfg.pulseaudio) "--sound-source=pulse"} \
--mdns=no \ --socket-dirs=/var/run/xpra \
--pulseaudio=no \ --xvfb="xpra_Xdummy ${concatStringsSep " " dmcfg.xserverArgs}" \
${optionalString (cfg.pulseaudio) "--sound-source=pulse"} \ ${optionalString (cfg.bindTcp != null) "--bind-tcp=${cfg.bindTcp}"} \
--socket-dirs=/var/run/xpra \ --auth=${cfg.auth} \
--xvfb="xpra_Xdummy ${concatStringsSep " " dmcfg.xserverArgs}" \ ${concatStringsSep " " cfg.extraOptions}
${optionalString (cfg.bindTcp != null) "--bind-tcp=${cfg.bindTcp}"} \ '';
--auth=${cfg.auth} \
${concatStringsSep " " cfg.extraOptions}
'';
};
services.xserver.terminateOnReset = false; services.xserver.terminateOnReset = false;

View File

@ -21,7 +21,8 @@ let
[ coreutils [ coreutils
gnugrep gnugrep
findutils findutils
glibc # needed for getent getent
stdenv.cc.libc # nscd in update-users-groups.pl
shadow shadow
nettools # needed for hostname nettools # needed for hostname
utillinux # needed for mount and mountpoint utillinux # needed for mount and mountpoint

View File

@ -246,10 +246,7 @@ checkFS() {
if [ "$fsType" = iso9660 -o "$fsType" = udf ]; then return 0; fi if [ "$fsType" = iso9660 -o "$fsType" = udf ]; then return 0; fi
# Don't check resilient COWs as they validate the fs structures at mount time # Don't check resilient COWs as they validate the fs structures at mount time
if [ "$fsType" = btrfs -o "$fsType" = zfs ]; then return 0; fi if [ "$fsType" = btrfs -o "$fsType" = zfs -o "$fsType" = bcachefs ]; then return 0; fi
# Skip fsck for bcachefs - not implemented yet.
if [ "$fsType" = bcachefs ]; then return 0; fi
# Skip fsck for nilfs2 - not needed by design and no fsck tool for this filesystem. # Skip fsck for nilfs2 - not needed by design and no fsck tool for this filesystem.
if [ "$fsType" = nilfs2 ]; then return 0; fi if [ "$fsType" = nilfs2 ]; then return 0; fi

View File

@ -147,7 +147,7 @@ let
${config.boot.initrd.extraUtilsCommands} ${config.boot.initrd.extraUtilsCommands}
# Copy ld manually since it isn't detected correctly # Copy ld manually since it isn't detected correctly
cp -pv ${pkgs.glibc.out}/lib/ld*.so.? $out/lib cp -pv ${pkgs.stdenv.cc.libc.out}/lib/ld*.so.? $out/lib
# Copy all of the needed libraries # Copy all of the needed libraries
find $out/bin $out/lib -type f | while read BIN; do find $out/bin $out/lib -type f | while read BIN; do

View File

@ -112,6 +112,7 @@ in {
environment.etc."systemd/nspawn".source = generateUnits "nspawn" units [] []; environment.etc."systemd/nspawn".source = generateUnits "nspawn" units [] [];
systemd.targets."multi-user".wants = [ "machines.target "];
}; };
} }

View File

@ -230,6 +230,8 @@ in
let let
fsToSkipCheck = [ "none" "bindfs" "btrfs" "zfs" "tmpfs" "nfs" "vboxsf" "glusterfs" ]; fsToSkipCheck = [ "none" "bindfs" "btrfs" "zfs" "tmpfs" "nfs" "vboxsf" "glusterfs" ];
skipCheck = fs: fs.noCheck || fs.device == "none" || builtins.elem fs.fsType fsToSkipCheck; skipCheck = fs: fs.noCheck || fs.device == "none" || builtins.elem fs.fsType fsToSkipCheck;
# https://wiki.archlinux.org/index.php/fstab#Filepath_spaces
escape = string: builtins.replaceStrings [ " " ] [ "\\040" ] string;
in '' in ''
# This is a generated file. Do not edit! # This is a generated file. Do not edit!
# #
@ -238,10 +240,10 @@ in
# Filesystems. # Filesystems.
${concatMapStrings (fs: ${concatMapStrings (fs:
(if fs.device != null then fs.device (if fs.device != null then escape fs.device
else if fs.label != null then "/dev/disk/by-label/${fs.label}" else if fs.label != null then "/dev/disk/by-label/${escape fs.label}"
else throw "No device specified for mount point ${fs.mountPoint}.") else throw "No device specified for mount point ${fs.mountPoint}.")
+ " " + fs.mountPoint + " " + escape fs.mountPoint
+ " " + fs.fsType + " " + fs.fsType
+ " " + builtins.concatStringsSep "," fs.options + " " + builtins.concatStringsSep "," fs.options
+ " 0" + " 0"

View File

@ -1,26 +1,65 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, utils, ... }:
with lib; with lib;
let let
inInitrd = any (fs: fs == "bcachefs") config.boot.initrd.supportedFilesystems; bootFs = filterAttrs (n: fs: (fs.fsType == "bcachefs") && (utils.fsNeededForBoot fs)) config.fileSystems;
commonFunctions = ''
prompt() {
local name="$1"
printf "enter passphrase for $name: "
}
tryUnlock() {
local name="$1"
local path="$2"
if bcachefs unlock -c $path > /dev/null 2> /dev/null; then # test for encryption
prompt $name
until bcachefs unlock $path 2> /dev/null; do # repeat until sucessfully unlocked
printf "unlocking failed!\n"
prompt $name
done
printf "unlocking successful.\n"
fi
}
'';
openCommand = name: fs:
let
# we need only unlock one device manually, and cannot pass multiple at once
# remove this adaptation when bcachefs implements mounting by filesystem uuid
# also, implement automatic waiting for the constituent devices when that happens
# bcachefs does not support mounting devices with colons in the path, ergo we don't (see #49671)
firstDevice = head (splitString ":" fs.device);
in
''
tryUnlock ${name} ${firstDevice}
'';
in in
{ {
config = mkIf (any (fs: fs == "bcachefs") config.boot.supportedFilesystems) { config = mkIf (elem "bcachefs" config.boot.supportedFilesystems) (mkMerge [
{
system.fsPackages = [ pkgs.bcachefs-tools ];
system.fsPackages = [ pkgs.bcachefs-tools ]; # use kernel package with bcachefs support until it's in mainline
boot.kernelPackages = pkgs.linuxPackages_testing_bcachefs;
}
# use kernel package with bcachefs support until it's in mainline (mkIf ((elem "bcachefs" config.boot.initrd.supportedFilesystems) || (bootFs != {})) {
boot.kernelPackages = pkgs.linuxPackages_testing_bcachefs; # the cryptographic modules are required only for decryption attempts
boot.initrd.availableKernelModules = mkIf inInitrd [ "bcachefs" ]; boot.initrd.availableKernelModules = [ "bcachefs" "chacha20" "poly1305" ];
boot.initrd.extraUtilsCommands = mkIf inInitrd boot.initrd.extraUtilsCommands = ''
'' copy_bin_and_libs ${pkgs.bcachefs-tools}/bin/bcachefs
copy_bin_and_libs ${pkgs.bcachefs-tools}/bin/fsck.bcachefs '';
boot.initrd.extraUtilsCommandsTest = ''
$out/bin/bcachefs version
''; '';
}; boot.initrd.postDeviceCommands = commonFunctions + concatStrings (mapAttrsToList openCommand bootFs);
})
]);
} }

View File

@ -53,7 +53,7 @@ let cfg = config.ec2; in
# Mount all formatted ephemeral disks and activate all swap devices. # Mount all formatted ephemeral disks and activate all swap devices.
# We cannot do this with the fileSystems and swapDevices options # We cannot do this with the fileSystems and swapDevices options
# because the set of devices is dependent on the instance type # because the set of devices is dependent on the instance type
# (e.g. "m1.large" has one ephemeral filesystem and one swap device, # (e.g. "m1.small" has one ephemeral filesystem and one swap device,
# while "m1.large" has two ephemeral filesystems and no swap # while "m1.large" has two ephemeral filesystems and no swap
# devices). Also, put /tmp and /var on /disk0, since it has a lot # devices). Also, put /tmp and /var on /disk0, since it has a lot
# more space than the root device. Similarly, "move" /nix to /disk0 # more space than the root device. Similarly, "move" /nix to /disk0

View File

@ -243,6 +243,9 @@ let
Restart = "on-failure"; Restart = "on-failure";
Slice = "machine.slice";
Delegate = true;
# Hack: we don't want to kill systemd-nspawn, since we call # Hack: we don't want to kill systemd-nspawn, since we call
# "machinectl poweroff" in preStop to shut down the # "machinectl poweroff" in preStop to shut down the
# container cleanly. But systemd requires sending a signal # container cleanly. But systemd requires sending a signal
@ -606,7 +609,7 @@ in
{ config = { config =
{ config, pkgs, ... }: { config, pkgs, ... }:
{ services.postgresql.enable = true; { services.postgresql.enable = true;
services.postgresql.package = pkgs.postgresql96; services.postgresql.package = pkgs.postgresql_9_6;
system.stateVersion = "17.03"; system.stateVersion = "17.03";
}; };
@ -657,6 +660,8 @@ in
serviceConfig = serviceDirectives dummyConfig; serviceConfig = serviceDirectives dummyConfig;
}; };
in { in {
systemd.targets."multi-user".wants = [ "machines.target" ];
systemd.services = listToAttrs (filter (x: x.value != null) ( systemd.services = listToAttrs (filter (x: x.value != null) (
# The generic container template used by imperative containers # The generic container template used by imperative containers
[{ name = "container@"; value = unit; }] [{ name = "container@"; value = unit; }]
@ -680,7 +685,7 @@ in
} // ( } // (
if config.autoStart then if config.autoStart then
{ {
wantedBy = [ "multi-user.target" ]; wantedBy = [ "machines.target" ];
wants = [ "network.target" ]; wants = [ "network.target" ];
after = [ "network.target" ]; after = [ "network.target" ];
restartTriggers = [ config.path ]; restartTriggers = [ config.path ];

View File

@ -0,0 +1,135 @@
{ config, lib, pkgs, ... }:
with lib;
with builtins;
let
cfg = config.virtualisation;
sanitizeImageName = image: replaceStrings ["/"] ["-"] image.imageName;
hash = drv: head (split "-" (baseNameOf drv.outPath));
# The label of an ext4 FS is limited to 16 bytes
labelFromImage = image: substring 0 16 (hash image);
# The Docker image is loaded and some files from /var/lib/docker/
# are written into a qcow image.
preload = image: pkgs.vmTools.runInLinuxVM (
pkgs.runCommand "docker-preload-image-${sanitizeImageName image}" {
buildInputs = with pkgs; [ docker e2fsprogs utillinux curl kmod ];
preVM = pkgs.vmTools.createEmptyImage {
size = cfg.dockerPreloader.qcowSize;
fullName = "docker-deamon-image.qcow2";
};
}
''
mkfs.ext4 /dev/vda
e2label /dev/vda ${labelFromImage image}
mkdir -p /var/lib/docker
mount -t ext4 /dev/vda /var/lib/docker
modprobe overlay
# from https://github.com/tianon/cgroupfs-mount/blob/master/cgroupfs-mount
mount -t tmpfs -o uid=0,gid=0,mode=0755 cgroup /sys/fs/cgroup
cd /sys/fs/cgroup
for sys in $(awk '!/^#/ { if ($4 == 1) print $1 }' /proc/cgroups); do
mkdir -p $sys
if ! mountpoint -q $sys; then
if ! mount -n -t cgroup -o $sys cgroup $sys; then
rmdir $sys || true
fi
fi
done
dockerd -H tcp://127.0.0.1:5555 -H unix:///var/run/docker.sock &
until $(curl --output /dev/null --silent --connect-timeout 2 http://127.0.0.1:5555); do
printf '.'
sleep 1
done
docker load -i ${image}
kill %1
find /var/lib/docker/ -maxdepth 1 -mindepth 1 -not -name "image" -not -name "overlay2" | xargs rm -rf
'');
preloadedImages = map preload cfg.dockerPreloader.images;
in
{
options.virtualisation.dockerPreloader = {
images = mkOption {
default = [ ];
type = types.listOf types.package;
description =
''
A list of Docker images to preload (in the /var/lib/docker directory).
'';
};
qcowSize = mkOption {
default = 1024;
type = types.int;
description =
''
The size (MB) of qcow files.
'';
};
};
config = {
assertions = [{
# If docker.storageDriver is null, Docker choose the storage
# driver. So, in this case, we cannot be sure overlay2 is used.
assertion = cfg.dockerPreloader.images == []
|| cfg.docker.storageDriver == "overlay2"
|| cfg.docker.storageDriver == "overlay"
|| cfg.docker.storageDriver == null;
message = "The Docker image Preloader only works with overlay2 storage driver!";
}];
virtualisation.qemu.options =
map (path: "-drive if=virtio,file=${path}/disk-image.qcow2,readonly,media=cdrom,format=qcow2")
preloadedImages;
# All attached QCOW files are mounted and their contents are linked
# to /var/lib/docker/ in order to make image available.
systemd.services.docker-preloader = {
description = "Preloaded Docker images";
wantedBy = ["docker.service"];
after = ["network.target"];
path = with pkgs; [ mount rsync jq ];
script = ''
mkdir -p /var/lib/docker/overlay2/l /var/lib/docker/image/overlay2
echo '{}' > /tmp/repositories.json
for i in ${concatStringsSep " " (map labelFromImage cfg.dockerPreloader.images)}; do
mkdir -p /mnt/docker-images/$i
# The ext4 label is limited to 16 bytes
mount /dev/disk/by-label/$(echo $i | cut -c1-16) -o ro,noload /mnt/docker-images/$i
find /mnt/docker-images/$i/overlay2/ -maxdepth 1 -mindepth 1 -not -name l\
-exec ln -s '{}' /var/lib/docker/overlay2/ \;
cp -P /mnt/docker-images/$i/overlay2/l/* /var/lib/docker/overlay2/l/
rsync -a /mnt/docker-images/$i/image/ /var/lib/docker/image/
# Accumulate image definitions
cp /tmp/repositories.json /tmp/repositories.json.tmp
jq -s '.[0] * .[1]' \
/tmp/repositories.json.tmp \
/mnt/docker-images/$i/image/overlay2/repositories.json \
> /tmp/repositories.json
done
mv /tmp/repositories.json /var/lib/docker/image/overlay2/repositories.json
'';
serviceConfig = {
Type = "oneshot";
};
};
};
}

View File

@ -144,7 +144,6 @@ in
path = with pkgs; [ iproute ]; path = with pkgs; [ iproute ];
serviceConfig = { serviceConfig = {
ExecStart = "${gce}/bin/google_network_daemon --debug"; ExecStart = "${gce}/bin/google_network_daemon --debug";
Type = "oneshot";
}; };
}; };

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