Merge remote-tracking branch 'origin/master' into gcc-6
This commit is contained in:
commit
3373a55cac
2
.github/CONTRIBUTING.md
vendored
2
.github/CONTRIBUTING.md
vendored
@ -32,4 +32,4 @@ See the nixpkgs manual for more details on how to [Submit changes to nixpkgs](ht
|
|||||||
|
|
||||||
## Reviewing contributions
|
## Reviewing contributions
|
||||||
|
|
||||||
See the nixpkgs manual for more details on how to [Review contributions](http://hydra.nixos.org/job/nixpkgs/trunk/manual/latest/download-by-type/doc/manual#chap-reviewing-contributions).
|
See the nixpkgs manual for more details on how to [Review contributions](https://nixos.org/nixpkgs/manual/#sec-reviewing-contributions).
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
{
|
{
|
||||||
"userBlacklist": [
|
"userBlacklist": [
|
||||||
"civodul",
|
"civodul",
|
||||||
"jhasse"
|
"jhasse",
|
||||||
|
"shlevy"
|
||||||
],
|
],
|
||||||
"alwaysNotifyForPaths": [
|
"alwaysNotifyForPaths": [
|
||||||
{ "name": "FRidh", "files": ["pkgs/top-level/python-packages.nix", "pkgs/development/interpreters/python/*", "pkgs/development/python-modules/*" ] },
|
{ "name": "FRidh", "files": ["pkgs/top-level/python-packages.nix", "pkgs/development/interpreters/python/*", "pkgs/development/python-modules/*" ] },
|
||||||
|
{ "name": "LnL7", "files": ["pkgs/stdenv/darwin/*", "pkgs/os-specific/darwin/*"] },
|
||||||
{ "name": "copumpkin", "files": ["pkgs/stdenv/darwin/*", "pkgs/os-specific/darwin/apple-source-releases/*"] }
|
{ "name": "copumpkin", "files": ["pkgs/stdenv/darwin/*", "pkgs/os-specific/darwin/apple-source-releases/*"] }
|
||||||
],
|
],
|
||||||
"fileBlacklist": ["pkgs/top-level/all-packages.nix"]
|
"fileBlacklist": ["pkgs/top-level/all-packages.nix"]
|
||||||
|
@ -4,7 +4,7 @@ matrix:
|
|||||||
- os: linux
|
- os: linux
|
||||||
sudo: false
|
sudo: false
|
||||||
script:
|
script:
|
||||||
- ./maintainers/scripts/travis-nox-review-pr.sh nixpkgs-verify nixpkgs-manual nixpkgs-tarball
|
- ./maintainers/scripts/travis-nox-review-pr.sh nixpkgs-verify nixpkgs-manual nixpkgs-tarball nixpkgs-unstable
|
||||||
- ./maintainers/scripts/travis-nox-review-pr.sh nixos-options nixos-manual
|
- ./maintainers/scripts/travis-nox-review-pr.sh nixos-options nixos-manual
|
||||||
- os: linux
|
- os: linux
|
||||||
sudo: required
|
sudo: required
|
||||||
|
@ -8,252 +8,295 @@
|
|||||||
The nixpkgs repository has several utility functions to manipulate Nix expressions.
|
The nixpkgs repository has several utility functions to manipulate Nix expressions.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<section xml:id="sec-pkgs-overridePackages">
|
<section xml:id="sec-overrides">
|
||||||
<title>pkgs.overridePackages</title>
|
<title>Overriding</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
This function inside the nixpkgs expression (<varname>pkgs</varname>)
|
Sometimes one wants to override parts of
|
||||||
can be used to override the set of packages itself.
|
<literal>nixpkgs</literal>, e.g. derivation attributes, the results of
|
||||||
</para>
|
derivations or even the whole package set.
|
||||||
<para>
|
|
||||||
Warning: this function is expensive and must not be used from within
|
|
||||||
the nixpkgs repository.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
Example usage:
|
|
||||||
|
|
||||||
<programlisting>let
|
|
||||||
pkgs = import <nixpkgs> {};
|
|
||||||
newpkgs = pkgs.overridePackages (self: super: {
|
|
||||||
foo = super.foo.override { ... };
|
|
||||||
};
|
|
||||||
in ...</programlisting>
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<section xml:id="sec-pkgs-overridePackages">
|
||||||
The resulting <varname>newpkgs</varname> will have the new <varname>foo</varname>
|
<title>pkgs.overridePackages</title>
|
||||||
expression, and all other expressions depending on <varname>foo</varname> will also
|
|
||||||
use the new <varname>foo</varname> expression.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
The behavior of this function is similar to <link
|
|
||||||
linkend="sec-modify-via-packageOverrides">config.packageOverrides</link>.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
The <varname>self</varname> parameter refers to the final package set with the
|
|
||||||
applied overrides. Using this parameter may lead to infinite recursion if not
|
|
||||||
used consciously.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
The <varname>super</varname> parameter refers to the old package set.
|
|
||||||
It's equivalent to <varname>pkgs</varname> in the above example.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Note that in previous versions of nixpkgs, this method replaced any changes from <link
|
|
||||||
linkend="sec-modify-via-packageOverrides">config.packageOverrides</link>,
|
|
||||||
along with that from previous calls if this function was called repeatedly.
|
|
||||||
Now those previous changes will be preserved so this function can be "chained" meaningfully.
|
|
||||||
To recover the old behavior, make sure <varname>config.packageOverrides</varname> is unset,
|
|
||||||
and call this only once off a "freshly" imported nixpkgs:
|
|
||||||
|
|
||||||
<programlisting>let
|
|
||||||
pkgs = import <nixpkgs> { config: {}; };
|
|
||||||
newpkgs = pkgs.overridePackages ...;
|
|
||||||
in ...</programlisting>
|
|
||||||
</para>
|
|
||||||
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section xml:id="sec-pkg-override">
|
|
||||||
<title><pkg>.override</title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
The function <varname>override</varname> is usually available for all the
|
|
||||||
derivations in the nixpkgs expression (<varname>pkgs</varname>).
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
It is used to override the arguments passed to a function.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
Example usages:
|
|
||||||
|
|
||||||
<programlisting>pkgs.foo.override { arg1 = val1; arg2 = val2; ... }</programlisting>
|
|
||||||
<programlisting>pkgs.overridePackages (self: super: {
|
|
||||||
foo = super.foo.override { barSupport = true ; };
|
|
||||||
})</programlisting>
|
|
||||||
<programlisting>mypkg = pkgs.callPackage ./mypkg.nix {
|
|
||||||
mydep = pkgs.mydep.override { ... };
|
|
||||||
})</programlisting>
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
In the first example, <varname>pkgs.foo</varname> is the result of a function call
|
|
||||||
with some default arguments, usually a derivation.
|
|
||||||
Using <varname>pkgs.foo.override</varname> will call the same function with
|
|
||||||
the given new arguments.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section xml:id="sec-pkg-overrideAttrs">
|
|
||||||
<title><pkg>.overrideAttrs</title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
The function <varname>overrideAttrs</varname> allows overriding the
|
|
||||||
attribute set passed to a <varname>stdenv.mkDerivation</varname> call,
|
|
||||||
producing a new derivation based on the original one.
|
|
||||||
This function is available on all derivations produced by the
|
|
||||||
<varname>stdenv.mkDerivation</varname> function, which is most packages
|
|
||||||
in the nixpkgs expression <varname>pkgs</varname>.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Example usage:
|
|
||||||
|
|
||||||
<programlisting>helloWithDebug = pkgs.hello.overrideAttrs (oldAttrs: rec {
|
|
||||||
separateDebugInfo = true;
|
|
||||||
});</programlisting>
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
In the above example, the <varname>separateDebugInfo</varname> attribute is
|
|
||||||
overriden to be true, thus building debug info for
|
|
||||||
<varname>helloWithDebug</varname>, while all other attributes will be
|
|
||||||
retained from the original <varname>hello</varname> package.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
The argument <varname>oldAttrs</varname> is conventionally used to refer to
|
|
||||||
the attr set originally passed to <varname>stdenv.mkDerivation</varname>.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<note>
|
|
||||||
<para>
|
<para>
|
||||||
Note that <varname>separateDebugInfo</varname> is processed only by the
|
This function inside the nixpkgs expression (<varname>pkgs</varname>)
|
||||||
<varname>stdenv.mkDerivation</varname> function, not the generated, raw
|
can be used to override the set of packages itself.
|
||||||
Nix derivation. Thus, using <varname>overrideDerivation</varname> will
|
|
||||||
not work in this case, as it overrides only the attributes of the final
|
|
||||||
derivation. It is for this reason that <varname>overrideAttrs</varname>
|
|
||||||
should be preferred in (almost) all cases to
|
|
||||||
<varname>overrideDerivation</varname>, i.e. to allow using
|
|
||||||
<varname>sdenv.mkDerivation</varname> to process input arguments, as well
|
|
||||||
as the fact that it is easier to use (you can use the same attribute
|
|
||||||
names you see in your Nix code, instead of the ones generated (e.g.
|
|
||||||
<varname>buildInputs</varname> vs <varname>nativeBuildInputs</varname>,
|
|
||||||
and involves less typing.
|
|
||||||
</para>
|
</para>
|
||||||
</note>
|
|
||||||
|
|
||||||
</section>
|
|
||||||
|
|
||||||
|
|
||||||
<section xml:id="sec-pkg-overrideDerivation">
|
|
||||||
<title><pkg>.overrideDerivation</title>
|
|
||||||
|
|
||||||
<warning>
|
|
||||||
<para>You should prefer <varname>overrideAttrs</varname> in almost all
|
|
||||||
cases, see its documentation for the reasons why.
|
|
||||||
<varname>overrideDerivation</varname> is not deprecated and will continue
|
|
||||||
to work, but is less nice to use and does not have as many abilities as
|
|
||||||
<varname>overrideAttrs</varname>.
|
|
||||||
</para>
|
|
||||||
</warning>
|
|
||||||
|
|
||||||
<warning>
|
|
||||||
<para>Do not use this function in Nixpkgs as it evaluates a Derivation
|
|
||||||
before modifying it, which breaks package abstraction and removes
|
|
||||||
error-checking of function arguments. In addition, this
|
|
||||||
evaluation-per-function application incurs a performance penalty,
|
|
||||||
which can become a problem if many overrides are used.
|
|
||||||
It is only intended for ad-hoc customisation, such as in
|
|
||||||
<filename>~/.nixpkgs/config.nix</filename>.
|
|
||||||
</para>
|
|
||||||
</warning>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
The function <varname>overrideDerivation</varname> creates a new derivation
|
|
||||||
based on an existing one by overriding the original's attributes with
|
|
||||||
the attribute set produced by the specified function.
|
|
||||||
This function is available on all
|
|
||||||
derivations defined using the <varname>makeOverridable</varname> function.
|
|
||||||
Most standard derivation-producing functions, such as
|
|
||||||
<varname>stdenv.mkDerivation</varname>, are defined using this
|
|
||||||
function, which means most packages in the nixpkgs expression,
|
|
||||||
<varname>pkgs</varname>, have this function.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Example usage:
|
|
||||||
|
|
||||||
<programlisting>mySed = pkgs.gnused.overrideDerivation (oldAttrs: {
|
|
||||||
name = "sed-4.2.2-pre";
|
|
||||||
src = fetchurl {
|
|
||||||
url = ftp://alpha.gnu.org/gnu/sed/sed-4.2.2-pre.tar.bz2;
|
|
||||||
sha256 = "11nq06d131y4wmf3drm0yk502d2xc6n5qy82cg88rb9nqd2lj41k";
|
|
||||||
};
|
|
||||||
patches = [];
|
|
||||||
});</programlisting>
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
In the above example, the <varname>name</varname>, <varname>src</varname>,
|
|
||||||
and <varname>patches</varname> of the derivation will be overridden, while
|
|
||||||
all other attributes will be retained from the original derivation.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
The argument <varname>oldAttrs</varname> is used to refer to the attribute set of
|
|
||||||
the original derivation.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<note>
|
|
||||||
<para>
|
<para>
|
||||||
A package's attributes are evaluated *before* being modified by
|
Warning: this function is expensive and must not be used from within
|
||||||
the <varname>overrideDerivation</varname> function.
|
the nixpkgs repository.
|
||||||
For example, the <varname>name</varname> attribute reference
|
|
||||||
in <varname>url = "mirror://gnu/hello/${name}.tar.gz";</varname>
|
|
||||||
is filled-in *before* the <varname>overrideDerivation</varname> function
|
|
||||||
modifies the attribute set. This means that overriding the
|
|
||||||
<varname>name</varname> attribute, in this example, *will not* change the
|
|
||||||
value of the <varname>url</varname> attribute. Instead, we need to override
|
|
||||||
both the <varname>name</varname> *and* <varname>url</varname> attributes.
|
|
||||||
</para>
|
</para>
|
||||||
</note>
|
<para>
|
||||||
|
Example usage:
|
||||||
|
|
||||||
|
<programlisting>let
|
||||||
|
pkgs = import <nixpkgs> {};
|
||||||
|
newpkgs = pkgs.overridePackages (self: super: {
|
||||||
|
foo = super.foo.override { ... };
|
||||||
|
};
|
||||||
|
in ...</programlisting>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The resulting <varname>newpkgs</varname> will have the new <varname>foo</varname>
|
||||||
|
expression, and all other expressions depending on <varname>foo</varname> will also
|
||||||
|
use the new <varname>foo</varname> expression.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The behavior of this function is similar to <link
|
||||||
|
linkend="sec-modify-via-packageOverrides">config.packageOverrides</link>.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The <varname>self</varname> parameter refers to the final package set with the
|
||||||
|
applied overrides. Using this parameter may lead to infinite recursion if not
|
||||||
|
used consciously.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The <varname>super</varname> parameter refers to the old package set.
|
||||||
|
It's equivalent to <varname>pkgs</varname> in the above example.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Note that in previous versions of nixpkgs, this method replaced any changes from <link
|
||||||
|
linkend="sec-modify-via-packageOverrides">config.packageOverrides</link>,
|
||||||
|
along with that from previous calls if this function was called repeatedly.
|
||||||
|
Now those previous changes will be preserved so this function can be "chained" meaningfully.
|
||||||
|
To recover the old behavior, make sure <varname>config.packageOverrides</varname> is unset,
|
||||||
|
and call this only once off a "freshly" imported nixpkgs:
|
||||||
|
|
||||||
|
<programlisting>let
|
||||||
|
pkgs = import <nixpkgs> { config: {}; };
|
||||||
|
newpkgs = pkgs.overridePackages ...;
|
||||||
|
in ...</programlisting>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section xml:id="sec-pkg-override">
|
||||||
|
<title><pkg>.override</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The function <varname>override</varname> is usually available for all the
|
||||||
|
derivations in the nixpkgs expression (<varname>pkgs</varname>).
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
It is used to override the arguments passed to a function.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Example usages:
|
||||||
|
|
||||||
|
<programlisting>pkgs.foo.override { arg1 = val1; arg2 = val2; ... }</programlisting>
|
||||||
|
<programlisting>pkgs.overridePackages (self: super: {
|
||||||
|
foo = super.foo.override { barSupport = true ; };
|
||||||
|
})</programlisting>
|
||||||
|
<programlisting>mypkg = pkgs.callPackage ./mypkg.nix {
|
||||||
|
mydep = pkgs.mydep.override { ... };
|
||||||
|
})</programlisting>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
In the first example, <varname>pkgs.foo</varname> is the result of a function call
|
||||||
|
with some default arguments, usually a derivation.
|
||||||
|
Using <varname>pkgs.foo.override</varname> will call the same function with
|
||||||
|
the given new arguments.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section xml:id="sec-pkg-overrideAttrs">
|
||||||
|
<title><pkg>.overrideAttrs</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The function <varname>overrideAttrs</varname> allows overriding the
|
||||||
|
attribute set passed to a <varname>stdenv.mkDerivation</varname> call,
|
||||||
|
producing a new derivation based on the original one.
|
||||||
|
This function is available on all derivations produced by the
|
||||||
|
<varname>stdenv.mkDerivation</varname> function, which is most packages
|
||||||
|
in the nixpkgs expression <varname>pkgs</varname>.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Example usage:
|
||||||
|
|
||||||
|
<programlisting>helloWithDebug = pkgs.hello.overrideAttrs (oldAttrs: rec {
|
||||||
|
separateDebugInfo = true;
|
||||||
|
});</programlisting>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
In the above example, the <varname>separateDebugInfo</varname> attribute is
|
||||||
|
overriden to be true, thus building debug info for
|
||||||
|
<varname>helloWithDebug</varname>, while all other attributes will be
|
||||||
|
retained from the original <varname>hello</varname> package.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The argument <varname>oldAttrs</varname> is conventionally used to refer to
|
||||||
|
the attr set originally passed to <varname>stdenv.mkDerivation</varname>.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<note>
|
||||||
|
<para>
|
||||||
|
Note that <varname>separateDebugInfo</varname> is processed only by the
|
||||||
|
<varname>stdenv.mkDerivation</varname> function, not the generated, raw
|
||||||
|
Nix derivation. Thus, using <varname>overrideDerivation</varname> will
|
||||||
|
not work in this case, as it overrides only the attributes of the final
|
||||||
|
derivation. It is for this reason that <varname>overrideAttrs</varname>
|
||||||
|
should be preferred in (almost) all cases to
|
||||||
|
<varname>overrideDerivation</varname>, i.e. to allow using
|
||||||
|
<varname>sdenv.mkDerivation</varname> to process input arguments, as well
|
||||||
|
as the fact that it is easier to use (you can use the same attribute
|
||||||
|
names you see in your Nix code, instead of the ones generated (e.g.
|
||||||
|
<varname>buildInputs</varname> vs <varname>nativeBuildInputs</varname>,
|
||||||
|
and involves less typing.
|
||||||
|
</para>
|
||||||
|
</note>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
|
||||||
|
<section xml:id="sec-pkg-overrideDerivation">
|
||||||
|
<title><pkg>.overrideDerivation</title>
|
||||||
|
|
||||||
|
<warning>
|
||||||
|
<para>You should prefer <varname>overrideAttrs</varname> in almost all
|
||||||
|
cases, see its documentation for the reasons why.
|
||||||
|
<varname>overrideDerivation</varname> is not deprecated and will continue
|
||||||
|
to work, but is less nice to use and does not have as many abilities as
|
||||||
|
<varname>overrideAttrs</varname>.
|
||||||
|
</para>
|
||||||
|
</warning>
|
||||||
|
|
||||||
|
<warning>
|
||||||
|
<para>Do not use this function in Nixpkgs as it evaluates a Derivation
|
||||||
|
before modifying it, which breaks package abstraction and removes
|
||||||
|
error-checking of function arguments. In addition, this
|
||||||
|
evaluation-per-function application incurs a performance penalty,
|
||||||
|
which can become a problem if many overrides are used.
|
||||||
|
It is only intended for ad-hoc customisation, such as in
|
||||||
|
<filename>~/.nixpkgs/config.nix</filename>.
|
||||||
|
</para>
|
||||||
|
</warning>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The function <varname>overrideDerivation</varname> creates a new derivation
|
||||||
|
based on an existing one by overriding the original's attributes with
|
||||||
|
the attribute set produced by the specified function.
|
||||||
|
This function is available on all
|
||||||
|
derivations defined using the <varname>makeOverridable</varname> function.
|
||||||
|
Most standard derivation-producing functions, such as
|
||||||
|
<varname>stdenv.mkDerivation</varname>, are defined using this
|
||||||
|
function, which means most packages in the nixpkgs expression,
|
||||||
|
<varname>pkgs</varname>, have this function.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Example usage:
|
||||||
|
|
||||||
|
<programlisting>mySed = pkgs.gnused.overrideDerivation (oldAttrs: {
|
||||||
|
name = "sed-4.2.2-pre";
|
||||||
|
src = fetchurl {
|
||||||
|
url = ftp://alpha.gnu.org/gnu/sed/sed-4.2.2-pre.tar.bz2;
|
||||||
|
sha256 = "11nq06d131y4wmf3drm0yk502d2xc6n5qy82cg88rb9nqd2lj41k";
|
||||||
|
};
|
||||||
|
patches = [];
|
||||||
|
});</programlisting>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
In the above example, the <varname>name</varname>, <varname>src</varname>,
|
||||||
|
and <varname>patches</varname> of the derivation will be overridden, while
|
||||||
|
all other attributes will be retained from the original derivation.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The argument <varname>oldAttrs</varname> is used to refer to the attribute set of
|
||||||
|
the original derivation.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<note>
|
||||||
|
<para>
|
||||||
|
A package's attributes are evaluated *before* being modified by
|
||||||
|
the <varname>overrideDerivation</varname> function.
|
||||||
|
For example, the <varname>name</varname> attribute reference
|
||||||
|
in <varname>url = "mirror://gnu/hello/${name}.tar.gz";</varname>
|
||||||
|
is filled-in *before* the <varname>overrideDerivation</varname> function
|
||||||
|
modifies the attribute set. This means that overriding the
|
||||||
|
<varname>name</varname> attribute, in this example, *will not* change the
|
||||||
|
value of the <varname>url</varname> attribute. Instead, we need to override
|
||||||
|
both the <varname>name</varname> *and* <varname>url</varname> attributes.
|
||||||
|
</para>
|
||||||
|
</note>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section xml:id="sec-lib-makeOverridable">
|
||||||
|
<title>lib.makeOverridable</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The function <varname>lib.makeOverridable</varname> is used to make the result
|
||||||
|
of a function easily customizable. This utility only makes sense for functions
|
||||||
|
that accept an argument set and return an attribute set.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Example usage:
|
||||||
|
|
||||||
|
<programlisting>f = { a, b }: { result = a+b; }
|
||||||
|
c = lib.makeOverridable f { a = 1; b = 2; }</programlisting>
|
||||||
|
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The variable <varname>c</varname> is the value of the <varname>f</varname> function
|
||||||
|
applied with some default arguments. Hence the value of <varname>c.result</varname>
|
||||||
|
is <literal>3</literal>, in this example.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The variable <varname>c</varname> however also has some additional functions, like
|
||||||
|
<link linkend="sec-pkg-override">c.override</link> which can be used to
|
||||||
|
override the default arguments. In this example the value of
|
||||||
|
<varname>(c.override { a = 4; }).result</varname> is 6.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section xml:id="sec-lib-makeOverridable">
|
<section xml:id="sec-generators">
|
||||||
<title>lib.makeOverridable</title>
|
<title>Generators</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The function <varname>lib.makeOverridable</varname> is used to make the result
|
Generators are functions that create file formats from nix
|
||||||
of a function easily customizable. This utility only makes sense for functions
|
data structures, e. g. for configuration files.
|
||||||
that accept an argument set and return an attribute set.
|
There are generators available for: <literal>INI</literal>,
|
||||||
|
<literal>JSON</literal> and <literal>YAML</literal>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Example usage:
|
All generators follow a similar call interface: <code>generatorName
|
||||||
|
configFunctions data</code>, where <literal>configFunctions</literal> is a
|
||||||
<programlisting>f = { a, b }: { result = a+b; }
|
set of user-defined functions that format variable parts of the content.
|
||||||
c = lib.makeOverridable f { a = 1; b = 2; }</programlisting>
|
They each have common defaults, so often they do not need to be set
|
||||||
|
manually. An example is <code>mkSectionName ? (name: libStr.escape [ "[" "]"
|
||||||
|
] name)</code> from the <literal>INI</literal> generator. It gets the name
|
||||||
|
of a section and returns a sanitized name. The default
|
||||||
|
<literal>mkSectionName</literal> escapes <literal>[</literal> and
|
||||||
|
<literal>]</literal> with a backslash.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<note><para>Nix store paths can be converted to strings by enclosing a
|
||||||
The variable <varname>c</varname> is the value of the <varname>f</varname> function
|
derivation attribute like so: <code>"${drv}"</code>.</para></note>
|
||||||
applied with some default arguments. Hence the value of <varname>c.result</varname>
|
|
||||||
is <literal>3</literal>, in this example.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The variable <varname>c</varname> however also has some additional functions, like
|
Detailed documentation for each generator can be found in
|
||||||
<link linkend="sec-pkg-override">c.override</link> which can be used to
|
<literal>lib/generators.nix</literal>.
|
||||||
override the default arguments. In this example the value of
|
|
||||||
<varname>(c.override { a = 4; }).result</varname> is 6.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
@ -370,37 +413,37 @@ c = lib.makeOverridable f { a = 1; b = 2; }</programlisting>
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section xml:id="sec-pkgs-dockerTools">
|
<section xml:id="sec-pkgs-dockerTools">
|
||||||
<title>pkgs.dockerTools</title>
|
<title>pkgs.dockerTools</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
<varname>pkgs.dockerTools</varname> is a set of functions for creating and
|
<varname>pkgs.dockerTools</varname> is a set of functions for creating and
|
||||||
manipulating Docker images according to the
|
manipulating Docker images according to the
|
||||||
<link xlink:href="https://github.com/docker/docker/blob/master/image/spec/v1.md#docker-image-specification-v100">
|
<link xlink:href="https://github.com/docker/docker/blob/master/image/spec/v1.md#docker-image-specification-v100">
|
||||||
Docker Image Specification v1.0.0
|
Docker Image Specification v1.0.0
|
||||||
</link>. Docker itself is not used to perform any of the operations done by these
|
</link>. Docker itself is not used to perform any of the operations done by these
|
||||||
functions.
|
functions.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<warning>
|
<warning>
|
||||||
<para>
|
<para>
|
||||||
The <varname>dockerTools</varname> API is unstable and may be subject to
|
The <varname>dockerTools</varname> API is unstable and may be subject to
|
||||||
backwards-incompatible changes in the future.
|
backwards-incompatible changes in the future.
|
||||||
</para>
|
</para>
|
||||||
</warning>
|
</warning>
|
||||||
|
|
||||||
<section xml:id="ssec-pkgs-dockerTools-buildImage">
|
<section xml:id="ssec-pkgs-dockerTools-buildImage">
|
||||||
<title>buildImage</title>
|
<title>buildImage</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
This function is analogous to the <command>docker build</command> command,
|
This function is analogous to the <command>docker build</command> command,
|
||||||
in that can used to build a Docker-compatible repository tarball containing
|
in that can used to build a Docker-compatible repository tarball containing
|
||||||
a single image with one or multiple layers. As such, the result
|
a single image with one or multiple layers. As such, the result
|
||||||
is suitable for being loaded in Docker with <command>docker load</command>.
|
is suitable for being loaded in Docker with <command>docker load</command>.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The parameters of <varname>buildImage</varname> with relative example values are
|
The parameters of <varname>buildImage</varname> with relative example values are
|
||||||
described below:
|
described below:
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<example xml:id='ex-dockerTools-buildImage'><title>Docker build</title>
|
<example xml:id='ex-dockerTools-buildImage'><title>Docker build</title>
|
||||||
@ -408,11 +451,11 @@ c = lib.makeOverridable f { a = 1; b = 2; }</programlisting>
|
|||||||
buildImage {
|
buildImage {
|
||||||
name = "redis"; <co xml:id='ex-dockerTools-buildImage-1' />
|
name = "redis"; <co xml:id='ex-dockerTools-buildImage-1' />
|
||||||
tag = "latest"; <co xml:id='ex-dockerTools-buildImage-2' />
|
tag = "latest"; <co xml:id='ex-dockerTools-buildImage-2' />
|
||||||
|
|
||||||
fromImage = someBaseImage; <co xml:id='ex-dockerTools-buildImage-3' />
|
fromImage = someBaseImage; <co xml:id='ex-dockerTools-buildImage-3' />
|
||||||
fromImageName = null; <co xml:id='ex-dockerTools-buildImage-4' />
|
fromImageName = null; <co xml:id='ex-dockerTools-buildImage-4' />
|
||||||
fromImageTag = "latest"; <co xml:id='ex-dockerTools-buildImage-5' />
|
fromImageTag = "latest"; <co xml:id='ex-dockerTools-buildImage-5' />
|
||||||
|
|
||||||
contents = pkgs.redis; <co xml:id='ex-dockerTools-buildImage-6' />
|
contents = pkgs.redis; <co xml:id='ex-dockerTools-buildImage-6' />
|
||||||
runAsRoot = '' <co xml:id='ex-dockerTools-buildImage-runAsRoot' />
|
runAsRoot = '' <co xml:id='ex-dockerTools-buildImage-runAsRoot' />
|
||||||
#!${stdenv.shell}
|
#!${stdenv.shell}
|
||||||
@ -431,131 +474,131 @@ c = lib.makeOverridable f { a = 1; b = 2; }</programlisting>
|
|||||||
</example>
|
</example>
|
||||||
|
|
||||||
<para>The above example will build a Docker image <literal>redis/latest</literal>
|
<para>The above example will build a Docker image <literal>redis/latest</literal>
|
||||||
from the given base image. Loading and running this image in Docker results in
|
from the given base image. Loading and running this image in Docker results in
|
||||||
<literal>redis-server</literal> being started automatically.
|
<literal>redis-server</literal> being started automatically.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<calloutlist>
|
<calloutlist>
|
||||||
<callout arearefs='ex-dockerTools-buildImage-1'>
|
<callout arearefs='ex-dockerTools-buildImage-1'>
|
||||||
<para>
|
<para>
|
||||||
<varname>name</varname> specifies the name of the resulting image.
|
<varname>name</varname> specifies the name of the resulting image.
|
||||||
This is the only required argument for <varname>buildImage</varname>.
|
This is the only required argument for <varname>buildImage</varname>.
|
||||||
</para>
|
</para>
|
||||||
</callout>
|
</callout>
|
||||||
|
|
||||||
<callout arearefs='ex-dockerTools-buildImage-2'>
|
<callout arearefs='ex-dockerTools-buildImage-2'>
|
||||||
<para>
|
<para>
|
||||||
<varname>tag</varname> specifies the tag of the resulting image.
|
<varname>tag</varname> specifies the tag of the resulting image.
|
||||||
By default it's <literal>latest</literal>.
|
By default it's <literal>latest</literal>.
|
||||||
</para>
|
</para>
|
||||||
</callout>
|
</callout>
|
||||||
|
|
||||||
<callout arearefs='ex-dockerTools-buildImage-3'>
|
<callout arearefs='ex-dockerTools-buildImage-3'>
|
||||||
<para>
|
<para>
|
||||||
<varname>fromImage</varname> is the repository tarball containing the base image.
|
<varname>fromImage</varname> is the repository tarball containing the base image.
|
||||||
It must be a valid Docker image, such as exported by <command>docker save</command>.
|
It must be a valid Docker image, such as exported by <command>docker save</command>.
|
||||||
By default it's <literal>null</literal>, which can be seen as equivalent
|
By default it's <literal>null</literal>, which can be seen as equivalent
|
||||||
to <literal>FROM scratch</literal> of a <filename>Dockerfile</filename>.
|
to <literal>FROM scratch</literal> of a <filename>Dockerfile</filename>.
|
||||||
</para>
|
</para>
|
||||||
</callout>
|
</callout>
|
||||||
|
|
||||||
<callout arearefs='ex-dockerTools-buildImage-4'>
|
|
||||||
<para>
|
|
||||||
<varname>fromImageName</varname> can be used to further specify
|
|
||||||
the base image within the repository, in case it contains multiple images.
|
|
||||||
By default it's <literal>null</literal>, in which case
|
|
||||||
<varname>buildImage</varname> will peek the first image available
|
|
||||||
in the repository.
|
|
||||||
</para>
|
|
||||||
</callout>
|
|
||||||
|
|
||||||
<callout arearefs='ex-dockerTools-buildImage-5'>
|
<callout arearefs='ex-dockerTools-buildImage-4'>
|
||||||
<para>
|
<para>
|
||||||
<varname>fromImageTag</varname> can be used to further specify the tag
|
<varname>fromImageName</varname> can be used to further specify
|
||||||
of the base image within the repository, in case an image contains multiple tags.
|
the base image within the repository, in case it contains multiple images.
|
||||||
By default it's <literal>null</literal>, in which case
|
By default it's <literal>null</literal>, in which case
|
||||||
<varname>buildImage</varname> will peek the first tag available for the base image.
|
<varname>buildImage</varname> will peek the first image available
|
||||||
|
in the repository.
|
||||||
</para>
|
</para>
|
||||||
</callout>
|
</callout>
|
||||||
|
|
||||||
<callout arearefs='ex-dockerTools-buildImage-6'>
|
<callout arearefs='ex-dockerTools-buildImage-5'>
|
||||||
<para>
|
<para>
|
||||||
<varname>contents</varname> is a derivation that will be copied in the new
|
<varname>fromImageTag</varname> can be used to further specify the tag
|
||||||
layer of the resulting image. This can be similarly seen as
|
of the base image within the repository, in case an image contains multiple tags.
|
||||||
<command>ADD contents/ /</command> in a <filename>Dockerfile</filename>.
|
By default it's <literal>null</literal>, in which case
|
||||||
By default it's <literal>null</literal>.
|
<varname>buildImage</varname> will peek the first tag available for the base image.
|
||||||
</para>
|
</para>
|
||||||
</callout>
|
</callout>
|
||||||
|
|
||||||
<callout arearefs='ex-dockerTools-buildImage-runAsRoot'>
|
<callout arearefs='ex-dockerTools-buildImage-6'>
|
||||||
<para>
|
<para>
|
||||||
<varname>runAsRoot</varname> is a bash script that will run as root
|
<varname>contents</varname> is a derivation that will be copied in the new
|
||||||
in an environment that overlays the existing layers of the base image with
|
layer of the resulting image. This can be similarly seen as
|
||||||
the new resulting layer, including the previously copied
|
<command>ADD contents/ /</command> in a <filename>Dockerfile</filename>.
|
||||||
<varname>contents</varname> derivation.
|
By default it's <literal>null</literal>.
|
||||||
This can be similarly seen as
|
</para>
|
||||||
<command>RUN ...</command> in a <filename>Dockerfile</filename>.
|
</callout>
|
||||||
|
|
||||||
<note>
|
<callout arearefs='ex-dockerTools-buildImage-runAsRoot'>
|
||||||
|
<para>
|
||||||
|
<varname>runAsRoot</varname> is a bash script that will run as root
|
||||||
|
in an environment that overlays the existing layers of the base image with
|
||||||
|
the new resulting layer, including the previously copied
|
||||||
|
<varname>contents</varname> derivation.
|
||||||
|
This can be similarly seen as
|
||||||
|
<command>RUN ...</command> in a <filename>Dockerfile</filename>.
|
||||||
|
|
||||||
|
<note>
|
||||||
<para>
|
<para>
|
||||||
Using this parameter requires the <literal>kvm</literal>
|
Using this parameter requires the <literal>kvm</literal>
|
||||||
device to be available.
|
device to be available.
|
||||||
</para>
|
</para>
|
||||||
</note>
|
</note>
|
||||||
</para>
|
</para>
|
||||||
</callout>
|
</callout>
|
||||||
|
|
||||||
<callout arearefs='ex-dockerTools-buildImage-8'>
|
<callout arearefs='ex-dockerTools-buildImage-8'>
|
||||||
<para>
|
<para>
|
||||||
<varname>config</varname> is used to specify the configuration of the
|
<varname>config</varname> is used to specify the configuration of the
|
||||||
containers that will be started off the built image in Docker.
|
containers that will be started off the built image in Docker.
|
||||||
The available options are listed in the
|
The available options are listed in the
|
||||||
<link xlink:href="https://github.com/docker/docker/blob/master/image/spec/v1.md#container-runconfig-field-descriptions">
|
<link xlink:href="https://github.com/docker/docker/blob/master/image/spec/v1.md#container-runconfig-field-descriptions">
|
||||||
Docker Image Specification v1.0.0
|
Docker Image Specification v1.0.0
|
||||||
</link>.
|
</link>.
|
||||||
</para>
|
</para>
|
||||||
</callout>
|
</callout>
|
||||||
|
|
||||||
</calloutlist>
|
</calloutlist>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
After the new layer has been created, its closure
|
After the new layer has been created, its closure
|
||||||
(to which <varname>contents</varname>, <varname>config</varname> and
|
(to which <varname>contents</varname>, <varname>config</varname> and
|
||||||
<varname>runAsRoot</varname> contribute) will be copied in the layer itself.
|
<varname>runAsRoot</varname> contribute) will be copied in the layer itself.
|
||||||
Only new dependencies that are not already in the existing layers will be copied.
|
Only new dependencies that are not already in the existing layers will be copied.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
At the end of the process, only one new single layer will be produced and
|
At the end of the process, only one new single layer will be produced and
|
||||||
added to the resulting image.
|
added to the resulting image.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The resulting repository will only list the single image
|
The resulting repository will only list the single image
|
||||||
<varname>image/tag</varname>. In the case of <xref linkend='ex-dockerTools-buildImage'/>
|
<varname>image/tag</varname>. In the case of <xref linkend='ex-dockerTools-buildImage'/>
|
||||||
it would be <varname>redis/latest</varname>.
|
it would be <varname>redis/latest</varname>.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
It is possible to inspect the arguments with which an image was built
|
It is possible to inspect the arguments with which an image was built
|
||||||
using its <varname>buildArgs</varname> attribute.
|
using its <varname>buildArgs</varname> attribute.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section xml:id="ssec-pkgs-dockerTools-fetchFromRegistry">
|
<section xml:id="ssec-pkgs-dockerTools-fetchFromRegistry">
|
||||||
<title>pullImage</title>
|
<title>pullImage</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
This function is analogous to the <command>docker pull</command> command,
|
This function is analogous to the <command>docker pull</command> command,
|
||||||
in that can be used to fetch a Docker image from a Docker registry.
|
in that can be used to fetch a Docker image from a Docker registry.
|
||||||
Currently only registry <literal>v1</literal> is supported.
|
Currently only registry <literal>v1</literal> is supported.
|
||||||
By default <link xlink:href="https://hub.docker.com/">Docker Hub</link>
|
By default <link xlink:href="https://hub.docker.com/">Docker Hub</link>
|
||||||
is used to pull images.
|
is used to pull images.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Its parameters are described in the example below:
|
Its parameters are described in the example below:
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<example xml:id='ex-dockerTools-pullImage'><title>Docker pull</title>
|
<example xml:id='ex-dockerTools-pullImage'><title>Docker pull</title>
|
||||||
@ -573,73 +616,73 @@ c = lib.makeOverridable f { a = 1; b = 2; }</programlisting>
|
|||||||
</example>
|
</example>
|
||||||
|
|
||||||
<calloutlist>
|
<calloutlist>
|
||||||
<callout arearefs='ex-dockerTools-pullImage-1'>
|
<callout arearefs='ex-dockerTools-pullImage-1'>
|
||||||
<para>
|
<para>
|
||||||
<varname>imageName</varname> specifies the name of the image to be downloaded,
|
<varname>imageName</varname> specifies the name of the image to be downloaded,
|
||||||
which can also include the registry namespace (e.g. <literal>library/debian</literal>).
|
which can also include the registry namespace (e.g. <literal>library/debian</literal>).
|
||||||
This argument is required.
|
This argument is required.
|
||||||
</para>
|
</para>
|
||||||
</callout>
|
</callout>
|
||||||
|
|
||||||
<callout arearefs='ex-dockerTools-pullImage-2'>
|
|
||||||
<para>
|
|
||||||
<varname>imageTag</varname> specifies the tag of the image to be downloaded.
|
|
||||||
By default it's <literal>latest</literal>.
|
|
||||||
</para>
|
|
||||||
</callout>
|
|
||||||
|
|
||||||
<callout arearefs='ex-dockerTools-pullImage-3'>
|
<callout arearefs='ex-dockerTools-pullImage-2'>
|
||||||
<para>
|
<para>
|
||||||
<varname>imageId</varname>, if specified this exact image will be fetched, instead
|
<varname>imageTag</varname> specifies the tag of the image to be downloaded.
|
||||||
of <varname>imageName/imageTag</varname>. However, the resulting repository
|
By default it's <literal>latest</literal>.
|
||||||
will still be named <varname>imageName/imageTag</varname>.
|
|
||||||
By default it's <literal>null</literal>.
|
|
||||||
</para>
|
</para>
|
||||||
</callout>
|
</callout>
|
||||||
|
|
||||||
<callout arearefs='ex-dockerTools-pullImage-4'>
|
<callout arearefs='ex-dockerTools-pullImage-3'>
|
||||||
<para>
|
<para>
|
||||||
<varname>sha256</varname> is the checksum of the whole fetched image.
|
<varname>imageId</varname>, if specified this exact image will be fetched, instead
|
||||||
This argument is required.
|
of <varname>imageName/imageTag</varname>. However, the resulting repository
|
||||||
|
will still be named <varname>imageName/imageTag</varname>.
|
||||||
|
By default it's <literal>null</literal>.
|
||||||
|
</para>
|
||||||
|
</callout>
|
||||||
|
|
||||||
|
<callout arearefs='ex-dockerTools-pullImage-4'>
|
||||||
|
<para>
|
||||||
|
<varname>sha256</varname> is the checksum of the whole fetched image.
|
||||||
|
This argument is required.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<note>
|
<note>
|
||||||
<para>The checksum is computed on the unpacked directory, not on the final tarball.</para>
|
<para>The checksum is computed on the unpacked directory, not on the final tarball.</para>
|
||||||
</note>
|
</note>
|
||||||
|
|
||||||
</callout>
|
</callout>
|
||||||
|
|
||||||
<callout arearefs='ex-dockerTools-pullImage-5'>
|
<callout arearefs='ex-dockerTools-pullImage-5'>
|
||||||
<para>
|
<para>
|
||||||
In the above example the default values are shown for the variables
|
In the above example the default values are shown for the variables
|
||||||
<varname>indexUrl</varname> and <varname>registryVersion</varname>.
|
<varname>indexUrl</varname> and <varname>registryVersion</varname>.
|
||||||
Hence by default the Docker.io registry is used to pull the images.
|
Hence by default the Docker.io registry is used to pull the images.
|
||||||
</para>
|
</para>
|
||||||
</callout>
|
</callout>
|
||||||
</calloutlist>
|
</calloutlist>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section xml:id="ssec-pkgs-dockerTools-exportImage">
|
<section xml:id="ssec-pkgs-dockerTools-exportImage">
|
||||||
<title>exportImage</title>
|
<title>exportImage</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
This function is analogous to the <command>docker export</command> command,
|
This function is analogous to the <command>docker export</command> command,
|
||||||
in that can used to flatten a Docker image that contains multiple layers.
|
in that can used to flatten a Docker image that contains multiple layers.
|
||||||
It is in fact the result of the merge of all the layers of the image.
|
It is in fact the result of the merge of all the layers of the image.
|
||||||
As such, the result is suitable for being imported in Docker
|
As such, the result is suitable for being imported in Docker
|
||||||
with <command>docker import</command>.
|
with <command>docker import</command>.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<note>
|
<note>
|
||||||
<para>
|
<para>
|
||||||
Using this function requires the <literal>kvm</literal>
|
Using this function requires the <literal>kvm</literal>
|
||||||
device to be available.
|
device to be available.
|
||||||
</para>
|
</para>
|
||||||
</note>
|
</note>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The parameters of <varname>exportImage</varname> are the following:
|
The parameters of <varname>exportImage</varname> are the following:
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<example xml:id='ex-dockerTools-exportImage'><title>Docker export</title>
|
<example xml:id='ex-dockerTools-exportImage'><title>Docker export</title>
|
||||||
@ -648,35 +691,35 @@ c = lib.makeOverridable f { a = 1; b = 2; }</programlisting>
|
|||||||
fromImage = someLayeredImage;
|
fromImage = someLayeredImage;
|
||||||
fromImageName = null;
|
fromImageName = null;
|
||||||
fromImageTag = null;
|
fromImageTag = null;
|
||||||
|
|
||||||
name = someLayeredImage.name;
|
name = someLayeredImage.name;
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</example>
|
</example>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The parameters relative to the base image have the same synopsis as
|
The parameters relative to the base image have the same synopsis as
|
||||||
described in <xref linkend='ssec-pkgs-dockerTools-buildImage'/>, except that
|
described in <xref linkend='ssec-pkgs-dockerTools-buildImage'/>, except that
|
||||||
<varname>fromImage</varname> is the only required argument in this case.
|
<varname>fromImage</varname> is the only required argument in this case.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The <varname>name</varname> argument is the name of the derivation output,
|
The <varname>name</varname> argument is the name of the derivation output,
|
||||||
which defaults to <varname>fromImage.name</varname>.
|
which defaults to <varname>fromImage.name</varname>.
|
||||||
</para>
|
</para>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section xml:id="ssec-pkgs-dockerTools-shadowSetup">
|
<section xml:id="ssec-pkgs-dockerTools-shadowSetup">
|
||||||
<title>shadowSetup</title>
|
<title>shadowSetup</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
This constant string is a helper for setting up the base files for managing
|
This constant string is a helper for setting up the base files for managing
|
||||||
users and groups, only if such files don't exist already.
|
users and groups, only if such files don't exist already.
|
||||||
It is suitable for being used in a
|
It is suitable for being used in a
|
||||||
<varname>runAsRoot</varname> <xref linkend='ex-dockerTools-buildImage-runAsRoot'/> script for cases like
|
<varname>runAsRoot</varname> <xref linkend='ex-dockerTools-buildImage-runAsRoot'/> script for cases like
|
||||||
in the example below:
|
in the example below:
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<example xml:id='ex-dockerTools-shadowSetup'><title>Shadow base files</title>
|
<example xml:id='ex-dockerTools-shadowSetup'><title>Shadow base files</title>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
buildImage {
|
buildImage {
|
||||||
@ -695,13 +738,13 @@ c = lib.makeOverridable f { a = 1; b = 2; }</programlisting>
|
|||||||
</example>
|
</example>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Creating base files like <literal>/etc/passwd</literal> or
|
Creating base files like <literal>/etc/passwd</literal> or
|
||||||
<literal>/etc/login.defs</literal> are necessary for shadow-utils to
|
<literal>/etc/login.defs</literal> are necessary for shadow-utils to
|
||||||
manipulate users and groups.
|
manipulate users and groups.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
</chapter>
|
</chapter>
|
||||||
|
@ -248,7 +248,7 @@ $ nix-env -f "<nixpkgs>" -iA beamPackages.ibrowse
|
|||||||
development. Many times we need to create a
|
development. Many times we need to create a
|
||||||
<literal>shell.nix</literal> file and do our development inside
|
<literal>shell.nix</literal> file and do our development inside
|
||||||
of the environment specified by that file. This file looks a lot
|
of the environment specified by that file. This file looks a lot
|
||||||
like the packageing described above. The main difference is that
|
like the packaging described above. The main difference is that
|
||||||
<literal>src</literal> points to project root and we call the
|
<literal>src</literal> points to project root and we call the
|
||||||
package directly.
|
package directly.
|
||||||
</para>
|
</para>
|
||||||
|
@ -633,7 +633,7 @@ Now the builds succeeds.
|
|||||||
Of course, in the concrete example of `ghc-events` this whole exercise is not
|
Of course, in the concrete example of `ghc-events` this whole exercise is not
|
||||||
an ideal solution, because `ghc-events` can analyze the output emitted by any
|
an ideal solution, because `ghc-events` can analyze the output emitted by any
|
||||||
version of GHC later than 6.12 regardless of the compiler version that was used
|
version of GHC later than 6.12 regardless of the compiler version that was used
|
||||||
to build the `ghc-events' executable, so strictly speaking there's no reason to
|
to build the `ghc-events` executable, so strictly speaking there's no reason to
|
||||||
prefer one built with GHC 7.8.x in the first place. However, for users who
|
prefer one built with GHC 7.8.x in the first place. However, for users who
|
||||||
cannot use GHC 7.10.x at all for some reason, the approach of downgrading to an
|
cannot use GHC 7.10.x at all for some reason, the approach of downgrading to an
|
||||||
older version might be useful.
|
older version might be useful.
|
||||||
|
@ -97,7 +97,7 @@ We will first have a look at how Python packages are packaged on Nix. Then, we w
|
|||||||
|
|
||||||
#### Python packaging on Nix
|
#### Python packaging on Nix
|
||||||
|
|
||||||
On Nix all packages are built by functions. The main function in Nix for building Python packages is [`buildPythonPackage`](https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/python-modules/generic/default.nix).
|
On Nix all packages are built by functions. The main function in Nix for building Python packages is [`buildPythonPackage`](https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/interpreters/python/build-python-package.nix).
|
||||||
Let's see how we would build the `toolz` package. According to [`python-packages.nix`](https://raw.githubusercontent.com/NixOS/nixpkgs/master/pkgs/top-level/python-packages.nix) `toolz` is build using
|
Let's see how we would build the `toolz` package. According to [`python-packages.nix`](https://raw.githubusercontent.com/NixOS/nixpkgs/master/pkgs/top-level/python-packages.nix) `toolz` is build using
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
@ -141,13 +141,15 @@ with import <nixpkgs> {};
|
|||||||
|
|
||||||
pkgs.python35Packages.buildPythonPackage rec {
|
pkgs.python35Packages.buildPythonPackage rec {
|
||||||
name = "toolz-${version}";
|
name = "toolz-${version}";
|
||||||
version = "0.7.4";
|
version = "0.8.0";
|
||||||
|
|
||||||
src = pkgs.fetchurl{
|
src = pkgs.fetchurl{
|
||||||
url = "mirror://pypi/t/toolz/toolz-${version}.tar.gz";
|
url = "mirror://pypi/t/toolz/toolz-${version}.tar.gz";
|
||||||
sha256 = "43c2c9e5e7a16b6c88ba3088a9bfc82f7db8e13378be7c78d6c14a5f8ed05afd";
|
sha256 = "e8451af61face57b7c5d09e71c0d27b8005f001ead56e9fdf470417e5cc6d479";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
doCheck = false;
|
||||||
|
|
||||||
meta = {
|
meta = {
|
||||||
homepage = "http://github.com/pytoolz/toolz/";
|
homepage = "http://github.com/pytoolz/toolz/";
|
||||||
description = "List processing tools and functional utilities";
|
description = "List processing tools and functional utilities";
|
||||||
@ -170,18 +172,18 @@ with import <nixpkgs> {};
|
|||||||
( let
|
( let
|
||||||
toolz = pkgs.python35Packages.buildPythonPackage rec {
|
toolz = pkgs.python35Packages.buildPythonPackage rec {
|
||||||
name = "toolz-${version}";
|
name = "toolz-${version}";
|
||||||
version = "0.7.4";
|
version = "0.8.0";
|
||||||
|
|
||||||
src = pkgs.fetchurl{
|
src = pkgs.fetchurl{
|
||||||
url = "mirror://pypi/t/toolz/toolz-${version}.tar.gz";
|
url = "mirror://pypi/t/toolz/toolz-${version}.tar.gz";
|
||||||
sha256 = "43c2c9e5e7a16b6c88ba3088a9bfc82f7db8e13378be7c78d6c14a5f8ed05afd";
|
sha256 = "e8451af61face57b7c5d09e71c0d27b8005f001ead56e9fdf470417e5cc6d479";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
doCheck = false;
|
||||||
|
|
||||||
meta = {
|
meta = {
|
||||||
homepage = "http://github.com/pytoolz/toolz/";
|
homepage = "http://github.com/pytoolz/toolz/";
|
||||||
description = "List processing tools and functional utilities";
|
description = "List processing tools and functional utilities";
|
||||||
license = licenses.bsd3;
|
|
||||||
maintainers = with maintainers; [ fridh ];
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -308,11 +310,10 @@ Note also the line `doCheck = false;`, we explicitly disabled running the test-s
|
|||||||
|
|
||||||
#### Develop local package
|
#### Develop local package
|
||||||
|
|
||||||
As a Python developer you're likely aware of [development mode](http://pythonhosted.org/setuptools/setuptools.html#development-mode) (`python setup.py develop`);
|
As a Python developer you're likely aware of [development mode](http://setuptools.readthedocs.io/en/latest/setuptools.html#development-mode) (`python setup.py develop`);
|
||||||
instead of installing the package this command creates a special link to the project code.
|
instead of installing the package this command creates a special link to the project code.
|
||||||
That way, you can run updated code without having to reinstall after each and every change you make.
|
That way, you can run updated code without having to reinstall after each and every change you make.
|
||||||
Development mode is also available on Nix as [explained](http://nixos.org/nixpkgs/manual/#ssec-python-development) in the Nixpkgs manual.
|
Development mode is also available. Let's see how you can use it.
|
||||||
Let's see how you can use it.
|
|
||||||
|
|
||||||
In the previous Nix expression the source was fetched from an url. We can also refer to a local source instead using
|
In the previous Nix expression the source was fetched from an url. We can also refer to a local source instead using
|
||||||
|
|
||||||
@ -409,10 +410,10 @@ and in this case the `python35` interpreter is automatically used.
|
|||||||
|
|
||||||
### Interpreters
|
### Interpreters
|
||||||
|
|
||||||
Versions 2.6, 2.7, 3.3, 3.4 and 3.5 of the CPython interpreter are as respectively
|
Versions 2.6, 2.7, 3.3, 3.4 and 3.5 of the CPython interpreter are available as respectively
|
||||||
`python26`, `python27`, `python33`, `python34` and `python35`. The PyPy interpreter
|
`python26`, `python27`, `python33`, `python34` and `python35`. The PyPy interpreter
|
||||||
is available as `pypy`. The aliases `python2` and `python3` correspond to respectively `python27` and
|
is available as `pypy`. The aliases `python2` and `python3` correspond to respectively `python27` and
|
||||||
`python35`. The default interpreter, `python`, maps to `python3`.
|
`python35`. The default interpreter, `python`, maps to `python2`.
|
||||||
The Nix expressions for the interpreters can be found in
|
The Nix expressions for the interpreters can be found in
|
||||||
`pkgs/development/interpreters/python`.
|
`pkgs/development/interpreters/python`.
|
||||||
|
|
||||||
@ -434,17 +435,20 @@ Each interpreter has the following attributes:
|
|||||||
- `withPackages`. Simpler interface to `buildEnv`. See section *python.withPackages function* for usage and documentation.
|
- `withPackages`. Simpler interface to `buildEnv`. See section *python.withPackages function* for usage and documentation.
|
||||||
- `sitePackages`. Alias for `lib/${libPrefix}/site-packages`.
|
- `sitePackages`. Alias for `lib/${libPrefix}/site-packages`.
|
||||||
- `executable`. Name of the interpreter executable, e.g. `python3.4`.
|
- `executable`. Name of the interpreter executable, e.g. `python3.4`.
|
||||||
|
- `pkgs`. Set of Python packages for that specific interpreter. The package set can be modified by overriding the interpreter and passing `packageOverrides`.
|
||||||
|
|
||||||
### Building packages and applications
|
### Building packages and applications
|
||||||
|
|
||||||
Python packages (libraries) and applications that use `setuptools` or
|
Python libraries and applications that use `setuptools` or
|
||||||
`distutils` are typically built with respectively the `buildPythonPackage` and
|
`distutils` are typically build with respectively the `buildPythonPackage` and
|
||||||
`buildPythonApplication` functions.
|
`buildPythonApplication` functions. These two functions also support installing a `wheel`.
|
||||||
|
|
||||||
All Python packages reside in `pkgs/top-level/python-packages.nix` and all
|
All Python packages reside in `pkgs/top-level/python-packages.nix` and all
|
||||||
applications elsewhere. Some packages are also defined in
|
applications elsewhere. In case a package is used as both a library and an application,
|
||||||
|
then the package should be in `pkgs/top-level/python-packages.nix` since only those packages are made
|
||||||
|
available for all interpreter versions. The preferred location for library expressions is in
|
||||||
`pkgs/development/python-modules`. It is important that these packages are
|
`pkgs/development/python-modules`. It is important that these packages are
|
||||||
called in `pkgs/top-level/python-packages.nix` and not elsewhere, to guarantee
|
called from `pkgs/top-level/python-packages.nix` and not elsewhere, to guarantee
|
||||||
the right version of the package is built.
|
the right version of the package is built.
|
||||||
|
|
||||||
Based on the packages defined in `pkgs/top-level/python-packages.nix` an
|
Based on the packages defined in `pkgs/top-level/python-packages.nix` an
|
||||||
@ -462,14 +466,14 @@ and the aliases
|
|||||||
|
|
||||||
* `pkgs.python2Packages` pointing to `pkgs.python27Packages`
|
* `pkgs.python2Packages` pointing to `pkgs.python27Packages`
|
||||||
* `pkgs.python3Packages` pointing to `pkgs.python35Packages`
|
* `pkgs.python3Packages` pointing to `pkgs.python35Packages`
|
||||||
* `pkgs.pythonPackages` pointing to `pkgs.python3Packages`
|
* `pkgs.pythonPackages` pointing to `pkgs.python2Packages`
|
||||||
|
|
||||||
#### `buildPythonPackage` function
|
#### `buildPythonPackage` function
|
||||||
|
|
||||||
The `buildPythonPackage` function is implemented in
|
The `buildPythonPackage` function is implemented in
|
||||||
`pkgs/development/interpreters/python/build-python-package.nix`
|
`pkgs/development/interpreters/python/build-python-package.nix`
|
||||||
|
|
||||||
and can be used as:
|
The following is an example:
|
||||||
|
|
||||||
twisted = buildPythonPackage {
|
twisted = buildPythonPackage {
|
||||||
name = "twisted-8.1.0";
|
name = "twisted-8.1.0";
|
||||||
@ -520,7 +524,7 @@ All parameters from `mkDerivation` function are still supported.
|
|||||||
* `postShellHook`: Hook to execute commands after `shellHook`.
|
* `postShellHook`: Hook to execute commands after `shellHook`.
|
||||||
* `makeWrapperArgs`: A list of strings. Arguments to be passed to `makeWrapper`, which wraps generated binaries. By default, the arguments to `makeWrapper` set `PATH` and `PYTHONPATH` environment variables before calling the binary. Additional arguments here can allow a developer to set environment variables which will be available when the binary is run. For example, `makeWrapperArgs = ["--set FOO BAR" "--set BAZ QUX"]`.
|
* `makeWrapperArgs`: A list of strings. Arguments to be passed to `makeWrapper`, which wraps generated binaries. By default, the arguments to `makeWrapper` set `PATH` and `PYTHONPATH` environment variables before calling the binary. Additional arguments here can allow a developer to set environment variables which will be available when the binary is run. For example, `makeWrapperArgs = ["--set FOO BAR" "--set BAZ QUX"]`.
|
||||||
* `installFlags`: A list of strings. Arguments to be passed to `pip install`. To pass options to `python setup.py install`, use `--install-option`. E.g., `installFlags=["--install-option='--cpp_implementation'"].
|
* `installFlags`: A list of strings. Arguments to be passed to `pip install`. To pass options to `python setup.py install`, use `--install-option`. E.g., `installFlags=["--install-option='--cpp_implementation'"].
|
||||||
* `format`: Format of the source. Options are `setup` for when the source has a `setup.py` and `setuptools` is used to build a wheel, and `wheel` in case the source is already a binary wheel. The default value is `setup`.
|
* `format`: Format of the source. Valid options are `setuptools` (default), `flit`, `wheel`, and `other`. `setuptools` is for when the source has a `setup.py` and `setuptools` is used to build a wheel, `flit`, in case `flit` should be used to build a wheel, and `wheel` in case a wheel is provided. In case you need to provide your own `buildPhase` and `installPhase` you can use `other`.
|
||||||
* `catchConflicts` If `true`, abort package build if a package name appears more than once in dependency tree. Default is `true`.
|
* `catchConflicts` If `true`, abort package build if a package name appears more than once in dependency tree. Default is `true`.
|
||||||
* `checkInputs` Dependencies needed for running the `checkPhase`. These are added to `buildInputs` when `doCheck = true`.
|
* `checkInputs` Dependencies needed for running the `checkPhase`. These are added to `buildInputs` when `doCheck = true`.
|
||||||
|
|
||||||
@ -697,59 +701,55 @@ should also be done when packaging `A`.
|
|||||||
|
|
||||||
### How to override a Python package?
|
### How to override a Python package?
|
||||||
|
|
||||||
Recursively updating a package can be done with `pkgs.overridePackages` as explained in the Nixpkgs manual.
|
We can override the interpreter and pass `packageOverrides`.
|
||||||
Python attribute sets are created for each interpreter version. We will therefore override the attribute set for the interpreter version we're interested.
|
In the following example we rename the `pandas` package and build it.
|
||||||
In the following example we change the name of the package `pandas` to `foo`.
|
```nix
|
||||||
```
|
|
||||||
newpkgs = pkgs.overridePackages(self: super: rec {
|
|
||||||
python35Packages = (super.python35Packages.override { self = python35Packages;})
|
|
||||||
// { pandas = super.python35Packages.pandas.override {name = "foo";};
|
|
||||||
};
|
|
||||||
});
|
|
||||||
```
|
|
||||||
This can be tested with
|
|
||||||
```
|
|
||||||
with import <nixpkgs> {};
|
with import <nixpkgs> {};
|
||||||
|
|
||||||
(let
|
let
|
||||||
|
python = let
|
||||||
|
packageOverrides = self: super: {
|
||||||
|
pandas = super.pandas.override {name="foo";};
|
||||||
|
};
|
||||||
|
in pkgs.python35.override {inherit packageOverrides;};
|
||||||
|
|
||||||
newpkgs = pkgs.overridePackages(self: super: rec {
|
in python.pkgs.pandas
|
||||||
python35Packages = (super.python35Packages.override { self = python35Packages;})
|
|
||||||
// { pandas = super.python35Packages.pandas.override {name = "foo";};
|
|
||||||
};
|
|
||||||
});
|
|
||||||
in newpkgs.python35.withPackages (ps: [ps.blaze])
|
|
||||||
).env
|
|
||||||
```
|
|
||||||
A typical use case is to switch to another version of a certain package. For example, in the Nixpkgs repository we have multiple versions of `django` and `scipy`.
|
|
||||||
In the following example we use a different version of `scipy`. All packages in `newpkgs` will now use the updated `scipy` version.
|
|
||||||
```
|
```
|
||||||
|
Using `nix-build` on this expression will build the package `pandas`
|
||||||
|
but with the new name `foo`.
|
||||||
|
|
||||||
|
All packages in the package set will use the renamed package.
|
||||||
|
A typical use case is to switch to another version of a certain package.
|
||||||
|
For example, in the Nixpkgs repository we have multiple versions of `django` and `scipy`.
|
||||||
|
In the following example we use a different version of `scipy` and create an environment that uses it.
|
||||||
|
All packages in the Python package set will now use the updated `scipy` version.
|
||||||
|
|
||||||
|
```nix
|
||||||
with import <nixpkgs> {};
|
with import <nixpkgs> {};
|
||||||
|
|
||||||
(let
|
(
|
||||||
|
let
|
||||||
newpkgs = pkgs.overridePackages(self: super: rec {
|
packageOverrides = self: super: {
|
||||||
python35Packages = super.python35Packages.override {
|
scipy = super.scipy_0_17;
|
||||||
self = python35Packages // { scipy = python35Packages.scipy_0_17;};
|
|
||||||
};
|
};
|
||||||
});
|
in (pkgs.python35.override {inherit packageOverrides;}).withPackages (ps: [ps.blaze])
|
||||||
in newpkgs.python35.withPackages (ps: [ps.blaze])
|
|
||||||
).env
|
).env
|
||||||
```
|
```
|
||||||
The requested package `blaze` depends upon `pandas` which itself depends on `scipy`.
|
The requested package `blaze` depends on `pandas` which itself depends on `scipy`.
|
||||||
|
|
||||||
A similar example but now using `django`
|
If you want the whole of Nixpkgs to use your modifications, then you can use `pkgs.overridePackages`
|
||||||
|
as explained in this manual. In the following example we build a `inkscape` using a different version of `numpy`.
|
||||||
```
|
```
|
||||||
with import <nixpkgs> {};
|
let
|
||||||
|
pkgs = import <nixpkgs> {};
|
||||||
(let
|
newpkgs = pkgs.overridePackages ( pkgsself: pkgssuper: {
|
||||||
|
python27 = let
|
||||||
newpkgs = pkgs.overridePackages(self: super: rec {
|
packageOverrides = self: super: {
|
||||||
python27Packages = (super.python27Packages.override {self = python27Packages;})
|
numpy = super.numpy_1_10;
|
||||||
// { django = super.python27Packages.django_1_9; };
|
};
|
||||||
});
|
in pkgssuper.python27.override {inherit packageOverrides;};
|
||||||
in newpkgs.python27.withPackages (ps: [ps.django_guardian ])
|
} );
|
||||||
).env
|
in newpkgs.inkscape
|
||||||
```
|
```
|
||||||
|
|
||||||
### `python setup.py bdist_wheel` cannot create .whl
|
### `python setup.py bdist_wheel` cannot create .whl
|
||||||
@ -770,9 +770,9 @@ or the current time:
|
|||||||
nix-shell --run "SOURCE_DATE_EPOCH=$(date +%s) python3 setup.py bdist_wheel"
|
nix-shell --run "SOURCE_DATE_EPOCH=$(date +%s) python3 setup.py bdist_wheel"
|
||||||
```
|
```
|
||||||
or unset:
|
or unset:
|
||||||
"""
|
```
|
||||||
nix-shell --run "unset SOURCE_DATE_EPOCH; python3 setup.py bdist_wheel"
|
nix-shell --run "unset SOURCE_DATE_EPOCH; python3 setup.py bdist_wheel"
|
||||||
"""
|
```
|
||||||
|
|
||||||
### `install_data` / `data_files` problems
|
### `install_data` / `data_files` problems
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
<xi:include href="package-notes.xml" />
|
<xi:include href="package-notes.xml" />
|
||||||
<xi:include href="coding-conventions.xml" />
|
<xi:include href="coding-conventions.xml" />
|
||||||
<xi:include href="submitting-changes.xml" />
|
<xi:include href="submitting-changes.xml" />
|
||||||
|
<xi:include href="reviewing-contributions.xml" />
|
||||||
<xi:include href="contributing.xml" />
|
<xi:include href="contributing.xml" />
|
||||||
|
|
||||||
</book>
|
</book>
|
||||||
|
@ -382,4 +382,138 @@ it. Place the resulting <filename>package.nix</filename> file into
|
|||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section xml:id="sec-steam">
|
||||||
|
|
||||||
|
<title>Steam</title>
|
||||||
|
|
||||||
|
<section xml:id="sec-steam-nix">
|
||||||
|
|
||||||
|
<title>Steam in Nix</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Steam is distributed as a <filename>.deb</filename> file, for now only
|
||||||
|
as an i686 package (the amd64 package only has documentation).
|
||||||
|
When unpacked, it has a script called <filename>steam</filename> that
|
||||||
|
in ubuntu (their target distro) would go to <filename>/usr/bin
|
||||||
|
</filename>. When run for the first time, this script copies some
|
||||||
|
files to the user's home, which include another script that is the
|
||||||
|
ultimate responsible for launching the steam binary, which is also
|
||||||
|
in $HOME.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Nix problems and constraints:
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem><para>We don't have <filename>/bin/bash</filename> and many
|
||||||
|
scripts point there. Similarly for <filename>/usr/bin/python</filename>
|
||||||
|
.</para></listitem>
|
||||||
|
<listitem><para>We don't have the dynamic loader in <filename>/lib
|
||||||
|
</filename>.</para></listitem>
|
||||||
|
<listitem><para>The <filename>steam.sh</filename> script in $HOME can
|
||||||
|
not be patched, as it is checked and rewritten by steam.</para></listitem>
|
||||||
|
<listitem><para>The steam binary cannot be patched, it's also checked.</para></listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
The current approach to deploy Steam in NixOS is composing a FHS-compatible
|
||||||
|
chroot environment, as documented
|
||||||
|
<link xlink:href="http://sandervanderburg.blogspot.nl/2013/09/composing-fhs-compatible-chroot.html">here</link>.
|
||||||
|
This allows us to have binaries in the expected paths without disrupting the system,
|
||||||
|
and to avoid patching them to work in a non FHS environment.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section xml:id="sec-steam-play">
|
||||||
|
|
||||||
|
<title>How to play</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
For 64-bit systems it's important to have
|
||||||
|
<programlisting>hardware.opengl.driSupport32Bit = true;</programlisting>
|
||||||
|
in your <filename>/etc/nixos/configuration.nix</filename>. You'll also need
|
||||||
|
<programlisting>hardware.pulseaudio.support32Bit = true;</programlisting>
|
||||||
|
if you are using PulseAudio - this will enable 32bit ALSA apps integration.
|
||||||
|
To use the Steam controller, you need to add
|
||||||
|
<programlisting>services.udev.extraRules = ''
|
||||||
|
SUBSYSTEM=="usb", ATTRS{idVendor}=="28de", MODE="0666"
|
||||||
|
KERNEL=="uinput", MODE="0660", GROUP="users", OPTIONS+="static_node=uinput"
|
||||||
|
'';</programlisting>
|
||||||
|
to your configuration.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section xml:id="sec-steam-troub">
|
||||||
|
|
||||||
|
<title>Troubleshooting</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<variablelist>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term>Steam fails to start. What do I do?</term>
|
||||||
|
<listitem><para>Try to run
|
||||||
|
<programlisting>strace steam</programlisting>
|
||||||
|
to see what is causing steam to fail.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term>Using the FOSS Radeon drivers</term>
|
||||||
|
<listitem><itemizedlist><listitem><para>
|
||||||
|
The open source radeon drivers need a newer libc++ than is provided
|
||||||
|
by the default runtime, which leads to a crash on launch. Use
|
||||||
|
<programlisting>environment.systemPackages = [(pkgs.steam.override { newStdcpp = true; })];</programlisting>
|
||||||
|
in your config if you get an error like
|
||||||
|
<programlisting>
|
||||||
|
libGL error: unable to load driver: radeonsi_dri.so
|
||||||
|
libGL error: driver pointer missing
|
||||||
|
libGL error: failed to load driver: radeonsi
|
||||||
|
libGL error: unable to load driver: swrast_dri.so
|
||||||
|
libGL error: failed to load driver: swrast</programlisting></para></listitem>
|
||||||
|
<listitem><para>
|
||||||
|
Steam ships statically linked with a version of libcrypto that
|
||||||
|
conflics with the one dynamically loaded by radeonsi_dri.so.
|
||||||
|
If you get the error
|
||||||
|
<programlisting>steam.sh: line 713: 7842 Segmentation fault (core dumped)</programlisting>
|
||||||
|
have a look at <link xlink:href="https://github.com/NixOS/nixpkgs/pull/20269">this pull request</link>.
|
||||||
|
</para></listitem>
|
||||||
|
|
||||||
|
</itemizedlist></listitem></varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term>Java</term>
|
||||||
|
<listitem><orderedlist>
|
||||||
|
<listitem><para>
|
||||||
|
There is no java in steam chrootenv by default. If you get a message like
|
||||||
|
<programlisting>/home/foo/.local/share/Steam/SteamApps/common/towns/towns.sh: line 1: java: command not found</programlisting>
|
||||||
|
You need to add
|
||||||
|
<programlisting> steam.override { withJava = true; };</programlisting>
|
||||||
|
to your configuration.
|
||||||
|
</para></listitem>
|
||||||
|
</orderedlist></listitem></varlistentry>
|
||||||
|
|
||||||
|
</variablelist>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section xml:id="sec-steam-run">
|
||||||
|
|
||||||
|
<title>steam-run</title>
|
||||||
|
<para>
|
||||||
|
The FHS-compatible chroot used for steam can also be used to run
|
||||||
|
other linux games that expect a FHS environment.
|
||||||
|
To do it, add
|
||||||
|
<programlisting>pkgs.(steam.override {
|
||||||
|
nativeOnly = true;
|
||||||
|
newStdcpp = true;
|
||||||
|
}).run</programlisting>
|
||||||
|
to your configuration, rebuild, and run the game with
|
||||||
|
<programlisting>steam-run ./foo</programlisting>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
</chapter>
|
</chapter>
|
||||||
|
@ -391,7 +391,7 @@ rec {
|
|||||||
);
|
);
|
||||||
in f [] [rhs lhs];
|
in f [] [rhs lhs];
|
||||||
|
|
||||||
/* A recursive variant of the update operator ‘//’. The recusion
|
/* A recursive variant of the update operator ‘//’. The recursion
|
||||||
stops when one of the attribute values is not an attribute set,
|
stops when one of the attribute values is not an attribute set,
|
||||||
in which case the right hand side value takes precedence over the
|
in which case the right hand side value takes precedence over the
|
||||||
left hand side value.
|
left hand side value.
|
||||||
|
@ -27,6 +27,7 @@ let
|
|||||||
|
|
||||||
# misc
|
# misc
|
||||||
debug = import ./debug.nix;
|
debug = import ./debug.nix;
|
||||||
|
generators = import ./generators.nix;
|
||||||
misc = import ./deprecated.nix;
|
misc = import ./deprecated.nix;
|
||||||
|
|
||||||
# domain-specific
|
# domain-specific
|
||||||
@ -39,7 +40,7 @@ in
|
|||||||
customisation maintainers meta sources
|
customisation maintainers meta sources
|
||||||
modules options types
|
modules options types
|
||||||
licenses platforms systems
|
licenses platforms systems
|
||||||
debug misc
|
debug generators misc
|
||||||
sandbox fetchers;
|
sandbox fetchers;
|
||||||
}
|
}
|
||||||
# !!! don't include everything at top-level; perhaps only the most
|
# !!! don't include everything at top-level; perhaps only the most
|
||||||
|
93
lib/generators.nix
Normal file
93
lib/generators.nix
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
/* Functions that generate widespread file
|
||||||
|
* formats from nix data structures.
|
||||||
|
*
|
||||||
|
* They all follow a similar interface:
|
||||||
|
* generator { config-attrs } data
|
||||||
|
*
|
||||||
|
* Tests can be found in ./tests.nix
|
||||||
|
* Documentation in the manual, #sec-generators
|
||||||
|
*/
|
||||||
|
with import ./trivial.nix;
|
||||||
|
let
|
||||||
|
libStr = import ./strings.nix;
|
||||||
|
libAttr = import ./attrsets.nix;
|
||||||
|
|
||||||
|
flipMapAttrs = flip libAttr.mapAttrs;
|
||||||
|
in
|
||||||
|
|
||||||
|
rec {
|
||||||
|
|
||||||
|
/* Generate a line of key k and value v, separated by
|
||||||
|
* character sep. If sep appears in k, it is escaped.
|
||||||
|
* Helper for synaxes with different separators.
|
||||||
|
*
|
||||||
|
* mkKeyValueDefault ":" "f:oo" "bar"
|
||||||
|
* > "f\:oo:bar"
|
||||||
|
*/
|
||||||
|
mkKeyValueDefault = sep: k: v:
|
||||||
|
"${libStr.escape [sep] k}${sep}${toString v}";
|
||||||
|
|
||||||
|
|
||||||
|
/* Generate a key-value-style config file from an attrset.
|
||||||
|
*
|
||||||
|
* mkKeyValue is the same as in toINI.
|
||||||
|
*/
|
||||||
|
toKeyValue = {
|
||||||
|
mkKeyValue ? mkKeyValueDefault "="
|
||||||
|
}: attrs:
|
||||||
|
let mkLine = k: v: mkKeyValue k v + "\n";
|
||||||
|
in libStr.concatStrings (libAttr.mapAttrsToList mkLine attrs);
|
||||||
|
|
||||||
|
|
||||||
|
/* Generate an INI-style config file from an
|
||||||
|
* attrset of sections to an attrset of key-value pairs.
|
||||||
|
*
|
||||||
|
* generators.toINI {} {
|
||||||
|
* foo = { hi = "${pkgs.hello}"; ciao = "bar"; };
|
||||||
|
* baz = { "also, integers" = 42; };
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
*> [baz]
|
||||||
|
*> also, integers=42
|
||||||
|
*>
|
||||||
|
*> [foo]
|
||||||
|
*> ciao=bar
|
||||||
|
*> hi=/nix/store/y93qql1p5ggfnaqjjqhxcw0vqw95rlz0-hello-2.10
|
||||||
|
*
|
||||||
|
* The mk* configuration attributes can generically change
|
||||||
|
* the way sections and key-value strings are generated.
|
||||||
|
*
|
||||||
|
* For more examples see the test cases in ./tests.nix.
|
||||||
|
*/
|
||||||
|
toINI = {
|
||||||
|
# apply transformations (e.g. escapes) to section names
|
||||||
|
mkSectionName ? (name: libStr.escape [ "[" "]" ] name),
|
||||||
|
# format a setting line from key and value
|
||||||
|
mkKeyValue ? mkKeyValueDefault "="
|
||||||
|
}: attrsOfAttrs:
|
||||||
|
let
|
||||||
|
# map function to string for each key val
|
||||||
|
mapAttrsToStringsSep = sep: mapFn: attrs:
|
||||||
|
libStr.concatStringsSep sep
|
||||||
|
(libAttr.mapAttrsToList mapFn attrs);
|
||||||
|
mkSection = sectName: sectValues: ''
|
||||||
|
[${mkSectionName sectName}]
|
||||||
|
'' + toKeyValue { inherit mkKeyValue; } sectValues;
|
||||||
|
in
|
||||||
|
# map input to ini sections
|
||||||
|
mapAttrsToStringsSep "\n" mkSection attrsOfAttrs;
|
||||||
|
|
||||||
|
|
||||||
|
/* Generates JSON from an arbitrary (non-function) value.
|
||||||
|
* For more information see the documentation of the builtin.
|
||||||
|
*/
|
||||||
|
toJSON = {}: builtins.toJSON;
|
||||||
|
|
||||||
|
|
||||||
|
/* YAML has been a strict superset of JSON since 1.2, so we
|
||||||
|
* use toJSON. Before it only had a few differences referring
|
||||||
|
* to implicit typing rules, so it should work with older
|
||||||
|
* parsers as well.
|
||||||
|
*/
|
||||||
|
toYAML = {}@args: toJSON args;
|
||||||
|
}
|
@ -48,6 +48,7 @@
|
|||||||
aske = "Kirill Boltaev <aske@fmap.me>";
|
aske = "Kirill Boltaev <aske@fmap.me>";
|
||||||
asppsa = "Alastair Pharo <asppsa@gmail.com>";
|
asppsa = "Alastair Pharo <asppsa@gmail.com>";
|
||||||
astsmtl = "Alexander Tsamutali <astsmtl@yandex.ru>";
|
astsmtl = "Alexander Tsamutali <astsmtl@yandex.ru>";
|
||||||
|
asymmetric = "Lorenzo Manacorda <lorenzo@mailbox.org>";
|
||||||
aszlig = "aszlig <aszlig@redmoonstudios.org>";
|
aszlig = "aszlig <aszlig@redmoonstudios.org>";
|
||||||
auntie = "Jonathan Glines <auntieNeo@gmail.com>";
|
auntie = "Jonathan Glines <auntieNeo@gmail.com>";
|
||||||
avnik = "Alexander V. Nikolaev <avn@avnik.info>";
|
avnik = "Alexander V. Nikolaev <avn@avnik.info>";
|
||||||
@ -88,6 +89,7 @@
|
|||||||
chris-martin = "Chris Martin <ch.martin@gmail.com>";
|
chris-martin = "Chris Martin <ch.martin@gmail.com>";
|
||||||
chrisjefferson = "Christopher Jefferson <chris@bubblescope.net>";
|
chrisjefferson = "Christopher Jefferson <chris@bubblescope.net>";
|
||||||
christopherpoole = "Christopher Mark Poole <mail@christopherpoole.net>";
|
christopherpoole = "Christopher Mark Poole <mail@christopherpoole.net>";
|
||||||
|
ckampka = "Christian Kampka <christian@kampka.net>";
|
||||||
cko = "Christine Koppelt <christine.koppelt@gmail.com>";
|
cko = "Christine Koppelt <christine.koppelt@gmail.com>";
|
||||||
cleverca22 = "Michael Bishop <cleverca22@gmail.com>";
|
cleverca22 = "Michael Bishop <cleverca22@gmail.com>";
|
||||||
cmcdragonkai = "Roger Qiu <roger.qiu@matrix.ai>";
|
cmcdragonkai = "Roger Qiu <roger.qiu@matrix.ai>";
|
||||||
@ -116,6 +118,7 @@
|
|||||||
deepfire = "Kosyrev Serge <_deepfire@feelingofgreen.ru>";
|
deepfire = "Kosyrev Serge <_deepfire@feelingofgreen.ru>";
|
||||||
demin-dmitriy = "Dmitriy Demin <demindf@gmail.com>";
|
demin-dmitriy = "Dmitriy Demin <demindf@gmail.com>";
|
||||||
DerGuteMoritz = "Moritz Heidkamp <moritz@twoticketsplease.de>";
|
DerGuteMoritz = "Moritz Heidkamp <moritz@twoticketsplease.de>";
|
||||||
|
DerTim1 = "Tim Digel <tim.digel@active-group.de>";
|
||||||
desiderius = "Didier J. Devroye <didier@devroye.name>";
|
desiderius = "Didier J. Devroye <didier@devroye.name>";
|
||||||
devhell = "devhell <\"^\"@regexmail.net>";
|
devhell = "devhell <\"^\"@regexmail.net>";
|
||||||
dezgeg = "Tuomas Tynkkynen <tuomas.tynkkynen@iki.fi>";
|
dezgeg = "Tuomas Tynkkynen <tuomas.tynkkynen@iki.fi>";
|
||||||
@ -128,6 +131,8 @@
|
|||||||
doublec = "Chris Double <chris.double@double.co.nz>";
|
doublec = "Chris Double <chris.double@double.co.nz>";
|
||||||
drets = "Dmytro Rets <dmitryrets@gmail.com>";
|
drets = "Dmytro Rets <dmitryrets@gmail.com>";
|
||||||
drewkett = "Andrew Burkett <burkett.andrew@gmail.com>";
|
drewkett = "Andrew Burkett <burkett.andrew@gmail.com>";
|
||||||
|
dtzWill = "Will Dietz <nix@wdtz.org>";
|
||||||
|
e-user = "Alexander Kahl <nixos@sodosopa.io>";
|
||||||
ebzzry = "Rommel Martinez <ebzzry@gmail.com>";
|
ebzzry = "Rommel Martinez <ebzzry@gmail.com>";
|
||||||
ederoyd46 = "Matthew Brown <matt@ederoyd.co.uk>";
|
ederoyd46 = "Matthew Brown <matt@ederoyd.co.uk>";
|
||||||
eduarrrd = "Eduard Bachmakov <e.bachmakov@gmail.com>";
|
eduarrrd = "Eduard Bachmakov <e.bachmakov@gmail.com>";
|
||||||
@ -137,6 +142,7 @@
|
|||||||
ehmry = "Emery Hemingway <emery@vfemail.net>";
|
ehmry = "Emery Hemingway <emery@vfemail.net>";
|
||||||
eikek = "Eike Kettner <eike.kettner@posteo.de>";
|
eikek = "Eike Kettner <eike.kettner@posteo.de>";
|
||||||
elasticdog = "Aaron Bull Schaefer <aaron@elasticdog.com>";
|
elasticdog = "Aaron Bull Schaefer <aaron@elasticdog.com>";
|
||||||
|
eleanor = "Dejan Lukan <dejan@proteansec.com>";
|
||||||
elitak = "Eric Litak <elitak@gmail.com>";
|
elitak = "Eric Litak <elitak@gmail.com>";
|
||||||
ellis = "Ellis Whitehead <nixos@ellisw.net>";
|
ellis = "Ellis Whitehead <nixos@ellisw.net>";
|
||||||
epitrochoid = "Mabry Cervin <mpcervin@uncg.edu>";
|
epitrochoid = "Mabry Cervin <mpcervin@uncg.edu>";
|
||||||
@ -182,6 +188,7 @@
|
|||||||
gridaphobe = "Eric Seidel <eric@seidel.io>";
|
gridaphobe = "Eric Seidel <eric@seidel.io>";
|
||||||
guibert = "David Guibert <david.guibert@gmail.com>";
|
guibert = "David Guibert <david.guibert@gmail.com>";
|
||||||
guillaumekoenig = "Guillaume Koenig <guillaume.edward.koenig@gmail.com>";
|
guillaumekoenig = "Guillaume Koenig <guillaume.edward.koenig@gmail.com>";
|
||||||
|
guyonvarch = "Joris Guyonvarch <joris@guyonvarch.me>";
|
||||||
hakuch = "Jesse Haber-Kucharsky <hakuch@gmail.com>";
|
hakuch = "Jesse Haber-Kucharsky <hakuch@gmail.com>";
|
||||||
havvy = "Ryan Scheel <ryan.havvy@gmail.com>";
|
havvy = "Ryan Scheel <ryan.havvy@gmail.com>";
|
||||||
hbunke = "Hendrik Bunke <bunke.hendrik@gmail.com>";
|
hbunke = "Hendrik Bunke <bunke.hendrik@gmail.com>";
|
||||||
@ -197,8 +204,10 @@
|
|||||||
jagajaga = "Arseniy Seroka <ars.seroka@gmail.com>";
|
jagajaga = "Arseniy Seroka <ars.seroka@gmail.com>";
|
||||||
javaguirre = "Javier Aguirre <contacto@javaguirre.net>";
|
javaguirre = "Javier Aguirre <contacto@javaguirre.net>";
|
||||||
jb55 = "William Casarin <bill@casarin.me>";
|
jb55 = "William Casarin <bill@casarin.me>";
|
||||||
|
jbedo = "Justin Bedő <cu@cua0.org>";
|
||||||
jcumming = "Jack Cummings <jack@mudshark.org>";
|
jcumming = "Jack Cummings <jack@mudshark.org>";
|
||||||
jefdaj = "Jeffrey David Johnson <jefdaj@gmail.com>";
|
jefdaj = "Jeffrey David Johnson <jefdaj@gmail.com>";
|
||||||
|
jerith666 = "Matt McHenry <github@matt.mchenryfamily.org>";
|
||||||
jfb = "James Felix Black <james@yamtime.com>";
|
jfb = "James Felix Black <james@yamtime.com>";
|
||||||
jgeerds = "Jascha Geerds <jascha@jgeerds.name>";
|
jgeerds = "Jascha Geerds <jascha@jgeerds.name>";
|
||||||
jgillich = "Jakob Gillich <jakob@gillich.me>";
|
jgillich = "Jakob Gillich <jakob@gillich.me>";
|
||||||
@ -235,6 +244,7 @@
|
|||||||
leonardoce = "Leonardo Cecchi <leonardo.cecchi@gmail.com>";
|
leonardoce = "Leonardo Cecchi <leonardo.cecchi@gmail.com>";
|
||||||
lethalman = "Luca Bruno <lucabru@src.gnome.org>";
|
lethalman = "Luca Bruno <lucabru@src.gnome.org>";
|
||||||
lewo = "Antoine Eiche <lewo@abesis.fr>";
|
lewo = "Antoine Eiche <lewo@abesis.fr>";
|
||||||
|
lheckemann = "Linus Heckemann <git@sphalerite.org>";
|
||||||
lhvwb = "Nathaniel Baxter <nathaniel.baxter@gmail.com>";
|
lhvwb = "Nathaniel Baxter <nathaniel.baxter@gmail.com>";
|
||||||
lihop = "Leroy Hopson <nixos@leroy.geek.nz>";
|
lihop = "Leroy Hopson <nixos@leroy.geek.nz>";
|
||||||
linquize = "Linquize <linquize@yahoo.com.hk>";
|
linquize = "Linquize <linquize@yahoo.com.hk>";
|
||||||
@ -266,12 +276,14 @@
|
|||||||
matthiasbeyer = "Matthias Beyer <mail@beyermatthias.de>";
|
matthiasbeyer = "Matthias Beyer <mail@beyermatthias.de>";
|
||||||
maurer = "Matthew Maurer <matthew.r.maurer+nix@gmail.com>";
|
maurer = "Matthew Maurer <matthew.r.maurer+nix@gmail.com>";
|
||||||
mbakke = "Marius Bakke <mbakke@fastmail.com>";
|
mbakke = "Marius Bakke <mbakke@fastmail.com>";
|
||||||
|
mbbx6spp = "Susan Potter <me@susanpotter.net>";
|
||||||
mbe = "Brandon Edens <brandonedens@gmail.com>";
|
mbe = "Brandon Edens <brandonedens@gmail.com>";
|
||||||
mboes = "Mathieu Boespflug <mboes@tweag.net>";
|
mboes = "Mathieu Boespflug <mboes@tweag.net>";
|
||||||
mcmtroffaes = "Matthias C. M. Troffaes <matthias.troffaes@gmail.com>";
|
mcmtroffaes = "Matthias C. M. Troffaes <matthias.troffaes@gmail.com>";
|
||||||
mdaiter = "Matthew S. Daiter <mdaiter8121@gmail.com>";
|
mdaiter = "Matthew S. Daiter <mdaiter8121@gmail.com>";
|
||||||
meditans = "Carlo Nucera <meditans@gmail.com>";
|
meditans = "Carlo Nucera <meditans@gmail.com>";
|
||||||
meisternu = "Matt Miemiec <meister@krutt.org>";
|
meisternu = "Matt Miemiec <meister@krutt.org>";
|
||||||
|
mguentner = "Maximilian Güntner <code@klandest.in>";
|
||||||
mic92 = "Jörg Thalheim <joerg@higgsboson.tk>";
|
mic92 = "Jörg Thalheim <joerg@higgsboson.tk>";
|
||||||
michaelpj = "Michael Peyton Jones <michaelpj@gmail.com>";
|
michaelpj = "Michael Peyton Jones <michaelpj@gmail.com>";
|
||||||
michalrus = "Michal Rus <m@michalrus.com>";
|
michalrus = "Michal Rus <m@michalrus.com>";
|
||||||
@ -281,9 +293,11 @@
|
|||||||
mingchuan = "Ming Chuan <ming@culpring.com>";
|
mingchuan = "Ming Chuan <ming@culpring.com>";
|
||||||
mirdhyn = "Merlin Gaillard <mirdhyn@gmail.com>";
|
mirdhyn = "Merlin Gaillard <mirdhyn@gmail.com>";
|
||||||
mirrexagon = "Andrew Abbott <mirrexagon@mirrexagon.com>";
|
mirrexagon = "Andrew Abbott <mirrexagon@mirrexagon.com>";
|
||||||
|
mjanczyk = "Marcin Janczyk <m@dragonvr.pl>";
|
||||||
mlieberman85 = "Michael Lieberman <mlieberman85@gmail.com>";
|
mlieberman85 = "Michael Lieberman <mlieberman85@gmail.com>";
|
||||||
modulistic = "Pablo Costa <modulistic@gmail.com>";
|
modulistic = "Pablo Costa <modulistic@gmail.com>";
|
||||||
mog = "Matthew O'Gorman <mog-lists@rldn.net>";
|
mog = "Matthew O'Gorman <mog-lists@rldn.net>";
|
||||||
|
montag451 = "montag451 <montag451@laposte.net>";
|
||||||
moosingin3space = "Nathan Moos <moosingin3space@gmail.com>";
|
moosingin3space = "Nathan Moos <moosingin3space@gmail.com>";
|
||||||
moretea = "Maarten Hoogendoorn <maarten@moretea.nl>";
|
moretea = "Maarten Hoogendoorn <maarten@moretea.nl>";
|
||||||
mornfall = "Petr Ročkai <me@mornfall.net>";
|
mornfall = "Petr Ročkai <me@mornfall.net>";
|
||||||
@ -316,6 +330,7 @@
|
|||||||
ocharles = "Oliver Charles <ollie@ocharles.org.uk>";
|
ocharles = "Oliver Charles <ollie@ocharles.org.uk>";
|
||||||
odi = "Oliver Dunkl <oliver.dunkl@gmail.com>";
|
odi = "Oliver Dunkl <oliver.dunkl@gmail.com>";
|
||||||
offline = "Jaka Hudoklin <jakahudoklin@gmail.com>";
|
offline = "Jaka Hudoklin <jakahudoklin@gmail.com>";
|
||||||
|
okasu = "Okasu <oka.sux@gmail.com>";
|
||||||
olcai = "Erik Timan <dev@timan.info>";
|
olcai = "Erik Timan <dev@timan.info>";
|
||||||
olejorgenb = "Ole Jørgen Brønner <olejorgenb@yahoo.no>";
|
olejorgenb = "Ole Jørgen Brønner <olejorgenb@yahoo.no>";
|
||||||
orbekk = "KJ Ørbekk <kjetil.orbekk@gmail.com>";
|
orbekk = "KJ Ørbekk <kjetil.orbekk@gmail.com>";
|
||||||
@ -329,6 +344,7 @@
|
|||||||
palo = "Ingolf Wanger <palipalo9@googlemail.com>";
|
palo = "Ingolf Wanger <palipalo9@googlemail.com>";
|
||||||
pashev = "Igor Pashev <pashev.igor@gmail.com>";
|
pashev = "Igor Pashev <pashev.igor@gmail.com>";
|
||||||
pawelpacana = "Paweł Pacana <pawel.pacana@gmail.com>";
|
pawelpacana = "Paweł Pacana <pawel.pacana@gmail.com>";
|
||||||
|
periklis = "theopompos@gmail.com";
|
||||||
pesterhazy = "Paulus Esterhazy <pesterhazy@gmail.com>";
|
pesterhazy = "Paulus Esterhazy <pesterhazy@gmail.com>";
|
||||||
peterhoeg = "Peter Hoeg <peter@hoeg.com>";
|
peterhoeg = "Peter Hoeg <peter@hoeg.com>";
|
||||||
peti = "Peter Simons <simons@cryp.to>";
|
peti = "Peter Simons <simons@cryp.to>";
|
||||||
@ -372,6 +388,7 @@
|
|||||||
retrry = "Tadas Barzdžius <retrry@gmail.com>";
|
retrry = "Tadas Barzdžius <retrry@gmail.com>";
|
||||||
rick68 = "Wei-Ming Yang <rick68@gmail.com>";
|
rick68 = "Wei-Ming Yang <rick68@gmail.com>";
|
||||||
rickynils = "Rickard Nilsson <rickynils@gmail.com>";
|
rickynils = "Rickard Nilsson <rickynils@gmail.com>";
|
||||||
|
rlupton20 = "Richard Lupton <richard.lupton@gmail.com>";
|
||||||
rnhmjoj = "Michele Guerini Rocco <micheleguerinirocco@me.com>";
|
rnhmjoj = "Michele Guerini Rocco <micheleguerinirocco@me.com>";
|
||||||
rob = "Rob Vermaas <rob.vermaas@gmail.com>";
|
rob = "Rob Vermaas <rob.vermaas@gmail.com>";
|
||||||
robberer = "Longrin Wischnewski <robberer@freakmail.de>";
|
robberer = "Longrin Wischnewski <robberer@freakmail.de>";
|
||||||
@ -458,6 +475,7 @@
|
|||||||
vbgl = "Vincent Laporte <Vincent.Laporte@gmail.com>";
|
vbgl = "Vincent Laporte <Vincent.Laporte@gmail.com>";
|
||||||
vbmithr = "Vincent Bernardoff <vb@luminar.eu.org>";
|
vbmithr = "Vincent Bernardoff <vb@luminar.eu.org>";
|
||||||
vcunat = "Vladimír Čunát <vcunat@gmail.com>";
|
vcunat = "Vladimír Čunát <vcunat@gmail.com>";
|
||||||
|
vdemeester = "Vincent Demeester <vincent@sbr.pm>";
|
||||||
veprbl = "Dmitry Kalinkin <veprbl@gmail.com>";
|
veprbl = "Dmitry Kalinkin <veprbl@gmail.com>";
|
||||||
viric = "Lluís Batlle i Rossell <viric@viric.name>";
|
viric = "Lluís Batlle i Rossell <viric@viric.name>";
|
||||||
vizanto = "Danny Wilson <danny@prime.vc>";
|
vizanto = "Danny Wilson <danny@prime.vc>";
|
||||||
@ -465,6 +483,7 @@
|
|||||||
vlstill = "Vladimír Štill <xstill@fi.muni.cz>";
|
vlstill = "Vladimír Štill <xstill@fi.muni.cz>";
|
||||||
vmandela = "Venkateswara Rao Mandela <venkat.mandela@gmail.com>";
|
vmandela = "Venkateswara Rao Mandela <venkat.mandela@gmail.com>";
|
||||||
volhovm = "Mikhail Volkhov <volhovm.cs@gmail.com>";
|
volhovm = "Mikhail Volkhov <volhovm.cs@gmail.com>";
|
||||||
|
volth = "Jaroslavas Pocepko <jaroslavas@volth.com>";
|
||||||
vozz = "Oliver Hunt <oliver.huntuk@gmail.com>";
|
vozz = "Oliver Hunt <oliver.huntuk@gmail.com>";
|
||||||
vrthra = "Rahul Gopinath <rahul@gopinath.org>";
|
vrthra = "Rahul Gopinath <rahul@gopinath.org>";
|
||||||
wedens = "wedens <kirill.wedens@gmail.com>";
|
wedens = "wedens <kirill.wedens@gmail.com>";
|
||||||
|
@ -375,10 +375,13 @@ rec {
|
|||||||
if def._type or "" == "merge" then
|
if def._type or "" == "merge" then
|
||||||
concatMap dischargeProperties def.contents
|
concatMap dischargeProperties def.contents
|
||||||
else if def._type or "" == "if" then
|
else if def._type or "" == "if" then
|
||||||
if def.condition then
|
if isBool def.condition then
|
||||||
dischargeProperties def.content
|
if def.condition then
|
||||||
|
dischargeProperties def.content
|
||||||
|
else
|
||||||
|
[ ]
|
||||||
else
|
else
|
||||||
[ ]
|
throw "‘mkIf’ called with a non-Boolean condition"
|
||||||
else
|
else
|
||||||
[ def ];
|
[ def ];
|
||||||
|
|
||||||
|
@ -12,19 +12,19 @@ rec {
|
|||||||
|
|
||||||
# Bring in a path as a source, filtering out all Subversion and CVS
|
# Bring in a path as a source, filtering out all Subversion and CVS
|
||||||
# directories, as well as backup files (*~).
|
# directories, as well as backup files (*~).
|
||||||
cleanSource =
|
cleanSourceFilter = name: type: let baseName = baseNameOf (toString name); in ! (
|
||||||
let filter = name: type: let baseName = baseNameOf (toString name); in ! (
|
# Filter out Subversion and CVS directories.
|
||||||
# Filter out Subversion and CVS directories.
|
(type == "directory" && (baseName == ".git" || baseName == ".svn" || baseName == "CVS" || baseName == ".hg")) ||
|
||||||
(type == "directory" && (baseName == ".git" || baseName == ".svn" || baseName == "CVS" || baseName == ".hg")) ||
|
# Filter out backup files.
|
||||||
# Filter out backup files.
|
lib.hasSuffix "~" baseName ||
|
||||||
lib.hasSuffix "~" baseName ||
|
# Filter out generates files.
|
||||||
# Filter out generates files.
|
lib.hasSuffix ".o" baseName ||
|
||||||
lib.hasSuffix ".o" baseName ||
|
lib.hasSuffix ".so" baseName ||
|
||||||
lib.hasSuffix ".so" baseName ||
|
# Filter out nix-build result symlinks
|
||||||
# Filter out nix-build result symlinks
|
(type == "symlink" && lib.hasPrefix "result" baseName)
|
||||||
(type == "symlink" && lib.hasPrefix "result" baseName)
|
);
|
||||||
);
|
|
||||||
in src: builtins.filterSource filter src;
|
cleanSource = builtins.filterSource cleanSourceFilter;
|
||||||
|
|
||||||
|
|
||||||
# Get all files ending with the specified suffices from the given
|
# Get all files ending with the specified suffices from the given
|
||||||
|
@ -130,4 +130,94 @@ runTests {
|
|||||||
expected = false;
|
expected = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Generator tests */
|
||||||
|
# these tests assume attributes are converted to lists
|
||||||
|
# in alphabetical order
|
||||||
|
|
||||||
|
testMkKeyValueDefault = {
|
||||||
|
expr = generators.mkKeyValueDefault ":" "f:oo" "bar";
|
||||||
|
expected = ''f\:oo:bar'';
|
||||||
|
};
|
||||||
|
|
||||||
|
testToKeyValue = {
|
||||||
|
expr = generators.toKeyValue {} {
|
||||||
|
key = "value";
|
||||||
|
"other=key" = "baz";
|
||||||
|
};
|
||||||
|
expected = ''
|
||||||
|
key=value
|
||||||
|
other\=key=baz
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
testToINIEmpty = {
|
||||||
|
expr = generators.toINI {} {};
|
||||||
|
expected = "";
|
||||||
|
};
|
||||||
|
|
||||||
|
testToINIEmptySection = {
|
||||||
|
expr = generators.toINI {} { foo = {}; bar = {}; };
|
||||||
|
expected = ''
|
||||||
|
[bar]
|
||||||
|
|
||||||
|
[foo]
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
testToINIDefaultEscapes = {
|
||||||
|
expr = generators.toINI {} {
|
||||||
|
"no [ and ] allowed unescaped" = {
|
||||||
|
"and also no = in keys" = 42;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
expected = ''
|
||||||
|
[no \[ and \] allowed unescaped]
|
||||||
|
and also no \= in keys=42
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
testToINIDefaultFull = {
|
||||||
|
expr = generators.toINI {} {
|
||||||
|
"section 1" = {
|
||||||
|
attribute1 = 5;
|
||||||
|
x = "Me-se JarJar Binx";
|
||||||
|
};
|
||||||
|
"foo[]" = {
|
||||||
|
"he\\h=he" = "this is okay";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
expected = ''
|
||||||
|
[foo\[\]]
|
||||||
|
he\h\=he=this is okay
|
||||||
|
|
||||||
|
[section 1]
|
||||||
|
attribute1=5
|
||||||
|
x=Me-se JarJar Binx
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
/* right now only invocation check */
|
||||||
|
testToJSONSimple =
|
||||||
|
let val = {
|
||||||
|
foobar = [ "baz" 1 2 3 ];
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
expr = generators.toJSON {} val;
|
||||||
|
# trival implementation
|
||||||
|
expected = builtins.toJSON val;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* right now only invocation check */
|
||||||
|
testToYAMLSimple =
|
||||||
|
let val = {
|
||||||
|
list = [ { one = 1; } { two = 2; } ];
|
||||||
|
all = 42;
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
expr = generators.toYAML {} val;
|
||||||
|
# trival implementation
|
||||||
|
expected = builtins.toJSON val;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -138,7 +138,4 @@ rec {
|
|||||||
*/
|
*/
|
||||||
warn = msg: builtins.trace "WARNING: ${msg}";
|
warn = msg: builtins.trace "WARNING: ${msg}";
|
||||||
info = msg: builtins.trace "INFO: ${msg}";
|
info = msg: builtins.trace "INFO: ${msg}";
|
||||||
|
|
||||||
fetchMD5warn = name: context : data : info
|
|
||||||
"Deprecated use of MD5 hash in ${name} to fetch ${context}" data;
|
|
||||||
}
|
}
|
||||||
|
@ -333,7 +333,15 @@ rec {
|
|||||||
name = "either";
|
name = "either";
|
||||||
description = "${t1.description} or ${t2.description}";
|
description = "${t1.description} or ${t2.description}";
|
||||||
check = x: t1.check x || t2.check x;
|
check = x: t1.check x || t2.check x;
|
||||||
merge = mergeOneOption;
|
merge = loc: defs:
|
||||||
|
let
|
||||||
|
defList = map (d: d.value) defs;
|
||||||
|
in
|
||||||
|
if all (x: t1.check x) defList
|
||||||
|
then t1.merge loc defs
|
||||||
|
else if all (x: t2.check x) defList
|
||||||
|
then t2.merge loc defs
|
||||||
|
else mergeOneOption loc defs;
|
||||||
typeMerge = f':
|
typeMerge = f':
|
||||||
let mt1 = t1.typeMerge (elemAt f'.wrapped 0).functor;
|
let mt1 = t1.typeMerge (elemAt f'.wrapped 0).functor;
|
||||||
mt2 = t2.typeMerge (elemAt f'.wrapped 1).functor;
|
mt2 = t2.typeMerge (elemAt f'.wrapped 1).functor;
|
||||||
|
@ -38,6 +38,12 @@ while test -n "$1"; do
|
|||||||
nix-build $TRAVIS_BUILD_DIR/pkgs/top-level/release.nix --attr tarball --show-trace
|
nix-build $TRAVIS_BUILD_DIR/pkgs/top-level/release.nix --attr tarball --show-trace
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
nixpkgs-unstable)
|
||||||
|
echo "=== Checking nixpkgs unstable job"
|
||||||
|
|
||||||
|
nix-instantiate $TRAVIS_BUILD_DIR/pkgs/top-level/release.nix --attr unstable --show-trace
|
||||||
|
;;
|
||||||
|
|
||||||
nixpkgs-lint)
|
nixpkgs-lint)
|
||||||
echo "=== Checking nixpkgs lint"
|
echo "=== Checking nixpkgs lint"
|
||||||
|
|
||||||
|
131
maintainers/scripts/update.nix
Executable file
131
maintainers/scripts/update.nix
Executable file
@ -0,0 +1,131 @@
|
|||||||
|
{ package ? null
|
||||||
|
, maintainer ? null
|
||||||
|
}:
|
||||||
|
|
||||||
|
# TODO: add assert statements
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
pkgs = import ./../../default.nix { };
|
||||||
|
|
||||||
|
packagesWith = cond: return: set:
|
||||||
|
pkgs.lib.flatten
|
||||||
|
(pkgs.lib.mapAttrsToList
|
||||||
|
(name: pkg:
|
||||||
|
let
|
||||||
|
result = builtins.tryEval (
|
||||||
|
if pkgs.lib.isDerivation pkg && cond name pkg
|
||||||
|
then [(return name pkg)]
|
||||||
|
else if pkg.recurseForDerivations or false || pkg.recurseForRelease or false
|
||||||
|
then packagesWith cond return pkg
|
||||||
|
else []
|
||||||
|
);
|
||||||
|
in
|
||||||
|
if result.success then result.value
|
||||||
|
else []
|
||||||
|
)
|
||||||
|
set
|
||||||
|
);
|
||||||
|
|
||||||
|
packagesWithUpdateScriptAndMaintainer = maintainer':
|
||||||
|
let
|
||||||
|
maintainer =
|
||||||
|
if ! builtins.hasAttr maintainer' pkgs.lib.maintainers then
|
||||||
|
builtins.throw "Maintainer with name `${maintainer'} does not exist in `lib/maintainers.nix`."
|
||||||
|
else
|
||||||
|
builtins.getAttr maintainer' pkgs.lib.maintainers;
|
||||||
|
in
|
||||||
|
packagesWith (name: pkg: builtins.hasAttr "updateScript" pkg &&
|
||||||
|
(if builtins.hasAttr "maintainers" pkg.meta
|
||||||
|
then (if builtins.isList pkg.meta.maintainers
|
||||||
|
then builtins.elem maintainer pkg.meta.maintainers
|
||||||
|
else maintainer == pkg.meta.maintainers
|
||||||
|
)
|
||||||
|
else false
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(name: pkg: pkg)
|
||||||
|
pkgs;
|
||||||
|
|
||||||
|
packageByName = name:
|
||||||
|
let
|
||||||
|
package = pkgs.lib.attrByPath (pkgs.lib.splitString "." name) null pkgs;
|
||||||
|
in
|
||||||
|
if package == null then
|
||||||
|
builtins.throw "Package with an attribute name `${name}` does not exists."
|
||||||
|
else if ! builtins.hasAttr "updateScript" package then
|
||||||
|
builtins.throw "Package with an attribute name `${name}` does have an `passthru.updateScript` defined."
|
||||||
|
else
|
||||||
|
package;
|
||||||
|
|
||||||
|
packages =
|
||||||
|
if package != null then
|
||||||
|
[ (packageByName package) ]
|
||||||
|
else if maintainer != null then
|
||||||
|
packagesWithUpdateScriptAndMaintainer maintainer
|
||||||
|
else
|
||||||
|
builtins.throw "No arguments provided.\n\n${helpText}";
|
||||||
|
|
||||||
|
helpText = ''
|
||||||
|
Please run:
|
||||||
|
|
||||||
|
% nix-shell maintainers/scripts/update.nix --argstr maintainer garbas
|
||||||
|
|
||||||
|
to run all update scripts for all packages that lists \`garbas\` as a maintainer
|
||||||
|
and have \`updateScript\` defined, or:
|
||||||
|
|
||||||
|
% nix-shell maintainers/scripts/update.nix --argstr package garbas
|
||||||
|
|
||||||
|
to run update script for specific package.
|
||||||
|
'';
|
||||||
|
|
||||||
|
runUpdateScript = package: ''
|
||||||
|
echo -ne " - ${package.name}: UPDATING ..."\\r
|
||||||
|
${package.updateScript} &> ${(builtins.parseDrvName package.name).name}.log
|
||||||
|
CODE=$?
|
||||||
|
if [ "$CODE" != "0" ]; then
|
||||||
|
echo " - ${package.name}: ERROR "
|
||||||
|
echo ""
|
||||||
|
echo "--- SHOWING ERROR LOG FOR ${package.name} ----------------------"
|
||||||
|
echo ""
|
||||||
|
cat ${(builtins.parseDrvName package.name).name}.log
|
||||||
|
echo ""
|
||||||
|
echo "--- SHOWING ERROR LOG FOR ${package.name} ----------------------"
|
||||||
|
exit $CODE
|
||||||
|
else
|
||||||
|
rm ${(builtins.parseDrvName package.name).name}.log
|
||||||
|
fi
|
||||||
|
echo " - ${package.name}: DONE. "
|
||||||
|
'';
|
||||||
|
|
||||||
|
in pkgs.stdenv.mkDerivation {
|
||||||
|
name = "nixpkgs-update-script";
|
||||||
|
buildCommand = ''
|
||||||
|
echo ""
|
||||||
|
echo "----------------------------------------------------------------"
|
||||||
|
echo ""
|
||||||
|
echo "Not possible to update packages using \`nix-build\`"
|
||||||
|
echo ""
|
||||||
|
echo "${helpText}"
|
||||||
|
echo "----------------------------------------------------------------"
|
||||||
|
exit 1
|
||||||
|
'';
|
||||||
|
shellHook = ''
|
||||||
|
echo ""
|
||||||
|
echo "Going to be running update for following packages:"
|
||||||
|
echo "${builtins.concatStringsSep "\n" (map (x: " - ${x.name}") packages)}"
|
||||||
|
echo ""
|
||||||
|
read -n1 -r -p "Press space to continue..." confirm
|
||||||
|
if [ "$confirm" = "" ]; then
|
||||||
|
echo ""
|
||||||
|
echo "Running update for:"
|
||||||
|
${builtins.concatStringsSep "\n" (map runUpdateScript packages)}
|
||||||
|
echo ""
|
||||||
|
echo "Packages updated!"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo "Aborting!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
}
|
@ -47,4 +47,12 @@ where <literal>eth0</literal> should be replaced with the desired
|
|||||||
external interface. Note that <literal>ve-+</literal> is a wildcard
|
external interface. Note that <literal>ve-+</literal> is a wildcard
|
||||||
that matches all container interfaces.</para>
|
that matches all container interfaces.</para>
|
||||||
|
|
||||||
|
<para>If you are using Network Manager, you need to explicitly prevent
|
||||||
|
it from managing container interfaces:
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
networking.networkmanager.unmanaged = [ "interface-name:ve-*" ];
|
||||||
|
</programlisting>
|
||||||
|
</para>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
@ -129,7 +129,7 @@ default; run <literal>nix-env -i nix-repl</literal> to get it. A
|
|||||||
typical use:
|
typical use:
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
$ nix-repl '<nixos>'
|
$ nix-repl '<nixpkgs/nixos>'
|
||||||
|
|
||||||
nix-repl> config.networking.hostName
|
nix-repl> config.networking.hostName
|
||||||
"mandark"
|
"mandark"
|
||||||
|
@ -18,7 +18,6 @@ NixOS.</para>
|
|||||||
<xi:include href="building-nixos.xml" />
|
<xi:include href="building-nixos.xml" />
|
||||||
<xi:include href="nixos-tests.xml" />
|
<xi:include href="nixos-tests.xml" />
|
||||||
<xi:include href="testing-installer.xml" />
|
<xi:include href="testing-installer.xml" />
|
||||||
<xi:include href="reviewing-contributions.xml" />
|
|
||||||
<xi:include href="releases.xml" />
|
<xi:include href="releases.xml" />
|
||||||
|
|
||||||
</part>
|
</part>
|
||||||
|
@ -101,6 +101,11 @@ channel by running
|
|||||||
which is equivalent to the more verbose <literal>nix-channel --update
|
which is equivalent to the more verbose <literal>nix-channel --update
|
||||||
nixos; nixos-rebuild switch</literal>.</para>
|
nixos; nixos-rebuild switch</literal>.</para>
|
||||||
|
|
||||||
|
<note><para>Channels are set per user. This means that running <literal>
|
||||||
|
nix-channel --add</literal> as a non root user (or without sudo) will not
|
||||||
|
affect configuration in <literal>/etc/nixos/configuration.nix</literal>
|
||||||
|
</para></note>
|
||||||
|
|
||||||
<warning><para>It is generally safe to switch back and forth between
|
<warning><para>It is generally safe to switch back and forth between
|
||||||
channels. The only exception is that a newer NixOS may also have a
|
channels. The only exception is that a newer NixOS may also have a
|
||||||
newer Nix version, which may involve an upgrade of Nix’s database
|
newer Nix version, which may involve an upgrade of Nix’s database
|
||||||
|
@ -68,7 +68,7 @@ desired operation. It must be one of the following:
|
|||||||
<listitem>
|
<listitem>
|
||||||
<para>Build and activate the new configuration, and make it the
|
<para>Build and activate the new configuration, and make it the
|
||||||
boot default. That is, the configuration is added to the GRUB
|
boot default. That is, the configuration is added to the GRUB
|
||||||
boot menu as the default meny entry, so that subsequent reboots
|
boot menu as the default menu entry, so that subsequent reboots
|
||||||
will boot the system into the new configuration. Previous
|
will boot the system into the new configuration. Previous
|
||||||
configurations activated with <command>nixos-rebuild
|
configurations activated with <command>nixos-rebuild
|
||||||
switch</command> or <command>nixos-rebuild boot</command> remain
|
switch</command> or <command>nixos-rebuild boot</command> remain
|
||||||
|
@ -68,6 +68,26 @@ following incompatible changes:</para>
|
|||||||
that may be in /etc.
|
that may be in /etc.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Parsoid service now uses YAML configuration format.
|
||||||
|
<literal>service.parsoid.interwikis</literal> is now called
|
||||||
|
<literal>service.parsoid.wikis</literal> and is a list of either API URLs
|
||||||
|
or attribute sets as specified in parsoid's documentation.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal>Ntpd</literal> was replaced by
|
||||||
|
<literal>systemd-timesyncd</literal> as the default service to synchronize
|
||||||
|
system time with a remote NTP server. The old behavior can be restored by
|
||||||
|
setting <literal>services.ntp.enable</literal> to <literal>true</literal>.
|
||||||
|
Upstream time servers for all NTP implementations are now configured using
|
||||||
|
<literal>networking.timeServers</literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
|
|
||||||
|
@ -9,6 +9,8 @@ rec {
|
|||||||
|
|
||||||
inherit pkgs;
|
inherit pkgs;
|
||||||
|
|
||||||
|
qemu = pkgs.qemu_test;
|
||||||
|
|
||||||
|
|
||||||
# Build a virtual network from an attribute set `{ machine1 =
|
# Build a virtual network from an attribute set `{ machine1 =
|
||||||
# config1; ... machineN = configN; }', where `machineX' is the
|
# config1; ... machineN = configN; }', where `machineX' is the
|
||||||
@ -27,6 +29,7 @@ rec {
|
|||||||
[ ../modules/virtualisation/qemu-vm.nix
|
[ ../modules/virtualisation/qemu-vm.nix
|
||||||
../modules/testing/test-instrumentation.nix # !!! should only get added for automated test runs
|
../modules/testing/test-instrumentation.nix # !!! should only get added for automated test runs
|
||||||
{ key = "no-manual"; services.nixosManual.enable = false; }
|
{ key = "no-manual"; services.nixosManual.enable = false; }
|
||||||
|
{ key = "qemu"; system.build.qemu = qemu; }
|
||||||
] ++ optional minimal ../modules/testing/minimal-kernel.nix;
|
] ++ optional minimal ../modules/testing/minimal-kernel.nix;
|
||||||
extraArgs = { inherit nodes; };
|
extraArgs = { inherit nodes; };
|
||||||
};
|
};
|
||||||
|
@ -27,6 +27,10 @@
|
|||||||
|
|
||||||
, name ? "nixos-disk-image"
|
, name ? "nixos-disk-image"
|
||||||
|
|
||||||
|
# This prevents errors while checking nix-store validity, see
|
||||||
|
# https://github.com/NixOS/nix/issues/1134
|
||||||
|
, fixValidity ? true
|
||||||
|
|
||||||
, format ? "raw"
|
, format ? "raw"
|
||||||
}:
|
}:
|
||||||
|
|
||||||
@ -61,9 +65,6 @@ pkgs.vmTools.runInLinuxVM (
|
|||||||
|
|
||||||
# Create an empty filesystem and mount it.
|
# Create an empty filesystem and mount it.
|
||||||
mkfs.${fsType} -L nixos $rootDisk
|
mkfs.${fsType} -L nixos $rootDisk
|
||||||
${optionalString (fsType == "ext4") ''
|
|
||||||
tune2fs -c 0 -i 0 $rootDisk
|
|
||||||
''}
|
|
||||||
mkdir /mnt
|
mkdir /mnt
|
||||||
mount $rootDisk /mnt
|
mount $rootDisk /mnt
|
||||||
|
|
||||||
@ -71,9 +72,11 @@ pkgs.vmTools.runInLinuxVM (
|
|||||||
printRegistration=1 perl ${pkgs.pathsFromGraph} /tmp/xchg/closure | \
|
printRegistration=1 perl ${pkgs.pathsFromGraph} /tmp/xchg/closure | \
|
||||||
${config.nix.package.out}/bin/nix-store --load-db --option build-users-group ""
|
${config.nix.package.out}/bin/nix-store --load-db --option build-users-group ""
|
||||||
|
|
||||||
# Add missing size/hash fields to the database. FIXME:
|
${if fixValidity then ''
|
||||||
# exportReferencesGraph should provide these directly.
|
# Add missing size/hash fields to the database. FIXME:
|
||||||
${config.nix.package.out}/bin/nix-store --verify --check-contents --option build-users-group ""
|
# exportReferencesGraph should provide these directly.
|
||||||
|
${config.nix.package.out}/bin/nix-store --verify --check-contents --option build-users-group ""
|
||||||
|
'' else ""}
|
||||||
|
|
||||||
# In case the bootloader tries to write to /dev/sda…
|
# In case the bootloader tries to write to /dev/sda…
|
||||||
ln -s vda /dev/xvda
|
ln -s vda /dev/xvda
|
||||||
@ -97,7 +100,9 @@ pkgs.vmTools.runInLinuxVM (
|
|||||||
|
|
||||||
umount /mnt
|
umount /mnt
|
||||||
|
|
||||||
# Do a fsck to make sure resize2fs works.
|
# Make sure resize2fs works
|
||||||
fsck.${fsType} -f -y $rootDisk
|
${optionalString (fsType == "ext4") ''
|
||||||
|
tune2fs -c 0 -i 0 $rootDisk
|
||||||
|
''}
|
||||||
''
|
''
|
||||||
)
|
)
|
||||||
|
@ -25,6 +25,6 @@ stdenv.mkDerivation {
|
|||||||
|
|
||||||
# Generate the squashfs image.
|
# Generate the squashfs image.
|
||||||
mksquashfs nix-path-registration $storePaths $out \
|
mksquashfs nix-path-registration $storePaths $out \
|
||||||
-keep-as-directory -all-root
|
-keep-as-directory -all-root -comp xz
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
@ -52,9 +52,10 @@ $extraCommands
|
|||||||
|
|
||||||
mkdir -p $out/tarball
|
mkdir -p $out/tarball
|
||||||
|
|
||||||
tar cvJf $out/tarball/$fileName.tar.xz * $extraArgs
|
rm env-vars
|
||||||
|
|
||||||
|
tar --sort=name --mtime='1970-01-01' -cvJf $out/tarball/$fileName.tar.xz * $extraArgs
|
||||||
|
|
||||||
mkdir -p $out/nix-support
|
mkdir -p $out/nix-support
|
||||||
echo $system > $out/nix-support/system
|
echo $system > $out/nix-support/system
|
||||||
echo "file system-tarball $out/tarball/$fileName.tar.xz" > $out/nix-support/hydra-build-products
|
echo "file system-tarball $out/tarball/$fileName.tar.xz" > $out/nix-support/hydra-build-products
|
||||||
|
|
||||||
|
@ -504,6 +504,31 @@ sub screenshot {
|
|||||||
}, { image => $name } );
|
}, { image => $name } );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Get the text of TTY<n>
|
||||||
|
sub getTTYText {
|
||||||
|
my ($self, $tty) = @_;
|
||||||
|
|
||||||
|
my ($status, $out) = $self->execute("fold -w 80 /dev/vcs${tty}");
|
||||||
|
return $out;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Wait until TTY<n>'s text matches a particular regular expression
|
||||||
|
sub waitUntilTTYMatches {
|
||||||
|
my ($self, $tty, $regexp) = @_;
|
||||||
|
|
||||||
|
$self->nest("waiting for $regexp to appear on tty $tty", sub {
|
||||||
|
retry sub {
|
||||||
|
return 1 if $self->getTTYText($tty) =~ /$regexp/;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
# Debugging: Dump the contents of the TTY<n>
|
||||||
|
sub dumpTTYContents {
|
||||||
|
my ($self, $tty) = @_;
|
||||||
|
|
||||||
|
$self->execute("fold -w 80 /dev/vcs${tty} | systemd-cat");
|
||||||
|
}
|
||||||
|
|
||||||
# Take a screenshot and return the result as text using optical character
|
# Take a screenshot and return the result as text using optical character
|
||||||
# recognition.
|
# recognition.
|
||||||
|
@ -29,7 +29,7 @@ rec {
|
|||||||
cp ${./test-driver/Logger.pm} $libDir/Logger.pm
|
cp ${./test-driver/Logger.pm} $libDir/Logger.pm
|
||||||
|
|
||||||
wrapProgram $out/bin/nixos-test-driver \
|
wrapProgram $out/bin/nixos-test-driver \
|
||||||
--prefix PATH : "${lib.makeBinPath [ qemu_kvm vde2 netpbm coreutils ]}" \
|
--prefix PATH : "${lib.makeBinPath [ qemu vde2 netpbm coreutils ]}" \
|
||||||
--prefix PERL5LIB : "${with perlPackages; lib.makePerlPath [ TermReadLineGnu XMLWriter IOTty FileSlurp ]}:$out/lib/perl5/site_perl"
|
--prefix PERL5LIB : "${with perlPackages; lib.makePerlPath [ TermReadLineGnu XMLWriter IOTty FileSlurp ]}:$out/lib/perl5/site_perl"
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
@ -93,7 +93,7 @@ rec {
|
|||||||
|
|
||||||
vms = map (m: m.config.system.build.vm) (lib.attrValues nodes);
|
vms = map (m: m.config.system.build.vm) (lib.attrValues nodes);
|
||||||
|
|
||||||
ocrProg = tesseract.override { enableLanguages = [ "eng" ]; };
|
ocrProg = tesseract;
|
||||||
|
|
||||||
# Generate onvenience wrappers for running the test driver
|
# Generate onvenience wrappers for running the test driver
|
||||||
# interactively with the specified network, and for starting the
|
# interactively with the specified network, and for starting the
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
#! /bin/sh -e
|
#!/usr/bin/env nix-shell
|
||||||
|
#! nix-shell -i bash -p qemu ec2_ami_tools jq ec2_api_tools awscli
|
||||||
|
|
||||||
|
# To start with do: nix-shell -p awscli --run "aws configure"
|
||||||
|
|
||||||
|
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
#set -x
|
#set -x
|
||||||
@ -15,7 +19,7 @@ rm -f ec2-amis.nix
|
|||||||
|
|
||||||
types="hvm pv"
|
types="hvm pv"
|
||||||
stores="ebs s3"
|
stores="ebs s3"
|
||||||
regions="eu-west-1 eu-central-1 us-east-1 us-west-1 us-west-2 ap-southeast-1 ap-southeast-2 ap-northeast-1 ap-northeast-2 sa-east-1 ap-south-1"
|
regions="eu-west-1 eu-central-1 us-east-1 us-east-2 us-west-1 us-west-2 ap-southeast-1 ap-southeast-2 ap-northeast-1 ap-northeast-2 sa-east-1 ap-south-1"
|
||||||
|
|
||||||
for type in $types; do
|
for type in $types; do
|
||||||
link=$stateDir/$type
|
link=$stateDir/$type
|
||||||
@ -57,7 +61,7 @@ for type in $types; do
|
|||||||
ami=$(aws ec2 copy-image \
|
ami=$(aws ec2 copy-image \
|
||||||
--region "$region" \
|
--region "$region" \
|
||||||
--source-region "$prevRegion" --source-image-id "$prevAmi" \
|
--source-region "$prevRegion" --source-image-id "$prevAmi" \
|
||||||
--name "$name" --description "$description" | json -q .ImageId)
|
--name "$name" --description "$description" | jq -r '.ImageId')
|
||||||
if [ "$ami" = null ]; then break; fi
|
if [ "$ami" = null ]; then break; fi
|
||||||
else
|
else
|
||||||
|
|
||||||
|
@ -301,9 +301,7 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
style = mkOption {
|
style = mkOption {
|
||||||
type = types.str // {
|
type = types.enum ["none" "slight" "medium" "full"];
|
||||||
check = flip elem ["none" "slight" "medium" "full"];
|
|
||||||
};
|
|
||||||
default = "full";
|
default = "full";
|
||||||
description = ''
|
description = ''
|
||||||
TrueType hinting style, one of <literal>none</literal>,
|
TrueType hinting style, one of <literal>none</literal>,
|
||||||
@ -329,9 +327,7 @@ in
|
|||||||
default = "rgb";
|
default = "rgb";
|
||||||
type = types.enum ["rgb" "bgr" "vrgb" "vbgr" "none"];
|
type = types.enum ["rgb" "bgr" "vrgb" "vbgr" "none"];
|
||||||
description = ''
|
description = ''
|
||||||
Subpixel order, one of <literal>none</literal>,
|
Subpixel order.
|
||||||
<literal>rgb</literal>, <literal>bgr</literal>,
|
|
||||||
<literal>vrgb</literal>, or <literal>vbgr</literal>.
|
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -339,9 +335,7 @@ in
|
|||||||
default = "default";
|
default = "default";
|
||||||
type = types.enum ["none" "default" "light" "legacy"];
|
type = types.enum ["none" "default" "light" "legacy"];
|
||||||
description = ''
|
description = ''
|
||||||
FreeType LCD filter, one of <literal>none</literal>,
|
FreeType LCD filter.
|
||||||
<literal>default</literal>, <literal>light</literal>, or
|
|
||||||
<literal>legacy</literal>.
|
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -7,11 +7,11 @@ with lib;
|
|||||||
gnu = mkOption {
|
gnu = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
description =
|
description = ''
|
||||||
'' When enabled, GNU software is chosen by default whenever a there is
|
When enabled, GNU software is chosen by default whenever a there is
|
||||||
a choice between GNU and non-GNU software (e.g., GNU lsh
|
a choice between GNU and non-GNU software (e.g., GNU lsh
|
||||||
vs. OpenSSH).
|
vs. OpenSSH).
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -44,8 +44,9 @@ in
|
|||||||
consolePackages = mkOption {
|
consolePackages = mkOption {
|
||||||
type = types.listOf types.package;
|
type = types.listOf types.package;
|
||||||
default = with pkgs.kbdKeymaps; [ dvp neo ];
|
default = with pkgs.kbdKeymaps; [ dvp neo ];
|
||||||
|
defaultText = ''with pkgs.kbdKeymaps; [ dvp neo ]'';
|
||||||
description = ''
|
description = ''
|
||||||
List of additional packages that provide console fonts, keymaps and
|
List of additional packages that provide console fonts, keymaps and
|
||||||
other resources.
|
other resources.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
@ -84,6 +84,18 @@ in
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
networking.timeServers = mkOption {
|
||||||
|
default = [
|
||||||
|
"0.nixos.pool.ntp.org"
|
||||||
|
"1.nixos.pool.ntp.org"
|
||||||
|
"2.nixos.pool.ntp.org"
|
||||||
|
"3.nixos.pool.ntp.org"
|
||||||
|
];
|
||||||
|
description = ''
|
||||||
|
The set of NTP servers from which to synchronise.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
networking.proxy = {
|
networking.proxy = {
|
||||||
|
|
||||||
default = lib.mkOption {
|
default = lib.mkOption {
|
||||||
|
@ -10,9 +10,21 @@ let
|
|||||||
inherit (config.services.samba) nsswins;
|
inherit (config.services.samba) nsswins;
|
||||||
ldap = (config.users.ldap.enable && config.users.ldap.nsswitch);
|
ldap = (config.users.ldap.enable && config.users.ldap.nsswitch);
|
||||||
|
|
||||||
in
|
hostArray = [ "files" "mymachines" ]
|
||||||
|
++ optionals nssmdns [ "mdns_minimal [!UNAVAIL=return]" ]
|
||||||
|
++ optionals nsswins [ "wins" ]
|
||||||
|
++ [ "dns" ]
|
||||||
|
++ optionals nssmdns [ "mdns" ]
|
||||||
|
++ ["myhostname" ];
|
||||||
|
|
||||||
{
|
passwdArray = [ "files" ]
|
||||||
|
++ optionals ldap [ "ldap" ]
|
||||||
|
++ [ "mymachines" ];
|
||||||
|
|
||||||
|
shadowArray = [ "files" ]
|
||||||
|
++ optionals ldap [ "ldap" ];
|
||||||
|
|
||||||
|
in {
|
||||||
options = {
|
options = {
|
||||||
|
|
||||||
# NSS modules. Hacky!
|
# NSS modules. Hacky!
|
||||||
@ -39,24 +51,26 @@ in
|
|||||||
# Name Service Switch configuration file. Required by the C
|
# Name Service Switch configuration file. Required by the C
|
||||||
# library. !!! Factor out the mdns stuff. The avahi module
|
# library. !!! Factor out the mdns stuff. The avahi module
|
||||||
# should define an option used by this module.
|
# should define an option used by this module.
|
||||||
environment.etc."nsswitch.conf".text =
|
environment.etc."nsswitch.conf".text = ''
|
||||||
''
|
passwd: ${concatStringsSep " " passwdArray}
|
||||||
passwd: files ${optionalString ldap "ldap"}
|
group: ${concatStringsSep " " passwdArray}
|
||||||
group: files ${optionalString ldap "ldap"}
|
shadow: ${concatStringsSep " " shadowArray}
|
||||||
shadow: files ${optionalString ldap "ldap"}
|
|
||||||
hosts: files ${optionalString nssmdns "mdns_minimal [NOTFOUND=return]"} dns ${optionalString nssmdns "mdns"} ${optionalString nsswins "wins"} myhostname mymachines
|
hosts: ${concatStringsSep " " hostArray}
|
||||||
networks: files dns
|
networks: files
|
||||||
ethers: files
|
|
||||||
services: files
|
ethers: files
|
||||||
protocols: files
|
services: files
|
||||||
'';
|
protocols: files
|
||||||
|
rpc: files
|
||||||
|
'';
|
||||||
|
|
||||||
# Systemd provides nss-myhostname to ensure that our hostname
|
# Systemd provides nss-myhostname to ensure that our hostname
|
||||||
# always resolves to a valid IP address. It returns all locally
|
# always resolves to a valid IP address. It returns all locally
|
||||||
# configured IP addresses, or ::1 and 127.0.0.2 as
|
# configured IP addresses, or ::1 and 127.0.0.2 as
|
||||||
# fallbacks. Systemd also provides nss-mymachines to return IP
|
# fallbacks. Systemd also provides nss-mymachines to return IP
|
||||||
# addresses of local containers.
|
# addresses of local containers.
|
||||||
system.nssModules = [ config.systemd.package ];
|
system.nssModules = [ config.systemd.package.out ];
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -118,6 +118,7 @@ in
|
|||||||
"/share/terminfo"
|
"/share/terminfo"
|
||||||
"/share/themes"
|
"/share/themes"
|
||||||
"/share/vim-plugins"
|
"/share/vim-plugins"
|
||||||
|
"/share/vulkan"
|
||||||
];
|
];
|
||||||
|
|
||||||
system.path = pkgs.buildEnv {
|
system.path = pkgs.buildEnv {
|
||||||
|
@ -135,6 +135,12 @@ in
|
|||||||
environment.sessionVariables.LD_LIBRARY_PATH =
|
environment.sessionVariables.LD_LIBRARY_PATH =
|
||||||
[ "/run/opengl-driver/lib" "/run/opengl-driver-32/lib" ];
|
[ "/run/opengl-driver/lib" "/run/opengl-driver-32/lib" ];
|
||||||
|
|
||||||
|
environment.extraInit = ''
|
||||||
|
export XDG_DATA_DIRS=$XDG_DATA_DIRS:/run/opengl-driver/share
|
||||||
|
'' + optionalString cfg.driSupport32Bit ''
|
||||||
|
export XDG_DATA_DIRS=$XDG_DATA_DIRS:/run/opengl-driver-32/share
|
||||||
|
'';
|
||||||
|
|
||||||
hardware.opengl.package = mkDefault (makePackage pkgs);
|
hardware.opengl.package = mkDefault (makePackage pkgs);
|
||||||
hardware.opengl.package32 = mkDefault (makePackage pkgs_i686);
|
hardware.opengl.package32 = mkDefault (makePackage pkgs_i686);
|
||||||
|
|
||||||
|
@ -45,10 +45,8 @@ in
|
|||||||
"amd/amdapfxx.blb".source = package + "/etc/amd/amdapfxx.blb";
|
"amd/amdapfxx.blb".source = package + "/etc/amd/amdapfxx.blb";
|
||||||
"gbm/gbm.conf".source = package + "/etc/gbm/gbm.conf";
|
"gbm/gbm.conf".source = package + "/etc/gbm/gbm.conf";
|
||||||
"OpenCL/vendors/amdocl64.icd".source = package + "/etc/OpenCL/vendors/amdocl64.icd";
|
"OpenCL/vendors/amdocl64.icd".source = package + "/etc/OpenCL/vendors/amdocl64.icd";
|
||||||
"vulkan/icd.d/amd_icd64.json".source = package + "/etc/vulkan/icd.d/amd_icd64.json";
|
|
||||||
} // optionalAttrs opengl.driSupport32Bit {
|
} // optionalAttrs opengl.driSupport32Bit {
|
||||||
"OpenCL/vendors/amdocl32.icd".source = package32 + "/etc/OpenCL/vendors/amdocl32.icd";
|
"OpenCL/vendors/amdocl32.icd".source = package32 + "/etc/OpenCL/vendors/amdocl32.icd";
|
||||||
"vulkan/icd.d/amd_icd32.json".source = package32 + "/etc/vulkan/icd.d/amd_icd32.json";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -13,6 +13,8 @@ let
|
|||||||
useDisplayDevice = cfg.connectDisplay;
|
useDisplayDevice = cfg.connectDisplay;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useBbswitch = cfg.pmMethod == "bbswitch";
|
||||||
|
|
||||||
primus = pkgs.primus.override {
|
primus = pkgs.primus.override {
|
||||||
inherit useNvidia;
|
inherit useNvidia;
|
||||||
};
|
};
|
||||||
@ -22,58 +24,69 @@ in
|
|||||||
{
|
{
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
hardware.bumblebee.enable = mkOption {
|
hardware.bumblebee = {
|
||||||
default = false;
|
|
||||||
type = types.bool;
|
|
||||||
description = ''
|
|
||||||
Enable the bumblebee daemon to manage Optimus hybrid video cards.
|
|
||||||
This should power off secondary GPU until its use is requested
|
|
||||||
by running an application with optirun.
|
|
||||||
|
|
||||||
Only nvidia driver is supported so far.
|
enable = mkOption {
|
||||||
'';
|
default = false;
|
||||||
};
|
type = types.bool;
|
||||||
hardware.bumblebee.group = mkOption {
|
description = ''
|
||||||
default = "wheel";
|
Enable the bumblebee daemon to manage Optimus hybrid video cards.
|
||||||
example = "video";
|
This should power off secondary GPU until its use is requested
|
||||||
type = types.str;
|
by running an application with optirun.
|
||||||
description = ''Group for bumblebee socket'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
hardware.bumblebee.connectDisplay = mkOption {
|
group = mkOption {
|
||||||
default = false;
|
default = "wheel";
|
||||||
type = types.bool;
|
example = "video";
|
||||||
description = ''
|
type = types.str;
|
||||||
Set to true if you intend to connect your discrete card to a
|
description = ''Group for bumblebee socket'';
|
||||||
monitor. This option will set up your Nvidia card for EDID
|
};
|
||||||
discovery and to turn on the monitor signal.
|
|
||||||
|
|
||||||
Only nvidia driver is supported so far.
|
connectDisplay = mkOption {
|
||||||
'';
|
default = false;
|
||||||
};
|
type = types.bool;
|
||||||
|
description = ''
|
||||||
|
Set to true if you intend to connect your discrete card to a
|
||||||
|
monitor. This option will set up your Nvidia card for EDID
|
||||||
|
discovery and to turn on the monitor signal.
|
||||||
|
|
||||||
|
Only nvidia driver is supported so far.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
driver = mkOption {
|
||||||
|
default = "nvidia";
|
||||||
|
type = types.enum [ "nvidia" "nouveau" ];
|
||||||
|
description = ''
|
||||||
|
Set driver used by bumblebeed. Supported are nouveau and nvidia.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
pmMethod = mkOption {
|
||||||
|
default = "auto";
|
||||||
|
type = types.enum [ "auto" "bbswitch" "nouveau" "switcheroo" "none" ];
|
||||||
|
description = ''
|
||||||
|
Set preferred power management method for unused card.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
hardware.bumblebee.driver = mkOption {
|
|
||||||
default = "nvidia";
|
|
||||||
type = types.enum [ "nvidia" "nouveau" ];
|
|
||||||
description = ''
|
|
||||||
Set driver used by bumblebeed. Supported are nouveau and nvidia.
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf config.hardware.bumblebee.enable {
|
config = mkIf cfg.enable {
|
||||||
boot.blacklistedKernelModules = [ "nouveau" "nvidia" ];
|
boot.blacklistedKernelModules = [ "nvidia-drm" "nvidia" "nouveau" ];
|
||||||
boot.kernelModules = [ "bbswitch" ];
|
boot.kernelModules = optional useBbswitch [ "bbswitch" ];
|
||||||
boot.extraModulePackages = [ kernel.bbswitch ] ++ optional useNvidia kernel.nvidia_x11;
|
boot.extraModulePackages = optional useBbswitch kernel.bbswitch ++ optional useNvidia kernel.nvidia_x11;
|
||||||
|
|
||||||
environment.systemPackages = [ bumblebee primus ];
|
environment.systemPackages = [ bumblebee primus ];
|
||||||
|
|
||||||
systemd.services.bumblebeed = {
|
systemd.services.bumblebeed = {
|
||||||
description = "Bumblebee Hybrid Graphics Switcher";
|
description = "Bumblebee Hybrid Graphics Switcher";
|
||||||
wantedBy = [ "display-manager.service" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
path = [ kernel.bbswitch bumblebee ];
|
before = [ "display-manager.service" ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
ExecStart = "${bumblebee}/bin/bumblebeed --use-syslog -g ${cfg.group} --driver ${cfg.driver}";
|
ExecStart = "${bumblebee}/bin/bumblebeed --use-syslog -g ${cfg.group} --driver ${cfg.driver} --pm-method ${cfg.pmMethod}";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -1,20 +1,41 @@
|
|||||||
# This module defines a NixOS installation CD that contains X11 and
|
# This module defines a NixOS installation CD that contains X11 and
|
||||||
# KDE 4.
|
# KDE 5.
|
||||||
|
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
|
|
||||||
{
|
{
|
||||||
imports = [ ./installation-cd-base.nix ../../profiles/graphical.nix ];
|
imports = [ ./installation-cd-base.nix ];
|
||||||
|
|
||||||
# Provide wicd for easy wireless configuration.
|
services.xserver = {
|
||||||
#networking.wicd.enable = true;
|
enable = true;
|
||||||
|
|
||||||
|
# Automatically login as root.
|
||||||
|
displayManager.slim = {
|
||||||
|
enable = true;
|
||||||
|
defaultUser = "root";
|
||||||
|
autoLogin = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
desktopManager.kde5 = {
|
||||||
|
enable = true;
|
||||||
|
enableQt4Support = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Enable touchpad support for many laptops.
|
||||||
|
synaptics.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
environment.systemPackages =
|
environment.systemPackages =
|
||||||
[ # Include gparted for partitioning disks.
|
[ pkgs.glxinfo
|
||||||
|
|
||||||
|
# Include gparted for partitioning disks.
|
||||||
pkgs.gparted
|
pkgs.gparted
|
||||||
|
|
||||||
|
# Firefox for reading the manual.
|
||||||
|
pkgs.firefox
|
||||||
|
|
||||||
# Include some editors.
|
# Include some editors.
|
||||||
pkgs.vim
|
pkgs.vim
|
||||||
pkgs.bvi # binary editor
|
pkgs.bvi # binary editor
|
||||||
@ -32,80 +53,21 @@ with lib;
|
|||||||
# Don't start the X server by default.
|
# Don't start the X server by default.
|
||||||
services.xserver.autorun = mkForce false;
|
services.xserver.autorun = mkForce false;
|
||||||
|
|
||||||
# Auto-login as root.
|
|
||||||
services.xserver.displayManager.kdm.extraConfig =
|
|
||||||
''
|
|
||||||
[X-*-Core]
|
|
||||||
AllowRootLogin=true
|
|
||||||
AutoLoginEnable=true
|
|
||||||
AutoLoginUser=root
|
|
||||||
AutoLoginPass=""
|
|
||||||
'';
|
|
||||||
|
|
||||||
# Custom kde-workspace adding some icons on the desktop
|
|
||||||
|
|
||||||
system.activationScripts.installerDesktop = let
|
system.activationScripts.installerDesktop = let
|
||||||
openManual = pkgs.writeScript "nixos-manual.sh" ''
|
|
||||||
#!${pkgs.stdenv.shell}
|
|
||||||
cd ${config.system.build.manual.manual}/share/doc/nixos/
|
|
||||||
konqueror ./index.html
|
|
||||||
'';
|
|
||||||
|
|
||||||
desktopFile = pkgs.writeText "nixos-manual.desktop" ''
|
desktopFile = pkgs.writeText "nixos-manual.desktop" ''
|
||||||
[Desktop Entry]
|
[Desktop Entry]
|
||||||
Version=1.0
|
Version=1.0
|
||||||
Type=Application
|
Type=Application
|
||||||
Name=NixOS Manual
|
Name=NixOS Manual
|
||||||
Exec=${openManual}
|
Exec=firefox ${config.system.build.manual.manual}/share/doc/nixos/index.html
|
||||||
Icon=konqueror
|
Icon=text-html
|
||||||
'';
|
'';
|
||||||
|
|
||||||
in ''
|
in ''
|
||||||
mkdir -p /root/Desktop
|
mkdir -p /root/Desktop
|
||||||
ln -sfT ${desktopFile} /root/Desktop/nixos-manual.desktop
|
ln -sfT ${desktopFile} /root/Desktop/nixos-manual.desktop
|
||||||
ln -sfT ${pkgs.kde4.konsole}/share/applications/kde4/konsole.desktop /root/Desktop/konsole.desktop
|
ln -sfT ${pkgs.kde5.konsole}/share/applications/org.kde.konsole.desktop /root/Desktop/org.kde.konsole.desktop
|
||||||
ln -sfT ${pkgs.gparted}/share/applications/gparted.desktop /root/Desktop/gparted.desktop
|
ln -sfT ${pkgs.gparted}/share/applications/gparted.desktop /root/Desktop/gparted.desktop
|
||||||
'';
|
'';
|
||||||
|
|
||||||
services.xserver.desktopManager.kde4.kdeWorkspacePackage = let
|
|
||||||
pkg = pkgs.kde4.kde_workspace;
|
|
||||||
|
|
||||||
plasmaInit = pkgs.writeText "00-defaultLayout.js" ''
|
|
||||||
loadTemplate("org.kde.plasma-desktop.defaultPanel")
|
|
||||||
|
|
||||||
for (var i = 0; i < screenCount; ++i) {
|
|
||||||
var desktop = new Activity
|
|
||||||
desktop.name = i18n("Desktop")
|
|
||||||
desktop.screen = i
|
|
||||||
desktop.wallpaperPlugin = 'image'
|
|
||||||
desktop.wallpaperMode = 'SingleImage'
|
|
||||||
|
|
||||||
var folderview = desktop.addWidget("folderview");
|
|
||||||
folderview.writeConfig("url", "desktop:/");
|
|
||||||
|
|
||||||
//Create more panels for other screens
|
|
||||||
if (i > 0){
|
|
||||||
var panel = new Panel
|
|
||||||
panel.screen = i
|
|
||||||
panel.location = 'bottom'
|
|
||||||
panel.height = screenGeometry(i).height > 1024 ? 35 : 27
|
|
||||||
var tasks = panel.addWidget("tasks")
|
|
||||||
tasks.writeConfig("showOnlyCurrentScreen", true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
|
|
||||||
in
|
|
||||||
pkgs.runCommand pkg.name
|
|
||||||
{ inherit (pkg) meta; }
|
|
||||||
''
|
|
||||||
mkdir -p $out
|
|
||||||
cp -prf ${pkg}/* $out/
|
|
||||||
chmod a+w $out/share/apps/plasma-desktop/init
|
|
||||||
cp -f ${plasmaInit} $out/share/apps/plasma-desktop/init/00-defaultLayout.js
|
|
||||||
'';
|
|
||||||
|
|
||||||
# Disable large stuff that's not very useful on the installation CD.
|
|
||||||
services.xserver.desktopManager.kde4.enablePIM = false;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -26,11 +26,6 @@ with lib;
|
|||||||
# here and it causes a cyclic dependency.
|
# here and it causes a cyclic dependency.
|
||||||
boot.loader.grub.enable = false;
|
boot.loader.grub.enable = false;
|
||||||
|
|
||||||
boot.initrd.postMountCommands = ''
|
|
||||||
mkdir -p /mnt-root/nix/store
|
|
||||||
mount -t squashfs /nix-store.squashfs /mnt-root/nix/store
|
|
||||||
'';
|
|
||||||
|
|
||||||
# !!! Hack - attributes expected by other modules.
|
# !!! Hack - attributes expected by other modules.
|
||||||
system.boot.loader.kernelFile = "bzImage";
|
system.boot.loader.kernelFile = "bzImage";
|
||||||
environment.systemPackages = [ pkgs.grub2 pkgs.grub2_efi pkgs.syslinux ];
|
environment.systemPackages = [ pkgs.grub2 pkgs.grub2_efi pkgs.syslinux ];
|
||||||
@ -42,13 +37,34 @@ with lib;
|
|||||||
options = [ "mode=0755" ];
|
options = [ "mode=0755" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# In stage 1, mount a tmpfs on top of /nix/store (the squashfs
|
||||||
|
# image) to make this a live CD.
|
||||||
|
fileSystems."/nix/.ro-store" =
|
||||||
|
{ fsType = "squashfs";
|
||||||
|
device = "../nix-store.squashfs";
|
||||||
|
options = [ "loop" ];
|
||||||
|
neededForBoot = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/nix/.rw-store" =
|
||||||
|
{ fsType = "tmpfs";
|
||||||
|
options = [ "mode=0755" ];
|
||||||
|
neededForBoot = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/nix/store" =
|
||||||
|
{ fsType = "unionfs-fuse";
|
||||||
|
device = "unionfs";
|
||||||
|
options = [ "allow_other" "cow" "nonempty" "chroot=/mnt-root" "max_files=32768" "hide_meta_files" "dirs=/nix/.rw-store=rw:/nix/.ro-store=ro" ];
|
||||||
|
};
|
||||||
|
|
||||||
boot.initrd.availableKernelModules = [ "squashfs" ];
|
boot.initrd.availableKernelModules = [ "squashfs" ];
|
||||||
|
|
||||||
boot.initrd.kernelModules = [ "loop" ];
|
boot.initrd.kernelModules = [ "loop" ];
|
||||||
|
|
||||||
# Closures to be copied to the Nix store, namely the init
|
# Closures to be copied to the Nix store, namely the init
|
||||||
# script and the top-level system configuration directory.
|
# script and the top-level system configuration directory.
|
||||||
netboot.storeContents =
|
netboot.storeContents =
|
||||||
[ config.system.build.toplevel ];
|
[ config.system.build.toplevel ];
|
||||||
|
|
||||||
# Create the squashfs image that contains the Nix store.
|
# Create the squashfs image that contains the Nix store.
|
||||||
|
@ -126,9 +126,9 @@ targetHostCmd() {
|
|||||||
copyToTarget() {
|
copyToTarget() {
|
||||||
if ! [ "$targetHost" = "$buildHost" ]; then
|
if ! [ "$targetHost" = "$buildHost" ]; then
|
||||||
if [ -z "$targetHost" ]; then
|
if [ -z "$targetHost" ]; then
|
||||||
NIX_SSHOPTS=$SSH_OPTS nix-copy-closure --from "$buildHost" "$1"
|
NIX_SSHOPTS=$SSHOPTS nix-copy-closure --from "$buildHost" "$1"
|
||||||
elif [ -z "$buildHost" ]; then
|
elif [ -z "$buildHost" ]; then
|
||||||
NIX_SSHOPTS=$SSH_OPTS nix-copy-closure --to "$targetHost" "$1"
|
NIX_SSHOPTS=$SSHOPTS nix-copy-closure --to "$targetHost" "$1"
|
||||||
else
|
else
|
||||||
buildHostCmd nix-copy-closure --to "$targetHost" "$1"
|
buildHostCmd nix-copy-closure --to "$targetHost" "$1"
|
||||||
fi
|
fi
|
||||||
@ -169,7 +169,7 @@ nixBuild() {
|
|||||||
|
|
||||||
local drv="$(nix-instantiate "${instArgs[@]}" "${extraBuildFlags[@]}")"
|
local drv="$(nix-instantiate "${instArgs[@]}" "${extraBuildFlags[@]}")"
|
||||||
if [ -a "$drv" ]; then
|
if [ -a "$drv" ]; then
|
||||||
NIX_SSHOPTS=$SSH_OPTS nix-copy-closure --to "$buildHost" "$drv"
|
NIX_SSHOPTS=$SSHOPTS nix-copy-closure --to "$buildHost" "$drv"
|
||||||
buildHostCmd nix-store -r "$drv" "${buildArgs[@]}"
|
buildHostCmd nix-store -r "$drv" "${buildArgs[@]}"
|
||||||
else
|
else
|
||||||
echo "nix-instantiate failed"
|
echo "nix-instantiate failed"
|
||||||
|
@ -18,5 +18,5 @@ with lib;
|
|||||||
|
|
||||||
# Add some more video drivers to give X11 a shot at working in
|
# Add some more video drivers to give X11 a shot at working in
|
||||||
# VMware and QEMU.
|
# VMware and QEMU.
|
||||||
services.xserver.videoDrivers = mkOverride 40 [ "virtualbox" "vmware" "cirrus" "vesa" ];
|
services.xserver.videoDrivers = mkOverride 40 [ "virtualbox" "vmware" "cirrus" "vesa" "modesetting" ];
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,6 @@
|
|||||||
#utmp = 29; # unused
|
#utmp = 29; # unused
|
||||||
ddclient = 30;
|
ddclient = 30;
|
||||||
davfs2 = 31;
|
davfs2 = 31;
|
||||||
privoxy = 32;
|
|
||||||
#disnix = 33; # unused
|
#disnix = 33; # unused
|
||||||
osgi = 34;
|
osgi = 34;
|
||||||
tor = 35;
|
tor = 35;
|
||||||
@ -84,7 +83,7 @@
|
|||||||
spamd = 56;
|
spamd = 56;
|
||||||
#networkmanager = 57; # unused
|
#networkmanager = 57; # unused
|
||||||
nslcd = 58;
|
nslcd = 58;
|
||||||
#scanner = 59; # unused
|
scanner = 59;
|
||||||
nginx = 60;
|
nginx = 60;
|
||||||
chrony = 61;
|
chrony = 61;
|
||||||
#systemd-journal = 62; # unused
|
#systemd-journal = 62; # unused
|
||||||
@ -212,7 +211,6 @@
|
|||||||
lambdabot = 191;
|
lambdabot = 191;
|
||||||
asterisk = 192;
|
asterisk = 192;
|
||||||
plex = 193;
|
plex = 193;
|
||||||
bird = 195;
|
|
||||||
grafana = 196;
|
grafana = 196;
|
||||||
skydns = 197;
|
skydns = 197;
|
||||||
ripple-rest = 198;
|
ripple-rest = 198;
|
||||||
@ -279,6 +277,10 @@
|
|||||||
hound = 259;
|
hound = 259;
|
||||||
leaps = 260;
|
leaps = 260;
|
||||||
ipfs = 261;
|
ipfs = 261;
|
||||||
|
stanchion = 262;
|
||||||
|
riak-cs = 263;
|
||||||
|
infinoted = 264;
|
||||||
|
keystone = 265;
|
||||||
|
|
||||||
# When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
|
# When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
|
||||||
|
|
||||||
@ -319,7 +321,6 @@
|
|||||||
utmp = 29;
|
utmp = 29;
|
||||||
#ddclient = 30; # unused
|
#ddclient = 30; # unused
|
||||||
davfs2 = 31;
|
davfs2 = 31;
|
||||||
privoxy = 32;
|
|
||||||
disnix = 33;
|
disnix = 33;
|
||||||
osgi = 34;
|
osgi = 34;
|
||||||
tor = 35;
|
tor = 35;
|
||||||
@ -469,7 +470,6 @@
|
|||||||
#asterisk = 192; # unused
|
#asterisk = 192; # unused
|
||||||
plex = 193;
|
plex = 193;
|
||||||
sabnzbd = 194;
|
sabnzbd = 194;
|
||||||
bird = 195;
|
|
||||||
#grafana = 196; #unused
|
#grafana = 196; #unused
|
||||||
#skydns = 197; #unused
|
#skydns = 197; #unused
|
||||||
#ripple-rest = 198; #unused
|
#ripple-rest = 198; #unused
|
||||||
@ -528,6 +528,10 @@
|
|||||||
hound = 259;
|
hound = 259;
|
||||||
leaps = 260;
|
leaps = 260;
|
||||||
ipfs = 261;
|
ipfs = 261;
|
||||||
|
stanchion = 262;
|
||||||
|
riak-cs = 263;
|
||||||
|
infinoted = 264;
|
||||||
|
keystone = 265;
|
||||||
|
|
||||||
# When adding a gid, make sure it doesn't match an existing
|
# When adding a gid, make sure it doesn't match an existing
|
||||||
# uid. Users and groups with the same name should have equal
|
# uid. Users and groups with the same name should have equal
|
||||||
|
@ -133,9 +133,11 @@
|
|||||||
./services/cluster/fleet.nix
|
./services/cluster/fleet.nix
|
||||||
./services/cluster/kubernetes.nix
|
./services/cluster/kubernetes.nix
|
||||||
./services/cluster/panamax.nix
|
./services/cluster/panamax.nix
|
||||||
|
./services/computing/boinc/client.nix
|
||||||
./services/computing/torque/server.nix
|
./services/computing/torque/server.nix
|
||||||
./services/computing/torque/mom.nix
|
./services/computing/torque/mom.nix
|
||||||
./services/computing/slurm/slurm.nix
|
./services/computing/slurm/slurm.nix
|
||||||
|
./services/continuous-integration/buildbot/master.nix
|
||||||
./services/continuous-integration/buildkite-agent.nix
|
./services/continuous-integration/buildkite-agent.nix
|
||||||
./services/continuous-integration/hydra/default.nix
|
./services/continuous-integration/hydra/default.nix
|
||||||
./services/continuous-integration/gitlab-runner.nix
|
./services/continuous-integration/gitlab-runner.nix
|
||||||
@ -159,6 +161,8 @@
|
|||||||
./services/databases/postgresql.nix
|
./services/databases/postgresql.nix
|
||||||
./services/databases/redis.nix
|
./services/databases/redis.nix
|
||||||
./services/databases/riak.nix
|
./services/databases/riak.nix
|
||||||
|
./services/databases/riak-cs.nix
|
||||||
|
./services/databases/stanchion.nix
|
||||||
./services/databases/virtuoso.nix
|
./services/databases/virtuoso.nix
|
||||||
./services/desktops/accountsservice.nix
|
./services/desktops/accountsservice.nix
|
||||||
./services/desktops/geoclue2.nix
|
./services/desktops/geoclue2.nix
|
||||||
@ -178,6 +182,7 @@
|
|||||||
./services/desktops/telepathy.nix
|
./services/desktops/telepathy.nix
|
||||||
./services/development/hoogle.nix
|
./services/development/hoogle.nix
|
||||||
./services/editors/emacs.nix
|
./services/editors/emacs.nix
|
||||||
|
./services/editors/infinoted.nix
|
||||||
./services/games/factorio.nix
|
./services/games/factorio.nix
|
||||||
./services/games/ghost-one.nix
|
./services/games/ghost-one.nix
|
||||||
./services/games/minecraft-server.nix
|
./services/games/minecraft-server.nix
|
||||||
@ -346,6 +351,7 @@
|
|||||||
./services/networking/connman.nix
|
./services/networking/connman.nix
|
||||||
./services/networking/consul.nix
|
./services/networking/consul.nix
|
||||||
./services/networking/coturn.nix
|
./services/networking/coturn.nix
|
||||||
|
./services/networking/dante.nix
|
||||||
./services/networking/ddclient.nix
|
./services/networking/ddclient.nix
|
||||||
./services/networking/dhcpcd.nix
|
./services/networking/dhcpcd.nix
|
||||||
./services/networking/dhcpd.nix
|
./services/networking/dhcpd.nix
|
||||||
@ -354,6 +360,7 @@
|
|||||||
./services/networking/dnsmasq.nix
|
./services/networking/dnsmasq.nix
|
||||||
./services/networking/ejabberd.nix
|
./services/networking/ejabberd.nix
|
||||||
./services/networking/fan.nix
|
./services/networking/fan.nix
|
||||||
|
./services/networking/fakeroute.nix
|
||||||
./services/networking/ferm.nix
|
./services/networking/ferm.nix
|
||||||
./services/networking/firefox/sync-server.nix
|
./services/networking/firefox/sync-server.nix
|
||||||
./services/networking/firewall.nix
|
./services/networking/firewall.nix
|
||||||
@ -478,6 +485,7 @@
|
|||||||
./services/security/torify.nix
|
./services/security/torify.nix
|
||||||
./services/security/tor.nix
|
./services/security/tor.nix
|
||||||
./services/security/torsocks.nix
|
./services/security/torsocks.nix
|
||||||
|
./services/system/cgmanager.nix
|
||||||
./services/system/cloud-init.nix
|
./services/system/cloud-init.nix
|
||||||
./services/system/dbus.nix
|
./services/system/dbus.nix
|
||||||
./services/system/kerberos.nix
|
./services/system/kerberos.nix
|
||||||
@ -519,6 +527,7 @@
|
|||||||
./services/x11/colord.nix
|
./services/x11/colord.nix
|
||||||
./services/x11/compton.nix
|
./services/x11/compton.nix
|
||||||
./services/x11/unclutter.nix
|
./services/x11/unclutter.nix
|
||||||
|
./services/x11/unclutter-xfixes.nix
|
||||||
./services/x11/desktop-managers/default.nix
|
./services/x11/desktop-managers/default.nix
|
||||||
./services/x11/display-managers/auto.nix
|
./services/x11/display-managers/auto.nix
|
||||||
./services/x11/display-managers/default.nix
|
./services/x11/display-managers/default.nix
|
||||||
@ -539,7 +548,6 @@
|
|||||||
./services/x11/window-managers/fluxbox.nix
|
./services/x11/window-managers/fluxbox.nix
|
||||||
./services/x11/window-managers/icewm.nix
|
./services/x11/window-managers/icewm.nix
|
||||||
./services/x11/window-managers/bspwm.nix
|
./services/x11/window-managers/bspwm.nix
|
||||||
./services/x11/window-managers/bspwm-unstable.nix
|
|
||||||
./services/x11/window-managers/metacity.nix
|
./services/x11/window-managers/metacity.nix
|
||||||
./services/x11/window-managers/none.nix
|
./services/x11/window-managers/none.nix
|
||||||
./services/x11/window-managers/twm.nix
|
./services/x11/window-managers/twm.nix
|
||||||
@ -612,6 +620,7 @@
|
|||||||
./virtualisation/docker.nix
|
./virtualisation/docker.nix
|
||||||
./virtualisation/libvirtd.nix
|
./virtualisation/libvirtd.nix
|
||||||
./virtualisation/lxc.nix
|
./virtualisation/lxc.nix
|
||||||
|
./virtualisation/lxcfs.nix
|
||||||
./virtualisation/lxd.nix
|
./virtualisation/lxd.nix
|
||||||
./virtualisation/amazon-options.nix
|
./virtualisation/amazon-options.nix
|
||||||
./virtualisation/openvswitch.nix
|
./virtualisation/openvswitch.nix
|
||||||
@ -622,4 +631,5 @@
|
|||||||
./virtualisation/vmware-guest.nix
|
./virtualisation/vmware-guest.nix
|
||||||
./virtualisation/xen-dom0.nix
|
./virtualisation/xen-dom0.nix
|
||||||
./virtualisation/xe-guest-utilities.nix
|
./virtualisation/xe-guest-utilities.nix
|
||||||
|
./virtualisation/openstack/keystone.nix
|
||||||
]
|
]
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
# Include some utilities that are useful for installing or repairing
|
# Include some utilities that are useful for installing or repairing
|
||||||
# the system.
|
# the system.
|
||||||
environment.systemPackages = [
|
environment.systemPackages = [
|
||||||
pkgs.w3m # needed for the manual anyway
|
pkgs.w3m-nox # needed for the manual anyway
|
||||||
pkgs.testdisk # useful for repairing boot problems
|
pkgs.testdisk # useful for repairing boot problems
|
||||||
pkgs.mssys # for writing Microsoft boot sectors / MBRs
|
pkgs.mssys # for writing Microsoft boot sectors / MBRs
|
||||||
pkgs.efibootmgr
|
pkgs.efibootmgr
|
||||||
@ -42,8 +42,6 @@
|
|||||||
# Some compression/archiver tools.
|
# Some compression/archiver tools.
|
||||||
pkgs.unzip
|
pkgs.unzip
|
||||||
pkgs.zip
|
pkgs.zip
|
||||||
pkgs.dar # disk archiver
|
|
||||||
pkgs.cabextract
|
|
||||||
];
|
];
|
||||||
|
|
||||||
# Include support for various filesystems.
|
# Include support for various filesystems.
|
||||||
|
@ -14,4 +14,6 @@ with lib;
|
|||||||
|
|
||||||
programs.man.enable = mkDefault false;
|
programs.man.enable = mkDefault false;
|
||||||
programs.info.enable = mkDefault false;
|
programs.info.enable = mkDefault false;
|
||||||
|
|
||||||
|
sound.enable = mkDefault false;
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ in
|
|||||||
|
|
||||||
package = mkOption {
|
package = mkOption {
|
||||||
default = pkgs.jdk;
|
default = pkgs.jdk;
|
||||||
|
defaultText = "pkgs.jdk";
|
||||||
description = ''
|
description = ''
|
||||||
Java package to install. Typical values are pkgs.jdk or pkgs.jre.
|
Java package to install. Typical values are pkgs.jdk or pkgs.jre.
|
||||||
'';
|
'';
|
||||||
|
@ -9,14 +9,14 @@ let
|
|||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.programs.mosh = {
|
options.programs.mosh = {
|
||||||
enable = mkOption {
|
enable = mkOption {
|
||||||
description = ''
|
description = ''
|
||||||
Whether to enable mosh. Note, this will open ports in your firewall!
|
Whether to enable mosh. Note, this will open ports in your firewall!
|
||||||
'';
|
'';
|
||||||
default = false;
|
default = false;
|
||||||
example = true;
|
example = true;
|
||||||
type = lib.types.bool;
|
type = lib.types.bool;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
|
@ -165,7 +165,7 @@ in
|
|||||||
config = {
|
config = {
|
||||||
|
|
||||||
programs.ssh.setXAuthLocation =
|
programs.ssh.setXAuthLocation =
|
||||||
mkDefault (config.services.xserver.enable || config.programs.ssh.forwardX11);
|
mkDefault (config.services.xserver.enable || config.programs.ssh.forwardX11 || config.services.openssh.forwardX11);
|
||||||
|
|
||||||
assertions =
|
assertions =
|
||||||
[ { assertion = cfg.forwardX11 -> cfg.setXAuthLocation;
|
[ { assertion = cfg.forwardX11 -> cfg.setXAuthLocation;
|
||||||
|
@ -30,6 +30,8 @@ with lib;
|
|||||||
(mkRenamedOptionModule [ "services" "gitlab" "stateDir" ] [ "services" "gitlab" "statePath" ])
|
(mkRenamedOptionModule [ "services" "gitlab" "stateDir" ] [ "services" "gitlab" "statePath" ])
|
||||||
(mkRemovedOptionModule [ "services" "gitlab" "satelliteDir" ] "")
|
(mkRemovedOptionModule [ "services" "gitlab" "satelliteDir" ] "")
|
||||||
|
|
||||||
|
(mkRenamedOptionModule [ "services" "clamav" "updater" "config" ] [ "services" "clamav" "updater" "extraConfig" ])
|
||||||
|
|
||||||
# Old Grub-related options.
|
# Old Grub-related options.
|
||||||
(mkRenamedOptionModule [ "boot" "initrd" "extraKernelModules" ] [ "boot" "initrd" "kernelModules" ])
|
(mkRenamedOptionModule [ "boot" "initrd" "extraKernelModules" ] [ "boot" "initrd" "kernelModules" ])
|
||||||
(mkRenamedOptionModule [ "boot" "extraKernelParams" ] [ "boot" "kernelParams" ])
|
(mkRenamedOptionModule [ "boot" "extraKernelParams" ] [ "boot" "kernelParams" ])
|
||||||
@ -142,6 +144,12 @@ with lib;
|
|||||||
# murmur
|
# murmur
|
||||||
(mkRenamedOptionModule [ "services" "murmur" "welcome" ] [ "services" "murmur" "welcometext" ])
|
(mkRenamedOptionModule [ "services" "murmur" "welcome" ] [ "services" "murmur" "welcometext" ])
|
||||||
|
|
||||||
|
# parsoid
|
||||||
|
(mkRemovedOptionModule [ "services" "parsoid" "interwikis" ] [ "services" "parsoid" "wikis" ])
|
||||||
|
|
||||||
|
# tarsnap
|
||||||
|
(mkRemovedOptionModule [ "services" "tarsnap" "cachedir" ] "Use services.tarsnap.archives.<name>.cachedir")
|
||||||
|
|
||||||
# Options that are obsolete and have no replacement.
|
# Options that are obsolete and have no replacement.
|
||||||
(mkRemovedOptionModule [ "boot" "initrd" "luks" "enable" ] "")
|
(mkRemovedOptionModule [ "boot" "initrd" "luks" "enable" ] "")
|
||||||
(mkRemovedOptionModule [ "programs" "bash" "enable" ] "")
|
(mkRemovedOptionModule [ "programs" "bash" "enable" ] "")
|
||||||
|
@ -178,6 +178,7 @@ in
|
|||||||
path = [ pkgs.simp_le ];
|
path = [ pkgs.simp_le ];
|
||||||
preStart = ''
|
preStart = ''
|
||||||
mkdir -p '${cfg.directory}'
|
mkdir -p '${cfg.directory}'
|
||||||
|
chown '${data.user}:${data.group}' '${cfg.directory}'
|
||||||
if [ ! -d '${cpath}' ]; then
|
if [ ! -d '${cpath}' ]; then
|
||||||
mkdir '${cpath}'
|
mkdir '${cpath}'
|
||||||
fi
|
fi
|
||||||
|
@ -75,7 +75,7 @@ options for the <literal>security.acme</literal> module.</para>
|
|||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
security.acme.certs."foo.example.com" = {
|
security.acme.certs."foo.example.com" = {
|
||||||
webroot = "/var/www/challenges";
|
webroot = config.security.acme.directory + "/acme-challenge";
|
||||||
email = "foo@example.com";
|
email = "foo@example.com";
|
||||||
user = "nginx";
|
user = "nginx";
|
||||||
group = "nginx";
|
group = "nginx";
|
||||||
|
@ -73,7 +73,7 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
failmode = mkOption {
|
failmode = mkOption {
|
||||||
type = types.str;
|
type = types.enum [ "safe" "enum" ];
|
||||||
default = "safe";
|
default = "safe";
|
||||||
description = ''
|
description = ''
|
||||||
On service or configuration errors that prevent Duo
|
On service or configuration errors that prevent Duo
|
||||||
@ -115,7 +115,7 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
prompts = mkOption {
|
prompts = mkOption {
|
||||||
type = types.int;
|
type = types.enum [ 1 2 3 ];
|
||||||
default = 3;
|
default = 3;
|
||||||
description = ''
|
description = ''
|
||||||
If a user fails to authenticate with a second factor, Duo
|
If a user fails to authenticate with a second factor, Duo
|
||||||
@ -181,13 +181,7 @@ in
|
|||||||
|
|
||||||
config = mkIf (cfg.ssh.enable || cfg.pam.enable) {
|
config = mkIf (cfg.ssh.enable || cfg.pam.enable) {
|
||||||
assertions =
|
assertions =
|
||||||
[ { assertion = cfg.failmode == "safe" || cfg.failmode == "secure";
|
[ { assertion = !cfg.pam.enable;
|
||||||
message = "Invalid value for failmode (must be safe or secure).";
|
|
||||||
}
|
|
||||||
{ assertion = cfg.prompts == 1 || cfg.prompts == 2 || cfg.prompts == 3;
|
|
||||||
message = "Invalid value for prompts (must be 1, 2, or 3).";
|
|
||||||
}
|
|
||||||
{ assertion = !cfg.pam.enable;
|
|
||||||
message = "PAM support is currently not implemented.";
|
message = "PAM support is currently not implemented.";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
@ -6,14 +6,6 @@ let
|
|||||||
cfg = config.security.grsecurity;
|
cfg = config.security.grsecurity;
|
||||||
grsecLockPath = "/proc/sys/kernel/grsecurity/grsec_lock";
|
grsecLockPath = "/proc/sys/kernel/grsecurity/grsec_lock";
|
||||||
|
|
||||||
# Ascertain whether ZFS is required for booting the system; grsecurity is
|
|
||||||
# currently incompatible with ZFS, rendering the system unbootable.
|
|
||||||
zfsNeededForBoot = filter
|
|
||||||
(fs: (fs.neededForBoot
|
|
||||||
|| elem fs.mountPoint [ "/" "/nix" "/nix/store" "/var" "/var/log" "/var/lib" "/etc" ])
|
|
||||||
&& fs.fsType == "zfs")
|
|
||||||
config.system.build.fileSystems != [];
|
|
||||||
|
|
||||||
# Ascertain whether NixOS container support is required
|
# Ascertain whether NixOS container support is required
|
||||||
containerSupportRequired =
|
containerSupportRequired =
|
||||||
config.boot.enableContainers && config.containers != {};
|
config.boot.enableContainers && config.containers != {};
|
||||||
@ -27,7 +19,14 @@ in
|
|||||||
|
|
||||||
options.security.grsecurity = {
|
options.security.grsecurity = {
|
||||||
|
|
||||||
enable = mkEnableOption "grsecurity/PaX";
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
example = true;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Enable grsecurity/PaX.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
lockTunables = mkOption {
|
lockTunables = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
@ -58,19 +57,10 @@ in
|
|||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
|
|
||||||
# Allow the user to select a different package set, subject to the stated
|
boot.kernelPackages = mkForce pkgs.linuxPackages_grsec_nixos;
|
||||||
# required kernel config
|
|
||||||
boot.kernelPackages = mkDefault pkgs.linuxPackages_grsec_nixos;
|
|
||||||
|
|
||||||
boot.kernelParams = optional cfg.disableEfiRuntimeServices "noefi";
|
boot.kernelParams = [ "grsec_sysfs_restrict=0" ]
|
||||||
|
++ optional cfg.disableEfiRuntimeServices "noefi";
|
||||||
system.requiredKernelConfig = with config.lib.kernelConfig;
|
|
||||||
[ (isEnabled "GRKERNSEC")
|
|
||||||
(isEnabled "PAX")
|
|
||||||
(isYes "GRKERNSEC_SYSCTL")
|
|
||||||
(isYes "GRKERNSEC_SYSCTL_DISTRO")
|
|
||||||
(isNo "GRKERNSEC_NO_RBAC")
|
|
||||||
];
|
|
||||||
|
|
||||||
nixpkgs.config.grsecurity = true;
|
nixpkgs.config.grsecurity = true;
|
||||||
|
|
||||||
@ -120,26 +110,63 @@ in
|
|||||||
boot.kernel.sysctl = {
|
boot.kernel.sysctl = {
|
||||||
# Read-only under grsecurity
|
# Read-only under grsecurity
|
||||||
"kernel.kptr_restrict" = mkForce null;
|
"kernel.kptr_restrict" = mkForce null;
|
||||||
|
|
||||||
|
# All grsec tunables default to off, those not enabled below are
|
||||||
|
# *disabled*. We use mkDefault to allow expert users to override
|
||||||
|
# our choices, but use mkForce where tunables would outright
|
||||||
|
# conflict with other settings.
|
||||||
|
|
||||||
|
# Enable all chroot restrictions by default (overwritten as
|
||||||
|
# necessary below)
|
||||||
|
"kernel.grsecurity.chroot_caps" = mkDefault 1;
|
||||||
|
"kernel.grsecurity.chroot_deny_bad_rename" = mkDefault 1;
|
||||||
|
"kernel.grsecurity.chroot_deny_chmod" = mkDefault 1;
|
||||||
|
"kernel.grsecurity.chroot_deny_chroot" = mkDefault 1;
|
||||||
|
"kernel.grsecurity.chroot_deny_fchdir" = mkDefault 1;
|
||||||
|
"kernel.grsecurity.chroot_deny_mknod" = mkDefault 1;
|
||||||
|
"kernel.grsecurity.chroot_deny_mount" = mkDefault 1;
|
||||||
|
"kernel.grsecurity.chroot_deny_pivot" = mkDefault 1;
|
||||||
|
"kernel.grsecurity.chroot_deny_shmat" = mkDefault 1;
|
||||||
|
"kernel.grsecurity.chroot_deny_sysctl" = mkDefault 1;
|
||||||
|
"kernel.grsecurity.chroot_deny_unix" = mkDefault 1;
|
||||||
|
"kernel.grsecurity.chroot_enforce_chdir" = mkDefault 1;
|
||||||
|
"kernel.grsecurity.chroot_findtask" = mkDefault 1;
|
||||||
|
"kernel.grsecurity.chroot_restrict_nice" = mkDefault 1;
|
||||||
|
|
||||||
|
# Enable various grsec protections
|
||||||
|
"kernel.grsecurity.consistent_setxid" = mkDefault 1;
|
||||||
|
"kernel.grsecurity.deter_bruteforce" = mkDefault 1;
|
||||||
|
"kernel.grsecurity.fifo_restrictions" = mkDefault 1;
|
||||||
|
"kernel.grsecurity.harden_ipc" = mkDefault 1;
|
||||||
|
"kernel.grsecurity.harden_ptrace" = mkDefault 1;
|
||||||
|
"kernel.grsecurity.harden_tty" = mkDefault 1;
|
||||||
|
"kernel.grsecurity.ip_blackhole" = mkDefault 1;
|
||||||
|
"kernel.grsecurity.linking_restrictions" = mkDefault 1;
|
||||||
|
"kernel.grsecurity.ptrace_readexec" = mkDefault 1;
|
||||||
|
|
||||||
|
# Enable auditing
|
||||||
|
"kernel.grsecurity.audit_ptrace" = mkDefault 1;
|
||||||
|
"kernel.grsecurity.forkfail_logging" = mkDefault 1;
|
||||||
|
"kernel.grsecurity.rwxmap_logging" = mkDefault 1;
|
||||||
|
"kernel.grsecurity.signal_logging" = mkDefault 1;
|
||||||
|
"kernel.grsecurity.timechange_logging" = mkDefault 1;
|
||||||
} // optionalAttrs config.nix.useSandbox {
|
} // optionalAttrs config.nix.useSandbox {
|
||||||
# chroot(2) restrictions that conflict with sandboxed Nix builds
|
# chroot(2) restrictions that conflict with sandboxed Nix builds
|
||||||
"kernel.grsecurity.chroot_caps" = mkForce 0;
|
"kernel.grsecurity.chroot_caps" = mkForce 0;
|
||||||
|
"kernel.grsecurity.chroot_deny_chmod" = mkForce 0;
|
||||||
"kernel.grsecurity.chroot_deny_chroot" = mkForce 0;
|
"kernel.grsecurity.chroot_deny_chroot" = mkForce 0;
|
||||||
"kernel.grsecurity.chroot_deny_mount" = mkForce 0;
|
"kernel.grsecurity.chroot_deny_mount" = mkForce 0;
|
||||||
"kernel.grsecurity.chroot_deny_pivot" = mkForce 0;
|
"kernel.grsecurity.chroot_deny_pivot" = mkForce 0;
|
||||||
"kernel.grsecurity.chroot_deny_chmod" = mkForce 0;
|
|
||||||
} // optionalAttrs containerSupportRequired {
|
} // optionalAttrs containerSupportRequired {
|
||||||
# chroot(2) restrictions that conflict with NixOS lightweight containers
|
# chroot(2) restrictions that conflict with NixOS lightweight containers
|
||||||
|
"kernel.grsecurity.chroot_caps" = mkForce 0;
|
||||||
"kernel.grsecurity.chroot_deny_chmod" = mkForce 0;
|
"kernel.grsecurity.chroot_deny_chmod" = mkForce 0;
|
||||||
"kernel.grsecurity.chroot_deny_mount" = mkForce 0;
|
"kernel.grsecurity.chroot_deny_mount" = mkForce 0;
|
||||||
"kernel.grsecurity.chroot_restrict_nice" = mkForce 0;
|
"kernel.grsecurity.chroot_restrict_nice" = mkForce 0;
|
||||||
"kernel.grsecurity.chroot_caps" = mkForce 0;
|
# Disable privileged IO by default, unless X is enabled
|
||||||
|
} // optionalAttrs (!config.services.xserver.enable) {
|
||||||
|
"kernel.grsecurity.disable_priv_io" = mkDefault 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
assertions = [
|
|
||||||
{ assertion = !zfsNeededForBoot;
|
|
||||||
message = "grsecurity is currently incompatible with ZFS";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,13 @@
|
|||||||
# nixos-rebuild boot
|
# nixos-rebuild boot
|
||||||
# reboot
|
# reboot
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
<note><para>
|
||||||
|
Enabling the grsecurity module overrides
|
||||||
|
<option>boot.kernelPackages</option>, to reduce the risk of
|
||||||
|
misconfiguration. <xref linkend="sec-grsec-custom-kernel" />
|
||||||
|
describes how to use a custom kernel package set.
|
||||||
|
</para></note>
|
||||||
|
|
||||||
For most users, further configuration should be unnecessary. All users
|
For most users, further configuration should be unnecessary. All users
|
||||||
are encouraged to look over <xref linkend="sec-grsec-security" /> before
|
are encouraged to look over <xref linkend="sec-grsec-security" /> before
|
||||||
using the system, however. If you experience problems, please refer to
|
using the system, however. If you experience problems, please refer to
|
||||||
@ -144,15 +151,8 @@
|
|||||||
a TCP simultaneous OPEN on that port before the connection is actually
|
a TCP simultaneous OPEN on that port before the connection is actually
|
||||||
established.</para></listitem>
|
established.</para></listitem>
|
||||||
|
|
||||||
<listitem><para><filename class="directory">/sys</filename> hardening:
|
|
||||||
breaks systemd.</para></listitem>
|
|
||||||
|
|
||||||
<listitem><para>Trusted path execution: a desirable feature, but
|
<listitem><para>Trusted path execution: a desirable feature, but
|
||||||
requires some more work to operate smoothly on NixOS.</para></listitem>
|
requires some more work to operate smoothly on NixOS.</para></listitem>
|
||||||
|
|
||||||
<listitem><para>Module hardening: would break user initiated module
|
|
||||||
loading. Might enable this at some point, depending on the potential
|
|
||||||
breakage.</para></listitem>
|
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
|
|
||||||
@ -205,31 +205,42 @@
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
To use a custom kernel with upstream's recommended settings for server
|
To build a custom kernel using upstream's recommended settings for server
|
||||||
deployments:
|
deployments, while still using the NixOS module:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
boot.kernelPackages =
|
nixpkgs.config.packageOverrides = super: {
|
||||||
let
|
linux_grsec_nixos = super.linux_grsec_nixos.override {
|
||||||
kernel = pkgs.linux_grsec_nixos.override {
|
extraConfig = ''
|
||||||
extraConfig = ''
|
GRKERNSEC_CONFIG_AUTO y
|
||||||
GRKERNSEC_CONFIG_AUTO y
|
GRKERNSEC_CONFIG_SERVER y
|
||||||
GRKERNSEC_CONFIG_SERVER y
|
GRKERNSEC_CONFIG_SECURITY y
|
||||||
GRKERNSEC_CONFIG_SECURITY y
|
'';
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
self = pkgs.linuxPackagesFor kernel self;
|
}
|
||||||
in self;
|
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
The wikibook provides an exhaustive listing of
|
The wikibook provides an exhaustive listing of
|
||||||
<link xlink:href="https://en.wikibooks.org/wiki/Grsecurity/Appendix/Grsecurity_and_PaX_Configuration_Options">kernel configuration options</link>.
|
<link xlink:href="https://en.wikibooks.org/wiki/Grsecurity/Appendix/Grsecurity_and_PaX_Configuration_Options">kernel configuration options</link>.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The NixOS module makes several assumptions about the kernel and so may be
|
The NixOS module makes several assumptions about the kernel and so
|
||||||
incompatible with your customised kernel. Most of these assumptions are
|
may be incompatible with your customised kernel. Currently, the only way
|
||||||
encoded as assertions — mismatches should ideally result in a build
|
to work around incompatibilities is to eschew the NixOS module.
|
||||||
failure. Currently, the only way to work around incompatibilities is to
|
|
||||||
eschew the NixOS module and do all configuration yourself.
|
If not using the NixOS module, a custom grsecurity package set can
|
||||||
|
be specified inline instead, as in
|
||||||
|
<programlisting>
|
||||||
|
boot.kernelPackages =
|
||||||
|
let
|
||||||
|
kernel = pkgs.linux_grsec_nixos.override {
|
||||||
|
extraConfig = /* as above */;
|
||||||
|
};
|
||||||
|
self = pkgs.linuxPackagesFor kernel self;
|
||||||
|
in self;
|
||||||
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
</sect1>
|
</sect1>
|
||||||
@ -277,6 +288,10 @@
|
|||||||
<option>security.grsecurity.disableEfiRuntimeServices</option> to override
|
<option>security.grsecurity.disableEfiRuntimeServices</option> to override
|
||||||
this behavior.</para></listitem>
|
this behavior.</para></listitem>
|
||||||
|
|
||||||
|
<listitem><para>User initiated autoloading of modules (e.g., when
|
||||||
|
using fuse or loop devices) is disallowed; either load requisite modules
|
||||||
|
as root or add them to<option>boot.kernelModules</option>.</para></listitem>
|
||||||
|
|
||||||
<listitem><para>Virtualization: KVM is the preferred virtualization
|
<listitem><para>Virtualization: KVM is the preferred virtualization
|
||||||
solution. Xen, Virtualbox, and VMWare are
|
solution. Xen, Virtualbox, and VMWare are
|
||||||
<emphasis>unsupported</emphasis> and most likely require a custom kernel.
|
<emphasis>unsupported</emphasis> and most likely require a custom kernel.
|
||||||
@ -310,6 +325,19 @@
|
|||||||
</programlisting>
|
</programlisting>
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
|
|
||||||
|
<listitem><para>
|
||||||
|
The gitlab service (<xref linkend="module-services-gitlab" />)
|
||||||
|
requires a variant of the <literal>ruby</literal> interpreter
|
||||||
|
built without `mprotect()` hardening, as in
|
||||||
|
<programlisting>
|
||||||
|
services.gitlab.packages.gitlab = pkgs.gitlab.override {
|
||||||
|
ruby = pkgs.ruby.overrideAttrs (attrs: {
|
||||||
|
postFixup = "paxmark m $out/bin/ruby";
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</programlisting>
|
||||||
|
</para></listitem>
|
||||||
|
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
</sect1>
|
</sect1>
|
||||||
@ -332,13 +360,19 @@
|
|||||||
|
|
||||||
<listitem><para>
|
<listitem><para>
|
||||||
<literal>pax_sanitize_slab={off|fast|full}</literal>: control kernel
|
<literal>pax_sanitize_slab={off|fast|full}</literal>: control kernel
|
||||||
slab object sanitization
|
slab object sanitization. Defaults to <literal>fast</literal>
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
|
|
||||||
<listitem><para>
|
<listitem><para>
|
||||||
<literal>pax_size_overflow_report_only</literal>: log size overflow
|
<literal>pax_size_overflow_report_only</literal>: log size overflow
|
||||||
violations but leave the violating task running
|
violations but leave the violating task running
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
|
|
||||||
|
<listitem><para>
|
||||||
|
<literal>grsec_sysfs_restrict=[0|1]</literal>: toggle sysfs
|
||||||
|
restrictions. The NixOS module sets this to <literal>0</literal>
|
||||||
|
for systemd compatibility
|
||||||
|
</para></listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
@ -19,7 +19,9 @@ with lib;
|
|||||||
|
|
||||||
config = mkIf config.security.hideProcessInformation {
|
config = mkIf config.security.hideProcessInformation {
|
||||||
users.groups.proc.gid = config.ids.gids.proc;
|
users.groups.proc.gid = config.ids.gids.proc;
|
||||||
|
users.groups.proc.members = [ "polkituser" ];
|
||||||
|
|
||||||
boot.specialFileSystems."/proc".options = [ "hidepid=2" "gid=${toString config.ids.gids.proc}" ];
|
boot.specialFileSystems."/proc".options = [ "hidepid=2" "gid=${toString config.ids.gids.proc}" ];
|
||||||
|
systemd.services.systemd-logind.serviceConfig.SupplementaryGroups = [ "proc" ];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ with lib;
|
|||||||
ensureDir ${crashplan.vardir}/backupArchives 700
|
ensureDir ${crashplan.vardir}/backupArchives 700
|
||||||
ensureDir ${crashplan.vardir}/log 777
|
ensureDir ${crashplan.vardir}/log 777
|
||||||
cp -avn ${crashplan}/conf.template/* ${crashplan.vardir}/conf
|
cp -avn ${crashplan}/conf.template/* ${crashplan.vardir}/conf
|
||||||
for x in app.asar bin EULA.txt install.vars lang lib libjniwrap64.so libjniwrap.so libjtux64.so libjtux.so libmd564.so libmd5.so share skin upgrade; do
|
for x in app.asar bin install.vars lang lib libc42archive64.so libc52archive.so libjniwrap64.so libjniwrap.so libjtux64.so libjtux.so libleveldb64.so libleveldb.so libmd564.so libmd5.so share skin upgrade; do
|
||||||
rm -f ${crashplan.vardir}/$x;
|
rm -f ${crashplan.vardir}/$x;
|
||||||
ln -sf ${crashplan}/$x ${crashplan.vardir}/$x;
|
ln -sf ${crashplan}/$x ${crashplan.vardir}/$x;
|
||||||
done
|
done
|
||||||
|
@ -1,25 +1,25 @@
|
|||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, utils, ... }:
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.services.tarsnap;
|
gcfg = config.services.tarsnap;
|
||||||
|
|
||||||
configFile = name: cfg: ''
|
configFile = name: cfg: ''
|
||||||
cachedir ${config.services.tarsnap.cachedir}/${name}
|
keyfile ${cfg.keyfile}
|
||||||
keyfile ${cfg.keyfile}
|
${optionalString (cfg.cachedir != null) "cachedir ${cfg.cachedir}"}
|
||||||
${optionalString cfg.nodump "nodump"}
|
${optionalString cfg.nodump "nodump"}
|
||||||
${optionalString cfg.printStats "print-stats"}
|
${optionalString cfg.printStats "print-stats"}
|
||||||
${optionalString cfg.printStats "humanize-numbers"}
|
${optionalString cfg.printStats "humanize-numbers"}
|
||||||
${optionalString (cfg.checkpointBytes != null) ("checkpoint-bytes "+cfg.checkpointBytes)}
|
${optionalString (cfg.checkpointBytes != null) ("checkpoint-bytes "+cfg.checkpointBytes)}
|
||||||
${optionalString cfg.aggressiveNetworking "aggressive-networking"}
|
${optionalString cfg.aggressiveNetworking "aggressive-networking"}
|
||||||
${concatStringsSep "\n" (map (v: "exclude "+v) cfg.excludes)}
|
${concatStringsSep "\n" (map (v: "exclude ${v}") cfg.excludes)}
|
||||||
${concatStringsSep "\n" (map (v: "include "+v) cfg.includes)}
|
${concatStringsSep "\n" (map (v: "include ${v}") cfg.includes)}
|
||||||
${optionalString cfg.lowmem "lowmem"}
|
${optionalString cfg.lowmem "lowmem"}
|
||||||
${optionalString cfg.verylowmem "verylowmem"}
|
${optionalString cfg.verylowmem "verylowmem"}
|
||||||
${optionalString (cfg.maxbw != null) ("maxbw "+toString cfg.maxbw)}
|
${optionalString (cfg.maxbw != null) "maxbw ${toString cfg.maxbw}"}
|
||||||
${optionalString (cfg.maxbwRateUp != null) ("maxbw-rate-up "+toString cfg.maxbwRateUp)}
|
${optionalString (cfg.maxbwRateUp != null) "maxbw-rate-up ${toString cfg.maxbwRateUp}"}
|
||||||
${optionalString (cfg.maxbwRateDown != null) ("maxbw-rate-down "+toString cfg.maxbwRateDown)}
|
${optionalString (cfg.maxbwRateDown != null) "maxbw-rate-down ${toString cfg.maxbwRateDown}"}
|
||||||
'';
|
'';
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
@ -60,34 +60,13 @@ in
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
cachedir = mkOption {
|
|
||||||
type = types.nullOr types.path;
|
|
||||||
default = "/var/cache/tarsnap";
|
|
||||||
description = ''
|
|
||||||
The cache allows tarsnap to identify previously stored data
|
|
||||||
blocks, reducing archival time and bandwidth usage.
|
|
||||||
|
|
||||||
Should the cache become desynchronized or corrupted, tarsnap
|
|
||||||
will refuse to run until you manually rebuild the cache with
|
|
||||||
<command>tarsnap --fsck</command>.
|
|
||||||
|
|
||||||
Note that each individual archive (specified below) has its own cache
|
|
||||||
directory specified under <literal>cachedir</literal>; this is because
|
|
||||||
tarsnap locks the cache during backups, meaning multiple services
|
|
||||||
archives cannot be backed up concurrently or overlap with a shared
|
|
||||||
cache.
|
|
||||||
|
|
||||||
Set to <literal>null</literal> to disable caching.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
archives = mkOption {
|
archives = mkOption {
|
||||||
type = types.attrsOf (types.submodule (
|
type = types.attrsOf (types.submodule ({ config, ... }:
|
||||||
{
|
{
|
||||||
options = {
|
options = {
|
||||||
keyfile = mkOption {
|
keyfile = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = config.services.tarsnap.keyfile;
|
default = gcfg.keyfile;
|
||||||
description = ''
|
description = ''
|
||||||
Set a specific keyfile for this archive. This defaults to
|
Set a specific keyfile for this archive. This defaults to
|
||||||
<literal>"/root/tarsnap.key"</literal> if left unspecified.
|
<literal>"/root/tarsnap.key"</literal> if left unspecified.
|
||||||
@ -107,6 +86,21 @@ in
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
cachedir = mkOption {
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
default = "/var/cache/tarsnap/${utils.escapeSystemdPath config.keyfile}";
|
||||||
|
description = ''
|
||||||
|
The cache allows tarsnap to identify previously stored data
|
||||||
|
blocks, reducing archival time and bandwidth usage.
|
||||||
|
|
||||||
|
Should the cache become desynchronized or corrupted, tarsnap
|
||||||
|
will refuse to run until you manually rebuild the cache with
|
||||||
|
<command>tarsnap --fsck</command>.
|
||||||
|
|
||||||
|
Set to <literal>null</literal> to disable caching.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
nodump = mkOption {
|
nodump = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = true;
|
default = true;
|
||||||
@ -249,7 +243,7 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
gamedata =
|
gamedata =
|
||||||
{ directories = [ "/var/lib/minecraft "];
|
{ directories = [ "/var/lib/minecraft" ];
|
||||||
period = "*:30";
|
period = "*:30";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -262,8 +256,8 @@ in
|
|||||||
archive names are suffixed by a 1 second resolution timestamp.
|
archive names are suffixed by a 1 second resolution timestamp.
|
||||||
|
|
||||||
For each member of the set is created a timer which triggers the
|
For each member of the set is created a timer which triggers the
|
||||||
instanced <literal>tarsnap@</literal> service unit. You may use
|
instanced <literal>tarsnap-archive-name</literal> service unit. You may use
|
||||||
<command>systemctl start tarsnap@archive-name</command> to
|
<command>systemctl start tarsnap-archive-name</command> to
|
||||||
manually trigger creation of <literal>archive-name</literal> at
|
manually trigger creation of <literal>archive-name</literal> at
|
||||||
any time.
|
any time.
|
||||||
'';
|
'';
|
||||||
@ -271,63 +265,73 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf gcfg.enable {
|
||||||
assertions =
|
assertions =
|
||||||
(mapAttrsToList (name: cfg:
|
(mapAttrsToList (name: cfg:
|
||||||
{ assertion = cfg.directories != [];
|
{ assertion = cfg.directories != [];
|
||||||
message = "Must specify paths for tarsnap to back up";
|
message = "Must specify paths for tarsnap to back up";
|
||||||
}) cfg.archives) ++
|
}) gcfg.archives) ++
|
||||||
(mapAttrsToList (name: cfg:
|
(mapAttrsToList (name: cfg:
|
||||||
{ assertion = !(cfg.lowmem && cfg.verylowmem);
|
{ assertion = !(cfg.lowmem && cfg.verylowmem);
|
||||||
message = "You cannot set both lowmem and verylowmem";
|
message = "You cannot set both lowmem and verylowmem";
|
||||||
}) cfg.archives);
|
}) gcfg.archives);
|
||||||
|
|
||||||
systemd.services."tarsnap@" = {
|
systemd.services =
|
||||||
description = "Tarsnap archive '%i'";
|
mapAttrs' (name: cfg: nameValuePair "tarsnap-${name}" {
|
||||||
requires = [ "network-online.target" ];
|
description = "Tarsnap archive '${name}'";
|
||||||
after = [ "network-online.target" ];
|
requires = [ "network-online.target" ];
|
||||||
|
after = [ "network-online.target" ];
|
||||||
|
|
||||||
path = [ pkgs.iputils pkgs.tarsnap pkgs.coreutils ];
|
path = [ pkgs.iputils pkgs.tarsnap pkgs.utillinux ];
|
||||||
|
|
||||||
# In order for the persistent tarsnap timer to work reliably, we have to
|
# In order for the persistent tarsnap timer to work reliably, we have to
|
||||||
# make sure that the tarsnap server is reachable after systemd starts up
|
# make sure that the tarsnap server is reachable after systemd starts up
|
||||||
# the service - therefore we sleep in a loop until we can ping the
|
# the service - therefore we sleep in a loop until we can ping the
|
||||||
# endpoint.
|
# endpoint.
|
||||||
preStart = "while ! ping -q -c 1 v1-0-0-server.tarsnap.com &> /dev/null; do sleep 3; done";
|
preStart = ''
|
||||||
scriptArgs = "%i";
|
while ! ping -q -c 1 v1-0-0-server.tarsnap.com &> /dev/null; do sleep 3; done
|
||||||
script = ''
|
'';
|
||||||
mkdir -p -m 0755 ${dirOf cfg.cachedir}
|
|
||||||
mkdir -p -m 0700 ${cfg.cachedir}
|
|
||||||
chown root:root ${cfg.cachedir}
|
|
||||||
chmod 0700 ${cfg.cachedir}
|
|
||||||
mkdir -p -m 0700 ${cfg.cachedir}/$1
|
|
||||||
DIRS=`cat /etc/tarsnap/$1.dirs`
|
|
||||||
exec tarsnap --configfile /etc/tarsnap/$1.conf -c -f $1-$(date +"%Y%m%d%H%M%S") $DIRS
|
|
||||||
'';
|
|
||||||
|
|
||||||
serviceConfig = {
|
script =
|
||||||
IOSchedulingClass = "idle";
|
let run = ''tarsnap --configfile "/etc/tarsnap/${name}.conf" -c -f "${name}-$(date +"%Y%m%d%H%M%S")" ${concatStringsSep " " cfg.directories}'';
|
||||||
NoNewPrivileges = "true";
|
in if (cfg.cachedir != null) then ''
|
||||||
CapabilityBoundingSet = "CAP_DAC_READ_SEARCH";
|
mkdir -p ${cfg.cachedir}
|
||||||
PermissionsStartOnly = "true";
|
chmod 0700 ${cfg.cachedir}
|
||||||
};
|
|
||||||
};
|
( flock 9
|
||||||
|
if [ ! -e ${cfg.cachedir}/firstrun ]; then
|
||||||
|
( flock 10
|
||||||
|
flock -u 9
|
||||||
|
tarsnap --configfile "/etc/tarsnap/${name}.conf" --fsck
|
||||||
|
flock 9
|
||||||
|
) 10>${cfg.cachedir}/firstrun
|
||||||
|
fi
|
||||||
|
) 9>${cfg.cachedir}/lockf
|
||||||
|
|
||||||
|
exec flock ${cfg.cachedir}/firstrun ${run}
|
||||||
|
'' else "exec ${run}";
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
IOSchedulingClass = "idle";
|
||||||
|
NoNewPrivileges = "true";
|
||||||
|
CapabilityBoundingSet = [ "CAP_DAC_READ_SEARCH" ];
|
||||||
|
PermissionsStartOnly = "true";
|
||||||
|
};
|
||||||
|
}) gcfg.archives;
|
||||||
|
|
||||||
# Note: the timer must be Persistent=true, so that systemd will start it even
|
# Note: the timer must be Persistent=true, so that systemd will start it even
|
||||||
# if e.g. your laptop was asleep while the latest interval occurred.
|
# if e.g. your laptop was asleep while the latest interval occurred.
|
||||||
systemd.timers = mapAttrs' (name: cfg: nameValuePair "tarsnap@${name}"
|
systemd.timers = mapAttrs' (name: cfg: nameValuePair "tarsnap-${name}"
|
||||||
{ timerConfig.OnCalendar = cfg.period;
|
{ timerConfig.OnCalendar = cfg.period;
|
||||||
timerConfig.Persistent = "true";
|
timerConfig.Persistent = "true";
|
||||||
wantedBy = [ "timers.target" ];
|
wantedBy = [ "timers.target" ];
|
||||||
}) cfg.archives;
|
}) gcfg.archives;
|
||||||
|
|
||||||
environment.etc =
|
environment.etc =
|
||||||
(mapAttrs' (name: cfg: nameValuePair "tarsnap/${name}.conf"
|
mapAttrs' (name: cfg: nameValuePair "tarsnap/${name}.conf"
|
||||||
{ text = configFile name cfg;
|
{ text = configFile name cfg;
|
||||||
}) cfg.archives) //
|
}) gcfg.archives;
|
||||||
(mapAttrs' (name: cfg: nameValuePair "tarsnap/${name}.dirs"
|
|
||||||
{ text = concatStringsSep " " cfg.directories;
|
|
||||||
}) cfg.archives);
|
|
||||||
|
|
||||||
environment.systemPackages = [ pkgs.tarsnap ];
|
environment.systemPackages = [ pkgs.tarsnap ];
|
||||||
};
|
};
|
||||||
|
@ -28,7 +28,7 @@ in {
|
|||||||
|
|
||||||
etcdServers = mkOption {
|
etcdServers = mkOption {
|
||||||
type = types.listOf types.str;
|
type = types.listOf types.str;
|
||||||
default = [ "http://127.0.0.1:4001" ];
|
default = [ "http://127.0.0.1:2379" ];
|
||||||
description = ''
|
description = ''
|
||||||
Fleet list of etcd endpoints to use.
|
Fleet list of etcd endpoints to use.
|
||||||
'';
|
'';
|
||||||
|
@ -5,28 +5,62 @@ with lib;
|
|||||||
let
|
let
|
||||||
cfg = config.services.kubernetes;
|
cfg = config.services.kubernetes;
|
||||||
|
|
||||||
|
skipAttrs = attrs: map (filterAttrs (k: v: k != "enable"))
|
||||||
|
(filter (v: !(hasAttr "enable" v) || v.enable) attrs);
|
||||||
|
|
||||||
|
infraContainer = pkgs.dockerTools.buildImage {
|
||||||
|
name = "pause";
|
||||||
|
tag = "latest";
|
||||||
|
contents = cfg.package.pause;
|
||||||
|
config.Cmd = "/bin/pause";
|
||||||
|
};
|
||||||
|
|
||||||
|
kubeconfig = pkgs.writeText "kubeconfig" (builtins.toJSON {
|
||||||
|
apiVersion = "v1";
|
||||||
|
kind = "Config";
|
||||||
|
clusters = [{
|
||||||
|
name = "local";
|
||||||
|
cluster.certificate-authority = cfg.kubeconfig.caFile;
|
||||||
|
cluster.server = cfg.kubeconfig.server;
|
||||||
|
}];
|
||||||
|
users = [{
|
||||||
|
name = "kubelet";
|
||||||
|
user = {
|
||||||
|
client-certificate = cfg.kubeconfig.certFile;
|
||||||
|
client-key = cfg.kubeconfig.keyFile;
|
||||||
|
};
|
||||||
|
}];
|
||||||
|
contexts = [{
|
||||||
|
context = {
|
||||||
|
cluster = "local";
|
||||||
|
user = "kubelet";
|
||||||
|
};
|
||||||
|
current-context = "kubelet-context";
|
||||||
|
}];
|
||||||
|
});
|
||||||
|
|
||||||
|
policyFile = pkgs.writeText "kube-policy"
|
||||||
|
concatStringsSep "\n" (map (builtins.toJSON cfg.apiserver.authorizationPolicy));
|
||||||
|
|
||||||
|
cniConfig = pkgs.buildEnv {
|
||||||
|
name = "kubernetes-cni-config";
|
||||||
|
paths = imap (i: entry:
|
||||||
|
pkgs.writeTextDir "${10+i}-${entry.type}.conf" (builtins.toJSON entry)
|
||||||
|
) cfg.kubelet.cni.config;
|
||||||
|
};
|
||||||
|
|
||||||
|
manifests = pkgs.buildEnv {
|
||||||
|
name = "kubernetes-manifests";
|
||||||
|
paths = mapAttrsToList (name: manifest:
|
||||||
|
pkgs.writeTextDir "${name}.json" (builtins.toJSON manifest)
|
||||||
|
) cfg.kubelet.manifests;
|
||||||
|
};
|
||||||
|
|
||||||
in {
|
in {
|
||||||
|
|
||||||
###### interface
|
###### interface
|
||||||
|
|
||||||
options.services.kubernetes = {
|
options.services.kubernetes = {
|
||||||
package = mkOption {
|
|
||||||
description = "Kubernetes package to use.";
|
|
||||||
type = types.package;
|
|
||||||
};
|
|
||||||
|
|
||||||
verbose = mkOption {
|
|
||||||
description = "Kubernetes enable verbose mode for debugging";
|
|
||||||
default = false;
|
|
||||||
type = types.bool;
|
|
||||||
};
|
|
||||||
|
|
||||||
etcdServers = mkOption {
|
|
||||||
description = "Kubernetes list of etcd servers to watch.";
|
|
||||||
default = [ "127.0.0.1:4001" ];
|
|
||||||
type = types.listOf types.str;
|
|
||||||
};
|
|
||||||
|
|
||||||
roles = mkOption {
|
roles = mkOption {
|
||||||
description = ''
|
description = ''
|
||||||
Kubernetes role that this machine should take.
|
Kubernetes role that this machine should take.
|
||||||
@ -38,18 +72,76 @@ in {
|
|||||||
type = types.listOf (types.enum ["master" "node"]);
|
type = types.listOf (types.enum ["master" "node"]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
package = mkOption {
|
||||||
|
description = "Kubernetes package to use.";
|
||||||
|
type = types.package;
|
||||||
|
default = pkgs.kubernetes;
|
||||||
|
};
|
||||||
|
|
||||||
|
verbose = mkOption {
|
||||||
|
description = "Kubernetes enable verbose mode for debugging";
|
||||||
|
default = false;
|
||||||
|
type = types.bool;
|
||||||
|
};
|
||||||
|
|
||||||
|
etcd = {
|
||||||
|
servers = mkOption {
|
||||||
|
description = "List of etcd servers. By default etcd is started, except if this option is changed.";
|
||||||
|
default = ["http://127.0.0.1:2379"];
|
||||||
|
type = types.listOf types.str;
|
||||||
|
};
|
||||||
|
|
||||||
|
keyFile = mkOption {
|
||||||
|
description = "Etcd key file";
|
||||||
|
default = null;
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
};
|
||||||
|
|
||||||
|
certFile = mkOption {
|
||||||
|
description = "Etcd cert file";
|
||||||
|
default = null;
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
};
|
||||||
|
|
||||||
|
caFile = mkOption {
|
||||||
|
description = "Etcd ca file";
|
||||||
|
default = null;
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
kubeconfig = {
|
||||||
|
server = mkOption {
|
||||||
|
description = "Kubernetes apiserver server address";
|
||||||
|
default = "http://${cfg.apiserver.address}:${toString cfg.apiserver.port}";
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
|
||||||
|
caFile = mkOption {
|
||||||
|
description = "Certificate authrority file to use to connect to kuberentes apiserver";
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
certFile = mkOption {
|
||||||
|
description = "Client certificate file to use to connect to kubernetes";
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
keyFile = mkOption {
|
||||||
|
description = "Client key file to use to connect to kubernetes";
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
dataDir = mkOption {
|
dataDir = mkOption {
|
||||||
description = "Kubernetes root directory for managing kubelet files.";
|
description = "Kubernetes root directory for managing kubelet files.";
|
||||||
default = "/var/lib/kubernetes";
|
default = "/var/lib/kubernetes";
|
||||||
type = types.path;
|
type = types.path;
|
||||||
};
|
};
|
||||||
|
|
||||||
dockerCfg = mkOption {
|
|
||||||
description = "Kubernetes contents of dockercfg file.";
|
|
||||||
default = "";
|
|
||||||
type = types.lines;
|
|
||||||
};
|
|
||||||
|
|
||||||
apiserver = {
|
apiserver = {
|
||||||
enable = mkOption {
|
enable = mkOption {
|
||||||
description = "Whether to enable kubernetes apiserver.";
|
description = "Whether to enable kubernetes apiserver.";
|
||||||
@ -72,6 +164,16 @@ in {
|
|||||||
type = types.str;
|
type = types.str;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
advertiseAddress = mkOption {
|
||||||
|
description = ''
|
||||||
|
Kubernetes apiserver IP address on which to advertise the apiserver
|
||||||
|
to members of the cluster. This address must be reachable by the rest
|
||||||
|
of the cluster.
|
||||||
|
'';
|
||||||
|
default = null;
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
};
|
||||||
|
|
||||||
port = mkOption {
|
port = mkOption {
|
||||||
description = "Kubernetes apiserver listening port.";
|
description = "Kubernetes apiserver listening port.";
|
||||||
default = 8080;
|
default = 8080;
|
||||||
@ -80,41 +182,36 @@ in {
|
|||||||
|
|
||||||
securePort = mkOption {
|
securePort = mkOption {
|
||||||
description = "Kubernetes apiserver secure port.";
|
description = "Kubernetes apiserver secure port.";
|
||||||
default = 6443;
|
default = 443;
|
||||||
type = types.int;
|
type = types.int;
|
||||||
};
|
};
|
||||||
|
|
||||||
tlsCertFile = mkOption {
|
tlsCertFile = mkOption {
|
||||||
description = "Kubernetes apiserver certificate file.";
|
description = "Kubernetes apiserver certificate file.";
|
||||||
default = "";
|
default = null;
|
||||||
type = types.str;
|
type = types.nullOr types.path;
|
||||||
};
|
};
|
||||||
|
|
||||||
tlsPrivateKeyFile = mkOption {
|
tlsKeyFile = mkOption {
|
||||||
description = "Kubernetes apiserver private key file.";
|
description = "Kubernetes apiserver private key file.";
|
||||||
default = "";
|
default = null;
|
||||||
type = types.str;
|
type = types.nullOr types.path;
|
||||||
};
|
};
|
||||||
|
|
||||||
clientCaFile = mkOption {
|
clientCaFile = mkOption {
|
||||||
description = "Kubernetes apiserver CA file for client auth.";
|
description = "Kubernetes apiserver CA file for client auth.";
|
||||||
default = "";
|
default = null;
|
||||||
type = types.str;
|
type = types.nullOr types.path;
|
||||||
};
|
};
|
||||||
|
|
||||||
tokenAuth = mkOption {
|
tokenAuth = mkOption {
|
||||||
description = ''
|
description = ''
|
||||||
Kubernetes apiserver token authentication file. See
|
Kubernetes apiserver token authentication file. See
|
||||||
<link xlink:href="http://kubernetes.io/v1.0/docs/admin/authentication.html"/>
|
<link xlink:href="http://kubernetes.io/docs/admin/authentication.html"/>
|
||||||
'';
|
'';
|
||||||
default = {};
|
default = null;
|
||||||
example = literalExample ''
|
example = ''token,user,uid,"group1,group2,group3"'';
|
||||||
{
|
type = types.nullOr types.lines;
|
||||||
alice = "abc123";
|
|
||||||
bob = "xyz987";
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
type = types.attrsOf types.str;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
authorizationMode = mkOption {
|
authorizationMode = mkOption {
|
||||||
@ -148,13 +245,13 @@ in {
|
|||||||
|
|
||||||
allowPrivileged = mkOption {
|
allowPrivileged = mkOption {
|
||||||
description = "Whether to allow privileged containers on kubernetes.";
|
description = "Whether to allow privileged containers on kubernetes.";
|
||||||
default = false;
|
default = true;
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
};
|
};
|
||||||
|
|
||||||
portalNet = mkOption {
|
portalNet = mkOption {
|
||||||
description = "Kubernetes CIDR notation IP range from which to assign portal IPs";
|
description = "Kubernetes CIDR notation IP range from which to assign portal IPs";
|
||||||
default = "10.10.10.10/16";
|
default = "10.10.10.10/24";
|
||||||
type = types.str;
|
type = types.str;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -171,9 +268,9 @@ in {
|
|||||||
admissionControl = mkOption {
|
admissionControl = mkOption {
|
||||||
description = ''
|
description = ''
|
||||||
Kubernetes admission control plugins to use. See
|
Kubernetes admission control plugins to use. See
|
||||||
<link xlink:href="http://kubernetes.io/v1.0/docs/admin/admission-controllers.html"/>
|
<link xlink:href="http://kubernetes.io/docs/admin/admission-controllers/"/>
|
||||||
'';
|
'';
|
||||||
default = ["AlwaysAdmit"];
|
default = ["NamespaceLifecycle" "LimitRanger" "ServiceAccount" "ResourceQuota"];
|
||||||
example = [
|
example = [
|
||||||
"NamespaceLifecycle" "NamespaceExists" "LimitRanger"
|
"NamespaceLifecycle" "NamespaceExists" "LimitRanger"
|
||||||
"SecurityContextDeny" "ServiceAccount" "ResourceQuota"
|
"SecurityContextDeny" "ServiceAccount" "ResourceQuota"
|
||||||
@ -181,15 +278,40 @@ in {
|
|||||||
type = types.listOf types.str;
|
type = types.listOf types.str;
|
||||||
};
|
};
|
||||||
|
|
||||||
serviceAccountKey = mkOption {
|
serviceAccountKeyFile = mkOption {
|
||||||
description = ''
|
description = ''
|
||||||
Kubernetes apiserver PEM-encoded x509 RSA private or public key file,
|
Kubernetes apiserver PEM-encoded x509 RSA private or public key file,
|
||||||
used to verify ServiceAccount tokens.
|
used to verify ServiceAccount tokens. By default tls private key file
|
||||||
|
is used.
|
||||||
'';
|
'';
|
||||||
default = null;
|
default = null;
|
||||||
type = types.nullOr types.path;
|
type = types.nullOr types.path;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
kubeletClientCaFile = mkOption {
|
||||||
|
description = "Path to a cert file for connecting to kubelet";
|
||||||
|
default = null;
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
};
|
||||||
|
|
||||||
|
kubeletClientCertFile = mkOption {
|
||||||
|
description = "Client certificate to use for connections to kubelet";
|
||||||
|
default = null;
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
};
|
||||||
|
|
||||||
|
kubeletClientKeyFile = mkOption {
|
||||||
|
description = "Key to use for connections to kubelet";
|
||||||
|
default = null;
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
};
|
||||||
|
|
||||||
|
kubeletHttps = mkOption {
|
||||||
|
description = "Whether to use https for connections to kubelet";
|
||||||
|
default = true;
|
||||||
|
type = types.bool;
|
||||||
|
};
|
||||||
|
|
||||||
extraOpts = mkOption {
|
extraOpts = mkOption {
|
||||||
description = "Kubernetes apiserver extra command line options.";
|
description = "Kubernetes apiserver extra command line options.";
|
||||||
default = "";
|
default = "";
|
||||||
@ -216,10 +338,10 @@ in {
|
|||||||
type = types.int;
|
type = types.int;
|
||||||
};
|
};
|
||||||
|
|
||||||
master = mkOption {
|
leaderElect = mkOption {
|
||||||
description = "Kubernetes apiserver address";
|
description = "Whether to start leader election before executing main loop";
|
||||||
default = "${cfg.apiserver.address}:${toString cfg.apiserver.port}";
|
type = types.bool;
|
||||||
type = types.str;
|
default = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
extraOpts = mkOption {
|
extraOpts = mkOption {
|
||||||
@ -248,13 +370,13 @@ in {
|
|||||||
type = types.int;
|
type = types.int;
|
||||||
};
|
};
|
||||||
|
|
||||||
master = mkOption {
|
leaderElect = mkOption {
|
||||||
description = "Kubernetes apiserver address";
|
description = "Whether to start leader election before executing main loop";
|
||||||
default = "${cfg.apiserver.address}:${toString cfg.apiserver.port}";
|
type = types.bool;
|
||||||
type = types.str;
|
default = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
serviceAccountPrivateKey = mkOption {
|
serviceAccountKeyFile = mkOption {
|
||||||
description = ''
|
description = ''
|
||||||
Kubernetes controller manager PEM-encoded private RSA key file used to
|
Kubernetes controller manager PEM-encoded private RSA key file used to
|
||||||
sign service account tokens
|
sign service account tokens
|
||||||
@ -272,6 +394,12 @@ in {
|
|||||||
type = types.nullOr types.path;
|
type = types.nullOr types.path;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
clusterCidr = mkOption {
|
||||||
|
description = "Kubernetes controller manager CIDR Range for Pods in cluster";
|
||||||
|
default = "10.10.0.0/16";
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
|
||||||
extraOpts = mkOption {
|
extraOpts = mkOption {
|
||||||
description = "Kubernetes controller manager extra command line options.";
|
description = "Kubernetes controller manager extra command line options.";
|
||||||
default = "";
|
default = "";
|
||||||
@ -292,6 +420,12 @@ in {
|
|||||||
type = types.bool;
|
type = types.bool;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
registerSchedulable = mkOption {
|
||||||
|
description = "Register the node as schedulable. No-op if register-node is false.";
|
||||||
|
default = true;
|
||||||
|
type = types.bool;
|
||||||
|
};
|
||||||
|
|
||||||
address = mkOption {
|
address = mkOption {
|
||||||
description = "Kubernetes kubelet info server listening address.";
|
description = "Kubernetes kubelet info server listening address.";
|
||||||
default = "0.0.0.0";
|
default = "0.0.0.0";
|
||||||
@ -304,6 +438,18 @@ in {
|
|||||||
type = types.int;
|
type = types.int;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
tlsCertFile = mkOption {
|
||||||
|
description = "File containing x509 Certificate for HTTPS.";
|
||||||
|
default = null;
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
};
|
||||||
|
|
||||||
|
tlsKeyFile = mkOption {
|
||||||
|
description = "File containing x509 private key matching tlsCertFile.";
|
||||||
|
default = null;
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
};
|
||||||
|
|
||||||
healthz = {
|
healthz = {
|
||||||
bind = mkOption {
|
bind = mkOption {
|
||||||
description = "Kubernetes kubelet healthz listening address.";
|
description = "Kubernetes kubelet healthz listening address.";
|
||||||
@ -326,19 +472,10 @@ in {
|
|||||||
|
|
||||||
allowPrivileged = mkOption {
|
allowPrivileged = mkOption {
|
||||||
description = "Whether to allow kubernetes containers to request privileged mode.";
|
description = "Whether to allow kubernetes containers to request privileged mode.";
|
||||||
default = false;
|
default = true;
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
};
|
};
|
||||||
|
|
||||||
apiServers = mkOption {
|
|
||||||
description = ''
|
|
||||||
Kubernetes kubelet list of Kubernetes API servers for publishing events,
|
|
||||||
and reading pods and services.
|
|
||||||
'';
|
|
||||||
default = ["${cfg.apiserver.address}:${toString cfg.apiserver.port}"];
|
|
||||||
type = types.listOf types.str;
|
|
||||||
};
|
|
||||||
|
|
||||||
cadvisorPort = mkOption {
|
cadvisorPort = mkOption {
|
||||||
description = "Kubernetes kubelet local cadvisor port.";
|
description = "Kubernetes kubelet local cadvisor port.";
|
||||||
default = 4194;
|
default = 4194;
|
||||||
@ -347,16 +484,62 @@ in {
|
|||||||
|
|
||||||
clusterDns = mkOption {
|
clusterDns = mkOption {
|
||||||
description = "Use alternative dns.";
|
description = "Use alternative dns.";
|
||||||
default = "";
|
default = "10.10.0.1";
|
||||||
type = types.str;
|
type = types.str;
|
||||||
};
|
};
|
||||||
|
|
||||||
clusterDomain = mkOption {
|
clusterDomain = mkOption {
|
||||||
description = "Use alternative domain.";
|
description = "Use alternative domain.";
|
||||||
default = "kubernetes.io";
|
default = "cluster.local";
|
||||||
type = types.str;
|
type = types.str;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
networkPlugin = mkOption {
|
||||||
|
description = "Network plugin to use by kubernetes";
|
||||||
|
type = types.nullOr (types.enum ["cni" "kubenet"]);
|
||||||
|
default = "kubenet";
|
||||||
|
};
|
||||||
|
|
||||||
|
cni = {
|
||||||
|
packages = mkOption {
|
||||||
|
description = "List of network plugin packages to install";
|
||||||
|
type = types.listOf types.package;
|
||||||
|
default = [];
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkOption {
|
||||||
|
description = "Kubernetes CNI configuration";
|
||||||
|
type = types.listOf types.attrs;
|
||||||
|
default = [];
|
||||||
|
example = literalExample ''
|
||||||
|
[{
|
||||||
|
"cniVersion": "0.2.0",
|
||||||
|
"name": "mynet",
|
||||||
|
"type": "bridge",
|
||||||
|
"bridge": "cni0",
|
||||||
|
"isGateway": true,
|
||||||
|
"ipMasq": true,
|
||||||
|
"ipam": {
|
||||||
|
"type": "host-local",
|
||||||
|
"subnet": "10.22.0.0/16",
|
||||||
|
"routes": [
|
||||||
|
{ "dst": "0.0.0.0/0" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
} {
|
||||||
|
"cniVersion": "0.2.0",
|
||||||
|
"type": "loopback"
|
||||||
|
}]
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
manifests = mkOption {
|
||||||
|
description = "List of manifests to bootstrap with kubelet";
|
||||||
|
type = types.attrsOf types.attrs;
|
||||||
|
default = {};
|
||||||
|
};
|
||||||
|
|
||||||
extraOpts = mkOption {
|
extraOpts = mkOption {
|
||||||
description = "Kubernetes kubelet extra command line options.";
|
description = "Kubernetes kubelet extra command line options.";
|
||||||
default = "";
|
default = "";
|
||||||
@ -377,12 +560,6 @@ in {
|
|||||||
type = types.str;
|
type = types.str;
|
||||||
};
|
};
|
||||||
|
|
||||||
master = mkOption {
|
|
||||||
description = "Kubernetes apiserver address";
|
|
||||||
default = "${cfg.apiserver.address}:${toString cfg.apiserver.port}";
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
|
|
||||||
extraOpts = mkOption {
|
extraOpts = mkOption {
|
||||||
description = "Kubernetes proxy extra command line options.";
|
description = "Kubernetes proxy extra command line options.";
|
||||||
default = "";
|
default = "";
|
||||||
@ -390,23 +567,23 @@ in {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
kube2sky = {
|
dns = {
|
||||||
enable = mkEnableOption "Whether to enable kube2sky dns service.";
|
enable = mkEnableOption "kubernetes dns service.";
|
||||||
|
|
||||||
|
port = mkOption {
|
||||||
|
description = "Kubernetes dns listening port";
|
||||||
|
default = 53;
|
||||||
|
type = types.int;
|
||||||
|
};
|
||||||
|
|
||||||
domain = mkOption {
|
domain = mkOption {
|
||||||
description = "Kuberntes kube2sky domain under which all DNS names will be hosted.";
|
description = "Kuberntes dns domain under which to create names.";
|
||||||
default = cfg.kubelet.clusterDomain;
|
default = cfg.kubelet.clusterDomain;
|
||||||
type = types.str;
|
type = types.str;
|
||||||
};
|
};
|
||||||
|
|
||||||
master = mkOption {
|
|
||||||
description = "Kubernetes apiserver address";
|
|
||||||
default = "${cfg.apiserver.address}:${toString cfg.apiserver.port}";
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
|
|
||||||
extraOpts = mkOption {
|
extraOpts = mkOption {
|
||||||
description = "Kubernetes kube2sky extra command line options.";
|
description = "Kubernetes dns extra command line options.";
|
||||||
default = "";
|
default = "";
|
||||||
type = types.str;
|
type = types.str;
|
||||||
};
|
};
|
||||||
@ -416,50 +593,118 @@ in {
|
|||||||
###### implementation
|
###### implementation
|
||||||
|
|
||||||
config = mkMerge [
|
config = mkMerge [
|
||||||
|
(mkIf cfg.kubelet.enable {
|
||||||
|
systemd.services.kubelet = {
|
||||||
|
description = "Kubernetes Kubelet Service";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
after = [ "network.target" "docker.service" "kube-apiserver.service" ];
|
||||||
|
path = with pkgs; [ gitMinimal openssh docker utillinux iproute ethtool thin-provisioning-tools iptables ];
|
||||||
|
preStart = ''
|
||||||
|
docker load < ${infraContainer}
|
||||||
|
rm /opt/cni/bin/* || true
|
||||||
|
${concatMapStringsSep "\n" (p: "ln -fs ${p.plugins}/* /opt/cni/bin") cfg.kubelet.cni.packages}
|
||||||
|
'';
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = ''${cfg.package}/bin/kubelet \
|
||||||
|
--pod-manifest-path=${manifests} \
|
||||||
|
--kubeconfig=${kubeconfig} \
|
||||||
|
--require-kubeconfig \
|
||||||
|
--address=${cfg.kubelet.address} \
|
||||||
|
--port=${toString cfg.kubelet.port} \
|
||||||
|
--register-node=${if cfg.kubelet.registerNode then "true" else "false"} \
|
||||||
|
--register-schedulable=${if cfg.kubelet.registerSchedulable then "true" else "false"} \
|
||||||
|
${optionalString (cfg.kubelet.tlsCertFile != null)
|
||||||
|
"--tls-cert-file=${cfg.kubelet.tlsCertFile}"} \
|
||||||
|
${optionalString (cfg.kubelet.tlsKeyFile != null)
|
||||||
|
"--tls-private-key-file=${cfg.kubelet.tlsKeyFile}"} \
|
||||||
|
--healthz-bind-address=${cfg.kubelet.healthz.bind} \
|
||||||
|
--healthz-port=${toString cfg.kubelet.healthz.port} \
|
||||||
|
--hostname-override=${cfg.kubelet.hostname} \
|
||||||
|
--allow-privileged=${if cfg.kubelet.allowPrivileged then "true" else "false"} \
|
||||||
|
--root-dir=${cfg.dataDir} \
|
||||||
|
--cadvisor_port=${toString cfg.kubelet.cadvisorPort} \
|
||||||
|
${optionalString (cfg.kubelet.clusterDns != "")
|
||||||
|
"--cluster-dns=${cfg.kubelet.clusterDns}"} \
|
||||||
|
${optionalString (cfg.kubelet.clusterDomain != "")
|
||||||
|
"--cluster-domain=${cfg.kubelet.clusterDomain}"} \
|
||||||
|
--pod-infra-container-image=pause \
|
||||||
|
${optionalString (cfg.kubelet.networkPlugin != null)
|
||||||
|
"--network-plugin=${cfg.kubelet.networkPlugin}"} \
|
||||||
|
--cni-conf-dir=${cniConfig} \
|
||||||
|
--reconcile-cidr \
|
||||||
|
--hairpin-mode=hairpin-veth \
|
||||||
|
${optionalString cfg.verbose "--v=6 --log_flush_frequency=1s"} \
|
||||||
|
${cfg.kubelet.extraOpts}
|
||||||
|
'';
|
||||||
|
WorkingDirectory = cfg.dataDir;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.etc = mapAttrs' (name: manifest:
|
||||||
|
nameValuePair "kubernetes/manifests/${name}.json" {
|
||||||
|
text = builtins.toJSON manifest;
|
||||||
|
mode = "0755";
|
||||||
|
}
|
||||||
|
) cfg.kubelet.manifests;
|
||||||
|
|
||||||
|
# Allways include cni plugins
|
||||||
|
services.kubernetes.kubelet.cni.packages = [pkgs.cni];
|
||||||
|
})
|
||||||
|
|
||||||
(mkIf cfg.apiserver.enable {
|
(mkIf cfg.apiserver.enable {
|
||||||
systemd.services.kube-apiserver = {
|
systemd.services.kube-apiserver = {
|
||||||
description = "Kubernetes Api Server";
|
description = "Kubernetes Kubelet Service";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
requires = ["kubernetes-setup.service"];
|
after = [ "network.target" "docker.service" ];
|
||||||
after = [ "network.target" "etcd.service" "kubernetes-setup.service" ];
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
ExecStart = let
|
ExecStart = ''${cfg.package}/bin/kube-apiserver \
|
||||||
authorizationPolicyFile =
|
--etcd-servers=${concatStringsSep "," cfg.etcd.servers} \
|
||||||
pkgs.writeText "kubernetes-policy"
|
${optionalString (cfg.etcd.caFile != null)
|
||||||
(builtins.toJSON cfg.apiserver.authorizationPolicy);
|
"--etcd-cafile=${cfg.etcd.caFile}"} \
|
||||||
tokenAuthFile =
|
${optionalString (cfg.etcd.certFile != null)
|
||||||
pkgs.writeText "kubernetes-auth"
|
"--etcd-certfile=${cfg.etcd.certFile}"} \
|
||||||
(concatImapStringsSep "\n" (i: v: v + "," + (toString i))
|
${optionalString (cfg.etcd.keyFile != null)
|
||||||
(mapAttrsToList (name: token: token + "," + name) cfg.apiserver.tokenAuth));
|
"--etcd-keyfile=${cfg.etcd.keyFile}"} \
|
||||||
in ''${cfg.package}/bin/kube-apiserver \
|
|
||||||
--etcd-servers=${concatMapStringsSep "," (f: "http://${f}") cfg.etcdServers} \
|
|
||||||
--insecure-bind-address=${cfg.apiserver.address} \
|
|
||||||
--insecure-port=${toString cfg.apiserver.port} \
|
--insecure-port=${toString cfg.apiserver.port} \
|
||||||
--bind-address=${cfg.apiserver.publicAddress} \
|
--bind-address=0.0.0.0 \
|
||||||
|
${optionalString (cfg.apiserver.advertiseAddress != null)
|
||||||
|
"--advertise-address=${cfg.apiserver.advertiseAddress}"} \
|
||||||
--allow-privileged=${if cfg.apiserver.allowPrivileged then "true" else "false"} \
|
--allow-privileged=${if cfg.apiserver.allowPrivileged then "true" else "false"} \
|
||||||
${optionalString (cfg.apiserver.tlsCertFile!="")
|
${optionalString (cfg.apiserver.tlsCertFile != null)
|
||||||
"--tls-cert-file=${cfg.apiserver.tlsCertFile}"} \
|
"--tls-cert-file=${cfg.apiserver.tlsCertFile}"} \
|
||||||
${optionalString (cfg.apiserver.tlsPrivateKeyFile!="")
|
${optionalString (cfg.apiserver.tlsKeyFile != null)
|
||||||
"--tls-private-key-file=${cfg.apiserver.tlsPrivateKeyFile}"} \
|
"--tls-private-key-file=${cfg.apiserver.tlsKeyFile}"} \
|
||||||
${optionalString (cfg.apiserver.tokenAuth!=[])
|
${optionalString (cfg.apiserver.tokenAuth != null)
|
||||||
"--token-auth-file=${tokenAuthFile}"} \
|
"--token-auth-file=${cfg.apiserver.tokenAuth}"} \
|
||||||
${optionalString (cfg.apiserver.clientCaFile!="")
|
--kubelet-https=${if cfg.apiserver.kubeletHttps then "true" else "false"} \
|
||||||
|
${optionalString (cfg.apiserver.kubeletClientCaFile != null)
|
||||||
|
"--kubelet-certificate-authority=${cfg.apiserver.kubeletClientCaFile}"} \
|
||||||
|
${optionalString (cfg.apiserver.kubeletClientCertFile != null)
|
||||||
|
"--kubelet-client-certificate=${cfg.apiserver.kubeletClientCertFile}"} \
|
||||||
|
${optionalString (cfg.apiserver.kubeletClientKeyFile != null)
|
||||||
|
"--kubelet-client-key=${cfg.apiserver.kubeletClientKeyFile}"} \
|
||||||
|
${optionalString (cfg.apiserver.clientCaFile != null)
|
||||||
"--client-ca-file=${cfg.apiserver.clientCaFile}"} \
|
"--client-ca-file=${cfg.apiserver.clientCaFile}"} \
|
||||||
--authorization-mode=${cfg.apiserver.authorizationMode} \
|
--authorization-mode=${cfg.apiserver.authorizationMode} \
|
||||||
${optionalString (cfg.apiserver.authorizationMode == "ABAC")
|
${optionalString (cfg.apiserver.authorizationMode == "ABAC")
|
||||||
"--authorization-policy-file=${authorizationPolicyFile}"} \
|
"--authorization-policy-file=${policyFile}"} \
|
||||||
--secure-port=${toString cfg.apiserver.securePort} \
|
--secure-port=${toString cfg.apiserver.securePort} \
|
||||||
--service-cluster-ip-range=${cfg.apiserver.portalNet} \
|
--service-cluster-ip-range=${cfg.apiserver.portalNet} \
|
||||||
${optionalString (cfg.apiserver.runtimeConfig!="")
|
${optionalString (cfg.apiserver.runtimeConfig != "")
|
||||||
"--runtime-config=${cfg.apiserver.runtimeConfig}"} \
|
"--runtime-config=${cfg.apiserver.runtimeConfig}"} \
|
||||||
--admission_control=${concatStringsSep "," cfg.apiserver.admissionControl} \
|
--admission_control=${concatStringsSep "," cfg.apiserver.admissionControl} \
|
||||||
${optionalString (cfg.apiserver.serviceAccountKey!=null)
|
${optionalString (cfg.apiserver.serviceAccountKeyFile!=null)
|
||||||
"--service-account-key-file=${cfg.apiserver.serviceAccountKey}"} \
|
"--service-account-key-file=${cfg.apiserver.serviceAccountKeyFile}"} \
|
||||||
--logtostderr=true \
|
${optionalString cfg.verbose "--v=6"} \
|
||||||
${optionalString cfg.verbose "--v=6 --log-flush-frequency=1s"} \
|
${optionalString cfg.verbose "--log-flush-frequency=1s"} \
|
||||||
${cfg.apiserver.extraOpts}
|
${cfg.apiserver.extraOpts}
|
||||||
'';
|
'';
|
||||||
|
WorkingDirectory = cfg.dataDir;
|
||||||
User = "kubernetes";
|
User = "kubernetes";
|
||||||
|
Group = "kubernetes";
|
||||||
|
AmbientCapabilities = "cap_net_bind_service";
|
||||||
|
Restart = "on-failure";
|
||||||
|
RestartSec = 5;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
@ -468,17 +713,20 @@ in {
|
|||||||
systemd.services.kube-scheduler = {
|
systemd.services.kube-scheduler = {
|
||||||
description = "Kubernetes Scheduler Service";
|
description = "Kubernetes Scheduler Service";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
after = [ "network.target" "kubernetes-apiserver.service" ];
|
after = [ "kube-apiserver.service" ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
ExecStart = ''${cfg.package}/bin/kube-scheduler \
|
ExecStart = ''${cfg.package}/bin/kube-scheduler \
|
||||||
--address=${cfg.scheduler.address} \
|
--address=${cfg.scheduler.address} \
|
||||||
--port=${toString cfg.scheduler.port} \
|
--port=${toString cfg.scheduler.port} \
|
||||||
--master=${cfg.scheduler.master} \
|
--leader-elect=${if cfg.scheduler.leaderElect then "true" else "false"} \
|
||||||
--logtostderr=true \
|
--kubeconfig=${kubeconfig} \
|
||||||
${optionalString cfg.verbose "--v=6 --log-flush-frequency=1s"} \
|
${optionalString cfg.verbose "--v=6"} \
|
||||||
|
${optionalString cfg.verbose "--log-flush-frequency=1s"} \
|
||||||
${cfg.scheduler.extraOpts}
|
${cfg.scheduler.extraOpts}
|
||||||
'';
|
'';
|
||||||
|
WorkingDirectory = cfg.dataDir;
|
||||||
User = "kubernetes";
|
User = "kubernetes";
|
||||||
|
Group = "kubernetes";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
@ -487,113 +735,94 @@ in {
|
|||||||
systemd.services.kube-controller-manager = {
|
systemd.services.kube-controller-manager = {
|
||||||
description = "Kubernetes Controller Manager Service";
|
description = "Kubernetes Controller Manager Service";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
after = [ "network.target" "kubernetes-apiserver.service" ];
|
after = [ "kube-apiserver.service" ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
ExecStart = ''${cfg.package}/bin/kube-controller-manager \
|
ExecStart = ''${cfg.package}/bin/kube-controller-manager \
|
||||||
--address=${cfg.controllerManager.address} \
|
--address=${cfg.controllerManager.address} \
|
||||||
--port=${toString cfg.controllerManager.port} \
|
--port=${toString cfg.controllerManager.port} \
|
||||||
--master=${cfg.controllerManager.master} \
|
--kubeconfig=${kubeconfig} \
|
||||||
${optionalString (cfg.controllerManager.serviceAccountPrivateKey!=null)
|
--leader-elect=${if cfg.controllerManager.leaderElect then "true" else "false"} \
|
||||||
"--service-account-private-key-file=${cfg.controllerManager.serviceAccountPrivateKey}"} \
|
${if (cfg.controllerManager.serviceAccountKeyFile!=null)
|
||||||
|
then "--service-account-private-key-file=${cfg.controllerManager.serviceAccountKeyFile}"
|
||||||
|
else "--service-account-private-key-file=/var/run/kubernetes/apiserver.key"} \
|
||||||
${optionalString (cfg.controllerManager.rootCaFile!=null)
|
${optionalString (cfg.controllerManager.rootCaFile!=null)
|
||||||
"--root-ca-file=${cfg.controllerManager.rootCaFile}"} \
|
"--root-ca-file=${cfg.controllerManager.rootCaFile}"} \
|
||||||
--logtostderr=true \
|
${optionalString (cfg.controllerManager.clusterCidr!=null)
|
||||||
${optionalString cfg.verbose "--v=6 --log-flush-frequency=1s"} \
|
"--cluster-cidr=${cfg.controllerManager.clusterCidr}"} \
|
||||||
|
--allocate-node-cidrs=true \
|
||||||
|
${optionalString cfg.verbose "--v=6"} \
|
||||||
|
${optionalString cfg.verbose "--log-flush-frequency=1s"} \
|
||||||
${cfg.controllerManager.extraOpts}
|
${cfg.controllerManager.extraOpts}
|
||||||
'';
|
'';
|
||||||
|
WorkingDirectory = cfg.dataDir;
|
||||||
User = "kubernetes";
|
User = "kubernetes";
|
||||||
|
Group = "kubernetes";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
|
||||||
(mkIf cfg.kubelet.enable {
|
|
||||||
systemd.services.kubelet = {
|
|
||||||
description = "Kubernetes Kubelet Service";
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
requires = ["kubernetes-setup.service"];
|
|
||||||
after = [ "network.target" "etcd.service" "docker.service" "kubernetes-setup.service" ];
|
|
||||||
path = [ pkgs.gitMinimal pkgs.openssh ];
|
|
||||||
script = ''
|
|
||||||
export PATH="/bin:/sbin:/usr/bin:/usr/sbin:$PATH"
|
|
||||||
exec ${cfg.package}/bin/kubelet \
|
|
||||||
--api-servers=${concatMapStringsSep "," (f: "http://${f}") cfg.kubelet.apiServers} \
|
|
||||||
--register-node=${if cfg.kubelet.registerNode then "true" else "false"} \
|
|
||||||
--address=${cfg.kubelet.address} \
|
|
||||||
--port=${toString cfg.kubelet.port} \
|
|
||||||
--healthz-bind-address=${cfg.kubelet.healthz.bind} \
|
|
||||||
--healthz-port=${toString cfg.kubelet.healthz.port} \
|
|
||||||
--hostname-override=${cfg.kubelet.hostname} \
|
|
||||||
--allow-privileged=${if cfg.kubelet.allowPrivileged then "true" else "false"} \
|
|
||||||
--root-dir=${cfg.dataDir} \
|
|
||||||
--cadvisor_port=${toString cfg.kubelet.cadvisorPort} \
|
|
||||||
${optionalString (cfg.kubelet.clusterDns != "")
|
|
||||||
''--cluster-dns=${cfg.kubelet.clusterDns}''} \
|
|
||||||
${optionalString (cfg.kubelet.clusterDomain != "")
|
|
||||||
''--cluster-domain=${cfg.kubelet.clusterDomain}''} \
|
|
||||||
--logtostderr=true \
|
|
||||||
${optionalString cfg.verbose "--v=6 --log_flush_frequency=1s"} \
|
|
||||||
${cfg.kubelet.extraOpts}
|
|
||||||
'';
|
|
||||||
serviceConfig.WorkingDirectory = cfg.dataDir;
|
|
||||||
};
|
|
||||||
})
|
|
||||||
|
|
||||||
(mkIf cfg.proxy.enable {
|
(mkIf cfg.proxy.enable {
|
||||||
systemd.services.kube-proxy = {
|
systemd.services.kube-proxy = {
|
||||||
description = "Kubernetes Proxy Service";
|
description = "Kubernetes Proxy Service";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
after = [ "network.target" "etcd.service" ];
|
after = [ "kube-apiserver.service" ];
|
||||||
|
path = [pkgs.iptables];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
ExecStart = ''${cfg.package}/bin/kube-proxy \
|
ExecStart = ''${cfg.package}/bin/kube-proxy \
|
||||||
--master=${cfg.proxy.master} \
|
--kubeconfig=${kubeconfig} \
|
||||||
--bind-address=${cfg.proxy.address} \
|
--bind-address=${cfg.proxy.address} \
|
||||||
--logtostderr=true \
|
${optionalString cfg.verbose "--v=6"} \
|
||||||
${optionalString cfg.verbose "--v=6 --log-flush-frequency=1s"} \
|
${optionalString cfg.verbose "--log-flush-frequency=1s"} \
|
||||||
${cfg.proxy.extraOpts}
|
${cfg.controllerManager.extraOpts}
|
||||||
'';
|
'';
|
||||||
Restart = "always"; # Retry connection
|
WorkingDirectory = cfg.dataDir;
|
||||||
RestartSec = "5s";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
|
||||||
(mkIf cfg.kube2sky.enable {
|
(mkIf cfg.dns.enable {
|
||||||
systemd.services.kube2sky = {
|
systemd.services.kube-dns = {
|
||||||
description = "Kubernetes Dns Bridge Service";
|
description = "Kubernetes Dns Service";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
after = [ "network.target" "skydns.service" "etcd.service" "kubernetes-apiserver.service" ];
|
after = [ "kube-apiserver.service" ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
ExecStart = ''${cfg.package}/bin/kube2sky \
|
ExecStart = ''${cfg.package}/bin/kube-dns \
|
||||||
-etcd-server=http://${head cfg.etcdServers} \
|
--kubecfg-file=${kubeconfig} \
|
||||||
-domain=${cfg.kube2sky.domain} \
|
--dns-port=${toString cfg.dns.port} \
|
||||||
-kube_master_url=http://${cfg.kube2sky.master} \
|
--domain=${cfg.dns.domain} \
|
||||||
-logtostderr=true \
|
${optionalString cfg.verbose "--v=6"} \
|
||||||
${optionalString cfg.verbose "--v=6 --log-flush-frequency=1s"} \
|
${optionalString cfg.verbose "--log-flush-frequency=1s"} \
|
||||||
${cfg.kube2sky.extraOpts}
|
${cfg.dns.extraOpts}
|
||||||
'';
|
'';
|
||||||
|
WorkingDirectory = cfg.dataDir;
|
||||||
User = "kubernetes";
|
User = "kubernetes";
|
||||||
|
Group = "kubernetes";
|
||||||
|
AmbientCapabilities = "cap_net_bind_service";
|
||||||
|
SendSIGHUP = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
|
||||||
|
(mkIf cfg.kubelet.enable {
|
||||||
|
boot.kernelModules = ["br_netfilter"];
|
||||||
|
})
|
||||||
|
|
||||||
(mkIf (any (el: el == "master") cfg.roles) {
|
(mkIf (any (el: el == "master") cfg.roles) {
|
||||||
|
virtualisation.docker.enable = mkDefault true;
|
||||||
|
services.kubernetes.kubelet.enable = mkDefault true;
|
||||||
|
services.kubernetes.kubelet.allowPrivileged = mkDefault true;
|
||||||
services.kubernetes.apiserver.enable = mkDefault true;
|
services.kubernetes.apiserver.enable = mkDefault true;
|
||||||
services.kubernetes.scheduler.enable = mkDefault true;
|
services.kubernetes.scheduler.enable = mkDefault true;
|
||||||
services.kubernetes.controllerManager.enable = mkDefault true;
|
services.kubernetes.controllerManager.enable = mkDefault true;
|
||||||
services.kubernetes.kube2sky.enable = mkDefault true;
|
services.etcd.enable = mkDefault (cfg.etcd.servers == ["http://127.0.0.1:2379"]);
|
||||||
})
|
})
|
||||||
|
|
||||||
(mkIf (any (el: el == "node") cfg.roles) {
|
(mkIf (any (el: el == "node") cfg.roles) {
|
||||||
virtualisation.docker.enable = mkDefault true;
|
virtualisation.docker.enable = mkDefault true;
|
||||||
|
virtualisation.docker.logDriver = mkDefault "json-file";
|
||||||
services.kubernetes.kubelet.enable = mkDefault true;
|
services.kubernetes.kubelet.enable = mkDefault true;
|
||||||
services.kubernetes.proxy.enable = mkDefault true;
|
services.kubernetes.proxy.enable = mkDefault true;
|
||||||
})
|
services.kubernetes.dns.enable = mkDefault true;
|
||||||
|
|
||||||
(mkIf (any (el: el == "node" || el == "master") cfg.roles) {
|
|
||||||
services.etcd.enable = mkDefault true;
|
|
||||||
|
|
||||||
services.skydns.enable = mkDefault true;
|
|
||||||
services.skydns.domain = mkDefault cfg.kubelet.clusterDomain;
|
|
||||||
})
|
})
|
||||||
|
|
||||||
(mkIf (
|
(mkIf (
|
||||||
@ -601,24 +830,16 @@ in {
|
|||||||
cfg.scheduler.enable ||
|
cfg.scheduler.enable ||
|
||||||
cfg.controllerManager.enable ||
|
cfg.controllerManager.enable ||
|
||||||
cfg.kubelet.enable ||
|
cfg.kubelet.enable ||
|
||||||
cfg.proxy.enable
|
cfg.proxy.enable ||
|
||||||
|
cfg.dns.enable
|
||||||
) {
|
) {
|
||||||
systemd.services.kubernetes-setup = {
|
systemd.tmpfiles.rules = [
|
||||||
description = "Kubernetes setup.";
|
"d /opt/cni/bin 0755 root root -"
|
||||||
serviceConfig.Type = "oneshot";
|
"d /var/run/kubernetes 0755 kubernetes kubernetes -"
|
||||||
script = ''
|
"d /var/lib/kubernetes 0755 kubernetes kubernetes -"
|
||||||
mkdir -p /var/run/kubernetes
|
];
|
||||||
chown kubernetes /var/lib/kubernetes
|
|
||||||
|
|
||||||
rm ${cfg.dataDir}/.dockercfg || true
|
|
||||||
ln -fs ${pkgs.writeText "kubernetes-dockercfg" cfg.dockerCfg} ${cfg.dataDir}/.dockercfg
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
services.kubernetes.package = mkDefault pkgs.kubernetes;
|
|
||||||
|
|
||||||
environment.systemPackages = [ cfg.package ];
|
environment.systemPackages = [ cfg.package ];
|
||||||
|
|
||||||
users.extraUsers = singleton {
|
users.extraUsers = singleton {
|
||||||
name = "kubernetes";
|
name = "kubernetes";
|
||||||
uid = config.ids.uids.kubernetes;
|
uid = config.ids.uids.kubernetes;
|
||||||
@ -630,6 +851,5 @@ in {
|
|||||||
};
|
};
|
||||||
users.extraGroups.kubernetes.gid = config.ids.gids.kubernetes;
|
users.extraGroups.kubernetes.gid = config.ids.gids.kubernetes;
|
||||||
})
|
})
|
||||||
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ in {
|
|||||||
|
|
||||||
fleetctlEndpoint = mkOption {
|
fleetctlEndpoint = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "http://127.0.0.1:4001";
|
default = "http://127.0.0.1:2379";
|
||||||
description = ''
|
description = ''
|
||||||
Panamax fleetctl endpoint.
|
Panamax fleetctl endpoint.
|
||||||
'';
|
'';
|
||||||
|
88
nixos/modules/services/computing/boinc/client.nix
Normal file
88
nixos/modules/services/computing/boinc/client.nix
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
{config, lib, pkgs, ...}:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.boinc;
|
||||||
|
allowRemoteGuiRpcFlag = optionalString cfg.allowRemoteGuiRpc "--allow_remote_gui_rpc";
|
||||||
|
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.services.boinc = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
example = true;
|
||||||
|
description = ''
|
||||||
|
Whether to enable the BOINC distributed computing client. If this
|
||||||
|
option is set to true, the boinc_client daemon will be run as a
|
||||||
|
background service. The boinccmd command can be used to control the
|
||||||
|
daemon.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
package = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = pkgs.boinc;
|
||||||
|
defaultText = "pkgs.boinc";
|
||||||
|
description = ''
|
||||||
|
Which BOINC package to use.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
dataDir = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
default = "/var/lib/boinc";
|
||||||
|
description = ''
|
||||||
|
The directory in which to store BOINC's configuration and data files.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
allowRemoteGuiRpc = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
example = true;
|
||||||
|
description = ''
|
||||||
|
If set to true, any remote host can connect to and control this BOINC
|
||||||
|
client (subject to password authentication). If instead set to false,
|
||||||
|
only the hosts listed in <varname>dataDir</varname>/remote_hosts.cfg will be allowed to
|
||||||
|
connect.
|
||||||
|
|
||||||
|
See also: <link xlink:href="http://boinc.berkeley.edu/wiki/Controlling_BOINC_remotely#Remote_access"/>
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
environment.systemPackages = [cfg.package];
|
||||||
|
|
||||||
|
users.users.boinc = {
|
||||||
|
createHome = false;
|
||||||
|
description = "BOINC Client";
|
||||||
|
home = cfg.dataDir;
|
||||||
|
isSystemUser = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.boinc = {
|
||||||
|
description = "BOINC Client";
|
||||||
|
after = ["network.target" "local-fs.target"];
|
||||||
|
wantedBy = ["multi-user.target"];
|
||||||
|
preStart = ''
|
||||||
|
mkdir -p ${cfg.dataDir}
|
||||||
|
chown boinc ${cfg.dataDir}
|
||||||
|
'';
|
||||||
|
script = ''
|
||||||
|
${cfg.package}/bin/boinc_client --dir ${cfg.dataDir} --redirectio ${allowRemoteGuiRpcFlag}
|
||||||
|
'';
|
||||||
|
serviceConfig = {
|
||||||
|
PermissionsStartOnly = true; # preStart must be run as root
|
||||||
|
User = "boinc";
|
||||||
|
Nice = 10;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
maintainers = with lib.maintainers; [kierdavis];
|
||||||
|
};
|
||||||
|
}
|
@ -0,0 +1,250 @@
|
|||||||
|
# NixOS module for Buildbot continous integration server.
|
||||||
|
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.buildbot-master;
|
||||||
|
escapeStr = s: escape ["'"] s;
|
||||||
|
masterCfg = pkgs.writeText "master.cfg" ''
|
||||||
|
from buildbot.plugins import *
|
||||||
|
factory = util.BuildFactory()
|
||||||
|
c = BuildmasterConfig = dict(
|
||||||
|
workers = [${concatStringsSep "," cfg.workers}],
|
||||||
|
protocols = { 'pb': {'port': ${cfg.bpPort} } },
|
||||||
|
title = '${escapeStr cfg.title}',
|
||||||
|
titleURL = '${escapeStr cfg.titleUrl}',
|
||||||
|
buildbotURL = '${escapeStr cfg.buildbotUrl}',
|
||||||
|
db = dict(db_url='${escapeStr cfg.dbUrl}'),
|
||||||
|
www = dict(port=${toString cfg.port}),
|
||||||
|
change_source = [ ${concatStringsSep "," cfg.changeSource} ],
|
||||||
|
schedulers = [ ${concatStringsSep "," cfg.schedulers} ],
|
||||||
|
builders = [ ${concatStringsSep "," cfg.builders} ],
|
||||||
|
status = [ ${concatStringsSep "," cfg.status} ],
|
||||||
|
)
|
||||||
|
for step in [ ${concatStringsSep "," cfg.factorySteps} ]:
|
||||||
|
factory.addStep(step)
|
||||||
|
|
||||||
|
${cfg.extraConfig}
|
||||||
|
'';
|
||||||
|
|
||||||
|
configFile = if cfg.masterCfg == null then masterCfg else cfg.masterCfg;
|
||||||
|
|
||||||
|
in {
|
||||||
|
options = {
|
||||||
|
services.buildbot-master = {
|
||||||
|
|
||||||
|
factorySteps = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
description = "Factory Steps";
|
||||||
|
default = [];
|
||||||
|
example = [
|
||||||
|
"steps.Git(repourl='git://github.com/buildbot/pyflakes.git', mode='incremental')"
|
||||||
|
"steps.ShellCommand(command=['trial', 'pyflakes'])"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
changeSource = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
description = "List of Change Sources.";
|
||||||
|
default = [];
|
||||||
|
example = [
|
||||||
|
"changes.GitPoller('git://github.com/buildbot/pyflakes.git', workdir='gitpoller-workdir', branch='master', pollinterval=300)"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Whether to enable the Buildbot continuous integration server.";
|
||||||
|
};
|
||||||
|
|
||||||
|
extraConfig = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "Extra configuration to append to master.cfg";
|
||||||
|
default = "";
|
||||||
|
};
|
||||||
|
|
||||||
|
masterCfg = mkOption {
|
||||||
|
type = with types; nullOr path;
|
||||||
|
description = ''
|
||||||
|
Optionally pass path to raw master.cfg file.
|
||||||
|
Other options in this configuration will be ignored.
|
||||||
|
'';
|
||||||
|
default = null;
|
||||||
|
example = literalExample ''
|
||||||
|
pkgs.writeText "master.cfg" "BuildmasterConfig = c = {}"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
schedulers = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
description = "List of Schedulers.";
|
||||||
|
default = [
|
||||||
|
"schedulers.SingleBranchScheduler(name='all', change_filter=util.ChangeFilter(branch='master'), treeStableTimer=None, builderNames=['runtests'])"
|
||||||
|
"schedulers.ForceScheduler(name='force',builderNames=['runtests'])"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
builders = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
description = "List of Builders.";
|
||||||
|
default = [
|
||||||
|
"util.BuilderConfig(name='runtests',workernames=['default-worker'],factory=factory)"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
workers = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
description = "List of Workers.";
|
||||||
|
default = [
|
||||||
|
"worker.Worker('default-worker', 'password')"
|
||||||
|
];
|
||||||
|
example = [ "worker.LocalWorker('default-worker')" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
status = mkOption {
|
||||||
|
default = [];
|
||||||
|
type = types.listOf types.str;
|
||||||
|
description = "List of status notification endpoints.";
|
||||||
|
};
|
||||||
|
|
||||||
|
user = mkOption {
|
||||||
|
default = "buildbot";
|
||||||
|
type = types.str;
|
||||||
|
description = "User the buildbot server should execute under.";
|
||||||
|
};
|
||||||
|
|
||||||
|
group = mkOption {
|
||||||
|
default = "buildbot";
|
||||||
|
type = types.str;
|
||||||
|
description = "Primary group of buildbot user.";
|
||||||
|
};
|
||||||
|
|
||||||
|
extraGroups = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ "nixbld" ];
|
||||||
|
description = "List of extra groups that the buildbot user should be a part of.";
|
||||||
|
};
|
||||||
|
|
||||||
|
home = mkOption {
|
||||||
|
default = "/home/buildbot";
|
||||||
|
type = types.path;
|
||||||
|
description = "Buildbot home directory.";
|
||||||
|
};
|
||||||
|
|
||||||
|
buildbotDir = mkOption {
|
||||||
|
default = "${cfg.home}/master";
|
||||||
|
type = types.path;
|
||||||
|
description = "Specifies the Buildbot directory.";
|
||||||
|
};
|
||||||
|
|
||||||
|
bpPort = mkOption {
|
||||||
|
default = "9989";
|
||||||
|
type = types.string;
|
||||||
|
example = "tcp:10000:interface=127.0.0.1";
|
||||||
|
description = "Port where the master will listen to Buildbot Worker.";
|
||||||
|
};
|
||||||
|
|
||||||
|
listenAddress = mkOption {
|
||||||
|
default = "0.0.0.0";
|
||||||
|
type = types.str;
|
||||||
|
description = "Specifies the bind address on which the buildbot HTTP interface listens.";
|
||||||
|
};
|
||||||
|
|
||||||
|
buildbotUrl = mkOption {
|
||||||
|
default = "http://localhost:8010/";
|
||||||
|
type = types.str;
|
||||||
|
description = "Specifies the Buildbot URL.";
|
||||||
|
};
|
||||||
|
|
||||||
|
title = mkOption {
|
||||||
|
default = "Buildbot";
|
||||||
|
type = types.str;
|
||||||
|
description = "Specifies the Buildbot Title.";
|
||||||
|
};
|
||||||
|
|
||||||
|
titleUrl = mkOption {
|
||||||
|
default = "Buildbot";
|
||||||
|
type = types.str;
|
||||||
|
description = "Specifies the Buildbot TitleURL.";
|
||||||
|
};
|
||||||
|
|
||||||
|
dbUrl = mkOption {
|
||||||
|
default = "sqlite:///state.sqlite";
|
||||||
|
type = types.str;
|
||||||
|
description = "Specifies the database connection string.";
|
||||||
|
};
|
||||||
|
|
||||||
|
port = mkOption {
|
||||||
|
default = 8010;
|
||||||
|
type = types.int;
|
||||||
|
description = "Specifies port number on which the buildbot HTTP interface listens.";
|
||||||
|
};
|
||||||
|
|
||||||
|
package = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = pkgs.buildbot-ui;
|
||||||
|
description = ''
|
||||||
|
Package to use for buildbot.
|
||||||
|
<literal>buildbot-full</literal> is required in order to use local workers.
|
||||||
|
'';
|
||||||
|
example = pkgs.buildbot-full;
|
||||||
|
};
|
||||||
|
|
||||||
|
packages = mkOption {
|
||||||
|
default = [ ];
|
||||||
|
example = [ pkgs.git ];
|
||||||
|
type = types.listOf types.package;
|
||||||
|
description = "Packages to add to PATH for the buildbot process.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
users.extraGroups = optional (cfg.group == "buildbot") {
|
||||||
|
name = "buildbot";
|
||||||
|
};
|
||||||
|
|
||||||
|
users.extraUsers = optional (cfg.user == "buildbot") {
|
||||||
|
name = "buildbot";
|
||||||
|
description = "buildbot user";
|
||||||
|
isNormalUser = true;
|
||||||
|
createHome = true;
|
||||||
|
home = cfg.home;
|
||||||
|
group = cfg.group;
|
||||||
|
extraGroups = cfg.extraGroups;
|
||||||
|
useDefaultShell = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.buildbot-master = {
|
||||||
|
description = "Buildbot Continuous Integration Server";
|
||||||
|
after = [ "network.target" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
path = cfg.packages;
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "forking";
|
||||||
|
User = cfg.user;
|
||||||
|
Group = cfg.group;
|
||||||
|
WorkingDirectory = cfg.home;
|
||||||
|
ExecStart = "${cfg.package}/bin/buildbot start ${cfg.buildbotDir}";
|
||||||
|
};
|
||||||
|
|
||||||
|
preStart = ''
|
||||||
|
mkdir -vp ${cfg.buildbotDir}
|
||||||
|
chown -c ${cfg.user}:${cfg.group} ${cfg.buildbotDir}
|
||||||
|
ln -sf ${configFile} ${cfg.buildbotDir}/master.cfg
|
||||||
|
${cfg.package}/bin/buildbot create-master ${cfg.buildbotDir}
|
||||||
|
'';
|
||||||
|
|
||||||
|
postStart = ''
|
||||||
|
until [[ $(${pkgs.curl}/bin/curl -s --head -w '\n%{http_code}' http://localhost:${toString cfg.port} | tail -n1) =~ ^(200|403)$ ]]; do
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -37,6 +37,7 @@ in {
|
|||||||
|
|
||||||
packages = mkOption {
|
packages = mkOption {
|
||||||
default = [ pkgs.stdenv pkgs.jre pkgs.git config.programs.ssh.package pkgs.nix ];
|
default = [ pkgs.stdenv pkgs.jre pkgs.git config.programs.ssh.package pkgs.nix ];
|
||||||
|
defaultText = "[ pkgs.stdenv pkgs.jre pkgs.git config.programs.ssh.package pkgs.nix ]";
|
||||||
type = types.listOf types.package;
|
type = types.listOf types.package;
|
||||||
description = ''
|
description = ''
|
||||||
Packages to add to PATH for the Go.CD agent process.
|
Packages to add to PATH for the Go.CD agent process.
|
||||||
|
@ -68,6 +68,7 @@ in {
|
|||||||
|
|
||||||
packages = mkOption {
|
packages = mkOption {
|
||||||
default = [ pkgs.stdenv pkgs.jre pkgs.git config.programs.ssh.package pkgs.nix ];
|
default = [ pkgs.stdenv pkgs.jre pkgs.git config.programs.ssh.package pkgs.nix ];
|
||||||
|
defaultText = "[ pkgs.stdenv pkgs.jre pkgs.git config.programs.ssh.package pkgs.nix ]";
|
||||||
type = types.listOf types.package;
|
type = types.listOf types.package;
|
||||||
description = ''
|
description = ''
|
||||||
Packages to add to PATH for the Go.CD server's process.
|
Packages to add to PATH for the Go.CD server's process.
|
||||||
|
@ -343,7 +343,7 @@ in
|
|||||||
{ wantedBy = [ "multi-user.target" ];
|
{ wantedBy = [ "multi-user.target" ];
|
||||||
requires = [ "hydra-init.service" ];
|
requires = [ "hydra-init.service" ];
|
||||||
after = [ "hydra-init.service" "network.target" ];
|
after = [ "hydra-init.service" "network.target" ];
|
||||||
path = [ pkgs.nettools ];
|
path = [ cfg.package pkgs.nettools ];
|
||||||
environment = env;
|
environment = env;
|
||||||
serviceConfig =
|
serviceConfig =
|
||||||
{ ExecStart = "@${cfg.package}/bin/hydra-evaluator hydra-evaluator";
|
{ ExecStart = "@${cfg.package}/bin/hydra-evaluator hydra-evaluator";
|
||||||
|
@ -162,7 +162,7 @@ in {
|
|||||||
|
|
||||||
if [ "$(id -u)" = 0 ]; then
|
if [ "$(id -u)" = 0 ]; then
|
||||||
chown ${cfg.user}:${cfg.group} `dirname ${cfg.uriFile}`;
|
chown ${cfg.user}:${cfg.group} `dirname ${cfg.uriFile}`;
|
||||||
(-f ${cfg.uriFile} && chown ${cfg.user}:${cfg.group} ${cfg.uriFile}) || true
|
(test -f ${cfg.uriFile} && chown ${cfg.user}:${cfg.group} ${cfg.uriFile}) || true
|
||||||
chown ${cfg.user}:${cfg.group} ${cfg.databaseDir}
|
chown ${cfg.user}:${cfg.group} ${cfg.databaseDir}
|
||||||
chown ${cfg.user}:${cfg.group} ${cfg.viewIndexDir}
|
chown ${cfg.user}:${cfg.group} ${cfg.viewIndexDir}
|
||||||
chown ${cfg.user}:${cfg.group} ${cfg.configFile}
|
chown ${cfg.user}:${cfg.group} ${cfg.configFile}
|
||||||
|
@ -52,9 +52,7 @@ in
|
|||||||
|
|
||||||
package = mkOption {
|
package = mkOption {
|
||||||
type = types.package;
|
type = types.package;
|
||||||
default = pkgs.mysql;
|
example = literalExample "pkgs.mysql";
|
||||||
defaultText = "pkgs.mysql";
|
|
||||||
example = literalExample "pkgs.mysql55";
|
|
||||||
description = "
|
description = "
|
||||||
Which MySQL derivation to use.
|
Which MySQL derivation to use.
|
||||||
";
|
";
|
||||||
|
202
nixos/modules/services/databases/riak-cs.nix
Normal file
202
nixos/modules/services/databases/riak-cs.nix
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.services.riak-cs;
|
||||||
|
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
###### interface
|
||||||
|
|
||||||
|
options = {
|
||||||
|
|
||||||
|
services.riak-cs = {
|
||||||
|
|
||||||
|
enable = mkEnableOption "riak-cs";
|
||||||
|
|
||||||
|
package = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = pkgs.riak-cs;
|
||||||
|
defaultText = "pkgs.riak-cs";
|
||||||
|
example = literalExample "pkgs.riak-cs";
|
||||||
|
description = ''
|
||||||
|
Riak package to use.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
nodeName = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "riak-cs@127.0.0.1";
|
||||||
|
description = ''
|
||||||
|
Name of the Erlang node.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
anonymousUserCreation = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Anonymous user creation.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
riakHost = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "127.0.0.1:8087";
|
||||||
|
description = ''
|
||||||
|
Name of riak hosting service.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
listener = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "127.0.0.1:8080";
|
||||||
|
description = ''
|
||||||
|
Name of Riak CS listening service.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
stanchionHost = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "127.0.0.1:8085";
|
||||||
|
description = ''
|
||||||
|
Name of stanchion hosting service.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
stanchionSsl = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = ''
|
||||||
|
Tell stanchion to use SSL.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
distributedCookie = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "riak";
|
||||||
|
description = ''
|
||||||
|
Cookie for distributed node communication. All nodes in the
|
||||||
|
same cluster should use the same cookie or they will not be able to
|
||||||
|
communicate.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
dataDir = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
default = "/var/db/riak-cs";
|
||||||
|
description = ''
|
||||||
|
Data directory for Riak CS.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
logDir = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
default = "/var/log/riak-cs";
|
||||||
|
description = ''
|
||||||
|
Log directory for Riak CS.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
extraConfig = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
default = "";
|
||||||
|
description = ''
|
||||||
|
Additional text to be appended to <filename>riak-cs.conf</filename>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
extraAdvancedConfig = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
default = "";
|
||||||
|
description = ''
|
||||||
|
Additional text to be appended to <filename>advanced.config</filename>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
###### implementation
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
|
||||||
|
environment.systemPackages = [ cfg.package ];
|
||||||
|
environment.etc."riak-cs/riak-cs.conf".text = ''
|
||||||
|
nodename = ${cfg.nodeName}
|
||||||
|
distributed_cookie = ${cfg.distributedCookie}
|
||||||
|
|
||||||
|
platform_log_dir = ${cfg.logDir}
|
||||||
|
|
||||||
|
riak_host = ${cfg.riakHost}
|
||||||
|
listener = ${cfg.listener}
|
||||||
|
stanchion_host = ${cfg.stanchionHost}
|
||||||
|
|
||||||
|
anonymous_user_creation = ${if cfg.anonymousUserCreation then "on" else "off"}
|
||||||
|
|
||||||
|
${cfg.extraConfig}
|
||||||
|
'';
|
||||||
|
|
||||||
|
environment.etc."riak-cs/advanced.config".text = ''
|
||||||
|
${cfg.extraAdvancedConfig}
|
||||||
|
'';
|
||||||
|
|
||||||
|
users.extraUsers.riak-cs = {
|
||||||
|
name = "riak-cs";
|
||||||
|
uid = config.ids.uids.riak-cs;
|
||||||
|
group = "riak";
|
||||||
|
description = "Riak CS server user";
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.riak-cs = {
|
||||||
|
description = "Riak CS Server";
|
||||||
|
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
after = [ "network.target" ];
|
||||||
|
|
||||||
|
path = [
|
||||||
|
pkgs.utillinux # for `logger`
|
||||||
|
pkgs.bash
|
||||||
|
];
|
||||||
|
|
||||||
|
environment.HOME = "${cfg.dataDir}";
|
||||||
|
environment.RIAK_CS_DATA_DIR = "${cfg.dataDir}";
|
||||||
|
environment.RIAK_CS_LOG_DIR = "${cfg.logDir}";
|
||||||
|
environment.RIAK_CS_ETC_DIR = "/etc/riak";
|
||||||
|
|
||||||
|
preStart = ''
|
||||||
|
if ! test -e ${cfg.logDir}; then
|
||||||
|
mkdir -m 0755 -p ${cfg.logDir}
|
||||||
|
chown -R riak-cs ${cfg.logDir}
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! test -e ${cfg.dataDir}; then
|
||||||
|
mkdir -m 0700 -p ${cfg.dataDir}
|
||||||
|
chown -R riak-cs ${cfg.dataDir}
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = "${cfg.package}/bin/riak-cs console";
|
||||||
|
ExecStop = "${cfg.package}/bin/riak-cs stop";
|
||||||
|
StandardInput = "tty";
|
||||||
|
User = "riak-cs";
|
||||||
|
Group = "riak-cs";
|
||||||
|
PermissionsStartOnly = true;
|
||||||
|
# Give Riak a decent amount of time to clean up.
|
||||||
|
TimeoutStopSec = 120;
|
||||||
|
LimitNOFILE = 65536;
|
||||||
|
};
|
||||||
|
|
||||||
|
unitConfig.RequiresMountsFor = [
|
||||||
|
"${cfg.dataDir}"
|
||||||
|
"${cfg.logDir}"
|
||||||
|
"/etc/riak"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
@ -20,6 +20,8 @@ in
|
|||||||
|
|
||||||
package = mkOption {
|
package = mkOption {
|
||||||
type = types.package;
|
type = types.package;
|
||||||
|
default = pkgs.riak;
|
||||||
|
defaultText = "pkgs.riak";
|
||||||
example = literalExample "pkgs.riak";
|
example = literalExample "pkgs.riak";
|
||||||
description = ''
|
description = ''
|
||||||
Riak package to use.
|
Riak package to use.
|
||||||
@ -68,6 +70,14 @@ in
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extraAdvancedConfig = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
default = "";
|
||||||
|
description = ''
|
||||||
|
Additional text to be appended to <filename>advanced.config</filename>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -88,6 +98,10 @@ in
|
|||||||
${cfg.extraConfig}
|
${cfg.extraConfig}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
environment.etc."riak/advanced.config".text = ''
|
||||||
|
${cfg.extraAdvancedConfig}
|
||||||
|
'';
|
||||||
|
|
||||||
users.extraUsers.riak = {
|
users.extraUsers.riak = {
|
||||||
name = "riak";
|
name = "riak";
|
||||||
uid = config.ids.uids.riak;
|
uid = config.ids.uids.riak;
|
||||||
|
212
nixos/modules/services/databases/stanchion.nix
Normal file
212
nixos/modules/services/databases/stanchion.nix
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.services.stanchion;
|
||||||
|
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
###### interface
|
||||||
|
|
||||||
|
options = {
|
||||||
|
|
||||||
|
services.stanchion = {
|
||||||
|
|
||||||
|
enable = mkEnableOption "stanchion";
|
||||||
|
|
||||||
|
package = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = pkgs.stanchion;
|
||||||
|
defaultText = "pkgs.stanchion";
|
||||||
|
example = literalExample "pkgs.stanchion";
|
||||||
|
description = ''
|
||||||
|
Stanchion package to use.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
nodeName = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "stanchion@127.0.0.1";
|
||||||
|
description = ''
|
||||||
|
Name of the Erlang node.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
adminKey = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "";
|
||||||
|
description = ''
|
||||||
|
Name of admin user.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
adminSecret = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "";
|
||||||
|
description = ''
|
||||||
|
Name of admin secret
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
riakHost = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "127.0.0.1:8087";
|
||||||
|
description = ''
|
||||||
|
Name of riak hosting service.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
listener = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "127.0.0.1:8085";
|
||||||
|
description = ''
|
||||||
|
Name of Riak CS listening service.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
stanchionHost = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "127.0.0.1:8085";
|
||||||
|
description = ''
|
||||||
|
Name of stanchion hosting service.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
stanchionSsl = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = ''
|
||||||
|
Tell stanchion to use SSL.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
distributedCookie = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "riak";
|
||||||
|
description = ''
|
||||||
|
Cookie for distributed node communication. All nodes in the
|
||||||
|
same cluster should use the same cookie or they will not be able to
|
||||||
|
communicate.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
dataDir = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
default = "/var/db/stanchion";
|
||||||
|
description = ''
|
||||||
|
Data directory for Stanchion.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
logDir = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
default = "/var/log/stanchion";
|
||||||
|
description = ''
|
||||||
|
Log directory for Stanchino.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
extraConfig = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
default = "";
|
||||||
|
description = ''
|
||||||
|
Additional text to be appended to <filename>stanchion.conf</filename>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
###### implementation
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
|
||||||
|
environment.systemPackages = [ cfg.package ];
|
||||||
|
|
||||||
|
environment.etc."stanchion/advanced.config".text = ''
|
||||||
|
[{stanchion, []}].
|
||||||
|
'';
|
||||||
|
|
||||||
|
environment.etc."stanchion/stanchion.conf".text = ''
|
||||||
|
listener = ${cfg.listener}
|
||||||
|
|
||||||
|
riak_host = ${cfg.riakHost}
|
||||||
|
|
||||||
|
${optionalString (cfg.adminKey == "") "#"} admin.key=${optionalString (cfg.adminKey != "") cfg.adminKey}
|
||||||
|
${optionalString (cfg.adminSecret == "") "#"} admin.secret=${optionalString (cfg.adminSecret != "") cfg.adminSecret}
|
||||||
|
|
||||||
|
platform_bin_dir = ${pkgs.stanchion}/bin
|
||||||
|
platform_data_dir = ${cfg.dataDir}
|
||||||
|
platform_etc_dir = /etc/stanchion
|
||||||
|
platform_lib_dir = ${pkgs.stanchion}/lib
|
||||||
|
platform_log_dir = ${cfg.logDir}
|
||||||
|
|
||||||
|
nodename = ${cfg.nodeName}
|
||||||
|
|
||||||
|
distributed_cookie = ${cfg.distributedCookie}
|
||||||
|
|
||||||
|
stanchion_ssl=${if cfg.stanchionSsl then "on" else "off"}
|
||||||
|
|
||||||
|
${cfg.extraConfig}
|
||||||
|
'';
|
||||||
|
|
||||||
|
users.extraUsers.stanchion = {
|
||||||
|
name = "stanchion";
|
||||||
|
uid = config.ids.uids.stanchion;
|
||||||
|
group = "stanchion";
|
||||||
|
description = "Stanchion server user";
|
||||||
|
};
|
||||||
|
|
||||||
|
users.extraGroups.stanchion.gid = config.ids.gids.stanchion;
|
||||||
|
|
||||||
|
systemd.services.stanchion = {
|
||||||
|
description = "Stanchion Server";
|
||||||
|
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
after = [ "network.target" ];
|
||||||
|
|
||||||
|
path = [
|
||||||
|
pkgs.utillinux # for `logger`
|
||||||
|
pkgs.bash
|
||||||
|
];
|
||||||
|
|
||||||
|
environment.HOME = "${cfg.dataDir}";
|
||||||
|
environment.STANCHION_DATA_DIR = "${cfg.dataDir}";
|
||||||
|
environment.STANCHION_LOG_DIR = "${cfg.logDir}";
|
||||||
|
environment.STANCHION_ETC_DIR = "/etc/stanchion";
|
||||||
|
|
||||||
|
preStart = ''
|
||||||
|
if ! test -e ${cfg.logDir}; then
|
||||||
|
mkdir -m 0755 -p ${cfg.logDir}
|
||||||
|
chown -R stanchion:stanchion ${cfg.logDir}
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! test -e ${cfg.dataDir}; then
|
||||||
|
mkdir -m 0700 -p ${cfg.dataDir}
|
||||||
|
chown -R stanchion:stanchion ${cfg.dataDir}
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = "${cfg.package}/bin/stanchion console";
|
||||||
|
ExecStop = "${cfg.package}/bin/stanchion stop";
|
||||||
|
StandardInput = "tty";
|
||||||
|
User = "stanchion";
|
||||||
|
Group = "stanchion";
|
||||||
|
PermissionsStartOnly = true;
|
||||||
|
# Give Stanchion a decent amount of time to clean up.
|
||||||
|
TimeoutStopSec = 120;
|
||||||
|
LimitNOFILE = 65536;
|
||||||
|
};
|
||||||
|
|
||||||
|
unitConfig.RequiresMountsFor = [
|
||||||
|
"${cfg.dataDir}"
|
||||||
|
"${cfg.logDir}"
|
||||||
|
"/etc/stanchion"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
@ -86,6 +86,12 @@ in {
|
|||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
|
assertions = [
|
||||||
|
{ assertion = cfg.users != [];
|
||||||
|
message = "services.psd.users must contain at least one user";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
systemd = {
|
systemd = {
|
||||||
services = {
|
services = {
|
||||||
psd = {
|
psd = {
|
||||||
|
158
nixos/modules/services/editors/infinoted.nix
Normal file
158
nixos/modules/services/editors/infinoted.nix
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.infinoted;
|
||||||
|
in {
|
||||||
|
options.services.infinoted = {
|
||||||
|
enable = mkEnableOption "infinoted";
|
||||||
|
|
||||||
|
package = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = pkgs.libinfinity.override { daemon = true; };
|
||||||
|
defaultText = "pkgs.libinfinity.override { daemon = true; }";
|
||||||
|
description = ''
|
||||||
|
Package providing infinoted
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
keyFile = mkOption {
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Private key to use for TLS
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
certificateFile = mkOption {
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Server certificate to use for TLS
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
certificateChain = mkOption {
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Chain of CA-certificates to which our `certificateFile` is relative.
|
||||||
|
Optional for TLS.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
securityPolicy = mkOption {
|
||||||
|
type = types.enum ["no-tls" "allow-tls" "require-tls"];
|
||||||
|
default = "require-tls";
|
||||||
|
description = ''
|
||||||
|
How strictly to enforce clients connection with TLS.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
port = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = 6523;
|
||||||
|
description = ''
|
||||||
|
Port to listen on
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
rootDirectory = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
default = "/var/lib/infinoted/documents/";
|
||||||
|
description = ''
|
||||||
|
Root of the directory structure to serve
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
plugins = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ "note-text" "note-chat" "logging" "autosave" ];
|
||||||
|
description = ''
|
||||||
|
Plugins to enable
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
passwordFile = mkOption {
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
File to read server-wide password from
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
extraConfig = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
default = ''
|
||||||
|
[autosave]
|
||||||
|
interval=10
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
Additional configuration to append to infinoted.conf
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
user = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "infinoted";
|
||||||
|
description = ''
|
||||||
|
What to call the dedicated user under which infinoted is run
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
group = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "infinoted";
|
||||||
|
description = ''
|
||||||
|
What to call the primary group of the dedicated user under which infinoted is run
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf (cfg.enable) {
|
||||||
|
users.extraUsers = optional (cfg.user == "infinoted")
|
||||||
|
{ name = "infinoted";
|
||||||
|
description = "Infinoted user";
|
||||||
|
group = cfg.group;
|
||||||
|
};
|
||||||
|
users.extraGroups = optional (cfg.group == "infinoted")
|
||||||
|
{ name = "infinoted";
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.infinoted =
|
||||||
|
{ description = "Gobby Dedicated Server";
|
||||||
|
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
after = [ "network.target" ];
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "simple";
|
||||||
|
Restart = "always";
|
||||||
|
ExecStart = "${cfg.package}/bin/infinoted-0.6 --config-file=/var/lib/infinoted/infinoted.conf";
|
||||||
|
User = cfg.user;
|
||||||
|
Group = cfg.group;
|
||||||
|
PermissionsStartOnly = true;
|
||||||
|
};
|
||||||
|
preStart = ''
|
||||||
|
mkdir -p /var/lib/infinoted
|
||||||
|
install -o ${cfg.user} -g ${cfg.group} -m 0600 /dev/null /var/lib/infinoted/infinoted.conf
|
||||||
|
cat >>/var/lib/infinoted/infinoted.conf <<EOF
|
||||||
|
[infinoted]
|
||||||
|
${optionalString (cfg.keyFile != null) ''key-file=${cfg.keyFile}''}
|
||||||
|
${optionalString (cfg.certificateFile != null) ''certificate-file=${cfg.certificateFile}''}
|
||||||
|
${optionalString (cfg.certificateChain != null) ''certificate-chain=${cfg.certificateChain}''}
|
||||||
|
port=${toString cfg.port}
|
||||||
|
security-policy=${cfg.securityPolicy}
|
||||||
|
root-directory=${cfg.rootDirectory}
|
||||||
|
plugins=${concatStringsSep ";" cfg.plugins}
|
||||||
|
${optionalString (cfg.passwordFile != null) ''password=$(head -n 1 ${cfg.passwordFile})''}
|
||||||
|
|
||||||
|
${cfg.extraConfig}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
install -o ${cfg.user} -g ${cfg.group} -m 0750 -d ${cfg.rootDirectory}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
@ -64,7 +64,7 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
worldPath = mkOption {
|
worldPath = mkOption {
|
||||||
type = types.path;
|
type = types.nullOr types.path;
|
||||||
default = null;
|
default = null;
|
||||||
description = ''
|
description = ''
|
||||||
The path to the world file (<literal>.wld</literal>) which should be loaded.
|
The path to the world file (<literal>.wld</literal>) which should be loaded.
|
||||||
@ -126,8 +126,8 @@ in
|
|||||||
User = "terraria";
|
User = "terraria";
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
RemainAfterExit = true;
|
RemainAfterExit = true;
|
||||||
ExecStart = "${pkgs.tmux.bin}/bin/tmux -S /var/lib/terraria/terraria.sock new -d ${pkgs.terraria-server}/bin/TerrariaServer ${concatStringsSep " " flags}";
|
ExecStart = "${getBin pkgs.tmux}/bin/tmux -S /var/lib/terraria/terraria.sock new -d ${pkgs.terraria-server}/bin/TerrariaServer ${concatStringsSep " " flags}";
|
||||||
ExecStop = "${pkgs.tmux.bin}/bin/tmux -S /var/lib/terraria/terraria.sock send-keys Enter \"exit\" Enter";
|
ExecStop = "${getBin pkgs.tmux}/bin/tmux -S /var/lib/terraria/terraria.sock send-keys Enter \"exit\" Enter";
|
||||||
};
|
};
|
||||||
|
|
||||||
postStart = ''
|
postStart = ''
|
||||||
|
@ -39,6 +39,8 @@ in {
|
|||||||
ProtectSystem = "full";
|
ProtectSystem = "full";
|
||||||
SystemCallArchitectures = "native";
|
SystemCallArchitectures = "native";
|
||||||
};
|
};
|
||||||
|
wants = [ "systemd-udev-settle.service" ];
|
||||||
|
after = [ "local-fs.target" "systemd-udev-settle.service" ];
|
||||||
before = [ "sysinit.target" ];
|
before = [ "sysinit.target" ];
|
||||||
wantedBy = [ "sysinit.target" ];
|
wantedBy = [ "sysinit.target" ];
|
||||||
};
|
};
|
||||||
|
@ -7,9 +7,35 @@ let
|
|||||||
pkg = if config.hardware.sane.snapshot
|
pkg = if config.hardware.sane.snapshot
|
||||||
then pkgs.sane-backends-git
|
then pkgs.sane-backends-git
|
||||||
else pkgs.sane-backends;
|
else pkgs.sane-backends;
|
||||||
backends = [ pkg ] ++ config.hardware.sane.extraBackends;
|
|
||||||
|
sanedConf = pkgs.writeTextFile {
|
||||||
|
name = "saned.conf";
|
||||||
|
destination = "/etc/sane.d/saned.conf";
|
||||||
|
text = ''
|
||||||
|
localhost
|
||||||
|
${config.services.saned.extraConfig}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
netConf = pkgs.writeTextFile {
|
||||||
|
name = "net.conf";
|
||||||
|
destination = "/etc/sane.d/net.conf";
|
||||||
|
text = ''
|
||||||
|
${lib.optionalString config.services.saned.enable "localhost"}
|
||||||
|
${config.hardware.sane.netConf}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
env = {
|
||||||
|
SANE_CONFIG_DIR = config.hardware.sane.configDir;
|
||||||
|
LD_LIBRARY_PATH = [ "${saneConfig}/lib/sane" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
backends = [ pkg netConf ] ++ optional config.services.saned.enable sanedConf ++ config.hardware.sane.extraBackends;
|
||||||
saneConfig = pkgs.mkSaneConfig { paths = backends; };
|
saneConfig = pkgs.mkSaneConfig { paths = backends; };
|
||||||
|
|
||||||
|
enabled = config.hardware.sane.enable || config.services.saned.enable;
|
||||||
|
|
||||||
in
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -51,27 +77,86 @@ in
|
|||||||
|
|
||||||
hardware.sane.configDir = mkOption {
|
hardware.sane.configDir = mkOption {
|
||||||
type = types.string;
|
type = types.string;
|
||||||
|
internal = true;
|
||||||
description = "The value of SANE_CONFIG_DIR.";
|
description = "The value of SANE_CONFIG_DIR.";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
hardware.sane.netConf = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
default = "";
|
||||||
|
example = "192.168.0.16";
|
||||||
|
description = ''
|
||||||
|
Network hosts that should be probed for remote scanners.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
services.saned.enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Enable saned network daemon for remote connection to scanners.
|
||||||
|
|
||||||
|
saned would be runned from <literal>scanner</literal> user; to allow
|
||||||
|
access to hardware that doesn't have <literal>scanner</literal> group
|
||||||
|
you should add needed groups to this user.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
services.saned.extraConfig = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
default = "";
|
||||||
|
example = "192.168.0.0/24";
|
||||||
|
description = ''
|
||||||
|
Extra saned configuration lines.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
###### implementation
|
###### implementation
|
||||||
|
|
||||||
config = mkIf config.hardware.sane.enable {
|
config = mkMerge [
|
||||||
|
(mkIf enabled {
|
||||||
|
hardware.sane.configDir = mkDefault "${saneConfig}/etc/sane.d";
|
||||||
|
|
||||||
hardware.sane.configDir = mkDefault "${saneConfig}/etc/sane.d";
|
environment.systemPackages = backends;
|
||||||
|
environment.sessionVariables = env;
|
||||||
|
services.udev.packages = backends;
|
||||||
|
|
||||||
environment.systemPackages = backends;
|
users.extraGroups."scanner".gid = config.ids.gids.scanner;
|
||||||
environment.sessionVariables = {
|
})
|
||||||
SANE_CONFIG_DIR = config.hardware.sane.configDir;
|
|
||||||
LD_LIBRARY_PATH = [ "${saneConfig}/lib/sane" ];
|
|
||||||
};
|
|
||||||
services.udev.packages = backends;
|
|
||||||
|
|
||||||
users.extraGroups."scanner".gid = config.ids.gids.scanner;
|
(mkIf config.services.saned.enable {
|
||||||
|
networking.firewall.connectionTrackingModules = [ "sane" ];
|
||||||
|
|
||||||
};
|
systemd.services."saned@" = {
|
||||||
|
description = "Scanner Service";
|
||||||
|
environment = mapAttrs (name: val: toString val) env;
|
||||||
|
serviceConfig = {
|
||||||
|
User = "scanner";
|
||||||
|
Group = "scanner";
|
||||||
|
ExecStart = "${pkg}/bin/saned";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.sockets.saned = {
|
||||||
|
description = "saned incoming socket";
|
||||||
|
wantedBy = [ "sockets.target" ];
|
||||||
|
listenStreams = [ "0.0.0.0:6566" "[::]:6566" ];
|
||||||
|
socketConfig = {
|
||||||
|
# saned needs to distinguish between IPv4 and IPv6 to open matching data sockets.
|
||||||
|
BindIPv6Only = "ipv6-only";
|
||||||
|
Accept = true;
|
||||||
|
MaxConnections = 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
users.extraUsers."scanner" = {
|
||||||
|
uid = config.ids.uids.scanner;
|
||||||
|
group = "scanner";
|
||||||
|
};
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -100,6 +100,12 @@ in
|
|||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
|
|
||||||
|
assertions =
|
||||||
|
[ { assertion = !config.services.rsyslogd.enable;
|
||||||
|
message = "rsyslogd conflicts with syslogd";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
environment.systemPackages = [ pkgs.sysklogd ];
|
environment.systemPackages = [ pkgs.sysklogd ];
|
||||||
|
|
||||||
services.syslogd.extraParams = optional cfg.enableNetworkInput "-r";
|
services.syslogd.extraParams = optional cfg.enableNetworkInput "-r";
|
||||||
|
@ -20,17 +20,29 @@ in {
|
|||||||
description = "Whether to enable the postsrsd SRS server for Postfix.";
|
description = "Whether to enable the postsrsd SRS server for Postfix.";
|
||||||
};
|
};
|
||||||
|
|
||||||
domain = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
description = "Domain name for rewrite";
|
|
||||||
};
|
|
||||||
|
|
||||||
secretsFile = mkOption {
|
secretsFile = mkOption {
|
||||||
type = types.path;
|
type = types.path;
|
||||||
default = "/var/lib/postsrsd/postsrsd.secret";
|
default = "/var/lib/postsrsd/postsrsd.secret";
|
||||||
description = "Secret keys used for signing and verification";
|
description = "Secret keys used for signing and verification";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
domain = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "Domain name for rewrite";
|
||||||
|
};
|
||||||
|
|
||||||
|
separator = mkOption {
|
||||||
|
type = types.enum ["-" "=" "+"];
|
||||||
|
default = "=";
|
||||||
|
description = "First separator character in generated addresses";
|
||||||
|
};
|
||||||
|
|
||||||
|
# bindAddress = mkOption { # uncomment once 1.5 is released
|
||||||
|
# type = types.str;
|
||||||
|
# default = "127.0.0.1";
|
||||||
|
# description = "Socket listen address";
|
||||||
|
# };
|
||||||
|
|
||||||
forwardPort = mkOption {
|
forwardPort = mkOption {
|
||||||
type = types.int;
|
type = types.int;
|
||||||
default = 10001;
|
default = 10001;
|
||||||
@ -43,6 +55,18 @@ in {
|
|||||||
description = "Port for the reverse SRS lookup";
|
description = "Port for the reverse SRS lookup";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
timeout = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = 1800;
|
||||||
|
description = "Timeout for idle client connections in seconds";
|
||||||
|
};
|
||||||
|
|
||||||
|
excludeDomains = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
description = "Origin domains to exclude from rewriting in addition to primary domain";
|
||||||
|
};
|
||||||
|
|
||||||
user = mkOption {
|
user = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "postsrsd";
|
default = "postsrsd";
|
||||||
@ -86,7 +110,7 @@ in {
|
|||||||
path = [ pkgs.coreutils ];
|
path = [ pkgs.coreutils ];
|
||||||
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
ExecStart = ''${pkgs.postsrsd}/sbin/postsrsd "-s${cfg.secretsFile}" "-d${cfg.domain}" -f${toString cfg.forwardPort} -r${toString cfg.reversePort}'';
|
ExecStart = ''${pkgs.postsrsd}/sbin/postsrsd "-s${cfg.secretsFile}" "-d${cfg.domain}" -a${cfg.separator} -f${toString cfg.forwardPort} -r${toString cfg.reversePort} -t${toString cfg.timeout} "-X${concatStringsSep "," cfg.excludeDomains}"'';
|
||||||
User = cfg.user;
|
User = cfg.user;
|
||||||
Group = cfg.group;
|
Group = cfg.group;
|
||||||
PermissionsStartOnly = true;
|
PermissionsStartOnly = true;
|
||||||
|
@ -203,7 +203,7 @@ milter_default_action = accept
|
|||||||
PermissionsStartOnly = true;
|
PermissionsStartOnly = true;
|
||||||
Restart = "always";
|
Restart = "always";
|
||||||
RuntimeDirectory = "rmilter";
|
RuntimeDirectory = "rmilter";
|
||||||
RuntimeDirectoryPermissions="0755";
|
RuntimeDirectoryMode = "0755";
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -25,7 +25,8 @@ in
|
|||||||
DBs = mkOption {
|
DBs = mkOption {
|
||||||
type = types.listOf types.package;
|
type = types.listOf types.package;
|
||||||
default = with pkgs.dictdDBs; [ wiktionary wordnet ];
|
default = with pkgs.dictdDBs; [ wiktionary wordnet ];
|
||||||
example = [ pkgs.dictdDBs.nld2eng ];
|
defaultText = "with pkgs.dictdDBs; [ wiktionary wordnet ]";
|
||||||
|
example = literalExample "[ pkgs.dictdDBs.nld2eng ]";
|
||||||
description = ''List of databases to make available.'';
|
description = ''List of databases to make available.'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@ in
|
|||||||
type = types.path;
|
type = types.path;
|
||||||
description = "The Disnix package";
|
description = "The Disnix package";
|
||||||
default = pkgs.disnix;
|
default = pkgs.disnix;
|
||||||
|
defaultText = "pkgs.disnix";
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -164,18 +164,21 @@ in {
|
|||||||
packages.gitlab = mkOption {
|
packages.gitlab = mkOption {
|
||||||
type = types.package;
|
type = types.package;
|
||||||
default = pkgs.gitlab;
|
default = pkgs.gitlab;
|
||||||
|
defaultText = "pkgs.gitlab";
|
||||||
description = "Reference to the gitlab package";
|
description = "Reference to the gitlab package";
|
||||||
};
|
};
|
||||||
|
|
||||||
packages.gitlab-shell = mkOption {
|
packages.gitlab-shell = mkOption {
|
||||||
type = types.package;
|
type = types.package;
|
||||||
default = pkgs.gitlab-shell;
|
default = pkgs.gitlab-shell;
|
||||||
|
defaultText = "pkgs.gitlab-shell";
|
||||||
description = "Reference to the gitlab-shell package";
|
description = "Reference to the gitlab-shell package";
|
||||||
};
|
};
|
||||||
|
|
||||||
packages.gitlab-workhorse = mkOption {
|
packages.gitlab-workhorse = mkOption {
|
||||||
type = types.package;
|
type = types.package;
|
||||||
default = pkgs.gitlab-workhorse;
|
default = pkgs.gitlab-workhorse;
|
||||||
|
defaultText = "pkgs.gitlab-workhorse";
|
||||||
description = "Reference to the gitlab-workhorse package";
|
description = "Reference to the gitlab-workhorse package";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -425,7 +428,7 @@ in {
|
|||||||
TimeoutSec = "300";
|
TimeoutSec = "300";
|
||||||
Restart = "on-failure";
|
Restart = "on-failure";
|
||||||
WorkingDirectory = "${cfg.packages.gitlab}/share/gitlab";
|
WorkingDirectory = "${cfg.packages.gitlab}/share/gitlab";
|
||||||
ExecStart="${cfg.packages.gitlab.env}/bin/bundle exec \"sidekiq -q post_receive -q mailers -q system_hook -q project_web_hook -q gitlab_shell -q common -q default -e production -P ${cfg.statePath}/tmp/sidekiq.pid\"";
|
ExecStart="${cfg.packages.gitlab.env}/bin/bundle exec \"sidekiq -C \"${cfg.packages.gitlab}/share/gitlab/config/sidekiq_queues.yml\" -e production -P ${cfg.statePath}/tmp/sidekiq.pid\"";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -59,7 +59,12 @@ uploads_path: "/var/lib/matrix-synapse/uploads"
|
|||||||
max_upload_size: "${cfg.max_upload_size}"
|
max_upload_size: "${cfg.max_upload_size}"
|
||||||
max_image_pixels: "${cfg.max_image_pixels}"
|
max_image_pixels: "${cfg.max_image_pixels}"
|
||||||
dynamic_thumbnails: ${fromBool cfg.dynamic_thumbnails}
|
dynamic_thumbnails: ${fromBool cfg.dynamic_thumbnails}
|
||||||
url_preview_enabled: False
|
url_preview_enabled: ${fromBool cfg.url_preview_enabled}
|
||||||
|
${optionalString (cfg.url_preview_enabled == true) ''
|
||||||
|
url_preview_ip_range_blacklist: ${builtins.toJSON cfg.url_preview_ip_range_blacklist}
|
||||||
|
url_preview_ip_range_whitelist: ${builtins.toJSON cfg.url_preview_ip_range_whitelist}
|
||||||
|
url_preview_url_blacklist: ${builtins.toJSON cfg.url_preview_url_blacklist}
|
||||||
|
''}
|
||||||
recaptcha_private_key: "${cfg.recaptcha_private_key}"
|
recaptcha_private_key: "${cfg.recaptcha_private_key}"
|
||||||
recaptcha_public_key: "${cfg.recaptcha_public_key}"
|
recaptcha_public_key: "${cfg.recaptcha_public_key}"
|
||||||
enable_registration_captcha: ${fromBool cfg.enable_registration_captcha}
|
enable_registration_captcha: ${fromBool cfg.enable_registration_captcha}
|
||||||
@ -355,6 +360,47 @@ in {
|
|||||||
default = "10K";
|
default = "10K";
|
||||||
description = "Number of events to cache in memory.";
|
description = "Number of events to cache in memory.";
|
||||||
};
|
};
|
||||||
|
url_preview_enabled = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Is the preview URL API enabled? If enabled, you *must* specify an
|
||||||
|
explicit url_preview_ip_range_blacklist of IPs that the spider is
|
||||||
|
denied from accessing.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
url_preview_ip_range_blacklist = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
description = ''
|
||||||
|
List of IP address CIDR ranges that the URL preview spider is denied
|
||||||
|
from accessing.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
url_preview_ip_range_whitelist = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
description = ''
|
||||||
|
List of IP address CIDR ranges that the URL preview spider is allowed
|
||||||
|
to access even if they are specified in
|
||||||
|
url_preview_ip_range_blacklist.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
url_preview_url_blacklist = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [
|
||||||
|
"127.0.0.0/8"
|
||||||
|
"10.0.0.0/8"
|
||||||
|
"172.16.0.0/12"
|
||||||
|
"192.168.0.0/16"
|
||||||
|
"100.64.0.0/10"
|
||||||
|
"169.254.0.0/16"
|
||||||
|
];
|
||||||
|
description = ''
|
||||||
|
Optional list of URL matches that the URL preview spider is
|
||||||
|
denied from accessing.
|
||||||
|
'';
|
||||||
|
};
|
||||||
recaptcha_private_key = mkOption {
|
recaptcha_private_key = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "";
|
default = "";
|
||||||
|
@ -172,8 +172,8 @@ in
|
|||||||
sshKey = "/root/.ssh/id_buildfarm";
|
sshKey = "/root/.ssh/id_buildfarm";
|
||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
maxJobs = 2;
|
maxJobs = 2;
|
||||||
supportedFeatures = "kvm";
|
supportedFeatures = [ "kvm" ];
|
||||||
mandatoryFeatures = "perf";
|
mandatoryFeatures = [ "perf" ];
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
description = ''
|
description = ''
|
||||||
|
@ -6,20 +6,21 @@ let
|
|||||||
|
|
||||||
cfg = config.services.parsoid;
|
cfg = config.services.parsoid;
|
||||||
|
|
||||||
conf = ''
|
confTree = {
|
||||||
exports.setup = function( parsoidConfig ) {
|
worker_heartbeat_timeout = 300000;
|
||||||
${toString (mapAttrsToList (name: str: "parsoidConfig.setInterwiki('${name}', '${str}');") cfg.interwikis)}
|
logging = { level = "info"; };
|
||||||
|
services = [{
|
||||||
|
module = "lib/index.js";
|
||||||
|
entrypoint = "apiServiceWorker";
|
||||||
|
conf = {
|
||||||
|
mwApis = map (x: if isAttrs x then x else { uri = x; }) cfg.wikis;
|
||||||
|
serverInterface = cfg.interface;
|
||||||
|
serverPort = cfg.port;
|
||||||
|
};
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
|
||||||
parsoidConfig.serverInterface = "${cfg.interface}";
|
confFile = pkgs.writeText "config.yml" (builtins.toJSON (recursiveUpdate confTree cfg.extraConfig));
|
||||||
parsoidConfig.serverPort = ${toString cfg.port};
|
|
||||||
|
|
||||||
parsoidConfig.useSelser = true;
|
|
||||||
|
|
||||||
${cfg.extraConfig}
|
|
||||||
};
|
|
||||||
'';
|
|
||||||
|
|
||||||
confFile = builtins.toFile "localsettings.js" conf;
|
|
||||||
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
@ -38,9 +39,9 @@ in
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
interwikis = mkOption {
|
wikis = mkOption {
|
||||||
type = types.attrsOf types.str;
|
type = types.listOf (types.either types.str types.attrs);
|
||||||
example = { localhost = "http://localhost/api.php"; };
|
example = [ "http://localhost/api.php" ];
|
||||||
description = ''
|
description = ''
|
||||||
Used MediaWiki API endpoints.
|
Used MediaWiki API endpoints.
|
||||||
'';
|
'';
|
||||||
@ -71,8 +72,8 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
extraConfig = mkOption {
|
extraConfig = mkOption {
|
||||||
type = types.lines;
|
type = types.attrs;
|
||||||
default = "";
|
default = {};
|
||||||
description = ''
|
description = ''
|
||||||
Extra configuration to add to parsoid configuration.
|
Extra configuration to add to parsoid configuration.
|
||||||
'';
|
'';
|
||||||
|
@ -9,7 +9,7 @@ let
|
|||||||
BaseDir "${cfg.dataDir}"
|
BaseDir "${cfg.dataDir}"
|
||||||
PIDFile "${cfg.pidFile}"
|
PIDFile "${cfg.pidFile}"
|
||||||
AutoLoadPlugin ${if cfg.autoLoadPlugin then "true" else "false"}
|
AutoLoadPlugin ${if cfg.autoLoadPlugin then "true" else "false"}
|
||||||
Hostname ${config.networking.hostName}
|
Hostname "${config.networking.hostName}"
|
||||||
|
|
||||||
LoadPlugin syslog
|
LoadPlugin syslog
|
||||||
<Plugin "syslog">
|
<Plugin "syslog">
|
||||||
@ -108,7 +108,8 @@ in {
|
|||||||
};
|
};
|
||||||
|
|
||||||
preStart = ''
|
preStart = ''
|
||||||
mkdir -m 0700 -p ${cfg.dataDir}
|
mkdir -p ${cfg.dataDir}
|
||||||
|
chmod 755 ${cfg.dataDir}
|
||||||
install -D /dev/null ${cfg.pidFile}
|
install -D /dev/null ${cfg.pidFile}
|
||||||
if [ "$(id -u)" = 0 ]; then
|
if [ "$(id -u)" = 0 ]; then
|
||||||
chown -R ${cfg.user} ${cfg.dataDir};
|
chown -R ${cfg.user} ${cfg.dataDir};
|
||||||
|
@ -25,9 +25,16 @@ let
|
|||||||
scrape_configs = cfg.scrapeConfigs;
|
scrape_configs = cfg.scrapeConfigs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
generatedPrometheusYml = writePrettyJSON "prometheus.yml" promConfig;
|
||||||
|
|
||||||
|
prometheusYml =
|
||||||
|
if cfg.configText != null then
|
||||||
|
pkgs.writeText "prometheus.yml" cfg.configText
|
||||||
|
else generatedPrometheusYml;
|
||||||
|
|
||||||
cmdlineArgs = cfg.extraFlags ++ [
|
cmdlineArgs = cfg.extraFlags ++ [
|
||||||
"-storage.local.path=${cfg.dataDir}/metrics"
|
"-storage.local.path=${cfg.dataDir}/metrics"
|
||||||
"-config.file=${writePrettyJSON "prometheus.yml" promConfig}"
|
"-config.file=${prometheusYml}"
|
||||||
"-web.listen-address=${cfg.listenAddress}"
|
"-web.listen-address=${cfg.listenAddress}"
|
||||||
"-alertmanager.notification-queue-capacity=${toString cfg.alertmanagerNotificationQueueCapacity}"
|
"-alertmanager.notification-queue-capacity=${toString cfg.alertmanagerNotificationQueueCapacity}"
|
||||||
"-alertmanager.timeout=${toString cfg.alertmanagerTimeout}s"
|
"-alertmanager.timeout=${toString cfg.alertmanagerTimeout}s"
|
||||||
@ -359,6 +366,16 @@ in {
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
configText = mkOption {
|
||||||
|
type = types.nullOr types.lines;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
If non-null, this option defines the text that is written to
|
||||||
|
prometheus.yml. If null, the contents of prometheus.yml is generated
|
||||||
|
from the structured config options.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
globalConfig = mkOption {
|
globalConfig = mkOption {
|
||||||
type = promTypes.globalConfig;
|
type = promTypes.globalConfig;
|
||||||
default = {};
|
default = {};
|
||||||
|
@ -47,6 +47,18 @@ in
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
gatewayAddress = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "/ip4/127.0.0.1/tcp/8080";
|
||||||
|
description = "Where the IPFS Gateway can be reached";
|
||||||
|
};
|
||||||
|
|
||||||
|
apiAddress = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "/ip4/127.0.0.1/tcp/5001";
|
||||||
|
description = "Where IPFS exposes its API to";
|
||||||
|
};
|
||||||
|
|
||||||
enableGC = mkOption {
|
enableGC = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
@ -98,6 +110,8 @@ in
|
|||||||
cd ${cfg.dataDir}
|
cd ${cfg.dataDir}
|
||||||
${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c "${ipfs}/bin/ipfs init"
|
${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c "${ipfs}/bin/ipfs init"
|
||||||
fi
|
fi
|
||||||
|
${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c "${ipfs}/bin/ipfs config Addresses.API ${cfg.apiAddress}"
|
||||||
|
${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c "${ipfs}/bin/ipfs config Addresses.Gateway ${cfg.gatewayAddress}"
|
||||||
'';
|
'';
|
||||||
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
|
@ -138,6 +138,45 @@ in
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
helper.enable = mkEnableOption "helper service";
|
helper.enable = mkEnableOption "helper service";
|
||||||
|
sftpd.enable = mkEnableOption "SFTP service";
|
||||||
|
sftpd.port = mkOption {
|
||||||
|
default = null;
|
||||||
|
type = types.nullOr types.int;
|
||||||
|
description = ''
|
||||||
|
The port on which the SFTP server will listen.
|
||||||
|
|
||||||
|
This is the correct setting to tweak if you want Tahoe's SFTP
|
||||||
|
daemon to listen on a different port.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
sftpd.hostPublicKeyFile = mkOption {
|
||||||
|
default = null;
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
description = ''
|
||||||
|
Path to the SSH host public key.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
sftpd.hostPrivateKeyFile = mkOption {
|
||||||
|
default = null;
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
description = ''
|
||||||
|
Path to the SSH host private key.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
sftpd.accounts.file = mkOption {
|
||||||
|
default = null;
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
description = ''
|
||||||
|
Path to the accounts file.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
sftpd.accounts.url = mkOption {
|
||||||
|
default = null;
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
description = ''
|
||||||
|
URL of the accounts server.
|
||||||
|
'';
|
||||||
|
};
|
||||||
package = mkOption {
|
package = mkOption {
|
||||||
default = pkgs.tahoelafs;
|
default = pkgs.tahoelafs;
|
||||||
defaultText = "pkgs.tahoelafs";
|
defaultText = "pkgs.tahoelafs";
|
||||||
@ -194,6 +233,12 @@ in
|
|||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "simple";
|
Type = "simple";
|
||||||
PIDFile = pidfile;
|
PIDFile = pidfile;
|
||||||
|
# Believe it or not, Tahoe is very brittle about the order of
|
||||||
|
# arguments to $(tahoe start). The node directory must come first,
|
||||||
|
# and arguments which alter Twisted's behavior come afterwards.
|
||||||
|
ExecStart = ''
|
||||||
|
${settings.package}/bin/tahoe start ${nodedir} -n -l- --pidfile=${pidfile}
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
preStart = ''
|
preStart = ''
|
||||||
if [ \! -d ${nodedir} ]; then
|
if [ \! -d ${nodedir} ]; then
|
||||||
@ -209,12 +254,6 @@ in
|
|||||||
# ln -s /etc/tahoe-lafs/introducer-${node}.cfg ${nodedir}/tahoe.cfg
|
# ln -s /etc/tahoe-lafs/introducer-${node}.cfg ${nodedir}/tahoe.cfg
|
||||||
cp /etc/tahoe-lafs/introducer-${node}.cfg ${nodedir}/tahoe.cfg
|
cp /etc/tahoe-lafs/introducer-${node}.cfg ${nodedir}/tahoe.cfg
|
||||||
'';
|
'';
|
||||||
# Believe it or not, Tahoe is very brittle about the order of
|
|
||||||
# arguments to $(tahoe start). The node directory must come first,
|
|
||||||
# and arguments which alter Twisted's behavior come afterwards.
|
|
||||||
script = ''
|
|
||||||
tahoe start ${nodedir} -n -l- --pidfile=${pidfile}
|
|
||||||
'';
|
|
||||||
});
|
});
|
||||||
users.extraUsers = flip mapAttrs' cfg.introducers (node: _:
|
users.extraUsers = flip mapAttrs' cfg.introducers (node: _:
|
||||||
nameValuePair "tahoe.introducer-${node}" {
|
nameValuePair "tahoe.introducer-${node}" {
|
||||||
@ -256,6 +295,19 @@ in
|
|||||||
|
|
||||||
[helper]
|
[helper]
|
||||||
enabled = ${if settings.helper.enable then "true" else "false"}
|
enabled = ${if settings.helper.enable then "true" else "false"}
|
||||||
|
|
||||||
|
[sftpd]
|
||||||
|
enabled = ${if settings.sftpd.enable then "true" else "false"}
|
||||||
|
${optionalString (settings.sftpd.port != null)
|
||||||
|
"port = ${toString settings.sftpd.port}"}
|
||||||
|
${optionalString (settings.sftpd.hostPublicKeyFile != null)
|
||||||
|
"host_pubkey_file = ${settings.sftpd.hostPublicKeyFile}"}
|
||||||
|
${optionalString (settings.sftpd.hostPrivateKeyFile != null)
|
||||||
|
"host_privkey_file = ${settings.sftpd.hostPrivateKeyFile}"}
|
||||||
|
${optionalString (settings.sftpd.accounts.file != null)
|
||||||
|
"accounts.file = ${settings.sftpd.accounts.file}"}
|
||||||
|
${optionalString (settings.sftpd.accounts.url != null)
|
||||||
|
"accounts.url = ${settings.sftpd.accounts.url}"}
|
||||||
'';
|
'';
|
||||||
});
|
});
|
||||||
# Actually require Tahoe, so that we will have it installed.
|
# Actually require Tahoe, so that we will have it installed.
|
||||||
@ -281,6 +333,12 @@ in
|
|||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "simple";
|
Type = "simple";
|
||||||
PIDFile = pidfile;
|
PIDFile = pidfile;
|
||||||
|
# Believe it or not, Tahoe is very brittle about the order of
|
||||||
|
# arguments to $(tahoe start). The node directory must come first,
|
||||||
|
# and arguments which alter Twisted's behavior come afterwards.
|
||||||
|
ExecStart = ''
|
||||||
|
${settings.package}/bin/tahoe start ${nodedir} -n -l- --pidfile=${pidfile}
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
preStart = ''
|
preStart = ''
|
||||||
if [ \! -d ${nodedir} ]; then
|
if [ \! -d ${nodedir} ]; then
|
||||||
@ -296,12 +354,6 @@ in
|
|||||||
# ln -s /etc/tahoe-lafs/${node}.cfg ${nodedir}/tahoe.cfg
|
# ln -s /etc/tahoe-lafs/${node}.cfg ${nodedir}/tahoe.cfg
|
||||||
cp /etc/tahoe-lafs/${node}.cfg ${nodedir}/tahoe.cfg
|
cp /etc/tahoe-lafs/${node}.cfg ${nodedir}/tahoe.cfg
|
||||||
'';
|
'';
|
||||||
# Believe it or not, Tahoe is very brittle about the order of
|
|
||||||
# arguments to $(tahoe start). The node directory must come first,
|
|
||||||
# and arguments which alter Twisted's behavior come afterwards.
|
|
||||||
script = ''
|
|
||||||
tahoe start ${nodedir} -n -l- --pidfile=${pidfile}
|
|
||||||
'';
|
|
||||||
});
|
});
|
||||||
users.extraUsers = flip mapAttrs' cfg.nodes (node: _:
|
users.extraUsers = flip mapAttrs' cfg.nodes (node: _:
|
||||||
nameValuePair "tahoe.${node}" {
|
nameValuePair "tahoe.${node}" {
|
||||||
|
@ -55,6 +55,15 @@ in
|
|||||||
description = "The directory to use for Yandex.Disk storage";
|
description = "The directory to use for Yandex.Disk storage";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
excludes = mkOption {
|
||||||
|
default = "";
|
||||||
|
type = types.string;
|
||||||
|
example = "data,backup";
|
||||||
|
description = ''
|
||||||
|
Comma-separated list of directories which are excluded from synchronization.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -86,7 +95,7 @@ in
|
|||||||
chown ${u} ${dir}
|
chown ${u} ${dir}
|
||||||
|
|
||||||
if ! test -d "${cfg.directory}" ; then
|
if ! test -d "${cfg.directory}" ; then
|
||||||
mkdir -p -m 755 ${cfg.directory} ||
|
(mkdir -p -m 755 ${cfg.directory} && chown ${u} ${cfg.directory}) ||
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -94,7 +103,7 @@ in
|
|||||||
-c '${pkgs.yandex-disk}/bin/yandex-disk token -p ${cfg.password} ${cfg.username} ${dir}/token'
|
-c '${pkgs.yandex-disk}/bin/yandex-disk token -p ${cfg.password} ${cfg.username} ${dir}/token'
|
||||||
|
|
||||||
${pkgs.su}/bin/su -s ${pkgs.stdenv.shell} ${u} \
|
${pkgs.su}/bin/su -s ${pkgs.stdenv.shell} ${u} \
|
||||||
-c '${pkgs.yandex-disk}/bin/yandex-disk start --no-daemon -a ${dir}/token -d ${cfg.directory}'
|
-c '${pkgs.yandex-disk}/bin/yandex-disk start --no-daemon -a ${dir}/token -d ${cfg.directory} --exclude-dirs=${cfg.excludes}'
|
||||||
'';
|
'';
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -1,76 +1,68 @@
|
|||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
inherit (lib) mkEnableOption mkIf mkOption singleton types;
|
inherit (lib) mkEnableOption mkIf mkOption types;
|
||||||
inherit (pkgs) bird;
|
|
||||||
cfg = config.services.bird;
|
|
||||||
|
|
||||||
configFile = pkgs.writeText "bird.conf" ''
|
generic = variant:
|
||||||
${cfg.config}
|
let
|
||||||
'';
|
cfg = config.services.${variant};
|
||||||
in
|
pkg = pkgs.${variant};
|
||||||
|
birdc = if variant == "bird6" then "birdc6" else "birdc";
|
||||||
{
|
configFile = pkgs.stdenv.mkDerivation {
|
||||||
|
name = "${variant}.conf";
|
||||||
###### interface
|
text = cfg.config;
|
||||||
|
preferLocalBuild = true;
|
||||||
options = {
|
buildCommand = ''
|
||||||
|
echo -n "$text" > $out
|
||||||
services.bird = {
|
${pkg}/bin/${variant} -d -p -c $out
|
||||||
|
|
||||||
enable = mkEnableOption "BIRD Internet Routing Daemon";
|
|
||||||
|
|
||||||
config = mkOption {
|
|
||||||
type = types.string;
|
|
||||||
description = ''
|
|
||||||
BIRD Internet Routing Daemon configuration file.
|
|
||||||
<link xlink:href='http://bird.network.cz/'/>
|
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
in {
|
||||||
user = mkOption {
|
###### interface
|
||||||
type = types.string;
|
options = {
|
||||||
default = "bird";
|
services.${variant} = {
|
||||||
description = ''
|
enable = mkEnableOption "BIRD Internet Routing Daemon";
|
||||||
BIRD Internet Routing Daemon user.
|
config = mkOption {
|
||||||
'';
|
type = types.lines;
|
||||||
|
description = ''
|
||||||
|
BIRD Internet Routing Daemon configuration file.
|
||||||
|
<link xlink:href='http://bird.network.cz/'/>
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
group = mkOption {
|
###### implementation
|
||||||
type = types.string;
|
config = mkIf cfg.enable {
|
||||||
default = "bird";
|
systemd.services.${variant} = {
|
||||||
description = ''
|
description = "BIRD Internet Routing Daemon";
|
||||||
BIRD Internet Routing Daemon group.
|
wantedBy = [ "multi-user.target" ];
|
||||||
'';
|
serviceConfig = {
|
||||||
};
|
Type = "forking";
|
||||||
|
Restart = "on-failure";
|
||||||
};
|
ExecStart = "${pkg}/bin/${variant} -c ${configFile} -u ${variant} -g ${variant}";
|
||||||
|
ExecReload = "${pkg}/bin/${birdc} configure";
|
||||||
};
|
ExecStop = "${pkg}/bin/${birdc} down";
|
||||||
|
CapabilityBoundingSet = [ "CAP_CHOWN" "CAP_FOWNER" "CAP_DAC_OVERRIDE" "CAP_SETUID" "CAP_SETGID"
|
||||||
|
# see bird/sysdep/linux/syspriv.h
|
||||||
###### implementation
|
"CAP_NET_BIND_SERVICE" "CAP_NET_BROADCAST" "CAP_NET_ADMIN" "CAP_NET_RAW" ];
|
||||||
|
ProtectSystem = "full";
|
||||||
config = mkIf cfg.enable {
|
ProtectHome = "yes";
|
||||||
|
SystemCallFilter="~@cpu-emulation @debug @keyring @module @mount @obsolete @raw-io";
|
||||||
users.extraUsers = singleton {
|
MemoryDenyWriteExecute = "yes";
|
||||||
name = cfg.user;
|
};
|
||||||
description = "BIRD Internet Routing Daemon user";
|
};
|
||||||
uid = config.ids.uids.bird;
|
users = {
|
||||||
group = cfg.group;
|
extraUsers.${variant} = {
|
||||||
};
|
description = "BIRD Internet Routing Daemon user";
|
||||||
|
group = "${variant}";
|
||||||
users.extraGroups = singleton {
|
};
|
||||||
name = cfg.group;
|
extraGroups.${variant} = {};
|
||||||
gid = config.ids.gids.bird;
|
};
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.bird = {
|
|
||||||
description = "BIRD Internet Routing Daemon";
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
serviceConfig = {
|
|
||||||
ExecStart = "${bird}/bin/bird -d -c ${configFile} -s /var/run/bird.ctl -u ${cfg.user} -g ${cfg.group}";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
inherit (config.services) bird bird6;
|
||||||
|
in {
|
||||||
|
imports = [(generic "bird") (generic "bird6")];
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
servers = mkOption {
|
servers = mkOption {
|
||||||
default = config.services.ntp.servers;
|
default = config.networking.timeServers;
|
||||||
description = ''
|
description = ''
|
||||||
The set of NTP servers from which to synchronise.
|
The set of NTP servers from which to synchronise.
|
||||||
'';
|
'';
|
||||||
@ -102,7 +102,7 @@ in
|
|||||||
home = stateDir;
|
home = stateDir;
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.services.ntpd.enable = mkForce false;
|
systemd.services.timesyncd.enable = mkForce false;
|
||||||
|
|
||||||
systemd.services.chronyd =
|
systemd.services.chronyd =
|
||||||
{ description = "chrony NTP daemon";
|
{ description = "chrony NTP daemon";
|
||||||
|
@ -19,30 +19,21 @@ let
|
|||||||
type = types.str;
|
type = types.str;
|
||||||
description = "Public key at the opposite end of the tunnel.";
|
description = "Public key at the opposite end of the tunnel.";
|
||||||
};
|
};
|
||||||
hostname = mkOption {
|
|
||||||
default = "";
|
|
||||||
example = "foobar.hype";
|
|
||||||
type = types.str;
|
|
||||||
description = "Optional hostname to add to /etc/hosts; prevents reverse lookup failures.";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# Additional /etc/hosts entries for peers with an associated hostname
|
# check for the required attributes, otherwise
|
||||||
cjdnsExtraHosts = import (pkgs.runCommand "cjdns-hosts" {}
|
# permit attributes not undefined here
|
||||||
# Generate a builder that produces an output usable as a Nix string value
|
checkPeers = x:
|
||||||
''
|
x // {
|
||||||
exec >$out
|
connectTo = mapAttrs
|
||||||
echo \'\'
|
(name: value:
|
||||||
${concatStringsSep "\n" (mapAttrsToList (k: v:
|
if !hasAttr "publicKey" value then abort "cjdns peer ${name} missing a publicKey" else
|
||||||
optionalString (v.hostname != "")
|
if !hasAttr "password" value then abort "cjdns peer ${name} missing a password" else
|
||||||
"echo $(${pkgs.cjdns}/bin/publictoip6 ${v.publicKey}) ${v.hostname}")
|
value
|
||||||
(cfg.ETHInterface.connectTo // cfg.UDPInterface.connectTo))}
|
)
|
||||||
echo \'\'
|
x.connectTo;
|
||||||
'');
|
};
|
||||||
|
|
||||||
parseModules = x:
|
|
||||||
x // { connectTo = mapAttrs (name: value: { inherit (value) password publicKey; }) x.connectTo; };
|
|
||||||
|
|
||||||
# would be nice to merge 'cfg' with a //,
|
# would be nice to merge 'cfg' with a //,
|
||||||
# but the json nesting is wacky.
|
# but the json nesting is wacky.
|
||||||
@ -53,8 +44,8 @@ let
|
|||||||
};
|
};
|
||||||
authorizedPasswords = map (p: { password = p; }) cfg.authorizedPasswords;
|
authorizedPasswords = map (p: { password = p; }) cfg.authorizedPasswords;
|
||||||
interfaces = {
|
interfaces = {
|
||||||
ETHInterface = if (cfg.ETHInterface.bind != "") then [ (parseModules cfg.ETHInterface) ] else [ ];
|
ETHInterface = if (cfg.ETHInterface.bind != "") then [ (checkPeers cfg.ETHInterface) ] else [ ];
|
||||||
UDPInterface = if (cfg.UDPInterface.bind != "") then [ (parseModules cfg.UDPInterface) ] else [ ];
|
UDPInterface = if (cfg.UDPInterface.bind != "") then [ (checkPeers cfg.UDPInterface) ] else [ ];
|
||||||
};
|
};
|
||||||
|
|
||||||
privateKey = "@CJDNS_PRIVATE_KEY@";
|
privateKey = "@CJDNS_PRIVATE_KEY@";
|
||||||
@ -134,12 +125,12 @@ in
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
connectTo = mkOption {
|
connectTo = mkOption {
|
||||||
type = types.attrsOf ( types.submodule ( connectToSubmodule ) );
|
type = types.attrsOf (types.attrsOf types.str);
|
||||||
default = { };
|
default = { };
|
||||||
example = {
|
example = {
|
||||||
"192.168.1.1:27313" = {
|
"192.168.1.1:27313" = {
|
||||||
hostname = "homer.hype";
|
user = "foobar";
|
||||||
password = "5kG15EfpdcKNX3f2GSQ0H1HC7yIfxoCoImnO5FHM";
|
password = "5kG15EfpdcKNX3f2GSQ0H1HC7yIfxoCoImnO5FHM";
|
||||||
publicKey = "371zpkgs8ss387tmr81q04mp0hg1skb51hw34vk1cq644mjqhup0.k";
|
publicKey = "371zpkgs8ss387tmr81q04mp0hg1skb51hw34vk1cq644mjqhup0.k";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -179,12 +170,12 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
connectTo = mkOption {
|
connectTo = mkOption {
|
||||||
type = types.attrsOf ( types.submodule ( connectToSubmodule ) );
|
type = types.attrsOf (types.attrsOf types.str);
|
||||||
default = { };
|
default = { };
|
||||||
example = {
|
example = {
|
||||||
"01:02:03:04:05:06" = {
|
"01:02:03:04:05:06" = {
|
||||||
hostname = "homer.hype";
|
user = "foobar";
|
||||||
password = "5kG15EfpdcKNX3f2GSQ0H1HC7yIfxoCoImnO5FHM";
|
password = "5kG15EfpdcKNX3f2GSQ0H1HC7yIfxoCoImnO5FHM";
|
||||||
publicKey = "371zpkgs8ss387tmr81q04mp0hg1skb51hw34vk1cq644mjqhup0.k";
|
publicKey = "371zpkgs8ss387tmr81q04mp0hg1skb51hw34vk1cq644mjqhup0.k";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -207,8 +198,9 @@ in
|
|||||||
|
|
||||||
systemd.services.cjdns = {
|
systemd.services.cjdns = {
|
||||||
description = "cjdns: routing engine designed for security, scalability, speed and ease of use";
|
description = "cjdns: routing engine designed for security, scalability, speed and ease of use";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" "sleep.target"];
|
||||||
after = [ "network.target" ];
|
after = [ "network-online.target" ];
|
||||||
|
bindsTo = [ "network-online.target" ];
|
||||||
|
|
||||||
preStart = if cfg.confFile != null then "" else ''
|
preStart = if cfg.confFile != null then "" else ''
|
||||||
[ -e /etc/cjdns.keys ] && source /etc/cjdns.keys
|
[ -e /etc/cjdns.keys ] && source /etc/cjdns.keys
|
||||||
@ -244,7 +236,9 @@ in
|
|||||||
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "forking";
|
Type = "forking";
|
||||||
Restart = "on-failure";
|
Restart = "always";
|
||||||
|
StartLimitInterval = 0;
|
||||||
|
RestartSec = 1;
|
||||||
CapabilityBoundingSet = "CAP_NET_ADMIN CAP_NET_RAW";
|
CapabilityBoundingSet = "CAP_NET_ADMIN CAP_NET_RAW";
|
||||||
AmbientCapabilities = "CAP_NET_ADMIN CAP_NET_RAW";
|
AmbientCapabilities = "CAP_NET_ADMIN CAP_NET_RAW";
|
||||||
ProtectSystem = "full";
|
ProtectSystem = "full";
|
||||||
@ -254,8 +248,6 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
networking.extraHosts = cjdnsExtraHosts;
|
|
||||||
|
|
||||||
assertions = [
|
assertions = [
|
||||||
{ assertion = ( cfg.ETHInterface.bind != "" || cfg.UDPInterface.bind != "" || cfg.confFile != null );
|
{ assertion = ( cfg.ETHInterface.bind != "" || cfg.UDPInterface.bind != "" || cfg.confFile != null );
|
||||||
message = "Neither cjdns.ETHInterface.bind nor cjdns.UDPInterface.bind defined.";
|
message = "Neither cjdns.ETHInterface.bind nor cjdns.UDPInterface.bind defined.";
|
||||||
|
61
nixos/modules/services/networking/dante.nix
Normal file
61
nixos/modules/services/networking/dante.nix
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.dante;
|
||||||
|
confFile = pkgs.writeText "dante-sockd.conf" ''
|
||||||
|
user.privileged: root
|
||||||
|
user.unprivileged: dante
|
||||||
|
|
||||||
|
${cfg.config}
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
meta = {
|
||||||
|
maintainers = with maintainers; [ arobyn ];
|
||||||
|
};
|
||||||
|
|
||||||
|
options = {
|
||||||
|
services.dante = {
|
||||||
|
enable = mkEnableOption "Dante SOCKS proxy";
|
||||||
|
|
||||||
|
config = mkOption {
|
||||||
|
default = null;
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
description = ''
|
||||||
|
Contents of Dante's configuration file
|
||||||
|
NOTE: user.privileged/user.unprivileged are set by the service
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
assertions = [
|
||||||
|
{ assertion = cfg.config != null;
|
||||||
|
message = "please provide Dante configuration file contents";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
users.users.dante = {
|
||||||
|
description = "Dante SOCKS proxy daemon user";
|
||||||
|
isSystemUser = true;
|
||||||
|
group = "dante";
|
||||||
|
};
|
||||||
|
users.groups.dante = {};
|
||||||
|
|
||||||
|
systemd.services.dante = {
|
||||||
|
description = "Dante SOCKS v4 and v5 compatible proxy server";
|
||||||
|
after = [ "network.target" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "simple";
|
||||||
|
ExecStart = "${pkgs.dante}/bin/sockd -f ${confFile}";
|
||||||
|
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
|
||||||
|
Restart = "always";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
63
nixos/modules/services/networking/fakeroute.nix
Normal file
63
nixos/modules/services/networking/fakeroute.nix
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.fakeroute;
|
||||||
|
routeConf = pkgs.writeText "route.conf" (concatStringsSep "\n" cfg.route);
|
||||||
|
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
###### interface
|
||||||
|
|
||||||
|
options = {
|
||||||
|
|
||||||
|
services.fakeroute = {
|
||||||
|
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Whether to enable the fakeroute service.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
route = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
example = [
|
||||||
|
"216.102.187.130"
|
||||||
|
"4.0.1.122"
|
||||||
|
"198.116.142.34"
|
||||||
|
"63.199.8.242"
|
||||||
|
];
|
||||||
|
description = ''
|
||||||
|
Fake route that will appear after the real
|
||||||
|
one to any host running a traceroute.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
###### implementation
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
systemd.services.fakeroute = {
|
||||||
|
description = "Fakeroute Daemon";
|
||||||
|
after = [ "network.target" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "forking";
|
||||||
|
User = "root";
|
||||||
|
ExecStart = "${pkgs.fakeroute}/bin/fakeroute -f ${routeConf}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user