Merge remote-tracking branch 'upstream/release-18.03' into aarch32-for-18.03

release-18.03-flake
John Ericson 2018-04-25 16:00:44 -04:00
commit 2cbb138147
1110 changed files with 31328 additions and 18148 deletions

View File

@ -12,12 +12,12 @@ build daemon as so-called channels. To get channel information via git, add
```
For stability and maximum binary package support, it is recommended to maintain
custom changes on top of one of the channels, e.g. `nixos-17.09` for the latest
custom changes on top of one of the channels, e.g. `nixos-18.03` for the latest
release and `nixos-unstable` for the latest successful build of master:
```
% git remote update channels
% git rebase channels/nixos-17.09
% git rebase channels/nixos-18.03
```
For pull-requests, please rebase onto nixpkgs `master`.
@ -31,9 +31,9 @@ For pull-requests, please rebase onto nixpkgs `master`.
* [Manual (NixOS)](https://nixos.org/nixos/manual/)
* [Community maintained wiki](https://nixos.wiki/)
* [Continuous package builds for unstable/master](https://hydra.nixos.org/jobset/nixos/trunk-combined)
* [Continuous package builds for 17.09 release](https://hydra.nixos.org/jobset/nixos/release-17.09)
* [Continuous package builds for 18.03 release](https://hydra.nixos.org/jobset/nixos/release-18.03)
* [Tests for unstable/master](https://hydra.nixos.org/job/nixos/trunk-combined/tested#tabs-constituents)
* [Tests for 17.09 release](https://hydra.nixos.org/job/nixos/release-17.09/tested#tabs-constituents)
* [Tests for 18.03 release](https://hydra.nixos.org/job/nixos/release-18.03/tested#tabs-constituents)
Communication:

6
doc/.gitignore vendored 100644
View File

@ -0,0 +1,6 @@
*.chapter.xml
*.section.xml
.version
out
manual-full.xml
highlightjs

90
doc/Makefile 100644
View File

@ -0,0 +1,90 @@
MD_TARGETS=$(addsuffix .xml, $(basename $(wildcard ./*.md ./**/*.md)))
.PHONY: all
all: validate out/html/index.html out/epub/manual.epub
.PHONY: debug
debug:
nix-shell --run "xmloscopy --docbook5 ./manual.xml ./manual-full.xml"
.PHONY: clean
clean:
rm -f ${MD_TARGETS} .version manual-full.xml
rm -rf ./out/ ./highlightjs
.PHONY: validate
validate: manual-full.xml
jing "$$RNG" manual-full.xml
out/html/index.html: manual-full.xml style.css highlightjs
mkdir -p out/html
xsltproc ${xsltFlags} \
--nonet --xinclude \
--output $@ \
"$$XSL/docbook/xhtml/docbook.xsl" \
./manual-full.xml
mkdir -p out/html/highlightjs/
cp -r highlightjs out/html/
cp ./overrides.css out/html/
cp ./style.css out/html/style.css
mkdir -p out/html/images/callouts
cp "$$XSL/docbook/images/callouts/"*.svg out/html/images/callouts/
chmod u+w -R out/html/
out/epub/manual.epub: manual-full.xml
mkdir -p out/epub/scratch
xsltproc ${xsltFlags} --nonet \
--output out/epub/scratch/ \
"$$XSL/docbook/epub/docbook.xsl" \
./manual-full.xml
cp ./overrides.css out/epub/scratch/OEBPS
cp ./style.css out/epub/scratch/OEBPS
mkdir -p out/epub/scratch/OEBPS/images/callouts/
cp "$$XSL/docbook/images/callouts/"*.svg out/epub/scratch/OEBPS/images/callouts/
echo "application/epub+zip" > mimetype
zip -0Xq "out/epub/manual.epub" mimetype
rm mimetype
cd "out/epub/scratch/" && zip -Xr9D "../manual.epub" *
rm -rf "out/epub/scratch/"
highlightjs:
mkdir -p highlightjs
cp -r "$$HIGHLIGHTJS/highlight.pack.js" highlightjs/
cp -r "$$HIGHLIGHTJS/LICENSE" highlightjs/
cp -r "$$HIGHLIGHTJS/mono-blue.css" highlightjs/
cp -r "$$HIGHLIGHTJS/loader.js" highlightjs/
manual-full.xml: ${MD_TARGETS} .version *.xml
xmllint --nonet --xinclude --noxincludenode manual.xml --output manual-full.xml
.version:
nix-instantiate --eval \
-E '(import ../lib).nixpkgsVersion' > .version
%.section.xml: %.section.md
pandoc $^ -w docbook+smart \
-f markdown+smart \
| sed -e 's|<ulink url=|<link xlink:href=|' \
-e 's|</ulink>|</link>|' \
-e 's|<sect. id=|<section xml:id=|' \
-e 's|</sect[0-9]>|</section>|' \
-e '1s| id=| xml:id=|' \
-e '1s|\(<[^ ]* \)|\1xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" |' \
| cat > $@
%.chapter.xml: %.chapter.md
pandoc $^ -w docbook+smart \
--top-level-division=chapter \
-f markdown+smart \
| sed -e 's|<ulink url=|<link xlink:href=|' \
-e 's|</ulink>|</link>|' \
-e 's|<sect. id=|<section xml:id=|' \
-e 's|</sect[0-9]>|</section>|' \
-e '1s| id=| xml:id=|' \
-e '1s|\(<[^ ]* \)|\1|' \
| cat > $@

View File

@ -6,12 +6,27 @@
<para>The DocBook sources of the Nixpkgs manual are in the <filename
xlink:href="https://github.com/NixOS/nixpkgs/tree/master/doc">doc</filename>
subdirectory of the Nixpkgs repository. If you make modifications to
the manual, it's important to build it before committing. You can do that as follows:
subdirectory of the Nixpkgs repository.</para>
<para>You can quickly check your edits with <command>make</command>:</para>
<screen>
$ cd /path/to/nixpkgs
$ nix-build doc
$ cd /path/to/nixpkgs/doc
$ nix-shell
[nix-shell]$ make
</screen>
<para>If you experience problems, run <command>make debug</command>
to help understand the docbook errors.</para>
<para>After making modifications to the manual, it's important to
build it before committing. You can do that as follows:
<screen>
$ cd /path/to/nixpkgs/doc
$ nix-shell
[nix-shell]$ make clean
[nix-shell]$ nix-build .
</screen>
If the build succeeds, the manual will be in

View File

@ -7,112 +7,41 @@ in
pkgs.stdenv.mkDerivation {
name = "nixpkgs-manual";
buildInputs = with pkgs; [ pandoc libxml2 libxslt zip jing ];
buildInputs = with pkgs; [ pandoc libxml2 libxslt zip ];
src = ./.;
xsltFlags = ''
--param section.autolabel 1
--param section.label.includes.component.label 1
--param html.stylesheet 'style.css'
--param xref.with.number.and.title 1
--param toc.section.depth 3
--param admon.style '''
--param callout.graphics.extension '.gif'
# Hacking on these variables? Make sure to close and open
# nix-shell between each test, maybe even:
# $ nix-shell --run "make clean all"
# otherwise they won't reapply :)
HIGHLIGHTJS = pkgs.documentation-highlighter;
XSL = "${pkgs.docbook5_xsl}/xml/xsl";
RNG = "${pkgs.docbook5}/xml/rng/docbook/docbook.rng";
xsltFlags = lib.concatStringsSep " " [
"--param section.autolabel 1"
"--param section.label.includes.component.label 1"
"--stringparam html.stylesheet 'style.css overrides.css highlightjs/mono-blue.css'"
"--stringparam html.script './highlightjs/highlight.pack.js ./highlightjs/loader.js'"
"--param xref.with.number.and.title 1"
"--param toc.section.depth 3"
"--stringparam admon.style ''"
"--stringparam callout.graphics.extension .svg"
];
postPatch = ''
echo ${lib.nixpkgsVersion} > .version
'';
installPhase = ''
dest="$out/share/doc/nixpkgs"
mkdir -p "$(dirname "$dest")"
mv out/html "$dest"
mv "$dest/index.html" "$dest/manual.html"
buildCommand = let toDocbook = { useChapters ? false, inputFile, outputFile }:
let
extraHeader = lib.optionalString (!useChapters)
''xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" '';
in ''
{
pandoc '${inputFile}' -w docbook+smart ${lib.optionalString useChapters "--top-level-division=chapter"} \
-f markdown+smart \
| sed -e 's|<ulink url=|<link xlink:href=|' \
-e 's|</ulink>|</link>|' \
-e 's|<sect. id=|<section xml:id=|' \
-e 's|</sect[0-9]>|</section>|' \
-e '1s| id=| xml:id=|' \
-e '1s|\(<[^ ]* \)|\1${extraHeader}|'
} > '${outputFile}'
'';
in
mv out/epub/manual.epub "$dest/nixpkgs-manual.epub"
''
ln -s '${sources}/'*.xml .
mkdir ./languages-frameworks
cp -s '${sources-langs}'/* ./languages-frameworks
''
+ toDocbook {
inputFile = ./introduction.md;
outputFile = "introduction.xml";
useChapters = true;
}
+ toDocbook {
inputFile = ./shell.md;
outputFile = "shell.xml";
}
+ toDocbook {
inputFile = ./languages-frameworks/python.md;
outputFile = "./languages-frameworks/python.xml";
}
+ toDocbook {
inputFile = ./languages-frameworks/haskell.md;
outputFile = "./languages-frameworks/haskell.xml";
}
+ toDocbook {
inputFile = ../pkgs/development/idris-modules/README.md;
outputFile = "languages-frameworks/idris.xml";
}
+ toDocbook {
inputFile = ../pkgs/development/node-packages/README.md;
outputFile = "languages-frameworks/node.xml";
}
+ toDocbook {
inputFile = ../pkgs/development/r-modules/README.md;
outputFile = "languages-frameworks/r.xml";
}
+ toDocbook {
inputFile = ./languages-frameworks/rust.md;
outputFile = "./languages-frameworks/rust.xml";
}
+ toDocbook {
inputFile = ./languages-frameworks/vim.md;
outputFile = "./languages-frameworks/vim.xml";
}
+ ''
echo ${lib.nixpkgsVersion} > .version
# validate against relaxng schema
xmllint --nonet --xinclude --noxincludenode manual.xml --output manual-full.xml
${pkgs.jing}/bin/jing ${pkgs.docbook5}/xml/rng/docbook/docbook.rng manual-full.xml
dst=$out/share/doc/nixpkgs
mkdir -p $dst
xsltproc $xsltFlags --nonet --xinclude \
--output $dst/manual.html \
${pkgs.docbook5_xsl}/xml/xsl/docbook/xhtml/docbook.xsl \
./manual.xml
cp ${./style.css} $dst/style.css
mkdir -p $dst/images/callouts
cp "${pkgs.docbook5_xsl}/xml/xsl/docbook/images/callouts/"*.gif $dst/images/callouts/
mkdir -p $out/nix-support
echo "doc manual $dst manual.html" >> $out/nix-support/hydra-build-products
xsltproc $xsltFlags --nonet --xinclude \
--output $dst/epub/ \
${pkgs.docbook5_xsl}/xml/xsl/docbook/epub/docbook.xsl \
./manual.xml
cp -r $dst/images $dst/epub/OEBPS
echo "application/epub+zip" > mimetype
manual="$dst/nixpkgs-manual.epub"
zip -0Xq "$manual" mimetype
cd $dst/epub && zip -Xr9D "$manual" *
rm -rf $dst/epub
mkdir -p $out/nix-support/
echo "doc manual $dest manual.html" >> $out/nix-support/hydra-build-products
'';
}

View File

@ -0,0 +1,39 @@
Idris packages
==============
This directory contains build rules for idris packages. In addition,
it contains several functions to build and compose those packages.
Everything is exposed to the user via the `idrisPackages` attribute.
callPackage
------------
This is like the normal nixpkgs callPackage function, specialized to
idris packages.
builtins
---------
This is a list of all of the libraries that come packaged with Idris
itself.
build-idris-package
--------------------
A function to build an idris package. Its sole argument is a set like
you might pass to `stdenv.mkDerivation`, except `build-idris-package`
sets several attributes for you. See `build-idris-package.nix` for
details.
build-builtin-package
----------------------
A version of `build-idris-package` specialized to builtin libraries.
Mostly for internal use.
with-packages
-------------
Bundle idris together with a list of packages. Because idris currently
only supports a single directory in its library path, you must include
all desired libraries here, including `prelude` and `base`.

View File

@ -17,19 +17,18 @@ such as Perl or Haskell. These are described in this chapter.</para>
<xi:include href="bower.xml" />
<xi:include href="coq.xml" />
<xi:include href="go.xml" />
<xi:include href="haskell.xml" />
<xi:include href="idris.xml" /> <!-- generated from ../../pkgs/development/idris-modules/README.md -->
<xi:include href="haskell.section.xml" />
<xi:include href="idris.section.xml" />
<xi:include href="java.xml" />
<xi:include href="lua.xml" />
<xi:include href="node.xml" /> <!-- generated from ../../pkgs/development/node-packages/README.md -->
<xi:include href="node.section.xml" />
<xi:include href="perl.xml" />
<xi:include href="python.xml" />
<xi:include href="python.section.xml" />
<xi:include href="qt.xml" />
<xi:include href="r.xml" /> <!-- generated from ../../pkgs/development/r-modules/README.md -->
<xi:include href="r.section.xml" />
<xi:include href="ruby.xml" />
<xi:include href="rust.xml" />
<xi:include href="rust.section.xml" />
<xi:include href="texlive.xml" />
<xi:include href="vim.xml" />
<xi:include href="vim.section.xml" />
</chapter>

View File

@ -0,0 +1,51 @@
Node.js packages
================
The `pkgs/development/node-packages` folder contains a generated collection of
[NPM packages](https://npmjs.com/) that can be installed with the Nix package
manager.
As a rule of thumb, the package set should only provide *end user* software
packages, such as command-line utilities. Libraries should only be added to the
package set if there is a non-NPM package that requires it.
When it is desired to use NPM libraries in a development project, use the
`node2nix` generator directly on the `package.json` configuration file of the
project.
The package set also provides support for multiple Node.js versions. The policy
is that a new package should be added to the collection for the latest stable LTS
release (which is currently 6.x), unless there is an explicit reason to support
a different release.
If your package uses native addons, you need to examine what kind of native
build system it uses. Here are some examples:
* `node-gyp`
* `node-gyp-builder`
* `node-pre-gyp`
After you have identified the correct system, you need to override your package
expression while adding in build system as a build input. For example, `dat`
requires `node-gyp-build`, so we override its expression in `default-v6.nix`:
```nix
dat = nodePackages.dat.override (oldAttrs: {
buildInputs = oldAttrs.buildInputs ++ [ nodePackages.node-gyp-build ];
});
```
To add a package from NPM to nixpkgs:
1. Modify `pkgs/development/node-packages/node-packages-v6.json` to add, update
or remove package entries. (Or `pkgs/development/node-packages/node-packages-v4.json`
for packages depending on Node.js 4.x)
2. Run the script: `(cd pkgs/development/node-packages && ./generate.sh)`.
3. Build your new package to test your changes:
`cd /path/to/nixpkgs && nix-build -A nodePackages.<new-or-updated-package>`.
To build against a specific Node.js version (e.g. 4.x):
`nix-build -A nodePackages_4_x.<new-or-updated-package>`
4. Add and commit all modified and generated files.
For more information about the generation process, consult the
[README.md](https://github.com/svanderburg/node2nix) file of the `node2nix`
tool.

View File

@ -871,8 +871,10 @@ Executing `python setup.py bdist_wheel` in a `nix-shell `fails with
```
ValueError: ZIP does not support timestamps before 1980
```
This is because files are included that depend on items in the Nix store which have a timestamp of, that is, it corresponds to January the 1st, 1970 at 00:00:00. And as the error informs you, ZIP does not support that.
The command `bdist_wheel` takes into account `SOURCE_DATE_EPOCH`, and `nix-shell` sets this to 1. By setting it to a value corresponding to 1980 or later, or by unsetting it, it is possible to build wheels.
This is because files from the Nix store (which have a timestamp of the UNIX epoch of January 1, 1970) are included in the .ZIP, but .ZIP archives follow the DOS convention of counting timestamps from 1980.
The command `bdist_wheel` reads the `SOURCE_DATE_EPOCH` environment variable, which `nix-shell` sets to 1. Unsetting this variable or giving it a value corresponding to 1980 or later enables building wheels.
Use 1980 as timestamp:
```shell
@ -882,7 +884,7 @@ or the current time:
```shell
nix-shell --run "SOURCE_DATE_EPOCH=$(date +%s) python3 setup.py bdist_wheel"
```
or unset:
or unset `SOURCE_DATE_EPOCH`:
```shell
nix-shell --run "unset SOURCE_DATE_EPOCH; python3 setup.py bdist_wheel"
```

View File

@ -0,0 +1,120 @@
R packages
==========
## Installation
Define an environment for R that contains all the libraries that you'd like to
use by adding the following snippet to your $HOME/.config/nixpkgs/config.nix file:
```nix
{
packageOverrides = super: let self = super.pkgs; in
{
rEnv = super.rWrapper.override {
packages = with self.rPackages; [
devtools
ggplot2
reshape2
yaml
optparse
];
};
};
}
```
Then you can use `nix-env -f "<nixpkgs>" -iA rEnv` to install it into your user
profile. The set of available libraries can be discovered by running the
command `nix-env -f "<nixpkgs>" -qaP -A rPackages`. The first column from that
output is the name that has to be passed to rWrapper in the code snipped above.
However, if you'd like to add a file to your project source to make the
environment available for other contributors, you can create a `default.nix`
file like so:
```nix
let
pkgs = import <nixpkgs> {};
stdenv = pkgs.stdenv;
in with pkgs; {
myProject = stdenv.mkDerivation {
name = "myProject";
version = "1";
src = if pkgs.lib.inNixShell then null else nix;
buildInputs = with rPackages; [
R
ggplot2
knitr
];
};
}
```
and then run `nix-shell .` to be dropped into a shell with those packages
available.
## RStudio
RStudio uses a standard set of packages and ignores any custom R
environments or installed packages you may have. To create a custom
environment, see `rstudioWrapper`, which functions similarly to
`rWrapper`:
```nix
{
packageOverrides = super: let self = super.pkgs; in
{
rstudioEnv = super.rstudioWrapper.override {
packages = with self.rPackages; [
dplyr
ggplot2
reshape2
];
};
};
}
```
Then like above, `nix-env -f "<nixpkgs>" -iA rstudioEnv` will install
this into your user profile.
Alternatively, you can create a self-contained `shell.nix` without the need to
modify any configuration files:
```nix
{ pkgs ? import <nixpkgs> {}
}:
pkgs.rstudioWrapper.override {
packages = with pkgs.rPackages; [ dplyr ggplot2 reshape2 ];
}
```
Executing `nix-shell` will then drop you into an environment equivalent to the
one above. If you need additional packages just add them to the list and
re-enter the shell.
## Updating the package set
```bash
nix-shell generate-shell.nix
Rscript generate-r-packages.R cran > cran-packages.nix.new
mv cran-packages.nix.new cran-packages.nix
Rscript generate-r-packages.R bioc > bioc-packages.nix.new
mv bioc-packages.nix.new bioc-packages.nix
```
`generate-r-packages.R <repo>` reads `<repo>-packages.nix`, therefor the renaming.
## Testing if the Nix-expression could be evaluated
```bash
nix-build test-evaluation.nix --dry-run
```
If this exits fine, the expression is ok. If not, you have to edit `default.nix`

View File

@ -16,6 +16,12 @@ cargo
into the `environment.systemPackages` or bring them into
scope with `nix-shell -p rustc cargo`.
> If you are using NixOS and you want to use rust without a nix expression you
> probably want to add the following in your `configuration.nix` to build
> crates with C dependencies.
>
> environment.systemPackages = [binutils gcc gnumake openssl pkgconfig]
For daily builds (beta and nightly) use either rustup from
nixpkgs or use the [Rust nightlies
overlay](#using-the-rust-nightlies-overlay).
@ -76,7 +82,7 @@ an example for a minimal `hello` crate:
Compiling hello v0.1.0 (file:///tmp/hello)
Finished dev [unoptimized + debuginfo] target(s) in 0.20 secs
$ carnix -o hello.nix --src ./. Cargo.lock --standalone
$ nix-build hello.nix
$ nix-build hello.nix -A hello_0_1_0
Now, the file produced by the call to `carnix`, called `hello.nix`, looks like:
@ -276,6 +282,84 @@ features, we would write:
Where `diesel.nix` is the file generated by Carnix, as explained above.
## Setting Up `nix-shell`
Oftentimes you want to develop code from within `nix-shell`. Unfortunately
`buildRustCrate` does not support common `nix-shell` operations directly
(see [this issue](https://github.com/NixOS/nixpkgs/issues/37945))
so we will use `stdenv.mkDerivation` instead.
Using the example `hello` project above, we want to do the following:
- Have access to `cargo` and `rustc`
- Have the `openssl` library available to a crate through it's _normal_
compilation mechanism (`pkg-config`).
A typical `shell.nix` might look like:
```
with import <nixpkgs> {};
stdenv.mkDerivation {
name = "rust-env";
buildInputs = [
rustc cargo
# Example Additional Dependencies
pkgconfig openssl
];
# Set Environment Variables
RUST_BACKTRACE = 1;
}
```
You should now be able to run the following:
```
$ nix-shell --pure
$ cargo build
$ cargo test
```
### Controlling Rust Version Inside `nix-shell`
To control your rust version (i.e. use nightly) from within `shell.nix` (or
other nix expressions) you can use the following `shell.nix`
```
# Latest Nightly
with import <nixpkgs> {};
let src = fetchFromGitHub {
owner = "mozilla";
repo = "nixpkgs-mozilla";
# commit from: 2018-03-27
rev = "2945b0b6b2fd19e7d23bac695afd65e320efcebe";
sha256 = "034m1dryrzh2lmjvk3c0krgip652dql46w5yfwpvh7gavd3iypyw";
};
in
with import "${src.out}/rust-overlay.nix" pkgs pkgs;
stdenv.mkDerivation {
name = "rust-env";
buildInputs = [
# Note: to use use stable, just replace `nightly` with `stable`
latest.rustChannels.nightly.rust
# Add some extra dependencies from `pkgs`
pkgconfig openssl
];
# Set Environment Variables
RUST_BACKTRACE = 1;
}
```
Now run:
```
$ rustc --version
rustc 1.26.0-nightly (188e693b3 2018-03-26)
```
To see that you are using nightly.
## Using the Rust nightlies overlay
Mozilla provides an overlay for nixpkgs to bring a nightly version of Rust into scope.

View File

@ -9,7 +9,7 @@
</info>
<xi:include href="introduction.xml" />
<xi:include href="introduction.chapter.xml" />
<xi:include href="quick-start.xml" />
<xi:include href="stdenv.xml" />
<xi:include href="multiple-output.xml" />

View File

@ -36,10 +36,16 @@
<para>Here you find how to write a derivation that produces multiple outputs.</para>
<para>In nixpkgs there is a framework supporting multiple-output derivations. It tries to cover most cases by default behavior. You can find the source separated in &lt;<filename>nixpkgs/pkgs/build-support/setup-hooks/multiple-outputs.sh</filename>&gt;; it's relatively well-readable. The whole machinery is triggered by defining the <varname>outputs</varname> attribute to contain the list of desired output names (strings).</para>
<programlisting>outputs = [ "bin" "dev" "out" "doc" ];</programlisting>
<para>Often such a single line is enough. For each output an equally named environment variable is passed to the builder and contains the path in nix store for that output. By convention, the first output should contain the executable programs provided by the package as that output is used by Nix in string conversions, allowing references to binaries like <literal>${pkgs.perl}/bin/perl</literal> to always work. Typically you also want to have the main <varname>out</varname> output, as it catches any files that didn't get elsewhere.</para>
<para>Often such a single line is enough. For each output an equally named environment variable is passed to the builder and contains the path in nix store for that output. Typically you also want to have the main <varname>out</varname> output, as it catches any files that didn't get elsewhere.</para>
<note><para>There is a special handling of the <varname>debug</varname> output, described at <xref linkend="stdenv-separateDebugInfo" />.</para></note>
<section xml:id="multiple-output-file-binaries-first-convention">
<title><quote>Binaries first</quote></title>
<para>A commonly adopted convention in <literal>nixpkgs</literal> is that executables provided by the package are contained within its first output. This convention allows the dependent packages to reference the executables provided by packages in a uniform manner. For instance, provided with the knowledge that the <literal>perl</literal> package contains a <literal>perl</literal> executable it can be referenced as <literal>${pkgs.perl}/bin/perl</literal> within a Nix derivation that needs to execute a Perl script.</para>
<para>The <literal>glibc</literal> package is a deliberate single exception to the <quote>binaries first</quote> convention. The <literal>glibc</literal> has <literal>libs</literal> as its first output allowing the libraries provided by <literal>glibc</literal> to be referenced directly (e.g. <literal>${stdenv.glibc}/lib/ld-linux-x86-64.so.2</literal>). The executables provided by <literal>glibc</literal> can be accessed via its <literal>bin</literal> attribute (e.g. <literal>${stdenv.glibc.bin}/bin/ldd</literal>).</para>
<para>The reason for why <literal>glibc</literal> deviates from the convention is because referencing a library provided by <literal>glibc</literal> is a very common operation among Nix packages. For instance, third-party executables packaged by Nix are typically patched and relinked with the relevant version of <literal>glibc</literal> libraries from Nix packages (please see the documentation on <link xlink:href="https://nixos.org/patchelf.html">patchelf</link> for more details).</para>
</section>
<section xml:id="multiple-output-file-type-groups">
<title>File type groups</title>
<para>The support code currently recognizes some particular kinds of outputs and either instructs the build system of the package to put files into their desired outputs or it moves the files during the fixup phase. Each group of file types has an <varname>outputFoo</varname> variable specifying the output name where they should go. If that variable isn't defined by the derivation writer, it is guessed &ndash; a default output name is defined, falling back to other possibilities if the output isn't defined.</para>

View File

@ -0,0 +1,9 @@
.docbook .xref img[src^=images\/callouts\/],
.screen img,
.programlisting img {
width: 1em;
}
.calloutlist img {
width: 1.5em;
}

4
doc/shell.nix 100644
View File

@ -0,0 +1,4 @@
{ pkgs ? import ../. {} }:
(import ./default.nix).overrideAttrs (x: {
buildInputs = x.buildInputs ++ [ pkgs.xmloscopy ];
})

View File

@ -4,6 +4,8 @@ author: zimbatm
date: 2017-10-30
---
# mkShell
pkgs.mkShell is a special kind of derivation that is only useful when using
it combined with nix-shell. It will in fact fail to instantiate when invoked
with nix-build.

View File

@ -29,8 +29,8 @@ h2 /* chapters, appendices, subtitle */
}
/* Extra space between chapters, appendices. */
div.chapter > div.titlepage h2, div.appendix > div.titlepage h2
{
div.chapter > div.titlepage h2, div.appendix > div.titlepage h2
{
margin-top: 1.5em;
}
@ -104,7 +104,7 @@ pre.screen, pre.programlisting
padding: 3px 3px;
margin-left: 1.5em;
margin-right: 1.5em;
color: #600000;
background: #f4f4f8;
font-family: monospace;
border-radius: 0.4em;
@ -118,7 +118,6 @@ div.example pre.programlisting
margin: 0 0 0 0;
}
/***************************************************************************
Notes, warnings etc:
***************************************************************************/
@ -172,7 +171,7 @@ div.navfooter *
/***************************************************************************
Links colors and highlighting:
Links colors and highlighting:
***************************************************************************/
a { text-decoration: none; }
@ -209,7 +208,7 @@ tt, code
.term
{
font-weight: bold;
}
div.variablelist dd p, div.glosslist dd p
@ -249,7 +248,24 @@ table
box-shadow: 0.4em 0.4em 0.5em #e0e0e0;
}
table.simplelist
{
text-align: left;
color: #005aa0;
border: 0;
padding: 5px;
background: #fffff5;
font-weight: normal;
font-style: italic;
box-shadow: none;
margin-bottom: 1em;
}
div.navheader table, div.navfooter table {
box-shadow: none;
}
div.affiliation
{
font-style: italic;
}
}

View File

@ -21,7 +21,7 @@ let
# packaging
customisation = callLibs ./customisation.nix;
maintainers = import ./maintainers-list.nix;
maintainers = import ../maintainers/maintainer-list.nix;
meta = callLibs ./meta.nix;
sources = callLibs ./sources.nix;
versions = callLibs ./versions.nix;

View File

@ -660,7 +660,7 @@ rec {
doRename = { from, to, visible, warn, use }:
let
toOf = attrByPath to
(abort "Renaming error: option `${showOption to}' does not exists.");
(abort "Renaming error: option `${showOption to}' does not exist.");
in
{ config, options, ... }:
{ options = setAttrByPath from (mkOption {

View File

@ -4,8 +4,8 @@ let
inherit (lib.systems.inspect) patterns;
in rec {
inherit (lib.systems.doubles) all mesaPlatforms;
none = [];
all = [ {} ]; # `{}` matches anything
none = [];
arm = [ patterns.isAarch32 ];
aarch64 = [ patterns.isAarch64 ];
@ -24,4 +24,7 @@ in rec {
netbsd = [ patterns.isNetBSD ];
openbsd = [ patterns.isOpenBSD ];
unix = patterns.isUnix; # Actually a list
windows = [ patterns.isWindows ];
inherit (lib.systems.doubles) mesaPlatforms;
}

View File

@ -176,6 +176,11 @@
github = "abigailbuccaneer";
name = "Abigail Bunyan";
};
aborsu = {
email = "a.borsu@gmail.com";
github = "aborsu";
name = "Augustin Borsu";
};
aboseley = {
email = "adam.boseley@gmail.com";
github = "aboseley";
@ -314,6 +319,11 @@
github = "amiloradovsky";
name = "Andrew Miloradovsky";
};
aminechikhaoui = {
email = "amine.chikhaoui91@gmail.com";
github = "AmineChikhaoui";
name = "Amine Chikhaoui";
};
amorsillo = {
email = "andrew.morsillo@gmail.com";
github = "AndrewMorsillo";
@ -555,7 +565,6 @@
};
bjg = {
email = "bjg@gnu.org";
github = "civodul";
name = "Brian Gough";
};
bjornfor = {
@ -632,11 +641,6 @@
github = "calbrecht";
name = "Christian Albrecht";
};
calrama = {
email = "moritz@ucworks.org";
github = "MoritzMaxeiner";
name = "Moritz Maxeiner";
};
calvertvl = {
email = "calvertvl@gmail.com";
github = "calvertvl";
@ -1524,6 +1528,11 @@
github = "hrdinka";
name = "Christoph Hrdinka";
};
hschaeidt = {
email = "he.schaeidt@gmail.com";
github = "hschaeidt";
name = "Hendrik Schaeidt";
};
htr = {
email = "hugo@linux.com";
github = "htr";
@ -1663,7 +1672,7 @@
name = "Johannes Frankenau";
};
jgeerds = {
email = "jascha@jgeerds.name";
email = "jascha@geerds.org";
github = "jgeerds";
name = "Jascha Geerds";
};
@ -2013,6 +2022,11 @@
github = "lo1tuma";
name = "Mathias Schreck";
};
lopsided98 = {
email = "benwolsieffer@gmail.com";
github = "lopsided98";
name = "Ben Wolsieffer";
};
loskutov = {
email = "ignat.loskutov@gmail.com";
github = "loskutov";
@ -3155,6 +3169,11 @@
github = "sellout";
name = "Greg Pfeil";
};
sengaya = {
email = "tlo@sengaya.de";
github = "sengaya";
name = "Thilo Uttendorfer";
};
sepi = {
email = "raffael@mancini.lu";
github = "sepi";

View File

@ -1,5 +1,5 @@
#! /usr/bin/env nix-shell
#! nix-shell -i python3 -p 'python3.withPackages(ps: with ps; [ packaging requests toolz ])' -p git
#! nix-shell -i python3 -p "python3.withPackages(ps: with ps; [ packaging requests toolz ])" -p git
"""
Update a Python package expression by passing in the `.nix` file, or the directory containing it.
@ -358,4 +358,4 @@ def main():
if __name__ == '__main__':
main()
main()

View File

@ -124,11 +124,12 @@ let
manualXsltprocOptions = toString [
"--param section.autolabel 1"
"--param section.label.includes.component.label 1"
"--stringparam html.stylesheet style.css"
"--stringparam html.stylesheet 'style.css overrides.css highlightjs/mono-blue.css'"
"--stringparam html.script './highlightjs/highlight.pack.js ./highlightjs/loader.js'"
"--param xref.with.number.and.title 1"
"--param toc.section.depth 3"
"--stringparam admon.style ''"
"--stringparam callout.graphics.extension .gif"
"--stringparam callout.graphics.extension .svg"
"--stringparam current.docid manual"
"--param chunk.section.depth 0"
"--param chunk.first.sections 1"
@ -260,9 +261,11 @@ in rec {
${manual-combined}/manual-combined.xml
mkdir -p $dst/images/callouts
cp ${docbook5_xsl}/xml/xsl/docbook/images/callouts/*.gif $dst/images/callouts/
cp ${docbook5_xsl}/xml/xsl/docbook/images/callouts/*.svg $dst/images/callouts/
cp ${./style.css} $dst/style.css
cp ${../../../doc/style.css} $dst/style.css
cp ${../../../doc/overrides.css} $dst/overrides.css
cp -r ${pkgs.documentation-highlighter} $dst/highlightjs
mkdir -p $out/nix-support
echo "nix-build out $out" >> $out/nix-support/hydra-build-products
@ -286,7 +289,7 @@ in rec {
${manual-combined}/manual-combined.xml
mkdir -p $dst/epub/OEBPS/images/callouts
cp -r ${docbook5_xsl}/xml/xsl/docbook/images/callouts/*.gif $dst/epub/OEBPS/images/callouts # */
cp -r ${docbook5_xsl}/xml/xsl/docbook/images/callouts/*.svg $dst/epub/OEBPS/images/callouts # */
echo "application/epub+zip" > mimetype
manual="$dst/nixos-manual.epub"
zip -0Xq "$manual" mimetype

View File

@ -282,8 +282,8 @@ options.mod = mkOption {
option set (<xref linkend='ex-submodule-listof-definition' />).</para>
<example xml:id='ex-submodule-listof-declaration'><title>Declaration of a list
nof submodules</title>
<example xml:id='ex-submodule-listof-declaration'><title>Declaration of a list
of submodules</title>
<screen>
options.mod = mkOption {
description = "submodule example";

View File

@ -227,6 +227,18 @@ $ sudo groupdel nixbld</screen>
line)</para></listitem>
</itemizedlist>
<note><para>Support for <literal>NIXOS_LUSTRATE</literal> was added
in NixOS 16.09. The act of "lustrating" refers to the
wiping of the existing distribution. Creating
<literal>/etc/NIXOS_LUSTRATE</literal> can also be used on
NixOS to remove all mutable files from your root partition
(anything that's not in <literal>/nix</literal> or
<literal>/boot</literal> gets "lustrated" on the next
boot.</para>
<para>lustrate /ˈlʌstreɪt/ verb.</para>
<para>purify by expiatory sacrifice, ceremonial washing, or
some other ritual action.</para></note>
<para>Let's create the files:</para>
<screen>

View File

@ -115,23 +115,17 @@ for a UEFI installation is by and large the same as a BIOS installation. The dif
<varlistentry><term>UEFI systems</term>
<listitem><para>For creating boot partitions:
<command>mkfs.fat</command>. Again its recommended to assign a
label to the boot partition: <option>-L
label to the boot partition: <option>-n
<replaceable>label</replaceable></option>. For example:
<screen>
# mkfs.fat -F 32 -L boot /dev/sda3</screen>
# mkfs.fat -F 32 -n boot /dev/sda3</screen>
</para></listitem></varlistentry></variablelist></listitem>
<listitem><para>For creating LVM volumes, the LVM commands, e.g.,
<screen>
# pvcreate /dev/sda1 /dev/sdb1
# vgcreate MyVolGroup /dev/sda1 /dev/sdb1
# lvcreate --size 2G --name bigdisk MyVolGroup
# lvcreate --size 1G --name smalldisk MyVolGroup</screen>
</para></listitem>
<command>pvcreate</command>, <command>vgcreate</command>, and
<command>lvcreate</command>.</para></listitem>
<listitem><para>For creating software RAID devices, use
<command>mdadm</command>.</para></listitem>
@ -155,6 +149,7 @@ for a UEFI installation is by and large the same as a BIOS installation. The dif
<listitem><para>Mount the boot file system on <filename>/mnt/boot</filename>, e.g.
<screen>
# mkdir -p /mnt/boot
# mount /dev/disk/by-label/boot /mnt/boot
</screen>
@ -366,8 +361,9 @@ drive (here <filename>/dev/sda</filename>). <xref linkend="ex-config"
# mkfs.ext4 -L nixos /dev/sda1
# mkswap -L swap /dev/sda2
# swapon /dev/sda2
# mkfs.fat -F 32 -L boot /dev/sda3 # <lineannotation>(for UEFI systems only)</lineannotation>
# mkfs.fat -F 32 -n boot /dev/sda3 # <lineannotation>(for UEFI systems only)</lineannotation>
# mount /dev/disk/by-label/nixos /mnt
# mkdir -p /mnt/boot # <lineannotation>(for UEFI systems only)</lineannotation>
# mount /dev/disk/by-label/boot /mnt/boot # <lineannotation>(for UEFI systems only)</lineannotation>
# nixos-generate-config --root /mnt
# nano /mnt/etc/nixos/configuration.nix

View File

@ -4,7 +4,7 @@
version="5.0"
xml:id="sec-release-18.03">
<title>Release 18.03 (“Impala”, 2018/03/??)</title>
<title>Release 18.03 (“Impala”, 2018/04/04)</title>
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
@ -18,6 +18,20 @@
has the following highlights: </para>
<itemizedlist>
<listitem>
<para>
End of support is planned for end of October 2018, handing over to 18.09.
</para>
</listitem>
<listitem>
<para>
Platform support: x86_64-linux and x86_64-darwin since release time (the latter isn't NixOS, really).
Binaries for aarch64-linux are available, but no channel exists yet, as it's waiting for some test fixes, etc.
</para>
</listitem>
<listitem>
<para>
Nix now defaults to 2.0; see its
@ -27,13 +41,13 @@ has the following highlights: </para>
<listitem>
<para>
Linux kernel defaults to the 4.14 branch (it was 4.9).
Core version changes: linux: 4.9 -> 4.14, glibc: 2.25 -> 2.26, gcc: 6 -> 7, systemd: 234 -> 237.
</para>
</listitem>
<listitem>
<para>
GCC defaults to 7.x (it was 6.x).
Desktop version changes: gnome: 3.24 -> 3.26, (KDE) plasma-desktop: 5.10 -> 5.12.
</para>
</listitem>
@ -59,13 +73,7 @@ has the following highlights: </para>
</listitem>
<listitem>
<para>
The GNOME version is now 3.26.
</para>
</listitem>
<listitem>
<para>PHP now defaults to PHP 7.2</para>
<para>PHP now defaults to PHP 7.2, updated from 7.1.</para>
</listitem>
</itemizedlist>
@ -81,9 +89,66 @@ has the following highlights: </para>
<para>The following new services were added since the last release:</para>
<itemizedlist>
<listitem>
<para></para>
</listitem>
<listitem><para><literal>./config/krb5/default.nix</literal></para></listitem>
<listitem><para><literal>./hardware/digitalbitbox.nix</literal></para></listitem>
<listitem><para><literal>./misc/label.nix</literal></para></listitem>
<listitem><para><literal>./programs/ccache.nix</literal></para></listitem>
<listitem><para><literal>./programs/criu.nix</literal></para></listitem>
<listitem><para><literal>./programs/digitalbitbox/default.nix</literal></para></listitem>
<listitem><para><literal>./programs/less.nix</literal></para></listitem>
<listitem><para><literal>./programs/npm.nix</literal></para></listitem>
<listitem><para><literal>./programs/plotinus.nix</literal></para></listitem>
<listitem><para><literal>./programs/rootston.nix</literal></para></listitem>
<listitem><para><literal>./programs/systemtap.nix</literal></para></listitem>
<listitem><para><literal>./programs/sway.nix</literal></para></listitem>
<listitem><para><literal>./programs/udevil.nix</literal></para></listitem>
<listitem><para><literal>./programs/way-cooler.nix</literal></para></listitem>
<listitem><para><literal>./programs/yabar.nix</literal></para></listitem>
<listitem><para><literal>./programs/zsh/zsh-autoenv.nix</literal></para></listitem>
<listitem><para><literal>./services/backup/borgbackup.nix</literal></para></listitem>
<listitem><para><literal>./services/backup/crashplan-small-business.nix</literal></para></listitem>
<listitem><para><literal>./services/desktops/dleyna-renderer.nix</literal></para></listitem>
<listitem><para><literal>./services/desktops/dleyna-server.nix</literal></para></listitem>
<listitem><para><literal>./services/desktops/pipewire.nix</literal></para></listitem>
<listitem><para><literal>./services/desktops/gnome3/chrome-gnome-shell.nix</literal></para></listitem>
<listitem><para><literal>./services/desktops/gnome3/tracker-miners.nix</literal></para></listitem>
<listitem><para><literal>./services/hardware/fwupd.nix</literal></para></listitem>
<listitem><para><literal>./services/hardware/interception-tools.nix</literal></para></listitem>
<listitem><para><literal>./services/hardware/u2f.nix</literal></para></listitem>
<listitem><para><literal>./services/hardware/usbmuxd.nix</literal></para></listitem>
<listitem><para><literal>./services/mail/clamsmtp.nix</literal></para></listitem>
<listitem><para><literal>./services/mail/dkimproxy-out.nix</literal></para></listitem>
<listitem><para><literal>./services/mail/pfix-srsd.nix</literal></para></listitem>
<listitem><para><literal>./services/misc/gitea.nix</literal></para></listitem>
<listitem><para><literal>./services/misc/home-assistant.nix</literal></para></listitem>
<listitem><para><literal>./services/misc/ihaskell.nix</literal></para></listitem>
<listitem><para><literal>./services/misc/logkeys.nix</literal></para></listitem>
<listitem><para><literal>./services/misc/novacomd.nix</literal></para></listitem>
<listitem><para><literal>./services/misc/osrm.nix</literal></para></listitem>
<listitem><para><literal>./services/misc/plexpy.nix</literal></para></listitem>
<listitem><para><literal>./services/misc/pykms.nix</literal></para></listitem>
<listitem><para><literal>./services/misc/tzupdate.nix</literal></para></listitem>
<listitem><para><literal>./services/monitoring/fusion-inventory.nix</literal></para></listitem>
<listitem><para><literal>./services/monitoring/prometheus/exporters.nix</literal></para></listitem>
<listitem><para><literal>./services/network-filesystems/beegfs.nix</literal></para></listitem>
<listitem><para><literal>./services/network-filesystems/davfs2.nix</literal></para></listitem>
<listitem><para><literal>./services/network-filesystems/openafs/client.nix</literal></para></listitem>
<listitem><para><literal>./services/network-filesystems/openafs/server.nix</literal></para></listitem>
<listitem><para><literal>./services/network-filesystems/ceph.nix</literal></para></listitem>
<listitem><para><literal>./services/networking/aria2.nix</literal></para></listitem>
<listitem><para><literal>./services/networking/monero.nix</literal></para></listitem>
<listitem><para><literal>./services/networking/nghttpx/default.nix</literal></para></listitem>
<listitem><para><literal>./services/networking/nixops-dns.nix</literal></para></listitem>
<listitem><para><literal>./services/networking/rxe.nix</literal></para></listitem>
<listitem><para><literal>./services/networking/stunnel.nix</literal></para></listitem>
<listitem><para><literal>./services/web-apps/matomo.nix</literal></para></listitem>
<listitem><para><literal>./services/web-apps/restya-board.nix</literal></para></listitem>
<listitem><para><literal>./services/web-servers/mighttpd2.nix</literal></para></listitem>
<listitem><para><literal>./services/x11/fractalart.nix</literal></para></listitem>
<listitem><para><literal>./system/boot/binfmt.nix</literal></para></listitem>
<listitem><para><literal>./system/boot/grow-partition.nix</literal></para></listitem>
<listitem><para><literal>./tasks/filesystems/ecryptfs.nix</literal></para></listitem>
<listitem><para><literal>./virtualisation/hyperv-guest.nix</literal></para></listitem>
</itemizedlist>
</section>
@ -174,7 +239,7 @@ following incompatible changes:</para>
the <literal>openssh_with_kerberos</literal> package
is now a deprecated alias.
If you do not want Kerberos support,
you can do <literal>openssh.override { withKerboros = false; }</literal>.
you can do <literal>openssh.override { withKerberos = false; }</literal>.
Note, this also applies to the <literal>openssh_hpn</literal> package.
</para>
</listitem>
@ -322,6 +387,43 @@ following incompatible changes:</para>
<link xlink:href="https://github.com/rvl/pump.io-nixos">external module</link>.
</para>
</listitem>
<listitem>
<para>
The Prosody XMPP server has received a major update. The following modules were renamed:
<itemizedlist>
<listitem>
<para>
<option>services.prosody.modules.httpserver</option> is now <option>services.prosody.modules.http_files</option>
</para>
</listitem>
<listitem>
<para>
<option>services.prosody.modules.console</option> is now <option>services.prosody.modules.admin_telnet</option>
</para>
</listitem>
</itemizedlist>
</para>
<para>
Many new modules are now core modules, most notably <option>services.prosody.modules.carbons</option>
and <option>services.prosody.modules.mam</option>.
</para>
<para>
The better-performing <literal>libevent</literal> backend is now enabled by default.
</para>
<para>
<literal>withCommunityModules</literal> now passes through the modules to <option>services.prosody.extraModules</option>.
Use <literal>withOnlyInstalledCommunityModules</literal> for modules that should not be enabled directly, e.g <literal>lib_ldap</literal>.
</para>
</listitem>
<listitem>
<para>
All prometheus exporter modules are now defined as submodules.
The exporters are configured using <literal>services.prometheus.exporters</literal>.
</para>
</listitem>
</itemizedlist>
</section>
@ -381,15 +483,6 @@ following incompatible changes:</para>
have been added to set up static routing.
</para>
</listitem>
<listitem>
<para>
The option <option>services.xserver.desktopManager.default</option> is now
<literal>none</literal> by default. An assertion failure is thrown if WM's
and DM's default are <literal>none</literal>.
To explicitly run a plain X session without and DM or WM, the newly
introduced option <option>services.xserver.plainX</option> must be set to true.
</para>
</listitem>
<listitem>
<para>
The option <option>services.logstash.listenAddress</option> is now <literal>127.0.0.1</literal> by default.

View File

@ -1,267 +0,0 @@
/* Copied from http://bakefile.sourceforge.net/, which appears
licensed under the GNU GPL. */
/***************************************************************************
Basic headers and text:
***************************************************************************/
body
{
font-family: "Nimbus Sans L", sans-serif;
background: white;
margin: 2em 1em 2em 1em;
}
h1, h2, h3, h4
{
color: #005aa0;
}
h1 /* title */
{
font-size: 200%;
}
h2 /* chapters, appendices, subtitle */
{
font-size: 180%;
}
/* Extra space between chapters, appendices. */
div.chapter > div.titlepage h2, div.appendix > div.titlepage h2
{
margin-top: 1.5em;
}
div.section > div.titlepage h2 /* sections */
{
font-size: 150%;
margin-top: 1.5em;
}
h3 /* subsections */
{
font-size: 125%;
}
div.simplesect h2
{
font-size: 110%;
}
div.appendix h3
{
font-size: 150%;
margin-top: 1.5em;
}
div.refnamediv h2, div.refsynopsisdiv h2, div.refsection h2 /* refentry parts */
{
margin-top: 1.4em;
font-size: 125%;
}
div.refsection h3
{
font-size: 110%;
}
/***************************************************************************
Examples:
***************************************************************************/
div.example
{
border: 1px solid #b0b0b0;
padding: 6px 6px;
margin-left: 1.5em;
margin-right: 1.5em;
background: #f4f4f8;
border-radius: 0.4em;
box-shadow: 0.4em 0.4em 0.5em #e0e0e0;
}
div.example p.title
{
margin-top: 0em;
}
div.example pre
{
box-shadow: none;
}
/***************************************************************************
Screen dumps:
***************************************************************************/
pre.screen, pre.programlisting
{
border: 1px solid #b0b0b0;
padding: 3px 3px;
margin-left: 1.5em;
margin-right: 1.5em;
color: #600000;
background: #f4f4f8;
font-family: monospace;
border-radius: 0.4em;
box-shadow: 0.4em 0.4em 0.5em #e0e0e0;
}
div.example pre.programlisting
{
border: 0px;
padding: 0 0;
margin: 0 0 0 0;
}
/***************************************************************************
Notes, warnings etc:
***************************************************************************/
.note, .warning
{
border: 1px solid #b0b0b0;
padding: 3px 3px;
margin-left: 1.5em;
margin-right: 1.5em;
margin-bottom: 1em;
padding: 0.3em 0.3em 0.3em 0.3em;
background: #fffff5;
border-radius: 0.4em;
box-shadow: 0.4em 0.4em 0.5em #e0e0e0;
}
div.note, div.warning
{
font-style: italic;
}
div.note h3, div.warning h3
{
color: red;
font-size: 100%;
padding-right: 0.5em;
display: inline;
}
div.note p, div.warning p
{
margin-bottom: 0em;
}
div.note h3 + p, div.warning h3 + p
{
display: inline;
}
div.note h3
{
color: blue;
font-size: 100%;
}
div.navfooter *
{
font-size: 90%;
}
/***************************************************************************
Links colors and highlighting:
***************************************************************************/
a { text-decoration: none; }
a:hover { text-decoration: underline; }
a:link { color: #0048b3; }
a:visited { color: #002a6a; }
/***************************************************************************
Table of contents:
***************************************************************************/
div.toc
{
font-size: 90%;
}
div.toc dl
{
margin-top: 0em;
margin-bottom: 0em;
}
/***************************************************************************
Special elements:
***************************************************************************/
tt, code
{
color: #400000;
}
.term
{
font-weight: bold;
}
div.variablelist dd p, div.glosslist dd p
{
margin-top: 0em;
}
div.variablelist dd, div.glosslist dd
{
margin-left: 1.5em;
}
div.glosslist dt
{
font-style: italic;
}
.varname
{
color: #400000;
}
span.command strong
{
font-weight: normal;
color: #400000;
}
div.calloutlist table
{
box-shadow: none;
}
table
{
border-collapse: collapse;
box-shadow: 0.4em 0.4em 0.5em #e0e0e0;
}
table.simplelist
{
text-align: left;
color: #005aa0;
border: 0;
padding: 5px;
background: #fffff5;
font-weight: normal;
font-style: italic;
box-shadow: none;
margin-bottom: 1em;
}
div.navheader table, div.navfooter table {
box-shadow: none;
}

View File

@ -7,23 +7,22 @@
, volumeLabel
}:
let
sdClosureInfo = pkgs.closureInfo { rootPaths = storePaths; };
in
pkgs.stdenv.mkDerivation {
name = "ext4-fs.img";
nativeBuildInputs = with pkgs; [e2fsprogs libfaketime perl];
# For obtaining the closure of `storePaths'.
exportReferencesGraph =
map (x: [("closure-" + baseNameOf x) x]) storePaths;
buildCommand =
''
# Add the closures of the top-level store objects.
storePaths=$(perl ${pkgs.pathsFromGraph} closure-*)
storePaths=$(cat ${sdClosureInfo}/store-paths)
# Also include a manifest of the closures in a format suitable
# for nix-store --load-db.
printRegistration=1 perl ${pkgs.pathsFromGraph} closure-* > nix-path-registration
# Also include a manifest of the closures in a format suitable for nix-store --load-db.
cp ${sdClosureInfo}/registration nix-path-registration
# Make a crude approximation of the size of the target image.
# If the script starts failing, increase the fudge factors here.

View File

@ -3,7 +3,7 @@
set -euo pipefail
BUCKET_NAME="${BUCKET_NAME:-nixos-images}"
BUCKET_NAME="${BUCKET_NAME:-nixos-cloud-images}"
TIMESTAMP="$(date +%Y%m%d%H%M)"
export TIMESTAMP
@ -19,5 +19,5 @@ img_name=$(basename "$img_path")
img_id=$(echo "$img_name" | sed 's|.raw.tar.gz$||;s|\.|-|g;s|_|-|g')
if ! gsutil ls "gs://${BUCKET_NAME}/$img_name"; then
gsutil cp "$img_path" "gs://${BUCKET_NAME}/$img_name"
gsutil acl ch -u AllUsers:R "gs://${BUCKET_NAME}/$img_name"
fi
gcloud compute images create "$img_id" --source-uri "gs://${BUCKET_NAME}/$img_name"

View File

@ -32,7 +32,6 @@ with lib;
networkmanager-l2tp = pkgs.networkmanager-l2tp.override { withGnome = false; };
networkmanager-openconnect = pkgs.networkmanager-openconnect.override { withGnome = false; };
networkmanager-openvpn = pkgs.networkmanager-openvpn.override { withGnome = false; };
networkmanager-pptp = pkgs.networkmanager-pptp.override { withGnome = false; };
networkmanager-vpnc = pkgs.networkmanager-vpnc.override { withGnome = false; };
networkmanager-iodine = pkgs.networkmanager-iodine.override { withGnome = false; };
pinentry = pkgs.pinentry_ncurses;

View File

@ -35,6 +35,7 @@ let
name = mkOption {
type = types.str;
apply = x: assert (builtins.stringLength x < 32 || abort "Username '${x}' is longer than 31 characters which is not allowed!"); x;
description = ''
The name of the user account. If undefined, the name of the
attribute set will be used.
@ -91,6 +92,7 @@ let
group = mkOption {
type = types.str;
apply = x: assert (builtins.stringLength x < 32 || abort "Group name '${x}' is longer than 31 characters which is not allowed!"); x;
default = "nogroup";
description = "The user's primary group.";
};

View File

@ -15,13 +15,19 @@ let
opengl = config.hardware.opengl;
kernel = pkgs.linux_4_9.override {
extraConfig = ''
KALLSYMS_ALL y
'';
};
in
{
config = mkIf enabled {
nixpkgs.config.xorg.abiCompat = "1.18";
nixpkgs.config.xorg.abiCompat = "1.19";
services.xserver.drivers = singleton
{ name = "amdgpu"; modules = [ package ]; libPath = [ package ]; };
@ -31,6 +37,9 @@ in
boot.extraModulePackages = [ package ];
boot.kernelPackages =
pkgs.recurseIntoAttrs (pkgs.linuxPackagesFor kernel);
boot.blacklistedKernelModules = [ "radeon" ];
hardware.firmware = [ package ];
@ -38,10 +47,15 @@ in
system.activationScripts.setup-amdgpu-pro = ''
mkdir -p /run/lib
ln -sfn ${package}/lib ${package.libCompatDir}
ln -sfn ${package} /run/amdgpu-pro
'' + optionalString opengl.driSupport32Bit ''
ln -sfn ${package32}/lib ${package32.libCompatDir}
'';
system.requiredKernelConfig = with config.lib.kernelConfig; [
(isYes "KALLSYMS_ALL")
];
environment.etc = {
"amd/amdrc".source = package + "/etc/amd/amdrc";
"amd/amdapfxx.blb".source = package + "/etc/amd/amdapfxx.blb";

View File

@ -16,8 +16,6 @@ let
kernelPackages.nvidia_x11
else if elem "nvidiaBeta" drivers then
kernelPackages.nvidia_x11_beta
else if elem "nvidiaLegacy173" drivers then
kernelPackages.nvidia_x11_legacy173
else if elem "nvidiaLegacy304" drivers then
kernelPackages.nvidia_x11_legacy304
else if elem "nvidiaLegacy340" drivers then

View File

@ -21,7 +21,9 @@ let
if [ ! -e $out/nixos/nixpkgs ]; then
ln -s . $out/nixos/nixpkgs
fi
echo -n ${config.system.nixos.revision} > $out/nixos/.git-revision
echo -n ${config.system.nixos.versionSuffix} > $out/nixos/.version-suffix
echo ${config.system.nixos.versionSuffix} | sed -e s/pre// > $out/nixos/svn-revision
'';
in

View File

@ -21,9 +21,6 @@ in
"it cannot be cross compiled";
};
# Needed by RPi firmware
nixpkgs.config.allowUnfree = true;
boot.loader.grub.enable = false;
boot.loader.generic-extlinux-compatible.enable = true;

View File

@ -21,9 +21,6 @@ in
"it cannot be cross compiled";
};
# Needed by RPi firmware
nixpkgs.config.allowUnfree = true;
boot.loader.grub.enable = false;
boot.loader.generic-extlinux-compatible.enable = true;

View File

@ -21,9 +21,6 @@ in
"it cannot be cross compiled";
};
# Needed by RPi firmware
nixpkgs.config.allowUnfree = true;
boot.loader.grub.enable = false;
boot.loader.generic-extlinux-compatible.enable = true;

View File

@ -20,6 +20,20 @@ let
in
{
options.sdImage = {
imageName = mkOption {
default = "${config.sdImage.imageBaseName}-${config.system.nixos.label}-${pkgs.stdenv.system}.img";
description = ''
Name of the generated image file.
'';
};
imageBaseName = mkOption {
default = "nixos-sd-image";
description = ''
Prefix of the name of the generated image file.
'';
};
storePaths = mkOption {
type = with types; listOf package;
example = literalExample "[ pkgs.stdenv ]";
@ -61,19 +75,25 @@ in
sdImage.storePaths = [ config.system.build.toplevel ];
system.build.sdImage = pkgs.stdenv.mkDerivation {
name = "sd-image-${pkgs.stdenv.system}.img";
name = config.sdImage.imageName;
buildInputs = with pkgs; [ dosfstools e2fsprogs mtools libfaketime utillinux ];
buildCommand = ''
mkdir -p $out/nix-support $out/sd-image
export img=$out/sd-image/${config.sdImage.imageName}
echo "${pkgs.stdenv.system}" > $out/nix-support/system
echo "file sd-image $img" >> $out/nix-support/hydra-build-products
# Create the image file sized to fit /boot and /, plus 20M of slack
rootSizeBlocks=$(du -B 512 --apparent-size ${rootfsImage} | awk '{ print $1 }')
bootSizeBlocks=$((${toString config.sdImage.bootSize} * 1024 * 1024 / 512))
imageSize=$((rootSizeBlocks * 512 + bootSizeBlocks * 512 + 20 * 1024 * 1024))
truncate -s $imageSize $out
truncate -s $imageSize $img
# type=b is 'W95 FAT32', type=83 is 'Linux'.
sfdisk $out <<EOF
sfdisk $img <<EOF
label: dos
label-id: 0x2178694e
@ -82,11 +102,11 @@ in
EOF
# Copy the rootfs into the SD image
eval $(partx $out -o START,SECTORS --nr 2 --pairs)
dd conv=notrunc if=${rootfsImage} of=$out seek=$START count=$SECTORS
eval $(partx $img -o START,SECTORS --nr 2 --pairs)
dd conv=notrunc if=${rootfsImage} of=$img seek=$START count=$SECTORS
# Create a FAT32 /boot partition of suitable size into bootpart.img
eval $(partx $out -o START,SECTORS --nr 1 --pairs)
eval $(partx $img -o START,SECTORS --nr 1 --pairs)
truncate -s $((SECTORS * 512)) bootpart.img
faketime "1970-01-01 00:00:00" mkfs.vfat -i 0x2178694e -n NIXOS_BOOT bootpart.img
@ -96,7 +116,7 @@ in
# Copy the populated /boot into the SD image
(cd boot; mcopy -bpsvm -i ../bootpart.img ./* ::)
dd conv=notrunc if=bootpart.img of=$out seek=$START count=$SECTORS
dd conv=notrunc if=bootpart.img of=$img seek=$START count=$SECTORS
'';
};

View File

@ -1,6 +1,6 @@
{
x86_64-linux = "/nix/store/6p2gambjac7xdkd2a7w1dsxdk1q5cq4d-nix-2.0";
i686-linux = "/nix/store/zznnaijjk3nwx0cmpczxsvngmqzhl7r4-nix-2.0";
aarch64-linux = "/nix/store/ci96w9kxfkmlc7x2vwqiz4da0r6abxnq-nix-2.0";
x86_64-darwin = "/nix/store/xmi4fylvx4qc79ji9v5q3zfy9vfdy4sv-nix-2.0";
x86_64-linux = "/nix/store/2gk7rk2sx2dkmsjr59gignrfdmya8f6s-nix-2.0.1";
i686-linux = "/nix/store/5160glkphiv13qggnivyidg8r0491pbl-nix-2.0.1";
aarch64-linux = "/nix/store/jk29zz3ns9vdkkclcyzzkpzp8dhv1x3i-nix-2.0.1";
x86_64-darwin = "/nix/store/4a9czmrpd4hf3r80zcmga2c2lm3hbbvv-nix-2.0.1";
}

View File

@ -51,8 +51,9 @@ if [[ ! -e $mountPoint/etc/NIXOS ]]; then
exit 126
fi
mkdir -m 0755 -p "$mountPoint/dev"
mkdir -m 0755 -p "$mountPoint/dev" "$mountPoint/sys"
mount --rbind /dev "$mountPoint/dev"
mount --rbind /sys "$mountPoint/sys"
# Run the activation script. Set $LOCALE_ARCHIVE to supress some Perl locale warnings.
LOCALE_ARCHIVE=$system/sw/lib/locale/locale-archive chroot "$mountPoint" "$system/activate" >&2 || true

View File

@ -382,6 +382,6 @@ fi
if [ "$action" = build-vm ]; then
cat >&2 <<EOF
Done. The virtual machine can be started by running $(echo $pathToConfig/bin/run-*-vm).
Done. The virtual machine can be started by running $(echo $pathToConfig/bin/run-*-vm)
EOF
fi

View File

@ -19,4 +19,6 @@ with lib;
# Add some more video drivers to give X11 a shot at working in
# VMware and QEMU.
services.xserver.videoDrivers = mkOverride 40 [ "virtualbox" "vmware" "cirrus" "vesa" "modesetting" ];
powerManagement.enable = false;
}

View File

@ -16,6 +16,21 @@ in
options.system = {
# XXX: Reintroduce old options to make nixops before 1.6 able to evaluate configurations
# XXX: Remove after nixops has been bumped to a compatible version
nixosVersion = mkOption {
readOnly = true;
internal = true;
type = types.str;
default = config.system.nixos.version;
};
nixosVersionSuffix = mkOption {
readOnly = true;
internal = true;
type = types.str;
default = config.system.nixos.versionSuffix;
};
nixos.version = mkOption {
internal = true;
type = types.str;
@ -70,7 +85,7 @@ in
defaultChannel = mkOption {
internal = true;
type = types.str;
default = https://nixos.org/channels/nixos-unstable;
default = https://nixos.org/channels/nixos-18.03;
description = "Default NixOS channel to which the root user is subscribed.";
};

View File

@ -159,6 +159,7 @@
./services/audio/ympd.nix
./services/backup/almir.nix
./services/backup/bacula.nix
./services/backup/borgbackup.nix
./services/backup/crashplan.nix
./services/backup/crashplan-small-business.nix
./services/backup/mysql-backup.nix
@ -322,7 +323,7 @@
./services/misc/geoip-updater.nix
./services/misc/gitea.nix
#./services/misc/gitit.nix
./services/misc/gitlab.nix
#./services/misc/gitlab.nix
./services/misc/gitolite.nix
./services/misc/gogs.nix
./services/misc/gollum.nix
@ -396,16 +397,7 @@
./services/monitoring/osquery.nix
./services/monitoring/prometheus/default.nix
./services/monitoring/prometheus/alertmanager.nix
./services/monitoring/prometheus/blackbox-exporter.nix
./services/monitoring/prometheus/collectd-exporter.nix
./services/monitoring/prometheus/fritzbox-exporter.nix
./services/monitoring/prometheus/json-exporter.nix
./services/monitoring/prometheus/minio-exporter.nix
./services/monitoring/prometheus/nginx-exporter.nix
./services/monitoring/prometheus/node-exporter.nix
./services/monitoring/prometheus/snmp-exporter.nix
./services/monitoring/prometheus/unifi-exporter.nix
./services/monitoring/prometheus/varnish-exporter.nix
./services/monitoring/prometheus/exporters.nix
./services/monitoring/riemann.nix
./services/monitoring/riemann-dash.nix
./services/monitoring/riemann-tools.nix

View File

@ -10,4 +10,10 @@
password = "demo";
uid = 1000;
};
services.xserver.displayManager.sddm.autoLogin = {
enable = true;
relogin = true;
user = "demo";
};
}

View File

@ -126,7 +126,7 @@ in
programs.bash = {
shellInit = ''
. ${config.system.build.setEnvironment}
${config.system.build.setEnvironment.text}
${cfge.shellInit}
'';

View File

@ -108,7 +108,7 @@ in
if [ -n "$__ETC_ZSHENV_SOURCED" ]; then return; fi
export __ETC_ZSHENV_SOURCED=1
. ${config.system.build.setEnvironment}
${config.system.build.setEnvironment.text}
${cfge.shellInit}

View File

@ -196,9 +196,9 @@ with lib;
(mkRenamedOptionModule [ "virtualization" "growPartition" ] [ "boot" "growPartition" ])
# misc/version.nix
(mkRenamedOptionModule [ "config" "system" "nixosVersion" ] [ "config" "system" "nixos" "version" ])
#(mkRenamedOptionModule [ "config" "system" "nixosVersion" ] [ "config" "system" "nixos" "version" ])
(mkRenamedOptionModule [ "config" "system" "nixosRelease" ] [ "config" "system" "nixos" "release" ])
(mkRenamedOptionModule [ "config" "system" "nixosVersionSuffix" ] [ "config" "system" "nixos" "versionSuffix" ])
#(mkRenamedOptionModule [ "config" "system" "nixosVersionSuffix" ] [ "config" "system" "nixos" "versionSuffix" ])
(mkRenamedOptionModule [ "config" "system" "nixosRevision" ] [ "config" "system" "nixos" "revision" ])
(mkRenamedOptionModule [ "config" "system" "nixosCodeName" ] [ "config" "system" "nixos" "codeName" ])
(mkRenamedOptionModule [ "config" "system" "nixosLabel" ] [ "config" "system" "nixos" "label" ])
@ -240,5 +240,11 @@ with lib;
# Xen
(mkRenamedOptionModule [ "virtualisation" "xen" "qemu-package" ] [ "virtualisation" "xen" "package-qemu" ])
];
] ++ (flip map [ "blackboxExporter" "collectdExporter" "fritzboxExporter"
"jsonExporter" "minioExporter" "nginxExporter" "nodeExporter"
"snmpExporter" "unifiExporter" "varnishExporter" ]
(opt: mkRemovedOptionModule [ "services" "prometheus" "${opt}" ] ''
The prometheus exporters are now configured using `services.prometheus.exporters'.
See the 18.03 release notes for more information.
'' ));
}

View File

@ -248,6 +248,7 @@ in
};
selfsignedService = {
description = "Create preliminary self-signed certificate for ${cert}";
path = [ pkgs.openssl ];
preStart = ''
if [ ! -d '${cpath}' ]
then
@ -258,37 +259,41 @@ in
'';
script =
''
# Create self-signed key
workdir="/run/acme-selfsigned-${cert}"
${pkgs.openssl.bin}/bin/openssl genrsa -des3 -passout pass:x -out $workdir/server.pass.key 2048
${pkgs.openssl.bin}/bin/openssl rsa -passin pass:x -in $workdir/server.pass.key -out $workdir/server.key
${pkgs.openssl.bin}/bin/openssl req -new -key $workdir/server.key -out $workdir/server.csr \
workdir="$(mktemp -d)"
# Create CA
openssl genrsa -des3 -passout pass:x -out $workdir/ca.pass.key 2048
openssl rsa -passin pass:x -in $workdir/ca.pass.key -out $workdir/ca.key
openssl req -new -key $workdir/ca.key -out $workdir/ca.csr \
-subj "/C=UK/ST=Warwickshire/L=Leamington/O=OrgName/OU=Security Department/CN=example.com"
openssl x509 -req -days 1 -in $workdir/ca.csr -signkey $workdir/ca.key -out $workdir/ca.crt
# Create key
openssl genrsa -des3 -passout pass:x -out $workdir/server.pass.key 2048
openssl rsa -passin pass:x -in $workdir/server.pass.key -out $workdir/server.key
openssl req -new -key $workdir/server.key -out $workdir/server.csr \
-subj "/C=UK/ST=Warwickshire/L=Leamington/O=OrgName/OU=IT Department/CN=example.com"
${pkgs.openssl.bin}/bin/openssl x509 -req -days 1 -in $workdir/server.csr -signkey $workdir/server.key -out $workdir/server.crt
openssl x509 -req -days 1 -in $workdir/server.csr -CA $workdir/ca.crt \
-CAkey $workdir/ca.key -CAserial $workdir/ca.srl -CAcreateserial \
-out $workdir/server.crt
# Move key to destination
mv $workdir/server.key ${cpath}/key.pem
mv $workdir/server.crt ${cpath}/fullchain.pem
# Copy key to destination
cp $workdir/server.key ${cpath}/key.pem
# Create full.pem for e.g. lighttpd (same format as "simp_le ... -f full.pem" creates)
cat "${cpath}/key.pem" "${cpath}/fullchain.pem" > "${cpath}/full.pem"
# Create fullchain.pem (same format as "simp_le ... -f fullchain.pem" creates)
cat $workdir/{server.crt,ca.crt} > "${cpath}/fullchain.pem"
# Clean up working directory
rm $workdir/server.csr
rm $workdir/server.pass.key
# Create full.pem for e.g. lighttpd
cat $workdir/{server.key,server.crt,ca.crt} > "${cpath}/full.pem"
# Give key acme permissions
chmod ${rights} '${cpath}/key.pem'
chown '${data.user}:${data.group}' '${cpath}/key.pem'
chmod ${rights} '${cpath}/fullchain.pem'
chown '${data.user}:${data.group}' '${cpath}/fullchain.pem'
chmod ${rights} '${cpath}/full.pem'
chown '${data.user}:${data.group}' '${cpath}/full.pem'
chown '${data.user}:${data.group}' "${cpath}/"{key,fullchain,full}.pem
chmod ${rights} "${cpath}/"{key,fullchain,full}.pem
'';
serviceConfig = {
Type = "oneshot";
RuntimeDirectory = "acme-selfsigned-${cert}";
PermissionsStartOnly = true;
PrivateTmp = true;
User = data.user;
Group = data.group;
};

View File

@ -47,8 +47,8 @@ in
default = true;
description =
''
Whether users of the <code>wheel</code> group can execute
commands as super user without entering a password.
Whether users of the <code>wheel</code> group must
provide a password to run commands as super user via <command>sudo</command>.
'';
};

View File

@ -0,0 +1,580 @@
{ config, lib, pkgs, ... }:
with lib;
let
isLocalPath = x:
builtins.substring 0 1 x == "/" # absolute path
|| builtins.substring 0 1 x == "." # relative path
|| builtins.match "[.*:.*]" == null; # not machine:path
mkExcludeFile = cfg:
# Write each exclude pattern to a new line
pkgs.writeText "excludefile" (concatStringsSep "\n" cfg.exclude);
mkKeepArgs = cfg:
# If cfg.prune.keep e.g. has a yearly attribute,
# its content is passed on as --keep-yearly
concatStringsSep " "
(mapAttrsToList (x: y: "--keep-${x}=${toString y}") cfg.prune.keep);
mkBackupScript = cfg: ''
on_exit()
{
exitStatus=$?
# Reset the EXIT handler, or else we're called again on 'exit' below
trap - EXIT
${cfg.postHook}
exit $exitStatus
}
trap 'on_exit' INT TERM QUIT EXIT
archiveName="${cfg.archiveBaseName}-$(date ${cfg.dateFormat})"
archiveSuffix="${optionalString cfg.appendFailedSuffix ".failed"}"
${cfg.preHook}
'' + optionalString cfg.doInit ''
# Run borg init if the repo doesn't exist yet
if ! borg list > /dev/null; then
borg init \
--encryption ${cfg.encryption.mode} \
$extraInitArgs
${cfg.postInit}
fi
'' + ''
borg create \
--compression ${cfg.compression} \
--exclude-from ${mkExcludeFile cfg} \
$extraCreateArgs \
"::$archiveName$archiveSuffix" \
${escapeShellArgs cfg.paths}
'' + optionalString cfg.appendFailedSuffix ''
borg rename "::$archiveName$archiveSuffix" "$archiveName"
'' + ''
${cfg.postCreate}
'' + optionalString (cfg.prune.keep != { }) ''
borg prune \
${mkKeepArgs cfg} \
--prefix ${escapeShellArg cfg.prune.prefix} \
$extraPruneArgs
${cfg.postPrune}
'';
mkPassEnv = cfg: with cfg.encryption;
if passCommand != null then
{ BORG_PASSCOMMAND = passCommand; }
else if passphrase != null then
{ BORG_PASSPHRASE = passphrase; }
else { };
mkBackupService = name: cfg:
let
userHome = config.users.users.${cfg.user}.home;
in nameValuePair "borgbackup-job-${name}" {
description = "BorgBackup job ${name}";
path = with pkgs; [
borgbackup openssh
];
script = mkBackupScript cfg;
serviceConfig = {
User = cfg.user;
Group = cfg.group;
# Only run when no other process is using CPU or disk
CPUSchedulingPolicy = "idle";
IOSchedulingClass = "idle";
ProtectSystem = "strict";
ReadWritePaths =
[ "${userHome}/.config/borg" "${userHome}/.cache/borg" ]
# Borg needs write access to repo if it is not remote
++ optional (isLocalPath cfg.repo) cfg.repo;
PrivateTmp = true;
};
environment = {
BORG_REPO = cfg.repo;
inherit (cfg) extraInitArgs extraCreateArgs extraPruneArgs;
} // (mkPassEnv cfg) // cfg.environment;
inherit (cfg) startAt;
};
# Paths listed in ReadWritePaths must exist before service is started
mkActivationScript = name: cfg:
let
install = "install -o ${cfg.user} -g ${cfg.group}";
in
nameValuePair "borgbackup-job-${name}" (stringAfter [ "users" ] (''
# Eensure that the home directory already exists
# We can't assert createHome == true because that's not the case for root
cd "${config.users.users.${cfg.user}.home}"
${install} -d .config/borg
${install} -d .cache/borg
'' + optionalString (isLocalPath cfg.repo) ''
${install} -d ${escapeShellArg cfg.repo}
''));
mkPassAssertion = name: cfg: {
assertion = with cfg.encryption;
mode != "none" -> passCommand != null || passphrase != null;
message =
"passCommand or passphrase has to be specified because"
+ '' borgbackup.jobs.${name}.encryption != "none"'';
};
mkRepoService = name: cfg:
nameValuePair "borgbackup-repo-${name}" {
description = "Create BorgBackup repository ${name} directory";
script = ''
mkdir -p ${escapeShellArg cfg.path}
chown ${cfg.user}:${cfg.group} ${escapeShellArg cfg.path}
'';
serviceConfig = {
# The service's only task is to ensure that the specified path exists
Type = "oneshot";
};
wantedBy = [ "multi-user.target" ];
};
mkAuthorizedKey = cfg: appendOnly: key:
let
# Because of the following line, clients do not need to specify an absolute repo path
cdCommand = "cd ${escapeShellArg cfg.path}";
restrictedArg = "--restrict-to-${if cfg.allowSubRepos then "path" else "repository"} .";
appendOnlyArg = optionalString appendOnly "--append-only";
quotaArg = optionalString (cfg.quota != null) "--storage-quota ${cfg.quota}";
serveCommand = "borg serve ${restrictedArg} ${appendOnlyArg} ${quotaArg}";
in
''command="${cdCommand} && ${serveCommand}",restrict ${key}'';
mkUsersConfig = name: cfg: {
users.${cfg.user} = {
openssh.authorizedKeys.keys =
(map (mkAuthorizedKey cfg false) cfg.authorizedKeys
++ map (mkAuthorizedKey cfg true) cfg.authorizedKeysAppendOnly);
useDefaultShell = true;
};
groups.${cfg.group} = { };
};
mkKeysAssertion = name: cfg: {
assertion = cfg.authorizedKeys != [ ] || cfg.authorizedKeysAppendOnly != [ ];
message =
"borgbackup.repos.${name} does not make sense"
+ " without at least one public key";
};
in {
meta.maintainers = with maintainers; [ dotlambda ];
###### interface
options.services.borgbackup.jobs = mkOption {
description = "Deduplicating backups using BorgBackup.";
default = { };
example = literalExample ''
{
rootBackup = {
paths = "/";
exclude = [ "/nix" ];
repo = "/path/to/local/repo";
encryption = {
mode = "repokey";
passphrase = "secret";
};
compression = "auto,lzma";
startAt = "weekly";
};
}
'';
type = types.attrsOf (types.submodule (let globalConfig = config; in
{ name, config, ... }: {
options = {
paths = mkOption {
type = with types; either path (nonEmptyListOf path);
description = "Path(s) to back up.";
example = "/home/user";
apply = x: if isList x then x else [ x ];
};
repo = mkOption {
type = types.str;
description = "Remote or local repository to back up to.";
example = "user@machine:/path/to/repo";
};
archiveBaseName = mkOption {
type = types.strMatching "[^/{}]+";
default = "${globalConfig.networking.hostName}-${name}";
defaultText = "\${config.networking.hostName}-<name>";
description = ''
How to name the created archives. A timestamp, whose format is
determined by <option>dateFormat</option>, will be appended. The full
name can be modified at runtime (<literal>$archiveName</literal>).
Placeholders like <literal>{hostname}</literal> must not be used.
'';
};
dateFormat = mkOption {
type = types.str;
description = ''
Arguments passed to <command>date</command>
to create a timestamp suffix for the archive name.
'';
default = "+%Y-%m-%dT%H:%M:%S";
example = "-u +%s";
};
startAt = mkOption {
type = with types; either str (listOf str);
default = "daily";
description = ''
When or how often the backup should run.
Must be in the format described in
<citerefentry><refentrytitle>systemd.time</refentrytitle>
<manvolnum>7</manvolnum></citerefentry>.
If you do not want the backup to start
automatically, use <literal>[ ]</literal>.
'';
};
user = mkOption {
type = types.str;
description = ''
The user <command>borg</command> is run as.
User or group need read permission
for the specified <option>paths</option>.
'';
default = "root";
};
group = mkOption {
type = types.str;
description = ''
The group borg is run as. User or group needs read permission
for the specified <option>paths</option>.
'';
default = "root";
};
encryption.mode = mkOption {
type = types.enum [
"repokey" "keyfile"
"repokey-blake2" "keyfile-blake2"
"authenticated" "authenticated-blake2"
"none"
];
description = ''
Encryption mode to use. Setting a mode
other than <literal>"none"</literal> requires
you to specify a <option>passCommand</option>
or a <option>passphrase</option>.
'';
};
encryption.passCommand = mkOption {
type = with types; nullOr str;
description = ''
A command which prints the passphrase to stdout.
Mutually exclusive with <option>passphrase</option>.
'';
default = null;
example = "cat /path/to/passphrase_file";
};
encryption.passphrase = mkOption {
type = with types; nullOr str;
description = ''
The passphrase the backups are encrypted with.
Mutually exclusive with <option>passCommand</option>.
If you do not want the passphrase to be stored in the
world-readable Nix store, use <option>passCommand</option>.
'';
default = null;
};
compression = mkOption {
# "auto" is optional,
# compression mode must be given,
# compression level is optional
type = types.strMatching "none|(auto,)?(lz4|zstd|zlib|lzma)(,[[:digit:]]{1,2})?";
description = ''
Compression method to use. Refer to
<command>borg help compression</command>
for all available options.
'';
default = "lz4";
example = "auto,lzma";
};
exclude = mkOption {
type = with types; listOf str;
description = ''
Exclude paths matching any of the given patterns. See
<command>borg help patterns</command> for pattern syntax.
'';
default = [ ];
example = [
"/home/*/.cache"
"/nix"
];
};
doInit = mkOption {
type = types.bool;
description = ''
Run <command>borg init</command> if the
specified <option>repo</option> does not exist.
You should set this to <literal>false</literal>
if the repository is located on an external drive
that might not always be mounted.
'';
default = true;
};
appendFailedSuffix = mkOption {
type = types.bool;
description = ''
Append a <literal>.failed</literal> suffix
to the archive name, which is only removed if
<command>borg create</command> has a zero exit status.
'';
default = true;
};
prune.keep = mkOption {
# Specifying e.g. `prune.keep.yearly = -1`
# means there is no limit of yearly archives to keep
# The regex is for use with e.g. --keep-within 1y
type = with types; attrsOf (either int (strMatching "[[:digit:]]+[Hdwmy]"));
description = ''
Prune a repository by deleting all archives not matching any of the
specified retention options. See <command>borg help prune</command>
for the available options.
'';
default = { };
example = literalExample ''
{
within = "1d"; # Keep all archives from the last day
daily = 7;
weekly = 4;
monthly = -1; # Keep at least one archive for each month
}
'';
};
prune.prefix = mkOption {
type = types.str;
description = ''
Only consider archive names starting with this prefix for pruning.
By default, only archives created by this job are considered.
Use <literal>""</literal> to consider all archives.
'';
default = config.archiveBaseName;
defaultText = "\${archiveBaseName}";
};
environment = mkOption {
type = with types; attrsOf str;
description = ''
Environment variables passed to the backup script.
You can for example specify which SSH key to use.
'';
default = { };
example = { BORG_RSH = "ssh -i /path/to/key"; };
};
preHook = mkOption {
type = types.lines;
description = ''
Shell commands to run before the backup.
This can for example be used to mount file systems.
'';
default = "";
example = ''
# To add excluded paths at runtime
extraCreateArgs="$extraCreateArgs --exclude /some/path"
'';
};
postInit = mkOption {
type = types.lines;
description = ''
Shell commands to run after <command>borg init</command>.
'';
default = "";
};
postCreate = mkOption {
type = types.lines;
description = ''
Shell commands to run after <command>borg create</command>. The name
of the created archive is stored in <literal>$archiveName</literal>.
'';
default = "";
};
postPrune = mkOption {
type = types.lines;
description = ''
Shell commands to run after <command>borg prune</command>.
'';
default = "";
};
postHook = mkOption {
type = types.lines;
description = ''
Shell commands to run just before exit. They are executed
even if a previous command exits with a non-zero exit code.
The latter is available as <literal>$exitStatus</literal>.
'';
default = "";
};
extraInitArgs = mkOption {
type = types.str;
description = ''
Additional arguments for <command>borg init</command>.
Can also be set at runtime using <literal>$extraInitArgs</literal>.
'';
default = "";
example = "--append-only";
};
extraCreateArgs = mkOption {
type = types.str;
description = ''
Additional arguments for <command>borg create</command>.
Can also be set at runtime using <literal>$extraCreateArgs</literal>.
'';
default = "";
example = "--stats --checkpoint-interval 600";
};
extraPruneArgs = mkOption {
type = types.str;
description = ''
Additional arguments for <command>borg prune</command>.
Can also be set at runtime using <literal>$extraPruneArgs</literal>.
'';
default = "";
example = "--save-space";
};
};
}
));
};
options.services.borgbackup.repos = mkOption {
description = ''
Serve BorgBackup repositories to given public SSH keys,
restricting their access to the repository only.
Also, clients do not need to specify the absolute path when accessing the repository,
i.e. <literal>user@machine:.</literal> is enough. (Note colon and dot.)
'';
default = { };
type = types.attrsOf (types.submodule (
{ name, config, ... }: {
options = {
path = mkOption {
type = types.path;
description = ''
Where to store the backups. Note that the directory
is created automatically, with correct permissions.
'';
default = "/var/lib/borgbackup";
};
user = mkOption {
type = types.str;
description = ''
The user <command>borg serve</command> is run as.
User or group needs write permission
for the specified <option>path</option>.
'';
default = "borg";
};
group = mkOption {
type = types.str;
description = ''
The group <command>borg serve</command> is run as.
User or group needs write permission
for the specified <option>path</option>.
'';
default = "borg";
};
authorizedKeys = mkOption {
type = with types; listOf str;
description = ''
Public SSH keys that are given full write access to this repository.
You should use a different SSH key for each repository you write to, because
the specified keys are restricted to running <command>borg serve</command>
and can only access this single repository.
'';
default = [ ];
};
authorizedKeysAppendOnly = mkOption {
type = with types; listOf str;
description = ''
Public SSH keys that can only be used to append new data (archives) to the repository.
Note that archives can still be marked as deleted and are subsequently removed from disk
upon accessing the repo with full write access, e.g. when pruning.
'';
default = [ ];
};
allowSubRepos = mkOption {
type = types.bool;
description = ''
Allow clients to create repositories in subdirectories of the
specified <option>path</option>. These can be accessed using
<literal>user@machine:path/to/subrepo</literal>. Note that a
<option>quota</option> applies to repositories independently.
Therefore, if this is enabled, clients can create multiple
repositories and upload an arbitrary amount of data.
'';
default = false;
};
quota = mkOption {
# See the definition of parse_file_size() in src/borg/helpers/parseformat.py
type = with types; nullOr (strMatching "[[:digit:].]+[KMGTP]?");
description = ''
Storage quota for the repository. This quota is ensured for all
sub-repositories if <option>allowSubRepos</option> is enabled
but not for the overall storage space used.
'';
default = null;
example = "100G";
};
};
}
));
};
###### implementation
config = mkIf (with config.services.borgbackup; jobs != { } || repos != { })
(with config.services.borgbackup; {
assertions =
mapAttrsToList mkPassAssertion jobs
++ mapAttrsToList mkKeysAssertion repos;
system.activationScripts = mapAttrs' mkActivationScript jobs;
systemd.services =
# A job named "foo" is mapped to systemd.services.borgbackup-job-foo
mapAttrs' mkBackupService jobs
# A repo named "foo" is mapped to systemd.services.borgbackup-repo-foo
// mapAttrs' mkRepoService repos;
users = mkMerge (mapAttrsToList mkUsersConfig repos);
environment.systemPackages = with pkgs; [ borgbackup ];
});
}

View File

@ -386,7 +386,7 @@ in
echo Resetting znapzend zetups
${pkgs.znapzend}/bin/znapzendzetup list \
| grep -oP '(?<=\*\*\* backup plan: ).*(?= \*\*\*)' \
| xargs ${pkgs.znapzend}/bin/znapzendzetup delete
| xargs -I{} ${pkgs.znapzend}/bin/znapzendzetup delete "{}"
'' + concatStringsSep "\n" (mapAttrsToList (dataset: config: ''
echo Importing znapzend zetup ${config} for dataset ${dataset}
${pkgs.znapzend}/bin/znapzendzetup import --write ${dataset} ${config}

View File

@ -145,6 +145,11 @@ in {
};
config = mkIf cfg.enable {
# server references the dejavu fonts
environment.systemPackages = [
pkgs.dejavu_fonts
];
users.extraGroups = optional (cfg.group == "jenkins") {
name = "jenkins";
gid = config.ids.gids.jenkins;
@ -200,10 +205,12 @@ in {
${replacePlugins}
'';
# For reference: https://wiki.jenkins.io/display/JENKINS/JenkinsLinuxStartupScript
script = ''
${pkgs.jdk}/bin/java ${concatStringsSep " " cfg.extraJavaOptions} -jar ${cfg.package}/webapps/jenkins.war --httpListenAddress=${cfg.listenAddress} \
--httpPort=${toString cfg.port} \
--prefix=${cfg.prefix} \
-Djava.awt.headless=true \
${concatStringsSep " " cfg.extraOptions}
'';

View File

@ -26,8 +26,15 @@ in {
name = "trezord-udev-rules";
destination = "/etc/udev/rules.d/51-trezor.rules";
text = ''
SUBSYSTEM=="usb", ATTR{idVendor}=="534c", ATTR{idProduct}=="0001", MODE="0666", GROUP="dialout", SYMLINK+="trezor%n"
KERNEL=="hidraw*", ATTRS{idVendor}=="534c", ATTRS{idProduct}=="0001", MODE="0666", GROUP="dialout"
# Trezor 1
SUBSYSTEM=="usb", ATTR{idVendor}=="534c", ATTR{idProduct}=="0001", MODE="0666", GROUP="dialout", SYMLINK+="trezor%n"
KERNEL=="hidraw*", ATTRS{idVendor}=="534c", ATTRS{idProduct}=="0001", MODE="0666", GROUP="dialout"
# Trezor 2 (Model-T)
SUBSYSTEM=="usb", ATTR{idVendor}=="1209", ATTR{idProduct}=="53c0", MODE="0661", GROUP="dialout", TAG+="uaccess", TAG+="udev-acl", SYMLINK+="trezor%n"
SUBSYSTEM=="usb", ATTR{idVendor}=="1209", ATTR{idProduct}=="53c1", MODE="0660", GROUP="dialout", TAG+="uaccess", TAG+="udev-acl", SYMLINK+="trezor%n"
KERNEL=="hidraw*", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="53c1", MODE="0660", GROUP="dialout", TAG+="uaccess", TAG+="udev-acl"
];
'';
});
@ -38,7 +45,7 @@ in {
path = [];
serviceConfig = {
Type = "simple";
ExecStart = "${pkgs.trezord}/bin/trezord -f";
ExecStart = "${pkgs.trezord}/bin/trezord-go";
User = "trezord";
};
};

View File

@ -141,7 +141,7 @@ in
JAVA_HOME = jre;
GRAYLOG_CONF = "${confFile}";
};
path = [ pkgs.openjdk8 pkgs.which pkgs.procps ];
path = [ pkgs.jre_headless pkgs.which pkgs.procps ];
preStart = ''
mkdir -p /var/lib/graylog -m 755

View File

@ -30,6 +30,7 @@ let
''
default_internal_user = ${cfg.user}
default_internal_group = ${cfg.group}
${optionalString (cfg.mailUser != null) "mail_uid = ${cfg.mailUser}"}
${optionalString (cfg.mailGroup != null) "mail_gid = ${cfg.mailGroup}"}

View File

@ -1,205 +1,69 @@
# The following was taken from github.com/crohr/syslogger and is BSD
# licensed.
require 'syslog'
require 'logger'
require 'thread'
class Syslogger
VERSION = "1.6.0"
attr_reader :level, :ident, :options, :facility, :max_octets
attr_accessor :formatter
MAPPING = {
Logger::DEBUG => Syslog::LOG_DEBUG,
Logger::INFO => Syslog::LOG_INFO,
Logger::WARN => Syslog::LOG_WARNING,
Logger::ERROR => Syslog::LOG_ERR,
Logger::FATAL => Syslog::LOG_CRIT,
Logger::UNKNOWN => Syslog::LOG_ALERT
}
#
# Initializes default options for the logger
# <tt>ident</tt>:: the name of your program [default=$0].
# <tt>options</tt>:: syslog options [default=<tt>Syslog::LOG_PID | Syslog::LOG_CONS</tt>].
# Correct values are:
# LOG_CONS : writes the message on the console if an error occurs when sending the message;
# LOG_NDELAY : no delay before sending the message;
# LOG_PERROR : messages will also be written on STDERR;
# LOG_PID : adds the process number to the message (just after the program name)
# <tt>facility</tt>:: the syslog facility [default=nil] Correct values include:
# Syslog::LOG_DAEMON
# Syslog::LOG_USER
# Syslog::LOG_SYSLOG
# Syslog::LOG_LOCAL2
# Syslog::LOG_NEWS
# etc.
#
# Usage:
# logger = Syslogger.new("my_app", Syslog::LOG_PID | Syslog::LOG_CONS, Syslog::LOG_LOCAL0)
# logger.level = Logger::INFO # use Logger levels
# logger.warn "warning message"
# logger.debug "debug message"
#
def initialize(ident = $0, options = Syslog::LOG_PID | Syslog::LOG_CONS, facility = nil)
@ident = ident
@options = options || (Syslog::LOG_PID | Syslog::LOG_CONS)
@facility = facility
@level = Logger::INFO
@mutex = Mutex.new
@formatter = Logger::Formatter.new
end
%w{debug info warn error fatal unknown}.each do |logger_method|
# Accepting *args as message could be nil.
# Default params not supported in ruby 1.8.7
define_method logger_method.to_sym do |*args, &block|
return true if @level > Logger.const_get(logger_method.upcase)
message = args.first || block && block.call
add(Logger.const_get(logger_method.upcase), message)
end
unless logger_method == 'unknown'
define_method "#{logger_method}?".to_sym do
@level <= Logger.const_get(logger_method.upcase)
end
end
end
# Log a message at the Logger::INFO level. Useful for use with Rack::CommonLogger
def write(msg)
add(Logger::INFO, msg)
end
# Logs a message at the Logger::INFO level.
def <<(msg)
add(Logger::INFO, msg)
end
# Low level method to add a message.
# +severity+:: the level of the message. One of Logger::DEBUG, Logger::INFO, Logger::WARN, Logger::ERROR, Logger::FATAL, Logger::UNKNOWN
# +message+:: the message string.
# If nil, the method will call the block and use the result as the message string.
# If both are nil or no block is given, it will use the progname as per the behaviour of both the standard Ruby logger, and the Rails BufferedLogger.
# +progname+:: optionally, overwrite the program name that appears in the log message.
def add(severity, message = nil, progname = nil, &block)
if message.nil? && block.nil? && !progname.nil?
message, progname = progname, nil
end
progname ||= @ident
@mutex.synchronize do
Syslog.open(progname, @options, @facility) do |s|
s.mask = Syslog::LOG_UPTO(MAPPING[@level])
communication = clean(message || block && block.call)
if self.max_octets
buffer = "#{tags_text}"
communication.bytes do |byte|
buffer.concat(byte)
# if the last byte we added is potentially part of an escape, we'll go ahead and add another byte
if buffer.bytesize >= self.max_octets && !['%'.ord,'\\'.ord].include?(byte)
s.log(MAPPING[severity],buffer)
buffer = ""
end
end
s.log(MAPPING[severity],buffer) unless buffer.empty?
else
s.log(MAPPING[severity],"#{tags_text}#{communication}")
end
end
end
end
# Set the max octets of the messages written to the log
def max_octets=(max_octets)
@max_octets = max_octets
end
# Sets the minimum level for messages to be written in the log.
# +level+:: one of <tt>Logger::DEBUG</tt>, <tt>Logger::INFO</tt>, <tt>Logger::WARN</tt>, <tt>Logger::ERROR</tt>, <tt>Logger::FATAL</tt>, <tt>Logger::UNKNOWN</tt>
def level=(level)
level = Logger.const_get(level.to_s.upcase) if level.is_a?(Symbol)
unless level.is_a?(Fixnum)
raise ArgumentError.new("Invalid logger level `#{level.inspect}`")
end
@level = level
end
# Sets the ident string passed along to Syslog
def ident=(ident)
@ident = ident
end
# Tagging code borrowed from ActiveSupport gem
def tagged(*tags)
new_tags = push_tags(*tags)
yield self
ensure
pop_tags(new_tags.size)
end
def push_tags(*tags)
tags.flatten.reject{ |i| i.respond_to?(:empty?) ? i.empty? : !i }.tap do |new_tags|
current_tags.concat new_tags
end
end
def pop_tags(size = 1)
current_tags.pop size
end
def clear_tags!
current_tags.clear
end
protected
# Borrowed from SyslogLogger.
def clean(message)
message = message.to_s.dup
message.strip! # remove whitespace
message.gsub!(/\n/, '\\n') # escape newlines
message.gsub!(/%/, '%%') # syslog(3) freaks on % (printf)
message.gsub!(/\e\[[^m]*m/, '') # remove useless ansi color codes
message
end
private
def tags_text
tags = current_tags
if tags.any?
tags.collect { |tag| "[#{tag}] " }.join
end
end
def current_tags
Thread.current[:syslogger_tagged_logging_tags] ||= []
end
end
worker_processes 2
working_directory ENV["GITLAB_PATH"]
pid ENV["UNICORN_PATH"] + "/tmp/pids/unicorn.pid"
worker_processes 3
listen ENV["UNICORN_PATH"] + "/tmp/sockets/gitlab.socket", :backlog => 1024
listen "/run/gitlab/gitlab.socket", :backlog => 1024
working_directory ENV["GITLAB_PATH"]
pid ENV["UNICORN_PATH"] + "/tmp/pids/unicorn.pid"
timeout 60
logger Syslogger.new
# combine Ruby 2.0.0dev or REE with "preload_app true" for memory savings
# http://rubyenterpriseedition.com/faq.html#adapt_apps_for_cow
preload_app true
GC.respond_to?(:copy_on_write_friendly=) and
GC.copy_on_write_friendly = true
check_client_connection false
before_fork do |server, worker|
# the following is highly recommended for Rails + "preload_app true"
# as there's no need for the master process to hold a connection
defined?(ActiveRecord::Base) and
ActiveRecord::Base.connection.disconnect!
# The following is only recommended for memory/DB-constrained
# installations. It is not needed if your system can house
# twice as many worker_processes as you have configured.
#
# This allows a new master process to incrementally
# phase out the old master process with SIGTTOU to avoid a
# thundering herd (especially in the "preload_app false" case)
# when doing a transparent upgrade. The last worker spawned
# will then kill off the old master process with a SIGQUIT.
old_pid = "#{server.config[:pid]}.oldbin"
if old_pid != server.pid
begin
sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
Process.kill(sig, File.read(old_pid).to_i)
rescue Errno::ENOENT, Errno::ESRCH
end
end
# Throttle the master from forking too quickly by sleeping. Due
# to the implementation of standard Unix signal handlers, this
# helps (but does not completely) prevent identical, repeated signals
# from being lost when the receiving process is busy.
# sleep 1
end
after_fork do |server, worker|
# per-process listener ports for debugging/admin/migrations
# addr = "127.0.0.1:#{9293 + worker.nr}"
# server.listen(addr, :tries => -1, :delay => 5, :tcp_nopush => true)
# the following is *required* for Rails + "preload_app true",
defined?(ActiveRecord::Base) and
ActiveRecord::Base.establish_connection
# reset prometheus client, this will cause any opened metrics files to be closed
defined?(::Prometheus::Client.reinitialize_on_pid_change) &&
Prometheus::Client.reinitialize_on_pid_change
# if preload_app is true, then you may also want to check and
# restart any other shared sockets/descriptors such as Memcached,
# and Redis. TokyoCabinet file handles are safe to reuse
# between any number of forked children (assuming your kernel
# correctly implements pread()/pwrite() system calls)
end

View File

@ -4,6 +4,8 @@ with lib;
let
cfg = config.services.gitea;
pg = config.services.postgresql;
usePostgresql = cfg.database.type == "postgres";
configFile = pkgs.writeText "app.ini" ''
APP_NAME = ${cfg.appName}
RUN_USER = ${cfg.user}
@ -16,6 +18,9 @@ let
USER = ${cfg.database.user}
PASSWD = #dbpass#
PATH = ${cfg.database.path}
${optionalString usePostgresql ''
SSL_MODE = disable
''}
[repository]
ROOT = ${cfg.repositoryRoot}
@ -35,6 +40,10 @@ let
SECRET_KEY = #secretkey#
INSTALL_LOCK = true
[log]
ROOT_PATH = ${cfg.log.rootPath}
LEVEL = ${cfg.log.level}
${cfg.extraConfig}
'';
in
@ -60,6 +69,19 @@ in
description = "gitea data directory.";
};
log = {
rootPath = mkOption {
default = "${cfg.stateDir}/log";
type = types.str;
description = "Root path for log files.";
};
level = mkOption {
default = "Trace";
type = types.enum [ "Trace" "Debug" "Info" "Warn" "Error" "Critical" ];
description = "General log level.";
};
};
user = mkOption {
type = types.str;
default = "gitea";
@ -82,7 +104,7 @@ in
port = mkOption {
type = types.int;
default = 3306;
default = (if !usePostgresql then 3306 else pg.port);
description = "Database host port.";
};
@ -123,6 +145,15 @@ in
default = "${cfg.stateDir}/data/gitea.db";
description = "Path to the sqlite3 database file.";
};
createDatabase = mkOption {
type = types.bool;
default = true;
description = ''
Whether to create a local postgresql database automatically.
This only applies if database type "postgres" is selected.
'';
};
};
appName = mkOption {
@ -186,10 +217,11 @@ in
};
config = mkIf cfg.enable {
services.postgresql.enable = mkIf usePostgresql (mkDefault true);
systemd.services.gitea = {
description = "gitea";
after = [ "network.target" ];
after = [ "network.target" "postgresql.service" ];
wantedBy = [ "multi-user.target" ];
path = [ pkgs.gitea.bin ];
@ -231,12 +263,31 @@ in
mkdir -p ${cfg.stateDir}/conf
cp -r ${pkgs.gitea.out}/locale ${cfg.stateDir}/conf/locale
fi
'' + optionalString (usePostgresql && cfg.database.createDatabase) ''
if ! test -e "${cfg.stateDir}/db-created"; then
echo "CREATE ROLE ${cfg.database.user}
WITH ENCRYPTED PASSWORD '$(head -n1 ${cfg.database.passwordFile})'
NOCREATEDB NOCREATEROLE LOGIN" |
${pkgs.sudo}/bin/sudo -u ${pg.superUser} ${pg.package}/bin/psql
${pkgs.sudo}/bin/sudo -u ${pg.superUser} \
${pg.package}/bin/createdb \
--owner=${cfg.database.user} \
--encoding=UTF8 \
--lc-collate=C \
--lc-ctype=C \
--template=template0 \
${cfg.database.name}
touch "${cfg.stateDir}/db-created"
fi
'' + ''
chown ${cfg.user} -R ${cfg.stateDir}
'';
serviceConfig = {
Type = "simple";
User = cfg.user;
WorkingDirectory = cfg.stateDir;
PermissionsStartOnly = true;
ExecStart = "${pkgs.gitea.bin}/bin/gitea web";
Restart = "always";
};
@ -253,6 +304,7 @@ in
description = "Gitea Service";
home = cfg.stateDir;
createHome = true;
useDefaultShell = true;
};
};

View File

@ -143,6 +143,7 @@ let
GITLAB_PATH = "${cfg.packages.gitlab}/share/gitlab/";
GITLAB_STATE_PATH = "${cfg.statePath}";
GITLAB_UPLOADS_PATH = "${cfg.statePath}/uploads";
SCHEMA = "${cfg.statePath}/db/schema.rb";
GITLAB_LOG_PATH = "${cfg.statePath}/log";
GITLAB_SHELL_PATH = "${cfg.packages.gitlab-shell}";
GITLAB_SHELL_CONFIG_PATH = "${cfg.statePath}/shell/config.yml";
@ -500,7 +501,7 @@ in {
Type = "simple";
User = cfg.user;
Group = cfg.group;
TimeoutSec = "300";
TimeoutSec = "infinity";
Restart = "on-failure";
WorkingDirectory = gitlabEnv.HOME;
ExecStart = "${cfg.packages.gitaly}/bin/gitaly ${gitalyToml}";
@ -566,6 +567,7 @@ in {
mkdir -p ${cfg.statePath}/tmp/pids
mkdir -p ${cfg.statePath}/tmp/sockets
mkdir -p ${cfg.statePath}/shell
mkdir -p ${cfg.statePath}/db
rm -rf ${cfg.statePath}/config ${cfg.statePath}/shell/hooks
mkdir -p ${cfg.statePath}/config
@ -580,6 +582,7 @@ in {
ln -sf ${cfg.statePath}/log /run/gitlab/log
ln -sf ${cfg.statePath}/uploads /run/gitlab/uploads
ln -sf ${cfg.statePath}/tmp /run/gitlab/tmp
ln -sf $GITLAB_SHELL_CONFIG_PATH /run/gitlab/shell-config.yml
chown -R ${cfg.user}:${cfg.group} /run/gitlab
# Prepare home directory
@ -587,6 +590,7 @@ in {
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/config.dist/* ${cfg.statePath}/config
${optionalString cfg.smtp.enable ''
ln -sf ${smtpSettings} ${cfg.statePath}/config/initializers/smtp_settings.rb

View File

@ -104,7 +104,6 @@ in {
config = mkIf cfg.enable {
systemd.services.home-assistant = {
description = "Home Assistant";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
preStart = lib.optionalString (cfg.config != null) ''
rm -f ${cfg.configDir}/configuration.yaml
@ -121,6 +120,16 @@ in {
ReadWritePaths = "${cfg.configDir}";
PrivateTmp = true;
};
path = [
"/run/wrappers" # needed for ping
];
};
systemd.targets.home-assistant = rec {
description = "Home Assistant";
wantedBy = [ "multi-user.target" ];
wants = [ "home-assistant.service" ];
after = wants;
};
users.extraUsers.hass = {

View File

@ -6,6 +6,8 @@ let
cfg = config.services.parsoid;
parsoid = pkgs.nodePackages."parsoid-git://github.com/abbradar/parsoid#stable";
confTree = {
worker_heartbeat_timeout = 300000;
logging = { level = "info"; };
@ -93,7 +95,7 @@ in
after = [ "network.target" ];
serviceConfig = {
User = "nobody";
ExecStart = "${pkgs.nodePackages.parsoid}/lib/node_modules/parsoid/bin/server.js -c ${confFile} -n ${toString cfg.workers}";
ExecStart = "${parsoid}/lib/node_modules/parsoid/bin/server.js -c ${confFile} -n ${toString cfg.workers}";
};
};

View File

@ -25,6 +25,7 @@ let
DATABASE_USER = cfg.database.user;
DATABASE_PASSWORD = cfg.database.password;
DATABASE_PATH = cfg.database.path;
DATABASE_CONN_MAX_LIFETIME = cfg.database.connMaxLifetime;
SECURITY_ADMIN_USER = cfg.security.adminUser;
SECURITY_ADMIN_PASSWORD = cfg.security.adminPassword;
@ -49,7 +50,7 @@ in {
protocol = mkOption {
description = "Which protocol to listen.";
default = "http";
type = types.enum ["http" "https"];
type = types.enum ["http" "https" "socket"];
};
addr = mkOption {
@ -143,6 +144,15 @@ in {
default = "${cfg.dataDir}/data/grafana.db";
type = types.path;
};
connMaxLifetime = mkOption {
description = ''
Sets the maximum amount of time (in seconds) a connection may be reused.
For MySQL this setting should be shorter than the `wait_timeout' variable.
'';
default = 14400;
type = types.int;
};
};
security = {
@ -241,7 +251,9 @@ in {
description = "Grafana Service Daemon";
wantedBy = ["multi-user.target"];
after = ["networking.target"];
environment = mapAttrs' (n: v: nameValuePair "GF_${n}" (toString v)) envOptions;
environment = {
QT_QPA_PLATFORM = "offscreen";
} // mapAttrs' (n: v: nameValuePair "GF_${n}" (toString v)) envOptions;
serviceConfig = {
ExecStart = "${cfg.package.bin}/bin/grafana-server -homepath ${cfg.dataDir}";
WorkingDirectory = cfg.dataDir;

View File

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

View File

@ -1,128 +0,0 @@
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.services.prometheus.collectdExporter;
collectSettingsArgs = if (cfg.collectdBinary.enable) then ''
-collectd.listen-address ${optionalString (cfg.collectdBinary.listenAddress != null) cfg.collectdBinary.listenAddress}:${toString cfg.collectdBinary.port} \
-collectd.security-level ${cfg.collectdBinary.securityLevel} \
'' else "";
in {
options = {
services.prometheus.collectdExporter = {
enable = mkEnableOption "prometheus collectd exporter";
port = mkOption {
type = types.int;
default = 9103;
description = ''
Port to listen on.
This is used for scraping as well as the to receive collectd data via the write_http plugin.
'';
};
listenAddress = mkOption {
type = types.nullOr types.str;
default = null;
example = "0.0.0.0";
description = ''
Address to listen on for web interface, telemetry and collectd JSON data.
'';
};
collectdBinary = {
enable = mkEnableOption "collectd binary protocol receiver";
authFile = mkOption {
default = null;
type = types.nullOr types.path;
description = "File mapping user names to pre-shared keys (passwords).";
};
port = mkOption {
type = types.int;
default = 25826;
description = ''Network address on which to accept collectd binary network packets.'';
};
listenAddress = mkOption {
type = types.nullOr types.str;
default = null;
example = "0.0.0.0";
description = ''
Address to listen on for binary network packets.
'';
};
securityLevel = mkOption {
type = types.enum ["None" "Sign" "Encrypt"];
default = "None";
description = ''
Minimum required security level for accepted packets.
'';
};
};
extraFlags = mkOption {
type = types.listOf types.str;
default = [];
description = ''
Extra commandline options when launching the collectd exporter.
'';
};
logFormat = mkOption {
type = types.str;
default = "logger:stderr";
example = "logger:syslog?appname=bob&local=7 or logger:stdout?json=true";
description = ''
Set the log target and format.
'';
};
logLevel = mkOption {
type = types.enum ["debug" "info" "warn" "error" "fatal"];
default = "info";
description = ''
Only log messages with the given severity or above.
'';
};
openFirewall = mkOption {
type = types.bool;
default = false;
description = ''
Open port in firewall for incoming connections.
'';
};
};
};
config = mkIf cfg.enable {
networking.firewall.allowedTCPPorts = (optional cfg.openFirewall cfg.port) ++
(optional (cfg.openFirewall && cfg.collectdBinary.enable) cfg.collectdBinary.port);
systemd.services.prometheus-collectd-exporter = {
description = "Prometheus exporter for Collectd metrics";
unitConfig.Documentation = "https://github.com/prometheus/collectd_exporter";
wantedBy = [ "multi-user.target" ];
serviceConfig = {
DynamicUser = true;
Restart = "always";
PrivateTmp = true;
WorkingDirectory = /tmp;
ExecStart = ''
${pkgs.prometheus-collectd-exporter}/bin/collectd_exporter \
-log.format ${cfg.logFormat} \
-log.level ${cfg.logLevel} \
-web.listen-address ${optionalString (cfg.listenAddress != null) cfg.listenAddress}:${toString cfg.port} \
${collectSettingsArgs} \
${concatStringsSep " " cfg.extraFlags}
'';
};
};
};
}

View File

@ -0,0 +1,172 @@
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.services.prometheus.exporters;
# each attribute in `exporterOpts` is expected to have specified:
# - port (types.int): port on which the exporter listens
# - serviceOpts (types.attrs): config that is merged with the
# default definition of the exporter's
# systemd service
# - extraOpts (types.attrs): extra configuration options to
# configure the exporter with, which
# are appended to the default options
#
# Note that `extraOpts` is optional, but a script for the exporter's
# systemd service must be provided by specifying either
# `serviceOpts.script` or `serviceOpts.serviceConfig.ExecStart`
exporterOpts = {
blackbox = import ./exporters/blackbox.nix { inherit config lib pkgs; };
collectd = import ./exporters/collectd.nix { inherit config lib pkgs; };
fritzbox = import ./exporters/fritzbox.nix { inherit config lib pkgs; };
json = import ./exporters/json.nix { inherit config lib pkgs; };
minio = import ./exporters/minio.nix { inherit config lib pkgs; };
nginx = import ./exporters/nginx.nix { inherit config lib pkgs; };
node = import ./exporters/node.nix { inherit config lib pkgs; };
postfix = import ./exporters/postfix.nix { inherit config lib pkgs; };
snmp = import ./exporters/snmp.nix { inherit config lib pkgs; };
unifi = import ./exporters/unifi.nix { inherit config lib pkgs; };
varnish = import ./exporters/varnish.nix { inherit config lib pkgs; };
};
mkExporterOpts = ({ name, port }: {
enable = mkEnableOption "the prometheus ${name} exporter";
port = mkOption {
type = types.int;
default = port;
description = ''
Port to listen on.
'';
};
listenAddress = mkOption {
type = types.str;
default = "0.0.0.0";
description = ''
Address to listen on.
'';
};
extraFlags = mkOption {
type = types.listOf types.str;
default = [];
description = ''
Extra commandline options to pass to the ${name} exporter.
'';
};
openFirewall = mkOption {
type = types.bool;
default = false;
description = ''
Open port in firewall for incoming connections.
'';
};
firewallFilter = mkOption {
type = types.str;
default = "-p tcp -m tcp --dport ${toString port}";
example = literalExample ''
"-i eth0 -p tcp -m tcp --dport ${toString port}"
'';
description = ''
Specify a filter for iptables to use when
<option>services.prometheus.exporters.${name}.openFirewall</option>
is true. It is used as `ip46tables -I INPUT <option>firewallFilter</option> -j ACCEPT`.
'';
};
user = mkOption {
type = types.str;
default = "nobody";
description = ''
User name under which the ${name} exporter shall be run.
Has no effect when <option>systemd.services.prometheus-${name}-exporter.serviceConfig.DynamicUser</option> is true.
'';
};
group = mkOption {
type = types.str;
default = "nobody";
description = ''
Group under which the ${name} exporter shall be run.
Has no effect when <option>systemd.services.prometheus-${name}-exporter.serviceConfig.DynamicUser</option> is true.
'';
};
});
mkSubModule = { name, port, extraOpts, serviceOpts }: {
${name} = mkOption {
type = types.submodule {
options = (mkExporterOpts {
inherit name port;
} // extraOpts);
};
internal = true;
default = {};
};
};
mkSubModules = (foldl' (a: b: a//b) {}
(mapAttrsToList (name: opts: mkSubModule {
inherit name;
inherit (opts) port serviceOpts;
extraOpts = opts.extraOpts or {};
}) exporterOpts)
);
mkExporterConf = { name, conf, serviceOpts }:
mkIf conf.enable {
networking.firewall.extraCommands = mkIf conf.openFirewall ''
ip46tables -I INPUT ${conf.firewallFilter} -j ACCEPT
'';
systemd.services."prometheus-${name}-exporter" = mkMerge ([{
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
serviceConfig = {
Restart = mkDefault "always";
PrivateTmp = mkDefault true;
WorkingDirectory = mkDefault /tmp;
} // mkIf (!(serviceOpts.serviceConfig.DynamicUser or false)) {
User = conf.user;
Group = conf.group;
};
} serviceOpts ]);
};
in
{
options.services.prometheus.exporters = mkOption {
type = types.submodule {
options = (mkSubModules);
};
description = "Prometheus exporter configuration";
default = {};
example = literalExample ''
{
node = {
enable = true;
enabledCollectors = [ "systemd" ];
};
varnish.enable = true;
}
'';
};
config = mkMerge ([{
assertions = [{
assertion = (cfg.snmp.configurationPath == null) != (cfg.snmp.configuration == null);
message = ''
Please ensure you have either `services.prometheus.exporters.snmp.configuration'
or `services.prometheus.exporters.snmp.configurationPath' set!
'';
}];
}] ++ [(mkIf config.services.minio.enable {
services.prometheus.exporters.minio.minioAddress = mkDefault "http://localhost:9000";
services.prometheus.exporters.minio.minioAccessKey = mkDefault config.services.minio.accessKey;
services.prometheus.exporters.minio.minioAccessSecret = mkDefault config.services.minio.secretKey;
})] ++ (mapAttrsToList (name: conf:
mkExporterConf {
inherit name;
inherit (conf) serviceOpts;
conf = cfg.${name};
}) exporterOpts)
);
meta.doc = ./exporters.xml;
}

View File

@ -0,0 +1,135 @@
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
version="5.0"
xml:id="module-services-prometheus-exporters">
<title>Prometheus exporters</title>
<para>Prometheus exporters provide metrics for the <link xlink:href="https://prometheus.io">prometheus monitoring system</link>.</para>
<section><title>Configuration</title>
<para>One of the most common exporters is the <link xlink:href="https://github.com/prometheus/node_exporter">node exporter</link>, it provides hardware and OS metrics from the host it's running on. The exporter could be configured as follows:
<programlisting>
services.promtheus.exporters.node = {
enable = true;
enabledCollectors = [
"logind"
"systemd"
];
disabledCollectors = [
"textfile"
];
openFirewall = true;
firewallFilter = "-i br0 -p tcp -m tcp --dport 9100";
};
</programlisting>
It should now serve all metrics from the collectors
that are explicitly enabled and the ones that are
<link xlink:href="https://github.com/prometheus/node_exporter#enabled-by-default">enabled by default</link>, via http under <literal>/metrics</literal>. In this example the firewall should just
allow incoming connections to the exporter's port on the bridge interface <literal>br0</literal>
(this would have to be configured seperately of course).
For more information about configuration see <literal>man configuration.nix</literal> or
search through the <link xlink:href="https://nixos.org/nixos/options.html#prometheus.exporters">available options</link>.
</para>
</section>
<section><title>Adding a new exporter</title>
<para>To add a new exporter, it has to be packaged first (see <literal>nixpkgs/pkgs/servers/monitoring/prometheus/</literal> for examples), then a module can be added. The postfix exporter is used in this example:</para>
<itemizedlist>
<listitem>
<para>
Some default options for all exporters are provided by
<literal>nixpkgs/nixos/modules/services/monitoring/prometheus/exporters.nix</literal>:
</para>
</listitem>
<listitem override='none'>
<itemizedlist>
<listitem><para><literal>enable</literal></para></listitem>
<listitem><para><literal>port</literal></para></listitem>
<listitem><para><literal>listenAddress</literal></para></listitem>
<listitem><para><literal>extraFlags</literal></para></listitem>
<listitem><para><literal>openFirewall</literal></para></listitem>
<listitem><para><literal>firewallFilter</literal></para></listitem>
<listitem><para><literal>user</literal></para></listitem>
<listitem><para><literal>group</literal></para></listitem>
</itemizedlist>
</listitem>
<listitem>
<para>As there is already a package available, the module can now be added.
This is accomplished by adding a new file to the
<literal>nixos/modules/services/monitoring/prometheus/exporters/</literal> directory,
which will be called postfix.nix and contains all exporter specific options
and configuration:
<programlisting>
# nixpgs/nixos/modules/services/prometheus/exporters/postfix.nix
{ config, lib, pkgs }:
with lib;
let
# for convenience we define cfg here
cfg = config.services.prometheus.exporters.postfix;
in
{
port = 9154; # The postfix exporter listens on this port by default
# `extraOpts` is an attribute set which contains additional options
# (and optional overrides for default options).
# Note that this attribute is optional.
extraOpts = {
telemetryPath = mkOption {
type = types.str;
default = "/metrics";
description = ''
Path under which to expose metrics.
'';
};
logfilePath = mkOption {
type = types.path;
default = /var/log/postfix_exporter_input.log;
example = /var/log/mail.log;
description = ''
Path where Postfix writes log entries.
This file will be truncated by this exporter!
'';
};
showqPath = mkOption {
type = types.path;
default = /var/spool/postfix/public/showq;
example = /var/lib/postfix/queue/public/showq;
description = ''
Path at which Postfix places its showq socket.
'';
};
};
# `serviceOpts` is an attribute set which contains configuration
# for the exporter's systemd service. One of
# `serviceOpts.script` and `serviceOpts.serviceConfig.ExecStart`
# has to be specified here. This will be merged with the default
# service confiuration.
serviceOpts = {
serviceConfig = {
ExecStart = ''
${pkgs.prometheus-postfix-exporter}/bin/postfix_exporter \
--web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
--web.telemetry-path ${cfg.telemetryPath} \
${concatStringsSep " \\\n " cfg.extraFlags}
'';
};
};
}
</programlisting>
</para>
</listitem>
<listitem>
<para>
This should already be enough for the postfix exporter. Additionally one could
now add assertions and conditional default values. This can be done in the
'meta-module' that combines all exporter definitions and generates the submodules:
<literal>nixpkgs/nixos/modules/services/prometheus/exporters.nix</literal>
</para>
</listitem>
</itemizedlist>
</section>
</chapter>

View File

@ -0,0 +1,31 @@
{ config, lib, pkgs }:
with lib;
let
cfg = config.services.prometheus.exporters.blackbox;
in
{
port = 9115;
extraOpts = {
configFile = mkOption {
type = types.path;
description = ''
Path to configuration file.
'';
};
};
serviceOpts = {
serviceConfig = {
AmbientCapabilities = [ "CAP_NET_RAW" ]; # for ping probes
DynamicUser = true;
ExecStart = ''
${pkgs.prometheus-blackbox-exporter}/bin/blackbox_exporter \
--web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
--config.file ${cfg.configFile} \
${concatStringsSep " \\\n " cfg.extraFlags}
'';
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
};
};
}

View File

@ -0,0 +1,78 @@
{ config, lib, pkgs }:
with lib;
let
cfg = config.services.prometheus.exporters.collectd;
in
{
port = 9103;
extraOpts = {
collectdBinary = {
enable = mkEnableOption "collectd binary protocol receiver";
authFile = mkOption {
default = null;
type = types.nullOr types.path;
description = "File mapping user names to pre-shared keys (passwords).";
};
port = mkOption {
type = types.int;
default = 25826;
description = ''Network address on which to accept collectd binary network packets.'';
};
listenAddress = mkOption {
type = types.str;
default = "0.0.0.0";
description = ''
Address to listen on for binary network packets.
'';
};
securityLevel = mkOption {
type = types.enum ["None" "Sign" "Encrypt"];
default = "None";
description = ''
Minimum required security level for accepted packets.
'';
};
};
logFormat = mkOption {
type = types.str;
default = "logger:stderr";
example = "logger:syslog?appname=bob&local=7 or logger:stdout?json=true";
description = ''
Set the log target and format.
'';
};
logLevel = mkOption {
type = types.enum ["debug" "info" "warn" "error" "fatal"];
default = "info";
description = ''
Only log messages with the given severity or above.
'';
};
};
serviceOpts = let
collectSettingsArgs = if (cfg.collectdBinary.enable) then ''
-collectd.listen-address ${cfg.collectdBinary.listenAddress}:${toString cfg.collectdBinary.port} \
-collectd.security-level ${cfg.collectdBinary.securityLevel} \
'' else "";
in {
serviceConfig = {
DynamicUser = true;
ExecStart = ''
${pkgs.prometheus-collectd-exporter}/bin/collectd_exporter \
-log.format ${cfg.logFormat} \
-log.level ${cfg.logLevel} \
-web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
${collectSettingsArgs} \
${concatStringsSep " \\\n " cfg.extraFlags}
'';
};
};
}

View File

@ -0,0 +1,39 @@
{ config, lib, pkgs }:
with lib;
let
cfg = config.services.prometheus.exporters.fritzbox;
in
{
port = 9133;
extraOpts = {
gatewayAddress = mkOption {
type = types.str;
default = "fritz.box";
description = ''
The hostname or IP of the FRITZ!Box.
'';
};
gatewayPort = mkOption {
type = types.int;
default = 49000;
description = ''
The port of the FRITZ!Box UPnP service.
'';
};
};
serviceOpts = {
serviceConfig = {
DynamicUser = true;
ExecStart = ''
${pkgs.prometheus-fritzbox-exporter}/bin/fritzbox_exporter \
-listen-address ${cfg.listenAddress}:${toString cfg.port} \
-gateway-address ${cfg.gatewayAddress} \
-gateway-port ${toString cfg.gatewayPort} \
${concatStringsSep " \\\n " cfg.extraFlags}
'';
};
};
}

View File

@ -0,0 +1,36 @@
{ config, lib, pkgs }:
with lib;
let
cfg = config.services.prometheus.exporters.json;
in
{
port = 7979;
extraOpts = {
url = mkOption {
type = types.str;
description = ''
URL to scrape JSON from.
'';
};
configFile = mkOption {
type = types.path;
description = ''
Path to configuration file.
'';
};
listenAddress = {}; # not used
};
serviceOpts = {
serviceConfig = {
DynamicUser = true;
ExecStart = ''
${pkgs.prometheus-json-exporter}/bin/prometheus-json-exporter \
--port ${toString cfg.port} \
${cfg.url} ${cfg.configFile} \
${concatStringsSep " \\\n " cfg.extraFlags}
'';
};
};
}

View File

@ -0,0 +1,65 @@
{ config, lib, pkgs }:
with lib;
let
cfg = config.services.prometheus.exporters.minio;
in
{
port = 9290;
extraOpts = {
minioAddress = mkOption {
type = types.str;
example = "https://10.0.0.1:9000";
description = ''
The URL of the minio server.
Use HTTPS if Minio accepts secure connections only.
By default this connects to the local minio server if enabled.
'';
};
minioAccessKey = mkOption {
type = types.str;
example = "yourMinioAccessKey";
description = ''
The value of the Minio access key.
It is required in order to connect to the server.
By default this uses the one from the local minio server if enabled
and <literal>config.services.minio.accessKey</literal>.
'';
};
minioAccessSecret = mkOption {
type = types.str;
description = ''
The value of the Minio access secret.
It is required in order to connect to the server.
By default this uses the one from the local minio server if enabled
and <literal>config.services.minio.secretKey</literal>.
'';
};
minioBucketStats = mkOption {
type = types.bool;
default = false;
description = ''
Collect statistics about the buckets and files in buckets.
It requires more computation, use it carefully in case of large buckets..
'';
};
};
serviceOpts = {
serviceConfig = {
DynamicUser = true;
ExecStart = ''
${pkgs.prometheus-minio-exporter}/bin/minio-exporter \
-web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
-minio.server ${cfg.minioAddress} \
-minio.access-key ${cfg.minioAccessKey} \
-minio.access-secret ${cfg.minioAccessSecret} \
${optionalString cfg.minioBucketStats "-minio.bucket-stats"} \
${concatStringsSep " \\\n " cfg.extraFlags}
'';
};
};
}

View File

@ -0,0 +1,31 @@
{ config, lib, pkgs }:
with lib;
let
cfg = config.services.prometheus.exporters.nginx;
in
{
port = 9113;
extraOpts = {
scrapeUri = mkOption {
type = types.string;
default = "http://localhost/nginx_status";
description = ''
Address to access the nginx status page.
Can be enabled with services.nginx.statusPage = true.
'';
};
};
serviceOpts = {
serviceConfig = {
DynamicUser = true;
ExecStart = ''
${pkgs.prometheus-nginx-exporter}/bin/nginx_exporter \
-nginx.scrape_uri '${cfg.scrapeUri}' \
-telemetry.address ${cfg.listenAddress}:${toString cfg.port} \
${concatStringsSep " \\\n " cfg.extraFlags}
'';
};
};
}

View File

@ -0,0 +1,39 @@
{ config, lib, pkgs }:
with lib;
let
cfg = config.services.prometheus.exporters.node;
in
{
port = 9100;
extraOpts = {
enabledCollectors = mkOption {
type = types.listOf types.string;
default = [];
example = ''[ "systemd" ]'';
description = ''
Collectors to enable. The collectors listed here are enabled in addition to the default ones.
'';
};
disabledCollectors = mkOption {
type = types.listOf types.str;
default = [];
example = ''[ "timex" ]'';
description = ''
Collectors to disable which are enabled by default.
'';
};
};
serviceOpts = {
serviceConfig = {
ExecStart = ''
${pkgs.prometheus-node-exporter}/bin/node_exporter \
${concatMapStringsSep " " (x: "--collector." + x) cfg.enabledCollectors} \
${concatMapStringsSep " " (x: "--no-collector." + x) cfg.disabledCollectors} \
--web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
${concatStringsSep " \\\n " cfg.extraFlags}
'';
};
};
}

View File

@ -0,0 +1,46 @@
{ config, lib, pkgs }:
with lib;
let
cfg = config.services.prometheus.exporters.postfix;
in
{
port = 9154;
extraOpts = {
telemetryPath = mkOption {
type = types.str;
default = "/metrics";
description = ''
Path under which to expose metrics.
'';
};
logfilePath = mkOption {
type = types.path;
default = "/var/log/postfix_exporter_input.log";
example = "/var/log/mail.log";
description = ''
Path where Postfix writes log entries.
This file will be truncated by this exporter!
'';
};
showqPath = mkOption {
type = types.path;
default = "/var/spool/postfix/public/showq";
example = "/var/lib/postfix/queue/public/showq";
description = ''
Path where Postfix places it's showq socket.
'';
};
};
serviceOpts = {
serviceConfig = {
ExecStart = ''
${pkgs.prometheus-postfix-exporter}/bin/postfix_exporter \
--web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
--web.telemetry-path ${cfg.telemetryPath} \
${concatStringsSep " \\\n " cfg.extraFlags}
'';
};
};
}

View File

@ -0,0 +1,71 @@
{ config, lib, pkgs }:
with lib;
let
cfg = config.services.prometheus.exporters.snmp;
in
{
port = 9116;
extraOpts = {
configurationPath = mkOption {
type = types.nullOr types.path;
default = null;
description = ''
Path to a snmp exporter configuration file. Mutually exclusive with 'configuration' option.
'';
example = "./snmp.yml";
};
configuration = mkOption {
type = types.nullOr types.attrs;
default = {};
description = ''
Snmp exporter configuration as nix attribute set. Mutually exclusive with 'configurationPath' option.
'';
example = ''
{
"default" = {
"version" = 2;
"auth" = {
"community" = "public";
};
};
};
'';
};
logFormat = mkOption {
type = types.str;
default = "logger:stderr";
description = ''
Set the log target and format.
'';
};
logLevel = mkOption {
type = types.enum ["debug" "info" "warn" "error" "fatal"];
default = "info";
description = ''
Only log messages with the given severity or above.
'';
};
};
serviceOpts = let
configFile = if cfg.configurationPath != null
then cfg.configurationPath
else "${pkgs.writeText "snmp-eporter-conf.yml" (builtins.toJSON cfg.configuration)}";
in {
serviceConfig = {
DynamicUser = true;
ExecStart = ''
${pkgs.prometheus-snmp-exporter.bin}/bin/snmp_exporter \
-config.file ${configFile} \
-log.format ${cfg.logFormat} \
-log.level ${cfg.logLevel} \
-web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
${concatStringsSep " \\\n " cfg.extraFlags}
'';
};
};
}

View File

@ -0,0 +1,67 @@
{ config, lib, pkgs }:
with lib;
let
cfg = config.services.prometheus.exporters.unifi;
in
{
port = 9130;
extraOpts = {
unifiAddress = mkOption {
type = types.str;
example = "https://10.0.0.1:8443";
description = ''
URL of the UniFi Controller API.
'';
};
unifiInsecure = mkOption {
type = types.bool;
default = false;
description = ''
If enabled skip the verification of the TLS certificate of the UniFi Controller API.
Use with caution.
'';
};
unifiUsername = mkOption {
type = types.str;
example = "ReadOnlyUser";
description = ''
username for authentication against UniFi Controller API.
'';
};
unifiPassword = mkOption {
type = types.str;
description = ''
Password for authentication against UniFi Controller API.
'';
};
unifiTimeout = mkOption {
type = types.str;
default = "5s";
example = "2m";
description = ''
Timeout including unit for UniFi Controller API requests.
'';
};
};
serviceOpts = {
serviceConfig = {
DynamicUser = true;
ExecStart = ''
${pkgs.prometheus-unifi-exporter}/bin/unifi_exporter \
-telemetry.addr ${cfg.listenAddress}:${toString cfg.port} \
-unifi.addr ${cfg.unifiAddress} \
-unifi.username ${cfg.unifiUsername} \
-unifi.password ${cfg.unifiPassword} \
-unifi.timeout ${cfg.unifiTimeout} \
${optionalString cfg.unifiInsecure "-unifi.insecure" } \
${concatStringsSep " \\\n " cfg.extraFlags}
'';
};
};
}

View File

@ -0,0 +1,21 @@
{ config, lib, pkgs }:
with lib;
let
cfg = config.services.prometheus.exporters.varnish;
in
{
port = 9131;
serviceOpts = {
path = [ pkgs.varnish ];
serviceConfig = {
DynamicUser = true;
ExecStart = ''
${pkgs.prometheus-varnish-exporter}/bin/prometheus_varnish_exporter \
-web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
${concatStringsSep " \\\n " cfg.extraFlags}
'';
};
};
}

View File

@ -1,76 +0,0 @@
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.services.prometheus.fritzboxExporter;
in {
options = {
services.prometheus.fritzboxExporter = {
enable = mkEnableOption "prometheus fritzbox exporter";
port = mkOption {
type = types.int;
default = 9133;
description = ''
Port to listen on.
'';
};
gatewayAddress = mkOption {
type = types.str;
default = "fritz.box";
description = ''
The hostname or IP of the FRITZ!Box.
'';
};
gatewayPort = mkOption {
type = types.int;
default = 49000;
description = ''
The port of the FRITZ!Box UPnP service.
'';
};
extraFlags = mkOption {
type = types.listOf types.str;
default = [];
description = ''
Extra commandline options when launching the fritzbox exporter.
'';
};
openFirewall = mkOption {
type = types.bool;
default = false;
description = ''
Open port in firewall for incoming connections.
'';
};
};
};
config = mkIf cfg.enable {
networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.port;
systemd.services.prometheus-fritzbox-exporter = {
description = "Prometheus exporter for FRITZ!Box via UPnP";
unitConfig.Documentation = "https://github.com/ndecker/fritzbox_exporter";
wantedBy = [ "multi-user.target" ];
serviceConfig = {
User = "nobody";
Restart = "always";
PrivateTmp = true;
WorkingDirectory = /tmp;
ExecStart = ''
${pkgs.prometheus-fritzbox-exporter}/bin/fritzbox_exporter \
-listen-address :${toString cfg.port} \
-gateway-address ${cfg.gatewayAddress} \
-gateway-port ${toString cfg.gatewayPort} \
${concatStringsSep " \\\n " cfg.extraFlags}
'';
};
};
};
}

View File

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

View File

@ -1,117 +0,0 @@
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.services.prometheus.minioExporter;
in {
options = {
services.prometheus.minioExporter = {
enable = mkEnableOption "prometheus minio exporter";
port = mkOption {
type = types.int;
default = 9290;
description = ''
Port to listen on.
'';
};
listenAddress = mkOption {
type = types.nullOr types.str;
default = null;
example = "0.0.0.0";
description = ''
Address to listen on for web interface and telemetry.
'';
};
minioAddress = mkOption {
type = types.str;
example = "https://10.0.0.1:9000";
default = if config.services.minio.enable then "http://localhost:9000" else null;
description = ''
The URL of the minio server.
Use HTTPS if Minio accepts secure connections only.
By default this connects to the local minio server if enabled.
'';
};
minioAccessKey = mkOption ({
type = types.str;
example = "BKIKJAA5BMMU2RHO6IBB";
description = ''
The value of the Minio access key.
It is required in order to connect to the server.
By default this uses the one from the local minio server if enabled
and <literal>config.services.minio.accessKey</literal>.
'';
} // optionalAttrs (config.services.minio.enable && config.services.minio.accessKey != "") {
default = config.services.minio.accessKey;
});
minioAccessSecret = mkOption ({
type = types.str;
description = ''
The calue of the Minio access secret.
It is required in order to connect to the server.
By default this uses the one from the local minio server if enabled
and <literal>config.services.minio.secretKey</literal>.
'';
} // optionalAttrs (config.services.minio.enable && config.services.minio.secretKey != "") {
default = config.services.minio.secretKey;
});
minioBucketStats = mkOption {
type = types.bool;
default = false;
description = ''
Collect statistics about the buckets and files in buckets.
It requires more computation, use it carefully in case of large buckets..
'';
};
extraFlags = mkOption {
type = types.listOf types.str;
default = [];
description = ''
Extra commandline options when launching the minio exporter.
'';
};
openFirewall = mkOption {
type = types.bool;
default = false;
description = ''
Open port in firewall for incoming connections.
'';
};
};
};
config = mkIf cfg.enable {
networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.port;
systemd.services.prometheus-minio-exporter = {
description = "Prometheus exporter for Minio server metrics";
unitConfig.Documentation = "https://github.com/joe-pll/minio-exporter";
wantedBy = [ "multi-user.target" ];
after = optional config.services.minio.enable "minio.service";
serviceConfig = {
DynamicUser = true;
Restart = "always";
PrivateTmp = true;
WorkingDirectory = /tmp;
ExecStart = ''
${pkgs.prometheus-minio-exporter}/bin/minio-exporter \
-web.listen-address ${optionalString (cfg.listenAddress != null) cfg.listenAddress}:${toString cfg.port} \
-minio.server ${cfg.minioAddress} \
-minio.access-key ${cfg.minioAccessKey} \
-minio.access-secret ${cfg.minioAccessSecret} \
${optionalString cfg.minioBucketStats "-minio.bucket-stats"} \
${concatStringsSep " \\\n " cfg.extraFlags}
'';
};
};
};
}

View File

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

View File

@ -1,87 +0,0 @@
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.services.prometheus.nodeExporter;
in {
options = {
services.prometheus.nodeExporter = {
enable = mkEnableOption "prometheus node exporter";
port = mkOption {
type = types.int;
default = 9100;
description = ''
Port to listen on.
'';
};
listenAddress = mkOption {
type = types.string;
default = "0.0.0.0";
description = ''
Address to listen on.
'';
};
enabledCollectors = mkOption {
type = types.listOf types.string;
default = [];
example = ''[ "systemd" ]'';
description = ''
Collectors to enable. The collectors listed here are enabled in addition to the default ones.
'';
};
disabledCollectors = mkOption {
type = types.listOf types.str;
default = [];
example = ''[ "timex" ]'';
description = ''
Collectors to disable which are enabled by default.
'';
};
extraFlags = mkOption {
type = types.listOf types.str;
default = [];
description = ''
Extra commandline options when launching the node exporter.
'';
};
openFirewall = mkOption {
type = types.bool;
default = false;
description = ''
Open port in firewall for incoming connections.
'';
};
};
};
config = mkIf cfg.enable {
networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.port;
systemd.services.prometheus-node-exporter = {
description = "Prometheus exporter for machine metrics";
unitConfig.Documentation = "https://github.com/prometheus/node_exporter";
wantedBy = [ "multi-user.target" ];
script = ''
exec ${pkgs.prometheus-node-exporter}/bin/node_exporter \
${concatMapStringsSep " " (x: "--collector." + x) cfg.enabledCollectors} \
${concatMapStringsSep " " (x: "--no-collector." + x) cfg.disabledCollectors} \
--web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
${concatStringsSep " \\\n " cfg.extraFlags}
'';
serviceConfig = {
User = "nobody";
Restart = "always";
PrivateTmp = true;
WorkingDirectory = /tmp;
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
};
};
};
}

View File

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

View File

@ -1,105 +0,0 @@
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.services.prometheus.unifiExporter;
in {
options = {
services.prometheus.unifiExporter = {
enable = mkEnableOption "prometheus unifi exporter";
port = mkOption {
type = types.int;
default = 9130;
description = ''
Port to listen on.
'';
};
unifiAddress = mkOption {
type = types.str;
example = "https://10.0.0.1:8443";
description = ''
URL of the UniFi Controller API.
'';
};
unifiInsecure = mkOption {
type = types.bool;
default = false;
description = ''
If enabled skip the verification of the TLS certificate of the UniFi Controller API.
Use with caution.
'';
};
unifiUsername = mkOption {
type = types.str;
example = "ReadOnlyUser";
description = ''
username for authentication against UniFi Controller API.
'';
};
unifiPassword = mkOption {
type = types.str;
description = ''
Password for authentication against UniFi Controller API.
'';
};
unifiTimeout = mkOption {
type = types.str;
default = "5s";
example = "2m";
description = ''
Timeout including unit for UniFi Controller API requests.
'';
};
extraFlags = mkOption {
type = types.listOf types.str;
default = [];
description = ''
Extra commandline options when launching the unifi exporter.
'';
};
openFirewall = mkOption {
type = types.bool;
default = false;
description = ''
Open port in firewall for incoming connections.
'';
};
};
};
config = mkIf cfg.enable {
networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.port;
systemd.services.prometheus-unifi-exporter = {
description = "Prometheus exporter for UniFi Controller metrics";
unitConfig.Documentation = "https://github.com/mdlayher/unifi_exporter";
wantedBy = [ "multi-user.target" ];
after = optional config.services.unifi.enable "unifi.service";
serviceConfig = {
User = "nobody";
Restart = "always";
PrivateTmp = true;
WorkingDirectory = /tmp;
ExecStart = ''
${pkgs.prometheus-unifi-exporter}/bin/unifi_exporter \
-telemetry.addr :${toString cfg.port} \
-unifi.addr ${cfg.unifiAddress} \
-unifi.username ${cfg.unifiUsername} \
-unifi.password ${cfg.unifiPassword} \
-unifi.timeout ${cfg.unifiTimeout} \
${optionalString cfg.unifiInsecure "-unifi.insecure" } \
${concatStringsSep " \\\n " cfg.extraFlags}
'';
};
};
};
}

View File

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

View File

@ -36,6 +36,7 @@ let
preStart = ''
mkdir -m 755 -p ${cfg.stateDir}
chown dhcpd:nogroup ${cfg.stateDir}
touch ${cfg.stateDir}/dhcpd.leases
'';

View File

@ -14,7 +14,7 @@ let
${concatStrings (mapAttrsToList (host: ips: ''
${concatMapStrings (ip: ''
echo ${lib.escapeShellArg ip} > "$out/servers/"${lib.escapeShellArg host}
echo ${lib.escapeShellArg ip} >> "$out/servers/"${lib.escapeShellArg host}
'') ips}
'') cfg.domainServers)}

View File

@ -135,8 +135,7 @@ in {
default = { inherit networkmanager modemmanager wpa_supplicant
networkmanager-openvpn networkmanager-vpnc
networkmanager-openconnect networkmanager-fortisslvpn
networkmanager-pptp networkmanager-l2tp
networkmanager-iodine; };
networkmanager-l2tp networkmanager-iodine; };
internal = true;
};
@ -267,8 +266,6 @@ in {
message = "You can not use networking.networkmanager with networking.wireless";
}];
boot.kernelModules = [ "ppp_mppe" ]; # Needed for most (all?) PPTP VPN connections.
environment.etc = with cfg.basePackages; [
{ source = configFile;
target = "NetworkManager/NetworkManager.conf";
@ -285,9 +282,6 @@ in {
{ source = "${networkmanager-fortisslvpn}/etc/NetworkManager/VPN/nm-fortisslvpn-service.name";
target = "NetworkManager/VPN/nm-fortisslvpn-service.name";
}
{ source = "${networkmanager-pptp}/etc/NetworkManager/VPN/nm-pptp-service.name";
target = "NetworkManager/VPN/nm-pptp-service.name";
}
{ source = "${networkmanager-l2tp}/etc/NetworkManager/VPN/nm-l2tp-service.name";
target = "NetworkManager/VPN/nm-l2tp-service.name";
}

View File

@ -55,6 +55,8 @@ in
environment.NIX_SECRET_KEY_FILE = cfg.secretKeyFile;
serviceConfig = {
Restart = "always";
RestartSec = "5s";
ExecStart = "${pkgs.nix-serve}/bin/nix-serve " +
"--listen ${cfg.bindAddress}:${toString cfg.port} ${cfg.extraParams}";
User = "nix-serve";

View File

@ -15,6 +15,7 @@ let
description = "Path to the key file.";
};
# TODO: rename to certificate to match the prosody config
cert = mkOption {
type = types.path;
description = "Path to the certificate file.";
@ -30,7 +31,7 @@ let
};
moduleOpts = {
# Generally required
roster = mkOption {
type = types.bool;
default = true;
@ -61,12 +62,38 @@ let
description = "Service discovery";
};
legacyauth = mkOption {
# Not essential, but recommended
carbons = mkOption {
type = types.bool;
default = true;
description = "Legacy authentication. Only used by some old clients and bots";
description = "Keep multiple clients in sync";
};
pep = mkOption {
type = types.bool;
default = true;
description = "Enables users to publish their mood, activity, playing music and more";
};
private = mkOption {
type = types.bool;
default = true;
description = "Private XML storage (for room bookmarks, etc.)";
};
blocklist = mkOption {
type = types.bool;
default = true;
description = "Allow users to block communications with other users";
};
vcard = mkOption {
type = types.bool;
default = true;
description = "Allow users to set vCards";
};
# Nice to have
version = mkOption {
type = types.bool;
default = true;
@ -91,36 +118,112 @@ let
description = "Replies to XMPP pings with pongs";
};
console = mkOption {
register = mkOption {
type = types.bool;
default = false;
description = "telnet to port 5582";
default = true;
description = "Allow users to register on this server using a client and change passwords";
};
mam = mkOption {
type = types.bool;
default = false;
description = "Store messages in an archive and allow users to access it";
};
# Admin interfaces
admin_adhoc = mkOption {
type = types.bool;
default = true;
description = "Allows administration via an XMPP client that supports ad-hoc commands";
};
admin_telnet = mkOption {
type = types.bool;
default = false;
description = "Opens telnet console interface on localhost port 5582";
};
# HTTP modules
bosh = mkOption {
type = types.bool;
default = false;
description = "Enable BOSH clients, aka 'Jabber over HTTP'";
};
httpserver = mkOption {
type = types.bool;
default = false;
description = "Serve static files from a directory over HTTP";
};
websocket = mkOption {
type = types.bool;
default = false;
description = "Enable WebSocket support";
};
http_files = mkOption {
type = types.bool;
default = false;
description = "Serve static files from a directory over HTTP";
};
# Other specific functionality
limits = mkOption {
type = types.bool;
default = false;
description = "Enable bandwidth limiting for XMPP connections";
};
groups = mkOption {
type = types.bool;
default = false;
description = "Shared roster support";
};
server_contact_info = mkOption {
type = types.bool;
default = false;
description = "Publish contact information for this service";
};
announce = mkOption {
type = types.bool;
default = false;
description = "Send announcement to all online users";
};
welcome = mkOption {
type = types.bool;
default = false;
description = "Welcome users who register accounts";
};
watchregistrations = mkOption {
type = types.bool;
default = false;
description = "Alert admins of registrations";
};
motd = mkOption {
type = types.bool;
default = false;
description = "Send a message to users when they log in";
};
legacyauth = mkOption {
type = types.bool;
default = false;
description = "Legacy authentication. Only used by some old clients and bots";
};
proxy65 = mkOption {
type = types.bool;
default = false;
description = "Enables a file transfer proxy service which clients behind NAT can use";
};
};
toLua = x:
if builtins.isString x then ''"${x}"''
else if builtins.isBool x then toString x
else if builtins.isBool x then (if x == true then "true" else "false")
else if builtins.isInt x then toString x
else if builtins.isList x then ''{ ${lib.concatStringsSep ", " (map (n: toLua n) x) } }''
else throw "Invalid Lua value";
createSSLOptsStr = o: ''
@ -198,6 +301,59 @@ in
description = "Allow account creation";
};
c2sRequireEncryption = mkOption {
type = types.bool;
default = true;
description = ''
Force clients to use encrypted connections? This option will
prevent clients from authenticating unless they are using encryption.
'';
};
s2sRequireEncryption = mkOption {
type = types.bool;
default = true;
description = ''
Force servers to use encrypted connections? This option will
prevent servers from authenticating unless they are using encryption.
Note that this is different from authentication.
'';
};
s2sSecureAuth = mkOption {
type = types.bool;
default = false;
description = ''
Force certificate authentication for server-to-server connections?
This provides ideal security, but requires servers you communicate
with to support encryption AND present valid, trusted certificates.
For more information see https://prosody.im/doc/s2s#security
'';
};
s2sInsecureDomains = mkOption {
type = types.listOf types.str;
default = [];
example = [ "insecure.example.com" ];
description = ''
Some servers have invalid or self-signed certificates. You can list
remote domains here that will not be required to authenticate using
certificates. They will be authenticated using DNS instead, even
when s2s_secure_auth is enabled.
'';
};
s2sSecureDomains = mkOption {
type = types.listOf types.str;
default = [];
example = [ "jabber.org" ];
description = ''
Even if you leave s2s_secure_auth disabled, you can still require valid
certificates for some domains by specifying a list here.
'';
};
modules = moduleOpts;
extraModules = mkOption {
@ -206,6 +362,12 @@ in
description = "Enable custom modules";
};
extraPluginPaths = mkOption {
type = types.listOf types.path;
default = [];
description = "Addtional path in which to look find plugins/modules";
};
virtualHosts = mkOption {
description = "Define the virtual hosts";
@ -255,38 +417,48 @@ in
config = mkIf cfg.enable {
environment.systemPackages = [ pkgs.prosody ];
environment.systemPackages = [ cfg.package ];
environment.etc."prosody/prosody.cfg.lua".text = ''
pidfile = "/var/lib/prosody/prosody.pid"
log = "*syslog"
data_path = "/var/lib/prosody"
allow_registration = ${boolToString cfg.allowRegistration};
${ optionalString cfg.modules.console "console_enabled = true;" }
plugin_paths = {
${lib.concatStringsSep ", " (map (n: "\"${n}\"") cfg.extraPluginPaths) }
}
${ optionalString (cfg.ssl != null) (createSSLOptsStr cfg.ssl) }
admins = { ${lib.concatStringsSep ", " (map (n: "\"${n}\"") cfg.admins) } };
admins = ${toLua cfg.admins}
-- we already build with libevent, so we can just enable it for a more performant server
use_libevent = true
modules_enabled = {
${ lib.concatStringsSep "\n\ \ " (lib.mapAttrsToList
(name: val: optionalString val ''"${name}";'')
(name: val: optionalString val "${toLua name};")
cfg.modules) }
${ optionalString cfg.allowRegistration "\"register\"\;" }
${ lib.concatStringsSep "\n" (map (x: "\"${x}\";") cfg.extraModules)}
"posix";
${ lib.concatStringsSep "\n" (map (x: "${toLua x};") cfg.package.communityModules)}
${ lib.concatStringsSep "\n" (map (x: "${toLua x};") cfg.extraModules)}
};
allow_registration = ${toLua cfg.allowRegistration}
c2s_require_encryption = ${toLua cfg.c2sRequireEncryption}
s2s_require_encryption = ${toLua cfg.s2sRequireEncryption}
s2s_secure_auth = ${toLua cfg.s2sSecureAuth}
s2s_insecure_domains = ${toLua cfg.s2sInsecureDomains}
s2s_secure_domains = ${toLua cfg.s2sSecureDomains}
${ cfg.extraConfig }
${ lib.concatStringsSep "\n" (lib.mapAttrsToList (n: v: ''

View File

@ -50,12 +50,7 @@ in
description = ''
If enabled, start the Resilio Sync daemon. Once enabled, you can
interact with the service through the Web UI, or configure it in your
NixOS configuration. Enabling the <literal>resilio</literal> service
also installs a systemd user unit which can be used to start
user-specific copies of the daemon. Once installed, you can use
<literal>systemctl --user start resilio</literal> as your user to start
the daemon using the configuration file located at
<literal>$HOME/.config/resilio-sync/config.json</literal>.
NixOS configuration.
'';
};

View File

@ -112,7 +112,7 @@ in
mkdir -m 0755 -p ${stateDir}/dev/
cp ${confFile} ${stateDir}/unbound.conf
${optionalString cfg.enableRootTrustAnchor ''
${pkgs.unbound}/bin/unbound-anchor -a ${rootTrustAnchorFile}
${pkgs.unbound}/bin/unbound-anchor -a ${rootTrustAnchorFile} || echo "Root anchor updated!"
chown unbound ${stateDir} ${rootTrustAnchorFile}
''}
touch ${stateDir}/dev/random

View File

@ -124,7 +124,7 @@ in
listenAddresses = mkOption {
type = types.listOf types.str;
default = [ "127.0.0.1:631" ];
default = [ "localhost:631" ];
example = [ "*:631" ];
description = ''
A list of addresses and ports on which to listen.
@ -321,7 +321,10 @@ in
''}
'';
serviceConfig.PrivateTmp = true;
serviceConfig = {
PrivateTmp = true;
RuntimeDirectory = [ "cups" ];
};
};
systemd.services.cups-browsed = mkIf avahiEnabled

View File

@ -32,8 +32,11 @@ let
(if es5 then (pkgs.writeTextDir "log4j2.properties" cfg.logging)
else (pkgs.writeTextDir "logging.yml" cfg.logging))
];
# Elasticsearch 5.x won't start when the scripts directory does not exist
postBuild = if es5 then "${pkgs.coreutils}/bin/mkdir -p $out/scripts" else "";
postBuild = concatStringsSep "\n" (concatLists [
# Elasticsearch 5.x won't start when the scripts directory does not exist
(optional es5 "${pkgs.coreutils}/bin/mkdir -p $out/scripts")
(optional es6 "ln -s ${cfg.package}/config/jvm.options $out/jvm.options")
]);
};
esPlugins = pkgs.buildEnv {

View File

@ -59,8 +59,8 @@ in
time the service starts). String values must be quoted, integer and
boolean values must not.
See https://trac.transmissionbt.com/wiki/EditConfigFiles for
documentation.
See https://github.com/transmission/transmission/wiki/Editing-Configuration-Files
for documentation.
'';
};

View File

@ -118,7 +118,7 @@ with lib;
default = [];
example = [
{ urlPath = "/foo/bar.png";
files = "/home/eelco/some-file.png";
file = "/home/eelco/some-file.png";
}
];
description = ''

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