Merge remote-tracking branch 'upstream/master' into parnell/fetchdocker
This commit is contained in:
commit
e4ec980e9c
23
.github/CODEOWNERS
vendored
23
.github/CODEOWNERS
vendored
@ -10,18 +10,19 @@
|
||||
# This file
|
||||
/.github/CODEOWNERS @edolstra
|
||||
|
||||
# Boostraping and core infra
|
||||
/pkgs/stdenv @edolstra
|
||||
/pkgs/build-support/cc-wrapper @edolstra
|
||||
|
||||
# Libraries
|
||||
/lib @edolstra @nbp
|
||||
/lib/systems @edolstra @nbp @ericson2314
|
||||
|
||||
# Nixpkgs Internals
|
||||
/default.nix @nbp
|
||||
/pkgs/top-level/default.nix @nbp
|
||||
/pkgs/top-level/impure.nix @nbp
|
||||
/pkgs/top-level/stage.nix @nbp
|
||||
/default.nix @nbp
|
||||
/pkgs/top-level/default.nix @nbp @Ericson2314
|
||||
/pkgs/top-level/impure.nix @nbp @Ericson2314
|
||||
/pkgs/top-level/stage.nix @nbp @Ericson2314
|
||||
/pkgs/stdenv @edolstra
|
||||
/pkgs/build-support/cc-wrapper @edolstra @Ericson2314
|
||||
/pkgs/build-support/bintools-wrapper @edolstra @Ericson2314
|
||||
/pkgs/build-support/setup-hooks @edolstra @Ericson2314
|
||||
|
||||
# NixOS Internals
|
||||
/nixos/default.nix @nbp
|
||||
@ -84,3 +85,9 @@
|
||||
# https://github.com/NixOS/nixpkgs/issues/31401
|
||||
/lib/maintainers.nix @ghost
|
||||
/lib/licenses.nix @ghost
|
||||
|
||||
# Qt / KDE
|
||||
/pkgs/applications/kde @ttuegel
|
||||
/pkgs/desktops/plasma-5 @ttuegel
|
||||
/pkgs/development/libraries/kde-frameworks @ttuegel
|
||||
/pkgs/development/libraries/qt-5 @ttuegel
|
||||
|
2
COPYING
2
COPYING
@ -1,4 +1,4 @@
|
||||
Copyright (c) 2003-2017 Eelco Dolstra and the Nixpkgs/NixOS contributors
|
||||
Copyright (c) 2003-2018 Eelco Dolstra and the Nixpkgs/NixOS contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
@ -18,9 +18,9 @@
|
||||
tab settings so it’s asking for trouble.</para></listitem>
|
||||
|
||||
<listitem><para>Use <literal>lowerCamelCase</literal> for variable
|
||||
names, not <literal>UpperCamelCase</literal>. TODO: naming of
|
||||
attributes in
|
||||
<filename>all-packages.nix</filename>?</para></listitem>
|
||||
names, not <literal>UpperCamelCase</literal>. Note, this rule does
|
||||
not apply to package attribute names, which instead follow the rules
|
||||
in <xref linkend="sec-package-naming"/>.</para></listitem>
|
||||
|
||||
<listitem><para>Function calls with attribute set arguments are
|
||||
written as
|
||||
@ -220,9 +220,10 @@ args.stdenv.mkDerivation (args // {
|
||||
|
||||
<listitem><para>The variable name used for the instantiated package
|
||||
in <filename>all-packages.nix</filename>, and when passing it as a
|
||||
dependency to other functions. This is what Nix expression authors
|
||||
see. It can also be used when installing using <command>nix-env
|
||||
-iA</command>.</para></listitem>
|
||||
dependency to other functions. Typically this is called the
|
||||
<emphasis>package attribute name</emphasis>. This is what Nix
|
||||
expression authors see. It can also be used when installing using
|
||||
<command>nix-env -iA</command>.</para></listitem>
|
||||
|
||||
<listitem><para>The filename for (the directory containing) the Nix
|
||||
expression.</para></listitem>
|
||||
@ -259,12 +260,12 @@ bound to the variable name <varname>e2fsprogs</varname> in
|
||||
Also append <literal>"unstable"</literal> to the name - e.g.,
|
||||
<literal>"pkgname-unstable-2014-09-23"</literal>.</para></listitem>
|
||||
|
||||
<listitem><para>Dashes in the package name should be preserved
|
||||
in new variable names, rather than converted to underscores
|
||||
(which was convention up to around 2013 and most names
|
||||
still have underscores instead of dashes) — e.g.,
|
||||
<varname>http-parser</varname> instead of
|
||||
<varname>http_parser</varname>.</para></listitem>
|
||||
<listitem><para>Dashes in the package name should be preserved in
|
||||
new variable names, rather than converted to underscores or camel
|
||||
cased — e.g., <varname>http-parser</varname> instead of
|
||||
<varname>http_parser</varname> or <varname>httpParser</varname>. The
|
||||
hyphenated style is preferred in all three package
|
||||
names.</para></listitem>
|
||||
|
||||
<listitem><para>If there are multiple versions of a package, this
|
||||
should be reflected in the variable names in
|
||||
|
@ -187,7 +187,7 @@
|
||||
How does this work in practice? Nixpkgs is now structured so that build-time dependencies are taken from <varname>buildPackages</varname>, whereas run-time dependencies are taken from the top level attribute set.
|
||||
For example, <varname>buildPackages.gcc</varname> should be used at build time, while <varname>gcc</varname> should be used at run time.
|
||||
Now, for most of Nixpkgs's history, there was no <varname>buildPackages</varname>, and most packages have not been refactored to use it explicitly.
|
||||
Instead, one can use the four attributes used for specifying dependencies as documented in <xref linkend="ssec-stdenv-attributes"/>.
|
||||
Instead, one can use the six (<emphasis>gasp</emphasis>) attributes used for specifying dependencies as documented in <xref linkend="ssec-stdenv-dependencies"/>.
|
||||
We "splice" together the run-time and build-time package sets with <varname>callPackage</varname>, and then <varname>mkDerivation</varname> for each of four attributes pulls the right derivation out.
|
||||
This splicing can be skipped when not cross compiling as the package sets are the same, but is a bit slow for cross compiling.
|
||||
Because of this, a best-of-both-worlds solution is in the works with no splicing or explicit access of <varname>buildPackages</varname> needed.
|
||||
@ -200,6 +200,45 @@
|
||||
</para></note>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Cross packagaing cookbook</title>
|
||||
<para>
|
||||
Some frequently problems when packaging for cross compilation are good to just spell and answer.
|
||||
Ideally the information above is exhaustive, so this section cannot provide any new information,
|
||||
but its ludicrous and cruel to expect everyone to spend effort working through the interaction of many features just to figure out the same answer to the same common problem.
|
||||
Feel free to add to this list!
|
||||
</para>
|
||||
<qandaset>
|
||||
<qandaentry>
|
||||
<question><para>
|
||||
What if my package's build system needs to build a C program to be run under the build environment?
|
||||
</para></question>
|
||||
<answer><para>
|
||||
<programlisting>depsBuildBuild = [ buildPackages.stdenv.cc ];</programlisting>
|
||||
Add it to your <function>mkDerivation</function> invocation.
|
||||
</para></answer>
|
||||
</qandaentry>
|
||||
<qandaentry>
|
||||
<question><para>
|
||||
My package fails to find <command>ar</command>.
|
||||
</para></question>
|
||||
<answer><para>
|
||||
Many packages assume that an unprefixed <command>ar</command> is available, but Nix doesn't provide one.
|
||||
It only provides a prefixed one, just as it only does for all the other binutils programs.
|
||||
It may be necessary to patch the package to fix the build system to use a prefixed `ar`.
|
||||
</para></answer>
|
||||
</qandaentry>
|
||||
<qandaentry>
|
||||
<question><para>
|
||||
My package's testsuite needs to run host platform code.
|
||||
</para></question>
|
||||
<answer><para>
|
||||
<programlisting>doCheck = stdenv.hostPlatform != stdenv.buildPlatfrom;</programlisting>
|
||||
Add it to your <function>mkDerivation</function> invocation.
|
||||
</para></answer>
|
||||
</qandaentry>
|
||||
</qandaset>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<!--============================================================-->
|
||||
|
@ -23,11 +23,12 @@ pkgs.stdenv.mkDerivation {
|
||||
|
||||
buildCommand = let toDocbook = { useChapters ? false, inputFile, outputFile }:
|
||||
let
|
||||
extraHeader = ''xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" '';
|
||||
extraHeader = lib.optionalString (!useChapters)
|
||||
''xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" '';
|
||||
in ''
|
||||
{
|
||||
pandoc '${inputFile}' -w docbook ${lib.optionalString useChapters "--top-level-division=chapter"} \
|
||||
--smart \
|
||||
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=|' \
|
||||
@ -48,6 +49,10 @@ pkgs.stdenv.mkDerivation {
|
||||
outputFile = "introduction.xml";
|
||||
useChapters = true;
|
||||
}
|
||||
+ toDocbook {
|
||||
inputFile = ./shell.md;
|
||||
outputFile = "shell.xml";
|
||||
}
|
||||
+ toDocbook {
|
||||
inputFile = ./languages-frameworks/python.md;
|
||||
outputFile = "./languages-frameworks/python.xml";
|
||||
|
@ -11,31 +11,53 @@
|
||||
in the Coq derivation.
|
||||
</para>
|
||||
<para>
|
||||
Some libraries require OCaml and sometimes also Camlp5. The exact
|
||||
versions that were used to build Coq are saved in the
|
||||
Some libraries require OCaml and sometimes also Camlp5 or findlib.
|
||||
The exact versions that were used to build Coq are saved in the
|
||||
<literal>coq.ocaml</literal> and <literal>coq.camlp5</literal>
|
||||
attributes.
|
||||
and <literal>coq.findlib</literal> attributes.
|
||||
</para>
|
||||
<para>
|
||||
Coq libraries may be compatible with some specific versions of Coq only.
|
||||
The <literal>compatibleCoqVersions</literal> attribute is used to
|
||||
precisely select those versions of Coq that are compatible with this
|
||||
derivation.
|
||||
</para>
|
||||
<para>
|
||||
Here is a simple package example. It is a pure Coq library, thus it
|
||||
only depends on Coq. Its <literal>makefile</literal> has been
|
||||
generated using <literal>coq_makefile</literal> so we only have to
|
||||
depends on Coq. It builds on the Mathematical Components library, thus it
|
||||
also takes <literal>mathcomp</literal> as <literal>buildInputs</literal>.
|
||||
Its <literal>Makefile</literal> has been generated using
|
||||
<literal>coq_makefile</literal> so we only have to
|
||||
set the <literal>$COQLIB</literal> variable at install time.
|
||||
</para>
|
||||
<programlisting>
|
||||
{stdenv, fetchurl, coq}:
|
||||
stdenv.mkDerivation {
|
||||
src = fetchurl {
|
||||
url = http://coq.inria.fr/pylons/contribs/files/Karatsuba/v8.4/Karatsuba.tar.gz;
|
||||
sha256 = "0ymfpv4v49k4fm63nq6gcl1hbnnxrvjjp7yzc4973n49b853c5b1";
|
||||
{ stdenv, fetchFromGitHub, coq, mathcomp }:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
name = "coq${coq.coq-version}-multinomials-${version}";
|
||||
version = "1.0";
|
||||
src = fetchFromGitHub {
|
||||
owner = "math-comp";
|
||||
repo = "multinomials";
|
||||
rev = version;
|
||||
sha256 = "1qmbxp1h81cy3imh627pznmng0kvv37k4hrwi2faa101s6bcx55m";
|
||||
};
|
||||
|
||||
name = "coq-karatsuba";
|
||||
|
||||
buildInputs = [ coq ];
|
||||
propagatedBuildInputs = [ mathcomp ];
|
||||
|
||||
installFlags = "COQLIB=$(out)/lib/coq/${coq.coq-version}/";
|
||||
|
||||
meta = {
|
||||
description = "A Coq/SSReflect Library for Monoidal Rings and Multinomials";
|
||||
inherit (src.meta) homepage;
|
||||
license = stdenv.lib.licenses.cecill-b;
|
||||
inherit (coq.meta) platforms;
|
||||
};
|
||||
|
||||
passthru = {
|
||||
compatibleCoqVersions = v: builtins.elem v [ "8.5" "8.6" "8.7" ];
|
||||
};
|
||||
}
|
||||
</programlisting>
|
||||
</section>
|
||||
|
||||
|
@ -581,8 +581,8 @@ nix-shell "<nixpkgs>" -A haskellPackages.bar.env
|
||||
Every Haskell package set takes a function called `overrides` that you can use
|
||||
to manipulate the package as much as you please. One useful application of this
|
||||
feature is to replace the default `mkDerivation` function with one that enables
|
||||
library profiling for all packages. To accomplish that, add configure the
|
||||
following snippet in your `~/.config/nixpkgs/config.nix` file:
|
||||
library profiling for all packages. To accomplish that add the following
|
||||
snippet to your `~/.config/nixpkgs/config.nix` file:
|
||||
```nix
|
||||
{
|
||||
packageOverrides = super: let self = super.pkgs; in
|
||||
@ -777,14 +777,14 @@ to find out the store path of the system's zlib library. Now, you can
|
||||
stack --extra-lib-dirs=/nix/store/alsvwzkiw4b7ip38l4nlfjijdvg3fvzn-zlib-1.2.8/lib build
|
||||
```
|
||||
|
||||
Typically, you'll need `--extra-include-dirs` as well. It's possible
|
||||
to add those flag to the project's `stack.yaml` or your user's
|
||||
global `~/.stack/global/stack.yaml` file so that you don't have to
|
||||
specify them manually every time. But again, you're likely better off
|
||||
using Stack's Nix support instead.
|
||||
Typically, you'll need `--extra-include-dirs` as well. It's possible
|
||||
to add those flag to the project's `stack.yaml` or your user's
|
||||
global `~/.stack/global/stack.yaml` file so that you don't have to
|
||||
specify them manually every time. But again, you're likely better off
|
||||
using Stack's Nix support instead.
|
||||
|
||||
The same thing applies to `cabal configure`, of course, if you're
|
||||
building with `cabal-install` instead of Stack.
|
||||
The same thing applies to `cabal configure`, of course, if you're
|
||||
building with `cabal-install` instead of Stack.
|
||||
|
||||
### Creating statically linked binaries
|
||||
|
||||
|
@ -134,7 +134,7 @@ with
|
||||
```nix
|
||||
with import <nixpkgs> {};
|
||||
|
||||
python35.withPackages (ps: [ps.numpy ps.toolz])
|
||||
(python35.withPackages (ps: [ps.numpy ps.toolz])).env
|
||||
```
|
||||
Executing `nix-shell` gives you again a Nix shell from which you can run Python.
|
||||
|
||||
|
@ -20,7 +20,7 @@ For daily builds (beta and nightly) use either rustup from
|
||||
nixpkgs or use the [Rust nightlies
|
||||
overlay](#using-the-rust-nightlies-overlay).
|
||||
|
||||
## Packaging Rust applications
|
||||
## Compiling Rust applications with Cargo
|
||||
|
||||
Rust applications are packaged by using the `buildRustPackage` helper from `rustPlatform`:
|
||||
|
||||
@ -56,6 +56,167 @@ checksum can be then take from the failed build.
|
||||
To install crates with nix there is also an experimental project called
|
||||
[nixcrates](https://github.com/fractalide/nixcrates).
|
||||
|
||||
## Compiling Rust crates using Nix instead of Cargo
|
||||
|
||||
When run, `cargo build` produces a file called `Cargo.lock`,
|
||||
containing pinned versions of all dependencies. Nixpkgs contains a
|
||||
tool called `carnix` (`nix-env -iA nixos.carnix`), which can be used
|
||||
to turn a `Cargo.lock` into a Nix expression.
|
||||
|
||||
That Nix expression calls `rustc` directly (hence bypassing Cargo),
|
||||
and can be used to compile a crate and all its dependencies. Here is
|
||||
an example for a minimal `hello` crate:
|
||||
|
||||
|
||||
$ cargo new hello
|
||||
$ cd hello
|
||||
$ cargo build
|
||||
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
|
||||
|
||||
Now, the file produced by the call to `carnix`, called `hello.nix`, looks like:
|
||||
|
||||
```
|
||||
with import <nixpkgs> {};
|
||||
let kernel = buildPlatform.parsed.kernel.name;
|
||||
# ... (content skipped)
|
||||
hello_0_1_0_ = { dependencies?[], buildDependencies?[], features?[] }: buildRustCrate {
|
||||
crateName = "hello";
|
||||
version = "0.1.0";
|
||||
authors = [ "Authorname <user@example.com>" ];
|
||||
src = ./.;
|
||||
inherit dependencies buildDependencies features;
|
||||
};
|
||||
in
|
||||
rec {
|
||||
hello_0_1_0 = hello_0_1_0_ rec {};
|
||||
}
|
||||
```
|
||||
|
||||
In particular, note that the argument given as `--src` is copied
|
||||
verbatim to the source. If we look at a more complicated
|
||||
dependencies, for instance by adding a single line `libc="*"` to our
|
||||
`Cargo.toml`, we first need to run `cargo build` to update the
|
||||
`Cargo.lock`. Then, `carnix` needs to be run again, and produces the
|
||||
following nix file:
|
||||
|
||||
```
|
||||
with import <nixpkgs> {};
|
||||
let kernel = buildPlatform.parsed.kernel.name;
|
||||
# ... (content skipped)
|
||||
hello_0_1_0_ = { dependencies?[], buildDependencies?[], features?[] }: buildRustCrate {
|
||||
crateName = "hello";
|
||||
version = "0.1.0";
|
||||
authors = [ "Jörg Thalheim <joerg@thalheim.io>" ];
|
||||
src = ./.;
|
||||
inherit dependencies buildDependencies features;
|
||||
};
|
||||
libc_0_2_34_ = { dependencies?[], buildDependencies?[], features?[] }: buildRustCrate {
|
||||
crateName = "libc";
|
||||
version = "0.2.34";
|
||||
authors = [ "The Rust Project Developers" ];
|
||||
sha256 = "11jmqdxmv0ka10ay0l8nzx0nl7s2lc3dbrnh1mgbr2grzwdyxi2s";
|
||||
inherit dependencies buildDependencies features;
|
||||
};
|
||||
in
|
||||
rec {
|
||||
hello_0_1_0 = hello_0_1_0_ rec {
|
||||
dependencies = [ libc_0_2_34 ];
|
||||
};
|
||||
libc_0_2_34_features."default".from_hello_0_1_0__default = true;
|
||||
libc_0_2_34 = libc_0_2_34_ rec {
|
||||
features = mkFeatures libc_0_2_34_features;
|
||||
};
|
||||
libc_0_2_34_features."use_std".self_default = hasDefault libc_0_2_34_features;
|
||||
}
|
||||
```
|
||||
|
||||
Here, the `libc` crate has no `src` attribute, so `buildRustCrate`
|
||||
will fetch it from [crates.io](https://crates.io). A `sha256`
|
||||
attribute is still needed for Nix purity.
|
||||
|
||||
Some crates require external libraries. For crates from
|
||||
[crates.io](https://crates.io), such libraries can be specified in
|
||||
`defaultCrateOverrides` package in nixpkgs itself.
|
||||
|
||||
Starting from that file, one can add more overrides, to add features
|
||||
or build inputs by overriding the hello crate in a seperate file.
|
||||
|
||||
```
|
||||
with import <nixpkgs> {};
|
||||
(import ./hello.nix).hello_0_1_0.override {
|
||||
crateOverrides = defaultCrateOverrides // {
|
||||
hello = attrs: { buildInputs = [ openssl ]; };
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Here, `crateOverrides` is expected to be a attribute set, where the
|
||||
key is the crate name without version number and the value a function.
|
||||
The function gets all attributes passed to `buildRustCrate` as first
|
||||
argument and returns a set that contains all attribute that should be
|
||||
overwritten.
|
||||
|
||||
For more complicated cases, such as when parts of the crate's
|
||||
derivation depend on the the crate's version, the `attrs` argument of
|
||||
the override above can be read, as in the following example, which
|
||||
patches the derivation:
|
||||
|
||||
```
|
||||
with import <nixpkgs> {};
|
||||
(import ./hello.nix).hello_0_1_0.override {
|
||||
crateOverrides = defaultCrateOverrides // {
|
||||
hello = attrs: lib.optionalAttrs (lib.versionAtLeast attrs.version "1.0") {
|
||||
postPatch = ''
|
||||
substituteInPlace lib/zoneinfo.rs \
|
||||
--replace "/usr/share/zoneinfo" "${tzdata}/share/zoneinfo"
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Another situation is when we want to override a nested
|
||||
dependency. This actually works in the exact same way, since the
|
||||
`crateOverrides` parameter is forwarded to the crate's
|
||||
dependencies. For instance, to override the build inputs for crate
|
||||
`libc` in the example above, where `libc` is a dependency of the main
|
||||
crate, we could do:
|
||||
|
||||
```
|
||||
with import <nixpkgs> {};
|
||||
(import hello.nix).hello_0_1_0.override {
|
||||
crateOverrides = defaultCrateOverrides // {
|
||||
libc = attrs: { buildInputs = []; };
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Three more parameters can be overridden:
|
||||
|
||||
- The version of rustc used to compile the crate:
|
||||
|
||||
```
|
||||
hello_0_1_0.override { rust = pkgs.rust; };
|
||||
```
|
||||
|
||||
- Whether to build in release mode or debug mode (release mode by
|
||||
default):
|
||||
|
||||
```
|
||||
hello_0_1_0.override { release = false; };
|
||||
```
|
||||
|
||||
- Whether to print the commands sent to rustc when building
|
||||
(equivalent to `--verbose` in cargo:
|
||||
|
||||
```
|
||||
hello_0_1_0.override { verbose = false; };
|
||||
```
|
||||
|
||||
|
||||
## Using the Rust nightlies overlay
|
||||
|
||||
Mozilla provides an overlay for nixpkgs to bring a nightly version of Rust into scope.
|
||||
|
@ -7,123 +7,123 @@
|
||||
<title>Reviewing contributions</title>
|
||||
|
||||
<warning>
|
||||
<para>The following section is a draft and reviewing policy is still being
|
||||
<para>The following section is a draft and reviewing policy is still being
|
||||
discussed.</para>
|
||||
</warning>
|
||||
|
||||
<para>The nixpkgs projects receives a fairly high number of contributions via
|
||||
GitHub pull-requests. Reviewing and approving these is an important task and a
|
||||
<para>The nixpkgs projects receives a fairly high number of contributions via
|
||||
GitHub pull-requests. Reviewing and approving these is an important task and a
|
||||
way to contribute to the project.</para>
|
||||
|
||||
<para>The high change rate of nixpkgs make any pull request that is open for
|
||||
long enough subject to conflicts that will require extra work from the
|
||||
submitter or the merger. Reviewing pull requests in a timely manner and being
|
||||
responsive to the comments is the key to avoid these. GitHub provides sort
|
||||
filters that can be used to see the <link
|
||||
xlink:href="https://github.com/NixOS/nixpkgs/pulls?q=is%3Apr+is%3Aopen+sort%3Aupdated-desc">most
|
||||
recently</link> and the <link
|
||||
xlink:href="https://github.com/NixOS/nixpkgs/pulls?q=is%3Apr+is%3Aopen+sort%3Aupdated-asc">least
|
||||
<para>The high change rate of nixpkgs make any pull request that is open for
|
||||
long enough subject to conflicts that will require extra work from the
|
||||
submitter or the merger. Reviewing pull requests in a timely manner and being
|
||||
responsive to the comments is the key to avoid these. GitHub provides sort
|
||||
filters that can be used to see the <link
|
||||
xlink:href="https://github.com/NixOS/nixpkgs/pulls?q=is%3Apr+is%3Aopen+sort%3Aupdated-desc">most
|
||||
recently</link> and the <link
|
||||
xlink:href="https://github.com/NixOS/nixpkgs/pulls?q=is%3Apr+is%3Aopen+sort%3Aupdated-asc">least
|
||||
recently</link> updated pull-requests.</para>
|
||||
|
||||
<para>When reviewing a pull request, please always be nice and polite.
|
||||
Controversial changes can lead to controversial opinions, but it is important
|
||||
<para>When reviewing a pull request, please always be nice and polite.
|
||||
Controversial changes can lead to controversial opinions, but it is important
|
||||
to respect every community members and their work.</para>
|
||||
|
||||
<para>GitHub provides reactions, they are a simple and quick way to provide
|
||||
feedback to pull-requests or any comments. The thumb-down reaction should be
|
||||
used with care and if possible accompanied with some explanations so the
|
||||
<para>GitHub provides reactions, they are a simple and quick way to provide
|
||||
feedback to pull-requests or any comments. The thumb-down reaction should be
|
||||
used with care and if possible accompanied with some explanations so the
|
||||
submitter has directions to improve his contribution.</para>
|
||||
|
||||
<para>Pull-requests reviews should include a list of what has been reviewed in a
|
||||
comment, so other reviewers and mergers can know the state of the
|
||||
<para>Pull-requests reviews should include a list of what has been reviewed in a
|
||||
comment, so other reviewers and mergers can know the state of the
|
||||
review.</para>
|
||||
|
||||
<para>All the review template samples provided in this section are generic and
|
||||
meant as examples. Their usage is optional and the reviewer is free to adapt
|
||||
<para>All the review template samples provided in this section are generic and
|
||||
meant as examples. Their usage is optional and the reviewer is free to adapt
|
||||
them to his liking.</para>
|
||||
|
||||
<section><title>Package updates</title>
|
||||
|
||||
<para>A package update is the most trivial and common type of pull-request.
|
||||
These pull-requests mainly consist in updating the version part of the package
|
||||
<para>A package update is the most trivial and common type of pull-request.
|
||||
These pull-requests mainly consist in updating the version part of the package
|
||||
name and the source hash.</para>
|
||||
<para>It can happen that non trivial updates include patches or more complex
|
||||
<para>It can happen that non trivial updates include patches or more complex
|
||||
changes.</para>
|
||||
|
||||
<para>Reviewing process:</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem><para>Add labels to the pull-request. (Requires commit
|
||||
<listitem><para>Add labels to the pull-request. (Requires commit
|
||||
rights)</para>
|
||||
<itemizedlist>
|
||||
<listitem><para><literal>8.has: package (update)</literal> and any topic
|
||||
<listitem><para><literal>8.has: package (update)</literal> and any topic
|
||||
label that fit the updated package.</para></listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
<listitem><para>Ensure that the package versioning is fitting the
|
||||
<listitem><para>Ensure that the package versioning is fitting the
|
||||
guidelines.</para></listitem>
|
||||
<listitem><para>Ensure that the commit text is fitting the
|
||||
<listitem><para>Ensure that the commit text is fitting the
|
||||
guidelines.</para></listitem>
|
||||
<listitem><para>Ensure that the package maintainers are notified.</para>
|
||||
<itemizedlist>
|
||||
<listitem><para>mention-bot usually notify GitHub users based on the
|
||||
submitted changes, but it can happen that it misses some of the
|
||||
<listitem><para>mention-bot usually notify GitHub users based on the
|
||||
submitted changes, but it can happen that it misses some of the
|
||||
package maintainers.</para></listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
<listitem><para>Ensure that the meta field contains correct
|
||||
<listitem><para>Ensure that the meta field contains correct
|
||||
information.</para>
|
||||
<itemizedlist>
|
||||
<listitem><para>License can change with version updates, so it should be
|
||||
<listitem><para>License can change with version updates, so it should be
|
||||
checked to be fitting upstream license.</para></listitem>
|
||||
<listitem><para>If the package has no maintainer, a maintainer must be
|
||||
set. This can be the update submitter or a community member that
|
||||
<listitem><para>If the package has no maintainer, a maintainer must be
|
||||
set. This can be the update submitter or a community member that
|
||||
accepts to take maintainership of the package.</para></listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
<listitem><para>Ensure that the code contains no typos.</para></listitem>
|
||||
<listitem><para>Building the package locally.</para>
|
||||
<itemizedlist>
|
||||
<listitem><para>Pull-requests are often targeted to the master or staging
|
||||
branch so building the pull-request locally as it is submitted can
|
||||
<listitem><para>Pull-requests are often targeted to the master or staging
|
||||
branch so building the pull-request locally as it is submitted can
|
||||
trigger a large amount of source builds.</para>
|
||||
<para>It is possible to rebase the changes on nixos-unstable or
|
||||
nixpkgs-unstable for easier review by running the following commands
|
||||
<para>It is possible to rebase the changes on nixos-unstable or
|
||||
nixpkgs-unstable for easier review by running the following commands
|
||||
from a nixpkgs clone.
|
||||
<screen>
|
||||
$ git remote add channels https://github.com/NixOS/nixpkgs-channels.git <co
|
||||
$ git remote add channels https://github.com/NixOS/nixpkgs-channels.git <co
|
||||
xml:id='reviewing-rebase-1' />
|
||||
$ git fetch channels nixos-unstable <co xml:id='reviewing-rebase-2' />
|
||||
$ git fetch origin pull/PRNUMBER/head <co xml:id='reviewing-rebase-3' />
|
||||
$ git rebase --onto nixos-unstable BASEBRANCH FETCH_HEAD <co
|
||||
$ git rebase --onto nixos-unstable BASEBRANCH FETCH_HEAD <co
|
||||
xml:id='reviewing-rebase-4' />
|
||||
</screen>
|
||||
<calloutlist>
|
||||
<callout arearefs='reviewing-rebase-1'>
|
||||
<para>This should be done only once to be able to fetch channel
|
||||
<para>This should be done only once to be able to fetch channel
|
||||
branches from the nixpkgs-channels repository.</para>
|
||||
</callout>
|
||||
<callout arearefs='reviewing-rebase-2'>
|
||||
<para>Fetching the nixos-unstable branch.</para>
|
||||
</callout>
|
||||
<callout arearefs='reviewing-rebase-3'>
|
||||
<para>Fetching the pull-request changes, <varname>PRNUMBER</varname>
|
||||
is the number at the end of the pull-request title and
|
||||
<varname>BASEBRANCH</varname> the base branch of the
|
||||
<para>Fetching the pull-request changes, <varname>PRNUMBER</varname>
|
||||
is the number at the end of the pull-request title and
|
||||
<varname>BASEBRANCH</varname> the base branch of the
|
||||
pull-request.</para>
|
||||
</callout>
|
||||
<callout arearefs='reviewing-rebase-3'>
|
||||
<para>Rebasing the pull-request changes to the nixos-unstable
|
||||
<para>Rebasing the pull-request changes to the nixos-unstable
|
||||
branch.</para>
|
||||
</callout>
|
||||
</calloutlist>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>The <link xlink:href="https://github.com/madjar/nox">nox</link>
|
||||
tool can be used to review a pull-request content in a single command.
|
||||
It doesn't rebase on a channel branch so it might trigger multiple
|
||||
source builds. <varname>PRNUMBER</varname> should be replaced by the
|
||||
<para>The <link xlink:href="https://github.com/madjar/nox">nox</link>
|
||||
tool can be used to review a pull-request content in a single command.
|
||||
It doesn't rebase on a channel branch so it might trigger multiple
|
||||
source builds. <varname>PRNUMBER</varname> should be replaced by the
|
||||
number at the end of the pull-request title.</para>
|
||||
<screen>
|
||||
$ nix-shell -p nox --run "nox-review -k pr PRNUMBER"
|
||||
@ -153,42 +153,42 @@ $ nix-shell -p nox --run "nox-review -k pr PRNUMBER"
|
||||
|
||||
<section><title>New packages</title>
|
||||
|
||||
<para>New packages are a common type of pull-requests. These pull requests
|
||||
<para>New packages are a common type of pull-requests. These pull requests
|
||||
consists in adding a new nix-expression for a package.</para>
|
||||
|
||||
<para>Reviewing process:</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem><para>Add labels to the pull-request. (Requires commit
|
||||
<listitem><para>Add labels to the pull-request. (Requires commit
|
||||
rights)</para>
|
||||
<itemizedlist>
|
||||
<listitem><para><literal>8.has: package (new)</literal> and any topic
|
||||
<listitem><para><literal>8.has: package (new)</literal> and any topic
|
||||
label that fit the new package.</para></listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
<listitem><para>Ensure that the package versioning is fitting the
|
||||
<listitem><para>Ensure that the package versioning is fitting the
|
||||
guidelines.</para></listitem>
|
||||
<listitem><para>Ensure that the commit name is fitting the
|
||||
<listitem><para>Ensure that the commit name is fitting the
|
||||
guidelines.</para></listitem>
|
||||
<listitem><para>Ensure that the meta field contains correct
|
||||
<listitem><para>Ensure that the meta field contains correct
|
||||
information.</para>
|
||||
<itemizedlist>
|
||||
<listitem><para>License must be checked to be fitting upstream
|
||||
<listitem><para>License must be checked to be fitting upstream
|
||||
license.</para></listitem>
|
||||
<listitem><para>Platforms should be set or the package will not get binary
|
||||
<listitem><para>Platforms should be set or the package will not get binary
|
||||
substitutes.</para></listitem>
|
||||
<listitem><para>A maintainer must be set, this can be the package
|
||||
submitter or a community member that accepts to take maintainership of
|
||||
<listitem><para>A maintainer must be set, this can be the package
|
||||
submitter or a community member that accepts to take maintainership of
|
||||
the package.</para></listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
<listitem><para>Ensure that the code contains no typos.</para></listitem>
|
||||
<listitem><para>Ensure the package source.</para>
|
||||
<itemizedlist>
|
||||
<listitem><para>Mirrors urls should be used when
|
||||
<listitem><para>Mirrors urls should be used when
|
||||
available.</para></listitem>
|
||||
<listitem><para>The most appropriate function should be used (e.g.
|
||||
packages from GitHub should use
|
||||
<listitem><para>The most appropriate function should be used (e.g.
|
||||
packages from GitHub should use
|
||||
<literal>fetchFromGitHub</literal>).</para></listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
@ -223,49 +223,49 @@ $ nix-shell -p nox --run "nox-review -k pr PRNUMBER"
|
||||
|
||||
<section><title>Module updates</title>
|
||||
|
||||
<para>Module updates are submissions changing modules in some ways. These often
|
||||
<para>Module updates are submissions changing modules in some ways. These often
|
||||
contains changes to the options or introduce new options.</para>
|
||||
|
||||
<para>Reviewing process</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem><para>Add labels to the pull-request. (Requires commit
|
||||
<listitem><para>Add labels to the pull-request. (Requires commit
|
||||
rights)</para>
|
||||
<itemizedlist>
|
||||
<listitem><para><literal>8.has: module (update)</literal> and any topic
|
||||
<listitem><para><literal>8.has: module (update)</literal> and any topic
|
||||
label that fit the module.</para></listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
<listitem><para>Ensure that the module maintainers are notified.</para>
|
||||
<itemizedlist>
|
||||
<listitem><para>Mention-bot notify GitHub users based on the submitted
|
||||
changes, but it can happen that it miss some of the package
|
||||
<listitem><para>Mention-bot notify GitHub users based on the submitted
|
||||
changes, but it can happen that it miss some of the package
|
||||
maintainers.</para></listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
<listitem><para>Ensure that the module tests, if any, are
|
||||
<listitem><para>Ensure that the module tests, if any, are
|
||||
succeeding.</para></listitem>
|
||||
<listitem><para>Ensure that the introduced options are correct.</para>
|
||||
<itemizedlist>
|
||||
<listitem><para>Type should be appropriate (string related types differs
|
||||
in their merging capabilities, <literal>optionSet</literal> and
|
||||
<listitem><para>Type should be appropriate (string related types differs
|
||||
in their merging capabilities, <literal>optionSet</literal> and
|
||||
<literal>string</literal> types are deprecated).</para></listitem>
|
||||
<listitem><para>Description, default and example should be
|
||||
<listitem><para>Description, default and example should be
|
||||
provided.</para></listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
<listitem><para>Ensure that option changes are backward compatible.</para>
|
||||
<itemizedlist>
|
||||
<listitem><para><literal>mkRenamedOptionModule</literal> and
|
||||
<literal>mkAliasOptionModule</literal> functions provide way to make
|
||||
<listitem><para><literal>mkRenamedOptionModule</literal> and
|
||||
<literal>mkAliasOptionModule</literal> functions provide way to make
|
||||
option changes backward compatible.</para></listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
<listitem><para>Ensure that removed options are declared with
|
||||
<listitem><para>Ensure that removed options are declared with
|
||||
<literal>mkRemovedOptionModule</literal></para></listitem>
|
||||
<listitem><para>Ensure that changes that are not backward compatible are
|
||||
<listitem><para>Ensure that changes that are not backward compatible are
|
||||
mentioned in release notes.</para></listitem>
|
||||
<listitem><para>Ensure that documentations affected by the change is
|
||||
<listitem><para>Ensure that documentations affected by the change is
|
||||
updated.</para></listitem>
|
||||
</itemizedlist>
|
||||
|
||||
@ -294,37 +294,37 @@ $ nix-shell -p nox --run "nox-review -k pr PRNUMBER"
|
||||
<para>New modules submissions introduce a new module to NixOS.</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem><para>Add labels to the pull-request. (Requires commit
|
||||
<listitem><para>Add labels to the pull-request. (Requires commit
|
||||
rights)</para>
|
||||
<itemizedlist>
|
||||
<listitem><para><literal>8.has: module (new)</literal> and any topic label
|
||||
<listitem><para><literal>8.has: module (new)</literal> and any topic label
|
||||
that fit the module.</para></listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
<listitem><para>Ensure that the module tests, if any, are
|
||||
<listitem><para>Ensure that the module tests, if any, are
|
||||
succeeding.</para></listitem>
|
||||
<listitem><para>Ensure that the introduced options are correct.</para>
|
||||
<itemizedlist>
|
||||
<listitem><para>Type should be appropriate (string related types differs
|
||||
in their merging capabilities, <literal>optionSet</literal> and
|
||||
<listitem><para>Type should be appropriate (string related types differs
|
||||
in their merging capabilities, <literal>optionSet</literal> and
|
||||
<literal>string</literal> types are deprecated).</para></listitem>
|
||||
<listitem><para>Description, default and example should be
|
||||
<listitem><para>Description, default and example should be
|
||||
provided.</para></listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
<listitem><para>Ensure that module <literal>meta</literal> field is
|
||||
<listitem><para>Ensure that module <literal>meta</literal> field is
|
||||
present</para>
|
||||
<itemizedlist>
|
||||
<listitem><para>Maintainers should be declared in
|
||||
<listitem><para>Maintainers should be declared in
|
||||
<literal>meta.maintainers</literal>.</para></listitem>
|
||||
<listitem><para>Module documentation should be declared with
|
||||
<listitem><para>Module documentation should be declared with
|
||||
<literal>meta.doc</literal>.</para></listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
<listitem><para>Ensure that the module respect other modules
|
||||
<listitem><para>Ensure that the module respect other modules
|
||||
functionality.</para>
|
||||
<itemizedlist>
|
||||
<listitem><para>For example, enabling a module should not open firewall
|
||||
<listitem><para>For example, enabling a module should not open firewall
|
||||
ports by default.</para></listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
@ -340,7 +340,7 @@ $ nix-shell -p nox --run "nox-review -k pr PRNUMBER"
|
||||
- [ ] options have default
|
||||
- [ ] options have example
|
||||
- [ ] options have descriptions
|
||||
- [ ] No unneeded package is added to system.environmentPackages
|
||||
- [ ] No unneeded package is added to environment.systemPackages
|
||||
- [ ] meta.maintainers is set
|
||||
- [ ] module documentation is declared in meta.doc
|
||||
|
||||
@ -355,22 +355,22 @@ $ nix-shell -p nox --run "nox-review -k pr PRNUMBER"
|
||||
|
||||
<para>Other type of submissions requires different reviewing steps.</para>
|
||||
|
||||
<para>If you consider having enough knowledge and experience in a topic and
|
||||
would like to be a long-term reviewer for related submissions, please contact
|
||||
the current reviewers for that topic. They will give you information about the
|
||||
<para>If you consider having enough knowledge and experience in a topic and
|
||||
would like to be a long-term reviewer for related submissions, please contact
|
||||
the current reviewers for that topic. They will give you information about the
|
||||
reviewing process.
|
||||
The main reviewers for a topic can be hard to find as there is no list, but
|
||||
checking past pull-requests to see who reviewed or git-blaming the code to see
|
||||
The main reviewers for a topic can be hard to find as there is no list, but
|
||||
checking past pull-requests to see who reviewed or git-blaming the code to see
|
||||
who committed to that topic can give some hints.</para>
|
||||
|
||||
<para>Container system, boot system and library changes are some examples of the
|
||||
<para>Container system, boot system and library changes are some examples of the
|
||||
pull requests fitting this category.</para>
|
||||
|
||||
</section>
|
||||
|
||||
<section><title>Merging pull-requests</title>
|
||||
|
||||
<para>It is possible for community members that have enough knowledge and
|
||||
<para>It is possible for community members that have enough knowledge and
|
||||
experience on a special topic to contribute by merging pull requests.</para>
|
||||
|
||||
<para>TODO: add the procedure to request merging rights.</para>
|
||||
@ -380,13 +380,13 @@ The following paragraph about how to deal with unactive contributors is just a
|
||||
proposition and should be modified to what the community agrees to be the right
|
||||
policy.
|
||||
|
||||
<para>Please note that contributors with commit rights unactive for more than
|
||||
<para>Please note that contributors with commit rights unactive for more than
|
||||
three months will have their commit rights revoked.</para>
|
||||
-->
|
||||
|
||||
<para>In a case a contributor leaves definitively the Nix community, he should
|
||||
create an issue or notify the mailing list with references of packages and
|
||||
modules he maintains so the maintainership can be taken over by other
|
||||
<para>In a case a contributor leaves definitively the Nix community, he should
|
||||
create an issue or notify the mailing list with references of packages and
|
||||
modules he maintains so the maintainership can be taken over by other
|
||||
contributors.</para>
|
||||
|
||||
</section>
|
||||
|
20
doc/shell.md
Normal file
20
doc/shell.md
Normal file
@ -0,0 +1,20 @@
|
||||
---
|
||||
title: pkgs.mkShell
|
||||
author: zimbatm
|
||||
date: 2017-10-30
|
||||
---
|
||||
|
||||
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.
|
||||
|
||||
## Usage
|
||||
|
||||
```nix
|
||||
{ pkgs ? import <nixpkgs> {} }:
|
||||
pkgs.mkShell {
|
||||
# this will make all the build inputs from hello and gnutar available to the shell environment
|
||||
inputsFrom = with pkgs; [ hello gnutar ];
|
||||
buildInputs = [ pkgs.gnumake ];
|
||||
}
|
||||
```
|
486
doc/stdenv.xml
486
doc/stdenv.xml
@ -179,6 +179,269 @@ genericBuild
|
||||
</section>
|
||||
|
||||
|
||||
<section xml:id="ssec-stdenv-dependencies"><title>Specifying dependencies</title>
|
||||
|
||||
<para>
|
||||
As described in the Nix manual, almost any <filename>*.drv</filename> store path in a derivation's attribute set will induce a dependency on that derivation.
|
||||
<varname>mkDerivation</varname>, however, takes a few attributes intended to, between them, include all the dependencies of a package.
|
||||
This is done both for structure and consistency, but also so that certain other setup can take place.
|
||||
For example, certain dependencies need their bin directories added to the <envar>PATH</envar>.
|
||||
That is built-in, but other setup is done via a pluggable mechanism that works in conjunction with these dependency attributes.
|
||||
See <xref linkend="ssec-setup-hooks"/> for details.
|
||||
</para>
|
||||
<para>
|
||||
Dependencies can be broken down along three axes: their host and target platforms relative to the new derivation's, and whether they are propagated.
|
||||
The platform distinctions are motivated by cross compilation; see <xref linkend="chap-cross"/> for exactly what each platform means.
|
||||
<footnote><para>
|
||||
The build platform is ignored because it is a mere implementation detail of the package satisfying the dependency:
|
||||
As a general programming principle, dependencies are always <emphasis>specified</emphasis> as interfaces, not concrete implementation.
|
||||
</para></footnote>
|
||||
But even if one is not cross compiling, the platforms imply whether or not the dependency is needed at run-time or build-time, a concept that makes perfect sense outside of cross compilation.
|
||||
For now, the run-time/build-time distinction is just a hint for mental clarity, but in the future it perhaps could be enforced.
|
||||
</para>
|
||||
<para>
|
||||
The extension of <envar>PATH</envar> with dependencies, alluded to above, proceeds according to the relative platforms alone.
|
||||
The process is carried out only for dependencies whose host platform matches the new derivation's build platform–i.e. which run on the platform where the new derivation will be built.
|
||||
<footnote><para>
|
||||
Currently, that means for native builds all dependencies are put on the <envar>PATH</envar>.
|
||||
But in the future that may not be the case for sake of matching cross:
|
||||
the platforms would be assumed to be unique for native and cross builds alike, so only the <varname>depsBuild*</varname> and <varname>nativeBuildDependencies</varname> dependencies would affect the <envar>PATH</envar>.
|
||||
</para></footnote>
|
||||
For each dependency <replaceable>dep</replaceable> of those dependencies, <filename><replaceable>dep</replaceable>/bin</filename>, if present, is added to the <envar>PATH</envar> environment variable.
|
||||
</para>
|
||||
<para>
|
||||
The dependency is propagated when it forces some of its other-transitive (non-immediate) downstream dependencies to also take it on as an immediate dependency.
|
||||
Nix itself already takes a package's transitive dependencies into account, but this propagation ensures nixpkgs-specific infrastructure like setup hooks (mentioned above) also are run as if the propagated dependency.
|
||||
</para>
|
||||
<para>
|
||||
It is important to note dependencies are not necessary propagated as the same sort of dependency that they were before, but rather as the corresponding sort so that the platform rules still line up.
|
||||
The exact rules for dependency propagation can be given by assigning each sort of dependency two integers based one how it's host and target platforms are offset from the depending derivation's platforms.
|
||||
Those offsets are given are given below in the descriptions of each dependency list attribute.
|
||||
Algorithmically, we traverse propagated inputs, accumulating every propagated dep's propagated deps and adjusting them to account for the "shift in perspective" described by the current dep's platform offsets.
|
||||
This results in sort a transitive closure of the dependency relation, with the offsets being approximately summed when two dependency links are combined.
|
||||
We also prune transitive deps whose combined offsets go out-of-bounds, which can be viewed as a filter over that transitive closure removing dependencies that are blatantly absurd.
|
||||
</para>
|
||||
<para>
|
||||
We can define the process precisely with <link xlink:href="https://en.wikipedia.org/wiki/Natural_deduction">Natural Deduction</link> using the inference rules.
|
||||
This probably seems a bit obtuse, but so is the bash code that actually implements it!
|
||||
<footnote><para>
|
||||
The <function>findInputs</function> function, currently residing in <filename>pkgs/stdenv/generic/setup.sh</filename>, implements the propagation logic.
|
||||
</para></footnote>
|
||||
They're confusing in very different ways so...hopefully if something doesn't make sense in one presentation, it does in the other!
|
||||
<programlisting>
|
||||
let mapOffset(h, t, i) = i + (if i <= 0 then h else t - 1)
|
||||
|
||||
propagated-dep(h0, t0, A, B)
|
||||
propagated-dep(h1, t1, B, C)
|
||||
h0 + h1 in {-1, 0, 1}
|
||||
h0 + t1 in {-1, 0, 1}
|
||||
-------------------------------------- Transitive property
|
||||
propagated-dep(mapOffset(h0, t0, h1),
|
||||
mapOffset(h0, t0, t1),
|
||||
A, C)</programlisting>
|
||||
<programlisting>
|
||||
let mapOffset(h, t, i) = i + (if i <= 0 then h else t - 1)
|
||||
|
||||
dep(h0, _, A, B)
|
||||
propagated-dep(h1, t1, B, C)
|
||||
h0 + h1 in {-1, 0, 1}
|
||||
h0 + t1 in {-1, 0, -1}
|
||||
-------------------------------------- Take immediate deps' propagated deps
|
||||
propagated-dep(mapOffset(h0, t0, h1),
|
||||
mapOffset(h0, t0, t1),
|
||||
A, C)</programlisting>
|
||||
<programlisting>
|
||||
propagated-dep(h, t, A, B)
|
||||
-------------------------------------- Propagated deps count as deps
|
||||
dep(h, t, A, B)</programlisting>
|
||||
Some explanation of this monstrosity is in order.
|
||||
In the common case, the target offset of a dependency is the successor to the target offset: <literal>t = h + 1</literal>.
|
||||
That means that:
|
||||
<programlisting>
|
||||
let f(h, t, i) = i + (if i <= 0 then h else t - 1)
|
||||
let f(h, h + 1, i) = i + (if i <= 0 then h else (h + 1) - 1)
|
||||
let f(h, h + 1, i) = i + (if i <= 0 then h else h)
|
||||
let f(h, h + 1, i) = i + h
|
||||
</programlisting>
|
||||
This is where the "sum-like" comes from above:
|
||||
We can just sum all the host offset to get the host offset of the transitive dependency.
|
||||
The target offset is the transitive dep is simply the host offset + 1, just as it was with the dependencies composed to make this transitive one;
|
||||
it can be ignored as it doesn't add any new information.
|
||||
</para>
|
||||
<para>
|
||||
Because of the bounds checks, the uncommon cases are <literal>h = t</literal> and <literal>h + 2 = t</literal>.
|
||||
In the former case, the motivation for <function>mapOffset</function> is that since its host and target platforms are the same, no transitive dep of it should be able to "discover" an offset greater than its reduced target offsets.
|
||||
<function>mapOffset</function> effectively "squashes" all its transitive dependencies' offsets so that none will ever be greater than the target offset of the original <literal>h = t</literal> package.
|
||||
In the other case, <literal>h + 1</literal> is skipped over between the host and target offsets.
|
||||
Instead of squashing the offsets, we need to "rip" them apart so no transitive dependencies' offset is that one.
|
||||
</para>
|
||||
<para>
|
||||
Overall, the unifying theme here is that propagation shouldn't be introducing transitive dependencies involving platforms the needing package is unaware of.
|
||||
The offset bounds checking and definition of <function>mapOffset</function> together ensure that this is the case.
|
||||
Discovering a new offset is discovering a new platform, and since those platforms weren't in the derivation "spec" of the needing package, they cannot be relevant.
|
||||
From a capability perspective, we can imagine that the host and target platforms of a package are the capabilities a package requires, and the depending package must provide the capability to the dependency.
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<title>Variables specifying dependencies</title>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>depsBuildBuild</varname></term>
|
||||
<listitem>
|
||||
<para>
|
||||
A list of dependencies whose host and target platforms are the new derivation's build platform.
|
||||
This means a <literal>-1</literal> host and <literal>-1</literal> target offset from the new derivation's platforms.
|
||||
They are programs/libraries used at build time that furthermore produce programs/libraries also used at build time.
|
||||
If the dependency doesn't care about the target platform (i.e. isn't a compiler or similar tool), put it in <varname>nativeBuildInputs</varname>instead.
|
||||
The most common use for this <literal>buildPackages.stdenv.cc</literal>, the default C compiler for this role.
|
||||
That example crops up more than one might think in old commonly used C libraries.
|
||||
</para>
|
||||
<para>
|
||||
Since these packages are able to be run at build time, that are always added to the <envar>PATH</envar>, as described above.
|
||||
But since these packages are only guaranteed to be able to run then, they shouldn't persist as run-time dependencies.
|
||||
This isn't currently enforced, but could be in the future.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>nativeBuildInputs</varname></term>
|
||||
<listitem>
|
||||
<para>
|
||||
A list of dependencies whose host platform is the new derivation's build platform, and target platform is the new derivation's host platform.
|
||||
This means a <literal>-1</literal> host offset and <literal>0</literal> target offset from the new derivation's platforms.
|
||||
They are programs/libraries used at build time that, if they are a compiler or similar tool, produce code to run at run time—i.e. tools used to build the new derivation.
|
||||
If the dependency doesn't care about the target platform (i.e. isn't a compiler or similar tool), put it here, rather than in <varname>depsBuildBuild</varname> or <varname>depsBuildTarget</varname>.
|
||||
This would be called <varname>depsBuildHost</varname> but for historical continuity.
|
||||
</para>
|
||||
<para>
|
||||
Since these packages are able to be run at build time, that are added to the <envar>PATH</envar>, as described above.
|
||||
But since these packages only are guaranteed to be able to run then, they shouldn't persist as run-time dependencies.
|
||||
This isn't currently enforced, but could be in the future.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>depsBuildTarget</varname></term>
|
||||
<listitem>
|
||||
<para>
|
||||
A list of dependencies whose host platform is the new derivation's build platform, and target platform is the new derivation's target platform.
|
||||
This means a <literal>-1</literal> host offset and <literal>1</literal> target offset from the new derivation's platforms.
|
||||
They are programs used at build time that produce code to run at run with code produced by the depending package.
|
||||
Most commonly, these would tools used to build the runtime or standard library the currently-being-built compiler will inject into any code it compiles.
|
||||
In many cases, the currently-being built compiler is itself employed for that task, but when that compiler won't run (i.e. its build and host platform differ) this is not possible.
|
||||
Other times, the compiler relies on some other tool, like binutils, that is always built separately so the dependency is unconditional.
|
||||
</para>
|
||||
<para>
|
||||
This is a somewhat confusing dependency to wrap ones head around, and for good reason.
|
||||
As the only one where the platform offsets are not adjacent integers, it requires thinking of a bootstrapping stage <emphasis>two</emphasis> away from the current one.
|
||||
It and it's use-case go hand in hand and are both considered poor form:
|
||||
try not to need this sort dependency, and try not avoid building standard libraries / runtimes in the same derivation as the compiler produces code using them.
|
||||
Instead strive to build those like a normal library, using the newly-built compiler just as a normal library would.
|
||||
In short, do not use this attribute unless you are packaging a compiler and are sure it is needed.
|
||||
</para>
|
||||
<para>
|
||||
Since these packages are able to be run at build time, that are added to the <envar>PATH</envar>, as described above.
|
||||
But since these packages only are guaranteed to be able to run then, they shouldn't persist as run-time dependencies.
|
||||
This isn't currently enforced, but could be in the future.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>depsHostHost</varname></term>
|
||||
<listitem><para>
|
||||
A list of dependencies whose host and target platforms match the new derivation's host platform.
|
||||
This means a both <literal>0</literal> host offset and <literal>0</literal> target offset from the new derivation's host platform.
|
||||
These are packages used at run-time to generate code also used at run-time.
|
||||
In practice, that would usually be tools used by compilers for metaprogramming/macro systems, or libraries used by the macros/metaprogramming code itself.
|
||||
It's always preferable to use a <varname>depsBuildBuild</varname> dependency in the derivation being built than a <varname>depsHostHost</varname> on the tool doing the building for this purpose.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>buildInputs</varname></term>
|
||||
<listitem>
|
||||
<para>
|
||||
A list of dependencies whose host platform and target platform match the new derivation's.
|
||||
This means a <literal>0</literal> host offset and <literal>1</literal> target offset from the new derivation's host platform.
|
||||
This would be called <varname>depsHostTarget</varname> but for historical continuity.
|
||||
If the dependency doesn't care about the target platform (i.e. isn't a compiler or similar tool), put it here, rather than in <varname>depsBuildBuild</varname>.
|
||||
</para>
|
||||
<para>
|
||||
These often are programs/libraries used by the new derivation at <emphasis>run</emphasis>-time, but that isn't always the case.
|
||||
For example, the machine code in a statically linked library is only used at run time, but the derivation containing the library is only needed at build time.
|
||||
Even in the dynamic case, the library may also be needed at build time to appease the linker.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>depsTargetTarget</varname></term>
|
||||
<listitem><para>
|
||||
A list of dependencies whose host platform matches the new derivation's target platform.
|
||||
This means a <literal>1</literal> offset from the new derivation's platforms.
|
||||
These are packages that run on the target platform, e.g. the standard library or run-time deps of standard library that a compiler insists on knowing about.
|
||||
It's poor form in almost all cases for a package to depend on another from a future stage [future stage corresponding to positive offset].
|
||||
Do not use this attribute unless you are packaging a compiler and are sure it is needed.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>depsBuildBuildPropagated</varname></term>
|
||||
<listitem><para>
|
||||
The propagated equivalent of <varname>depsBuildBuild</varname>.
|
||||
This perhaps never ought to be used, but it is included for consistency [see below for the others].
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>propagatedNativeBuildInputs</varname></term>
|
||||
<listitem><para>
|
||||
The propagated equivalent of <varname>nativeBuildInputs</varname>.
|
||||
This would be called <varname>depsBuildHostPropagated</varname> but for historical continuity.
|
||||
For example, if package <varname>Y</varname> has <literal>propagatedNativeBuildInputs = [X]</literal>, and package <varname>Z</varname> has <literal>buildInputs = [Y]</literal>, then package <varname>Z</varname> will be built as if it included package <varname>X</varname> in its <varname>nativeBuildInputs</varname>.
|
||||
If instead, package <varname>Z</varname> has <literal>nativeBuildInputs = [Y]</literal>, then <varname>Z</varname> will be built as if it included <varname>X</varname> in the <varname>depsBuildBuild</varname> of package <varname>Z</varname>, because of the sum of the two <literal>-1</literal> host offsets.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>depsBuildTargetPropagated</varname></term>
|
||||
<listitem><para>
|
||||
The propagated equivalent of <varname>depsBuildTarget</varname>.
|
||||
This is prefixed for the same reason of alerting potential users.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>depsHostHostPropagated</varname></term>
|
||||
<listitem><para>
|
||||
The propagated equivalent of <varname>depsHostHost</varname>.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>propagatedBuildInputs</varname></term>
|
||||
<listitem><para>
|
||||
The propagated equivalent of <varname>buildInputs</varname>.
|
||||
This would be called <varname>depsHostTargetPropagated</varname> but for historical continuity.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>depsTargetTarget</varname></term>
|
||||
<listitem><para>
|
||||
The propagated equivalent of <varname>depsTargetTarget</varname>.
|
||||
This is prefixed for the same reason of alerting potential users.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
<section xml:id="ssec-stdenv-attributes"><title>Attributes</title>
|
||||
|
||||
<variablelist>
|
||||
@ -198,63 +461,22 @@ genericBuild
|
||||
|
||||
</variablelist>
|
||||
|
||||
<variablelist>
|
||||
<title>Variables specifying dependencies</title>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>nativeBuildInputs</varname></term>
|
||||
<listitem><para>
|
||||
A list of dependencies used by the new derivation at <emphasis>build</emphasis>-time.
|
||||
I.e. these dependencies should not make it into the package's runtime-closure, though this is currently not checked.
|
||||
For each dependency <replaceable>dir</replaceable>, the directory <filename><replaceable>dir</replaceable>/bin</filename>, if it exists, is added to the <envar>PATH</envar> environment variable.
|
||||
Other environment variables are also set up via a pluggable mechanism.
|
||||
For instance, if <varname>buildInputs</varname> contains Perl, then the <filename>lib/site_perl</filename> subdirectory of each input is added to the <envar>PERL5LIB</envar> environment variable.
|
||||
See <xref linkend="ssec-setup-hooks"/> for details.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>buildInputs</varname></term>
|
||||
<listitem><para>
|
||||
A list of dependencies used by the new derivation at <emphasis>run</emphasis>-time.
|
||||
Currently, the build-time environment is modified in the exact same way as with <varname>nativeBuildInputs</varname>.
|
||||
This is problematic in that when cross-compiling, foreign executables can clobber native ones on the <envar>PATH</envar>.
|
||||
Even more confusing is static-linking.
|
||||
A statically-linked library should be listed here because ultimately that generated machine code will be used at run-time, even though a derivation containing the object files or static archives will only be used at build-time.
|
||||
A less confusing solution to this would be nice.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>propagatedNativeBuildInputs</varname></term>
|
||||
<listitem><para>
|
||||
Like <varname>nativeBuildInputs</varname>, but these dependencies are <emphasis>propagated</emphasis>:
|
||||
that is, the dependencies listed here are added to the <varname>nativeBuildInputs</varname> of any package that uses <emphasis>this</emphasis> package as a dependency.
|
||||
So if package Y has <literal>propagatedNativeBuildInputs = [X]</literal>, and package Z has <literal>nativeBuildInputs = [Y]</literal>,
|
||||
then package X will appear in Z’s build environment automatically.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>propagatedBuildInputs</varname></term>
|
||||
<listitem><para>
|
||||
Like <varname>buildInputs</varname>, but propagated just like <varname>propagatedNativeBuildInputs</varname>.
|
||||
This inherits <varname>buildInputs</varname>'s flaws of clobbering native executables when cross-compiling and being confusing for static linking.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
<variablelist>
|
||||
<title>Variables affecting build properties</title>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>enableParallelBuilding</varname></term>
|
||||
<listitem><para>If set, <literal>stdenv</literal> will pass specific
|
||||
flags to <literal>make</literal> and other build tools to enable
|
||||
parallel building with up to <literal>build-cores</literal>
|
||||
workers.</para></listitem>
|
||||
<listitem>
|
||||
<para>If set to <literal>true</literal>, <literal>stdenv</literal> will
|
||||
pass specific flags to <literal>make</literal> and other build tools to
|
||||
enable parallel building with up to <literal>build-cores</literal>
|
||||
workers.</para>
|
||||
|
||||
<para>Unless set to <literal>false</literal>, some build systems with good
|
||||
support for parallel building including <literal>cmake</literal>,
|
||||
<literal>meson</literal>, and <literal>qmake</literal> will set it to
|
||||
<literal>true</literal>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
@ -649,7 +871,7 @@ script) if it exists.</para>
|
||||
By default, when cross compiling, the configure script has <option>--build=...</option> and <option>--host=...</option> passed.
|
||||
Packages can instead pass <literal>[ "build" "host" "target" ]</literal> or a subset to control exactly which platform flags are passed.
|
||||
Compilers and other tools should use this to also pass the target platform, for example.
|
||||
Note eventually these will be passed when in native builds too, to improve determinism: build-time guessing, as is done today, is a risk of impurity.
|
||||
<footnote><para>Eventually these will be passed when in native builds too, to improve determinism: build-time guessing, as is done today, is a risk of impurity.</para></footnote>
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
@ -773,13 +995,14 @@ but only if the <varname>doCheck</varname> variable is enabled.</para>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>doCheck</varname></term>
|
||||
<listitem><para>If set to a non-empty string, the check phase is
|
||||
executed, otherwise it is skipped (default). Thus you should set
|
||||
|
||||
<programlisting>
|
||||
doCheck = true;</programlisting>
|
||||
|
||||
in the derivation to enable checks.</para></listitem>
|
||||
<listitem><para>
|
||||
Controls whether the check phase is executed.
|
||||
By default it is skipped, but if <varname>doCheck</varname> is set to true, the check phase is usually executed.
|
||||
Thus you should set <programlisting>doCheck = true;</programlisting> in the derivation to enable checks.
|
||||
The exception is cross compilation.
|
||||
Cross compiled builds never run tests, no matter how <varname>doCheck</varname> is set,
|
||||
as the newly-built program won't run on the platform used to build it.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
@ -916,6 +1139,20 @@ following:
|
||||
<listitem><para>If set, libraries and executables are not
|
||||
stripped. By default, they are.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>dontStripHost</varname></term>
|
||||
<listitem><para>
|
||||
Like <varname>dontStripHost</varname>, but only affects the <command>strip</command> command targetting the package's host platform.
|
||||
Useful when supporting cross compilation, but otherwise feel free to ignore.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>dontStripTarget</varname></term>
|
||||
<listitem><para>
|
||||
Like <varname>dontStripHost</varname>, but only affects the <command>strip</command> command targetting the packages' target platform.
|
||||
Useful when supporting cross compilation, but otherwise feel free to ignore.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>dontMoveSbin</varname></term>
|
||||
@ -1044,12 +1281,14 @@ installcheck</command>.</para>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>doInstallCheck</varname></term>
|
||||
<listitem><para>If set to a non-empty string, the installCheck phase is
|
||||
executed, otherwise it is skipped (default). Thus you should set
|
||||
|
||||
<programlisting>doInstallCheck = true;</programlisting>
|
||||
|
||||
in the derivation to enable install checks.</para></listitem>
|
||||
<listitem><para>
|
||||
Controls whether the installCheck phase is executed.
|
||||
By default it is skipped, but if <varname>doInstallCheck</varname> is set to true, the installCheck phase is usually executed.
|
||||
Thus you should set <programlisting>doInstallCheck = true;</programlisting> in the derivation to enable install checks.
|
||||
The exception is cross compilation.
|
||||
Cross compiled builds never run tests, no matter how <varname>doInstallCheck</varname> is set,
|
||||
as the newly-built program won't run on the platform used to build it.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
@ -1346,46 +1585,127 @@ someVar=$(stripHash $name)
|
||||
|
||||
<section xml:id="ssec-setup-hooks"><title>Package setup hooks</title>
|
||||
|
||||
<para>The following packages provide a setup hook:
|
||||
|
||||
<para>
|
||||
Nix itself considers a build-time dependency merely something that should previously be built and accessible at build time—packages themselves are on their own to perform any additional setup.
|
||||
In most cases, that is fine, and the downstream derivation can deal with it's own dependencies.
|
||||
But for a few common tasks, that would result in almost every package doing the same sort of setup work---depending not on the package itself, but entirely on which dependencies were used.
|
||||
</para>
|
||||
<para>
|
||||
In order to alleviate this burden, the <firstterm>setup hook></firstterm>mechanism was written, where any package can include a shell script that [by convention rather than enforcement by Nix], any downstream reverse-dependency will source as part of its build process.
|
||||
That allows the downstream dependency to merely specify its dependencies, and lets those dependencies effectively initialize themselves.
|
||||
No boilerplate mirroring the list of dependencies is needed.
|
||||
</para>
|
||||
<para>
|
||||
The Setup hook mechanism is a bit of a sledgehammer though: a powerful feature with a broad and indiscriminate area of effect.
|
||||
The combination of its power and implicit use may be expedient, but isn't without costs.
|
||||
Nix itself is unchanged, but the spirit of adding dependencies being effect-free is violated even if the letter isn't.
|
||||
For example, if a derivation path is mentioned more than once, Nix itself doesn't care and simply makes sure the dependency derivation is already built just the same—depending is just needing something to exist, and needing is idempotent.
|
||||
However, a dependency specified twice will have its setup hook run twice, and that could easily change the build environment (though a well-written setup hook will therefore strive to be idempotent so this is in fact not observable).
|
||||
More broadly, setup hooks are anti-modular in that multiple dependencies, whether the same or different, should not interfere and yet their setup hooks may well do so.
|
||||
</para>
|
||||
<para>
|
||||
The most typical use of the setup hook is actually to add other hooks which are then run (i.e. after all the setup hooks) on each dependency.
|
||||
For example, the C compiler wrapper's setup hook feeds itself flags for each dependency that contains relevant libaries and headers.
|
||||
This is done by defining a bash function, and appending its name to one of
|
||||
<envar>envBuildBuildHooks</envar>`,
|
||||
<envar>envBuildHostHooks</envar>`,
|
||||
<envar>envBuildTargetHooks</envar>`,
|
||||
<envar>envHostHostHooks</envar>`,
|
||||
<envar>envHostTargetHooks</envar>`, or
|
||||
<envar>envTargetTargetHooks</envar>`.
|
||||
These 6 bash variables correspond to the 6 sorts of dependencies by platform (there's 12 total but we ignore the propagated/non-propagated axis).
|
||||
</para>
|
||||
<para>
|
||||
Packages adding a hook should not hard code a specific hook, but rather choose a variable <emphasis>relative</emphasis> to how they are included.
|
||||
Returning to the C compiler wrapper example, if it itself is an <literal>n</literal> dependency, then it only wants to accumulate flags from <literal>n + 1</literal> dependencies, as only those ones match the compiler's target platform.
|
||||
The <envar>hostOffset</envar> variable is defined with the current dependency's host offset <envar>targetOffset</envar> with its target offset, before it's setup hook is sourced.
|
||||
Additionally, since most environment hooks don't care about the target platform,
|
||||
That means the setup hook can append to the right bash array by doing something like
|
||||
<programlisting language="bash">
|
||||
addEnvHooks "$hostOffset" myBashFunction
|
||||
</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
The <emphasis>existence</emphasis> of setups hooks has long been documented and packages inside Nixpkgs are free to use these mechanism.
|
||||
Other packages, however, should not rely on these mechanisms not changing between Nixpkgs versions.
|
||||
Because of the existing issues with this system, there's little benefit from mandating it be stable for any period of time.
|
||||
</para>
|
||||
<para>
|
||||
Here are some packages that provide a setup hook.
|
||||
Since the mechanism is modular, this probably isn't an exhaustive list.
|
||||
Then again, since the mechanism is only to be used as a last resort, it might be.
|
||||
<variablelist>
|
||||
|
||||
<varlistentry>
|
||||
<term>CC Wrapper</term>
|
||||
<term>Bintools Wrapper</term>
|
||||
<listitem>
|
||||
<para>
|
||||
CC Wrapper wraps a C toolchain for a bunch of miscellaneous purposes.
|
||||
Specifically, a C compiler (GCC or Clang), Binutils (or the CCTools + binutils mashup when targetting Darwin), and a C standard library (glibc or Darwin's libSystem) are all fed in, and dependency finding, hardening (see below), and purity checks for each are handled by CC Wrapper.
|
||||
Packages typically depend on only CC Wrapper, instead of those 3 inputs directly.
|
||||
Bintools Wrapper wraps the binary utilities for a bunch of miscellaneous purposes.
|
||||
These are GNU Binutils when targetting Linux, and a mix of cctools and GNU binutils for Darwin.
|
||||
[The "Bintools" name is supposed to be a compromise between "Binutils" and "cctools" not denoting any specific implementation.]
|
||||
Specifically, the underlying bintools package, and a C standard library (glibc or Darwin's libSystem, just for the dynamic loader) are all fed in, and dependency finding, hardening (see below), and purity checks for each are handled by Bintools Wrapper.
|
||||
Packages typically depend on CC Wrapper, which in turn (at run time) depends on Bintools Wrapper.
|
||||
</para>
|
||||
<para>
|
||||
Dependency finding is undoubtedly the main task of CC wrapper.
|
||||
Bintools Wrapper was only just recently split off from CC Wrapper, so the division of labor is still being worked out.
|
||||
For example, it shouldn't care about about the C standard library, but just take a derivation with the dynamic loader (which happens to be the glibc on linux).
|
||||
Dependency finding however is a task both wrappers will continue to need to share, and probably the most important to understand.
|
||||
It is currently accomplished by collecting directories of host-platform dependencies (i.e. <varname>buildInputs</varname> and <varname>nativeBuildInputs</varname>) in environment variables.
|
||||
CC wrapper's setup hook causes any <filename>include</filename> subdirectory of such a dependency to be added to <envar>NIX_CFLAGS_COMPILE</envar>, and any <filename>lib</filename> and <filename>lib64</filename> subdirectories to <envar>NIX_LDFLAGS</envar>.
|
||||
The setup hook itself contains some lengthy comments describing the exact convoluted mechanism by which this is accomplished.
|
||||
Bintools Wrapper's setup hook causes any <filename>lib</filename> and <filename>lib64</filename> subdirectories to be added to <envar>NIX_LDFLAGS</envar>.
|
||||
Since CC Wrapper and Bintools Wrapper use the same strategy, most of the Bintools Wrapper code is sparsely commented and refers to CC Wrapper.
|
||||
But CC Wrapper's code, by contrast, has quite lengthy comments.
|
||||
Bintools Wrapper merely cites those, rather than repeating them, to avoid falling out of sync.
|
||||
</para>
|
||||
<para>
|
||||
A final task of the setup hook is defining a number of standard environment variables to tell build systems which executables full-fill which purpose.
|
||||
They are defined to just be the base name of the tools, under the assumption that CC Wrapper's binaries will be on the path.
|
||||
They are defined to just be the base name of the tools, under the assumption that Bintools Wrapper's binaries will be on the path.
|
||||
Firstly, this helps poorly-written packages, e.g. ones that look for just <command>gcc</command> when <envar>CC</envar> isn't defined yet <command>clang</command> is to be used.
|
||||
Secondly, this helps packages not get confused when cross-compiling, in which case multiple CC wrappers may be simultaneous in use (targeting different platforms).
|
||||
<envar>BUILD_</envar>- and <envar>TARGET_</envar>-prefixed versions of the normal environment variable are defined for the additional CC Wrappers, properly disambiguating them.
|
||||
Secondly, this helps packages not get confused when cross-compiling, in which case multiple Bintools Wrappers may simultaneously be in use.
|
||||
<footnote><para>
|
||||
Each wrapper targets a single platform, so if binaries for multiple platforms are needed, the underlying binaries must be wrapped multiple times.
|
||||
As this is a property of the wrapper itself, the multiple wrappings are needed whether or not the same underlying binaries can target multiple platforms.
|
||||
</para></footnote>
|
||||
<envar>BUILD_</envar>- and <envar>TARGET_</envar>-prefixed versions of the normal environment variable are defined for the additional Bintools Wrappers, properly disambiguating them.
|
||||
</para>
|
||||
<para>
|
||||
A problem with this final task is that CC Wrapper is honest and defines <envar>LD</envar> as <command>ld</command>.
|
||||
A problem with this final task is that Bintools Wrapper is honest and defines <envar>LD</envar> as <command>ld</command>.
|
||||
Most packages, however, firstly use the C compiler for linking, secondly use <envar>LD</envar> anyways, defining it as the C compiler, and thirdly, only so define <envar>LD</envar> when it is undefined as a fallback.
|
||||
This triple-threat means CC Wrapper will break those packages, as LD is already defined as the actually linker which the package won't override yet doesn't want to use.
|
||||
This triple-threat means Bintools Wrapper will break those packages, as LD is already defined as the actual linker which the package won't override yet doesn't want to use.
|
||||
The workaround is to define, just for the problematic package, <envar>LD</envar> as the C compiler.
|
||||
A good way to do this would be <command>preConfigure = "LD=$CC"</command>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>CC Wrapper</term>
|
||||
<listitem>
|
||||
<para>
|
||||
CC Wrapper wraps a C toolchain for a bunch of miscellaneous purposes.
|
||||
Specifically, a C compiler (GCC or Clang), wrapped binary tools, and a C standard library (glibc or Darwin's libSystem, just for the dynamic loader) are all fed in, and dependency finding, hardening (see below), and purity checks for each are handled by CC Wrapper.
|
||||
Packages typically depend on CC Wrapper, which in turn (at run time) depends on Bintools Wrapper.
|
||||
</para>
|
||||
<para>
|
||||
Dependency finding is undoubtedly the main task of CC Wrapper.
|
||||
This works just like Bintools Wrapper, except that any <filename>include</filename> subdirectory of any relevant dependency is added to <envar>NIX_CFLAGS_COMPILE</envar>.
|
||||
The setup hook itself contains some lengthy comments describing the exact convoluted mechanism by which this is accomplished.
|
||||
</para>
|
||||
<para>
|
||||
CC Wrapper also like Bintools Wrapper defines standard environment variables with the names of the tools it wraps, for the same reasons described above.
|
||||
Importantly, while it includes a <command>cc</command> symlink to the c compiler for portability, the <envar>CC</envar> will be defined using the compiler's "real name" (i.e. <command>gcc</command> or <command>clang</command>).
|
||||
This helps lousy build systems that inspect on the name of the compiler rather than run it.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>Perl</term>
|
||||
<listitem><para>Adds the <filename>lib/site_perl</filename> subdirectory
|
||||
of each build input to the <envar>PERL5LIB</envar>
|
||||
environment variable.</para></listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Adds the <filename>lib/site_perl</filename> subdirectory of each build input to the <envar>PERL5LIB</envar> environment variable.
|
||||
For instance, if <varname>buildInputs</varname> contains Perl, then the <filename>lib/site_perl</filename> subdirectory of each input is added to the <envar>PERL5LIB</envar> environment variable.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
|
@ -93,7 +93,7 @@ let
|
||||
hiPrioSet;
|
||||
inherit (sources) pathType pathIsDirectory cleanSourceFilter
|
||||
cleanSource sourceByRegex sourceFilesBySuffices
|
||||
commitIdFromGitRepo;
|
||||
commitIdFromGitRepo cleanSourceWith;
|
||||
inherit (modules) evalModules closeModules unifyModuleSyntax
|
||||
applyIfFunction unpackSubmodule packSubmodule mergeModules
|
||||
mergeModules' mergeOptionDecls evalOptionValue mergeDefinitions
|
||||
|
@ -130,6 +130,6 @@ rec {
|
||||
(name: value:
|
||||
"${toPretty args name} = ${toPretty args value};") v)
|
||||
+ " }"
|
||||
else "toPretty: should never happen (v = ${v})";
|
||||
else abort "toPretty: should never happen (v = ${v})";
|
||||
|
||||
}
|
||||
|
@ -309,6 +309,12 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
||||
free = false;
|
||||
};
|
||||
|
||||
inria-icesl = {
|
||||
fullName = "INRIA Non-Commercial License Agreement for IceSL";
|
||||
url = "http://shapeforge.loria.fr/icesl/EULA_IceSL_binary.pdf";
|
||||
free = false;
|
||||
};
|
||||
|
||||
ipa = spdx {
|
||||
spdxId = "IPA";
|
||||
fullName = "IPA Font License";
|
||||
|
@ -28,6 +28,8 @@
|
||||
afranchuk = "Alex Franchuk <alex.franchuk@gmail.com>";
|
||||
aherrmann = "Andreas Herrmann <andreash87@gmx.ch>";
|
||||
ahmedtd = "Taahir Ahmed <ahmed.taahir@gmail.com>";
|
||||
aij = "Ivan Jager <aij+git@mrph.org>";
|
||||
ajgrf = "Alex Griffin <a@ajgrf.com>";
|
||||
ak = "Alexander Kjeldaas <ak@formalprivacy.com>";
|
||||
akaWolf = "Artjom Vejsel <akawolf0@gmail.com>";
|
||||
akc = "Anders Claesson <akc@akc.is>";
|
||||
@ -80,6 +82,7 @@
|
||||
benley = "Benjamin Staffin <benley@gmail.com>";
|
||||
bennofs = "Benno Fünfstück <benno.fuenfstueck@gmail.com>";
|
||||
benwbooth = "Ben Booth <benwbooth@gmail.com>";
|
||||
berce = "Bert Moens <bert.moens@gmail.com>";
|
||||
berdario = "Dario Bertini <berdario@gmail.com>";
|
||||
bergey = "Daniel Bergey <bergey@teallabs.org>";
|
||||
bhipple = "Benjamin Hipple <bhipple@protonmail.com>";
|
||||
@ -95,6 +98,7 @@
|
||||
bradediger = "Brad Ediger <brad@bradediger.com>";
|
||||
bramd = "Bram Duvigneau <bram@bramd.nl>";
|
||||
bstrik = "Berno Strik <dutchman55@gmx.com>";
|
||||
bugworm = "Roman Gerasimenko <bugworm@zoho.com>";
|
||||
bzizou = "Bruno Bzeznik <Bruno@bzizou.net>";
|
||||
c0bw3b = "Renaud <c0bw3b@gmail.com>";
|
||||
c0dehero = "CodeHero <codehero@nerdpol.ch>";
|
||||
@ -115,6 +119,7 @@
|
||||
ChengCat = "Yucheng Zhang <yu@cheng.cat>";
|
||||
choochootrain = "Hurshal Patel <hurshal@imap.cc>";
|
||||
chpatrick = "Patrick Chilton <chpatrick@gmail.com>";
|
||||
chreekat = "Bryan Richter <b@chreekat.net>";
|
||||
chris-martin = "Chris Martin <ch.martin@gmail.com>";
|
||||
chrisjefferson = "Christopher Jefferson <chris@bubblescope.net>";
|
||||
chrisrosset = "Christopher Rosset <chris@rosset.org.uk>";
|
||||
@ -122,7 +127,7 @@
|
||||
ciil = "Simon Lackerbauer <simon@lackerbauer.com>";
|
||||
ck3d = "Christian Kögler <ck3d@gmx.de>";
|
||||
ckampka = "Christian Kampka <christian@kampka.net>";
|
||||
ckauhaus = "Christian Kauhaus <christian@kauhaus.de>";
|
||||
ckauhaus = "Christian Kauhaus <kc@flyingcircus.io>";
|
||||
cko = "Christine Koppelt <christine.koppelt@gmail.com>";
|
||||
cleverca22 = "Michael Bishop <cleverca22@gmail.com>";
|
||||
cmcdragonkai = "Roger Qiu <roger.qiu@matrix.ai>";
|
||||
@ -186,6 +191,7 @@
|
||||
dtzWill = "Will Dietz <nix@wdtz.org>";
|
||||
dupgit = "Olivier Delhomme <olivier.delhomme@free.fr>";
|
||||
dywedir = "Vladyslav M. <dywedir@protonmail.ch>";
|
||||
dzabraev = "Maksim Dzabraev <dzabraew@gmail.com>";
|
||||
e-user = "Alexander Kahl <nixos@sodosopa.io>";
|
||||
earldouglas = "James Earl Douglas <james@earldouglas.com>";
|
||||
ebzzry = "Rommel Martinez <ebzzry@ebzzry.io>";
|
||||
@ -204,6 +210,7 @@
|
||||
elijahcaine = "Elijah Caine <elijahcainemv@gmail.com>";
|
||||
elitak = "Eric Litak <elitak@gmail.com>";
|
||||
ellis = "Ellis Whitehead <nixos@ellisw.net>";
|
||||
enzime = "Michael Hoang <enzime@users.noreply.github.com>";
|
||||
eperuffo = "Emanuele Peruffo <info@emanueleperuffo.com>";
|
||||
epitrochoid = "Mabry Cervin <mpcervin@uncg.edu>";
|
||||
eqyiel = "Ruben Maher <r@rkm.id.au>";
|
||||
@ -279,15 +286,18 @@
|
||||
hodapp = "Chris Hodapp <hodapp87@gmail.com>";
|
||||
hrdinka = "Christoph Hrdinka <c.nix@hrdinka.at>";
|
||||
htr = "Hugo Tavares Reis <hugo@linux.com>";
|
||||
hyphon81 = "Masato Yonekawa <zero812n@gmail.com>";
|
||||
iand675 = "Ian Duncan <ian@iankduncan.com>";
|
||||
ianwookim = "Ian-Woo Kim <ianwookim@gmail.com>";
|
||||
iblech = "Ingo Blechschmidt <iblech@speicherleck.de>";
|
||||
igsha = "Igor Sharonov <igor.sharonov@gmail.com>";
|
||||
ikervagyok = "Balázs Lengyel <ikervagyok@gmail.com>";
|
||||
ilya-kolpakov = "Ilya Kolpakov <ilya.kolpakov@gmail.com>";
|
||||
infinisil = "Silvan Mosberger <infinisil@icloud.com>";
|
||||
ironpinguin = "Michele Catalano <michele@catalano.de>";
|
||||
ivan-tkatchev = "Ivan Tkatchev <tkatchev@gmail.com>";
|
||||
ixmatus = "Parnell Springmeyer <parnell@digitalmentat.com>";
|
||||
izorkin = "Yurii Izorkin <Izorkin@gmail.com>";
|
||||
j-keck = "Jürgen Keck <jhyphenkeck@gmail.com>";
|
||||
jagajaga = "Arseniy Seroka <ars.seroka@gmail.com>";
|
||||
jammerful = "jammerful <jammerful@gmail.com>";
|
||||
@ -319,6 +329,7 @@
|
||||
joko = "Ioannis Koutras <ioannis.koutras@gmail.com>";
|
||||
jonafato = "Jon Banafato <jon@jonafato.com>";
|
||||
joncojonathan = "Jonathan Haddock <joncojonathan@gmail.com>";
|
||||
jpdoyle = "Joe Doyle <joethedoyle@gmail.com>";
|
||||
jpierre03 = "Jean-Pierre PRUNARET <nix@prunetwork.fr>";
|
||||
jpotier = "Martin Potier <jpo.contributes.to.nixos@marvid.fr>";
|
||||
jraygauthier = "Raymond Gauthier <jraygauthier@gmail.com>";
|
||||
@ -354,6 +365,7 @@
|
||||
ldesgoui = "Lucas Desgouilles <ldesgoui@gmail.com>";
|
||||
league = "Christopher League <league@contrapunctus.net>";
|
||||
lebastr = "Alexander Lebedev <lebastr@gmail.com>";
|
||||
ledif = "Adam Fidel <refuse@gmail.com>";
|
||||
leemachin = "Lee Machin <me@mrl.ee>";
|
||||
leenaars = "Michiel Leenaars <ml.software@leenaa.rs>";
|
||||
leonardoce = "Leonardo Cecchi <leonardo.cecchi@gmail.com>";
|
||||
@ -389,6 +401,7 @@
|
||||
manveru = "Michael Fellinger <m.fellinger@gmail.com>";
|
||||
marcweber = "Marc Weber <marco-oweber@gmx.de>";
|
||||
markus1189 = "Markus Hauck <markus1189@gmail.com>";
|
||||
markuskowa = "Markus Kowalewski <markus.kowalewski@gmail.com>";
|
||||
markWot = "Markus Wotringer <markus@wotringer.de>";
|
||||
martijnvermaat = "Martijn Vermaat <martijn@vermaat.name>";
|
||||
martingms = "Martin Gammelsæter <martin@mg.am>";
|
||||
@ -400,6 +413,7 @@
|
||||
mbakke = "Marius Bakke <mbakke@fastmail.com>";
|
||||
mbbx6spp = "Susan Potter <me@susanpotter.net>";
|
||||
mbe = "Brandon Edens <brandonedens@gmail.com>";
|
||||
mbode = "Maximilian Bode <maxbode@gmail.com>";
|
||||
mboes = "Mathieu Boespflug <mboes@tweag.net>";
|
||||
mbrgm = "Marius Bergmann <marius@yeai.de>";
|
||||
mcmtroffaes = "Matthias C. M. Troffaes <matthias.troffaes@gmail.com>";
|
||||
@ -409,6 +423,7 @@
|
||||
meisternu = "Matt Miemiec <meister@krutt.org>";
|
||||
metabar = "Celine Mercier <softs@metabarcoding.org>";
|
||||
mgdelacroix = "Miguel de la Cruz <mgdelacroix@gmail.com>";
|
||||
mgttlinger = "Merlin Göttlinger <megoettlinger@gmail.com";
|
||||
mguentner = "Maximilian Güntner <code@klandest.in>";
|
||||
mic92 = "Jörg Thalheim <joerg@thalheim.io>";
|
||||
michaelpj = "Michael Peyton Jones <michaelpj@gmail.com>";
|
||||
@ -425,10 +440,12 @@
|
||||
mjanczyk = "Marcin Janczyk <m@dragonvr.pl>";
|
||||
mjp = "Mike Playle <mike@mythik.co.uk>"; # github = "MikePlayle";
|
||||
mlieberman85 = "Michael Lieberman <mlieberman85@gmail.com>";
|
||||
moaxcp = "John Mercier <moaxcp@gmail.com>";
|
||||
modulistic = "Pablo Costa <modulistic@gmail.com>";
|
||||
mog = "Matthew O'Gorman <mog-lists@rldn.net>";
|
||||
montag451 = "montag451 <montag451@laposte.net>";
|
||||
moosingin3space = "Nathan Moos <moosingin3space@gmail.com>";
|
||||
moredread = "André-Patrick Bubel <code@apb.name>";
|
||||
moretea = "Maarten Hoogendoorn <maarten@moretea.nl>";
|
||||
mornfall = "Petr Ročkai <me@mornfall.net>";
|
||||
MostAwesomeDude = "Corbin Simpson <cds@corbinsimpson.com>";
|
||||
@ -440,6 +457,7 @@
|
||||
mrVanDalo = "Ingolf Wanger <contact@ingolf-wagner.de>";
|
||||
msackman = "Matthew Sackman <matthew@wellquite.org>";
|
||||
mschristiansen = "Mikkel Christiansen <mikkel@rheosystems.com>";
|
||||
mstarzyk = "Maciek Starzyk <mstarzyk@gmail.com>";
|
||||
msteen = "Matthijs Steen <emailmatthijs@gmail.com>";
|
||||
mt-caret = "Masayuki Takeda <mtakeda.enigsol@gmail.com>";
|
||||
mtreskin = "Max Treskin <zerthurd@gmail.com>";
|
||||
@ -512,6 +530,7 @@
|
||||
plcplc = "Philip Lykke Carlsen <plcplc@gmail.com>";
|
||||
plumps = "Maksim Bronsky <maks.bronsky@web.de";
|
||||
pmahoney = "Patrick Mahoney <pat@polycrystal.org>";
|
||||
pmeunier = "Pierre-Étienne Meunier <pierre-etienne.meunier@inria.fr>";
|
||||
pmiddend = "Philipp Middendorf <pmidden@secure.mailbox.org>";
|
||||
polyrod = "Maurizio Di Pietro <dc1mdp@gmail.com>";
|
||||
pradeepchhetri = "Pradeep Chhetri <pradeep.chhetri89@gmail.com>";
|
||||
@ -563,10 +582,11 @@
|
||||
rushmorem = "Rushmore Mushambi <rushmore@webenchanter.com>";
|
||||
rvl = "Rodney Lorrimar <dev+nix@rodney.id.au>";
|
||||
rvlander = "Gaëtan André <rvlander@gaetanandre.eu>";
|
||||
rvolosatovs = "Roman Volosatovs <rvolosatovs@riseup.net";
|
||||
rvolosatovs = "Roman Volosatovs <rvolosatovs@riseup.net>";
|
||||
ryanartecona = "Ryan Artecona <ryanartecona@gmail.com>";
|
||||
ryansydnor = "Ryan Sydnor <ryan.t.sydnor@gmail.com>";
|
||||
ryantm = "Ryan Mulligan <ryan@ryantm.com>";
|
||||
ryantrinkle = "Ryan Trinkle <ryan.trinkle@gmail.com>";
|
||||
rybern = "Ryan Bernstein <ryan.bernstein@columbia.edu>";
|
||||
rycee = "Robert Helgesson <robert@rycee.net>";
|
||||
ryneeverett = "Ryne Everett <ryneeverett@gmail.com>";
|
||||
@ -641,6 +661,7 @@
|
||||
tex = "Milan Svoboda <milan.svoboda@centrum.cz>";
|
||||
thall = "Niclas Thall <niclas.thall@gmail.com>";
|
||||
thammers = "Tobias Hammerschmidt <jawr@gmx.de>";
|
||||
thanegill = "Thane Gill <me@thanegill.com>";
|
||||
the-kenny = "Moritz Ulrich <moritz@tarn-vedra.de>";
|
||||
theuni = "Christian Theune <ct@flyingcircus.io>";
|
||||
ThomasMader = "Thomas Mader <thomas.mader@gmail.com>";
|
||||
@ -648,6 +669,7 @@
|
||||
thpham = "Thomas Pham <thomas.pham@ithings.ch>";
|
||||
timbertson = "Tim Cuthbertson <tim@gfxmonk.net>";
|
||||
timokau = "Timo Kaufmann <timokau@zoho.com>";
|
||||
tiramiseb = "Sébastien Maccagnoni <sebastien@maccagnoni.eu>";
|
||||
titanous = "Jonathan Rudenberg <jonathan@titanous.com>";
|
||||
tnias = "Philipp Bartsch <phil@grmr.de>";
|
||||
tohl = "Tomas Hlavaty <tom@logand.com>";
|
||||
@ -677,7 +699,9 @@
|
||||
vbmithr = "Vincent Bernardoff <vb@luminar.eu.org>";
|
||||
vcunat = "Vladimír Čunát <vcunat@gmail.com>";
|
||||
vdemeester = "Vincent Demeester <vincent@sbr.pm>";
|
||||
velovix = "Tyler Compton <xaviosx@gmail.com>";
|
||||
veprbl = "Dmitry Kalinkin <veprbl@gmail.com>";
|
||||
vidbina = "David Asabina <vid@bina.me>";
|
||||
vifino = "Adrian Pistol <vifino@tty.sh>";
|
||||
vinymeuh = "VinyMeuh <vinymeuh@gmail.com>";
|
||||
viric = "Lluís Batlle i Rossell <viric@viric.name>";
|
||||
|
@ -26,14 +26,35 @@ rec {
|
||||
(type == "symlink" && lib.hasPrefix "result" baseName)
|
||||
);
|
||||
|
||||
cleanSource = builtins.filterSource cleanSourceFilter;
|
||||
cleanSource = src: cleanSourceWith { filter = cleanSourceFilter; inherit src; };
|
||||
|
||||
# Like `builtins.filterSource`, except it will compose with itself,
|
||||
# allowing you to chain multiple calls together without any
|
||||
# intermediate copies being put in the nix store.
|
||||
#
|
||||
# lib.cleanSourceWith f (lib.cleanSourceWith g ./.) # Succeeds!
|
||||
# builtins.filterSource f (builtins.filterSource g ./.) # Fails!
|
||||
cleanSourceWith = { filter, src }:
|
||||
let
|
||||
isFiltered = src ? _isLibCleanSourceWith;
|
||||
origSrc = if isFiltered then src.origSrc else src;
|
||||
filter' = if isFiltered then name: type: filter name type && src.filter name type else filter;
|
||||
in {
|
||||
inherit origSrc;
|
||||
filter = filter';
|
||||
outPath = builtins.filterSource filter' origSrc;
|
||||
_isLibCleanSourceWith = true;
|
||||
};
|
||||
|
||||
# Filter sources by a list of regular expressions.
|
||||
#
|
||||
# E.g. `src = sourceByRegex ./my-subproject [".*\.py$" "^database.sql$"]`
|
||||
sourceByRegex = src: regexes: builtins.filterSource (path: type:
|
||||
let relPath = lib.removePrefix (toString src + "/") (toString path);
|
||||
in lib.any (re: builtins.match re relPath != null) regexes) src;
|
||||
sourceByRegex = src: regexes: cleanSourceWith {
|
||||
filter = (path: type:
|
||||
let relPath = lib.removePrefix (toString src + "/") (toString path);
|
||||
in lib.any (re: builtins.match re relPath != null) regexes);
|
||||
inherit src;
|
||||
};
|
||||
|
||||
# Get all files ending with the specified suffices from the given
|
||||
# directory or its descendants. E.g. `sourceFilesBySuffices ./dir
|
||||
@ -42,7 +63,7 @@ rec {
|
||||
let filter = name: type:
|
||||
let base = baseNameOf (toString name);
|
||||
in type == "directory" || lib.any (ext: lib.hasSuffix ext base) exts;
|
||||
in builtins.filterSource filter path;
|
||||
in cleanSourceWith { inherit filter; src = path; };
|
||||
|
||||
|
||||
# Get the commit id of a git repo
|
||||
|
@ -219,6 +219,14 @@ rec {
|
||||
*/
|
||||
escapeShellArgs = concatMapStringsSep " " escapeShellArg;
|
||||
|
||||
/* Turn a string into a Nix expression representing that string
|
||||
|
||||
Example:
|
||||
escapeNixString "hello\${}\n"
|
||||
=> "\"hello\\\${}\\n\""
|
||||
*/
|
||||
escapeNixString = s: escape ["$"] (builtins.toJSON s);
|
||||
|
||||
/* Obsolete - use replaceStrings instead. */
|
||||
replaceChars = builtins.replaceStrings or (
|
||||
del: new: s:
|
||||
|
@ -18,7 +18,6 @@ rec {
|
||||
libc = "glibc";
|
||||
platform = platforms.sheevaplug;
|
||||
openssl.system = "linux-generic32";
|
||||
inherit (platform) gcc;
|
||||
};
|
||||
|
||||
raspberryPi = rec {
|
||||
@ -31,7 +30,6 @@ rec {
|
||||
libc = "glibc";
|
||||
platform = platforms.raspberrypi;
|
||||
openssl.system = "linux-generic32";
|
||||
inherit (platform) gcc;
|
||||
};
|
||||
|
||||
armv7l-hf-multiplatform = rec {
|
||||
@ -44,7 +42,6 @@ rec {
|
||||
libc = "glibc";
|
||||
platform = platforms.armv7l-hf-multiplatform;
|
||||
openssl.system = "linux-generic32";
|
||||
inherit (platform) gcc;
|
||||
};
|
||||
|
||||
aarch64-multiplatform = rec {
|
||||
@ -54,23 +51,20 @@ rec {
|
||||
withTLS = true;
|
||||
libc = "glibc";
|
||||
platform = platforms.aarch64-multiplatform;
|
||||
inherit (platform) gcc;
|
||||
};
|
||||
|
||||
scaleway-c1 = armv7l-hf-multiplatform // rec {
|
||||
platform = platforms.scaleway-c1;
|
||||
inherit (platform) gcc;
|
||||
inherit (gcc) fpu;
|
||||
inherit (platform.gcc) fpu;
|
||||
};
|
||||
|
||||
pogoplug4 = rec {
|
||||
arch = "armv5tel";
|
||||
config = "armv5tel-softfloat-linux-gnueabi";
|
||||
config = "armv5tel-unknown-linux-gnueabi";
|
||||
float = "soft";
|
||||
|
||||
platform = platforms.pogoplug4;
|
||||
|
||||
inherit (platform) gcc;
|
||||
libc = "glibc";
|
||||
|
||||
withTLS = true;
|
||||
@ -86,7 +80,6 @@ rec {
|
||||
libc = "glibc";
|
||||
platform = platforms.fuloong2f_n32;
|
||||
openssl.system = "linux-generic32";
|
||||
inherit (platform) gcc;
|
||||
};
|
||||
|
||||
#
|
||||
|
@ -174,6 +174,13 @@ rec {
|
||||
merge = mergeOneOption;
|
||||
};
|
||||
|
||||
strMatching = pattern: mkOptionType {
|
||||
name = "strMatching ${escapeNixString pattern}";
|
||||
description = "string matching the pattern ${pattern}";
|
||||
check = x: str.check x && builtins.match pattern x != null;
|
||||
inherit (str) merge;
|
||||
};
|
||||
|
||||
# Merge multiple definitions by concatenating them (with the given
|
||||
# separator between the values).
|
||||
separatedString = sep: mkOptionType rec {
|
||||
|
@ -1,5 +1,5 @@
|
||||
#! /usr/bin/env nix-shell
|
||||
#! nix-shell -i perl -p perl perlPackages.NetAmazonS3 perlPackages.FileSlurp nixUnstable
|
||||
#! nix-shell -i perl -p perl perlPackages.NetAmazonS3 perlPackages.FileSlurp nixUnstable nixUnstable.perl-bindings
|
||||
|
||||
# This command uploads tarballs to tarballs.nixos.org, the
|
||||
# content-addressed cache used by fetchurl as a fallback for when
|
||||
@ -59,6 +59,7 @@ my $s3 = Net::Amazon::S3->new(
|
||||
{ aws_access_key_id => $aws_access_key_id,
|
||||
aws_secret_access_key => $aws_secret_access_key,
|
||||
retry => 1,
|
||||
host => "s3-eu-west-1.amazonaws.com",
|
||||
});
|
||||
|
||||
my $bucket = $s3->bucket("nixpkgs-tarballs") or die;
|
||||
|
@ -1,5 +1,5 @@
|
||||
#! /usr/bin/env nix-shell
|
||||
#! nix-shell -i python3 -p 'python3.withPackages(ps: with ps; [ requests toolz ])'
|
||||
#! 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.
|
||||
@ -18,7 +18,12 @@ import os
|
||||
import re
|
||||
import requests
|
||||
import toolz
|
||||
from concurrent.futures import ThreadPoolExecutor as pool
|
||||
from concurrent.futures import ThreadPoolExecutor as Pool
|
||||
from packaging.version import Version as _Version
|
||||
from packaging.version import InvalidVersion
|
||||
from packaging.specifiers import SpecifierSet
|
||||
import collections
|
||||
import subprocess
|
||||
|
||||
INDEX = "https://pypi.io/pypi"
|
||||
"""url of PyPI"""
|
||||
@ -26,10 +31,30 @@ INDEX = "https://pypi.io/pypi"
|
||||
EXTENSIONS = ['tar.gz', 'tar.bz2', 'tar', 'zip', '.whl']
|
||||
"""Permitted file extensions. These are evaluated from left to right and the first occurance is returned."""
|
||||
|
||||
PRERELEASES = False
|
||||
|
||||
import logging
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
|
||||
class Version(_Version, collections.abc.Sequence):
|
||||
|
||||
def __init__(self, version):
|
||||
super().__init__(version)
|
||||
# We cannot use `str(Version(0.04.21))` because that becomes `0.4.21`
|
||||
# https://github.com/avian2/unidecode/issues/13#issuecomment-354538882
|
||||
self.raw_version = version
|
||||
|
||||
def __getitem__(self, i):
|
||||
return self._version.release[i]
|
||||
|
||||
def __len__(self):
|
||||
return len(self._version.release)
|
||||
|
||||
def __iter__(self):
|
||||
yield from self._version.release
|
||||
|
||||
|
||||
def _get_values(attribute, text):
|
||||
"""Match attribute in text and return all matches.
|
||||
|
||||
@ -82,13 +107,59 @@ def _fetch_page(url):
|
||||
else:
|
||||
raise ValueError("request for {} failed".format(url))
|
||||
|
||||
def _get_latest_version_pypi(package, extension):
|
||||
|
||||
SEMVER = {
|
||||
'major' : 0,
|
||||
'minor' : 1,
|
||||
'patch' : 2,
|
||||
}
|
||||
|
||||
|
||||
def _determine_latest_version(current_version, target, versions):
|
||||
"""Determine latest version, given `target`.
|
||||
"""
|
||||
current_version = Version(current_version)
|
||||
|
||||
def _parse_versions(versions):
|
||||
for v in versions:
|
||||
try:
|
||||
yield Version(v)
|
||||
except InvalidVersion:
|
||||
pass
|
||||
|
||||
versions = _parse_versions(versions)
|
||||
|
||||
index = SEMVER[target]
|
||||
|
||||
ceiling = list(current_version[0:index])
|
||||
if len(ceiling) == 0:
|
||||
ceiling = None
|
||||
else:
|
||||
ceiling[-1]+=1
|
||||
ceiling = Version(".".join(map(str, ceiling)))
|
||||
|
||||
# We do not want prereleases
|
||||
versions = SpecifierSet(prereleases=PRERELEASES).filter(versions)
|
||||
|
||||
if ceiling is not None:
|
||||
versions = SpecifierSet(f"<{ceiling}").filter(versions)
|
||||
|
||||
return (max(sorted(versions))).raw_version
|
||||
|
||||
|
||||
def _get_latest_version_pypi(package, extension, current_version, target):
|
||||
"""Get latest version and hash from PyPI."""
|
||||
url = "{}/{}/json".format(INDEX, package)
|
||||
json = _fetch_page(url)
|
||||
|
||||
version = json['info']['version']
|
||||
for release in json['releases'][version]:
|
||||
versions = json['releases'].keys()
|
||||
version = _determine_latest_version(current_version, target, versions)
|
||||
|
||||
try:
|
||||
releases = json['releases'][version]
|
||||
except KeyError as e:
|
||||
raise KeyError('Could not find version {} for {}'.format(version, package)) from e
|
||||
for release in releases:
|
||||
if release['filename'].endswith(extension):
|
||||
# TODO: In case of wheel we need to do further checks!
|
||||
sha256 = release['digests']['sha256']
|
||||
@ -98,7 +169,7 @@ def _get_latest_version_pypi(package, extension):
|
||||
return version, sha256
|
||||
|
||||
|
||||
def _get_latest_version_github(package, extension):
|
||||
def _get_latest_version_github(package, extension, current_version, target):
|
||||
raise ValueError("updating from GitHub is not yet supported.")
|
||||
|
||||
|
||||
@ -141,9 +212,9 @@ def _determine_extension(text, fetcher):
|
||||
"""
|
||||
if fetcher == 'fetchPypi':
|
||||
try:
|
||||
format = _get_unique_value('format', text)
|
||||
src_format = _get_unique_value('format', text)
|
||||
except ValueError as e:
|
||||
format = None # format was not given
|
||||
src_format = None # format was not given
|
||||
|
||||
try:
|
||||
extension = _get_unique_value('extension', text)
|
||||
@ -151,9 +222,11 @@ def _determine_extension(text, fetcher):
|
||||
extension = None # extension was not given
|
||||
|
||||
if extension is None:
|
||||
if format is None:
|
||||
format = 'setuptools'
|
||||
extension = FORMATS[format]
|
||||
if src_format is None:
|
||||
src_format = 'setuptools'
|
||||
elif src_format == 'flit':
|
||||
raise ValueError("Don't know how to update a Flit package.")
|
||||
extension = FORMATS[src_format]
|
||||
|
||||
elif fetcher == 'fetchurl':
|
||||
url = _get_unique_value('url', text)
|
||||
@ -167,9 +240,7 @@ def _determine_extension(text, fetcher):
|
||||
return extension
|
||||
|
||||
|
||||
def _update_package(path):
|
||||
|
||||
|
||||
def _update_package(path, target):
|
||||
|
||||
# Read the expression
|
||||
with open(path, 'r') as f:
|
||||
@ -186,11 +257,13 @@ def _update_package(path):
|
||||
|
||||
extension = _determine_extension(text, fetcher)
|
||||
|
||||
new_version, new_sha256 = _get_latest_version_pypi(pname, extension)
|
||||
new_version, new_sha256 = FETCHERS[fetcher](pname, extension, version, target)
|
||||
|
||||
if new_version == version:
|
||||
logging.info("Path {}: no update available for {}.".format(path, pname))
|
||||
return False
|
||||
elif new_version <= version:
|
||||
raise ValueError("downgrade for {}.".format(pname))
|
||||
if not new_sha256:
|
||||
raise ValueError("no file available for {}.".format(pname))
|
||||
|
||||
@ -202,10 +275,19 @@ def _update_package(path):
|
||||
|
||||
logging.info("Path {}: updated {} from {} to {}".format(path, pname, version, new_version))
|
||||
|
||||
return True
|
||||
result = {
|
||||
'path' : path,
|
||||
'target': target,
|
||||
'pname': pname,
|
||||
'old_version' : version,
|
||||
'new_version' : new_version,
|
||||
#'fetcher' : fetcher,
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def _update(path):
|
||||
def _update(path, target):
|
||||
|
||||
# We need to read and modify a Nix expression.
|
||||
if os.path.isdir(path):
|
||||
@ -222,24 +304,58 @@ def _update(path):
|
||||
return False
|
||||
|
||||
try:
|
||||
return _update_package(path)
|
||||
return _update_package(path, target)
|
||||
except ValueError as e:
|
||||
logging.warning("Path {}: {}".format(path, e))
|
||||
return False
|
||||
|
||||
|
||||
def _commit(path, pname, old_version, new_version, **kwargs):
|
||||
"""Commit result.
|
||||
"""
|
||||
|
||||
msg = f'python: {pname}: {old_version} -> {new_version}'
|
||||
|
||||
try:
|
||||
subprocess.check_call(['git', 'add', path])
|
||||
subprocess.check_call(['git', 'commit', '-m', msg])
|
||||
except subprocess.CalledProcessError as e:
|
||||
subprocess.check_call(['git', 'checkout', path])
|
||||
raise subprocess.CalledProcessError(f'Could not commit {path}') from e
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('package', type=str, nargs='+')
|
||||
parser.add_argument('--target', type=str, choices=SEMVER.keys(), default='major')
|
||||
parser.add_argument('--commit', action='store_true', help='Create a commit for each package update')
|
||||
|
||||
args = parser.parse_args()
|
||||
target = args.target
|
||||
|
||||
packages = map(os.path.abspath, args.package)
|
||||
packages = list(map(os.path.abspath, args.package))
|
||||
|
||||
logging.info("Updating packages...")
|
||||
|
||||
# Use threads to update packages concurrently
|
||||
with Pool() as p:
|
||||
results = list(p.map(lambda pkg: _update(pkg, target), packages))
|
||||
|
||||
logging.info("Finished updating packages.")
|
||||
|
||||
# Commits are created sequentially.
|
||||
if args.commit:
|
||||
logging.info("Committing updates...")
|
||||
list(map(lambda x: _commit(**x), filter(bool, results)))
|
||||
logging.info("Finished committing updates")
|
||||
|
||||
count = sum(map(bool, results))
|
||||
logging.info("{} package(s) updated".format(count))
|
||||
|
||||
with pool() as p:
|
||||
count = list(p.map(_update, packages))
|
||||
|
||||
logging.info("{} package(s) updated".format(sum(count)))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -23,10 +23,23 @@ networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||
</programlisting>
|
||||
|
||||
Note that TCP port 22 (ssh) is opened automatically if the SSH daemon
|
||||
is enabled (<option>services.openssh.enable = true</option>). UDP
|
||||
is enabled (<option>services.openssh.enable = true</option>). UDP
|
||||
ports can be opened through
|
||||
<option>networking.firewall.allowedUDPPorts</option>. Also of
|
||||
interest is
|
||||
<option>networking.firewall.allowedUDPPorts</option>.</para>
|
||||
|
||||
<para>To open ranges of TCP ports:
|
||||
|
||||
<programlisting>
|
||||
networking.firewall.allowedTCPPortRanges = [
|
||||
{ from = 4000; to = 4007; }
|
||||
{ from = 8000; to = 8010; }
|
||||
];
|
||||
</programlisting>
|
||||
|
||||
Similarly, UDP port ranges can be opened through
|
||||
<option>networking.firewall.allowedUDPPortRanges</option>.</para>
|
||||
|
||||
<para>Also of interest is
|
||||
|
||||
<programlisting>
|
||||
networking.firewall.allowPing = true;
|
||||
|
@ -115,13 +115,14 @@ hardware.opengl.driSupport32Bit = true;
|
||||
<para>Support for Synaptics touchpads (found in many laptops such as
|
||||
the Dell Latitude series) can be enabled as follows:
|
||||
<programlisting>
|
||||
services.xserver.synaptics.enable = true;
|
||||
services.xserver.libinput.enable = true;
|
||||
</programlisting>
|
||||
The driver has many options (see <xref linkend="ch-options"/>). For
|
||||
instance, the following enables two-finger scrolling:
|
||||
instance, the following disables tap-to-click behavior:
|
||||
<programlisting>
|
||||
services.xserver.synaptics.twoFingerScroll = true;
|
||||
services.xserver.libinput.tapping = false;
|
||||
</programlisting>
|
||||
Note: the use of <literal>services.xserver.synaptics</literal> is deprecated since NixOS 17.09.
|
||||
</para>
|
||||
|
||||
</simplesect>
|
||||
@ -129,7 +130,7 @@ services.xserver.synaptics.twoFingerScroll = true;
|
||||
<simplesect><title>GTK/Qt themes</title>
|
||||
|
||||
<para>GTK themes can be installed either to user profile or system-wide (via
|
||||
<literal>system.environmentPackages</literal>). To make Qt 5 applications look similar
|
||||
<literal>environment.systemPackages</literal>). To make Qt 5 applications look similar
|
||||
to GTK2 ones, you can install <literal>qt5.qtbase.gtk</literal> package into your
|
||||
system environment. It should work for all Qt 5 library versions.
|
||||
</para>
|
||||
|
@ -22,6 +22,15 @@ options = {
|
||||
};
|
||||
</programlisting>
|
||||
|
||||
The attribute names within the <replaceable>name</replaceable>
|
||||
attribute path must be camel cased in general but should, as an
|
||||
exception, match the
|
||||
<link
|
||||
xlink:href="https://nixos.org/nixpkgs/manual/#sec-package-naming">
|
||||
package attribute name</link> when referencing a Nixpkgs package. For
|
||||
example, the option <varname>services.nix-serve.bindAddress</varname>
|
||||
references the <varname>nix-serve</varname> Nixpkgs package.
|
||||
|
||||
</para>
|
||||
|
||||
<para>The function <varname>mkOption</varname> accepts the following arguments.
|
||||
|
@ -110,6 +110,12 @@
|
||||
<listitem><para>A string. Multiple definitions are concatenated with a
|
||||
collon <literal>":"</literal>.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>types.strMatching</varname></term>
|
||||
<listitem><para>A string matching a specific regular expression. Multiple
|
||||
definitions cannot be merged. The regular expression is processed using
|
||||
<literal>builtins.match</literal>.</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
</section>
|
||||
|
@ -272,8 +272,37 @@ startAll;
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><methodname>systemctl</methodname></term>
|
||||
<listitem>
|
||||
<para>Runs <literal>systemctl</literal> commands with optional support for
|
||||
<literal>systemctl --user</literal></para>
|
||||
<para>
|
||||
<programlisting>
|
||||
$machine->systemctl("list-jobs --no-pager"); // runs `systemctl list-jobs --no-pager`
|
||||
$machine->systemctl("list-jobs --no-pager", "any-user"); // spawns a shell for `any-user` and runs `systemctl --user list-jobs --no-pager`
|
||||
</programlisting>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To test user units declared by <literal>systemd.user.services</literal> the optional <literal>$user</literal>
|
||||
argument can be used:
|
||||
|
||||
<programlisting>
|
||||
$machine->start;
|
||||
$machine->waitForX;
|
||||
$machine->waitForUnit("xautolock.service", "x-session-user");
|
||||
</programlisting>
|
||||
|
||||
This applies to <literal>systemctl</literal>, <literal>getUnitInfo</literal>,
|
||||
<literal>waitForUnit</literal>, <literal>startJob</literal>
|
||||
and <literal>stopJob</literal>.
|
||||
</para>
|
||||
|
||||
</section>
|
||||
|
@ -1,48 +0,0 @@
|
||||
<section 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="sec-uefi-installation">
|
||||
|
||||
<title>UEFI Installation</title>
|
||||
|
||||
<para>NixOS can also be installed on UEFI systems. The procedure
|
||||
is by and large the same as a BIOS installation, with the following
|
||||
changes:
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>You should boot the live CD in UEFI mode (consult your
|
||||
specific hardware's documentation for instructions). You may find
|
||||
the <link
|
||||
xlink:href="http://www.rodsbooks.com/refind">rEFInd
|
||||
boot manager</link> useful.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Instead of <command>fdisk</command>, you should use
|
||||
<command>gdisk</command> to partition your disks. You will need to
|
||||
have a separate partition for <filename>/boot</filename> with
|
||||
partition code EF00, and it should be formatted as a
|
||||
<literal>vfat</literal> filesystem.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Instead of <option>boot.loader.grub.device</option>,
|
||||
you must set <option>boot.loader.systemd-boot.enable</option> to
|
||||
<literal>true</literal>. <command>nixos-generate-config</command>
|
||||
should do this automatically for new configurations when booted in
|
||||
UEFI mode.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>After having mounted your installation partition to
|
||||
<code>/mnt</code>, you must mount the <code>boot</code> partition
|
||||
to <code>/mnt/boot</code>.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>You may want to look at the options starting with
|
||||
<option>boot.loader.efi</option> and <option>boot.loader.systemd-boot</option>
|
||||
as well.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
</section>
|
@ -11,10 +11,24 @@ a USB stick. You can use the <command>dd</command> utility to write the image:
|
||||
<command>dd if=<replaceable>path-to-image</replaceable>
|
||||
of=<replaceable>/dev/sdb</replaceable></command>. Be careful about specifying the
|
||||
correct drive; you can use the <command>lsblk</command> command to get a list of
|
||||
block devices. If you're on macOS you can run <command>diskutil list</command>
|
||||
to see the list of devices; the device you'll use for the USB must be ejected
|
||||
before writing the image.</para>
|
||||
block devices.</para>
|
||||
|
||||
<para>On macOS:
|
||||
<programlisting>
|
||||
$ diskutil list
|
||||
[..]
|
||||
/dev/diskN (external, physical):
|
||||
#: TYPE NAME SIZE IDENTIFIER
|
||||
[..]
|
||||
$ diskutil unmountDisk diskN
|
||||
Unmount of all volumes on diskN was successful
|
||||
$ sudo dd bs=1m if=nix.iso of=/dev/rdiskN
|
||||
</programlisting>
|
||||
Using the 'raw' <command>rdiskN</command> device instead of <command>diskN</command>
|
||||
completes in minutes instead of hours. After <command>dd</command> completes, a GUI
|
||||
dialog "The disk you inserted was not readable by this computer" will pop up, which
|
||||
can be ignored.</para>
|
||||
|
||||
<para>The <command>dd</command> utility will write the image verbatim to the drive,
|
||||
making it the recommended option for both UEFI and non-UEFI installations. For
|
||||
non-UEFI installations, you can alternatively use
|
||||
|
@ -6,9 +6,18 @@
|
||||
|
||||
<title>Installing NixOS</title>
|
||||
|
||||
<para>NixOS can be installed on BIOS or UEFI systems. The procedure
|
||||
for a UEFI installation is by and large the same as a BIOS installation. The differences are mentioned in the steps that follow.</para>
|
||||
|
||||
<orderedlist>
|
||||
|
||||
<listitem><para>Boot from the CD.</para></listitem>
|
||||
<listitem><para>Boot from the CD.</para>
|
||||
<variablelist>
|
||||
<varlistentry><term>UEFI systems</term>
|
||||
<listitem><para>You should boot the live CD in UEFI mode
|
||||
(consult your specific hardware's documentation for instructions).
|
||||
You may find the <link xlink:href="http://www.rodsbooks.com/refind">rEFInd boot
|
||||
manager</link> useful.</para></listitem></varlistentry></variablelist></listitem>
|
||||
|
||||
<listitem><para>The CD contains a basic NixOS installation. (It
|
||||
also contains Memtest86+, useful if you want to test new hardware).
|
||||
@ -50,7 +59,31 @@
|
||||
<itemizedlist>
|
||||
|
||||
<listitem><para>For partitioning:
|
||||
<command>fdisk</command>.</para></listitem>
|
||||
<command>fdisk</command>.
|
||||
<screen>
|
||||
# fdisk /dev/sda # <lineannotation>(or whatever device you want to install on)</lineannotation>
|
||||
-- for UEFI systems only
|
||||
> n # <lineannotation>(create a new partition for /boot)</lineannotation>
|
||||
> 3 # <lineannotation>(make it a partition number 3)</lineannotation>
|
||||
> # <lineannotation>(press enter to accept the default)</lineannotation>
|
||||
> +512M # <lineannotation>(the size of the UEFI boot partition)</lineannotation>
|
||||
> t # <lineannotation>(change the partition type ...)</lineannotation>
|
||||
> 3 # <lineannotation>(... of the boot partition ...)</lineannotation>
|
||||
> 1 # <lineannotation>(... to 'UEFI System')</lineannotation>
|
||||
-- for BIOS or UEFI systems
|
||||
> n # <lineannotation>(create a new partition for /swap)</lineannotation>
|
||||
> 2 # <lineannotation>(make it a partition number 2)</lineannotation>
|
||||
> # <lineannotation>(press enter to accept the default)</lineannotation>
|
||||
> +8G # <lineannotation>(the size of the swap partition, set to whatever you like)</lineannotation>
|
||||
> n # <lineannotation>(create a new partition for /)</lineannotation>
|
||||
> 1 # <lineannotation>(make it a partition number 1)</lineannotation>
|
||||
> # <lineannotation>(press enter to accept the default)</lineannotation>
|
||||
> # <lineannotation>(press enter to accept the default and use the rest of the remaining space)</lineannotation>
|
||||
> a # <lineannotation>(make the partition bootable)</lineannotation>
|
||||
> x # <lineannotation>(enter expert mode)</lineannotation>
|
||||
> f # <lineannotation>(fix up the partition ordering)</lineannotation>
|
||||
> r # <lineannotation>(exit expert mode)</lineannotation>
|
||||
> w # <lineannotation>(write the partition table to disk and exit)</lineannotation></screen></para></listitem>
|
||||
|
||||
<listitem><para>For initialising Ext4 partitions:
|
||||
<command>mkfs.ext4</command>. It is recommended that you assign a
|
||||
@ -67,7 +100,25 @@
|
||||
<listitem><para>For creating swap partitions:
|
||||
<command>mkswap</command>. Again it’s recommended to assign a
|
||||
label to the swap partition: <option>-L
|
||||
<replaceable>label</replaceable></option>.</para></listitem>
|
||||
<replaceable>label</replaceable></option>. For example:
|
||||
|
||||
<screen>
|
||||
# mkswap -L swap /dev/sda2</screen>
|
||||
|
||||
</para></listitem>
|
||||
|
||||
<listitem>
|
||||
<variablelist>
|
||||
<varlistentry><term>UEFI systems</term>
|
||||
<listitem><para>For creating boot partitions:
|
||||
<command>mkfs.fat</command>. Again it’s recommended to assign a
|
||||
label to the boot partition: <option>-L
|
||||
<replaceable>label</replaceable></option>. For example:
|
||||
|
||||
<screen>
|
||||
# mkfs.fat -F 32 -L boot /dev/sda3</screen>
|
||||
|
||||
</para></listitem></varlistentry></variablelist></listitem>
|
||||
|
||||
<listitem><para>For creating LVM volumes, the LVM commands, e.g.,
|
||||
|
||||
@ -95,11 +146,27 @@
|
||||
|
||||
</para></listitem>
|
||||
|
||||
<listitem>
|
||||
<variablelist>
|
||||
<varlistentry><term>UEFI systems</term>
|
||||
<listitem><para>Mount the boot file system on <filename>/mnt/boot</filename>, e.g.
|
||||
|
||||
<screen>
|
||||
# mount /dev/disk/by-label/boot /mnt/boot
|
||||
</screen>
|
||||
|
||||
</para></listitem></varlistentry></variablelist></listitem>
|
||||
|
||||
<listitem><para>If your machine has a limited amount of memory, you
|
||||
may want to activate swap devices now (<command>swapon
|
||||
<replaceable>device</replaceable></command>). The installer (or
|
||||
rather, the build actions that it may spawn) may need quite a bit of
|
||||
RAM, depending on your configuration.</para></listitem>
|
||||
RAM, depending on your configuration.
|
||||
|
||||
<screen>
|
||||
# swapon /dev/sda2</screen>
|
||||
|
||||
</para></listitem>
|
||||
|
||||
<listitem>
|
||||
|
||||
@ -135,10 +202,25 @@
|
||||
install Emacs by running <literal>nix-env -i
|
||||
emacs</literal>.</para>
|
||||
|
||||
<para>You <emphasis>must</emphasis> set the option
|
||||
<variablelist>
|
||||
|
||||
<varlistentry><term>BIOS systems</term>
|
||||
<listitem><para>You <emphasis>must</emphasis> set the option
|
||||
<option>boot.loader.grub.device</option> to specify on which disk
|
||||
the GRUB boot loader is to be installed. Without it, NixOS cannot
|
||||
boot.</para>
|
||||
boot.</para></listitem></varlistentry>
|
||||
|
||||
<varlistentry><term>UEFI systems</term>
|
||||
<listitem><para>You <emphasis>must</emphasis> set the option
|
||||
<option>boot.loader.systemd-boot.enable</option> to <literal>true</literal>.
|
||||
<command>nixos-generate-config</command> should do this automatically for new
|
||||
configurations when booted in
|
||||
UEFI mode.</para>
|
||||
<para>You may want to look at the options starting with
|
||||
<option>boot.loader.efi</option> and <option>boot.loader.systemd-boot</option>
|
||||
as well.</para></listitem></varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
<para>If there are other operating systems running on the machine before
|
||||
installing NixOS, the
|
||||
@ -247,10 +329,34 @@ drive (here <filename>/dev/sda</filename>). <xref linkend="ex-config"
|
||||
<example xml:id='ex-install-sequence'><title>Commands for Installing NixOS on <filename>/dev/sda</filename></title>
|
||||
<screen>
|
||||
# fdisk /dev/sda # <lineannotation>(or whatever device you want to install on)</lineannotation>
|
||||
-- for UEFI systems only
|
||||
> n # <lineannotation>(create a new partition for /boot)</lineannotation>
|
||||
> 3 # <lineannotation>(make it a partition number 3)</lineannotation>
|
||||
> # <lineannotation>(press enter to accept the default)</lineannotation>
|
||||
> +512M # <lineannotation>(the size of the UEFI boot partition)</lineannotation>
|
||||
> t # <lineannotation>(change the partition type ...)</lineannotation>
|
||||
> 3 # <lineannotation>(... of the boot partition ...)</lineannotation>
|
||||
> 1 # <lineannotation>(... to 'UEFI System')</lineannotation>
|
||||
-- for BIOS or UEFI systems
|
||||
> n # <lineannotation>(create a new partition for /swap)</lineannotation>
|
||||
> 2 # <lineannotation>(make it a partition number 2)</lineannotation>
|
||||
> # <lineannotation>(press enter to accept the default)</lineannotation>
|
||||
> +8G # <lineannotation>(the size of the swap partition)</lineannotation>
|
||||
> n # <lineannotation>(create a new partition for /)</lineannotation>
|
||||
> 1 # <lineannotation>(make it a partition number 1)</lineannotation>
|
||||
> # <lineannotation>(press enter to accept the default)</lineannotation>
|
||||
> # <lineannotation>(press enter to accept the default and use the rest of the remaining space)</lineannotation>
|
||||
> a # <lineannotation>(make the partition bootable)</lineannotation>
|
||||
> x # <lineannotation>(enter expert mode)</lineannotation>
|
||||
> f # <lineannotation>(fix up the partition ordering)</lineannotation>
|
||||
> r # <lineannotation>(exit expert mode)</lineannotation>
|
||||
> w # <lineannotation>(write the partition table to disk and exit)</lineannotation>
|
||||
# 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>
|
||||
# mount /dev/disk/by-label/nixos /mnt
|
||||
# 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
|
||||
# nixos-install
|
||||
@ -267,7 +373,8 @@ drive (here <filename>/dev/sda</filename>). <xref linkend="ex-config"
|
||||
./hardware-configuration.nix
|
||||
];
|
||||
|
||||
boot.loader.grub.device = "/dev/sda";
|
||||
boot.loader.grub.device = "/dev/sda"; # <lineannotation>(for BIOS systems only)</lineannotation>
|
||||
boot.loader.systemd-boot.enable = true; # <lineannotation>(for UEFI systems only)</lineannotation>
|
||||
|
||||
# Note: setting fileSystems is generally not
|
||||
# necessary, since nixos-generate-config figures them out
|
||||
@ -279,7 +386,6 @@ drive (here <filename>/dev/sda</filename>). <xref linkend="ex-config"
|
||||
}</screen>
|
||||
</example>
|
||||
|
||||
<xi:include href="installing-uefi.xml" />
|
||||
<xi:include href="installing-usb.xml" />
|
||||
<xi:include href="installing-pxe.xml" />
|
||||
<xi:include href="installing-virtualbox-guest.xml" />
|
||||
|
@ -12,11 +12,10 @@ download page</link>. There are a number of installation options. If
|
||||
you happen to have an optical drive and a spare CD, burning the
|
||||
image to CD and booting from that is probably the easiest option.
|
||||
Most people will need to prepare a USB stick to boot from.
|
||||
Unetbootin is recommended and the process is described in brief below.
|
||||
Note that systems which use UEFI require some additional manual steps.
|
||||
If you run into difficulty a number of alternative methods are presented
|
||||
in the <link
|
||||
xlink:href="https://nixos.org/wiki/Installing_NixOS_from_a_USB_stick">NixOS
|
||||
<xref linkend="sec-booting-from-usb"/> describes the preferred method
|
||||
to prepare a USB stick.
|
||||
A number of alternative methods are presented in the <link
|
||||
xlink:href="https://nixos.wiki/wiki/NixOS_Installation_Guide#Making_the_installation_media">NixOS
|
||||
Wiki</link>.</para>
|
||||
|
||||
<para>As an alternative to installing NixOS yourself, you can get a
|
||||
|
@ -13,7 +13,7 @@ the following highlights:
|
||||
<itemizedlist>
|
||||
|
||||
<listitem><para>Installation on UEFI systems is now supported. See
|
||||
<xref linkend="sec-uefi-installation"/> for
|
||||
<xref linkend="sec-installation"/> for
|
||||
details.</para></listitem>
|
||||
|
||||
<listitem><para>Systemd has been updated to version 212, which has
|
||||
|
@ -20,6 +20,22 @@ has the following highlights: </para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
MariaDB 10.2, updated from 10.1, is now the default MySQL implementation. While upgrading a few changes
|
||||
have been made to the infrastructure involved:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>libmysql</literal> has been deprecated, please use <literal>mysql.connector-c</literal>
|
||||
instead, a compatibility passthru has been added to the MySQL packages.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The <literal>mysql57</literal> package has a new <literal>static</literal> output containing
|
||||
the static libraries including <literal>libmysqld.a</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
@ -95,6 +111,34 @@ following incompatible changes:</para>
|
||||
<link xlink:href="https://search.nix.gsc.io/?q=stateVersion">here</link>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>cc-wrapper</literal>has been split in two; there is now also a <literal>bintools-wrapper</literal>.
|
||||
The most commonly used files in <filename>nix-support</filename> are now split between the two wrappers.
|
||||
Some commonly used ones, like <filename>nix-support/dynamic-linker</filename>, are duplicated for backwards compatability, even though they rightly belong only in <literal>bintools-wrapper</literal>.
|
||||
Other more obscure ones are just moved.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The propagation logic has been changed.
|
||||
The new logic, along with new types of dependencies that go with, is thoroughly documented in the "Specifying dependencies" section of the "Standard Environment" chapter of the nixpkgs manual.
|
||||
<!-- That's <xref linkend="ssec-stdenv-attributes"> were we to merge the manuals. -->
|
||||
The old logic isn't but is easy to describe: dependencies were propagated as the same type of dependency no matter what.
|
||||
In practice, that means that many <function>propagatedNativeBuildInputs</function> should instead be <function>propagatedBuildInputs</function>.
|
||||
Thankfully, that was and is the least used type of dependency.
|
||||
Also, it means that some <function>propagatedBuildInputs</function> should instead be <function>depsTargetTargetPropagated</function>.
|
||||
Other types dependencies should be unaffected.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The <literal>memcached</literal> service no longer accept dynamic socket
|
||||
paths via <option>services.memcached.socket</option>. Unix sockets can be
|
||||
still enabled by <option>services.memcached.enableUnixSocket</option> and
|
||||
will be accessible at <literal>/run/memcached/memcached.sock</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
</section>
|
||||
@ -131,6 +175,72 @@ following incompatible changes:</para>
|
||||
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.
|
||||
Previously the default behaviour was to listen on all interfaces.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>services.btrfs.autoScrub</literal> has been added, to
|
||||
periodically check btrfs filesystems for data corruption.
|
||||
If there's a correct copy available, it will automatically repair
|
||||
corrupted blocks.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>displayManager.lightdm.greeters.gtk.clock-format.</literal>
|
||||
has been added, the clock format string (as expected by
|
||||
strftime, e.g. <literal>%H:%M</literal>) to use with the lightdm
|
||||
gtk greeter panel.
|
||||
</para>
|
||||
<para>
|
||||
If set to null the default clock format is used.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>displayManager.lightdm.greeters.gtk.indicators</literal>
|
||||
has been added, a list of allowed indicator modules to use with
|
||||
the lightdm gtk greeter panel.
|
||||
</para>
|
||||
<para>
|
||||
Built-in indicators include <literal>~a11y</literal>,
|
||||
<literal>~language</literal>, <literal>~session</literal>,
|
||||
<literal>~power</literal>, <literal>~clock</literal>,
|
||||
<literal>~host</literal>, <literal>~spacer</literal>. Unity
|
||||
indicators can be represented by short name
|
||||
(e.g. <literal>sound</literal>, <literal>power</literal>),
|
||||
service file name, or absolute path.
|
||||
</para>
|
||||
<para>
|
||||
If set to <literal>null</literal> the default indicators are
|
||||
used.
|
||||
</para>
|
||||
<para>
|
||||
In order to have the previous default configuration add
|
||||
<programlisting>
|
||||
services.xserver.displayManager.lightdm.greeters.gtk.indicators = [
|
||||
"~host" "~spacer"
|
||||
"~clock" "~spacer"
|
||||
"~session"
|
||||
"~language"
|
||||
"~a11y"
|
||||
"~power"
|
||||
];
|
||||
</programlisting>
|
||||
to your <literal>configuration.nix</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The NixOS test driver supports user services declared by <literal>systemd.user.services</literal>.
|
||||
The methods <literal>waitForUnit</literal>, <literal>getUnitInfo</literal>, <literal>startJob</literal>
|
||||
and <literal>stopJob</literal> provide an optional <literal>$user</literal> argument for that purpose.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
</section>
|
||||
|
@ -129,6 +129,9 @@ let format' = format; in let
|
||||
# TODO: Nix really likes to chown things it creates to its current user...
|
||||
fakeroot nixos-prepare-root $root ${channelSources} ${config.system.build.toplevel} closure
|
||||
|
||||
# fakeroot seems to always give the owner write permissions, which we do not want
|
||||
find $root/nix/store -mindepth 1 -maxdepth 1 -type f -o -type d | xargs chmod -R a-w
|
||||
|
||||
echo "copying staging root to image..."
|
||||
cptofs ${optionalString partitioned "-P 1"} -t ${fsType} -i $diskImage $root/* /
|
||||
'';
|
||||
@ -150,8 +153,6 @@ in pkgs.vmTools.runInLinuxVM (
|
||||
}
|
||||
''
|
||||
${if partitioned then ''
|
||||
. /sys/class/block/vda1/uevent
|
||||
mknod /dev/vda1 b $MAJOR $MINOR
|
||||
rootDisk=/dev/vda1
|
||||
'' else ''
|
||||
rootDisk=/dev/vda
|
||||
|
@ -10,7 +10,7 @@
|
||||
pkgs.stdenv.mkDerivation {
|
||||
name = "ext4-fs.img";
|
||||
|
||||
buildInputs = with pkgs; [e2fsprogs libfaketime perl];
|
||||
nativeBuildInputs = with pkgs; [e2fsprogs libfaketime perl];
|
||||
|
||||
# For obtaining the closure of `storePaths'.
|
||||
exportReferencesGraph =
|
||||
|
@ -8,7 +8,7 @@
|
||||
stdenv.mkDerivation {
|
||||
name = "squashfs.img";
|
||||
|
||||
buildInputs = [perl squashfsTools];
|
||||
nativeBuildInputs = [perl squashfsTools];
|
||||
|
||||
# For obtaining the closure of `storeContents'.
|
||||
exportReferencesGraph =
|
||||
@ -19,6 +19,33 @@ stdenv.mkDerivation {
|
||||
# Add the closures of the top-level store objects.
|
||||
storePaths=$(perl ${pathsFromGraph} closure-*)
|
||||
|
||||
# If a Hydra slave happens to have store paths with bad permissions/mtime,
|
||||
# abort now so that they don't end up in ISO images in the channel.
|
||||
# https://github.com/NixOS/nixpkgs/issues/32242
|
||||
hasBadPaths=""
|
||||
for path in $storePaths; do
|
||||
if [ -h "$path" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
mtime=$(stat -c %Y "$path")
|
||||
mode=$(stat -c %a "$path")
|
||||
|
||||
if [ "$mtime" != 1 ]; then
|
||||
echo "Store path '$path' has an invalid mtime."
|
||||
hasBadPaths=1
|
||||
fi
|
||||
if [ "$mode" != 444 ] && [ "$mode" != 555 ]; then
|
||||
echo "Store path '$path' has invalid permissions ($mode)."
|
||||
hasBadPaths=1
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "$hasBadPaths" ]; then
|
||||
echo "You have bad paths in your store, please fix them."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Also include a manifest of the closures in a format suitable
|
||||
# for nix-store --load-db.
|
||||
printRegistration=1 perl ${pathsFromGraph} closure-* > nix-path-registration
|
||||
|
@ -362,8 +362,8 @@ sub mustFail {
|
||||
|
||||
|
||||
sub getUnitInfo {
|
||||
my ($self, $unit) = @_;
|
||||
my ($status, $lines) = $self->execute("systemctl --no-pager show '$unit'");
|
||||
my ($self, $unit, $user) = @_;
|
||||
my ($status, $lines) = $self->systemctl("--no-pager show \"$unit\"", $user);
|
||||
return undef if $status != 0;
|
||||
my $info = {};
|
||||
foreach my $line (split '\n', $lines) {
|
||||
@ -373,6 +373,16 @@ sub getUnitInfo {
|
||||
return $info;
|
||||
}
|
||||
|
||||
sub systemctl {
|
||||
my ($self, $q, $user) = @_;
|
||||
if ($user) {
|
||||
$q =~ s/'/\\'/g;
|
||||
return $self->execute("su -l $user -c \$'XDG_RUNTIME_DIR=/run/user/`id -u` systemctl --user $q'");
|
||||
}
|
||||
|
||||
return $self->execute("systemctl $q");
|
||||
}
|
||||
|
||||
# Fail if the given systemd unit is not in the "active" state.
|
||||
sub requireActiveUnit {
|
||||
my ($self, $unit) = @_;
|
||||
@ -387,16 +397,16 @@ sub requireActiveUnit {
|
||||
|
||||
# Wait for a systemd unit to reach the "active" state.
|
||||
sub waitForUnit {
|
||||
my ($self, $unit) = @_;
|
||||
my ($self, $unit, $user) = @_;
|
||||
$self->nest("waiting for unit ‘$unit’", sub {
|
||||
retry sub {
|
||||
my $info = $self->getUnitInfo($unit);
|
||||
my $info = $self->getUnitInfo($unit, $user);
|
||||
my $state = $info->{ActiveState};
|
||||
die "unit ‘$unit’ reached state ‘$state’\n" if $state eq "failed";
|
||||
if ($state eq "inactive") {
|
||||
# If there are no pending jobs, then assume this unit
|
||||
# will never reach active state.
|
||||
my ($status, $jobs) = $self->execute("systemctl list-jobs --full 2>&1");
|
||||
my ($status, $jobs) = $self->systemctl("list-jobs --full 2>&1", $user);
|
||||
if ($jobs =~ /No jobs/) { # FIXME: fragile
|
||||
# Handle the case where the unit may have started
|
||||
# between the previous getUnitInfo() and
|
||||
@ -430,14 +440,14 @@ sub waitForFile {
|
||||
}
|
||||
|
||||
sub startJob {
|
||||
my ($self, $jobName) = @_;
|
||||
$self->execute("systemctl start $jobName");
|
||||
my ($self, $jobName, $user) = @_;
|
||||
$self->systemctl("start $jobName", $user);
|
||||
# FIXME: check result
|
||||
}
|
||||
|
||||
sub stopJob {
|
||||
my ($self, $jobName) = @_;
|
||||
$self->execute("systemctl stop $jobName");
|
||||
my ($self, $jobName, $user) = @_;
|
||||
$self->systemctl("stop $jobName", $user);
|
||||
}
|
||||
|
||||
|
||||
|
@ -18,7 +18,7 @@ rm -f ec2-amis.nix
|
||||
|
||||
types="hvm"
|
||||
stores="ebs"
|
||||
regions="eu-west-1 eu-west-2 eu-central-1 us-east-1 us-east-2 us-west-1 us-west-2 ca-central-1 ap-southeast-1 ap-southeast-2 ap-northeast-1 ap-northeast-2 sa-east-1 ap-south-1"
|
||||
regions="eu-west-1 eu-west-2 eu-west-3 eu-central-1 us-east-1 us-east-2 us-west-1 us-west-2 ca-central-1 ap-southeast-1 ap-southeast-2 ap-northeast-1 ap-northeast-2 sa-east-1 ap-south-1"
|
||||
|
||||
for type in $types; do
|
||||
link=$stateDir/$type
|
||||
|
@ -290,8 +290,8 @@ in
|
||||
ln -s /run/systemd/resolve/resolv.conf /run/resolvconf/interfaces/systemd
|
||||
''}
|
||||
|
||||
# Make sure resolv.conf is up to date if not managed by systemd
|
||||
${optionalString (!config.services.resolved.enable) ''
|
||||
# Make sure resolv.conf is up to date if not managed manually or by systemd
|
||||
${optionalString (!config.environment.etc?"resolv.conf") ''
|
||||
${pkgs.openresolv}/bin/resolvconf -u
|
||||
''}
|
||||
'';
|
||||
|
@ -35,7 +35,7 @@ with lib;
|
||||
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.override { gtk2 = null; qt4 = null; };
|
||||
pinentry = pkgs.pinentry_ncurses;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -18,17 +18,17 @@ with lib;
|
||||
|
||||
};
|
||||
|
||||
config = {
|
||||
|
||||
boot.loader.grub.version = 2;
|
||||
|
||||
config = rec {
|
||||
# Don't build the GRUB menu builder script, since we don't need it
|
||||
# here and it causes a cyclic dependency.
|
||||
boot.loader.grub.enable = false;
|
||||
|
||||
# !!! Hack - attributes expected by other modules.
|
||||
system.boot.loader.kernelFile = "bzImage";
|
||||
environment.systemPackages = [ pkgs.grub2 pkgs.grub2_efi pkgs.syslinux ];
|
||||
environment.systemPackages = [ pkgs.grub2_efi ]
|
||||
++ (if pkgs.stdenv.system == "aarch64-linux"
|
||||
then []
|
||||
else [ pkgs.grub2 pkgs.syslinux ]);
|
||||
system.boot.loader.kernelFile = pkgs.stdenv.platform.kernelTarget;
|
||||
|
||||
fileSystems."/" =
|
||||
{ fsType = "tmpfs";
|
||||
@ -84,7 +84,12 @@ with lib;
|
||||
];
|
||||
};
|
||||
|
||||
system.build.netbootIpxeScript = pkgs.writeTextDir "netboot.ipxe" "#!ipxe\nkernel bzImage init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}\ninitrd initrd\nboot";
|
||||
system.build.netbootIpxeScript = pkgs.writeTextDir "netboot.ipxe" ''
|
||||
#!ipxe
|
||||
kernel ${pkgs.stdenv.platform.kernelTarget} init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}
|
||||
initrd initrd
|
||||
boot
|
||||
'';
|
||||
|
||||
boot.loader.timeout = 10;
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
{
|
||||
x86_64-linux = "/nix/store/b4s1gxiis1ryvybnjhdjvgc5sr1nq0ys-nix-1.11.15";
|
||||
i686-linux = "/nix/store/kgb5hs7qw13bvb6icramv1ry9dard3h9-nix-1.11.15";
|
||||
x86_64-darwin = "/nix/store/dgwz3dxdzs2wwd7pg7cdhvl8rv0qpnbj-nix-1.11.15";
|
||||
x86_64-linux = "/nix/store/gy4yv67gv3j6in0lalw37j353zdmfcwm-nix-1.11.16";
|
||||
i686-linux = "/nix/store/ifmyq5ryfxhhrzh62hiq65xyz1fwffga-nix-1.11.16";
|
||||
aarch64-linux = "/nix/store/y9mfv3sx75mbfibf1zna1kq9v98fk2nb-nix-1.11.16";
|
||||
x86_64-darwin = "/nix/store/hwpp7kia2f0in5ns2hiw41q38k30jpj2-nix-1.11.16";
|
||||
}
|
||||
|
@ -65,7 +65,7 @@
|
||||
foldingathome = 37;
|
||||
sabnzbd = 38;
|
||||
#kdm = 39; # dropped in 17.03
|
||||
ghostone = 40;
|
||||
#ghostone = 40; # dropped in 18.03
|
||||
git = 41;
|
||||
fourstore = 42;
|
||||
fourstorehttp = 43;
|
||||
@ -197,10 +197,10 @@
|
||||
#input = 174; # unused
|
||||
sddm = 175;
|
||||
tss = 176;
|
||||
memcached = 177;
|
||||
#memcached = 177; removed 2018-01-03
|
||||
ntp = 179;
|
||||
zabbix = 180;
|
||||
redis = 181;
|
||||
#redis = 181; removed 2018-01-03
|
||||
unifi = 183;
|
||||
uptimed = 184;
|
||||
zope2 = 185;
|
||||
@ -281,8 +281,8 @@
|
||||
stanchion = 262;
|
||||
riak-cs = 263;
|
||||
infinoted = 264;
|
||||
keystone = 265;
|
||||
glance = 266;
|
||||
# keystone = 265; # unused, removed 2017-12-13
|
||||
# glance = 266; # unused, removed 2017-12-13
|
||||
couchpotato = 267;
|
||||
gogs = 268;
|
||||
pdns-recursor = 269;
|
||||
@ -348,7 +348,7 @@
|
||||
#foldingathome = 37; # unused
|
||||
#sabnzd = 38; # unused
|
||||
#kdm = 39; # unused, even before 17.03
|
||||
ghostone = 40;
|
||||
#ghostone = 40; # dropped in 18.03
|
||||
git = 41;
|
||||
fourstore = 42;
|
||||
fourstorehttp = 43;
|
||||
@ -475,10 +475,10 @@
|
||||
input = 174;
|
||||
sddm = 175;
|
||||
tss = 176;
|
||||
#memcached = 177; # unused
|
||||
#memcached = 177; # unused, removed 2018-01-03
|
||||
#ntp = 179; # unused
|
||||
#zabbix = 180; # unused
|
||||
#redis = 181; # unused
|
||||
#redis = 181; # unused, removed 2018-01-03
|
||||
#unifi = 183; # unused
|
||||
#uptimed = 184; # unused
|
||||
#zope2 = 185; # unused
|
||||
@ -551,8 +551,8 @@
|
||||
stanchion = 262;
|
||||
riak-cs = 263;
|
||||
infinoted = 264;
|
||||
keystone = 265;
|
||||
glance = 266;
|
||||
# keystone = 265; # unused, removed 2017-12-13
|
||||
# glance = 266; # unused, removed 2017-12-13
|
||||
couchpotato = 267;
|
||||
gogs = 268;
|
||||
kresd = 270;
|
||||
|
@ -71,6 +71,7 @@
|
||||
./programs/bcc.nix
|
||||
./programs/blcr.nix
|
||||
./programs/browserpass.nix
|
||||
./programs/ccache.nix
|
||||
./programs/cdemu.nix
|
||||
./programs/chromium.nix
|
||||
./programs/command-not-found/command-not-found.nix
|
||||
@ -91,6 +92,7 @@
|
||||
./programs/npm.nix
|
||||
./programs/oblogout.nix
|
||||
./programs/qt5ct.nix
|
||||
./programs/rootston.nix
|
||||
./programs/screen.nix
|
||||
./programs/slock.nix
|
||||
./programs/shadow.nix
|
||||
@ -104,6 +106,7 @@
|
||||
./programs/tmux.nix
|
||||
./programs/venus.nix
|
||||
./programs/vim.nix
|
||||
./programs/way-cooler.nix
|
||||
./programs/wireshark.nix
|
||||
./programs/xfs_quota.nix
|
||||
./programs/xonsh.nix
|
||||
@ -217,7 +220,6 @@
|
||||
./services/editors/emacs.nix
|
||||
./services/editors/infinoted.nix
|
||||
./services/games/factorio.nix
|
||||
./services/games/ghost-one.nix
|
||||
./services/games/minecraft-server.nix
|
||||
./services/games/minetest-server.nix
|
||||
./services/games/terraria.nix
|
||||
@ -239,9 +241,11 @@
|
||||
./services/hardware/tlp.nix
|
||||
./services/hardware/thinkfan.nix
|
||||
./services/hardware/trezord.nix
|
||||
./services/hardware/u2f.nix
|
||||
./services/hardware/udev.nix
|
||||
./services/hardware/udisks2.nix
|
||||
./services/hardware/upower.nix
|
||||
./services/hardware/usbmuxd.nix
|
||||
./services/hardware/thermald.nix
|
||||
./services/logging/SystemdJournal2Gelf.nix
|
||||
./services/logging/awstats.nix
|
||||
@ -257,6 +261,8 @@
|
||||
./services/logging/rsyslogd.nix
|
||||
./services/logging/syslog-ng.nix
|
||||
./services/logging/syslogd.nix
|
||||
./services/mail/clamsmtp.nix
|
||||
./services/mail/dkimproxy-out.nix
|
||||
./services/mail/dovecot.nix
|
||||
./services/mail/dspam.nix
|
||||
./services/mail/exim.nix
|
||||
@ -328,6 +334,7 @@
|
||||
./services/misc/nix-ssh-serve.nix
|
||||
./services/misc/nzbget.nix
|
||||
./services/misc/octoprint.nix
|
||||
./services/misc/osrm.nix
|
||||
./services/misc/packagekit.nix
|
||||
./services/misc/parsoid.nix
|
||||
./services/misc/phd.nix
|
||||
@ -352,6 +359,7 @@
|
||||
./services/misc/taskserver
|
||||
./services/misc/tzupdate.nix
|
||||
./services/misc/uhub.nix
|
||||
./services/misc/xmr-stak.nix
|
||||
./services/misc/zookeeper.nix
|
||||
./services/monitoring/apcupsd.nix
|
||||
./services/monitoring/arbtt.nix
|
||||
@ -398,7 +406,9 @@
|
||||
./services/monitoring/vnstat.nix
|
||||
./services/monitoring/zabbix-agent.nix
|
||||
./services/monitoring/zabbix-server.nix
|
||||
./services/network-filesystems/beegfs.nix
|
||||
./services/network-filesystems/cachefilesd.nix
|
||||
./services/network-filesystems/davfs2.nix
|
||||
./services/network-filesystems/drbd.nix
|
||||
./services/network-filesystems/glusterfs.nix
|
||||
./services/network-filesystems/kbfs.nix
|
||||
@ -588,6 +598,7 @@
|
||||
./services/system/cloud-init.nix
|
||||
./services/system/dbus.nix
|
||||
./services/system/earlyoom.nix
|
||||
./services/system/localtime.nix
|
||||
./services/system/kerberos.nix
|
||||
./services/system/nscd.nix
|
||||
./services/system/saslauthd.nix
|
||||
@ -671,6 +682,7 @@
|
||||
./system/activation/top-level.nix
|
||||
./system/boot/coredump.nix
|
||||
./system/boot/emergency-mode.nix
|
||||
./system/boot/grow-partition.nix
|
||||
./system/boot/initrd-network.nix
|
||||
./system/boot/initrd-ssh.nix
|
||||
./system/boot/kernel.nix
|
||||
@ -737,6 +749,7 @@
|
||||
./virtualisation/lxcfs.nix
|
||||
./virtualisation/lxd.nix
|
||||
./virtualisation/amazon-options.nix
|
||||
./virtualisation/hyperv-guest.nix
|
||||
./virtualisation/openvswitch.nix
|
||||
./virtualisation/parallels-guest.nix
|
||||
./virtualisation/rkt.nix
|
||||
@ -745,6 +758,4 @@
|
||||
./virtualisation/vmware-guest.nix
|
||||
./virtualisation/xen-dom0.nix
|
||||
./virtualisation/xe-guest-utilities.nix
|
||||
./virtualisation/openstack/keystone.nix
|
||||
./virtualisation/openstack/glance.nix
|
||||
]
|
||||
|
@ -19,13 +19,12 @@
|
||||
"sata_sil" "sata_sil24" "sata_sis" "sata_svw" "sata_sx4"
|
||||
"sata_uli" "sata_via" "sata_vsc"
|
||||
|
||||
"pata_ali" "pata_amd" "pata_artop" "pata_atiixp"
|
||||
"pata_cs5520" "pata_cs5530" "pata_cs5535" "pata_efar"
|
||||
"pata_ali" "pata_amd" "pata_artop" "pata_atiixp" "pata_efar"
|
||||
"pata_hpt366" "pata_hpt37x" "pata_hpt3x2n" "pata_hpt3x3"
|
||||
"pata_it8213" "pata_it821x" "pata_jmicron" "pata_marvell"
|
||||
"pata_mpiix" "pata_netcell" "pata_ns87410" "pata_oldpiix"
|
||||
"pata_pcmcia" "pata_pdc2027x" "pata_qdi" "pata_rz1000"
|
||||
"pata_sc1200" "pata_serverworks" "pata_sil680" "pata_sis"
|
||||
"pata_serverworks" "pata_sil680" "pata_sis"
|
||||
"pata_sl82c105" "pata_triflex" "pata_via"
|
||||
"pata_winbond"
|
||||
|
||||
|
@ -14,13 +14,16 @@ let
|
||||
bashCompletion = optionalString cfg.enableCompletion ''
|
||||
# Check whether we're running a version of Bash that has support for
|
||||
# programmable completion. If we do, enable all modules installed in
|
||||
# the system (and user profile).
|
||||
# the system and user profile in obsolete /etc/bash_completion.d/
|
||||
# directories. Bash loads completions in all
|
||||
# $XDG_DATA_DIRS/share/bash-completion/completions/
|
||||
# on demand, so they do not need to be sourced here.
|
||||
if shopt -q progcomp &>/dev/null; then
|
||||
. "${pkgs.bash-completion}/etc/profile.d/bash_completion.sh"
|
||||
nullglobStatus=$(shopt -p nullglob)
|
||||
shopt -s nullglob
|
||||
for p in $NIX_PROFILES; do
|
||||
for m in "$p/etc/bash_completion.d/"* "$p/share/bash-completion/completions/"*; do
|
||||
for m in "$p/etc/bash_completion.d/"*; do
|
||||
. $m
|
||||
done
|
||||
done
|
||||
|
83
nixos/modules/programs/ccache.nix
Normal file
83
nixos/modules/programs/ccache.nix
Normal file
@ -0,0 +1,83 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.programs.ccache;
|
||||
in {
|
||||
options.programs.ccache = {
|
||||
# host configuration
|
||||
enable = mkEnableOption "CCache";
|
||||
cacheDir = mkOption {
|
||||
type = types.path;
|
||||
description = "CCache directory";
|
||||
default = "/var/cache/ccache";
|
||||
};
|
||||
# target configuration
|
||||
packageNames = mkOption {
|
||||
type = types.listOf types.str;
|
||||
description = "Nix top-level packages to be compiled using CCache";
|
||||
default = [];
|
||||
example = [ "wxGTK30" "qt48" "ffmpeg_3_3" "libav_all" ];
|
||||
};
|
||||
};
|
||||
|
||||
config = mkMerge [
|
||||
# host configuration
|
||||
(mkIf cfg.enable {
|
||||
systemd.tmpfiles.rules = [ "d ${cfg.cacheDir} 0770 root nixbld -" ];
|
||||
|
||||
# "nix-ccache --show-stats" and "nix-ccache --clear"
|
||||
security.wrappers.nix-ccache = {
|
||||
group = "nixbld";
|
||||
setgid = true;
|
||||
source = pkgs.writeScript "nix-ccache.pl" ''
|
||||
#!${pkgs.perl}/bin/perl
|
||||
|
||||
%ENV=( CCACHE_DIR => '${cfg.cacheDir}' );
|
||||
sub untaint {
|
||||
my $v = shift;
|
||||
return '-C' if $v eq '-C' || $v eq '--clear';
|
||||
return '-V' if $v eq '-V' || $v eq '--version';
|
||||
return '-s' if $v eq '-s' || $v eq '--show-stats';
|
||||
return '-z' if $v eq '-z' || $v eq '--zero-stats';
|
||||
exec('${pkgs.ccache}/bin/ccache', '-h');
|
||||
}
|
||||
exec('${pkgs.ccache}/bin/ccache', map { untaint $_ } @ARGV);
|
||||
'';
|
||||
};
|
||||
})
|
||||
|
||||
# target configuration
|
||||
(mkIf (cfg.packageNames != []) {
|
||||
nixpkgs.overlays = [
|
||||
(self: super: genAttrs cfg.packageNames (pn: super.${pn}.override { stdenv = builtins.trace "with ccache: ${pn}" self.ccacheStdenv; }))
|
||||
|
||||
(self: super: {
|
||||
ccacheWrapper = super.ccacheWrapper.override {
|
||||
extraConfig = ''
|
||||
export CCACHE_COMPRESS=1
|
||||
export CCACHE_DIR="${cfg.cacheDir}"
|
||||
export CCACHE_UMASK=007
|
||||
if [ ! -d "$CCACHE_DIR" ]; then
|
||||
echo "====="
|
||||
echo "Directory '$CCACHE_DIR' does not exist"
|
||||
echo "Please create it with:"
|
||||
echo " sudo mkdir -m0770 '$CCACHE_DIR'"
|
||||
echo " sudo chown root:nixbld '$CCACHE_DIR'"
|
||||
echo "====="
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -w "$CCACHE_DIR" ]; then
|
||||
echo "====="
|
||||
echo "Directory '$CCACHE_DIR' is not accessible for user $(whoami)"
|
||||
echo "Please verify its access permissions"
|
||||
echo "====="
|
||||
exit 1
|
||||
fi
|
||||
'';
|
||||
};
|
||||
})
|
||||
];
|
||||
})
|
||||
];
|
||||
}
|
@ -1,7 +1,8 @@
|
||||
{ config, lib, ... }:
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
inherit (lib) mkOption mkIf types mapAttrsToList;
|
||||
cfg = config.programs.dconf;
|
||||
|
||||
mkDconfProfile = name: path:
|
||||
@ -13,6 +14,7 @@ in
|
||||
|
||||
options = {
|
||||
programs.dconf = {
|
||||
enable = mkEnableOption "dconf";
|
||||
|
||||
profiles = mkOption {
|
||||
type = types.attrsOf types.path;
|
||||
@ -26,9 +28,15 @@ in
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf (cfg.profiles != {}) {
|
||||
environment.etc =
|
||||
config = mkIf (cfg.profiles != {} || cfg.enable) {
|
||||
environment.etc = optionals (cfg.profiles != {})
|
||||
(mapAttrsToList mkDconfProfile cfg.profiles);
|
||||
|
||||
environment.variables.GIO_EXTRA_MODULES = optional cfg.enable
|
||||
"${pkgs.gnome3.dconf.lib}/lib/gio/modules";
|
||||
# https://github.com/NixOS/nixpkgs/pull/31891
|
||||
#environment.variables.XDG_DATA_DIRS = optional cfg.enable
|
||||
# "$(echo ${pkgs.gnome3.gsettings_desktop_schemas}/share/gsettings-schemas/gsettings-desktop-schemas-*)";
|
||||
};
|
||||
|
||||
}
|
||||
|
103
nixos/modules/programs/rootston.nix
Normal file
103
nixos/modules/programs/rootston.nix
Normal file
@ -0,0 +1,103 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.programs.rootston;
|
||||
|
||||
rootstonWrapped = pkgs.writeScriptBin "rootston" ''
|
||||
#! ${pkgs.stdenv.shell}
|
||||
if [[ "$#" -ge 1 ]]; then
|
||||
exec ${pkgs.rootston}/bin/rootston "$@"
|
||||
else
|
||||
${cfg.extraSessionCommands}
|
||||
exec ${pkgs.rootston}/bin/rootston -C ${cfg.configFile}
|
||||
fi
|
||||
'';
|
||||
in {
|
||||
options.programs.rootston = {
|
||||
enable = mkEnableOption ''
|
||||
rootston, the reference compositor for wlroots. The purpose of rootston
|
||||
is to test and demonstrate the features of wlroots (if you want a real
|
||||
Wayland compositor you should e.g. use Sway instead). You can manually
|
||||
start the compositor by running "rootston" from a terminal'';
|
||||
|
||||
extraSessionCommands = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
example = ''
|
||||
# Define a keymap (US QWERTY is the default)
|
||||
export XKB_DEFAULT_LAYOUT=de,us
|
||||
export XKB_DEFAULT_VARIANT=nodeadkeys
|
||||
export XKB_DEFAULT_OPTIONS=grp:alt_shift_toggle,caps:escape
|
||||
'';
|
||||
description = ''
|
||||
Shell commands executed just before rootston is started.
|
||||
'';
|
||||
};
|
||||
|
||||
extraPackages = mkOption {
|
||||
type = with types; listOf package;
|
||||
default = with pkgs; [
|
||||
westonLite xwayland rofi
|
||||
];
|
||||
defaultText = literalExample ''
|
||||
with pkgs; [
|
||||
westonLite xwayland rofi
|
||||
]
|
||||
'';
|
||||
example = literalExample "[ ]";
|
||||
description = ''
|
||||
Extra packages to be installed system wide.
|
||||
'';
|
||||
};
|
||||
|
||||
config = mkOption {
|
||||
type = types.str;
|
||||
default = ''
|
||||
[keyboard]
|
||||
meta-key = Logo
|
||||
|
||||
# Sway/i3 like Keybindings
|
||||
# Maps key combinations with commands to execute
|
||||
# Commands include:
|
||||
# - "exit" to stop the compositor
|
||||
# - "exec" to execute a shell command
|
||||
# - "close" to close the current view
|
||||
# - "next_window" to cycle through windows
|
||||
[bindings]
|
||||
Logo+Shift+e = exit
|
||||
Logo+q = close
|
||||
Logo+m = maximize
|
||||
Alt+Tab = next_window
|
||||
Logo+Return = exec weston-terminal
|
||||
Logo+d = exec rofi -show run
|
||||
'';
|
||||
description = ''
|
||||
Default configuration for rootston (used when called without any
|
||||
parameters).
|
||||
'';
|
||||
};
|
||||
|
||||
configFile = mkOption {
|
||||
type = types.path;
|
||||
default = "/etc/rootston.ini";
|
||||
example = literalExample "${pkgs.rootston}/etc/rootston.ini";
|
||||
description = ''
|
||||
Path to the default rootston configuration file (the "config" option
|
||||
will have no effect if you change the path).
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
environment.etc."rootston.ini".text = cfg.config;
|
||||
environment.systemPackages = [ rootstonWrapped ] ++ cfg.extraPackages;
|
||||
|
||||
hardware.opengl.enable = mkDefault true;
|
||||
fonts.enableDefaultFonts = mkDefault true;
|
||||
programs.dconf.enable = mkDefault true;
|
||||
};
|
||||
|
||||
meta.maintainers = with lib.maintainers; [ primeos gnidorah ];
|
||||
}
|
@ -4,36 +4,42 @@ with lib;
|
||||
|
||||
let
|
||||
cfg = config.programs.sway;
|
||||
sway = pkgs.sway;
|
||||
swayPackage = pkgs.sway;
|
||||
|
||||
swayWrapped = pkgs.writeScriptBin "sway" ''
|
||||
#! ${pkgs.stdenv.shell}
|
||||
if [ "$1" != "" ]; then
|
||||
sway-setcap "$@"
|
||||
exit
|
||||
swayWrapped = pkgs.writeShellScriptBin "sway" ''
|
||||
if [[ "$#" -ge 1 ]]; then
|
||||
exec sway-setcap "$@"
|
||||
else
|
||||
${cfg.extraSessionCommands}
|
||||
exec ${pkgs.dbus.dbus-launch} --exit-with-session sway-setcap
|
||||
fi
|
||||
${cfg.extraSessionCommands}
|
||||
exec ${pkgs.dbus.dbus-launch} --exit-with-session sway-setcap
|
||||
'';
|
||||
swayJoined = pkgs.symlinkJoin {
|
||||
name = "sway-wrapped";
|
||||
paths = [ swayWrapped sway ];
|
||||
name = "sway-joined";
|
||||
paths = [ swayWrapped swayPackage ];
|
||||
};
|
||||
in
|
||||
{
|
||||
in {
|
||||
options.programs.sway = {
|
||||
enable = mkEnableOption "sway";
|
||||
enable = mkEnableOption ''
|
||||
the tiling Wayland compositor Sway. After adding yourself to the "sway"
|
||||
group you can manually launch Sway by executing "sway" from a terminal.
|
||||
If you call "sway" with any parameters the extraSessionCommands won't be
|
||||
executed and Sway won't be launched with dbus-launch'';
|
||||
|
||||
extraSessionCommands = mkOption {
|
||||
default = "";
|
||||
type = types.lines;
|
||||
type = types.lines;
|
||||
default = "";
|
||||
example = ''
|
||||
export XKB_DEFAULT_LAYOUT=us,de
|
||||
export XKB_DEFAULT_VARIANT=,nodeadkeys
|
||||
export XKB_DEFAULT_OPTIONS=grp:alt_shift_toggle,
|
||||
# Define a keymap (US QWERTY is the default)
|
||||
export XKB_DEFAULT_LAYOUT=de,us
|
||||
export XKB_DEFAULT_VARIANT=nodeadkeys
|
||||
export XKB_DEFAULT_OPTIONS=grp:alt_shift_toggle,caps:escape
|
||||
# Change the Keyboard repeat delay and rate
|
||||
export WLC_REPEAT_DELAY=660
|
||||
export WLC_REPEAT_RATE=25
|
||||
'';
|
||||
description = ''
|
||||
Shell commands executed just before sway is started.
|
||||
Shell commands executed just before Sway is started.
|
||||
'';
|
||||
};
|
||||
|
||||
@ -42,9 +48,12 @@ in
|
||||
default = with pkgs; [
|
||||
i3status xwayland rxvt_unicode dmenu
|
||||
];
|
||||
defaultText = literalExample ''
|
||||
with pkgs; [ i3status xwayland rxvt_unicode dmenu ];
|
||||
'';
|
||||
example = literalExample ''
|
||||
with pkgs; [
|
||||
i3status xwayland rxvt_unicode dmenu
|
||||
i3lock light termite
|
||||
]
|
||||
'';
|
||||
description = ''
|
||||
@ -57,7 +66,7 @@ in
|
||||
environment.systemPackages = [ swayJoined ] ++ cfg.extraPackages;
|
||||
security.wrappers.sway = {
|
||||
program = "sway-setcap";
|
||||
source = "${sway}/bin/sway";
|
||||
source = "${swayPackage}/bin/sway";
|
||||
capabilities = "cap_sys_ptrace,cap_sys_tty_config=eip";
|
||||
owner = "root";
|
||||
group = "sway";
|
||||
@ -65,8 +74,12 @@ in
|
||||
};
|
||||
|
||||
users.extraGroups.sway = {};
|
||||
security.pam.services.swaylock = {};
|
||||
|
||||
hardware.opengl.enable = mkDefault true;
|
||||
fonts.enableDefaultFonts = mkDefault true;
|
||||
programs.dconf.enable = mkDefault true;
|
||||
};
|
||||
|
||||
meta.maintainers = with lib.maintainers; [ gnidorah primeos ];
|
||||
}
|
||||
|
@ -151,6 +151,15 @@ in {
|
||||
type = types.str;
|
||||
description = "Set the $TERM variable.";
|
||||
};
|
||||
|
||||
secureSocket = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Store tmux socket under /run, which is more secure than /tmp, but as a
|
||||
downside it doesn't survive user logout.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@ -163,7 +172,7 @@ in {
|
||||
systemPackages = [ pkgs.tmux ];
|
||||
|
||||
variables = {
|
||||
TMUX_TMPDIR = ''''${XDG_RUNTIME_DIR:-"/run/user/\$(id -u)"}'';
|
||||
TMUX_TMPDIR = lib.optional cfg.secureSocket ''''${XDG_RUNTIME_DIR:-"/run/user/\$(id -u)"}'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
78
nixos/modules/programs/way-cooler.nix
Normal file
78
nixos/modules/programs/way-cooler.nix
Normal file
@ -0,0 +1,78 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.programs.way-cooler;
|
||||
way-cooler = pkgs.way-cooler;
|
||||
|
||||
wcWrapped = pkgs.writeShellScriptBin "way-cooler" ''
|
||||
${cfg.extraSessionCommands}
|
||||
exec ${pkgs.dbus.dbus-launch} --exit-with-session ${way-cooler}/bin/way-cooler
|
||||
'';
|
||||
wcJoined = pkgs.symlinkJoin {
|
||||
name = "way-cooler-wrapped";
|
||||
paths = [ wcWrapped way-cooler ];
|
||||
};
|
||||
configFile = readFile "${way-cooler}/etc/way-cooler/init.lua";
|
||||
spawnBar = ''
|
||||
util.program.spawn_at_startup("lemonbar");
|
||||
'';
|
||||
in
|
||||
{
|
||||
options.programs.way-cooler = {
|
||||
enable = mkEnableOption "way-cooler";
|
||||
|
||||
extraSessionCommands = mkOption {
|
||||
default = "";
|
||||
type = types.lines;
|
||||
example = ''
|
||||
export XKB_DEFAULT_LAYOUT=us,de
|
||||
export XKB_DEFAULT_VARIANT=,nodeadkeys
|
||||
export XKB_DEFAULT_OPTIONS=grp:caps_toggle,
|
||||
'';
|
||||
description = ''
|
||||
Shell commands executed just before way-cooler is started.
|
||||
'';
|
||||
};
|
||||
|
||||
extraPackages = mkOption {
|
||||
type = with types; listOf package;
|
||||
default = with pkgs; [
|
||||
westonLite xwayland dmenu
|
||||
];
|
||||
example = literalExample ''
|
||||
with pkgs; [
|
||||
westonLite xwayland dmenu
|
||||
]
|
||||
'';
|
||||
description = ''
|
||||
Extra packages to be installed system wide.
|
||||
'';
|
||||
};
|
||||
|
||||
enableBar = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to enable an unofficial bar.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
environment.systemPackages = [ wcJoined ] ++ cfg.extraPackages;
|
||||
|
||||
security.pam.services.wc-lock = {};
|
||||
environment.etc."way-cooler/init.lua".text = ''
|
||||
${configFile}
|
||||
${optionalString cfg.enableBar spawnBar}
|
||||
'';
|
||||
|
||||
hardware.opengl.enable = mkDefault true;
|
||||
fonts.enableDefaultFonts = mkDefault true;
|
||||
programs.dconf.enable = mkDefault true;
|
||||
};
|
||||
|
||||
meta.maintainers = with maintainers; [ gnidorah ];
|
||||
}
|
@ -82,6 +82,10 @@ with lib;
|
||||
(mkRenamedOptionModule [ "services" "virtualboxHost" "addNetworkInterface" ] [ "virtualisation" "virtualbox" "host" "addNetworkInterface" ])
|
||||
(mkRenamedOptionModule [ "services" "virtualboxHost" "enableHardening" ] [ "virtualisation" "virtualbox" "host" "enableHardening" ])
|
||||
|
||||
# libvirtd
|
||||
(mkRemovedOptionModule [ "virtualisation" "libvirtd" "enableKVM" ]
|
||||
"Set the option `virtualisation.libvirtd.qemuPackage' instead.")
|
||||
|
||||
# Tarsnap
|
||||
(mkRenamedOptionModule [ "services" "tarsnap" "config" ] [ "services" "tarsnap" "archives" ])
|
||||
|
||||
@ -182,6 +186,9 @@ with lib;
|
||||
(mkRenamedOptionModule [ "config" "fonts" "fontconfig" "ultimate" "forceAutohint" ] [ "config" "fonts" "fontconfig" "forceAutohint" ])
|
||||
(mkRenamedOptionModule [ "config" "fonts" "fontconfig" "ultimate" "renderMonoTTFAsBitmap" ] [ "config" "fonts" "fontconfig" "renderMonoTTFAsBitmap" ])
|
||||
|
||||
# Profile splitting
|
||||
(mkRenamedOptionModule [ "virtualization" "growPartition" ] [ "boot" "growPartition" ])
|
||||
|
||||
# Options that are obsolete and have no replacement.
|
||||
(mkRemovedOptionModule [ "boot" "initrd" "luks" "enable" ] "")
|
||||
(mkRemovedOptionModule [ "programs" "bash" "enable" ] "")
|
||||
|
@ -223,6 +223,17 @@ let
|
||||
'';
|
||||
};
|
||||
|
||||
enableGnomeKeyring = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
If enabled, pam_gnome_keyring will attempt to automatically unlock the
|
||||
user's default Gnome keyring upon login. If the user login password does
|
||||
not match their keyring password, Gnome Keyring will prompt separately
|
||||
after login.
|
||||
'';
|
||||
};
|
||||
|
||||
text = mkOption {
|
||||
type = types.nullOr types.lines;
|
||||
description = "Contents of the PAM service file.";
|
||||
@ -273,7 +284,7 @@ let
|
||||
# prompts the user for password so we run it once with 'required' at an
|
||||
# earlier point and it will run again with 'sufficient' further down.
|
||||
# We use try_first_pass the second time to avoid prompting password twice
|
||||
(optionalString (cfg.unixAuth && (config.security.pam.enableEcryptfs || cfg.pamMount || cfg.enableKwallet)) ''
|
||||
(optionalString (cfg.unixAuth && (config.security.pam.enableEcryptfs || cfg.pamMount || cfg.enableKwallet || cfg.enableGnomeKeyring)) ''
|
||||
auth required pam_unix.so ${optionalString cfg.allowNullPassword "nullok"} likeauth
|
||||
${optionalString config.security.pam.enableEcryptfs
|
||||
"auth optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so unwrap"}
|
||||
@ -282,6 +293,8 @@ let
|
||||
${optionalString cfg.enableKwallet
|
||||
("auth optional ${pkgs.plasma5.kwallet-pam}/lib/security/pam_kwallet5.so" +
|
||||
" kwalletd=${pkgs.libsForQt5.kwallet.bin}/bin/kwalletd5")}
|
||||
${optionalString cfg.enableGnomeKeyring
|
||||
("auth optional ${pkgs.gnome3.gnome_keyring}/lib/security/pam_gnome_keyring.so")}
|
||||
'') + ''
|
||||
${optionalString cfg.unixAuth
|
||||
"auth sufficient pam_unix.so ${optionalString cfg.allowNullPassword "nullok"} likeauth try_first_pass"}
|
||||
@ -351,6 +364,10 @@ let
|
||||
${optionalString (cfg.enableKwallet)
|
||||
("session optional ${pkgs.plasma5.kwallet-pam}/lib/security/pam_kwallet5.so" +
|
||||
" kwalletd=${pkgs.libsForQt5.kwallet.bin}/bin/kwalletd5")}
|
||||
${optionalString (cfg.enableGnomeKeyring)
|
||||
"session optional ${pkgs.gnome3.gnome_keyring}/lib/security/pam_gnome_keyring.so auto_start"}
|
||||
${optionalString (config.virtualisation.lxc.lxcfs.enable)
|
||||
"session optional ${pkgs.lxcfs}/lib/security/pam_cgfs.so -c freezer,memory,name=systemd,unified,cpuset"}
|
||||
'');
|
||||
};
|
||||
|
||||
@ -519,7 +536,6 @@ in
|
||||
ftp = {};
|
||||
i3lock = {};
|
||||
i3lock-color = {};
|
||||
swaylock = {};
|
||||
screen = {};
|
||||
vlock = {};
|
||||
xlock = {};
|
||||
|
@ -17,7 +17,7 @@ let
|
||||
hardeningEnable = [ "pie" ];
|
||||
installPhase = ''
|
||||
mkdir -p $out/bin
|
||||
gcc -Wall -O2 -DWRAPPER_DIR=\"${parentWrapperDir}\" \
|
||||
$CC -Wall -O2 -DWRAPPER_DIR=\"${parentWrapperDir}\" \
|
||||
-lcap-ng -lcap ${./wrapper.c} -o $out/bin/security-wrapper
|
||||
'';
|
||||
};
|
||||
@ -79,7 +79,7 @@ let
|
||||
({ owner = "root";
|
||||
group = "root";
|
||||
} // s)
|
||||
else if
|
||||
else if
|
||||
(s ? "setuid" && s.setuid) ||
|
||||
(s ? "setgid" && s.setgid) ||
|
||||
(s ? "permissions")
|
||||
|
@ -4,17 +4,22 @@ with pkgs;
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
uid = config.ids.uids.mopidy;
|
||||
gid = config.ids.gids.mopidy;
|
||||
cfg = config.services.mopidy;
|
||||
|
||||
mopidyConf = writeText "mopidy.conf" cfg.configuration;
|
||||
|
||||
mopidyEnv = python.buildEnv.override {
|
||||
extraLibs = [ mopidy ] ++ cfg.extensionPackages;
|
||||
mopidyEnv = buildEnv {
|
||||
name = "mopidy-with-extensions-${mopidy.version}";
|
||||
paths = closePropagation cfg.extensionPackages;
|
||||
pathsToLink = [ "/${python.sitePackages}" ];
|
||||
buildInputs = [ makeWrapper ];
|
||||
postBuild = ''
|
||||
makeWrapper ${mopidy}/bin/mopidy $out/bin/mopidy \
|
||||
--prefix PYTHONPATH : $out/${python.sitePackages}
|
||||
'';
|
||||
};
|
||||
|
||||
in {
|
||||
|
||||
options = {
|
||||
@ -61,7 +66,6 @@ in {
|
||||
|
||||
};
|
||||
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
@ -115,7 +115,7 @@ in
|
||||
description = ''
|
||||
Print global archive statistics upon completion.
|
||||
The output is available via
|
||||
<command>systemctl status tarsnap@archive-name</command>.
|
||||
<command>systemctl status tarsnap-archive-name</command>.
|
||||
'';
|
||||
};
|
||||
|
||||
|
@ -1,39 +1,372 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
with types;
|
||||
|
||||
let
|
||||
|
||||
# Converts a plan like
|
||||
# { "1d" = "1h"; "1w" = "1d"; }
|
||||
# into
|
||||
# "1d=>1h,1w=>1d"
|
||||
attrToPlan = attrs: concatStringsSep "," (builtins.attrValues (
|
||||
mapAttrs (n: v: "${n}=>${v}") attrs));
|
||||
|
||||
planDescription = ''
|
||||
The znapzend backup plan to use for the source.
|
||||
</para>
|
||||
<para>
|
||||
The plan specifies how often to backup and for how long to keep the
|
||||
backups. It consists of a series of retention periodes to interval
|
||||
associations:
|
||||
</para>
|
||||
<para>
|
||||
<literal>
|
||||
retA=>intA,retB=>intB,...
|
||||
</literal>
|
||||
</para>
|
||||
<para>
|
||||
Both intervals and retention periods are expressed in standard units
|
||||
of time or multiples of them. You can use both the full name or a
|
||||
shortcut according to the following listing:
|
||||
</para>
|
||||
<para>
|
||||
<literal>
|
||||
second|sec|s, minute|min, hour|h, day|d, week|w, month|mon|m, year|y
|
||||
</literal>
|
||||
</para>
|
||||
<para>
|
||||
See <citerefentry><refentrytitle>znapzendzetup</refentrytitle><manvolnum>1</manvolnum></citerefentry> for more info.
|
||||
'';
|
||||
planExample = "1h=>10min,1d=>1h,1w=>1d,1m=>1w,1y=>1m";
|
||||
|
||||
# A type for a string of the form number{b|k|M|G}
|
||||
mbufferSizeType = str // {
|
||||
check = x: str.check x && builtins.isList (builtins.match "^[0-9]+[bkMG]$" x);
|
||||
description = "string of the form number{b|k|M|G}";
|
||||
};
|
||||
|
||||
# Type for a string that must contain certain other strings (the list parameter).
|
||||
# Note that these would need regex escaping.
|
||||
stringContainingStrings = list: let
|
||||
matching = s: map (str: builtins.match ".*${str}.*" s) list;
|
||||
in str // {
|
||||
check = x: str.check x && all isList (matching x);
|
||||
description = "string containing all of the characters ${concatStringsSep ", " list}";
|
||||
};
|
||||
|
||||
timestampType = stringContainingStrings [ "%Y" "%m" "%d" "%H" "%M" "%S" ];
|
||||
|
||||
destType = srcConfig: submodule ({ name, ... }: {
|
||||
options = {
|
||||
|
||||
label = mkOption {
|
||||
type = str;
|
||||
description = "Label for this destination. Defaults to the attribute name.";
|
||||
};
|
||||
|
||||
plan = mkOption {
|
||||
type = str;
|
||||
description = planDescription;
|
||||
example = planExample;
|
||||
};
|
||||
|
||||
dataset = mkOption {
|
||||
type = str;
|
||||
description = "Dataset name to send snapshots to.";
|
||||
example = "tank/main";
|
||||
};
|
||||
|
||||
host = mkOption {
|
||||
type = nullOr str;
|
||||
description = ''
|
||||
Host to use for the destination dataset. Can be prefixed with
|
||||
<literal>user@</literal> to specify the ssh user.
|
||||
'';
|
||||
default = null;
|
||||
example = "john@example.com";
|
||||
};
|
||||
|
||||
presend = mkOption {
|
||||
type = nullOr str;
|
||||
description = ''
|
||||
Command to run before sending the snapshot to the destination.
|
||||
Intended to run a remote script via <command>ssh</command> on the
|
||||
destination, e.g. to bring up a backup disk or server or to put a
|
||||
zpool online/offline. See also <option>postsend</option>.
|
||||
'';
|
||||
default = null;
|
||||
example = "ssh root@bserv zpool import -Nf tank";
|
||||
};
|
||||
|
||||
postsend = mkOption {
|
||||
type = nullOr str;
|
||||
description = ''
|
||||
Command to run after sending the snapshot to the destination.
|
||||
Intended to run a remote script via <command>ssh</command> on the
|
||||
destination, e.g. to bring up a backup disk or server or to put a
|
||||
zpool online/offline. See also <option>presend</option>.
|
||||
'';
|
||||
default = null;
|
||||
example = "ssh root@bserv zpool export tank";
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
label = mkDefault name;
|
||||
plan = mkDefault srcConfig.plan;
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
|
||||
srcType = submodule ({ name, config, ... }: {
|
||||
options = {
|
||||
|
||||
enable = mkOption {
|
||||
type = bool;
|
||||
description = "Whether to enable this source.";
|
||||
default = true;
|
||||
};
|
||||
|
||||
recursive = mkOption {
|
||||
type = bool;
|
||||
description = "Whether to do recursive snapshots.";
|
||||
default = false;
|
||||
};
|
||||
|
||||
mbuffer = {
|
||||
enable = mkOption {
|
||||
type = bool;
|
||||
description = "Whether to use <command>mbuffer</command>.";
|
||||
default = false;
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = nullOr ints.u16;
|
||||
description = ''
|
||||
Port to use for <command>mbuffer</command>.
|
||||
</para>
|
||||
<para>
|
||||
If this is null, it will run <command>mbuffer</command> through
|
||||
ssh.
|
||||
</para>
|
||||
<para>
|
||||
If this is not null, it will run <command>mbuffer</command>
|
||||
directly through TCP, which is not encrypted but faster. In that
|
||||
case the given port needs to be open on the destination host.
|
||||
'';
|
||||
default = null;
|
||||
};
|
||||
|
||||
size = mkOption {
|
||||
type = mbufferSizeType;
|
||||
description = ''
|
||||
The size for <command>mbuffer</command>.
|
||||
Supports the units b, k, M, G.
|
||||
'';
|
||||
default = "1G";
|
||||
example = "128M";
|
||||
};
|
||||
};
|
||||
|
||||
presnap = mkOption {
|
||||
type = nullOr str;
|
||||
description = ''
|
||||
Command to run before snapshots are taken on the source dataset,
|
||||
e.g. for database locking/flushing. See also
|
||||
<option>postsnap</option>.
|
||||
'';
|
||||
default = null;
|
||||
example = literalExample ''
|
||||
''${pkgs.mariadb}/bin/mysql -e "set autocommit=0;flush tables with read lock;\\! ''${pkgs.coreutils}/bin/sleep 600" & ''${pkgs.coreutils}/bin/echo $! > /tmp/mariadblock.pid ; sleep 10
|
||||
'';
|
||||
};
|
||||
|
||||
postsnap = mkOption {
|
||||
type = nullOr str;
|
||||
description = ''
|
||||
Command to run after snapshots are taken on the source dataset,
|
||||
e.g. for database unlocking. See also <option>presnap</option>.
|
||||
'';
|
||||
default = null;
|
||||
example = literalExample ''
|
||||
''${pkgs.coreutils}/bin/kill `''${pkgs.coreutils}/bin/cat /tmp/mariadblock.pid`;''${pkgs.coreutils}/bin/rm /tmp/mariadblock.pid
|
||||
'';
|
||||
};
|
||||
|
||||
timestampFormat = mkOption {
|
||||
type = timestampType;
|
||||
description = ''
|
||||
The timestamp format to use for constructing snapshot names.
|
||||
The syntax is <literal>strftime</literal>-like. The string must
|
||||
consist of the mandatory <literal>%Y %m %d %H %M %S</literal>.
|
||||
Optionally <literal>- _ . :</literal> characters as well as any
|
||||
alphanumeric character are allowed. If suffixed by a
|
||||
<literal>Z</literal>, times will be in UTC.
|
||||
'';
|
||||
default = "%Y-%m-%d-%H%M%S";
|
||||
example = "znapzend-%m.%d.%Y-%H%M%SZ";
|
||||
};
|
||||
|
||||
sendDelay = mkOption {
|
||||
type = int;
|
||||
description = ''
|
||||
Specify delay (in seconds) before sending snaps to the destination.
|
||||
May be useful if you want to control sending time.
|
||||
'';
|
||||
default = 0;
|
||||
example = 60;
|
||||
};
|
||||
|
||||
plan = mkOption {
|
||||
type = str;
|
||||
description = planDescription;
|
||||
example = planExample;
|
||||
};
|
||||
|
||||
dataset = mkOption {
|
||||
type = str;
|
||||
description = "The dataset to use for this source.";
|
||||
example = "tank/home";
|
||||
};
|
||||
|
||||
destinations = mkOption {
|
||||
type = loaOf (destType config);
|
||||
description = "Additional destinations.";
|
||||
default = {};
|
||||
example = literalExample ''
|
||||
{
|
||||
local = {
|
||||
dataset = "btank/backup";
|
||||
presend = "zpool import -N btank";
|
||||
postsend = "zpool export btank";
|
||||
};
|
||||
remote = {
|
||||
host = "john@example.com";
|
||||
dataset = "tank/john";
|
||||
};
|
||||
};
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
dataset = mkDefault name;
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
### Generating the configuration from here
|
||||
|
||||
cfg = config.services.znapzend;
|
||||
|
||||
onOff = b: if b then "on" else "off";
|
||||
nullOff = b: if isNull b then "off" else toString b;
|
||||
stripSlashes = replaceStrings [ "/" ] [ "." ];
|
||||
|
||||
attrsToFile = config: concatStringsSep "\n" (builtins.attrValues (
|
||||
mapAttrs (n: v: "${n}=${v}") config));
|
||||
|
||||
mkDestAttrs = dst: with dst;
|
||||
mapAttrs' (n: v: nameValuePair "dst_${label}${n}" v) ({
|
||||
"" = optionalString (! isNull host) "${host}:" + dataset;
|
||||
_plan = plan;
|
||||
} // optionalAttrs (presend != null) {
|
||||
_precmd = presend;
|
||||
} // optionalAttrs (postsend != null) {
|
||||
_pstcmd = postsend;
|
||||
});
|
||||
|
||||
mkSrcAttrs = srcCfg: with srcCfg; {
|
||||
enabled = onOff enable;
|
||||
mbuffer = with mbuffer; if enable then "${pkgs.mbuffer}/bin/mbuffer"
|
||||
+ optionalString (port != null) ":${toString port}" else "off";
|
||||
mbuffer_size = mbuffer.size;
|
||||
post_znap_cmd = nullOff postsnap;
|
||||
pre_znap_cmd = nullOff presnap;
|
||||
recursive = onOff recursive;
|
||||
src = dataset;
|
||||
src_plan = plan;
|
||||
tsformat = timestampFormat;
|
||||
zend_delay = toString sendDelay;
|
||||
} // fold (a: b: a // b) {} (
|
||||
map mkDestAttrs (builtins.attrValues destinations)
|
||||
);
|
||||
|
||||
files = mapAttrs' (n: srcCfg: let
|
||||
fileText = attrsToFile (mkSrcAttrs srcCfg);
|
||||
in {
|
||||
name = srcCfg.dataset;
|
||||
value = pkgs.writeText (stripSlashes srcCfg.dataset) fileText;
|
||||
}) cfg.zetup;
|
||||
|
||||
in
|
||||
{
|
||||
options = {
|
||||
services.znapzend = {
|
||||
enable = mkEnableOption "ZnapZend daemon";
|
||||
enable = mkEnableOption "ZnapZend ZFS backup daemon";
|
||||
|
||||
logLevel = mkOption {
|
||||
default = "debug";
|
||||
example = "warning";
|
||||
type = lib.types.enum ["debug" "info" "warning" "err" "alert"];
|
||||
description = "The log level when logging to file. Any of debug, info, warning, err, alert. Default in daemonized form is debug.";
|
||||
type = enum ["debug" "info" "warning" "err" "alert"];
|
||||
description = ''
|
||||
The log level when logging to file. Any of debug, info, warning, err,
|
||||
alert. Default in daemonized form is debug.
|
||||
'';
|
||||
};
|
||||
|
||||
logTo = mkOption {
|
||||
type = types.str;
|
||||
type = str;
|
||||
default = "syslog::daemon";
|
||||
example = "/var/log/znapzend.log";
|
||||
description = "Where to log to (syslog::<facility> or <filepath>).";
|
||||
description = ''
|
||||
Where to log to (syslog::<facility> or <filepath>).
|
||||
'';
|
||||
};
|
||||
|
||||
noDestroy = mkOption {
|
||||
type = types.bool;
|
||||
type = bool;
|
||||
default = false;
|
||||
description = "Does all changes to the filesystem except destroy.";
|
||||
};
|
||||
|
||||
autoCreation = mkOption {
|
||||
type = types.bool;
|
||||
type = bool;
|
||||
default = false;
|
||||
description = "Automatically create the destination dataset if it does not exists.";
|
||||
};
|
||||
|
||||
zetup = mkOption {
|
||||
type = loaOf srcType;
|
||||
description = "Znapzend configuration.";
|
||||
default = {};
|
||||
example = literalExample ''
|
||||
{
|
||||
"tank/home" = {
|
||||
# Make snapshots of tank/home every hour, keep those for 1 day,
|
||||
# keep every days snapshot for 1 month, etc.
|
||||
plan = "1d=>1h,1m=>1d,1y=>1m";
|
||||
recursive = true;
|
||||
# Send all those snapshots to john@example.com:rtank/john as well
|
||||
destinations.remote = {
|
||||
host = "john@example.com";
|
||||
dataset = "rtank/john";
|
||||
};
|
||||
};
|
||||
};
|
||||
'';
|
||||
};
|
||||
|
||||
pure = mkOption {
|
||||
type = bool;
|
||||
description = ''
|
||||
Do not persist any stateful znapzend setups. If this option is
|
||||
enabled, your previously set znapzend setups will be cleared and only
|
||||
the ones defined with this module will be applied.
|
||||
'';
|
||||
default = false;
|
||||
description = "Automatically create the dataset on dest if it does not exists.";
|
||||
};
|
||||
};
|
||||
};
|
||||
@ -49,12 +382,30 @@ in
|
||||
|
||||
path = with pkgs; [ zfs mbuffer openssh ];
|
||||
|
||||
preStart = optionalString cfg.pure ''
|
||||
echo Resetting znapzend zetups
|
||||
${pkgs.znapzend}/bin/znapzendzetup list \
|
||||
| grep -oP '(?<=\*\*\* backup plan: ).*(?= \*\*\*)' \
|
||||
| xargs ${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}
|
||||
'') files);
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = "${pkgs.znapzend}/bin/znapzend --logto=${cfg.logTo} --loglevel=${cfg.logLevel} ${optionalString cfg.noDestroy "--nodestroy"} ${optionalString cfg.autoCreation "--autoCreation"}";
|
||||
ExecStart = let
|
||||
args = concatStringsSep " " [
|
||||
"--logto=${cfg.logTo}"
|
||||
"--loglevel=${cfg.logLevel}"
|
||||
(optionalString cfg.noDestroy "--nodestroy")
|
||||
(optionalString cfg.autoCreation "--autoCreation")
|
||||
]; in "${pkgs.znapzend}/bin/znapzend ${args}";
|
||||
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
|
||||
Restart = "on-failure";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
meta.maintainers = with maintainers; [ infinisil ];
|
||||
}
|
||||
|
@ -48,6 +48,15 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
hooksPath = mkOption {
|
||||
type = types.path;
|
||||
default = "${pkgs.buildkite-agent}/share/hooks";
|
||||
defaultText = "${pkgs.buildkite-agent}/share/hooks";
|
||||
description = ''
|
||||
Path to the directory storing the hooks.
|
||||
'';
|
||||
};
|
||||
|
||||
meta-data = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
@ -114,8 +123,8 @@ in
|
||||
token="$(cat ${toString cfg.tokenPath})"
|
||||
name="${cfg.name}"
|
||||
meta-data="${cfg.meta-data}"
|
||||
hooks-path="${pkgs.buildkite-agent}/share/hooks"
|
||||
build-path="${cfg.dataDir}/builds"
|
||||
hooks-path="${cfg.hooksPath}"
|
||||
bootstrap-script="${pkgs.buildkite-agent}/share/bootstrap.sh"
|
||||
EOF
|
||||
'';
|
||||
|
@ -40,11 +40,7 @@ in
|
||||
description = "The port to bind to";
|
||||
};
|
||||
|
||||
socket = mkOption {
|
||||
default = "";
|
||||
description = "Unix socket path to listen on. Setting this will disable network support";
|
||||
example = "/var/run/memcached";
|
||||
};
|
||||
enableUnixSocket = mkEnableOption "unix socket at /run/memcached/memcached.sock";
|
||||
|
||||
maxMemory = mkOption {
|
||||
default = 64;
|
||||
@ -68,31 +64,40 @@ in
|
||||
|
||||
config = mkIf config.services.memcached.enable {
|
||||
|
||||
users.extraUsers.memcached =
|
||||
{ name = cfg.user;
|
||||
uid = config.ids.uids.memcached;
|
||||
description = "Memcached server user";
|
||||
};
|
||||
users.extraUsers = optional (cfg.user == "memcached") {
|
||||
name = "memcached";
|
||||
description = "Memcached server user";
|
||||
};
|
||||
|
||||
environment.systemPackages = [ memcached ];
|
||||
|
||||
systemd.services.memcached =
|
||||
{ description = "Memcached server";
|
||||
systemd.services.memcached = {
|
||||
description = "Memcached server";
|
||||
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart =
|
||||
let
|
||||
networking = if cfg.socket != ""
|
||||
then "-s ${cfg.socket}"
|
||||
else "-l ${cfg.listen} -p ${toString cfg.port}";
|
||||
in "${memcached}/bin/memcached ${networking} -m ${toString cfg.maxMemory} -c ${toString cfg.maxConnections} ${concatStringsSep " " cfg.extraOptions}";
|
||||
serviceConfig = {
|
||||
PermissionsStartOnly = true;
|
||||
ExecStartPre = optionals cfg.enableUnixSocket [
|
||||
"${pkgs.coreutils}/bin/install -d -o ${cfg.user} /run/memcached/"
|
||||
"${pkgs.coreutils}/bin/chown -R ${cfg.user} /run/memcached/"
|
||||
];
|
||||
ExecStart =
|
||||
let
|
||||
networking = if cfg.enableUnixSocket
|
||||
then "-s /run/memcached/memcached.sock"
|
||||
else "-l ${cfg.listen} -p ${toString cfg.port}";
|
||||
in "${memcached}/bin/memcached ${networking} -m ${toString cfg.maxMemory} -c ${toString cfg.maxConnections} ${concatStringsSep " " cfg.extraOptions}";
|
||||
|
||||
User = cfg.user;
|
||||
};
|
||||
User = cfg.user;
|
||||
};
|
||||
};
|
||||
};
|
||||
imports = [
|
||||
(mkRemovedOptionModule ["services" "memcached" "socket"] ''
|
||||
This option was replaced by a fixed unix socket path at /run/memcached/memcached.sock enabled using services.memached.enableUnixSocket.
|
||||
'')
|
||||
];
|
||||
|
||||
}
|
||||
|
@ -7,14 +7,12 @@ let
|
||||
cfg = config.services.mysql;
|
||||
|
||||
mysql = cfg.package;
|
||||
|
||||
isMariaDB =
|
||||
|
||||
isMariaDB =
|
||||
let
|
||||
pName = _p: (builtins.parseDrvName (_p.name)).name;
|
||||
in pName mysql == pName pkgs.mariadb;
|
||||
|
||||
atLeast55 = versionAtLeast mysql.mysqlVersion "5.5";
|
||||
|
||||
pidFile = "${cfg.pidDir}/mysqld.pid";
|
||||
|
||||
mysqldOptions =
|
||||
@ -28,13 +26,6 @@ let
|
||||
${optionalString (cfg.bind != null) "bind-address = ${cfg.bind}" }
|
||||
${optionalString (cfg.replication.role == "master" || cfg.replication.role == "slave") "log-bin=mysql-bin"}
|
||||
${optionalString (cfg.replication.role == "master" || cfg.replication.role == "slave") "server-id = ${toString cfg.replication.serverId}"}
|
||||
${optionalString (cfg.replication.role == "slave" && !atLeast55)
|
||||
''
|
||||
master-host = ${cfg.replication.masterHost}
|
||||
master-user = ${cfg.replication.masterUser}
|
||||
master-password = ${cfg.replication.masterPassword}
|
||||
master-port = ${toString cfg.replication.masterPort}
|
||||
''}
|
||||
${optionalString (cfg.ensureUsers != [])
|
||||
''
|
||||
plugin-load-add = auth_socket.so
|
||||
@ -315,7 +306,7 @@ in
|
||||
fi
|
||||
'') cfg.initialDatabases}
|
||||
|
||||
${optionalString (cfg.replication.role == "master" && atLeast55)
|
||||
${optionalString (cfg.replication.role == "master")
|
||||
''
|
||||
# Set up the replication master
|
||||
|
||||
@ -326,7 +317,7 @@ in
|
||||
) | ${mysql}/bin/mysql -u root -N
|
||||
''}
|
||||
|
||||
${optionalString (cfg.replication.role == "slave" && atLeast55)
|
||||
${optionalString (cfg.replication.role == "slave")
|
||||
''
|
||||
# Set up the replication slave
|
||||
|
||||
|
@ -219,7 +219,6 @@ in
|
||||
|
||||
users.extraUsers.redis =
|
||||
{ name = cfg.user;
|
||||
uid = config.ids.uids.redis;
|
||||
description = "Redis database user";
|
||||
};
|
||||
|
||||
|
@ -28,14 +28,15 @@ with lib;
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf config.services.gnome3.at-spi2-core.enable {
|
||||
|
||||
environment.systemPackages = [ pkgs.at_spi2_core ];
|
||||
|
||||
services.dbus.packages = [ pkgs.at_spi2_core ];
|
||||
|
||||
systemd.packages = [ pkgs.at_spi2_core ];
|
||||
|
||||
};
|
||||
config = mkMerge [
|
||||
(mkIf config.services.gnome3.at-spi2-core.enable {
|
||||
environment.systemPackages = [ pkgs.at_spi2_core ];
|
||||
services.dbus.packages = [ pkgs.at_spi2_core ];
|
||||
systemd.packages = [ pkgs.at_spi2_core ];
|
||||
})
|
||||
|
||||
(mkIf (!config.services.gnome3.at-spi2-core.enable) {
|
||||
environment.variables.NO_AT_BRIDGE = "1";
|
||||
})
|
||||
];
|
||||
}
|
||||
|
@ -1,105 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
with lib;
|
||||
let
|
||||
|
||||
cfg = config.services.ghostOne;
|
||||
ghostUser = "ghostone";
|
||||
stateDir = "/var/lib/ghost-one";
|
||||
|
||||
in
|
||||
{
|
||||
|
||||
###### interface
|
||||
|
||||
options = {
|
||||
services.ghostOne = {
|
||||
|
||||
enable = mkOption {
|
||||
default = false;
|
||||
description = "Enable Ghost-One Warcraft3 game hosting server.";
|
||||
};
|
||||
|
||||
language = mkOption {
|
||||
default = "English";
|
||||
type = types.enum [ "English" "Spanish" "Russian" "Serbian" "Turkish" ];
|
||||
description = "The language of bot messages: English, Spanish, Russian, Serbian or Turkish.";
|
||||
};
|
||||
|
||||
war3path = mkOption {
|
||||
default = "";
|
||||
description = ''
|
||||
The path to your local Warcraft III directory, which must contain war3.exe, storm.dll, and game.dll.
|
||||
'';
|
||||
};
|
||||
|
||||
mappath = mkOption {
|
||||
default = "";
|
||||
description = ''
|
||||
The path to the directory where you keep your map files. GHost One doesn't require
|
||||
map files but if it has access to them it can send them to players and automatically
|
||||
calculate most map config values. GHost One will search [bot_mappath + map_localpath]
|
||||
for the map file (map_localpath is set in each map's config file).
|
||||
'';
|
||||
};
|
||||
|
||||
config = mkOption {
|
||||
default = "";
|
||||
description = "Extra configuration options.";
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
users.extraUsers = singleton
|
||||
{ name = ghostUser;
|
||||
uid = config.ids.uids.ghostone;
|
||||
description = "Ghost One game server user";
|
||||
home = stateDir;
|
||||
};
|
||||
|
||||
users.extraGroups = singleton
|
||||
{ name = ghostUser;
|
||||
gid = config.ids.gids.ghostone;
|
||||
};
|
||||
|
||||
services.ghostOne.config = ''
|
||||
# bot_log = /dev/stderr
|
||||
bot_language = ${pkgs.ghostOne}/share/ghost-one/languages/${cfg.language}.cfg
|
||||
bot_war3path = ${cfg.war3path}
|
||||
|
||||
bot_mapcfgpath = mapcfgs
|
||||
bot_savegamepath = savegames
|
||||
bot_mappath = ${cfg.mappath}
|
||||
bot_replaypath = replays
|
||||
'';
|
||||
|
||||
systemd.services."ghost-one" = {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
script = ''
|
||||
mkdir -p ${stateDir}
|
||||
cd ${stateDir}
|
||||
chown ${ghostUser}:${ghostUser} .
|
||||
|
||||
mkdir -p mapcfgs
|
||||
chown ${ghostUser}:${ghostUser} mapcfgs
|
||||
|
||||
mkdir -p replays
|
||||
chown ${ghostUser}:${ghostUser} replays
|
||||
|
||||
mkdir -p savegames
|
||||
chown ${ghostUser}:${ghostUser} savegames
|
||||
|
||||
ln -sf ${pkgs.writeText "ghost.cfg" cfg.config} ghost.cfg
|
||||
ln -sf ${pkgs.ghostOne}/share/ghost-one/ip-to-country.csv
|
||||
${pkgs.su}/bin/su -s ${pkgs.stdenv.shell} ${ghostUser} \
|
||||
-c "LANG=C ${pkgs.ghostOne}/bin/ghost++"
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
# Copied from systemd 203.
|
||||
ACTION=="remove", GOTO="net_name_slot_end"
|
||||
SUBSYSTEM!="net", GOTO="net_name_slot_end"
|
||||
NAME!="", GOTO="net_name_slot_end"
|
||||
|
||||
IMPORT{cmdline}="net.ifnames"
|
||||
ENV{net.ifnames}=="0", GOTO="net_name_slot_end"
|
||||
|
||||
NAME=="", ENV{ID_NET_NAME_ONBOARD}!="", NAME="$env{ID_NET_NAME_ONBOARD}"
|
||||
NAME=="", ENV{ID_NET_NAME_SLOT}!="", NAME="$env{ID_NET_NAME_SLOT}"
|
||||
NAME=="", ENV{ID_NET_NAME_PATH}!="", NAME="$env{ID_NET_NAME_PATH}"
|
||||
|
||||
LABEL="net_name_slot_end"
|
@ -55,7 +55,7 @@ in {
|
||||
enable = mkOption {
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to enable thinkfan, fan controller for ibm/lenovo thinkpads.
|
||||
Whether to enable thinkfan, fan controller for IBM/Lenovo ThinkPads.
|
||||
'';
|
||||
};
|
||||
|
||||
|
23
nixos/modules/services/hardware/u2f.nix
Normal file
23
nixos/modules/services/hardware/u2f.nix
Normal file
@ -0,0 +1,23 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.hardware.u2f;
|
||||
in {
|
||||
options = {
|
||||
hardware.u2f = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Enable U2F hardware support.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.udev.packages = [ pkgs.libu2f-host ];
|
||||
};
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ let
|
||||
fi
|
||||
|
||||
${optionalString config.networking.usePredictableInterfaceNames ''
|
||||
cp ${./80-net-setup-link.rules} $out/80-net-setup-link.rules
|
||||
cp ${udev}/lib/udev/rules.d/80-net-setup-link.rules $out/80-net-setup-link.rules
|
||||
''}
|
||||
|
||||
# If auto-configuration is disabled, then remove
|
||||
|
74
nixos/modules/services/hardware/usbmuxd.nix
Normal file
74
nixos/modules/services/hardware/usbmuxd.nix
Normal file
@ -0,0 +1,74 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
defaultUserGroup = "usbmux";
|
||||
apple = "05ac";
|
||||
|
||||
cfg = config.services.usbmuxd;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
options.services.usbmuxd = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Enable the usbmuxd ("USB multiplexing daemon") service. This daemon is
|
||||
in charge of multiplexing connections over USB to an iOS device. This is
|
||||
needed for transferring data from and to iOS devices (see ifuse). Also
|
||||
this may enable plug-n-play tethering for iPhones.
|
||||
'';
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
default = defaultUserGroup;
|
||||
description = ''
|
||||
The user usbmuxd should use to run after startup.
|
||||
'';
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
default = defaultUserGroup;
|
||||
description = ''
|
||||
The group usbmuxd should use to run after startup.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
users.extraUsers = optional (cfg.user == defaultUserGroup) {
|
||||
name = cfg.user;
|
||||
description = "usbmuxd user";
|
||||
group = cfg.group;
|
||||
};
|
||||
|
||||
users.extraGroups = optional (cfg.group == defaultUserGroup) {
|
||||
name = cfg.group;
|
||||
};
|
||||
|
||||
# Give usbmuxd permission for Apple devices
|
||||
services.udev.extraRules = ''
|
||||
SUBSYSTEM=="usb", ATTR{idVendor}=="${apple}", GROUP="${cfg.group}"
|
||||
'';
|
||||
|
||||
systemd.services.usbmuxd = {
|
||||
description = "usbmuxd";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
unitConfig.Documentation = "man:usbmuxd(8)";
|
||||
serviceConfig = {
|
||||
# Trigger the udev rule manually. This doesn't require replugging the
|
||||
# device when first enabling the option to get it to work
|
||||
ExecStartPre = "${pkgs.libudev}/bin/udevadm trigger -s usb -a idVendor=${apple}";
|
||||
ExecStart = "${pkgs.usbmuxd}/bin/usbmuxd -U ${cfg.user} -f";
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
}
|
@ -8,7 +8,7 @@ let
|
||||
defaultRules = pkgs.runCommand "logcheck-default-rules" {} ''
|
||||
cp -prd ${pkgs.logcheck}/etc/logcheck $out
|
||||
chmod u+w $out
|
||||
rm $out/logcheck.*
|
||||
rm -r $out/logcheck.*
|
||||
'';
|
||||
|
||||
rulesDir = pkgs.symlinkJoin
|
||||
|
@ -103,7 +103,7 @@ in
|
||||
|
||||
listenAddress = mkOption {
|
||||
type = types.str;
|
||||
default = "0.0.0.0";
|
||||
default = "127.0.0.1";
|
||||
description = "Address on which to start webserver.";
|
||||
};
|
||||
|
||||
|
179
nixos/modules/services/mail/clamsmtp.nix
Normal file
179
nixos/modules/services/mail/clamsmtp.nix
Normal file
@ -0,0 +1,179 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.services.clamsmtp;
|
||||
clamdSocket = "/run/clamav/clamd.ctl"; # See services/security/clamav.nix
|
||||
in
|
||||
{
|
||||
##### interface
|
||||
options = {
|
||||
services.clamsmtp = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Whether to enable clamsmtp.";
|
||||
};
|
||||
|
||||
instances = mkOption {
|
||||
description = "Instances of clamsmtp to run.";
|
||||
type = types.listOf (types.submodule { options = {
|
||||
action = mkOption {
|
||||
type = types.enum [ "bounce" "drop" "pass" ];
|
||||
default = "drop";
|
||||
description =
|
||||
''
|
||||
Action to take when a virus is detected.
|
||||
|
||||
Note that viruses often spoof sender addresses, so bouncing is
|
||||
in most cases not a good idea.
|
||||
'';
|
||||
};
|
||||
|
||||
header = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
example = "X-Virus-Scanned: ClamAV using ClamSMTP";
|
||||
description =
|
||||
''
|
||||
A header to add to scanned messages. See clamsmtpd.conf(5) for
|
||||
more details. Empty means no header.
|
||||
'';
|
||||
};
|
||||
|
||||
keepAlives = mkOption {
|
||||
type = types.int;
|
||||
default = 0;
|
||||
description =
|
||||
''
|
||||
Number of seconds to wait between each NOOP sent to the sending
|
||||
server. 0 to disable.
|
||||
|
||||
This is meant for slow servers where the sending MTA times out
|
||||
waiting for clamd to scan the file.
|
||||
'';
|
||||
};
|
||||
|
||||
listen = mkOption {
|
||||
type = types.str;
|
||||
example = "127.0.0.1:10025";
|
||||
description =
|
||||
''
|
||||
Address to wait for incoming SMTP connections on. See
|
||||
clamsmtpd.conf(5) for more details.
|
||||
'';
|
||||
};
|
||||
|
||||
quarantine = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description =
|
||||
''
|
||||
Whether to quarantine files that contain viruses by leaving them
|
||||
in the temporary directory.
|
||||
'';
|
||||
};
|
||||
|
||||
maxConnections = mkOption {
|
||||
type = types.int;
|
||||
default = 64;
|
||||
description = "Maximum number of connections to accept at once.";
|
||||
};
|
||||
|
||||
outAddress = mkOption {
|
||||
type = types.str;
|
||||
description =
|
||||
''
|
||||
Address of the SMTP server to send email to once it has been
|
||||
scanned.
|
||||
'';
|
||||
};
|
||||
|
||||
tempDirectory = mkOption {
|
||||
type = types.str;
|
||||
default = "/tmp";
|
||||
description =
|
||||
''
|
||||
Temporary directory that needs to be accessible to both clamd
|
||||
and clamsmtpd.
|
||||
'';
|
||||
};
|
||||
|
||||
timeout = mkOption {
|
||||
type = types.int;
|
||||
default = 180;
|
||||
description = "Time-out for network connections.";
|
||||
};
|
||||
|
||||
transparentProxy = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Enable clamsmtp's transparent proxy support.";
|
||||
};
|
||||
|
||||
virusAction = mkOption {
|
||||
type = with types; nullOr path;
|
||||
default = null;
|
||||
description =
|
||||
''
|
||||
Command to run when a virus is found. Please see VIRUS ACTION in
|
||||
clamsmtpd(8) for a discussion of this option and its safe use.
|
||||
'';
|
||||
};
|
||||
|
||||
xClient = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description =
|
||||
''
|
||||
Send the XCLIENT command to the receiving server, for forwarding
|
||||
client addresses and connection information if the receiving
|
||||
server supports this feature.
|
||||
'';
|
||||
};
|
||||
};});
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
##### implementation
|
||||
config = let
|
||||
configfile = conf: pkgs.writeText "clamsmtpd.conf"
|
||||
''
|
||||
Action: ${conf.action}
|
||||
ClamAddress: ${clamdSocket}
|
||||
Header: ${conf.header}
|
||||
KeepAlives: ${toString conf.keepAlives}
|
||||
Listen: ${conf.listen}
|
||||
Quarantine: ${if conf.quarantine then "on" else "off"}
|
||||
MaxConnections: ${toString conf.maxConnections}
|
||||
OutAddress: ${conf.outAddress}
|
||||
TempDirectory: ${conf.tempDirectory}
|
||||
TimeOut: ${toString conf.timeout}
|
||||
TransparentProxy: ${if conf.transparentProxy then "on" else "off"}
|
||||
User: clamav
|
||||
${optionalString (conf.virusAction != null) "VirusAction: ${conf.virusAction}"}
|
||||
XClient: ${if conf.xClient then "on" else "off"}
|
||||
'';
|
||||
in
|
||||
mkIf cfg.enable {
|
||||
assertions = [
|
||||
{ assertion = config.services.clamav.daemon.enable;
|
||||
message = "clamsmtp requires clamav to be enabled";
|
||||
}
|
||||
];
|
||||
|
||||
systemd.services = listToAttrs (imap1 (i: conf:
|
||||
nameValuePair "clamsmtp-${toString i}" {
|
||||
description = "ClamSMTP instance ${toString i}";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
script = "exec ${pkgs.clamsmtp}/bin/clamsmtpd -f ${configfile conf}";
|
||||
after = [ "clamav-daemon.service" ];
|
||||
requires = [ "clamav-daemon.service" ];
|
||||
serviceConfig.Type = "forking";
|
||||
serviceConfig.PrivateTmp = "yes";
|
||||
unitConfig.JoinsNamespaceOf = "clamav-daemon.service";
|
||||
}
|
||||
) cfg.instances);
|
||||
};
|
||||
}
|
118
nixos/modules/services/mail/dkimproxy-out.nix
Normal file
118
nixos/modules/services/mail/dkimproxy-out.nix
Normal file
@ -0,0 +1,118 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.services.dkimproxy-out;
|
||||
keydir = "/var/lib/dkimproxy-out";
|
||||
privkey = "${keydir}/private.key";
|
||||
pubkey = "${keydir}/public.key";
|
||||
in
|
||||
{
|
||||
##### interface
|
||||
options = {
|
||||
services.dkimproxy-out = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description =
|
||||
''
|
||||
Whether to enable dkimproxy_out.
|
||||
|
||||
Note that a key will be auto-generated, and can be found in
|
||||
${keydir}.
|
||||
'';
|
||||
};
|
||||
|
||||
listen = mkOption {
|
||||
type = types.str;
|
||||
example = "127.0.0.1:10027";
|
||||
description = "Address:port DKIMproxy should listen on.";
|
||||
};
|
||||
|
||||
relay = mkOption {
|
||||
type = types.str;
|
||||
example = "127.0.0.1:10028";
|
||||
description = "Address:port DKIMproxy should forward mail to.";
|
||||
};
|
||||
|
||||
domains = mkOption {
|
||||
type = with types; listOf str;
|
||||
example = [ "example.org" "example.com" ];
|
||||
description = "List of domains DKIMproxy can sign for.";
|
||||
};
|
||||
|
||||
selector = mkOption {
|
||||
type = types.str;
|
||||
example = "selector1";
|
||||
description =
|
||||
''
|
||||
The selector to use for DKIM key identification.
|
||||
|
||||
For example, if 'selector1' is used here, then for each domain
|
||||
'example.org' given in `domain`, 'selector1._domainkey.example.org'
|
||||
should contain the TXT record indicating the public key is the one
|
||||
in ${pubkey}: "v=DKIM1; t=s; p=[THE PUBLIC KEY]".
|
||||
'';
|
||||
};
|
||||
|
||||
keySize = mkOption {
|
||||
type = types.int;
|
||||
default = 2048;
|
||||
description =
|
||||
''
|
||||
Size of the RSA key to use to sign outgoing emails. Note that the
|
||||
maximum mandatorily verified as per RFC6376 is 2048.
|
||||
'';
|
||||
};
|
||||
|
||||
# TODO: allow signature for other schemes than dkim(c=relaxed/relaxed)?
|
||||
# This being the scheme used by gmail, maybe nothing more is needed for
|
||||
# reasonable use.
|
||||
};
|
||||
};
|
||||
|
||||
##### implementation
|
||||
config = let
|
||||
configfile = pkgs.writeText "dkimproxy_out.conf"
|
||||
''
|
||||
listen ${cfg.listen}
|
||||
relay ${cfg.relay}
|
||||
|
||||
domain ${concatStringsSep "," cfg.domains}
|
||||
selector ${cfg.selector}
|
||||
|
||||
signature dkim(c=relaxed/relaxed)
|
||||
|
||||
keyfile ${privkey}
|
||||
'';
|
||||
in
|
||||
mkIf cfg.enable {
|
||||
users.groups.dkimproxy-out = {};
|
||||
users.users.dkimproxy-out = {
|
||||
description = "DKIMproxy_out daemon";
|
||||
group = "dkimproxy-out";
|
||||
isSystemUser = true;
|
||||
};
|
||||
|
||||
systemd.services.dkimproxy-out = {
|
||||
description = "DKIMproxy_out";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
preStart = ''
|
||||
if [ ! -d "${keydir}" ]; then
|
||||
mkdir -p "${keydir}"
|
||||
chmod 0700 "${keydir}"
|
||||
${pkgs.openssl}/bin/openssl genrsa -out "${privkey}" ${toString cfg.keySize}
|
||||
${pkgs.openssl}/bin/openssl rsa -in "${privkey}" -pubout -out "${pubkey}"
|
||||
chown -R dkimproxy-out:dkimproxy-out "${keydir}"
|
||||
fi
|
||||
'';
|
||||
script = ''
|
||||
exec ${pkgs.dkimproxy}/bin/dkimproxy.out --conf_file=${configfile}
|
||||
'';
|
||||
serviceConfig = {
|
||||
User = "dkimproxy-out";
|
||||
PermissionsStartOnly = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
@ -31,6 +31,8 @@ let
|
||||
${mkBindSockets cfg.bindUISocket}
|
||||
.include "$CONFDIR/worker-controller.inc"
|
||||
}
|
||||
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
|
||||
in
|
||||
@ -79,6 +81,15 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Extra configuration to add at the end of the rspamd configuration
|
||||
file.
|
||||
'';
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.string;
|
||||
default = "rspamd";
|
||||
|
@ -192,9 +192,11 @@ in
|
||||
mysqlPassword = builtins.readFile (config.services.mysql.rootPassword);
|
||||
};
|
||||
}
|
||||
// lib.optionalAttrs (config.services.postgresql.enable && cfg.enableAuthentication) { postgresql-database = {
|
||||
postgresqlUsername = "root";
|
||||
}; }
|
||||
// lib.optionalAttrs (config.services.postgresql.enable) { postgresql-database = {
|
||||
} // lib.optionalAttrs (cfg.enableAuthentication) {
|
||||
postgresqlUsername = "postgres";
|
||||
};
|
||||
}
|
||||
// lib.optionalAttrs (config.services.tomcat.enable) { tomcat-webapplication = {
|
||||
tomcatPort = 8080;
|
||||
}; }
|
||||
|
@ -29,8 +29,12 @@ let
|
||||
|
||||
gitalyToml = pkgs.writeText "gitaly.toml" ''
|
||||
socket_path = "${lib.escape ["\""] gitalySocket}"
|
||||
bin_dir = "${cfg.packages.gitaly}/bin"
|
||||
prometheus_listen_addr = "localhost:9236"
|
||||
|
||||
[git]
|
||||
bin_path = "${pkgs.git}/bin/git"
|
||||
|
||||
[gitaly-ruby]
|
||||
dir = "${cfg.packages.gitaly.ruby}"
|
||||
|
||||
@ -70,7 +74,7 @@ let
|
||||
secret_key_base: ${cfg.secrets.secret}
|
||||
otp_key_base: ${cfg.secrets.otp}
|
||||
db_key_base: ${cfg.secrets.db}
|
||||
jws_private_key: ${builtins.toJSON cfg.secrets.jws}
|
||||
openid_connect_signing_key: ${builtins.toJSON cfg.secrets.jws}
|
||||
'';
|
||||
|
||||
gitlabConfig = {
|
||||
@ -104,6 +108,7 @@ let
|
||||
ldap.enabled = false;
|
||||
omniauth.enabled = false;
|
||||
shared.path = "${cfg.statePath}/shared";
|
||||
gitaly.client_path = "${cfg.packages.gitaly}/bin";
|
||||
backup.path = "${cfg.backupPath}";
|
||||
gitlab_shell = {
|
||||
path = "${cfg.packages.gitlab-shell}";
|
||||
@ -117,8 +122,6 @@ let
|
||||
};
|
||||
git = {
|
||||
bin_path = "git";
|
||||
max_size = 20971520; # 20MB
|
||||
timeout = 10;
|
||||
};
|
||||
monitoring = {
|
||||
ip_whitelist = [ "127.0.0.0/8" "::1/128" ];
|
||||
@ -248,7 +251,6 @@ in {
|
||||
|
||||
databasePassword = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = "Gitlab database user password.";
|
||||
};
|
||||
|
||||
@ -440,12 +442,6 @@ in {
|
||||
|
||||
environment.systemPackages = [ pkgs.git gitlab-rake cfg.packages.gitlab-shell ];
|
||||
|
||||
assertions = [
|
||||
{ assertion = cfg.databasePassword != "";
|
||||
message = "databasePassword must be set";
|
||||
}
|
||||
];
|
||||
|
||||
# Redis is required for the sidekiq queue runner.
|
||||
services.redis.enable = mkDefault true;
|
||||
# We use postgres as the main data store.
|
||||
@ -496,7 +492,9 @@ in {
|
||||
after = [ "network.target" "gitlab.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
environment.HOME = gitlabEnv.HOME;
|
||||
path = with pkgs; [ gitAndTools.git cfg.packages.gitaly.rubyEnv ];
|
||||
environment.GEM_HOME = "${cfg.packages.gitaly.rubyEnv}/${ruby.gemPath}";
|
||||
environment.GITLAB_SHELL_CONFIG_PATH = gitlabEnv.GITLAB_SHELL_CONFIG_PATH;
|
||||
path = with pkgs; [ gitAndTools.git cfg.packages.gitaly.rubyEnv ruby ];
|
||||
serviceConfig = {
|
||||
#PermissionsStartOnly = true; # preStart must be run as root
|
||||
Type = "simple";
|
||||
|
@ -207,7 +207,7 @@ in
|
||||
gitolite setup -pk ${pubkeyFile}
|
||||
fi
|
||||
if [ -n "${hooks}" ]; then
|
||||
cp ${hooks} .gitolite/hooks/common/
|
||||
cp -f ${hooks} .gitolite/hooks/common/
|
||||
chmod +x .gitolite/hooks/common/*
|
||||
fi
|
||||
gitolite setup # Upgrade if needed
|
||||
|
@ -32,6 +32,24 @@ in
|
||||
description = "Content of the configuration file";
|
||||
};
|
||||
|
||||
mathjax = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Enable support for math rendering using MathJax";
|
||||
};
|
||||
|
||||
allowUploads = mkOption {
|
||||
type = types.nullOr (types.enum [ "dir" "page" ]);
|
||||
default = null;
|
||||
description = "Enable uploads of external files";
|
||||
};
|
||||
|
||||
emoji = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Parse and interpret emoji tags";
|
||||
};
|
||||
|
||||
branch = mkOption {
|
||||
type = types.str;
|
||||
default = "master";
|
||||
@ -84,6 +102,9 @@ in
|
||||
--host ${cfg.address} \
|
||||
--config ${builtins.toFile "gollum-config.rb" cfg.extraConfig} \
|
||||
--ref ${cfg.branch} \
|
||||
${optionalString cfg.mathjax "--mathjax"} \
|
||||
${optionalString cfg.emoji "--emoji"} \
|
||||
${optionalString (cfg.allowUploads != null) "--allow-uploads ${cfg.allowUploads}"} \
|
||||
${cfg.stateDir}
|
||||
'';
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
{ config, lib, ... }:
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
|
@ -578,6 +578,18 @@ in {
|
||||
Extra config options for matrix-synapse.
|
||||
'';
|
||||
};
|
||||
extraConfigFiles = mkOption {
|
||||
type = types.listOf types.path;
|
||||
default = [];
|
||||
description = ''
|
||||
Extra config files to include.
|
||||
|
||||
The configuration files will be included based on the command line
|
||||
argument --config-path. This allows to configure secrets without
|
||||
having to go through the Nix store, e.g. based on deployment keys if
|
||||
NixOPS is in use.
|
||||
'';
|
||||
};
|
||||
logConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = readFile ./matrix-synapse-log_config.yaml;
|
||||
@ -627,7 +639,11 @@ in {
|
||||
Group = "matrix-synapse";
|
||||
WorkingDirectory = cfg.dataDir;
|
||||
PermissionsStartOnly = true;
|
||||
ExecStart = "${cfg.package}/bin/homeserver --config-path ${configFile} --keys-directory ${cfg.dataDir}";
|
||||
ExecStart = ''
|
||||
${cfg.package}/bin/homeserver \
|
||||
${ concatMapStringsSep "\n " (x: "--config-path ${x} \\") ([ configFile ] ++ cfg.extraConfigFiles) }
|
||||
--keys-directory ${cfg.dataDir}
|
||||
'';
|
||||
Restart = "on-failure";
|
||||
};
|
||||
};
|
||||
|
@ -8,13 +8,7 @@ let
|
||||
|
||||
in {
|
||||
options.services.mbpfan = {
|
||||
enable = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to enable the mbpfan daemon.
|
||||
'';
|
||||
};
|
||||
enable = mkEnableOption "mbpfan, fan controller daemon for Apple Macs and MacBooks";
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
|
85
nixos/modules/services/misc/osrm.nix
Normal file
85
nixos/modules/services/misc/osrm.nix
Normal file
@ -0,0 +1,85 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.osrm;
|
||||
in
|
||||
|
||||
{
|
||||
options.services.osrm = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Enable the OSRM service.";
|
||||
};
|
||||
|
||||
address = mkOption {
|
||||
type = types.str;
|
||||
default = "0.0.0.0";
|
||||
description = "IP address on which the web server will listen.";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.int;
|
||||
default = 5000;
|
||||
description = "Port on which the web server will run.";
|
||||
};
|
||||
|
||||
threads = mkOption {
|
||||
type = types.int;
|
||||
default = 4;
|
||||
description = "Number of threads to use.";
|
||||
};
|
||||
|
||||
algorithm = mkOption {
|
||||
type = types.enum [ "CH" "CoreCH" "MLD" ];
|
||||
default = "MLD";
|
||||
description = "Algorithm to use for the data. Must be one of CH, CoreCH, MLD";
|
||||
};
|
||||
|
||||
extraFlags = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
example = [ "--max-table-size 1000" "--max-matching-size 1000" ];
|
||||
description = "Extra command line arguments passed to osrm-routed";
|
||||
};
|
||||
|
||||
dataFile = mkOption {
|
||||
type = types.path;
|
||||
example = "/var/lib/osrm/berlin-latest.osrm";
|
||||
description = "Data file location";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
users.users.osrm = {
|
||||
group = config.users.users.osrm.name;
|
||||
description = "OSRM user";
|
||||
createHome = false;
|
||||
};
|
||||
|
||||
users.groups.osrm = { };
|
||||
|
||||
systemd.services.osrm = {
|
||||
description = "OSRM service";
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
serviceConfig = {
|
||||
User = config.users.extraUsers.osrm.name;
|
||||
ExecStart = ''
|
||||
${pkgs.osrm-backend}/bin/osrm-routed \
|
||||
--ip ${cfg.address} \
|
||||
--port ${toString cfg.port} \
|
||||
--threads ${toString cfg.threads} \
|
||||
--algorithm ${cfg.algorithm} \
|
||||
${toString cfg.extraFlags} \
|
||||
${cfg.dataFile}
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
73
nixos/modules/services/misc/xmr-stak.nix
Normal file
73
nixos/modules/services/misc/xmr-stak.nix
Normal file
@ -0,0 +1,73 @@
|
||||
{ lib, config, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.xmr-stak;
|
||||
|
||||
pkg = pkgs.xmr-stak.override {
|
||||
inherit (cfg) openclSupport cudaSupport;
|
||||
};
|
||||
|
||||
xmrConfArg = optionalString (cfg.configText != "") ("-c " +
|
||||
pkgs.writeText "xmr-stak-config.txt" cfg.configText);
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
options = {
|
||||
services.xmr-stak = {
|
||||
enable = mkEnableOption "xmr-stak miner";
|
||||
openclSupport = mkEnableOption "support for OpenCL (AMD/ATI graphics cards)";
|
||||
cudaSupport = mkEnableOption "support for CUDA (NVidia graphics cards)";
|
||||
|
||||
extraArgs = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
example = [ "--noCPU" "--currency monero" ];
|
||||
description = "List of parameters to pass to xmr-stak.";
|
||||
};
|
||||
|
||||
configText = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
example = ''
|
||||
"currency" : "monero",
|
||||
"pool_list" :
|
||||
[ { "pool_address" : "pool.supportxmr.com:5555",
|
||||
"wallet_address" : "<long-hash>",
|
||||
"pool_password" : "minername",
|
||||
"pool_weight" : 1,
|
||||
},
|
||||
],
|
||||
'';
|
||||
description = ''
|
||||
Verbatim xmr-stak config.txt. If empty, the <literal>-c</literal>
|
||||
parameter will not be added to the xmr-stak command.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
systemd.services.xmr-stak = {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
bindsTo = [ "network-online.target" ];
|
||||
after = [ "network-online.target" ];
|
||||
environment = mkIf cfg.cudaSupport {
|
||||
LD_LIBRARY_PATH = "${pkgs.linuxPackages_latest.nvidia_x11}/lib";
|
||||
};
|
||||
script = ''
|
||||
exec ${pkg}/bin/xmr-stak ${xmrConfArg} ${concatStringsSep " " cfg.extraArgs}
|
||||
'';
|
||||
serviceConfig = let rootRequired = cfg.openclSupport || cfg.cudaSupport; in {
|
||||
# xmr-stak generates cpu and/or gpu configuration files
|
||||
WorkingDirectory = "/tmp";
|
||||
PrivateTmp = true;
|
||||
DynamicUser = !rootRequired;
|
||||
LimitMEMLOCK = toString (1024*1024);
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
@ -64,7 +64,7 @@ let
|
||||
"DEVICESCAN ${notifyOpts}${cfg.defaults.autodetected}"}
|
||||
'';
|
||||
|
||||
smartdOpts = { name, ... }: {
|
||||
smartdDeviceOpts = { name, ... }: {
|
||||
|
||||
options = {
|
||||
|
||||
@ -108,6 +108,18 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
extraOptions = mkOption {
|
||||
default = [];
|
||||
type = types.listOf types.str;
|
||||
example = ["-A /var/log/smartd/" "--interval=3600"];
|
||||
description = ''
|
||||
Extra command-line options passed to the <literal>smartd</literal>
|
||||
daemon on startup.
|
||||
|
||||
(See <literal>man 8 smartd</literal>.)
|
||||
'';
|
||||
};
|
||||
|
||||
notifications = {
|
||||
|
||||
mail = {
|
||||
@ -197,7 +209,7 @@ in
|
||||
devices = mkOption {
|
||||
default = [];
|
||||
example = [ { device = "/dev/sda"; } { device = "/dev/sdb"; options = "-d sat"; } ];
|
||||
type = with types; listOf (submodule smartdOpts);
|
||||
type = with types; listOf (submodule smartdDeviceOpts);
|
||||
description = "List of devices to monitor.";
|
||||
};
|
||||
|
||||
@ -222,7 +234,7 @@ in
|
||||
|
||||
path = [ pkgs.nettools ]; # for hostname and dnsdomanname calls in smartd
|
||||
|
||||
serviceConfig.ExecStart = "${pkgs.smartmontools}/sbin/smartd --no-fork --configfile=${smartdConf}";
|
||||
serviceConfig.ExecStart = "${pkgs.smartmontools}/sbin/smartd ${lib.concatStringsSep " " cfg.extraOptions} --no-fork --configfile=${smartdConf}";
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -9,6 +9,12 @@ let
|
||||
isBuiltinBackend = name:
|
||||
builtins.elem name [ "graphite" "console" "repeater" ];
|
||||
|
||||
backendsToPackages = let
|
||||
mkMap = list: name:
|
||||
if isBuiltinBackend name then list
|
||||
else list ++ [ pkgs.nodePackages.${name} ];
|
||||
in foldl mkMap [];
|
||||
|
||||
configFile = pkgs.writeText "statsd.conf" ''
|
||||
{
|
||||
address: "${cfg.listenAddress}",
|
||||
@ -27,13 +33,21 @@ let
|
||||
prettyprint: false
|
||||
},
|
||||
log: {
|
||||
backend: "syslog"
|
||||
backend: "stdout"
|
||||
},
|
||||
automaticConfigReload: false${optionalString (cfg.extraConfig != null) ","}
|
||||
${cfg.extraConfig}
|
||||
}
|
||||
'';
|
||||
|
||||
deps = pkgs.buildEnv {
|
||||
name = "statsd-runtime-deps";
|
||||
pathsToLink = [ "/lib" ];
|
||||
ignoreCollisions = true;
|
||||
|
||||
paths = backendsToPackages cfg.backends;
|
||||
};
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
@ -42,11 +56,7 @@ in
|
||||
|
||||
options.services.statsd = {
|
||||
|
||||
enable = mkOption {
|
||||
description = "Whether to enable statsd stats aggregation service";
|
||||
default = false;
|
||||
type = types.bool;
|
||||
};
|
||||
enable = mkEnableOption "statsd";
|
||||
|
||||
listenAddress = mkOption {
|
||||
description = "Address that statsd listens on over UDP";
|
||||
@ -110,6 +120,11 @@ in
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
assertions = map (backend: {
|
||||
assertion = !isBuiltinBackend backend -> hasAttrByPath [ backend ] pkgs.nodePackages;
|
||||
message = "Only builtin backends (graphite, console, repeater) or backends enumerated in `pkgs.nodePackages` are allowed!";
|
||||
}) cfg.backends;
|
||||
|
||||
users.extraUsers = singleton {
|
||||
name = "statsd";
|
||||
uid = config.ids.uids.statsd;
|
||||
@ -120,9 +135,7 @@ in
|
||||
description = "Statsd Server";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
environment = {
|
||||
NODE_PATH=concatMapStringsSep ":"
|
||||
(pkg: "${builtins.getAttr pkg pkgs.statsd.nodePackages}/lib/node_modules")
|
||||
(filter (name: !isBuiltinBackend name) cfg.backends);
|
||||
NODE_PATH = "${deps}/lib/node_modules";
|
||||
};
|
||||
serviceConfig = {
|
||||
ExecStart = "${pkgs.statsd}/bin/statsd ${configFile}";
|
||||
|
343
nixos/modules/services/network-filesystems/beegfs.nix
Normal file
343
nixos/modules/services/network-filesystems/beegfs.nix
Normal file
@ -0,0 +1,343 @@
|
||||
{ config, lib, pkgs, ...} :
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.beegfs;
|
||||
|
||||
# functions for the generations of config files
|
||||
|
||||
configMgmtd = name: cfg: pkgs.writeText "mgmt-${name}.conf" ''
|
||||
storeMgmtdDirectory = ${cfg.mgmtd.storeDir}
|
||||
storeAllowFirstRunInit = false
|
||||
connAuthFile = ${cfg.connAuthFile}
|
||||
connPortShift = ${toString cfg.connPortShift}
|
||||
|
||||
${cfg.mgmtd.extraConfig}
|
||||
'';
|
||||
|
||||
configAdmon = name: cfg: pkgs.writeText "admon-${name}.conf" ''
|
||||
sysMgmtdHost = ${cfg.mgmtdHost}
|
||||
connAuthFile = ${cfg.connAuthFile}
|
||||
connPortShift = ${toString cfg.connPortShift}
|
||||
|
||||
${cfg.admon.extraConfig}
|
||||
'';
|
||||
|
||||
configMeta = name: cfg: pkgs.writeText "meta-${name}.conf" ''
|
||||
storeMetaDirectory = ${cfg.meta.storeDir}
|
||||
sysMgmtdHost = ${cfg.mgmtdHost}
|
||||
connAuthFile = ${cfg.connAuthFile}
|
||||
connPortShift = ${toString cfg.connPortShift}
|
||||
storeAllowFirstRunInit = false
|
||||
|
||||
${cfg.mgmtd.extraConfig}
|
||||
'';
|
||||
|
||||
configStorage = name: cfg: pkgs.writeText "storage-${name}.conf" ''
|
||||
storeStorageDirectory = ${cfg.storage.storeDir}
|
||||
sysMgmtdHost = ${cfg.mgmtdHost}
|
||||
connAuthFile = ${cfg.connAuthFile}
|
||||
connPortShift = ${toString cfg.connPortShift}
|
||||
storeAllowFirstRunInit = false
|
||||
|
||||
${cfg.storage.extraConfig}
|
||||
'';
|
||||
|
||||
configHelperd = name: cfg: pkgs.writeText "helperd-${name}.conf" ''
|
||||
connAuthFile = ${cfg.connAuthFile}
|
||||
${cfg.helperd.extraConfig}
|
||||
'';
|
||||
|
||||
configClientFilename = name : "/etc/beegfs/client-${name}.conf";
|
||||
|
||||
configClient = name: cfg: ''
|
||||
sysMgmtdHost = ${cfg.mgmtdHost}
|
||||
connAuthFile = ${cfg.connAuthFile}
|
||||
connPortShift = ${toString cfg.connPortShift}
|
||||
|
||||
${cfg.client.extraConfig}
|
||||
'';
|
||||
|
||||
serviceList = [
|
||||
{ service = "admon"; cfgFile = configAdmon; }
|
||||
{ service = "meta"; cfgFile = configMeta; }
|
||||
{ service = "mgmtd"; cfgFile = configMgmtd; }
|
||||
{ service = "storage"; cfgFile = configStorage; }
|
||||
];
|
||||
|
||||
# functions to generate systemd.service entries
|
||||
|
||||
systemdEntry = service: cfgFile: (mapAttrs' ( name: cfg:
|
||||
(nameValuePair "beegfs-${service}-${name}" (mkIf cfg."${service}".enable {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
requires = [ "network-online.target" ];
|
||||
after = [ "network-online.target" ];
|
||||
serviceConfig = rec {
|
||||
ExecStart = ''
|
||||
${pkgs.beegfs}/bin/beegfs-${service} \
|
||||
cfgFile=${cfgFile name cfg} \
|
||||
pidFile=${PIDFile}
|
||||
'';
|
||||
PIDFile = "/run/beegfs-${service}-${name}.pid";
|
||||
TimeoutStopSec = "300";
|
||||
};
|
||||
}))) cfg);
|
||||
|
||||
systemdHelperd = mapAttrs' ( name: cfg:
|
||||
(nameValuePair "beegfs-helperd-${name}" (mkIf cfg.client.enable {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
requires = [ "network-online.target" ];
|
||||
after = [ "network-online.target" ];
|
||||
serviceConfig = rec {
|
||||
ExecStart = ''
|
||||
${pkgs.beegfs}/bin/beegfs-helperd \
|
||||
cfgFile=${configHelperd name cfg} \
|
||||
pidFile=${PIDFile}
|
||||
'';
|
||||
PIDFile = "/run/beegfs-helperd-${name}.pid";
|
||||
TimeoutStopSec = "300";
|
||||
};
|
||||
}))) cfg;
|
||||
|
||||
# wrappers to beegfs tools. Avoid typing path of config files
|
||||
utilWrappers = mapAttrsToList ( name: cfg:
|
||||
( pkgs.runCommand "beegfs-utils-${name}" { nativeBuildInputs = [ pkgs.makeWrapper ]; } ''
|
||||
mkdir -p $out/bin
|
||||
|
||||
makeWrapper ${pkgs.beegfs}/bin/beegfs-check-servers \
|
||||
$out/bin/beegfs-check-servers-${name} \
|
||||
--add-flags "-c ${configClientFilename name}" \
|
||||
--prefix PATH : ${lib.makeBinPath [ pkgs.beegfs ]}
|
||||
|
||||
makeWrapper ${pkgs.beegfs}/bin/beegfs-ctl \
|
||||
$out/bin/beegfs-ctl-${name} \
|
||||
--add-flags "--cfgFile=${configClientFilename name}"
|
||||
|
||||
makeWrapper ${pkgs.beegfs}/bin/beegfs-ctl \
|
||||
$out/bin/beegfs-df-${name} \
|
||||
--add-flags "--cfgFile=${configClientFilename name}" \
|
||||
--add-flags --listtargets \
|
||||
--add-flags --hidenodeid \
|
||||
--add-flags --pools \
|
||||
--add-flags --spaceinfo
|
||||
|
||||
makeWrapper ${pkgs.beegfs}/bin/beegfs-fsck \
|
||||
$out/bin/beegfs-fsck-${name} \
|
||||
--add-flags "--cfgFile=${configClientFilename name}"
|
||||
''
|
||||
)) cfg;
|
||||
in
|
||||
{
|
||||
###### interface
|
||||
|
||||
options = {
|
||||
services.beegfsEnable = mkEnableOption "BeeGFS";
|
||||
|
||||
services.beegfs = mkOption {
|
||||
default = {};
|
||||
description = ''
|
||||
BeeGFS configurations. Every mount point requires a separate configuration.
|
||||
'';
|
||||
type = with types; attrsOf (submodule ({ config, ... } : {
|
||||
options = {
|
||||
mgmtdHost = mkOption {
|
||||
type = types.str;
|
||||
default = null;
|
||||
example = "master";
|
||||
description = ''Hostname of managament host.'';
|
||||
};
|
||||
|
||||
connAuthFile = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
example = "/etc/my.key";
|
||||
description = "File containing shared secret authentication.";
|
||||
};
|
||||
|
||||
connPortShift = mkOption {
|
||||
type = types.int;
|
||||
default = 0;
|
||||
example = 5;
|
||||
description = ''
|
||||
For each additional beegfs configuration shift all
|
||||
service TCP/UDP ports by at least 5.
|
||||
'';
|
||||
};
|
||||
|
||||
client = {
|
||||
enable = mkEnableOption "BeeGFS client";
|
||||
|
||||
mount = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Create fstab entry automatically";
|
||||
};
|
||||
|
||||
mountPoint = mkOption {
|
||||
type = types.str;
|
||||
default = "/run/beegfs";
|
||||
description = ''
|
||||
Mount point under which the beegfs filesytem should be mounted.
|
||||
If mounted manually the mount option specifing the config file is needed:
|
||||
cfgFile=/etc/beegfs/beegfs-client-<name>.conf
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Additional lines for beegfs-client.conf.
|
||||
See documentation for further details.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
helperd = {
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Additional lines for beegfs-helperd.conf. See documentation
|
||||
for further details.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
mgmtd = {
|
||||
enable = mkEnableOption "BeeGFS mgmtd daemon";
|
||||
|
||||
storeDir = mkOption {
|
||||
type = types.path;
|
||||
default = null;
|
||||
example = "/data/beegfs-mgmtd";
|
||||
description = ''
|
||||
Data directory for mgmtd.
|
||||
Must not be shared with other beegfs daemons.
|
||||
This directory must exist and it must be initialized
|
||||
with beegfs-setup-mgmtd, e.g. "beegfs-setup-mgmtd -C -p <storeDir>"
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Additional lines for beegfs-mgmtd.conf. See documentation
|
||||
for further details.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
admon = {
|
||||
enable = mkEnableOption "BeeGFS admon daemon";
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Additional lines for beegfs-admon.conf. See documentation
|
||||
for further details.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
meta = {
|
||||
enable = mkEnableOption "BeeGFS meta data daemon";
|
||||
|
||||
storeDir = mkOption {
|
||||
type = types.path;
|
||||
default = null;
|
||||
example = "/data/beegfs-meta";
|
||||
description = ''
|
||||
Data directory for meta data service.
|
||||
Must not be shared with other beegfs daemons.
|
||||
The underlying filesystem must be mounted with xattr turned on.
|
||||
This directory must exist and it must be initialized
|
||||
with beegfs-setup-meta, e.g.
|
||||
"beegfs-setup-meta -C -s <serviceID> -p <storeDir>"
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
Additional lines for beegfs-meta.conf. See documentation
|
||||
for further details.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
storage = {
|
||||
enable = mkEnableOption "BeeGFS storage daemon";
|
||||
|
||||
storeDir = mkOption {
|
||||
type = types.path;
|
||||
default = null;
|
||||
example = "/data/beegfs-storage";
|
||||
description = ''
|
||||
Data directories for storage service.
|
||||
Must not be shared with other beegfs daemons.
|
||||
The underlying filesystem must be mounted with xattr turned on.
|
||||
This directory must exist and it must be initialized
|
||||
with beegfs-setup-storage, e.g.
|
||||
"beegfs-setup-storage -C -s <serviceID> -i <storageTargetID> -p <storeDir>"
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
Addional lines for beegfs-storage.conf. See documentation
|
||||
for further details.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
}));
|
||||
};
|
||||
};
|
||||
|
||||
###### implementation
|
||||
|
||||
config =
|
||||
mkIf config.services.beegfsEnable {
|
||||
|
||||
environment.systemPackages = utilWrappers;
|
||||
|
||||
# Put the client.conf files in /etc since they are needed
|
||||
# by the commandline tools
|
||||
environment.etc = mapAttrs' ( name: cfg:
|
||||
(nameValuePair "beegfs/client-${name}.conf" (mkIf (cfg.client.enable)
|
||||
{
|
||||
enable = true;
|
||||
text = configClient name cfg;
|
||||
}))) cfg;
|
||||
|
||||
# Kernel module, we need it only once per host.
|
||||
boot = mkIf (
|
||||
foldr (a: b: a || b) false
|
||||
(map (x: x.client.enable) (collect (x: x ? client) cfg)))
|
||||
{
|
||||
kernelModules = [ "beegfs" ];
|
||||
extraModulePackages = [ pkgs.linuxPackages.beegfs-module ];
|
||||
};
|
||||
|
||||
# generate fstab entries
|
||||
fileSystems = mapAttrs' (name: cfg:
|
||||
(nameValuePair cfg.client.mountPoint (optionalAttrs cfg.client.mount (mkIf cfg.client.enable {
|
||||
device = "beegfs_nodev";
|
||||
fsType = "beegfs";
|
||||
mountPoint = cfg.client.mountPoint;
|
||||
options = [ "cfgFile=${configClientFilename name}" "_netdev" ];
|
||||
})))) cfg;
|
||||
|
||||
# generate systemd services
|
||||
systemd.services = systemdHelperd //
|
||||
foldr (a: b: a // b) {}
|
||||
(map (x: systemdEntry x.service x.cfgFile) serviceList);
|
||||
};
|
||||
}
|
74
nixos/modules/services/network-filesystems/davfs2.nix
Normal file
74
nixos/modules/services/network-filesystems/davfs2.nix
Normal file
@ -0,0 +1,74 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.davfs2;
|
||||
cfgFile = pkgs.writeText "davfs2.conf" ''
|
||||
dav_user ${cfg.davUser}
|
||||
dav_group ${cfg.davGroup}
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
in
|
||||
{
|
||||
options.services.davfs2 = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to enable davfs2.
|
||||
'';
|
||||
};
|
||||
|
||||
davUser = mkOption {
|
||||
type = types.string;
|
||||
default = "davfs2";
|
||||
description = ''
|
||||
When invoked by root the mount.davfs daemon will run as this user.
|
||||
Value must be given as name, not as numerical id.
|
||||
'';
|
||||
};
|
||||
|
||||
davGroup = mkOption {
|
||||
type = types.string;
|
||||
default = "davfs2";
|
||||
description = ''
|
||||
The group of the running mount.davfs daemon. Ordinary users must be
|
||||
member of this group in order to mount a davfs2 file system. Value must
|
||||
be given as name, not as numerical id.
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
example = ''
|
||||
kernel_fs coda
|
||||
proxy foo.bar:8080
|
||||
use_locks 0
|
||||
'';
|
||||
description = ''
|
||||
Extra lines appended to the configuration of davfs2.
|
||||
'' ;
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
environment.systemPackages = [ pkgs.davfs2 ];
|
||||
environment.etc."davfs2/davfs2.conf".source = cfgFile;
|
||||
|
||||
users.extraGroups = optionalAttrs (cfg.davGroup == "davfs2") (singleton {
|
||||
name = "davfs2";
|
||||
gid = config.ids.gids.davfs2;
|
||||
});
|
||||
|
||||
users.extraUsers = optionalAttrs (cfg.davUser == "davfs2") (singleton {
|
||||
name = "davfs2";
|
||||
createHome = false;
|
||||
group = cfg.davGroup;
|
||||
uid = config.ids.uids.davfs2;
|
||||
description = "davfs2 user";
|
||||
});
|
||||
};
|
||||
|
||||
}
|
@ -56,6 +56,7 @@ let
|
||||
serviceConfig = {
|
||||
ExecStart = "${samba}/sbin/${appName} ${args}";
|
||||
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
|
||||
LimitNOFILE = 16384;
|
||||
Type = "notify";
|
||||
};
|
||||
|
||||
|
@ -10,7 +10,7 @@ let
|
||||
# This is somewhat more flexible than preloading the key as an
|
||||
# embedded string.
|
||||
upstreamResolverListPubKey = pkgs.fetchurl {
|
||||
url = https://raw.githubusercontent.com/jedisct1/dnscrypt-proxy/master/minisign.pub;
|
||||
url = https://raw.githubusercontent.com/dyne/dnscrypt-proxy/master/minisign.pub;
|
||||
sha256 = "18lnp8qr6ghfc2sd46nn1rhcpr324fqlvgsp4zaigw396cd7vnnh";
|
||||
};
|
||||
|
||||
@ -258,9 +258,9 @@ in
|
||||
domain=raw.githubusercontent.com
|
||||
get="curl -fSs --resolve $domain:443:$(hostip -r 8.8.8.8 $domain | head -1)"
|
||||
$get -o dnscrypt-resolvers.csv.tmp \
|
||||
https://$domain/jedisct1/dnscrypt-proxy/master/dnscrypt-resolvers.csv
|
||||
https://$domain/dyne/dnscrypt-proxy/master/dnscrypt-resolvers.csv
|
||||
$get -o dnscrypt-resolvers.csv.minisig.tmp \
|
||||
https://$domain/jedisct1/dnscrypt-proxy/master/dnscrypt-resolvers.csv.minisig
|
||||
https://$domain/dyne/dnscrypt-proxy/master/dnscrypt-resolvers.csv.minisig
|
||||
mv dnscrypt-resolvers.csv.minisig{.tmp,}
|
||||
if ! minisign -q -V -p ${upstreamResolverListPubKey} \
|
||||
-m dnscrypt-resolvers.csv.tmp -x dnscrypt-resolvers.csv.minisig ; then
|
||||
|
@ -126,6 +126,7 @@ let
|
||||
[${tun.name}]
|
||||
type = client
|
||||
destination = ${tun.destination}
|
||||
destinationport = ${toString tun.destinationPort}
|
||||
keys = ${tun.keys}
|
||||
address = ${tun.address}
|
||||
port = ${toString tun.port}
|
||||
@ -137,15 +138,15 @@ let
|
||||
'')
|
||||
}
|
||||
${flip concatMapStrings
|
||||
(collect (tun: tun ? port && tun ? host) cfg.inTunnels)
|
||||
(tun: let portStr = toString tun.port; in ''
|
||||
(collect (tun: tun ? port && tun ? address) cfg.inTunnels)
|
||||
(tun: ''
|
||||
[${tun.name}]
|
||||
type = server
|
||||
destination = ${tun.destination}
|
||||
keys = ${tun.keys}
|
||||
host = ${tun.address}
|
||||
port = ${tun.port}
|
||||
inport = ${tun.inPort}
|
||||
port = ${toString tun.port}
|
||||
inport = ${toString tun.inPort}
|
||||
accesslist = ${builtins.concatStringsSep "," tun.accessList}
|
||||
'')
|
||||
}
|
||||
@ -405,7 +406,13 @@ in
|
||||
default = {};
|
||||
type = with types; loaOf (submodule (
|
||||
{ name, config, ... }: {
|
||||
options = commonTunOpts name;
|
||||
options = {
|
||||
destinationPort = mkOption {
|
||||
type = types.int;
|
||||
default = 0;
|
||||
description = "Connect to particular port at destination.";
|
||||
};
|
||||
} // commonTunOpts name;
|
||||
config = {
|
||||
name = mkDefault name;
|
||||
};
|
||||
|
@ -72,6 +72,7 @@ in
|
||||
(iface: if elem ":" (stringToCharacters iface) then "[${iface}]:53" else "${iface}:53")
|
||||
cfg.interfaces;
|
||||
socketConfig.ListenDatagram = listenStreams;
|
||||
socketConfig.FreeBind = true;
|
||||
};
|
||||
|
||||
systemd.sockets.kresd-control = rec {
|
||||
@ -82,20 +83,11 @@ in
|
||||
socketConfig = {
|
||||
FileDescriptorName = "control";
|
||||
Service = "kresd.service";
|
||||
SocketMode = "0660"; # only root user/group may connect
|
||||
SocketMode = "0660"; # only root user/group may connect and control kresd
|
||||
};
|
||||
};
|
||||
|
||||
# Create the cacheDir; tmpfiles don't work on nixos-rebuild switch.
|
||||
systemd.services.kresd-cachedir = {
|
||||
serviceConfig.Type = "oneshot";
|
||||
script = ''
|
||||
if [ ! -d '${cfg.cacheDir}' ]; then
|
||||
mkdir -p '${cfg.cacheDir}'
|
||||
chown kresd:kresd '${cfg.cacheDir}'
|
||||
fi
|
||||
'';
|
||||
};
|
||||
systemd.tmpfiles.rules = [ "d '${cfg.cacheDir}' 0770 kresd kresd - -" ];
|
||||
|
||||
systemd.services.kresd = {
|
||||
description = "Knot-resolver daemon";
|
||||
@ -104,16 +96,15 @@ in
|
||||
User = "kresd";
|
||||
Type = "notify";
|
||||
WorkingDirectory = cfg.cacheDir;
|
||||
Restart = "on-failure";
|
||||
};
|
||||
|
||||
script = ''
|
||||
exec '${package}/bin/kresd' --config '${configFile}' \
|
||||
-k '${cfg.cacheDir}/root.key'
|
||||
-k '${pkgs.dns-root-data}/root.key'
|
||||
'';
|
||||
|
||||
after = [ "kresd-cachedir.service" ];
|
||||
requires = [ "kresd.socket" "kresd-cachedir.service" ];
|
||||
wantedBy = [ "sockets.target" ];
|
||||
requires = [ "kresd.socket" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ in
|
||||
description = "lldpd user";
|
||||
group = "_lldpd";
|
||||
home = "/var/run/lldpd";
|
||||
isSystemUser = true;
|
||||
};
|
||||
users.extraGroups._lldpd = {};
|
||||
|
||||
|
@ -19,6 +19,8 @@ let
|
||||
iptables -w -t nat -D POSTROUTING -j nixos-nat-post 2>/dev/null || true
|
||||
iptables -w -t nat -F nixos-nat-post 2>/dev/null || true
|
||||
iptables -w -t nat -X nixos-nat-post 2>/dev/null || true
|
||||
|
||||
${cfg.extraStopCommands}
|
||||
'';
|
||||
|
||||
setupNat = ''
|
||||
@ -53,6 +55,14 @@ let
|
||||
-j DNAT --to-destination ${fwd.destination}
|
||||
'') cfg.forwardPorts}
|
||||
|
||||
${optionalString (cfg.dmzHost != null) ''
|
||||
iptables -w -t nat -A nixos-nat-pre \
|
||||
-i ${cfg.externalInterface} -j DNAT \
|
||||
--to-destination ${cfg.dmzHost}
|
||||
''}
|
||||
|
||||
${cfg.extraCommands}
|
||||
|
||||
# Append our chains to the nat tables
|
||||
iptables -w -t nat -A PREROUTING -j nixos-nat-pre
|
||||
iptables -w -t nat -A POSTROUTING -j nixos-nat-post
|
||||
@ -125,15 +135,15 @@ in
|
||||
type = with types; listOf (submodule {
|
||||
options = {
|
||||
sourcePort = mkOption {
|
||||
type = types.int;
|
||||
type = types.either types.int (types.strMatching "[[:digit:]]+:[[:digit:]]+");
|
||||
example = 8080;
|
||||
description = "Source port of the external interface";
|
||||
description = "Source port of the external interface; to specify a port range, use a string with a colon (e.g. \"60000:61000\")";
|
||||
};
|
||||
|
||||
destination = mkOption {
|
||||
type = types.str;
|
||||
example = "10.0.0.1:80";
|
||||
description = "Forward connection to destination ip:port";
|
||||
description = "Forward connection to destination ip:port; to specify a port range, use ip:start-end";
|
||||
};
|
||||
|
||||
proto = mkOption {
|
||||
@ -153,6 +163,39 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
networking.nat.dmzHost = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "10.0.0.1";
|
||||
description =
|
||||
''
|
||||
The local IP address to which all traffic that does not match any
|
||||
forwarding rule is forwarded.
|
||||
'';
|
||||
};
|
||||
|
||||
networking.nat.extraCommands = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
example = "iptables -A INPUT -p icmp -j ACCEPT";
|
||||
description =
|
||||
''
|
||||
Additional shell commands executed as part of the nat
|
||||
initialisation script.
|
||||
'';
|
||||
};
|
||||
|
||||
networking.nat.extraStopCommands = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
example = "iptables -D INPUT -p icmp -j ACCEPT || true";
|
||||
description =
|
||||
''
|
||||
Additional shell commands executed as part of the nat
|
||||
teardown script.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -241,6 +241,19 @@ in {
|
||||
A list of scripts which will be executed in response to network events.
|
||||
'';
|
||||
};
|
||||
|
||||
enableStrongSwan = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Enable the StrongSwan plugin.
|
||||
</para><para>
|
||||
If you enable this option the
|
||||
<literal>networkmanager_strongswan</literal> plugin will be added to
|
||||
the <option>networking.networkmanager.packages</option> option
|
||||
so you don't need to to that yourself.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@ -333,13 +346,13 @@ in {
|
||||
wireless.enable = lib.mkDefault false;
|
||||
};
|
||||
|
||||
powerManagement.resumeCommands = ''
|
||||
${config.systemd.package}/bin/systemctl restart network-manager
|
||||
'';
|
||||
|
||||
security.polkit.extraConfig = polkitConf;
|
||||
|
||||
services.dbus.packages = cfg.packages;
|
||||
networking.networkmanager.packages =
|
||||
mkIf cfg.enableStrongSwan [ pkgs.networkmanager_strongswan ];
|
||||
|
||||
services.dbus.packages =
|
||||
optional cfg.enableStrongSwan pkgs.strongswanNM ++ cfg.packages;
|
||||
|
||||
services.udev.packages = cfg.packages;
|
||||
};
|
||||
|
@ -11,6 +11,8 @@ let
|
||||
|
||||
# build nsd with the options needed for the given config
|
||||
nsdPkg = pkgs.nsd.override {
|
||||
configFile = "${configFile}/nsd.conf";
|
||||
|
||||
bind8Stats = cfg.bind8Stats;
|
||||
ipv6 = cfg.ipv6;
|
||||
ratelimit = cfg.ratelimit.enable;
|
||||
@ -788,6 +790,8 @@ in
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
environment.systemPackages = [ nsdPkg ];
|
||||
|
||||
users.extraGroups = singleton {
|
||||
name = username;
|
||||
gid = config.ids.gids.nsd;
|
||||
@ -845,4 +849,6 @@ in
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
meta.maintainers = with lib.maintainers; [ hrdinka ];
|
||||
}
|
||||
|
@ -10,98 +10,126 @@ let
|
||||
|
||||
options = {
|
||||
|
||||
# TODO: require attribute
|
||||
key = mkOption {
|
||||
type = types.str;
|
||||
description = "Path to the key file";
|
||||
type = types.path;
|
||||
description = "Path to the key file.";
|
||||
};
|
||||
|
||||
# TODO: require attribute
|
||||
cert = mkOption {
|
||||
type = types.str;
|
||||
description = "Path to the certificate file";
|
||||
type = types.path;
|
||||
description = "Path to the certificate file.";
|
||||
};
|
||||
|
||||
extraOptions = mkOption {
|
||||
type = types.attrs;
|
||||
default = {};
|
||||
description = "Extra SSL configuration options.";
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
moduleOpts = {
|
||||
|
||||
roster = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Allow users to have a roster";
|
||||
};
|
||||
|
||||
saslauth = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Authentication for clients and servers. Recommended if you want to log in.";
|
||||
};
|
||||
|
||||
tls = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Add support for secure TLS on c2s/s2s connections";
|
||||
};
|
||||
|
||||
dialback = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "s2s dialback support";
|
||||
};
|
||||
|
||||
disco = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Service discovery";
|
||||
};
|
||||
|
||||
legacyauth = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Legacy authentication. Only used by some old clients and bots";
|
||||
};
|
||||
|
||||
version = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Replies to server version requests";
|
||||
};
|
||||
|
||||
uptime = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Report how long server has been running";
|
||||
};
|
||||
|
||||
time = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Let others know the time here on this server";
|
||||
};
|
||||
|
||||
ping = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Replies to XMPP pings with pongs";
|
||||
};
|
||||
|
||||
console = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "telnet to port 5582";
|
||||
};
|
||||
|
||||
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";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
createSSLOptsStr = o:
|
||||
if o ? key && o ? cert then
|
||||
''ssl = { key = "${o.key}"; certificate = "${o.cert}"; };''
|
||||
else "";
|
||||
toLua = x:
|
||||
if builtins.isString x then ''"${x}"''
|
||||
else if builtins.isBool x then toString x
|
||||
else if builtins.isInt x then toString x
|
||||
else throw "Invalid Lua value";
|
||||
|
||||
createSSLOptsStr = o: ''
|
||||
ssl = {
|
||||
key = "${o.key}";
|
||||
certificate = "${o.cert}";
|
||||
${concatStringsSep "\n" (mapAttrsToList (name: value: "${name} = ${toLua value};") o.extraOptions)}
|
||||
};
|
||||
'';
|
||||
|
||||
vHostOpts = { ... }: {
|
||||
|
||||
@ -114,18 +142,20 @@ let
|
||||
};
|
||||
|
||||
enabled = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Whether to enable the virtual host";
|
||||
};
|
||||
|
||||
ssl = mkOption {
|
||||
description = "Paths to SSL files";
|
||||
type = types.nullOr (types.submodule sslOpts);
|
||||
default = null;
|
||||
options = [ sslOpts ];
|
||||
description = "Paths to SSL files";
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
default = '''';
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = "Additional virtual host specific configuration";
|
||||
};
|
||||
|
||||
@ -144,11 +174,13 @@ in
|
||||
services.prosody = {
|
||||
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Whether to enable the prosody server";
|
||||
};
|
||||
|
||||
allowRegistration = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Allow account creation";
|
||||
};
|
||||
@ -156,8 +188,9 @@ in
|
||||
modules = moduleOpts;
|
||||
|
||||
extraModules = mkOption {
|
||||
description = "Enable custom modules";
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
description = "Enable custom modules";
|
||||
};
|
||||
|
||||
virtualHosts = mkOption {
|
||||
@ -183,20 +216,21 @@ in
|
||||
};
|
||||
|
||||
ssl = mkOption {
|
||||
description = "Paths to SSL files";
|
||||
type = types.nullOr (types.submodule sslOpts);
|
||||
default = null;
|
||||
options = [ sslOpts ];
|
||||
description = "Paths to SSL files";
|
||||
};
|
||||
|
||||
admins = mkOption {
|
||||
description = "List of administrators of the current host";
|
||||
example = [ "admin1@example.com" "admin2@example.com" ];
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
example = [ "admin1@example.com" "admin2@example.com" ];
|
||||
description = "List of administrators of the current host";
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = '''';
|
||||
default = "";
|
||||
description = "Additional prosody configuration";
|
||||
};
|
||||
|
||||
@ -263,17 +297,17 @@ in
|
||||
};
|
||||
|
||||
systemd.services.prosody = {
|
||||
|
||||
description = "Prosody XMPP server";
|
||||
after = [ "network-online.target" ];
|
||||
wants = [ "network-online.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
restartTriggers = [ config.environment.etc."prosody/prosody.cfg.lua".source ];
|
||||
serviceConfig = {
|
||||
User = "prosody";
|
||||
Type = "forking";
|
||||
PIDFile = "/var/lib/prosody/prosody.pid";
|
||||
ExecStart = "${pkgs.prosody}/bin/prosodyctl start";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -248,13 +248,10 @@ in
|
||||
let
|
||||
service =
|
||||
{ description = "SSH Daemon";
|
||||
|
||||
wantedBy = optional (!cfg.startWhenNeeded) "multi-user.target";
|
||||
|
||||
after = [ "network.target" ];
|
||||
stopIfChanged = false;
|
||||
|
||||
path = [ cfgc.package pkgs.gawk ];
|
||||
|
||||
environment.LD_LIBRARY_PATH = nssModulesPath;
|
||||
|
||||
preStart =
|
||||
|
@ -90,16 +90,24 @@ in
|
||||
[ (allowdeny "allow" (cfg.allow))
|
||||
(allowdeny "deny" cfg.deny)
|
||||
# see man 5 fcron.conf
|
||||
{ source = pkgs.writeText "fcron.conf" ''
|
||||
fcrontabs = /var/spool/fcron
|
||||
pidfile = /var/run/fcron.pid
|
||||
fifofile = /var/run/fcron.fifo
|
||||
fcronallow = /etc/fcron.allow
|
||||
fcrondeny = /etc/fcron.deny
|
||||
shell = /bin/sh
|
||||
sendmail = /run/wrappers/bin/sendmail
|
||||
editor = ${pkgs.vim}/bin/vim
|
||||
'';
|
||||
{ source =
|
||||
let
|
||||
isSendmailWrapped =
|
||||
lib.hasAttr "sendmail" config.security.wrappers;
|
||||
sendmailPath =
|
||||
if isSendmailWrapped then "/run/wrappers/bin/sendmail"
|
||||
else "${config.system.path}/bin/sendmail";
|
||||
in
|
||||
pkgs.writeText "fcron.conf" ''
|
||||
fcrontabs = /var/spool/fcron
|
||||
pidfile = /var/run/fcron.pid
|
||||
fifofile = /var/run/fcron.fifo
|
||||
fcronallow = /etc/fcron.allow
|
||||
fcrondeny = /etc/fcron.deny
|
||||
shell = /bin/sh
|
||||
sendmail = ${sendmailPath}
|
||||
editor = ${pkgs.vim}/bin/vim
|
||||
'';
|
||||
target = "fcron.conf";
|
||||
gid = config.ids.gids.fcron;
|
||||
mode = "0644";
|
||||
|
@ -97,8 +97,8 @@ in
|
||||
|
||||
systemd.services.clamav-daemon = optionalAttrs cfg.daemon.enable {
|
||||
description = "ClamAV daemon (clamd)";
|
||||
after = mkIf cfg.updater.enable [ "clamav-freshclam.service" ];
|
||||
requires = mkIf cfg.updater.enable [ "clamav-freshclam.service" ];
|
||||
after = optional cfg.updater.enable "clamav-freshclam.service";
|
||||
requires = optional cfg.updater.enable "clamav-freshclam.service";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
restartTriggers = [ clamdConfigFile ];
|
||||
|
||||
|
@ -9,6 +9,26 @@ let
|
||||
opt = name: value: optionalString (value != null) "${name} ${value}";
|
||||
optint = name: value: optionalString (value != null && value != 0) "${name} ${toString value}";
|
||||
|
||||
isolationOptions = {
|
||||
type = types.listOf (types.enum [
|
||||
"IsolateClientAddr"
|
||||
"IsolateSOCKSAuth"
|
||||
"IsolateClientProtocol"
|
||||
"IsolateDestPort"
|
||||
"IsolateDestAddr"
|
||||
]);
|
||||
default = [];
|
||||
example = [
|
||||
"IsolateClientAddr"
|
||||
"IsolateSOCKSAuth"
|
||||
"IsolateClientProtocol"
|
||||
"IsolateDestPort"
|
||||
"IsolateDestAddr"
|
||||
];
|
||||
description = "Tor isolation options";
|
||||
};
|
||||
|
||||
|
||||
torRc = ''
|
||||
User tor
|
||||
DataDirectory ${torDirectory}
|
||||
@ -20,10 +40,20 @@ let
|
||||
${optint "ControlPort" cfg.controlPort}
|
||||
''
|
||||
# Client connection config
|
||||
+ optionalString cfg.client.enable ''
|
||||
SOCKSPort ${cfg.client.socksListenAddress} IsolateDestAddr
|
||||
+ optionalString cfg.client.enable ''
|
||||
SOCKSPort ${cfg.client.socksListenAddress} ${toString cfg.client.socksIsolationOptions}
|
||||
SOCKSPort ${cfg.client.socksListenAddressFaster}
|
||||
${opt "SocksPolicy" cfg.client.socksPolicy}
|
||||
|
||||
${optionalString cfg.client.transparentProxy.enable ''
|
||||
TransPort ${cfg.client.transparentProxy.listenAddress} ${toString cfg.client.transparentProxy.isolationOptions}
|
||||
''}
|
||||
|
||||
${optionalString cfg.client.dns.enable ''
|
||||
DNSPort ${cfg.client.dns.listenAddress} ${toString cfg.client.dns.isolationOptions}
|
||||
AutomapHostsOnResolve 1
|
||||
AutomapHostsSuffixes ${concatStringsSep "," cfg.client.dns.automapHostsSuffixes}
|
||||
''}
|
||||
''
|
||||
# Relay config
|
||||
+ optionalString cfg.relay.enable ''
|
||||
@ -154,6 +184,55 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
socksIsolationOptions = mkOption (isolationOptions // {
|
||||
default = ["IsolateDestAddr"];
|
||||
});
|
||||
|
||||
transparentProxy = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Whether to enable tor transaprent proxy";
|
||||
};
|
||||
|
||||
listenAddress = mkOption {
|
||||
type = types.str;
|
||||
default = "127.0.0.1:9040";
|
||||
example = "192.168.0.1:9040";
|
||||
description = ''
|
||||
Bind transparent proxy to this address.
|
||||
'';
|
||||
};
|
||||
|
||||
isolationOptions = mkOption isolationOptions;
|
||||
};
|
||||
|
||||
dns = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Whether to enable tor dns resolver";
|
||||
};
|
||||
|
||||
listenAddress = mkOption {
|
||||
type = types.str;
|
||||
default = "127.0.0.1:9053";
|
||||
example = "192.168.0.1:9053";
|
||||
description = ''
|
||||
Bind tor dns to this address.
|
||||
'';
|
||||
};
|
||||
|
||||
isolationOptions = mkOption isolationOptions;
|
||||
|
||||
automapHostsSuffixes = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [".onion" ".exit"];
|
||||
example = [".onion"];
|
||||
description = "List of suffixes to use with automapHostsOnResolve";
|
||||
};
|
||||
};
|
||||
|
||||
privoxy.enable = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user