mirror of
https://github.com/NixOS/nixpkgs.git
synced 2024-10-30 22:21:26 +00:00
Merge remote-tracking branch 'upstream/master' into hardened-stdenv
This commit is contained in:
commit
5185bc1773
4
.github/PULL_REQUEST_TEMPLATE.md
vendored
4
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -4,8 +4,8 @@
|
||||
###### Things done
|
||||
|
||||
- [ ] Tested using sandboxing
|
||||
([nix.useSandbox](http://nixos.org/nixos/manual/options.html#opt-nix.useSandbox) on NixOS,
|
||||
or option `build-use-sandbox` in [`nix.conf`](http://nixos.org/nix/manual/#sec-conf-file)
|
||||
([nix.useChroot](http://nixos.org/nixos/manual/options.html#opt-nix.useChroot) on NixOS,
|
||||
or option `build-use-chroot` in [`nix.conf`](http://nixos.org/nix/manual/#sec-conf-file)
|
||||
on non-NixOS)
|
||||
- Built on platform(s)
|
||||
- [ ] NixOS
|
||||
|
@ -57,11 +57,11 @@ stdenv.mkDerivation {
|
||||
outputFile = "./languages-frameworks/haskell.xml";
|
||||
}
|
||||
+ toDocbook {
|
||||
inputFile = ./../pkgs/development/idris-modules/README.md;
|
||||
inputFile = ../pkgs/development/idris-modules/README.md;
|
||||
outputFile = "languages-frameworks/idris.xml";
|
||||
}
|
||||
+ toDocbook {
|
||||
inputFile = ./../pkgs/development/r-modules/README.md;
|
||||
inputFile = ../pkgs/development/r-modules/README.md;
|
||||
outputFile = "languages-frameworks/r.xml";
|
||||
}
|
||||
+ ''
|
||||
|
@ -89,27 +89,27 @@ in ...</programlisting>
|
||||
<title><pkg>.overrideDerivation</title>
|
||||
|
||||
<warning>
|
||||
<para>Do not use this function in Nixpkgs. Because it breaks
|
||||
package abstraction and doesn’t provide error checking for
|
||||
function arguments, it is only intended for ad-hoc customisation
|
||||
(such as in <filename>~/.nixpkgs/config.nix</filename>).
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Additionally, <varname>overrideDerivation</varname> forces an evaluation
|
||||
of the Derivation which can be quite a performance penalty if there are many
|
||||
overrides used.
|
||||
<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> is usually available for all the
|
||||
derivations in the nixpkgs expression (<varname>pkgs</varname>).
|
||||
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>
|
||||
It is used to create a new derivation by overriding the attributes of
|
||||
the original derivation according to the given function.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Example usage:
|
||||
@ -125,9 +125,9 @@ in ...</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In the above example, the name, src and patches of the derivation
|
||||
will be overridden, while all other attributes will be retained from the
|
||||
original derivation.
|
||||
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>
|
||||
@ -135,6 +135,20 @@ in ...</programlisting>
|
||||
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">
|
||||
@ -171,42 +185,18 @@ c = lib.makeOverridable f { a = 1; b = 2; }</programlisting>
|
||||
|
||||
|
||||
<section xml:id="sec-fhs-environments">
|
||||
<title>buildFHSChrootEnv/buildFHSUserEnv</title>
|
||||
<title>buildFHSUserEnv</title>
|
||||
|
||||
<para>
|
||||
<function>buildFHSChrootEnv</function> and
|
||||
<function>buildFHSUserEnv</function> provide a way to build and run
|
||||
FHS-compatible lightweight sandboxes. They get their own isolated root with
|
||||
binded <filename>/nix/store</filename>, so their footprint in terms of disk
|
||||
<function>buildFHSUserEnv</function> provides a way to build and run
|
||||
FHS-compatible lightweight sandboxes. It creates an isolated root with
|
||||
bound <filename>/nix/store</filename>, so its footprint in terms of disk
|
||||
space needed is quite small. This allows one to run software which is hard or
|
||||
unfeasible to patch for NixOS -- 3rd-party source trees with FHS assumptions,
|
||||
games distributed as tarballs, software with integrity checking and/or external
|
||||
self-updated binaries.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<function>buildFHSChrootEnv</function> allows to create persistent
|
||||
environments, which can be constructed, deconstructed and entered by
|
||||
multiple users at once. A downside is that it requires
|
||||
<literal>root</literal> access for both those who create and destroy and
|
||||
those who enter it. It can be useful to create environments for daemons that
|
||||
one can enter and observe.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<function>buildFHSUserEnv</function> uses Linux namespaces feature to create
|
||||
self-updated binaries. It uses Linux namespaces feature to create
|
||||
temporary lightweight environments which are destroyed after all child
|
||||
processes exit. It does not require root access, and can be useful to create
|
||||
sandboxes and wrap applications.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Those functions both rely on <function>buildFHSEnv</function>, which creates
|
||||
an actual directory structure given a list of necessary packages and extra
|
||||
build commands.
|
||||
<function>buildFHSChrootEnv</function> and <function>buildFHSUserEnv</function>
|
||||
both accept those arguments which are passed to
|
||||
<function>buildFHSEnv</function>:
|
||||
processes exit, without root user rights requirement. Accepted arguments are:
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
@ -220,14 +210,16 @@ c = lib.makeOverridable f { a = 1; b = 2; }</programlisting>
|
||||
<term><literal>targetPkgs</literal></term>
|
||||
|
||||
<listitem><para>Packages to be installed for the main host's architecture
|
||||
(i.e. x86_64 on x86_64 installations).</para></listitem>
|
||||
(i.e. x86_64 on x86_64 installations). Along with libraries binaries are also
|
||||
installed.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>multiPkgs</literal></term>
|
||||
|
||||
<listitem><para>Packages to be installed for all architectures supported by
|
||||
a host (i.e. i686 and x86_64 on x86_64 installations).</para></listitem>
|
||||
a host (i.e. i686 and x86_64 on x86_64 installations). Only libraries are
|
||||
installed by default.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
@ -240,29 +232,33 @@ c = lib.makeOverridable f { a = 1; b = 2; }</programlisting>
|
||||
<varlistentry>
|
||||
<term><literal>extraBuildCommandsMulti</literal></term>
|
||||
|
||||
<listitem><para>Like <literal>extraBuildCommandsMulti</literal>, but
|
||||
<listitem><para>Like <literal>extraBuildCommands</literal>, but
|
||||
executed only on multilib architectures.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>extraOutputsToInstall</literal></term>
|
||||
|
||||
<listitem><para>Additional derivation outputs to be linked for both
|
||||
target and multi-architecture packages.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>extraInstallCommands</literal></term>
|
||||
|
||||
<listitem><para>Additional commands to be executed for finalizing the
|
||||
derivation with runner script.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>runScript</literal></term>
|
||||
|
||||
<listitem><para>A command that would be executed inside the sandbox and
|
||||
passed all the command line arguments. It defaults to
|
||||
<literal>bash</literal>.</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<para>
|
||||
Additionally, <function>buildFHSUserEnv</function> accepts
|
||||
<literal>runScript</literal> parameter, which is a command that would be
|
||||
executed inside the sandbox and passed all the command line arguments. It
|
||||
default to <literal>bash</literal>.
|
||||
</para>
|
||||
<para>
|
||||
It also uses <literal>CHROOTENV_EXTRA_BINDS</literal> environment variable
|
||||
for binding extra directories in the sandbox to outside places. The format of
|
||||
the variable is <literal>/mnt=test-mnt:/data</literal>, where
|
||||
<literal>/mnt</literal> would be mounted as <literal>/test-mnt</literal>
|
||||
and <literal>/data</literal> would be mounted as <literal>/data</literal>.
|
||||
<literal>extraBindMounts</literal> array argument to
|
||||
<function>buildFHSUserEnv</function> function is prepended to this variable.
|
||||
Latter entries take priority if defined several times -- i.e. in case of
|
||||
<literal>/data=data1:/data=data2</literal> the actual bind path would be
|
||||
<literal>/data2</literal>.
|
||||
</para>
|
||||
<para>
|
||||
One can create a simple environment using a <literal>shell.nix</literal>
|
||||
like that:
|
||||
|
@ -5,27 +5,29 @@
|
||||
<title>Go</title>
|
||||
|
||||
<para>The function <varname>buildGoPackage</varname> builds
|
||||
standard Go packages.
|
||||
standard Go programs.
|
||||
</para>
|
||||
|
||||
<example xml:id='ex-buildGoPackage'><title>buildGoPackage</title>
|
||||
<programlisting>
|
||||
net = buildGoPackage rec {
|
||||
name = "go.net-${rev}";
|
||||
goPackagePath = "golang.org/x/net"; <co xml:id='ex-buildGoPackage-1' />
|
||||
subPackages = [ "ipv4" "ipv6" ]; <co xml:id='ex-buildGoPackage-2' />
|
||||
rev = "e0403b4e005";
|
||||
deis = buildGoPackage rec {
|
||||
name = "deis-${version}";
|
||||
version = "1.13.0";
|
||||
|
||||
goPackagePath = "github.com/deis/deis"; <co xml:id='ex-buildGoPackage-1' />
|
||||
subPackages = [ "client" ]; <co xml:id='ex-buildGoPackage-2' />
|
||||
|
||||
src = fetchFromGitHub {
|
||||
inherit rev;
|
||||
owner = "golang";
|
||||
repo = "net";
|
||||
sha256 = "1g7cjzw4g4301a3yqpbk8n1d4s97sfby2aysl275x04g0zh8jxqp";
|
||||
owner = "deis";
|
||||
repo = "deis";
|
||||
rev = "v${version}";
|
||||
sha256 = "1qv9lxqx7m18029lj8cw3k7jngvxs4iciwrypdy0gd2nnghc68sw";
|
||||
};
|
||||
goPackageAliases = [ "code.google.com/p/go.net" ]; <co xml:id='ex-buildGoPackage-3' />
|
||||
propagatedBuildInputs = [ goPackages.text ]; <co xml:id='ex-buildGoPackage-4' />
|
||||
buildFlags = "--tags release"; <co xml:id='ex-buildGoPackage-5' />
|
||||
disabled = isGo13;<co xml:id='ex-buildGoPackage-6' />
|
||||
};
|
||||
|
||||
goDeps = ./deps.json; <co xml:id='ex-buildGoPackage-3' />
|
||||
|
||||
buildFlags = "--tags release"; <co xml:id='ex-buildGoPackage-4' />
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
@ -47,50 +49,90 @@ the following arguments are of special significance to the function:
|
||||
packages will be built.
|
||||
</para>
|
||||
<para>
|
||||
In this example only <literal>code.google.com/p/go.net/ipv4</literal> and
|
||||
<literal>code.google.com/p/go.net/ipv6</literal> will be built.
|
||||
In this example only <literal>github.com/deis/deis/client</literal> will be built.
|
||||
</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs='ex-buildGoPackage-3'>
|
||||
<para>
|
||||
<varname>goPackageAliases</varname> is a list of alternative import paths
|
||||
that are valid for this library.
|
||||
Packages that depend on this library will automatically rename
|
||||
import paths that match any of the aliases to <literal>goPackagePath</literal>.
|
||||
</para>
|
||||
<para>
|
||||
In this example imports will be renamed from
|
||||
<literal>code.google.com/p/go.net</literal> to
|
||||
<literal>golang.org/x/net</literal> in every package that depend on the
|
||||
<literal>go.net</literal> library.
|
||||
<varname>goDeps</varname> is where the Go dependencies of a Go program are listed
|
||||
in a JSON format described below.
|
||||
</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs='ex-buildGoPackage-4'>
|
||||
<para>
|
||||
<varname>propagatedBuildInputs</varname> is where the dependencies of a Go library are
|
||||
listed. Only libraries should list <varname>propagatedBuildInputs</varname>. If a standalone
|
||||
program is being built instead, use <varname>buildInputs</varname>. If a library's tests require
|
||||
additional dependencies that are not propagated, they should be listed in <varname>buildInputs</varname>.
|
||||
</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs='ex-buildGoPackage-5'>
|
||||
<para>
|
||||
<varname>buildFlags</varname> is a list of flags passed to the go build command.
|
||||
</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs='ex-buildGoPackage-6'>
|
||||
</calloutlist>
|
||||
|
||||
</para>
|
||||
|
||||
<para>The <varname>goDeps</varname> attribute should point to a JSON file that defines which Go libraries
|
||||
are needed and should be included in <varname>GOPATH</varname> for <varname>buildPhase</varname>.
|
||||
|
||||
</para>
|
||||
|
||||
<example xml:id='ex-goDeps'><title>deps.json</title>
|
||||
<programlisting>
|
||||
[ <co xml:id='ex-goDeps-1' />
|
||||
{
|
||||
"goPackagePath": "gopkg.in/yaml.v2", <co xml:id='ex-goDeps-2' />
|
||||
"fetch": {
|
||||
"type": "git", <co xml:id='ex-goDeps-3' />
|
||||
"url": "https://gopkg.in/yaml.v2",
|
||||
"rev": "a83829b6f1293c91addabc89d0571c246397bbf4",
|
||||
"sha256": "1m4dsmk90sbi17571h6pld44zxz7jc4lrnl4f27dpd1l8g5xvjhh"
|
||||
}
|
||||
},
|
||||
{
|
||||
"include": "../../libs.json", <co xml:id='ex-goDeps-4' />
|
||||
"packages": [ <co xml:id='ex-goDeps-5' />
|
||||
"github.com/docopt/docopt-go",
|
||||
"golang.org/x/crypto",
|
||||
]
|
||||
}
|
||||
]
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
|
||||
<calloutlist>
|
||||
|
||||
<callout arearefs='ex-goDeps-1'>
|
||||
<para>
|
||||
If <varname>disabled</varname> is <literal>true</literal>,
|
||||
nix will refuse to build this package.
|
||||
<varname>goDeps</varname> is a list of Go dependencies.
|
||||
</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs='ex-goDeps-2'>
|
||||
<para>
|
||||
In this example the package will not be built for go 1.3. The <literal>isGo13</literal>
|
||||
is an utility function that returns <literal>true</literal> if go used to build the
|
||||
package has version 1.3.x.
|
||||
<varname>goPackagePath</varname> specifies Go package import path.
|
||||
</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs='ex-goDeps-3'>
|
||||
<para>
|
||||
<varname>fetch type</varname> that needs to be used to get package source. If <varname>git</varname>
|
||||
is used there should be <varname>url</varname>, <varname>rev</varname> and <varname>sha256</varname>
|
||||
defined next to it.
|
||||
</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs='ex-goDeps-4'>
|
||||
<para>
|
||||
<varname>include</varname> could be used to reuse <varname>goDeps</varname> between Go programs.
|
||||
There is a common libs set in <varname><nixpkgs/pkgs/development/go-modules/libs.json></varname>
|
||||
with pinned versions of many packages that you can reuse.
|
||||
</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs='ex-goDeps-5'>
|
||||
<para>
|
||||
<varname>packages</varname> enumerates all Go packages that will be imported from included file.
|
||||
</para>
|
||||
</callout>
|
||||
|
||||
@ -99,12 +141,21 @@ the following arguments are of special significance to the function:
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Reusable Go libraries may be found in the <varname>goPackages</varname> set. You can test
|
||||
build a Go package as follows:
|
||||
<varname>buildGoPackage</varname> produces <xref linkend='chap-multiple-output' xrefstyle="select: title" />
|
||||
where <varname>bin</varname> includes program binaries. You can test build a Go binary as follows:
|
||||
|
||||
<screen>
|
||||
$ nix-build -A goPackages.net
|
||||
</screen>
|
||||
<screen>
|
||||
$ nix-build -A deis.bin
|
||||
</screen>
|
||||
|
||||
or build all outputs with:
|
||||
|
||||
<screen>
|
||||
$ nix-build -A deis.all
|
||||
</screen>
|
||||
|
||||
<varname>bin</varname> output will be installed by default with <varname>nix-env -i</varname>
|
||||
or <varname>systemPackages</varname>.
|
||||
|
||||
</para>
|
||||
|
||||
@ -119,6 +170,7 @@ done
|
||||
</screen>
|
||||
</para>
|
||||
|
||||
<para>To extract dependency information from a Go package in automated way use <link xlink:href="https://github.com/kamilchm/go2nix">go2nix</link>.</para>
|
||||
<para>To extract dependency information from a Go package in automated way use <link xlink:href="https://github.com/kamilchm/go2nix">go2nix</link>.
|
||||
It can produce complete derivation and <varname>goDeps</varname> file for Go programs.</para>
|
||||
</section>
|
||||
|
||||
|
@ -378,6 +378,23 @@ special options turned on:
|
||||
buildInputs = [ R zeromq zlib ];
|
||||
}
|
||||
|
||||
You can select a particular GHC version to compile with by setting the
|
||||
`ghc` attribute as an argument to `buildStackProject`. Better yet, let
|
||||
Stack choose what GHC version it wants based on the snapshot specified
|
||||
in `stack.yaml` (only works with Stack >= 1.1.3):
|
||||
|
||||
{nixpkgs ? import <nixpkgs> { }, ghc ? nixpkgs.ghc}
|
||||
|
||||
with nixpkgs;
|
||||
|
||||
let R = pkgs.R.override { enableStrictBarrier = true; };
|
||||
in
|
||||
haskell.lib.buildStackProject {
|
||||
name = "HaskellR";
|
||||
buildInputs = [ R zeromq zlib ];
|
||||
inherit ghc;
|
||||
}
|
||||
|
||||
[stack-nix-doc]: http://docs.haskellstack.org/en/stable/nix_integration.html
|
||||
|
||||
### How to create ad hoc environments for `nix-shell`
|
||||
@ -636,7 +653,7 @@ then you have to download and re-install `foo` and all its dependents from
|
||||
scratch:
|
||||
|
||||
# nix-store -q --referrers /nix/store/*-haskell-text-1.2.0.4 \
|
||||
| xargs -L 1 nix-store --repair-path --option binary-caches http://hydra.nixos.org
|
||||
| xargs -L 1 nix-store --repair-path
|
||||
|
||||
If you're using additional Hydra servers other than `hydra.nixos.org`, then it
|
||||
might be necessary to purge the local caches that store data from those
|
||||
|
@ -532,6 +532,7 @@ All parameters from `mkDerivation` function are still supported.
|
||||
* `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'"].
|
||||
* `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`.
|
||||
* `catchConflicts` If `true`, abort package build if a package name appears more than once in dependency tree. Default is `true`.
|
||||
|
||||
#### `buildPythonApplication` function
|
||||
|
||||
@ -648,6 +649,56 @@ community to help save time. No tool is preferred at the moment.
|
||||
|
||||
## FAQ
|
||||
|
||||
### How can I install a working Python environment?
|
||||
|
||||
As explained in the user's guide installing individual Python packages
|
||||
imperatively with `nix-env -i` or declaratively in `environment.systemPackages`
|
||||
is not supported. However, it is possible to install a Python environment with packages (`python.buildEnv`).
|
||||
|
||||
In the following examples we create an environment with Python 3.5, `numpy` and `ipython`.
|
||||
As you might imagine there is one limitation here, and that's you can install
|
||||
only one environment at a time. You will notice the complaints about collisions
|
||||
when you try to install a second environment.
|
||||
|
||||
#### Environment defined in separate `.nix` file
|
||||
|
||||
Create a file, e.g. `build.nix`, with the following expression
|
||||
```nix
|
||||
with import <nixpkgs> {};
|
||||
with python35Packages;
|
||||
|
||||
python.withPackages (ps: with ps; [ numpy ipython ])
|
||||
```
|
||||
and install it in your profile with
|
||||
```
|
||||
nix-env -if build.nix
|
||||
```
|
||||
Now you can use the Python interpreter, as well as the extra packages that you added to the environment.
|
||||
|
||||
#### Environment defined in `~/.nixpkgs/config.nix`
|
||||
|
||||
If you prefer to, you could also add the environment as a package override to the Nixpkgs set.
|
||||
```
|
||||
packageOverrides = pkgs: with pkgs; with python35Packages; {
|
||||
myEnv = python.withPackages (ps: with ps; [ numpy ipython ]);
|
||||
};
|
||||
```
|
||||
and install it in your profile with
|
||||
```
|
||||
nix-env -iA nixos.blogEnv
|
||||
```
|
||||
Note that I'm using the attribute path here.
|
||||
|
||||
#### Environment defined in `/etc/nixos/configuration.nix`
|
||||
|
||||
For the sake of completeness, here's another example how to install the environment system-wide.
|
||||
|
||||
```nix
|
||||
environment.systemPackages = with pkgs; [
|
||||
(python35Packages.python.withPackages (ps: callPackage ../packages/common-python-packages.nix { pythonPackages = ps; }))
|
||||
];
|
||||
```
|
||||
|
||||
### How to solve circular dependencies?
|
||||
|
||||
Consider the packages `A` and `B` that depend on each other. When packaging `B`,
|
||||
|
@ -1196,10 +1196,24 @@ echo @foo@
|
||||
<term><function>stripHash</function>
|
||||
<replaceable>path</replaceable></term>
|
||||
<listitem><para>Strips the directory and hash part of a store
|
||||
path, and prints (on standard output) only the name part. For
|
||||
instance, <literal>stripHash
|
||||
/nix/store/68afga4khv0w...-coreutils-6.12</literal> print
|
||||
<literal>coreutils-6.12</literal>.</para></listitem>
|
||||
path, storing the name part in the environment variable
|
||||
<literal>strippedName</literal>. For example:
|
||||
|
||||
<programlisting>
|
||||
stripHash "/nix/store/9s9r019176g7cvn2nvcw41gsp862y6b4-coreutils-8.24"
|
||||
# prints coreutils-8.24
|
||||
echo $strippedName
|
||||
</programlisting>
|
||||
|
||||
If you wish to store the result in another variable, then the
|
||||
following idiom may be useful:
|
||||
|
||||
<programlisting>
|
||||
name="/nix/store/9s9r019176g7cvn2nvcw41gsp862y6b4-coreutils-8.24"
|
||||
someVar=$(stripHash $name; echo $strippedName)
|
||||
</programlisting>
|
||||
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
|
@ -457,7 +457,6 @@ rec {
|
||||
|
||||
/*** deprecated stuff ***/
|
||||
|
||||
deepSeqAttrs = throw "removed 2016-02-29 because unused and broken";
|
||||
zipWithNames = zipAttrsWithNames;
|
||||
zip = builtins.trace
|
||||
"lib.zip is deprecated, use lib.zipAttrsWith instead" zipAttrsWith;
|
||||
|
@ -68,18 +68,7 @@ rec {
|
||||
imap (i: v: "${v}-${toString i}") ["a" "b"]
|
||||
=> [ "a-1" "b-2" ]
|
||||
*/
|
||||
imap =
|
||||
if builtins ? genList then
|
||||
f: list: genList (n: f (n + 1) (elemAt list n)) (length list)
|
||||
else
|
||||
f: list:
|
||||
let
|
||||
len = length list;
|
||||
imap' = n:
|
||||
if n == len
|
||||
then []
|
||||
else [ (f (n + 1) (elemAt list n)) ] ++ imap' (n + 1);
|
||||
in imap' 0;
|
||||
imap = f: list: genList (n: f (n + 1) (elemAt list n)) (length list);
|
||||
|
||||
/* Map and concatenate the result.
|
||||
|
||||
@ -216,17 +205,11 @@ rec {
|
||||
range 3 2
|
||||
=> [ ]
|
||||
*/
|
||||
range =
|
||||
if builtins ? genList then
|
||||
first: last:
|
||||
if first > last
|
||||
then []
|
||||
else genList (n: first + n) (last - first + 1)
|
||||
range = first: last:
|
||||
if first > last then
|
||||
[]
|
||||
else
|
||||
first: last:
|
||||
if last < first
|
||||
then []
|
||||
else [first] ++ range (first + 1) last;
|
||||
genList (n: first + n) (last - first + 1);
|
||||
|
||||
/* Splits the elements of a list in two lists, `right' and
|
||||
`wrong', depending on the evaluation of a predicate.
|
||||
@ -250,19 +233,9 @@ rec {
|
||||
zipListsWith (a: b: a + b) ["h" "l"] ["e" "o"]
|
||||
=> ["he" "lo"]
|
||||
*/
|
||||
zipListsWith =
|
||||
if builtins ? genList then
|
||||
f: fst: snd: genList (n: f (elemAt fst n) (elemAt snd n)) (min (length fst) (length snd))
|
||||
else
|
||||
f: fst: snd:
|
||||
let
|
||||
len = min (length fst) (length snd);
|
||||
zipListsWith' = n:
|
||||
if n != len then
|
||||
[ (f (elemAt fst n) (elemAt snd n)) ]
|
||||
++ zipListsWith' (n + 1)
|
||||
else [];
|
||||
in zipListsWith' 0;
|
||||
zipListsWith = f: fst: snd:
|
||||
genList
|
||||
(n: f (elemAt fst n) (elemAt snd n)) (min (length fst) (length snd));
|
||||
|
||||
/* Merges two lists of the same size together. If the sizes aren't the same
|
||||
the merging stops at the shortest.
|
||||
@ -280,11 +253,8 @@ rec {
|
||||
reverseList [ "b" "o" "j" ]
|
||||
=> [ "j" "o" "b" ]
|
||||
*/
|
||||
reverseList =
|
||||
if builtins ? genList then
|
||||
xs: let l = length xs; in genList (n: elemAt xs (l - n - 1)) l
|
||||
else
|
||||
fold (e: acc: acc ++ [ e ]) [];
|
||||
reverseList = xs:
|
||||
let l = length xs; in genList (n: elemAt xs (l - n - 1)) l;
|
||||
|
||||
/* Sort a list based on a comparator function which compares two
|
||||
elements and returns true if the first argument is strictly below
|
||||
@ -320,19 +290,7 @@ rec {
|
||||
take 2 [ ]
|
||||
=> [ ]
|
||||
*/
|
||||
take =
|
||||
if builtins ? genList then
|
||||
count: sublist 0 count
|
||||
else
|
||||
count: list:
|
||||
let
|
||||
len = length list;
|
||||
take' = n:
|
||||
if n == len || n == count
|
||||
then []
|
||||
else
|
||||
[ (elemAt list n) ] ++ take' (n + 1);
|
||||
in take' 0;
|
||||
take = count: sublist 0 count;
|
||||
|
||||
/* Remove the first (at most) N elements of a list.
|
||||
|
||||
@ -342,19 +300,7 @@ rec {
|
||||
drop 2 [ ]
|
||||
=> [ ]
|
||||
*/
|
||||
drop =
|
||||
if builtins ? genList then
|
||||
count: list: sublist count (length list) list
|
||||
else
|
||||
count: list:
|
||||
let
|
||||
len = length list;
|
||||
drop' = n:
|
||||
if n == -1 || n < count
|
||||
then []
|
||||
else
|
||||
drop' (n - 1) ++ [ (elemAt list n) ];
|
||||
in drop' (len - 1);
|
||||
drop = count: list: sublist count (length list) list;
|
||||
|
||||
/* Return a list consisting of at most ‘count’ elements of ‘list’,
|
||||
starting at index ‘start’.
|
||||
@ -428,8 +374,4 @@ rec {
|
||||
*/
|
||||
subtractLists = e: filter (x: !(elem x e));
|
||||
|
||||
/*** deprecated stuff ***/
|
||||
|
||||
deepSeqList = throw "removed 2016-02-29 because unused and broken";
|
||||
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
adev = "Adrien Devresse <adev@adev.name>";
|
||||
Adjective-Object = "Maxwell Huang-Hobbs <mhuan13@gmail.com>";
|
||||
adnelson = "Allen Nelson <ithinkican@gmail.com>";
|
||||
adolfogc = "Adolfo E. García Castro <adolfo.garcia.cr@gmail.com>";
|
||||
aespinosa = "Allan Espinosa <allan.espinosa@outlook.com>";
|
||||
aflatter = "Alexander Flatter <flatter@fastmail.fm>";
|
||||
aforemny = "Alexander Foremny <alexanderforemny@googlemail.com>";
|
||||
@ -70,6 +71,7 @@
|
||||
c0dehero = "CodeHero <codehero@nerdpol.ch>";
|
||||
calrama = "Moritz Maxeiner <moritz@ucworks.org>";
|
||||
campadrenalin = "Philip Horger <campadrenalin@gmail.com>";
|
||||
carlsverre = "Carl Sverre <accounts@carlsverre.com>";
|
||||
cdepillabout = "Dennis Gosnell <cdep.illabout@gmail.com>";
|
||||
cfouche = "Chaddaï Fouché <chaddai.fouche@gmail.com>";
|
||||
chaoflow = "Florian Friesdorf <flo@chaoflow.net>";
|
||||
@ -78,6 +80,7 @@
|
||||
chris-martin = "Chris Martin <ch.martin@gmail.com>";
|
||||
chrisjefferson = "Christopher Jefferson <chris@bubblescope.net>";
|
||||
christopherpoole = "Christopher Mark Poole <mail@christopherpoole.net>";
|
||||
cko = "Christine Koppelt <christine.koppelt@gmail.com>";
|
||||
cleverca22 = "Michael Bishop <cleverca22@gmail.com>";
|
||||
cmcdragonkai = "Roger Qiu <roger.qiu@matrix.ai>";
|
||||
coconnor = "Corey O'Connor <coreyoconnor@gmail.com>";
|
||||
@ -131,6 +134,7 @@
|
||||
falsifian = "James Cook <james.cook@utoronto.ca>";
|
||||
flosse = "Markus Kohlhase <mail@markus-kohlhase.de>";
|
||||
fluffynukeit = "Daniel Austin <dan@fluffynukeit.com>";
|
||||
fmthoma = "Franz Thoma <f.m.thoma@googlemail.com>";
|
||||
forkk = "Andrew Okin <forkk@forkk.net>";
|
||||
fornever = "Friedrich von Never <friedrich@fornever.me>";
|
||||
fpletz = "Franz Pletz <fpletz@fnordicwalking.de>";
|
||||
@ -182,6 +186,7 @@
|
||||
joamaki = "Jussi Maki <joamaki@gmail.com>";
|
||||
joelmo = "Joel Moberg <joel.moberg@gmail.com>";
|
||||
joelteon = "Joel Taylor <me@joelt.io>";
|
||||
joko = "Ioannis Koutras <ioannis.koutras@gmail.com>";
|
||||
jpbernardy = "Jean-Philippe Bernardy <jeanphilippe.bernardy@gmail.com>";
|
||||
jraygauthier = "Raymond Gauthier <jraygauthier@gmail.com>";
|
||||
juliendehos = "Julien Dehos <dehos@lisic.univ-littoral.fr>";
|
||||
@ -228,6 +233,7 @@
|
||||
markus1189 = "Markus Hauck <markus1189@gmail.com>";
|
||||
markWot = "Markus Wotringer <markus@wotringer.de>";
|
||||
martijnvermaat = "Martijn Vermaat <martijn@vermaat.name>";
|
||||
martingms = "Martin Gammelsæter <martin@mg.am>";
|
||||
matejc = "Matej Cotman <cotman.matej@gmail.com>";
|
||||
mathnerd314 = "Mathnerd314 <mathnerd314.gph+hs@gmail.com>";
|
||||
matthiasbeyer = "Matthias Beyer <mail@beyermatthias.de>";
|
||||
@ -252,6 +258,7 @@
|
||||
mornfall = "Petr Ročkai <me@mornfall.net>";
|
||||
MostAwesomeDude = "Corbin Simpson <cds@corbinsimpson.com>";
|
||||
MP2E = "Cray Elliott <MP2E@archlinux.us>";
|
||||
mpscholten = "Marc Scholten <marc@mpscholten.de>";
|
||||
msackman = "Matthew Sackman <matthew@wellquite.org>";
|
||||
mschristiansen = "Mikkel Christiansen <mikkel@rheosystems.com>";
|
||||
msteen = "Matthijs Steen <emailmatthijs@gmail.com>";
|
||||
@ -260,6 +267,7 @@
|
||||
muflax = "Stefan Dorn <mail@muflax.com>";
|
||||
myrl = "Myrl Hex <myrl.0xf@gmail.com>";
|
||||
nathan-gs = "Nathan Bijnens <nathan@nathan.gs>";
|
||||
Nate-Devv = "Nathan Moore <natedevv@gmail.com>";
|
||||
nckx = "Tobias Geerinckx-Rice <tobias.geerinckx.rice@gmail.com>";
|
||||
nequissimus = "Tim Steinbach <tim@nequissimus.com>";
|
||||
nfjinjing = "Jinjing Wang <nfjinjing@gmail.com>";
|
||||
@ -273,6 +281,7 @@
|
||||
odi = "Oliver Dunkl <oliver.dunkl@gmail.com>";
|
||||
offline = "Jaka Hudoklin <jakahudoklin@gmail.com>";
|
||||
olcai = "Erik Timan <dev@timan.info>";
|
||||
olejorgenb = "Ole Jørgen Brønner <olejorgenb@yahoo.no>";
|
||||
orbitz = "Malcolm Matalka <mmatalka@gmail.com>";
|
||||
osener = "Ozan Sener <ozan@ozansener.com>";
|
||||
otwieracz = "Slawomir Gonet <slawek@otwiera.cz>";
|
||||
@ -282,6 +291,7 @@
|
||||
pakhfn = "Fedor Pakhomov <pakhfn@gmail.com>";
|
||||
palo = "Ingolf Wanger <palipalo9@googlemail.com>";
|
||||
pashev = "Igor Pashev <pashev.igor@gmail.com>";
|
||||
pawelpacana = "Paweł Pacana <pawel.pacana@gmail.com>";
|
||||
pesterhazy = "Paulus Esterhazy <pesterhazy@gmail.com>";
|
||||
peterhoeg = "Peter Hoeg <peter@hoeg.com>";
|
||||
peti = "Peter Simons <simons@cryp.to>";
|
||||
@ -307,6 +317,8 @@
|
||||
pxc = "Patrick Callahan <patrick.callahan@latitudeengineering.com>";
|
||||
qknight = "Joachim Schiele <js@lastlog.de>";
|
||||
ragge = "Ragnar Dahlen <r.dahlen@gmail.com>";
|
||||
ralith = "Benjamin Saunders <ben.e.saunders@gmail.com>";
|
||||
ramkromberg = "Ram Kromberg <ramkromberg@mail.com>";
|
||||
rardiol = "Ricardo Ardissone <ricardo.ardissone@gmail.com>";
|
||||
rasendubi = "Alexey Shmalko <rasen.dubi@gmail.com>";
|
||||
raskin = "Michael Raskin <7c6f434c@mail.ru>";
|
||||
@ -352,11 +364,13 @@
|
||||
skrzyp = "Jakub Skrzypnik <jot.skrzyp@gmail.com>";
|
||||
sleexyz = "Sean Lee <freshdried@gmail.com>";
|
||||
smironov = "Sergey Mironov <ierton@gmail.com>";
|
||||
solson = "Scott Olson <scott@solson.me>";
|
||||
spacefrogg = "Michael Raitza <spacefrogg-nixos@meterriblecrew.net>";
|
||||
spencerjanssen = "Spencer Janssen <spencerjanssen@gmail.com>";
|
||||
spinus = "Tomasz Czyż <tomasz.czyz@gmail.com>";
|
||||
sprock = "Roger Mason <rmason@mun.ca>";
|
||||
spwhitt = "Spencer Whitt <sw@swhitt.me>";
|
||||
SShrike = "Severen Redwood <severen@shrike.me>";
|
||||
stephenmw = "Stephen Weinberg <stephen@q5comm.com>";
|
||||
steveej = "Stefan Junker <mail@stefanjunker.de>";
|
||||
swistak35 = "Rafał Łasocha <me@swistak35.com>";
|
||||
@ -409,6 +423,7 @@
|
||||
wscott = "Wayne Scott <wsc9tt@gmail.com>";
|
||||
wyvie = "Elijah Rum <elijahrum@gmail.com>";
|
||||
yarr = "Dmitry V. <savraz@gmail.com>";
|
||||
yurrriq = "Eric Bailey <eric@ericb.me>";
|
||||
z77z = "Marco Maggesi <maggesi@math.unifi.it>";
|
||||
zagy = "Christian Zagrodnick <cz@flyingcircus.io>";
|
||||
zef = "Zef Hemel <zef@zef.me>";
|
||||
|
@ -16,11 +16,7 @@ rec {
|
||||
concatStrings ["foo" "bar"]
|
||||
=> "foobar"
|
||||
*/
|
||||
concatStrings =
|
||||
if builtins ? concatStringsSep then
|
||||
builtins.concatStringsSep ""
|
||||
else
|
||||
lib.foldl' (x: y: x + y) "";
|
||||
concatStrings = builtins.concatStringsSep "";
|
||||
|
||||
/* Map a function over a list and concatenate the resulting strings.
|
||||
|
||||
@ -207,13 +203,21 @@ rec {
|
||||
*/
|
||||
escape = list: replaceChars list (map (c: "\\${c}") list);
|
||||
|
||||
/* Escape all characters that have special meaning in the Bourne shell.
|
||||
/* Quote string to be used safely within the Bourne shell.
|
||||
|
||||
Example:
|
||||
escapeShellArg "so([<>])me"
|
||||
=> "so\\(\\[\\<\\>\\]\\)me"
|
||||
escapeShellArg "esc'ape\nme"
|
||||
=> "'esc'\\''ape\nme'"
|
||||
*/
|
||||
escapeShellArg = lib.escape (stringToCharacters "\\ ';$`()|<>\t*[]");
|
||||
escapeShellArg = arg: "'${replaceStrings ["'"] ["'\\''"] (toString arg)}'";
|
||||
|
||||
/* Quote all arguments to be safely passed to the Bourne shell.
|
||||
|
||||
Example:
|
||||
escapeShellArgs ["one" "two three" "four'five"]
|
||||
=> "'one' 'two three' 'four'\\''five'"
|
||||
*/
|
||||
escapeShellArgs = concatMapStringsSep " " escapeShellArg;
|
||||
|
||||
/* Obsolete - use replaceStrings instead. */
|
||||
replaceChars = builtins.replaceStrings or (
|
||||
|
@ -1,6 +1,6 @@
|
||||
{ nixpkgs }:
|
||||
|
||||
with import ./../.. { };
|
||||
with import ../.. { };
|
||||
with lib;
|
||||
|
||||
stdenv.mkDerivation {
|
||||
|
@ -100,6 +100,10 @@ rec {
|
||||
in if isDerivation res then res else toDerivation res;
|
||||
};
|
||||
|
||||
shellPackage = package // {
|
||||
check = x: (package.check x) && (hasAttr "shellPath" x);
|
||||
};
|
||||
|
||||
path = mkOptionType {
|
||||
name = "path";
|
||||
# Hacky: there is no ‘isPath’ primop.
|
||||
|
49
maintainers/scripts/fetch-kde-qt.sh
Executable file
49
maintainers/scripts/fetch-kde-qt.sh
Executable file
@ -0,0 +1,49 @@
|
||||
#! /usr/bin/env nix-shell
|
||||
#! nix-shell -i bash -p coreutils findutils gnused nix wget
|
||||
|
||||
tmp=$(mktemp -d)
|
||||
pushd $tmp >/dev/null
|
||||
wget -nH -r -c --no-parent "$@" >/dev/null
|
||||
|
||||
csv=$(mktemp)
|
||||
find . -type f | while read src; do
|
||||
# Sanitize file name
|
||||
filename=$(basename "$src" | tr '@' '_')
|
||||
nameVersion="${filename%.tar.*}"
|
||||
name=$(echo "$nameVersion" | sed -e 's,-[[:digit:]].*,,' | sed -e 's,-opensource-src$,,')
|
||||
version=$(echo "$nameVersion" | sed -e 's,^\([[:alpha:]][[:alnum:]]*-\)\+,,')
|
||||
echo "$name,$version,$src,$filename" >>$csv
|
||||
done
|
||||
|
||||
cat <<EOF
|
||||
# DO NOT EDIT! This file is generated automatically by fetchsrcs.sh
|
||||
{ fetchurl, mirror }:
|
||||
|
||||
{
|
||||
EOF
|
||||
|
||||
gawk -F , "{ print \$1 }" $csv | sort | uniq | while read name; do
|
||||
versions=$(gawk -F , "/^$name,/ { print \$2 }" $csv)
|
||||
latestVersion=$(echo "$versions" | sort -rV | head -n 1)
|
||||
src=$(gawk -F , "/^$name,$latestVersion,/ { print \$3 }" $csv)
|
||||
filename=$(gawk -F , "/^$name,$latestVersion,/ { print \$4 }" $csv)
|
||||
url="${src:2}"
|
||||
sha256=$(nix-hash --type sha256 --base32 --flat "$src")
|
||||
cat <<EOF
|
||||
$name = {
|
||||
version = "$latestVersion";
|
||||
src = fetchurl {
|
||||
url = "\${mirror}/$url";
|
||||
sha256 = "$sha256";
|
||||
name = "$filename";
|
||||
};
|
||||
};
|
||||
EOF
|
||||
done
|
||||
|
||||
echo "}"
|
||||
|
||||
popd >/dev/null
|
||||
rm -fr $tmp >/dev/null
|
||||
|
||||
rm -f $csv >/dev/null
|
5
maintainers/scripts/generate-kde-applications.sh
Executable file
5
maintainers/scripts/generate-kde-applications.sh
Executable file
@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
./maintainers/scripts/fetch-kde-qt.sh \
|
||||
http://download.kde.org/stable/applications/16.04.3/ -A '*.tar.xz' \
|
||||
>pkgs/desktops/kde-5/applications/srcs.nix
|
5
maintainers/scripts/generate-kde-frameworks.sh
Executable file
5
maintainers/scripts/generate-kde-frameworks.sh
Executable file
@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
./maintainers/scripts/fetch-kde-qt.sh \
|
||||
http://download.kde.org/stable/frameworks/5.24/ -A '*.tar.xz' \
|
||||
>pkgs/desktops/kde-5/frameworks/srcs.nix
|
5
maintainers/scripts/generate-kde-plasma.sh
Executable file
5
maintainers/scripts/generate-kde-plasma.sh
Executable file
@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
./maintainers/scripts/fetch-kde-qt.sh \
|
||||
http://download.kde.org/stable/plasma/5.7.1/ -A '*.tar.xz' \
|
||||
>pkgs/desktops/kde-5/plasma/srcs.nix
|
3
maintainers/scripts/generate-qt.sh
Executable file
3
maintainers/scripts/generate-qt.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
./fetch-kde-qt.sh http://download.qt.io/official_releases/qt/5.6/5.6.1/submodules/ -A '*.tar.xz'
|
@ -13,10 +13,6 @@ if [[ $1 == nix ]]; then
|
||||
sudo mkdir /etc/nix
|
||||
sudo sh -c 'echo "build-max-jobs = 4" > /etc/nix/nix.conf'
|
||||
|
||||
# Nix builds in /tmp and we need exec support
|
||||
sudo mount
|
||||
sudo mount -o remount,exec /run
|
||||
|
||||
# Verify evaluation
|
||||
echo "=== Verifying that nixpkgs evaluates..."
|
||||
nix-env -f. -qa --json >/dev/null
|
||||
@ -30,6 +26,11 @@ elif [[ $1 == build ]]; then
|
||||
if [[ $TRAVIS_OS_NAME == "osx" ]]; then
|
||||
echo "Skipping NixOS things on darwin"
|
||||
else
|
||||
# Nix builds in /tmp and we need exec support
|
||||
sudo mount -o remount,exec /run
|
||||
sudo mount -o remount,exec /run/user
|
||||
sudo mount
|
||||
|
||||
echo "=== Checking NixOS options"
|
||||
nix-build nixos/release.nix -A options --show-trace
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
(with empty password).</para></listitem>
|
||||
|
||||
<listitem><para>If you downloaded the graphical ISO image, you can
|
||||
run <command>start display-manager</command> to start KDE. If you
|
||||
run <command>systemctl start display-manager</command> to start KDE. If you
|
||||
want to continue on the terminal, you can use
|
||||
<command>loadkeys</command> to switch to your preferred keyboard layout.
|
||||
(We even provide neo2 via <command>loadkeys de neo</command>!)</para></listitem>
|
||||
|
97
nixos/doc/manual/man-nixos-version.xml
Normal file
97
nixos/doc/manual/man-nixos-version.xml
Normal file
@ -0,0 +1,97 @@
|
||||
<refentry xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
|
||||
<refmeta>
|
||||
<refentrytitle><command>nixos-version</command></refentrytitle>
|
||||
<manvolnum>8</manvolnum>
|
||||
<refmiscinfo class="source">NixOS</refmiscinfo>
|
||||
</refmeta>
|
||||
|
||||
<refnamediv>
|
||||
<refname><command>nixos-version</command></refname>
|
||||
<refpurpose>show the NixOS version</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
<refsynopsisdiv>
|
||||
<cmdsynopsis>
|
||||
<command>nixos-version</command>
|
||||
<arg><option>--hash</option></arg>
|
||||
<arg><option>--revision</option></arg>
|
||||
</cmdsynopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
<refsection><title>Description</title>
|
||||
|
||||
<para>This command shows the version of the currently active NixOS
|
||||
configuration. For example:
|
||||
|
||||
<screen>$ nixos-version
|
||||
16.03.1011.6317da4 (Emu)
|
||||
</screen>
|
||||
|
||||
The version consists of the following elements:
|
||||
|
||||
<variablelist>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>16.03</literal></term>
|
||||
<listitem><para>The NixOS release, indicating the year and month
|
||||
in which it was released (e.g. March 2016).</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>1011</literal></term>
|
||||
<listitem><para>The number of commits in the Nixpkgs Git
|
||||
repository between the start of the release branch and the commit
|
||||
from which this version was built. This ensures that NixOS
|
||||
versions are monotonically increasing. It is
|
||||
<literal>git</literal> when the current NixOS configuration was
|
||||
built from a checkout of the Nixpkgs Git repository rather than
|
||||
from a NixOS channel.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>6317da4</literal></term>
|
||||
<listitem><para>The first 7 characters of the commit in the
|
||||
Nixpkgs Git repository from which this version was
|
||||
built.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>Emu</literal></term>
|
||||
<listitem><para>The code name of the NixOS release. The first
|
||||
letter of the code name indicates that this is the N'th stable
|
||||
NixOS release; for example, Emu is the fifth
|
||||
release.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
</para>
|
||||
|
||||
</refsection>
|
||||
|
||||
|
||||
<refsection><title>Options</title>
|
||||
|
||||
<para>This command accepts the following options:</para>
|
||||
|
||||
<variablelist>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--hash</option></term>
|
||||
<term><option>--revision</option></term>
|
||||
<listitem>
|
||||
<para>Show the full SHA1 hash of the Git commit from which this
|
||||
configuration was built, e.g.
|
||||
<screen>$ nixos-version --hash
|
||||
6317da40006f6bc2480c6781999c52d88dde2acf
|
||||
</screen>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
</refsection>
|
||||
</refentry>
|
@ -27,5 +27,6 @@
|
||||
<xi:include href="man-nixos-install.xml" />
|
||||
<xi:include href="man-nixos-option.xml" />
|
||||
<xi:include href="man-nixos-rebuild.xml" />
|
||||
<xi:include href="man-nixos-version.xml" />
|
||||
|
||||
</reference>
|
||||
|
@ -113,14 +113,14 @@ rec {
|
||||
--add-flags "$vms" \
|
||||
${lib.optionalString enableOCR "--prefix PATH : '${ocrProg}/bin'"} \
|
||||
--run "testScript=\"\$(cat $out/test-script)\"" \
|
||||
--set testScript '"$testScript"' \
|
||||
--set VLANS '"${toString vlans}"'
|
||||
--set testScript '$testScript' \
|
||||
--set VLANS '${toString vlans}'
|
||||
ln -s ${testDriver}/bin/nixos-test-driver $out/bin/nixos-run-vms
|
||||
wrapProgram $out/bin/nixos-run-vms \
|
||||
--add-flags "$vms" \
|
||||
${lib.optionalString enableOCR "--prefix PATH : '${ocrProg}/bin'"} \
|
||||
--set tests '"startAll; joinAll;"' \
|
||||
--set VLANS '"${toString vlans}"' \
|
||||
--set tests 'startAll; joinAll;' \
|
||||
--set VLANS '${toString vlans}' \
|
||||
${lib.optionalString (builtins.length vms == 1) "--set USE_SERIAL 1"}
|
||||
''; # "
|
||||
|
||||
|
@ -8,4 +8,12 @@ rec {
|
||||
replaceChars ["/" "-" " "] ["-" "\\x2d" "\\x20"]
|
||||
(if hasPrefix "/" s then substring 1 (stringLength s) s else s);
|
||||
|
||||
# Returns a system path for a given shell package
|
||||
toShellPath = shell:
|
||||
if types.shellPackage.check shell then
|
||||
"/run/current-system/sw${shell.shellPath}"
|
||||
else if types.package.check shell then
|
||||
throw "${shell} is not a shell package"
|
||||
else
|
||||
shell;
|
||||
}
|
||||
|
@ -13,8 +13,11 @@ echo "NixOS version is $version ($major)"
|
||||
|
||||
rm -f ec2-amis.nix
|
||||
|
||||
types="hvm pv"
|
||||
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"
|
||||
|
||||
for type in hvm pv; do
|
||||
for type in $types; do
|
||||
link=$stateDir/$type
|
||||
imageFile=$link/nixos.qcow2
|
||||
system=x86_64-linux
|
||||
@ -31,7 +34,7 @@ for type in hvm pv; do
|
||||
--arg configuration "{ imports = [ <nixpkgs/nixos/maintainers/scripts/ec2/amazon-image.nix> ]; ec2.hvm = $hvmFlag; }"
|
||||
fi
|
||||
|
||||
for store in ebs s3; do
|
||||
for store in $stores; do
|
||||
|
||||
bucket=nixos-amis
|
||||
bucketDir="$version-$type-$store"
|
||||
@ -39,7 +42,7 @@ for type in hvm pv; do
|
||||
prevAmi=
|
||||
prevRegion=
|
||||
|
||||
for region in eu-west-1 eu-central-1 us-east-1 us-west-1 us-west-2 ap-southeast-1 ap-southeast-2 ap-northeast-1 sa-east-1; do
|
||||
for region in $regions; do
|
||||
|
||||
name=nixos-$version-$arch-$type-$store
|
||||
description="NixOS $system $version ($type-$store)"
|
||||
@ -51,10 +54,11 @@ for type in hvm pv; do
|
||||
echo "doing $name in $region..."
|
||||
|
||||
if [ -n "$prevAmi" ]; then
|
||||
ami=$(ec2-copy-image \
|
||||
ami=$(aws ec2 copy-image \
|
||||
--region "$region" \
|
||||
--source-region "$prevRegion" --source-ami-id "$prevAmi" \
|
||||
--name "$name" --description "$description" | cut -f 2)
|
||||
--source-region "$prevRegion" --source-image-id "$prevAmi" \
|
||||
--name "$name" --description "$description" | json -q .ImageId)
|
||||
if [ "$ami" = null ]; then break; fi
|
||||
else
|
||||
|
||||
if [ $store = s3 ]; then
|
||||
@ -85,12 +89,12 @@ for type in hvm pv; do
|
||||
ec2-upload-bundle \
|
||||
-m $imageDir/$type.raw.manifest.xml \
|
||||
-b "$bucket/$bucketDir" \
|
||||
-a "$EC2_ACCESS_KEY" -s "$EC2_SECRET_KEY" \
|
||||
-a "$AWS_ACCESS_KEY_ID" -s "$AWS_SECRET_ACCESS_KEY" \
|
||||
--location EU
|
||||
touch $imageDir/uploaded
|
||||
fi
|
||||
|
||||
extraFlags="$bucket/$bucketDir/$type.raw.manifest.xml"
|
||||
extraFlags="--image-location $bucket/$bucketDir/$type.raw.manifest.xml"
|
||||
|
||||
else
|
||||
|
||||
@ -115,7 +119,8 @@ for type in hvm pv; do
|
||||
if [ -z "$snapId" -a -z "$volId" -a -z "$taskId" ]; then
|
||||
echo "importing $vhdFile..."
|
||||
taskId=$(ec2-import-volume $vhdFile --no-upload -f vhd \
|
||||
-o "$EC2_ACCESS_KEY" -w "$EC2_SECRET_KEY" \
|
||||
-O "$AWS_ACCESS_KEY_ID" -W "$AWS_SECRET_ACCESS_KEY" \
|
||||
-o "$AWS_ACCESS_KEY_ID" -w "$AWS_SECRET_ACCESS_KEY" \
|
||||
--region "$region" -z "${region}a" \
|
||||
--bucket "$bucket" --prefix "$bucketDir/" \
|
||||
| tee /dev/stderr \
|
||||
@ -125,15 +130,16 @@ for type in hvm pv; do
|
||||
|
||||
if [ -z "$snapId" -a -z "$volId" ]; then
|
||||
ec2-resume-import $vhdFile -t "$taskId" --region "$region" \
|
||||
-o "$EC2_ACCESS_KEY" -w "$EC2_SECRET_KEY"
|
||||
-O "$AWS_ACCESS_KEY_ID" -W "$AWS_SECRET_ACCESS_KEY" \
|
||||
-o "$AWS_ACCESS_KEY_ID" -w "$AWS_SECRET_ACCESS_KEY"
|
||||
fi
|
||||
|
||||
# Wait for the volume creation to finish.
|
||||
if [ -z "$snapId" -a -z "$volId" ]; then
|
||||
echo "waiting for import to finish..."
|
||||
while true; do
|
||||
volId=$(ec2-describe-conversion-tasks "$taskId" --region "$region" | sed 's/.*VolumeId.*\(vol-[0-9a-f]\+\).*/\1/ ; t ; d')
|
||||
if [ -n "$volId" ]; then break; fi
|
||||
volId=$(aws ec2 describe-conversion-tasks --conversion-task-ids "$taskId" --region "$region" | jq -r .ConversionTasks[0].ImportVolume.Volume.Id)
|
||||
if [ "$volId" != null ]; then break; fi
|
||||
sleep 10
|
||||
done
|
||||
|
||||
@ -143,22 +149,24 @@ for type in hvm pv; do
|
||||
# Delete the import task.
|
||||
if [ -n "$volId" -a -n "$taskId" ]; then
|
||||
echo "removing import task..."
|
||||
ec2-delete-disk-image -t "$taskId" --region "$region" -o "$EC2_ACCESS_KEY" -w "$EC2_SECRET_KEY" || true
|
||||
ec2-delete-disk-image -t "$taskId" --region "$region" \
|
||||
-O "$AWS_ACCESS_KEY_ID" -W "$AWS_SECRET_ACCESS_KEY" \
|
||||
-o "$AWS_ACCESS_KEY_ID" -w "$AWS_SECRET_ACCESS_KEY" || true
|
||||
rm -f $stateDir/$region.$type.task-id
|
||||
fi
|
||||
|
||||
# Create a snapshot.
|
||||
if [ -z "$snapId" ]; then
|
||||
echo "creating snapshot..."
|
||||
snapId=$(ec2-create-snapshot "$volId" --region "$region" | cut -f 2)
|
||||
snapId=$(aws ec2 create-snapshot --volume-id "$volId" --region "$region" --description "$description" | jq -r .SnapshotId)
|
||||
if [ "$snapId" = null ]; then exit 1; fi
|
||||
echo -n "$snapId" > $stateDir/$region.$type.snap-id
|
||||
ec2-create-tags "$snapId" -t "Name=$description" --region "$region"
|
||||
fi
|
||||
|
||||
# Wait for the snapshot to finish.
|
||||
echo "waiting for snapshot to finish..."
|
||||
while true; do
|
||||
status=$(ec2-describe-snapshots "$snapId" --region "$region" | head -n1 | cut -f 4)
|
||||
status=$(aws ec2 describe-snapshots --snapshot-ids "$snapId" --region "$region" | jq -r .Snapshots[0].State)
|
||||
if [ "$status" = completed ]; then break; fi
|
||||
sleep 10
|
||||
done
|
||||
@ -166,35 +174,50 @@ for type in hvm pv; do
|
||||
# Delete the volume.
|
||||
if [ -n "$volId" ]; then
|
||||
echo "deleting volume..."
|
||||
ec2-delete-volume "$volId" --region "$region" || true
|
||||
aws ec2 delete-volume --volume-id "$volId" --region "$region" || true
|
||||
rm -f $stateDir/$region.$type.vol-id
|
||||
fi
|
||||
|
||||
extraFlags="-b /dev/sda1=$snapId:$vhdFileLogicalGigaBytes:true:gp2"
|
||||
blockDeviceMappings="DeviceName=/dev/sda1,Ebs={SnapshotId=$snapId,VolumeSize=$vhdFileLogicalGigaBytes,DeleteOnTermination=true,VolumeType=gp2}"
|
||||
extraFlags=""
|
||||
|
||||
if [ $type = pv ]; then
|
||||
extraFlags+=" --root-device-name=/dev/sda1"
|
||||
extraFlags+=" --root-device-name /dev/sda1"
|
||||
else
|
||||
extraFlags+=" --root-device-name /dev/sda1"
|
||||
extraFlags+=" --sriov-net-support simple"
|
||||
extraFlags+=" --ena-support"
|
||||
fi
|
||||
|
||||
extraFlags+=" -b /dev/sdb=ephemeral0 -b /dev/sdc=ephemeral1 -b /dev/sdd=ephemeral2 -b /dev/sde=ephemeral3"
|
||||
blockDeviceMappings+=" DeviceName=/dev/sdb,VirtualName=ephemeral0"
|
||||
blockDeviceMappings+=" DeviceName=/dev/sdc,VirtualName=ephemeral1"
|
||||
blockDeviceMappings+=" DeviceName=/dev/sdd,VirtualName=ephemeral2"
|
||||
blockDeviceMappings+=" DeviceName=/dev/sde,VirtualName=ephemeral3"
|
||||
fi
|
||||
|
||||
if [ $type = hvm ]; then
|
||||
extraFlags+=" --sriov-net-support simple"
|
||||
extraFlags+=" --ena-support"
|
||||
fi
|
||||
|
||||
# Register the AMI.
|
||||
if [ $type = pv ]; then
|
||||
kernel=$(ec2-describe-images -o amazon --filter "manifest-location=*pv-grub-hd0_1.04-$arch*" --region "$region" | cut -f 2)
|
||||
[ -n "$kernel" ]
|
||||
kernel=$(aws ec2 describe-images --owner amazon --filters "Name=name,Values=pv-grub-hd0_1.04-$arch.gz" | jq -r .Images[0].ImageId)
|
||||
if [ "$kernel" = null ]; then break; fi
|
||||
echo "using PV-GRUB kernel $kernel"
|
||||
extraFlags+=" --virtualization-type paravirtual --kernel $kernel"
|
||||
else
|
||||
extraFlags+=" --virtualization-type hvm"
|
||||
fi
|
||||
|
||||
ami=$(ec2-register \
|
||||
-n "$name" \
|
||||
-d "$description" \
|
||||
ami=$(aws ec2 register-image \
|
||||
--name "$name" \
|
||||
--description "$description" \
|
||||
--region "$region" \
|
||||
--architecture "$arch" \
|
||||
$extraFlags | cut -f 2)
|
||||
--block-device-mappings $blockDeviceMappings \
|
||||
$extraFlags | jq -r .ImageId)
|
||||
if [ "$ami" = null ]; then break; fi
|
||||
fi
|
||||
|
||||
echo -n "$ami" > $amiFile
|
||||
@ -204,23 +227,45 @@ for type in hvm pv; do
|
||||
ami=$(cat $amiFile)
|
||||
fi
|
||||
|
||||
if [ -z "$NO_WAIT" -o -z "$prevAmi" ]; then
|
||||
echo "waiting for AMI..."
|
||||
while true; do
|
||||
status=$(ec2-describe-images "$ami" --region "$region" | head -n1 | cut -f 5)
|
||||
if [ "$status" = available ]; then break; fi
|
||||
sleep 10
|
||||
done
|
||||
|
||||
ec2-modify-image-attribute \
|
||||
--region "$region" "$ami" -l -a all
|
||||
fi
|
||||
|
||||
echo "region = $region, type = $type, store = $store, ami = $ami"
|
||||
|
||||
if [ -z "$prevAmi" ]; then
|
||||
prevAmi="$ami"
|
||||
prevRegion="$region"
|
||||
fi
|
||||
done
|
||||
|
||||
done
|
||||
|
||||
done
|
||||
|
||||
for type in $types; do
|
||||
link=$stateDir/$type
|
||||
system=x86_64-linux
|
||||
arch=x86_64
|
||||
|
||||
for store in $stores; do
|
||||
|
||||
for region in $regions; do
|
||||
|
||||
name=nixos-$version-$arch-$type-$store
|
||||
amiFile=$stateDir/$region.$type.$store.ami-id
|
||||
ami=$(cat $amiFile)
|
||||
|
||||
echo "region = $region, type = $type, store = $store, ami = $ami"
|
||||
|
||||
echo -n "waiting for AMI..."
|
||||
while true; do
|
||||
status=$(aws ec2 describe-images --image-ids "$ami" --region "$region" | jq -r .Images[0].State)
|
||||
if [ "$status" = available ]; then break; fi
|
||||
sleep 10
|
||||
echo -n '.'
|
||||
done
|
||||
echo
|
||||
|
||||
# Make the image public.
|
||||
aws ec2 modify-image-attribute \
|
||||
--image-id "$ami" --region "$region" --launch-permission 'Add={Group=all}'
|
||||
|
||||
echo " \"$major\".$region.$type-$store = \"$ami\";" >> ec2-amis.nix
|
||||
done
|
||||
|
@ -3,6 +3,84 @@
|
||||
with lib;
|
||||
|
||||
let fcBool = x: if x then "<bool>true</bool>" else "<bool>false</bool>";
|
||||
cfg = config.fonts.fontconfig.ultimate;
|
||||
fontconfigUltimateConf = pkgs.writeText "ultimate-conf" ''
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
|
||||
<fontconfig>
|
||||
|
||||
${optionalString (!cfg.allowBitmaps) ''
|
||||
<!-- Reject bitmap fonts -->
|
||||
<selectfont>
|
||||
<rejectfont>
|
||||
<pattern>
|
||||
<patelt name="scalable"><bool>false</bool></patelt>
|
||||
</pattern>
|
||||
</rejectfont>
|
||||
</selectfont>
|
||||
''}
|
||||
|
||||
${optionalString cfg.allowType1 ''
|
||||
<!-- Reject Type 1 fonts -->
|
||||
<selectfont>
|
||||
<rejectfont>
|
||||
<pattern>
|
||||
<patelt name="fontformat">
|
||||
<string>Type 1</string>
|
||||
</patelt>
|
||||
</pattern>
|
||||
</rejectfont>
|
||||
</selectfont>
|
||||
''}
|
||||
|
||||
<!-- Use embedded bitmaps in fonts like Calibri? -->
|
||||
<match target="font">
|
||||
<edit name="embeddedbitmap" mode="assign">
|
||||
${fcBool cfg.useEmbeddedBitmaps}
|
||||
</edit>
|
||||
</match>
|
||||
|
||||
<!-- Force autohint always -->
|
||||
<match target="font">
|
||||
<edit name="force_autohint" mode="assign">
|
||||
${fcBool cfg.forceAutohint}
|
||||
</edit>
|
||||
</match>
|
||||
|
||||
<!-- Render some monospace TTF fonts as bitmaps -->
|
||||
<match target="pattern">
|
||||
<edit name="bitmap_monospace" mode="assign">
|
||||
${fcBool cfg.renderMonoTTFAsBitmap}
|
||||
</edit>
|
||||
</match>
|
||||
|
||||
</fontconfig>
|
||||
'';
|
||||
confPkg =
|
||||
let version = pkgs.fontconfig.configVersion;
|
||||
in pkgs.runCommand "font-ultimate-conf" {} ''
|
||||
mkdir -p $out/etc/fonts/{,${version}/}conf.d/
|
||||
|
||||
cp ${fontconfigUltimateConf} \
|
||||
$out/etc/fonts/conf.d/52-fontconfig-ultimate.conf
|
||||
|
||||
cp ${fontconfigUltimateConf} \
|
||||
$out/etc/fonts/${version}/conf.d/52-fontconfig-ultimate.conf
|
||||
|
||||
${optionalString (cfg.substitutions != "none") ''
|
||||
cp ${pkgs.fontconfig-ultimate.confd}/etc/fonts/presets/${cfg.substitutions}/*.conf \
|
||||
$out/etc/fonts/conf.d/
|
||||
cp ${pkgs.fontconfig-ultimate.confd}/etc/fonts/presets/${cfg.substitutions}/*.conf \
|
||||
$out/etc/fonts/${version}/conf.d/
|
||||
''}
|
||||
|
||||
ln -s ${pkgs.fontconfig-ultimate.confd}/etc/fonts/conf.d/*.conf \
|
||||
$out/etc/fonts/conf.d/
|
||||
|
||||
ln -s ${pkgs.fontconfig-ultimate.confd}/etc/fonts/conf.d/*.conf \
|
||||
$out/etc/fonts/${version}/conf.d/
|
||||
'';
|
||||
|
||||
in
|
||||
{
|
||||
|
||||
@ -115,78 +193,11 @@ in
|
||||
};
|
||||
|
||||
|
||||
config =
|
||||
let ultimate = config.fonts.fontconfig.ultimate;
|
||||
fontconfigUltimateConf = ''
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
|
||||
<fontconfig>
|
||||
config = mkIf (config.fonts.fontconfig.enable && cfg.enable) {
|
||||
|
||||
${optionalString (!ultimate.allowBitmaps) ''
|
||||
<!-- Reject bitmap fonts -->
|
||||
<selectfont>
|
||||
<rejectfont>
|
||||
<pattern>
|
||||
<patelt name="scalable"><bool>false</bool></patelt>
|
||||
</pattern>
|
||||
</rejectfont>
|
||||
</selectfont>
|
||||
''}
|
||||
|
||||
${optionalString ultimate.allowType1 ''
|
||||
<!-- Reject Type 1 fonts -->
|
||||
<selectfont>
|
||||
<rejectfont>
|
||||
<pattern>
|
||||
<patelt name="fontformat">
|
||||
<string>Type 1</string>
|
||||
</patelt>
|
||||
</pattern>
|
||||
</rejectfont>
|
||||
</selectfont>
|
||||
''}
|
||||
|
||||
<!-- Use embedded bitmaps in fonts like Calibri? -->
|
||||
<match target="font">
|
||||
<edit name="embeddedbitmap" mode="assign">
|
||||
${fcBool ultimate.useEmbeddedBitmaps}
|
||||
</edit>
|
||||
</match>
|
||||
|
||||
<!-- Force autohint always -->
|
||||
<match target="font">
|
||||
<edit name="force_autohint" mode="assign">
|
||||
${fcBool ultimate.forceAutohint}
|
||||
</edit>
|
||||
</match>
|
||||
|
||||
<!-- Render some monospace TTF fonts as bitmaps -->
|
||||
<match target="pattern">
|
||||
<edit name="bitmap_monospace" mode="assign">
|
||||
${fcBool ultimate.renderMonoTTFAsBitmap}
|
||||
</edit>
|
||||
</match>
|
||||
|
||||
${optionalString (ultimate.substitutions != "none") ''
|
||||
<!-- Type 1 font substitutions -->
|
||||
<include ignore_missing="yes">${pkgs.fontconfig-ultimate.confd}/etc/fonts/presets/${ultimate.substitutions}</include>
|
||||
''}
|
||||
|
||||
<include ignore_missing="yes">${pkgs.fontconfig-ultimate.confd}/etc/fonts/conf.d</include>
|
||||
|
||||
</fontconfig>
|
||||
'';
|
||||
in mkIf (config.fonts.fontconfig.enable && ultimate.enable) {
|
||||
|
||||
environment.etc."fonts/conf.d/52-fontconfig-ultimate.conf" = {
|
||||
text = fontconfigUltimateConf;
|
||||
};
|
||||
|
||||
environment.etc."fonts/${pkgs.fontconfig.configVersion}/conf.d/52-fontconfig-ultimate.conf" = {
|
||||
text = fontconfigUltimateConf;
|
||||
};
|
||||
|
||||
environment.variables = ultimate.rendering;
|
||||
fonts.fontconfig.confPkgs = [ confPkg ];
|
||||
|
||||
environment.variables = cfg.rendering;
|
||||
|
||||
};
|
||||
|
||||
|
@ -2,6 +2,121 @@
|
||||
|
||||
with lib;
|
||||
|
||||
let cfg = config.fonts.fontconfig;
|
||||
fcBool = x: "<bool>" + (if x then "true" else "false") + "</bool>";
|
||||
renderConf = pkgs.writeText "render-conf" ''
|
||||
<?xml version='1.0'?>
|
||||
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
|
||||
<fontconfig>
|
||||
|
||||
<!-- Default rendering settings -->
|
||||
<match target="font">
|
||||
<edit mode="assign" name="hinting">
|
||||
${fcBool cfg.hinting.enable}
|
||||
</edit>
|
||||
<edit mode="assign" name="autohint">
|
||||
${fcBool cfg.hinting.autohint}
|
||||
</edit>
|
||||
<edit mode="assign" name="hintstyle">
|
||||
<const>hint${cfg.hinting.style}</const>
|
||||
</edit>
|
||||
<edit mode="assign" name="antialias">
|
||||
${fcBool cfg.antialias}
|
||||
</edit>
|
||||
<edit mode="assign" name="rgba">
|
||||
<const>${cfg.subpixel.rgba}</const>
|
||||
</edit>
|
||||
<edit mode="assign" name="lcdfilter">
|
||||
<const>lcd${cfg.subpixel.lcdfilter}</const>
|
||||
</edit>
|
||||
</match>
|
||||
|
||||
${optionalString (cfg.dpi != 0) ''
|
||||
<match target="pattern">
|
||||
<edit name="dpi" mode="assign">
|
||||
<double>${toString cfg.dpi}</double>
|
||||
</edit>
|
||||
</match>
|
||||
''}
|
||||
|
||||
</fontconfig>
|
||||
'';
|
||||
genericAliasConf =
|
||||
let genDefault = fonts: name:
|
||||
optionalString (fonts != []) ''
|
||||
<alias>
|
||||
<family>${name}</family>
|
||||
<prefer>
|
||||
${concatStringsSep ""
|
||||
(map (font: ''
|
||||
<family>${font}</family>
|
||||
'') fonts)}
|
||||
</prefer>
|
||||
</alias>
|
||||
'';
|
||||
in
|
||||
pkgs.writeText "generic-alias-conf" ''
|
||||
<?xml version='1.0'?>
|
||||
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
|
||||
<fontconfig>
|
||||
|
||||
<!-- Default fonts -->
|
||||
${genDefault cfg.defaultFonts.sansSerif "sans-serif"}
|
||||
|
||||
${genDefault cfg.defaultFonts.serif "serif"}
|
||||
|
||||
${genDefault cfg.defaultFonts.monospace "monospace"}
|
||||
|
||||
</fontconfig>
|
||||
'';
|
||||
cacheConf = let
|
||||
cache = fontconfig: pkgs.makeFontsCache { inherit fontconfig; fontDirectories = config.fonts.fonts; };
|
||||
in
|
||||
pkgs.writeText "cache-conf" ''
|
||||
<?xml version='1.0'?>
|
||||
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
|
||||
<fontconfig>
|
||||
<!-- Font directories -->
|
||||
${concatStringsSep "\n" (map (font: "<dir>${font}</dir>") config.fonts.fonts)}
|
||||
<!-- Pre-generated font caches -->
|
||||
<cachedir>${cache pkgs.fontconfig}</cachedir>
|
||||
${optionalString (pkgs.stdenv.isx86_64 && cfg.cache32Bit) ''
|
||||
<cachedir>${cache pkgs.pkgsi686Linux.fontconfig}</cachedir>
|
||||
''}
|
||||
</fontconfig>
|
||||
'';
|
||||
userConf = pkgs.writeText "user-conf" ''
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
|
||||
<fontconfig>
|
||||
<include ignore_missing="yes" prefix="xdg">fontconfig/conf.d</include>
|
||||
<include ignore_missing="yes" prefix="xdg">fontconfig/fonts.conf</include>
|
||||
</fontconfig>
|
||||
'';
|
||||
fontsConf = pkgs.makeFontsConf { fontconfig = pkgs.fontconfig_210; fontDirectories = config.fonts.fonts; };
|
||||
confPkg =
|
||||
let version = pkgs.fontconfig.configVersion;
|
||||
in pkgs.runCommand "fontconfig-conf" {} ''
|
||||
mkdir -p $out/etc/fonts/{,${version}/}conf.d
|
||||
|
||||
ln -s ${fontsConf} $out/etc/fonts/fonts.conf
|
||||
|
||||
ln -s ${pkgs.fontconfig.out}/etc/fonts/fonts.conf $out/etc/fonts/${version}/fonts.conf
|
||||
ln -s ${pkgs.fontconfig.out}/etc/fonts/conf.d/* $out/etc/fonts/${version}/conf.d/
|
||||
|
||||
ln -s ${renderConf} $out/etc/fonts/conf.d/10-nixos-rendering.conf
|
||||
ln -s ${genericAliasConf} $out/etc/fonts/conf.d/60-nixos-generic-alias.conf
|
||||
|
||||
ln -s ${cacheConf} $out/etc/fonts/${version}/conf.d/00-nixos.conf
|
||||
|
||||
ln -s ${renderConf} $out/etc/fonts/${version}/conf.d/10-nixos-rendering.conf
|
||||
ln -s ${genericAliasConf} $out/etc/fonts/${version}/conf.d/30-nixos-generic-alias.conf
|
||||
|
||||
${optionalString cfg.includeUserConf
|
||||
"ln -s ${userConf} $out/etc/fonts/${version}/conf.d/99-user.conf"}
|
||||
|
||||
'';
|
||||
in
|
||||
{
|
||||
|
||||
options = {
|
||||
@ -21,6 +136,15 @@ with lib;
|
||||
'';
|
||||
};
|
||||
|
||||
confPkgs = mkOption {
|
||||
internal = true;
|
||||
type = with types; listOf path;
|
||||
default = [ ];
|
||||
description = ''
|
||||
Fontconfig configuration packages.
|
||||
'';
|
||||
};
|
||||
|
||||
antialias = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
@ -143,135 +267,17 @@ with lib;
|
||||
|
||||
};
|
||||
|
||||
config =
|
||||
let fontconfig = config.fonts.fontconfig;
|
||||
fcBool = x: "<bool>" + (if x then "true" else "false") + "</bool>";
|
||||
renderConf = ''
|
||||
<?xml version='1.0'?>
|
||||
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
|
||||
<fontconfig>
|
||||
config = mkIf cfg.enable {
|
||||
fonts.fontconfig.confPkgs = [ confPkg ];
|
||||
|
||||
<!-- Default rendering settings -->
|
||||
<match target="font">
|
||||
<edit mode="assign" name="hinting">
|
||||
${fcBool fontconfig.hinting.enable}
|
||||
</edit>
|
||||
<edit mode="assign" name="autohint">
|
||||
${fcBool fontconfig.hinting.autohint}
|
||||
</edit>
|
||||
<edit mode="assign" name="hintstyle">
|
||||
<const>hint${fontconfig.hinting.style}</const>
|
||||
</edit>
|
||||
<edit mode="assign" name="antialias">
|
||||
${fcBool fontconfig.antialias}
|
||||
</edit>
|
||||
<edit mode="assign" name="rgba">
|
||||
<const>${fontconfig.subpixel.rgba}</const>
|
||||
</edit>
|
||||
<edit mode="assign" name="lcdfilter">
|
||||
<const>lcd${fontconfig.subpixel.lcdfilter}</const>
|
||||
</edit>
|
||||
</match>
|
||||
environment.etc.fonts.source =
|
||||
let fontConf = pkgs.symlinkJoin {
|
||||
name = "fontconfig-etc";
|
||||
paths = cfg.confPkgs;
|
||||
};
|
||||
in "${fontConf}/etc/fonts/";
|
||||
|
||||
${optionalString (fontconfig.dpi != 0) ''
|
||||
<match target="pattern">
|
||||
<edit name="dpi" mode="assign">
|
||||
<double>${toString fontconfig.dpi}</double>
|
||||
</edit>
|
||||
</match>
|
||||
''}
|
||||
|
||||
</fontconfig>
|
||||
'';
|
||||
genericAliasConf = ''
|
||||
<?xml version='1.0'?>
|
||||
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
|
||||
<fontconfig>
|
||||
|
||||
<!-- Default fonts -->
|
||||
${optionalString (fontconfig.defaultFonts.sansSerif != []) ''
|
||||
<alias>
|
||||
<family>sans-serif</family>
|
||||
<prefer>
|
||||
${concatStringsSep "\n"
|
||||
(map (font: "<family>${font}</family>")
|
||||
fontconfig.defaultFonts.sansSerif)}
|
||||
</prefer>
|
||||
</alias>
|
||||
''}
|
||||
${optionalString (fontconfig.defaultFonts.serif != []) ''
|
||||
<alias>
|
||||
<family>serif</family>
|
||||
<prefer>
|
||||
${concatStringsSep "\n"
|
||||
(map (font: "<family>${font}</family>")
|
||||
fontconfig.defaultFonts.serif)}
|
||||
</prefer>
|
||||
</alias>
|
||||
''}
|
||||
${optionalString (fontconfig.defaultFonts.monospace != []) ''
|
||||
<alias>
|
||||
<family>monospace</family>
|
||||
<prefer>
|
||||
${concatStringsSep "\n"
|
||||
(map (font: "<family>${font}</family>")
|
||||
fontconfig.defaultFonts.monospace)}
|
||||
</prefer>
|
||||
</alias>
|
||||
''}
|
||||
|
||||
</fontconfig>
|
||||
'';
|
||||
in mkIf fontconfig.enable {
|
||||
|
||||
# Fontconfig 2.10 backward compatibility
|
||||
|
||||
# Bring in the default (upstream) fontconfig configuration, only for fontconfig 2.10
|
||||
environment.etc."fonts/fonts.conf".source =
|
||||
pkgs.makeFontsConf { fontconfig = pkgs.fontconfig_210; fontDirectories = config.fonts.fonts; };
|
||||
|
||||
environment.etc."fonts/conf.d/10-nixos-rendering.conf".text = renderConf;
|
||||
environment.etc."fonts/conf.d/60-nixos-generic-alias.conf".text = genericAliasConf;
|
||||
|
||||
# Versioned fontconfig > 2.10. Take shared fonts.conf from fontconfig.
|
||||
# Otherwise specify only font directories.
|
||||
environment.etc."fonts/${pkgs.fontconfig.configVersion}/fonts.conf".source =
|
||||
"${pkgs.fontconfig.out}/etc/fonts/fonts.conf";
|
||||
|
||||
environment.etc."fonts/${pkgs.fontconfig.configVersion}/conf.d/00-nixos.conf".text =
|
||||
let
|
||||
cache = fontconfig: pkgs.makeFontsCache { inherit fontconfig; fontDirectories = config.fonts.fonts; };
|
||||
in ''
|
||||
<?xml version='1.0'?>
|
||||
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
|
||||
<fontconfig>
|
||||
<!-- Font directories -->
|
||||
${concatStringsSep "\n" (map (font: "<dir>${font}</dir>") config.fonts.fonts)}
|
||||
<!-- Pre-generated font caches -->
|
||||
<cachedir>${cache pkgs.fontconfig}</cachedir>
|
||||
${optionalString (pkgs.stdenv.isx86_64 && config.fonts.fontconfig.cache32Bit) ''
|
||||
<cachedir>${cache pkgs.pkgsi686Linux.fontconfig}</cachedir>
|
||||
''}
|
||||
</fontconfig>
|
||||
'';
|
||||
|
||||
environment.etc."fonts/${pkgs.fontconfig.configVersion}/conf.d/10-nixos-rendering.conf".text = renderConf;
|
||||
environment.etc."fonts/${pkgs.fontconfig.configVersion}/conf.d/60-nixos-generic-alias.conf".text = genericAliasConf;
|
||||
|
||||
environment.etc."fonts/${pkgs.fontconfig.configVersion}/conf.d/99-user.conf" = {
|
||||
enable = fontconfig.includeUserConf;
|
||||
text = ''
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
|
||||
<fontconfig>
|
||||
<include ignore_missing="yes" prefix="xdg">fontconfig/conf.d</include>
|
||||
<include ignore_missing="yes" prefix="xdg">fontconfig/fonts.conf</include>
|
||||
</fontconfig>
|
||||
'';
|
||||
};
|
||||
|
||||
environment.systemPackages = [ pkgs.fontconfig ];
|
||||
|
||||
};
|
||||
environment.systemPackages = [ pkgs.fontconfig ];
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -41,6 +41,15 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
consolePackages = mkOption {
|
||||
type = types.listOf types.package;
|
||||
default = with pkgs.kbdKeymaps; [ dvp neo ];
|
||||
description = ''
|
||||
List of additional packages that provide console fonts, keymaps and
|
||||
other resources.
|
||||
'';
|
||||
};
|
||||
|
||||
consoleFont = mkOption {
|
||||
type = types.str;
|
||||
default = "Lat2-Terminus16";
|
||||
|
@ -1,7 +1,7 @@
|
||||
# This module defines a global environment configuration and
|
||||
# a common configuration for all shells.
|
||||
|
||||
{ config, lib, pkgs, ... }:
|
||||
{ config, lib, utils, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
@ -135,13 +135,13 @@ in
|
||||
|
||||
environment.shells = mkOption {
|
||||
default = [];
|
||||
example = [ "/run/current-system/sw/bin/zsh" ];
|
||||
example = literalExample "[ pkgs.bashInteractive pkgs.zsh ]";
|
||||
description = ''
|
||||
A list of permissible login shells for user accounts.
|
||||
No need to mention <literal>/bin/sh</literal>
|
||||
here, it is placed into this list implicitly.
|
||||
'';
|
||||
type = types.listOf types.path;
|
||||
type = types.listOf (types.either types.shellPackage types.path);
|
||||
};
|
||||
|
||||
};
|
||||
@ -158,7 +158,7 @@ in
|
||||
|
||||
environment.etc."shells".text =
|
||||
''
|
||||
${concatStringsSep "\n" cfg.shells}
|
||||
${concatStringsSep "\n" (map utils.toShellPath cfg.shells)}
|
||||
/bin/sh
|
||||
'';
|
||||
|
||||
|
@ -30,8 +30,7 @@ let
|
||||
description = ''
|
||||
If this option is set, ‘device’ is interpreted as the
|
||||
path of a swapfile that will be created automatically
|
||||
with the indicated size (in megabytes) if it doesn't
|
||||
exist.
|
||||
with the indicated size (in megabytes).
|
||||
'';
|
||||
};
|
||||
|
||||
@ -132,9 +131,13 @@ in
|
||||
script =
|
||||
''
|
||||
${optionalString (sw.size != null) ''
|
||||
if [ ! -e "${sw.device}" ]; then
|
||||
currentSize=$(( $(stat -c "%s" "${sw.device}" 2>/dev/null || echo 0) / 1024 / 1024 ))
|
||||
if [ "${toString sw.size}" != "$currentSize" ]; then
|
||||
fallocate -l ${toString sw.size}M "${sw.device}" ||
|
||||
dd if=/dev/zero of="${sw.device}" bs=1M count=${toString sw.size}
|
||||
if [ "${toString sw.size}" -lt "$currentSize" ]; then
|
||||
truncate --size "${toString sw.size}M" "${sw.device}"
|
||||
fi
|
||||
chmod 0600 ${sw.device}
|
||||
${optionalString (!sw.randomEncryption) "mkswap ${sw.realDevice}"}
|
||||
fi
|
||||
|
@ -103,7 +103,7 @@ foreach my $g (@{$spec->{groups}}) {
|
||||
if (defined $existing) {
|
||||
$g->{gid} = $existing->{gid} if !defined $g->{gid};
|
||||
if ($g->{gid} != $existing->{gid}) {
|
||||
warn "warning: not applying GID change of group ‘$name’\n";
|
||||
warn "warning: not applying GID change of group ‘$name’ ($existing->{gid} -> $g->{gid})\n";
|
||||
$g->{gid} = $existing->{gid};
|
||||
}
|
||||
$g->{password} = $existing->{password}; # do we want this?
|
||||
@ -163,7 +163,7 @@ foreach my $u (@{$spec->{users}}) {
|
||||
if (defined $existing) {
|
||||
$u->{uid} = $existing->{uid} if !defined $u->{uid};
|
||||
if ($u->{uid} != $existing->{uid}) {
|
||||
warn "warning: not applying UID change of user ‘$name’\n";
|
||||
warn "warning: not applying UID change of user ‘$name’ ($existing->{uid} -> $u->{uid})\n";
|
||||
$u->{uid} = $existing->{uid};
|
||||
}
|
||||
} else {
|
||||
|
@ -1,9 +1,8 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
{ config, lib, utils, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
ids = config.ids;
|
||||
cfg = config.users;
|
||||
|
||||
@ -103,7 +102,7 @@ let
|
||||
};
|
||||
|
||||
home = mkOption {
|
||||
type = types.str;
|
||||
type = types.path;
|
||||
default = "/var/empty";
|
||||
description = "The user's home directory.";
|
||||
};
|
||||
@ -118,9 +117,17 @@ let
|
||||
};
|
||||
|
||||
shell = mkOption {
|
||||
type = types.str;
|
||||
default = "/run/current-system/sw/bin/nologin";
|
||||
description = "The path to the user's shell.";
|
||||
type = types.either types.shellPackage types.path;
|
||||
default = pkgs.nologin;
|
||||
defaultText = "pkgs.nologin";
|
||||
example = literalExample "pkgs.bashInteractive";
|
||||
description = ''
|
||||
The path to the user's shell. Can use shell derivations,
|
||||
like <literal>pkgs.bashInteractive</literal>. Don’t
|
||||
forget to enable your shell in
|
||||
<literal>programs</literal> if necessary,
|
||||
like <code>programs.zsh.enable = true;</code>.
|
||||
'';
|
||||
};
|
||||
|
||||
subUidRanges = mkOption {
|
||||
@ -359,11 +366,12 @@ let
|
||||
|
||||
spec = pkgs.writeText "users-groups.json" (builtins.toJSON {
|
||||
inherit (cfg) mutableUsers;
|
||||
users = mapAttrsToList (n: u:
|
||||
users = mapAttrsToList (_: u:
|
||||
{ inherit (u)
|
||||
name uid group description home shell createHome isSystemUser
|
||||
name uid group description home createHome isSystemUser
|
||||
password passwordFile hashedPassword
|
||||
initialPassword initialHashedPassword;
|
||||
shell = utils.toShellPath u.shell;
|
||||
}) cfg.users;
|
||||
groups = mapAttrsToList (n: g:
|
||||
{ inherit (g) name gid;
|
||||
@ -373,6 +381,12 @@ let
|
||||
}) cfg.groups;
|
||||
});
|
||||
|
||||
systemShells =
|
||||
let
|
||||
shells = mapAttrsToList (_: u: u.shell) cfg.users;
|
||||
in
|
||||
filter types.shellPackage.check shells;
|
||||
|
||||
in {
|
||||
|
||||
###### interface
|
||||
@ -468,7 +482,6 @@ in {
|
||||
home = "/root";
|
||||
shell = mkDefault cfg.defaultUserShell;
|
||||
group = "root";
|
||||
extraGroups = [ "grsecurity" ];
|
||||
initialHashedPassword = mkDefault config.security.initialRootPassword;
|
||||
};
|
||||
nobody = {
|
||||
@ -478,6 +491,9 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
# Install all the user shells
|
||||
environment.systemPackages = systemShells;
|
||||
|
||||
users.groups = {
|
||||
root.gid = ids.gids.root;
|
||||
wheel.gid = ids.gids.wheel;
|
||||
@ -497,7 +513,6 @@ in {
|
||||
nixbld.gid = ids.gids.nixbld;
|
||||
utmp.gid = ids.gids.utmp;
|
||||
adm.gid = ids.gids.adm;
|
||||
grsecurity.gid = ids.gids.grsecurity;
|
||||
input.gid = ids.gids.input;
|
||||
};
|
||||
|
||||
|
@ -4,7 +4,7 @@ with lib;
|
||||
|
||||
let
|
||||
cfg = config.i18n.inputMethod.fcitx;
|
||||
fcitxPackage = pkgs.fcitx-with-plugins.override { plugins = cfg.engines; };
|
||||
fcitxPackage = pkgs.fcitx.override { plugins = cfg.engines; };
|
||||
fcitxEngine = types.package // {
|
||||
name = "fcitx-engine";
|
||||
check = x: (lib.types.package.check x) && (attrByPath ["meta" "isFcitxEngine"] false x);
|
||||
|
@ -19,18 +19,37 @@ in
|
||||
"it cannot be cross compiled";
|
||||
};
|
||||
|
||||
# Needed by RPi firmware
|
||||
nixpkgs.config.allowUnfree = true;
|
||||
|
||||
boot.loader.grub.enable = false;
|
||||
boot.loader.generic-extlinux-compatible.enable = true;
|
||||
|
||||
boot.kernelPackages = pkgs.linuxPackages_latest;
|
||||
boot.kernelParams = ["console=ttyS0,115200n8" "console=ttymxc0,115200n8" "console=ttyAMA0,115200n8" "console=tty0"];
|
||||
boot.kernelParams = ["console=ttyS0,115200n8" "console=ttymxc0,115200n8" "console=ttyAMA0,115200n8" "console=ttyO0,115200n8" "console=tty0"];
|
||||
boot.consoleLogLevel = 7;
|
||||
|
||||
# FIXME: this probably should be in installation-device.nix
|
||||
users.extraUsers.root.initialHashedPassword = "";
|
||||
|
||||
sdImage = {
|
||||
populateBootCommands = ''
|
||||
populateBootCommands = let
|
||||
configTxt = pkgs.writeText "config.txt" ''
|
||||
[pi2]
|
||||
kernel=u-boot-rpi2.bin
|
||||
|
||||
[pi3]
|
||||
kernel=u-boot-rpi3.bin
|
||||
enable_uart=1
|
||||
'';
|
||||
in ''
|
||||
for f in bootcode.bin fixup.dat start.elf; do
|
||||
cp ${pkgs.raspberrypifw}/share/raspberrypi/boot/$f boot/
|
||||
done
|
||||
cp ${pkgs.ubootRaspberryPi2}/u-boot.bin boot/u-boot-rpi2.bin
|
||||
cp ${pkgs.ubootRaspberryPi3}/u-boot.bin boot/u-boot-rpi3.bin
|
||||
cp ${configTxt} boot/config.txt
|
||||
${extlinux-conf-builder} -t 3 -c ${config.system.build.toplevel} -d ./boot
|
||||
'';
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ in
|
||||
boot.loader.generic-extlinux-compatible.enable = true;
|
||||
|
||||
boot.kernelPackages = pkgs.linuxPackages_rpi;
|
||||
boot.consoleLogLevel = 7;
|
||||
|
||||
# FIXME: this probably should be in installation-device.nix
|
||||
users.extraUsers.root.initialHashedPassword = "";
|
||||
|
@ -91,12 +91,10 @@ ln -s /run $mountPoint/var/run
|
||||
rm -f $mountPoint/etc/{resolv.conf,hosts}
|
||||
cp -Lf /etc/resolv.conf /etc/hosts $mountPoint/etc/
|
||||
|
||||
if [ -e "$SSL_CERT_FILE" ]; then
|
||||
cp -Lf "$SSL_CERT_FILE" "$mountPoint/tmp/ca-cert.crt"
|
||||
export SSL_CERT_FILE=/tmp/ca-cert.crt
|
||||
# For Nix 1.7
|
||||
export CURL_CA_BUNDLE=/tmp/ca-cert.crt
|
||||
fi
|
||||
cp -Lf "@cacert@" "$mountPoint/tmp/ca-cert.crt"
|
||||
export SSL_CERT_FILE=/tmp/ca-cert.crt
|
||||
# For Nix 1.7
|
||||
export CURL_CA_BUNDLE=/tmp/ca-cert.crt
|
||||
|
||||
if [ -n "$runChroot" ]; then
|
||||
if ! [ -L $mountPoint/nix/var/nix/profiles/system ]; then
|
||||
|
@ -1,6 +1,10 @@
|
||||
#! @shell@
|
||||
|
||||
case "$1" in
|
||||
-h|--help)
|
||||
exec man nixos-version
|
||||
exit 1
|
||||
;;
|
||||
--hash|--revision)
|
||||
echo "@nixosRevision@"
|
||||
;;
|
||||
|
@ -23,6 +23,7 @@ let
|
||||
|
||||
inherit (pkgs) perl pathsFromGraph;
|
||||
nix = config.nix.package.out;
|
||||
cacert = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt";
|
||||
|
||||
nixClosure = pkgs.runCommand "closure"
|
||||
{ exportReferencesGraph = ["refs" config.nix.package.out]; }
|
||||
|
@ -147,7 +147,6 @@
|
||||
foundationdb = 118;
|
||||
newrelic = 119;
|
||||
starbound = 120;
|
||||
#grsecurity = 121; # unused
|
||||
hydra = 122;
|
||||
spiped = 123;
|
||||
teamspeak = 124;
|
||||
@ -269,6 +268,8 @@
|
||||
nzbget = 245;
|
||||
mosquitto = 246;
|
||||
toxvpn = 247;
|
||||
squeezelite = 248;
|
||||
turnserver = 249;
|
||||
|
||||
# When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
|
||||
|
||||
@ -369,7 +370,7 @@
|
||||
quassel = 89;
|
||||
amule = 90;
|
||||
minidlna = 91;
|
||||
#elasticsearch = 92; # unused
|
||||
elasticsearch = 92;
|
||||
#tcpcryptd = 93; # unused
|
||||
connman = 94;
|
||||
firebird = 95;
|
||||
@ -396,7 +397,6 @@
|
||||
foundationdb = 118;
|
||||
newrelic = 119;
|
||||
starbound = 120;
|
||||
grsecurity = 121;
|
||||
hydra = 122;
|
||||
spiped = 123;
|
||||
teamspeak = 124;
|
||||
@ -508,6 +508,8 @@
|
||||
nzbget = 245;
|
||||
mosquitto = 246;
|
||||
#toxvpn = 247; # unused
|
||||
#squeezelite = 248; #unused
|
||||
turnserver = 249;
|
||||
|
||||
# When adding a gid, make sure it doesn't match an existing
|
||||
# uid. Users and groups with the same name should have equal
|
||||
|
@ -76,6 +76,7 @@
|
||||
./programs/screen.nix
|
||||
./programs/shadow.nix
|
||||
./programs/shell.nix
|
||||
./programs/spacefm.nix
|
||||
./programs/ssh.nix
|
||||
./programs/ssmtp.nix
|
||||
./programs/tmux.nix
|
||||
@ -110,6 +111,7 @@
|
||||
./services/audio/liquidsoap.nix
|
||||
./services/audio/mpd.nix
|
||||
./services/audio/mopidy.nix
|
||||
./services/audio/squeezelite.nix
|
||||
./services/backup/almir.nix
|
||||
./services/backup/bacula.nix
|
||||
./services/backup/crashplan.nix
|
||||
@ -125,10 +127,11 @@
|
||||
./services/computing/torque/server.nix
|
||||
./services/computing/torque/mom.nix
|
||||
./services/computing/slurm/slurm.nix
|
||||
./services/continuous-integration/jenkins/default.nix
|
||||
./services/continuous-integration/jenkins/slave.nix
|
||||
./services/continuous-integration/jenkins/job-builder.nix
|
||||
./services/continuous-integration/buildkite-agent.nix
|
||||
./services/continuous-integration/hydra/default.nix
|
||||
./services/continuous-integration/jenkins/default.nix
|
||||
./services/continuous-integration/jenkins/job-builder.nix
|
||||
./services/continuous-integration/jenkins/slave.nix
|
||||
./services/databases/4store-endpoint.nix
|
||||
./services/databases/4store.nix
|
||||
./services/databases/couchdb.nix
|
||||
@ -162,6 +165,7 @@
|
||||
./services/desktops/profile-sync-daemon.nix
|
||||
./services/desktops/telepathy.nix
|
||||
./services/development/hoogle.nix
|
||||
./services/editors/emacs.nix
|
||||
./services/games/factorio.nix
|
||||
./services/games/ghost-one.nix
|
||||
./services/games/minecraft-server.nix
|
||||
@ -218,6 +222,7 @@
|
||||
./services/misc/confd.nix
|
||||
./services/misc/devmon.nix
|
||||
./services/misc/dictd.nix
|
||||
./services/misc/dysnomia.nix
|
||||
./services/misc/disnix.nix
|
||||
./services/misc/docker-registry.nix
|
||||
./services/misc/emby.nix
|
||||
@ -314,6 +319,7 @@
|
||||
./services/networking/cntlm.nix
|
||||
./services/networking/connman.nix
|
||||
./services/networking/consul.nix
|
||||
./services/networking/coturn.nix
|
||||
./services/networking/ddclient.nix
|
||||
./services/networking/dhcpcd.nix
|
||||
./services/networking/dhcpd.nix
|
||||
@ -362,6 +368,7 @@
|
||||
./services/networking/ntopng.nix
|
||||
./services/networking/ntpd.nix
|
||||
./services/networking/nylon.nix
|
||||
./services/networking/offlineimap.nix
|
||||
./services/networking/oidentd.nix
|
||||
./services/networking/openfire.nix
|
||||
./services/networking/openntpd.nix
|
||||
@ -369,6 +376,7 @@
|
||||
./services/networking/ostinato.nix
|
||||
./services/networking/pdnsd.nix
|
||||
./services/networking/polipo.nix
|
||||
./services/networking/pptpd.nix
|
||||
./services/networking/prayer.nix
|
||||
./services/networking/privoxy.nix
|
||||
./services/networking/prosody.nix
|
||||
@ -409,6 +417,7 @@
|
||||
./services/networking/wicd.nix
|
||||
./services/networking/wpa_supplicant.nix
|
||||
./services/networking/xinetd.nix
|
||||
./services/networking/xl2tpd.nix
|
||||
./services/networking/zerobin.nix
|
||||
./services/networking/zerotierone.nix
|
||||
./services/networking/znc.nix
|
||||
@ -455,6 +464,7 @@
|
||||
./services/web-servers/lighttpd/cgit.nix
|
||||
./services/web-servers/lighttpd/default.nix
|
||||
./services/web-servers/lighttpd/gitweb.nix
|
||||
./services/web-servers/lighttpd/inginious.nix
|
||||
./services/web-servers/nginx/default.nix
|
||||
./services/web-servers/phpfpm.nix
|
||||
./services/web-servers/shellinabox.nix
|
||||
@ -490,6 +500,7 @@
|
||||
./services/x11/window-managers/windowlab.nix
|
||||
./services/x11/window-managers/wmii.nix
|
||||
./services/x11/window-managers/xmonad.nix
|
||||
./services/x11/xbanish.nix
|
||||
./services/x11/xfs.nix
|
||||
./services/x11/xserver.nix
|
||||
./system/activation/activation-script.nix
|
||||
@ -513,6 +524,7 @@
|
||||
./system/boot/luksroot.nix
|
||||
./system/boot/modprobe.nix
|
||||
./system/boot/networkd.nix
|
||||
./system/boot/plymouth.nix
|
||||
./system/boot/resolved.nix
|
||||
./system/boot/shutdown.nix
|
||||
./system/boot/stage-1.nix
|
||||
|
@ -42,7 +42,7 @@ with lib;
|
||||
|
||||
The "root" account has an empty password. ${
|
||||
optionalString config.services.xserver.enable
|
||||
"Type `start display-manager' to\nstart the graphical user interface."}
|
||||
"Type `systemctl start display-manager' to\nstart the graphical user interface."}
|
||||
'';
|
||||
|
||||
# Allow sshd to be started manually through "start sshd".
|
||||
|
@ -200,7 +200,7 @@ in
|
||||
# Configuration for readline in bash.
|
||||
environment.etc."inputrc".source = ./inputrc;
|
||||
|
||||
users.defaultUserShell = mkDefault "/run/current-system/sw/bin/bash";
|
||||
users.defaultUserShell = mkDefault pkgs.bashInteractive;
|
||||
|
||||
environment.pathsToLink = optionals cfg.enableCompletion [
|
||||
"/etc/bash_completion.d"
|
||||
|
@ -6,6 +6,7 @@ set meta-flag on
|
||||
set input-meta on
|
||||
set convert-meta off
|
||||
set output-meta on
|
||||
set colored-stats on
|
||||
|
||||
#set mark-symlinked-directories on
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Configuration for the pwdutils suite of tools: passwd, useradd, etc.
|
||||
|
||||
{ config, lib, pkgs, ... }:
|
||||
{ config, lib, utils, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
@ -43,13 +43,13 @@ in
|
||||
users.defaultUserShell = lib.mkOption {
|
||||
description = ''
|
||||
This option defines the default shell assigned to user
|
||||
accounts. This must not be a store path, since the path is
|
||||
accounts. This can be either a full system path or a shell package.
|
||||
|
||||
This must not be a store path, since the path is
|
||||
used outside the store (in particular in /etc/passwd).
|
||||
Rather, it should be the path of a symlink that points to the
|
||||
actual shell in the Nix store.
|
||||
'';
|
||||
example = "/run/current-system/sw/bin/zsh";
|
||||
type = types.path;
|
||||
example = literalExample "pkgs.zsh";
|
||||
type = types.either types.path types.shellPackage;
|
||||
};
|
||||
|
||||
};
|
||||
@ -60,7 +60,9 @@ in
|
||||
config = {
|
||||
|
||||
environment.systemPackages =
|
||||
lib.optional config.users.mutableUsers pkgs.shadow;
|
||||
lib.optional config.users.mutableUsers pkgs.shadow ++
|
||||
lib.optional (types.shellPackage.check config.users.defaultUserShell)
|
||||
config.users.defaultUserShell;
|
||||
|
||||
environment.etc =
|
||||
[ { # /etc/login.defs: global configuration for pwdutils. You
|
||||
@ -74,7 +76,7 @@ in
|
||||
''
|
||||
GROUP=100
|
||||
HOME=/home
|
||||
SHELL=${config.users.defaultUserShell}
|
||||
SHELL=${utils.toShellPath config.users.defaultUserShell}
|
||||
'';
|
||||
target = "default/useradd";
|
||||
}
|
||||
|
55
nixos/modules/programs/spacefm.nix
Normal file
55
nixos/modules/programs/spacefm.nix
Normal file
@ -0,0 +1,55 @@
|
||||
# Global configuration for spacefm.
|
||||
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let cfg = config.programs.spacefm;
|
||||
|
||||
in
|
||||
{
|
||||
###### interface
|
||||
|
||||
options = {
|
||||
|
||||
programs.spacefm = {
|
||||
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to install SpaceFM and create <filename>/etc/spacefm/spacefm.conf</filename>.
|
||||
'';
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
type = types.attrs;
|
||||
default = {
|
||||
tmp_dir = "/tmp";
|
||||
terminal_su = "${pkgs.sudo}/bin/sudo";
|
||||
graphical_su = "${pkgs.gksu}/bin/gksu";
|
||||
};
|
||||
example = literalExample ''{
|
||||
tmp_dir = "/tmp";
|
||||
terminal_su = "''${pkgs.sudo}/bin/sudo";
|
||||
graphical_su = "''${pkgs.gksu}/bin/gksu";
|
||||
}'';
|
||||
description = ''
|
||||
The system-wide spacefm configuration.
|
||||
Parameters to be written to <filename>/etc/spacefm/spacefm.conf</filename>.
|
||||
Refer to the <link xlink:href="https://ignorantguru.github.io/spacefm/spacefm-manual-en.html#programfiles-etc">relevant entry</link> in the SpaceFM manual.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
environment.systemPackages = [ pkgs.spaceFM ];
|
||||
|
||||
environment.etc."spacefm/spacefm.conf".text =
|
||||
concatStrings (mapAttrsToList (n: v: "${n}=${toString v}\n") cfg.settings);
|
||||
};
|
||||
}
|
@ -114,6 +114,26 @@ with lib;
|
||||
(mkRenamedOptionModule [ "services" "iodined" "extraConfig" ] [ "services" "iodine" "server" "extraConfig" ])
|
||||
(mkRemovedOptionModule [ "services" "iodined" "client" ])
|
||||
|
||||
# Grsecurity
|
||||
(mkRemovedOptionModule [ "security" "grsecurity" "kernelPatch" ])
|
||||
(mkRemovedOptionModule [ "security" "grsecurity" "config" "mode" ])
|
||||
(mkRemovedOptionModule [ "security" "grsecurity" "config" "priority" ])
|
||||
(mkRemovedOptionModule [ "security" "grsecurity" "config" "system" ])
|
||||
(mkRemovedOptionModule [ "security" "grsecurity" "config" "virtualisationConfig" ])
|
||||
(mkRemovedOptionModule [ "security" "grsecurity" "config" "hardwareVirtualisation" ])
|
||||
(mkRemovedOptionModule [ "security" "grsecurity" "config" "virtualisationSoftware" ])
|
||||
(mkRemovedOptionModule [ "security" "grsecurity" "config" "sysctl" ])
|
||||
(mkRemovedOptionModule [ "security" "grsecurity" "config" "denyChrootChmod" ])
|
||||
(mkRemovedOptionModule [ "security" "grsecurity" "config" "denyChrootCaps" ])
|
||||
(mkRemovedOptionModule [ "security" "grsecurity" "config" "denyUSB" ])
|
||||
(mkRemovedOptionModule [ "security" "grsecurity" "config" "restrictProc" ])
|
||||
(mkRemovedOptionModule [ "security" "grsecurity" "config" "restrictProcWithGroup" ])
|
||||
(mkRemovedOptionModule [ "security" "grsecurity" "config" "unrestrictProcGid" ])
|
||||
(mkRemovedOptionModule [ "security" "grsecurity" "config" "disableRBAC" ])
|
||||
(mkRemovedOptionModule [ "security" "grsecurity" "config" "disableSimultConnect" ])
|
||||
(mkRemovedOptionModule [ "security" "grsecurity" "config" "verboseVersion" ])
|
||||
(mkRemovedOptionModule [ "security" "grsecurity" "config" "kernelExtraConfig" ])
|
||||
|
||||
# Options that are obsolete and have no replacement.
|
||||
(mkRemovedOptionModule [ "boot" "initrd" "luks" "enable" ])
|
||||
(mkRemovedOptionModule [ "programs" "bash" "enable" ])
|
||||
|
@ -187,7 +187,7 @@ in
|
||||
script = ''
|
||||
cd '${cpath}'
|
||||
set +e
|
||||
simp_le ${concatMapStringsSep " " (arg: escapeShellArg (toString arg)) cmdline}
|
||||
simp_le ${escapeShellArgs cmdline}
|
||||
EXITCODE=$?
|
||||
set -e
|
||||
echo "$EXITCODE" > /tmp/lastExitCode
|
||||
|
@ -1,312 +1,122 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.security.grsecurity;
|
||||
grsecLockPath = "/proc/sys/kernel/grsecurity/grsec_lock";
|
||||
|
||||
customGrsecPkg =
|
||||
(import ../../../pkgs/build-support/grsecurity {
|
||||
grsecOptions = cfg;
|
||||
inherit pkgs lib;
|
||||
}).grsecPackage;
|
||||
# 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")
|
||||
(attrValues config.fileSystems) != [];
|
||||
in
|
||||
|
||||
{
|
||||
options = {
|
||||
security.grsecurity = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Enable grsecurity support. This enables advanced exploit
|
||||
hardening for the Linux kernel, and adds support for
|
||||
administrative Role-Based Acess Control (RBAC) via
|
||||
<literal>gradm</literal>. It also includes traditional
|
||||
utilities for PaX.
|
||||
'';
|
||||
};
|
||||
options.security.grsecurity = {
|
||||
|
||||
kernelPatch = mkOption {
|
||||
type = types.attrs;
|
||||
example = lib.literalExample "pkgs.kernelPatches.grsecurity_4_1";
|
||||
description = ''
|
||||
Grsecurity patch to use.
|
||||
'';
|
||||
};
|
||||
enable = mkEnableOption "Grsecurity/PaX";
|
||||
|
||||
config = {
|
||||
mode = mkOption {
|
||||
type = types.enum [ "auto" "custom" ];
|
||||
default = "auto";
|
||||
description = ''
|
||||
grsecurity configuration mode. This specifies whether
|
||||
grsecurity is auto-configured or otherwise completely
|
||||
manually configured.
|
||||
'';
|
||||
};
|
||||
|
||||
priority = mkOption {
|
||||
type = types.enum [ "security" "performance" ];
|
||||
default = "security";
|
||||
description = ''
|
||||
grsecurity configuration priority. This specifies whether
|
||||
the kernel configuration should emphasize speed or
|
||||
security.
|
||||
'';
|
||||
};
|
||||
|
||||
system = mkOption {
|
||||
type = types.enum [ "desktop" "server" ];
|
||||
default = "desktop";
|
||||
description = ''
|
||||
grsecurity system configuration.
|
||||
'';
|
||||
};
|
||||
|
||||
virtualisationConfig = mkOption {
|
||||
type = types.nullOr (types.enum [ "host" "guest" ]);
|
||||
default = null;
|
||||
description = ''
|
||||
grsecurity virtualisation configuration. This specifies
|
||||
the virtualisation role of the machine - that is, whether
|
||||
it will be a virtual machine guest, a virtual machine
|
||||
host, or neither.
|
||||
'';
|
||||
};
|
||||
|
||||
hardwareVirtualisation = mkOption {
|
||||
type = types.nullOr types.bool;
|
||||
default = null;
|
||||
example = true;
|
||||
description = ''
|
||||
grsecurity hardware virtualisation configuration. Set to
|
||||
<literal>true</literal> if your machine supports hardware
|
||||
accelerated virtualisation.
|
||||
'';
|
||||
};
|
||||
|
||||
virtualisationSoftware = mkOption {
|
||||
type = types.nullOr (types.enum [ "kvm" "xen" "vmware" "virtualbox" ]);
|
||||
default = null;
|
||||
description = ''
|
||||
Configure grsecurity for use with this virtualisation software.
|
||||
'';
|
||||
};
|
||||
|
||||
sysctl = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
If true, then set <literal>GRKERN_SYSCTL y</literal>. If
|
||||
enabled then grsecurity can be controlled using sysctl
|
||||
(and turned off). You are advised to *never* enable this,
|
||||
but if you do, make sure to always set the sysctl
|
||||
<literal>kernel.grsecurity.grsec_lock</literal> to
|
||||
non-zero as soon as all sysctl options are set. *THIS IS
|
||||
EXTREMELY IMPORTANT*!
|
||||
'';
|
||||
};
|
||||
|
||||
denyChrootChmod = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
If true, then set <literal>GRKERN_CHROOT_CHMOD
|
||||
y</literal>. If enabled, this denies processes inside a
|
||||
chroot from setting the suid or sgid bits using
|
||||
<literal>chmod</literal> or <literal>fchmod</literal>.
|
||||
|
||||
By default this protection is disabled - it makes it
|
||||
impossible to use Nix to build software on your system,
|
||||
which is what most users want.
|
||||
|
||||
If you are using NixOps to deploy your software to a
|
||||
remote machine, you're encouraged to enable this as you
|
||||
won't need to compile code.
|
||||
'';
|
||||
};
|
||||
|
||||
denyChrootCaps = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to lower capabilities of all processes within a chroot,
|
||||
preventing commands that require <literal>CAP_SYS_ADMIN</literal>.
|
||||
|
||||
This protection is disabled by default because it breaks
|
||||
<literal>nixos-rebuild</literal>. Whenever possible, it is
|
||||
highly recommended to enable this protection.
|
||||
'';
|
||||
};
|
||||
|
||||
denyUSB = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
If true, then set <literal>GRKERNSEC_DENYUSB y</literal>.
|
||||
|
||||
This enables a sysctl with name
|
||||
<literal>kernel.grsecurity.deny_new_usb</literal>. Setting
|
||||
its value to <literal>1</literal> will prevent any new USB
|
||||
devices from being recognized by the OS. Any attempted
|
||||
USB device insertion will be logged.
|
||||
|
||||
This option is intended to be used against custom USB
|
||||
devices designed to exploit vulnerabilities in various USB
|
||||
device drivers.
|
||||
'';
|
||||
};
|
||||
|
||||
restrictProc = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
If true, then set <literal>GRKERN_PROC_USER
|
||||
y</literal>. This restricts non-root users to only viewing
|
||||
their own processes and restricts network-related
|
||||
information, kernel symbols, and module information.
|
||||
'';
|
||||
};
|
||||
|
||||
restrictProcWithGroup = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
If true, then set <literal>GRKERN_PROC_USERGROUP
|
||||
y</literal>. This is similar to
|
||||
<literal>restrictProc</literal> except it allows a special
|
||||
group (specified by <literal>unrestrictProcGid</literal>)
|
||||
to still access otherwise classified information in
|
||||
<literal>/proc</literal>.
|
||||
'';
|
||||
};
|
||||
|
||||
unrestrictProcGid = mkOption {
|
||||
type = types.int;
|
||||
default = config.ids.gids.grsecurity;
|
||||
description = ''
|
||||
If set, specifies a GID which is exempt from
|
||||
<literal>/proc</literal> restrictions (set by
|
||||
<literal>GRKERN_PROC_USERGROUP</literal>). By default,
|
||||
this is set to the GID for <literal>grsecurity</literal>,
|
||||
a predefined NixOS group, which the
|
||||
<literal>root</literal> account is a member of. You may
|
||||
conveniently add other users to this group if you need
|
||||
access to <literal>/proc</literal>
|
||||
'';
|
||||
};
|
||||
|
||||
disableRBAC = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
If true, then set <literal>GRKERN_NO_RBAC
|
||||
y</literal>. This disables the
|
||||
<literal>/dev/grsec</literal> device, which in turn
|
||||
disables the RBAC system (and <literal>gradm</literal>).
|
||||
'';
|
||||
};
|
||||
|
||||
disableSimultConnect = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Disable TCP simultaneous connect. The TCP simultaneous connect
|
||||
feature allows two clients to connect without either of them
|
||||
entering the listening state. This feature of the TCP specification
|
||||
is claimed to enable an attacker to deny the target access to a given
|
||||
server by guessing the source port the target would use to make the
|
||||
connection.
|
||||
|
||||
This option is OFF by default because TCP simultaneous connect has
|
||||
some legitimate uses. Enable this option if you know what this TCP
|
||||
feature is for and know that you do not need it.
|
||||
'';
|
||||
};
|
||||
|
||||
verboseVersion = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Use verbose version in kernel localversion.";
|
||||
};
|
||||
|
||||
kernelExtraConfig = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = "Extra kernel configuration parameters.";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
assertions =
|
||||
[
|
||||
{ assertion = (cfg.config.restrictProc -> !cfg.config.restrictProcWithGroup) ||
|
||||
(cfg.config.restrictProcWithGroup -> !cfg.config.restrictProc);
|
||||
message = "You cannot enable both restrictProc and restrictProcWithGroup";
|
||||
}
|
||||
{ assertion = config.boot.kernelPackages.kernel.features ? grsecurity
|
||||
&& config.boot.kernelPackages.kernel.features.grsecurity;
|
||||
message = "grsecurity enabled, but kernel doesn't have grsec support";
|
||||
}
|
||||
{ assertion = (cfg.config.mode == "auto" && (cfg.config.virtualisationConfig != null)) ->
|
||||
cfg.config.hardwareVirtualisation != null;
|
||||
message = "when using auto grsec mode with virtualisation, you must specify if your hardware has virtualisation extensions";
|
||||
}
|
||||
{ assertion = (cfg.config.mode == "auto" && (cfg.config.virtualisationConfig != null)) ->
|
||||
cfg.config.virtualisationSoftware != null;
|
||||
message = "grsecurity configured for virtualisation but no virtualisation software specified";
|
||||
}
|
||||
];
|
||||
|
||||
security.grsecurity.kernelPatch = lib.mkDefault pkgs.kernelPatches.grsecurity_latest;
|
||||
|
||||
systemd.services.grsec-lock = mkIf cfg.config.sysctl {
|
||||
description = "grsecurity sysctl-lock Service";
|
||||
wants = [ "systemd-sysctl.service" ];
|
||||
after = [ "systemd-sysctl.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig.Type = "oneshot";
|
||||
serviceConfig.RemainAfterExit = "yes";
|
||||
unitConfig.ConditionPathIsReadWrite = "/proc/sys/kernel/grsecurity/grsec_lock";
|
||||
script = ''
|
||||
locked=`cat /proc/sys/kernel/grsecurity/grsec_lock`
|
||||
if [ "$locked" == "0" ]; then
|
||||
echo 1 > /proc/sys/kernel/grsecurity/grsec_lock
|
||||
echo grsecurity sysctl lock - enabled
|
||||
else
|
||||
echo grsecurity sysctl lock already enabled - doing nothing
|
||||
fi
|
||||
lockTunables = mkOption {
|
||||
type = types.bool;
|
||||
example = false;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to automatically lock grsecurity tunables
|
||||
(<option>boot.kernel.sysctl."kernel.grsecurity.*"</option>). Disable
|
||||
this to allow configuration of grsecurity features while the system is
|
||||
running. The lock can be manually engaged by activating the
|
||||
<literal>grsec-lock</literal> service unit.
|
||||
'';
|
||||
};
|
||||
|
||||
# systemd.services.grsec-learn = {
|
||||
# description = "grsecurity learning Service";
|
||||
# wantedBy = [ "local-fs.target" ];
|
||||
# serviceConfig = {
|
||||
# Type = "oneshot";
|
||||
# RemainAfterExit = "yes";
|
||||
# ExecStart = "${pkgs.gradm}/sbin/gradm -VFL /etc/grsec/learning.logs";
|
||||
# ExecStop = "${pkgs.gradm}/sbin/gradm -D";
|
||||
# };
|
||||
# };
|
||||
};
|
||||
|
||||
system.activationScripts = lib.optionalAttrs (!cfg.config.disableRBAC) { grsec = ''
|
||||
mkdir -p /etc/grsec
|
||||
if [ ! -f /etc/grsec/learn_config ]; then
|
||||
cp ${pkgs.gradm}/etc/grsec/learn_config /etc/grsec
|
||||
fi
|
||||
if [ ! -f /etc/grsec/policy ]; then
|
||||
cp ${pkgs.gradm}/etc/grsec/policy /etc/grsec
|
||||
fi
|
||||
chmod -R 0600 /etc/grsec
|
||||
''; };
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
# Allow the user to select a different package set, subject to the stated
|
||||
# required kernel config
|
||||
boot.kernelPackages = mkDefault pkgs.linuxPackages_grsec_nixos;
|
||||
|
||||
system.requiredKernelConfig = with config.lib.kernelConfig;
|
||||
[ (isEnabled "GRKERNSEC")
|
||||
(isEnabled "PAX")
|
||||
(isYES "GRKERNSEC_SYSCTL")
|
||||
(isYES "GRKERNSEC_SYSCTL_DISTRO")
|
||||
];
|
||||
|
||||
# Crashing on an overflow in kernel land is user unfriendly and may prevent
|
||||
# the system from booting, which is too severe for our use case.
|
||||
boot.kernelParams = [ "pax_size_overflow_report_only" ];
|
||||
|
||||
# Install PaX related utillities into the system profile. Eventually, we
|
||||
# also want to include gradm here.
|
||||
environment.systemPackages = with pkgs; [ paxctl pax-utils ];
|
||||
|
||||
# Install rules for the grsec device node
|
||||
services.udev.packages = [ pkgs.gradm ];
|
||||
|
||||
# This service unit is responsible for locking the Grsecurity tunables. The
|
||||
# unit is always defined, but only activated on bootup if lockTunables is
|
||||
# toggled. When lockTunables is toggled, failure to activate the unit will
|
||||
# enter emergency mode. The intent is to make it difficult to silently
|
||||
# enter multi-user mode without having locked the tunables. Some effort is
|
||||
# made to ensure that starting the unit is an idempotent operation.
|
||||
systemd.services.grsec-lock = {
|
||||
description = "Lock grsecurity tunables";
|
||||
|
||||
wantedBy = optional cfg.lockTunables "multi-user.target";
|
||||
|
||||
wants = [ "local-fs.target" "systemd-sysctl.service" ];
|
||||
after = [ "local-fs.target" "systemd-sysctl.service" ];
|
||||
conflicts = [ "shutdown.target" ];
|
||||
|
||||
restartIfChanged = false;
|
||||
|
||||
script = ''
|
||||
if ${pkgs.gnugrep}/bin/grep -Fq 0 ${grsecLockPath} ; then
|
||||
echo -n 1 > ${grsecLockPath}
|
||||
fi
|
||||
'';
|
||||
|
||||
unitConfig = {
|
||||
ConditionPathIsReadWrite = grsecLockPath;
|
||||
DefaultDependencies = false;
|
||||
} // optionalAttrs cfg.lockTunables {
|
||||
OnFailure = "emergency.target";
|
||||
};
|
||||
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
};
|
||||
|
||||
# Configure system tunables
|
||||
boot.kernel.sysctl = {
|
||||
# Removed under grsecurity
|
||||
"kernel.kptr_restrict" = mkForce null;
|
||||
} // optionalAttrs config.nix.useSandbox {
|
||||
# chroot(2) restrictions that conflict with sandboxed Nix builds
|
||||
"kernel.grsecurity.chroot_caps" = mkForce 0;
|
||||
"kernel.grsecurity.chroot_deny_chroot" = mkForce 0;
|
||||
"kernel.grsecurity.chroot_deny_mount" = mkForce 0;
|
||||
"kernel.grsecurity.chroot_deny_pivot" = mkForce 0;
|
||||
} // optionalAttrs config.boot.enableContainers {
|
||||
# chroot(2) restrictions that conflict with NixOS lightweight containers
|
||||
"kernel.grsecurity.chroot_deny_chmod" = mkForce 0;
|
||||
"kernel.grsecurity.chroot_deny_mount" = mkForce 0;
|
||||
"kernel.grsecurity.chroot_restrict_nice" = mkForce 0;
|
||||
};
|
||||
|
||||
assertions = [
|
||||
{ assertion = !zfsNeededForBoot;
|
||||
message = "grsecurity is currently incompatible with ZFS";
|
||||
}
|
||||
];
|
||||
|
||||
# Enable AppArmor, gradm udev rules, and utilities
|
||||
security.apparmor.enable = true;
|
||||
boot.kernelPackages = customGrsecPkg;
|
||||
services.udev.packages = lib.optional (!cfg.config.disableRBAC) pkgs.gradm;
|
||||
environment.systemPackages = [ pkgs.paxctl pkgs.pax-utils ] ++ lib.optional (!cfg.config.disableRBAC) pkgs.gradm;
|
||||
};
|
||||
}
|
||||
|
67
nixos/modules/services/audio/squeezelite.nix
Normal file
67
nixos/modules/services/audio/squeezelite.nix
Normal file
@ -0,0 +1,67 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
uid = config.ids.uids.squeezelite;
|
||||
cfg = config.services.squeezelite;
|
||||
|
||||
in {
|
||||
|
||||
###### interface
|
||||
|
||||
options = {
|
||||
|
||||
services.squeezelite= {
|
||||
|
||||
enable = mkEnableOption "Squeezelite, a software Squeezebox emulator";
|
||||
|
||||
dataDir = mkOption {
|
||||
default = "/var/lib/squeezelite";
|
||||
type = types.str;
|
||||
description = ''
|
||||
The directory where Squeezelite stores its name file.
|
||||
'';
|
||||
};
|
||||
|
||||
extraArguments = mkOption {
|
||||
default = "";
|
||||
type = types.str;
|
||||
description = ''
|
||||
Additional command line arguments to pass to Squeezelite.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
systemd.services.squeezelite= {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" "sound.target" ];
|
||||
description = "Software Squeezebox emulator";
|
||||
preStart = "mkdir -p ${cfg.dataDir} && chown -R squeezelite ${cfg.dataDir}";
|
||||
serviceConfig = {
|
||||
ExecStart = "${pkgs.squeezelite}/bin/squeezelite -N ${cfg.dataDir}/player-name ${cfg.extraArguments}";
|
||||
User = "squeezelite";
|
||||
PermissionsStartOnly = true;
|
||||
};
|
||||
};
|
||||
|
||||
users.extraUsers.squeezelite= {
|
||||
inherit uid;
|
||||
group = "nogroup";
|
||||
extraGroups = [ "audio" ];
|
||||
description = "Squeezelite user";
|
||||
home = "${cfg.dataDir}";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.buildkite-agent;
|
||||
configFile = pkgs.writeText "buildkite-agent.cfg"
|
||||
''
|
||||
token="${cfg.token}"
|
||||
name="${cfg.name}"
|
||||
meta-data="${cfg.meta-data}"
|
||||
hooks-path="${pkgs.buildkite-agent}/share/hooks"
|
||||
build-path="/var/lib/buildkite-agent/builds"
|
||||
bootstrap-script="${pkgs.buildkite-agent}/share/bootstrap.sh"
|
||||
'';
|
||||
in
|
||||
|
||||
{
|
||||
options = {
|
||||
services.buildkite-agent = {
|
||||
enable = mkEnableOption "buildkite-agent";
|
||||
|
||||
token = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
The token from your Buildkite "Agents" page.
|
||||
'';
|
||||
};
|
||||
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
The name of the agent.
|
||||
'';
|
||||
};
|
||||
|
||||
meta-data = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
Meta data for the agent.
|
||||
'';
|
||||
};
|
||||
|
||||
openssh =
|
||||
{ privateKey = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
Private agent key.
|
||||
'';
|
||||
};
|
||||
publicKey = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
Public agent key.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf config.services.buildkite-agent.enable {
|
||||
users.extraUsers.buildkite-agent =
|
||||
{ name = "buildkite-agent";
|
||||
home = "/var/lib/buildkite-agent";
|
||||
createHome = true;
|
||||
description = "Buildkite agent user";
|
||||
};
|
||||
|
||||
environment.systemPackages = [ pkgs.buildkite-agent ];
|
||||
|
||||
systemd.services.buildkite-agent =
|
||||
{ description = "Buildkite Agent";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
environment.HOME = "/var/lib/buildkite-agent";
|
||||
preStart = ''
|
||||
${pkgs.coreutils}/bin/mkdir -m 0700 -p /var/lib/buildkite-agent/.ssh
|
||||
|
||||
if ! [ -f /var/lib/buildkite-agent/.ssh/id_rsa ]; then
|
||||
echo "${cfg.openssh.privateKey}" > /var/lib/buildkite-agent/.ssh/id_rsa
|
||||
${pkgs.coreutils}/bin/chmod 600 /var/lib/buildkite-agent/.ssh/id_rsa
|
||||
fi
|
||||
|
||||
if ! [ -f /var/lib/buildkite-agent/.ssh/id_rsa.pub ]; then
|
||||
echo "${cfg.openssh.publicKey}" > /var/lib/buildkite-agent/.ssh/id_rsa.pub
|
||||
${pkgs.coreutils}/bin/chmod 600 /var/lib/buildkite-agent/.ssh/id_rsa.pub
|
||||
fi
|
||||
'';
|
||||
|
||||
serviceConfig =
|
||||
{ ExecStart = "${pkgs.buildkite-agent}/bin/buildkite-agent start --config ${configFile}";
|
||||
User = "buildkite-agent";
|
||||
RestartSec = 5;
|
||||
Restart = "on-failure";
|
||||
TimeoutSec = 10;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
@ -154,7 +154,7 @@ in {
|
||||
'';
|
||||
|
||||
script = ''
|
||||
${pkgs.jdk}/bin/java -jar ${pkgs.jenkins} --httpListenAddress=${cfg.listenAddress} \
|
||||
${pkgs.jdk}/bin/java -jar ${pkgs.jenkins}/lib/jenkins.war --httpListenAddress=${cfg.listenAddress} \
|
||||
--httpPort=${toString cfg.port} \
|
||||
--prefix=${cfg.prefix} \
|
||||
${concatStringsSep " " cfg.extraOptions}
|
||||
|
@ -40,6 +40,13 @@ in
|
||||
description = "Group account under which slapd runs.";
|
||||
};
|
||||
|
||||
urlList = mkOption {
|
||||
type = types.listOf types.string;
|
||||
default = [ "ldap:///" ];
|
||||
description = "URL list slapd should listen on.";
|
||||
example = [ "ldaps:///" ];
|
||||
};
|
||||
|
||||
dataDir = mkOption {
|
||||
type = types.string;
|
||||
default = "/var/db/openldap";
|
||||
@ -50,7 +57,7 @@ in
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = "
|
||||
sldapd.conf configuration
|
||||
slapd.conf configuration
|
||||
";
|
||||
example = literalExample ''
|
||||
'''
|
||||
@ -89,7 +96,7 @@ in
|
||||
mkdir -p ${cfg.dataDir}
|
||||
chown -R ${cfg.user}:${cfg.group} ${cfg.dataDir}
|
||||
'';
|
||||
serviceConfig.ExecStart = "${openldap.out}/libexec/slapd -u ${cfg.user} -g ${cfg.group} -d 0 -f ${configFile}";
|
||||
serviceConfig.ExecStart = "${openldap.out}/libexec/slapd -u ${cfg.user} -g ${cfg.group} -d 0 -h \"${concatStringsSep " " cfg.urlList}\" -f ${configFile}";
|
||||
};
|
||||
|
||||
users.extraUsers.openldap =
|
||||
|
86
nixos/modules/services/editors/emacs.nix
Normal file
86
nixos/modules/services/editors/emacs.nix
Normal file
@ -0,0 +1,86 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.emacs;
|
||||
|
||||
editorScript = pkgs.writeScriptBin "emacseditor" ''
|
||||
#!${pkgs.stdenv.shell}
|
||||
if [ -z "$1" ]; then
|
||||
exec ${cfg.package}/bin/emacsclient --create-frame --alternate-editor ${cfg.package}/bin/emacs
|
||||
else
|
||||
exec ${cfg.package}/bin/emacsclient --alternate-editor ${cfg.package}/bin/emacs "$@"
|
||||
fi
|
||||
'';
|
||||
|
||||
in {
|
||||
|
||||
options.services.emacs = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
example = true;
|
||||
description = ''
|
||||
Whether to enable a user service for the Emacs daemon. Use <literal>emacsclient</literal> to connect to the
|
||||
daemon. If <literal>true</literal>, <varname>services.emacs.install</varname> is
|
||||
considered <literal>true</literal>, whatever its value.
|
||||
'';
|
||||
};
|
||||
|
||||
install = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
example = true;
|
||||
description = ''
|
||||
Whether to install a user service for the Emacs daemon. Once
|
||||
the service is started, use emacsclient to connect to the
|
||||
daemon.
|
||||
|
||||
The service must be manually started for each user with
|
||||
"systemctl --user start emacs" or globally through
|
||||
<varname>services.emacs.enable</varname>.
|
||||
'';
|
||||
};
|
||||
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.emacs;
|
||||
defaultText = "pkgs.emacs";
|
||||
description = ''
|
||||
emacs derivation to use.
|
||||
'';
|
||||
};
|
||||
|
||||
defaultEditor = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
example = true;
|
||||
description = ''
|
||||
When enabled, configures emacsclient to be the default editor
|
||||
using the EDITOR environment variable.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf (cfg.enable || cfg.install) {
|
||||
systemd.user.services.emacs = {
|
||||
description = "Emacs: the extensible, self-documenting text editor";
|
||||
|
||||
serviceConfig = {
|
||||
Type = "forking";
|
||||
ExecStart = "${pkgs.bash}/bin/bash -c 'source ${config.system.build.setEnvironment}; exec ${cfg.package}/bin/emacs --daemon'";
|
||||
ExecStop = "${cfg.package}/bin/emacsclient --eval (kill-emacs)";
|
||||
Restart = "always";
|
||||
};
|
||||
} // optionalAttrs cfg.enable { wantedBy = [ "default.target" ]; };
|
||||
|
||||
environment.systemPackages = [ cfg.package editorScript ];
|
||||
|
||||
environment.variables = if cfg.defaultEditor then {
|
||||
EDITOR = mkOverride 900 "${editorScript}/bin/emacseditor";
|
||||
} else {};
|
||||
};
|
||||
}
|
@ -78,7 +78,7 @@ in
|
||||
test -e ${stateDir}/saves/${cfg.saveName}.zip || \
|
||||
${pkgs.factorio-headless}/bin/factorio \
|
||||
--config=${cfg.configFile} \
|
||||
--create=${cfg.saveName}
|
||||
--create=${stateDir}/saves/${cfg.saveName}.zip
|
||||
'';
|
||||
|
||||
serviceConfig = {
|
||||
@ -93,7 +93,7 @@ in
|
||||
"${pkgs.factorio-headless}/bin/factorio"
|
||||
"--config=${cfg.configFile}"
|
||||
"--port=${toString cfg.port}"
|
||||
"--start-server=${cfg.saveName}"
|
||||
"--start-server=${stateDir}/saves/${cfg.saveName}.zip"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
@ -54,6 +54,9 @@ in
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
powerManagement.scsiLinkPolicy = null;
|
||||
powerManagement.cpuFreqGovernor = null;
|
||||
|
||||
systemd.services = {
|
||||
tlp = {
|
||||
description = "TLP system startup/shutdown";
|
||||
@ -61,6 +64,7 @@ in
|
||||
after = [ "multi-user.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
before = [ "shutdown.target" ];
|
||||
restartTriggers = [ confFile ];
|
||||
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
|
@ -105,7 +105,7 @@ in
|
||||
prune {
|
||||
whitelist_names => [
|
||||
"type", "@timestamp", "@version",
|
||||
"MESSAGE", "PRIORITY", "SYSLOG_FACILITY",
|
||||
"MESSAGE", "PRIORITY", "SYSLOG_FACILITY"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ in {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = "${pkgs.opendkim}/bin/opendkim ${concatMapStringsSep " " escapeShellArg args}";
|
||||
ExecStart = "${pkgs.opendkim}/bin/opendkim ${escapeShellArgs args}";
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
RuntimeDirectory = optional (cfg.socket == defaultSock) "opendkim";
|
||||
|
@ -127,11 +127,11 @@ let
|
||||
# (yes) (yes) (no) (never) (100)
|
||||
# ==========================================================================
|
||||
smtp inet n - n - - smtpd
|
||||
#submission inet n - n - - smtpd
|
||||
# -o smtpd_tls_security_level=encrypt
|
||||
# -o smtpd_sasl_auth_enable=yes
|
||||
# -o smtpd_client_restrictions=permit_sasl_authenticated,reject
|
||||
# -o milter_macro_daemon_name=ORIGINATING
|
||||
'' + optionalString cfg.enableSubmission ''
|
||||
submission inet n - n - - smtpd
|
||||
${concatStringsSep "\n " (mapAttrsToList (x: y: "-o " + x + "=" + y) cfg.submissionOptions)}
|
||||
''
|
||||
+ ''
|
||||
pickup unix n - n 60 1 pickup
|
||||
cleanup unix n - n - 0 cleanup
|
||||
qmgr unix n - n 300 1 qmgr
|
||||
@ -201,6 +201,28 @@ in
|
||||
default = true;
|
||||
description = "Whether to enable smtp in master.cf.";
|
||||
};
|
||||
|
||||
enableSubmission = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Whether to enable smtp submission";
|
||||
};
|
||||
|
||||
submissionOptions = mkOption {
|
||||
type = types.attrs;
|
||||
default = { "smtpd_tls_security_level" = "encrypt";
|
||||
"smtpd_sasl_auth_enable" = "yes";
|
||||
"smtpd_client_restrictions" = "permit_sasl_authenticated,reject";
|
||||
"milter_macro_daemon_name" = "ORIGINATING";
|
||||
};
|
||||
description = "Options for the submission config in master.cf";
|
||||
example = { "smtpd_tls_security_level" = "encrypt";
|
||||
"smtpd_sasl_auth_enable" = "yes";
|
||||
"smtpd_sasl_type" = "dovecot";
|
||||
"smtpd_client_restrictions" = "permit_sasl_authenticated,reject";
|
||||
"milter_macro_daemon_name" = "ORIGINATING";
|
||||
};
|
||||
};
|
||||
|
||||
setSendmail = mkOption {
|
||||
type = types.bool;
|
||||
|
@ -75,7 +75,7 @@ in {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
serviceConfig = {
|
||||
ExecStart = "${cfg.package}/bin/confd";
|
||||
ExecStart = "${cfg.package.bin}/bin/confd";
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -36,49 +36,32 @@ in
|
||||
default = false;
|
||||
description = "Whether to enable the DisnixWebService interface running on Apache Tomcat";
|
||||
};
|
||||
|
||||
publishInfrastructure = {
|
||||
enable = mkOption {
|
||||
default = false;
|
||||
description = "Whether to publish capabilities/properties of this machine in as attributes in the infrastructure option";
|
||||
};
|
||||
|
||||
enableAuthentication = mkOption {
|
||||
default = false;
|
||||
description = "Whether to publish authentication credentials through the infrastructure attribute (not recommended in combination with Avahi)";
|
||||
};
|
||||
};
|
||||
|
||||
infrastructure = mkOption {
|
||||
default = {};
|
||||
description = "List of name value pairs containing properties for the infrastructure model";
|
||||
};
|
||||
|
||||
publishAvahi = mkOption {
|
||||
default = false;
|
||||
description = "Whether to publish capabilities/properties as a Disnix service through Avahi";
|
||||
|
||||
package = mkOption {
|
||||
type = types.path;
|
||||
description = "The Disnix package";
|
||||
default = pkgs.disnix;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
environment.systemPackages = [ pkgs.disnix pkgs.dysnomia ] ++ optional cfg.useWebServiceInterface pkgs.DisnixWebService;
|
||||
dysnomia.enable = true;
|
||||
|
||||
environment.systemPackages = [ pkgs.disnix ] ++ optional cfg.useWebServiceInterface pkgs.DisnixWebService;
|
||||
|
||||
services.dbus.enable = true;
|
||||
services.dbus.packages = [ pkgs.disnix ];
|
||||
|
||||
services.avahi.enable = cfg.publishAvahi;
|
||||
|
||||
services.tomcat.enable = cfg.useWebServiceInterface;
|
||||
services.tomcat.extraGroups = [ "disnix" ];
|
||||
services.tomcat.javaOpts = "${optionalString cfg.useWebServiceInterface "-Djava.library.path=${pkgs.libmatthew_java}/lib/jni"} ";
|
||||
services.tomcat.sharedLibs = optional cfg.useWebServiceInterface "${pkgs.DisnixWebService}/share/java/DisnixConnection.jar"
|
||||
++ optional cfg.useWebServiceInterface "${pkgs.dbus_java}/share/java/dbus.jar";
|
||||
++ optional cfg.useWebServiceInterface "${pkgs.dbus_java}/share/java/dbus.jar";
|
||||
services.tomcat.webapps = optional cfg.useWebServiceInterface pkgs.DisnixWebService;
|
||||
|
||||
users.extraGroups = singleton
|
||||
@ -86,38 +69,6 @@ in
|
||||
gid = config.ids.gids.disnix;
|
||||
};
|
||||
|
||||
services.disnix.infrastructure =
|
||||
optionalAttrs (cfg.publishInfrastructure.enable)
|
||||
( { hostname = config.networking.hostName;
|
||||
#targetHost = config.deployment.targetHost;
|
||||
system = if config.nixpkgs.system == "" then builtins.currentSystem else config.nixpkgs.system;
|
||||
|
||||
supportedTypes = (import "${pkgs.stdenv.mkDerivation {
|
||||
name = "supportedtypes";
|
||||
buildCommand = ''
|
||||
( echo -n "[ "
|
||||
cd ${dysnomia}/libexec/dysnomia
|
||||
for i in *
|
||||
do
|
||||
echo -n "\"$i\" "
|
||||
done
|
||||
echo -n " ]") > $out
|
||||
'';
|
||||
}}");
|
||||
}
|
||||
#// optionalAttrs (cfg.useWebServiceInterface) { targetEPR = "http://${config.deployment.targetHost}:8080/DisnixWebService/services/DisnixWebService"; }
|
||||
// optionalAttrs (config.services.httpd.enable) { documentRoot = config.services.httpd.documentRoot; }
|
||||
// optionalAttrs (config.services.mysql.enable) { mysqlPort = config.services.mysql.port; }
|
||||
// optionalAttrs (config.services.tomcat.enable) { tomcatPort = 8080; }
|
||||
// optionalAttrs (config.services.svnserve.enable) { svnBaseDir = config.services.svnserve.svnBaseDir; }
|
||||
// optionalAttrs (config.services.ejabberd.enable) { ejabberdUser = config.services.ejabberd.user; }
|
||||
// optionalAttrs (cfg.publishInfrastructure.enableAuthentication) (
|
||||
optionalAttrs (config.services.mysql.enable) { mysqlUsername = "root"; mysqlPassword = readFile config.services.mysql.rootPassword; })
|
||||
)
|
||||
;
|
||||
|
||||
services.disnix.publishInfrastructure.enable = cfg.publishAvahi;
|
||||
|
||||
systemd.services = {
|
||||
disnix = {
|
||||
description = "Disnix server";
|
||||
@ -133,46 +84,17 @@ in
|
||||
|
||||
restartIfChanged = false;
|
||||
|
||||
path = [ pkgs.nix pkgs.disnix dysnomia "/run/current-system/sw" ];
|
||||
path = [ config.nix.package cfg.package config.dysnomia.package "/run/current-system/sw" ];
|
||||
|
||||
environment = {
|
||||
HOME = "/root";
|
||||
};
|
||||
|
||||
preStart = ''
|
||||
mkdir -p /etc/systemd-mutable/system
|
||||
if [ ! -f /etc/systemd-mutable/system/dysnomia.target ]
|
||||
then
|
||||
( echo "[Unit]"
|
||||
echo "Description=Services that are activated and deactivated by Dysnomia"
|
||||
echo "After=final.target"
|
||||
) > /etc/systemd-mutable/system/dysnomia.target
|
||||
fi
|
||||
'';
|
||||
|
||||
script = "disnix-service";
|
||||
}
|
||||
// (if config.environment.variables ? DYSNOMIA_CONTAINERS_PATH then { inherit (config.environment.variables) DYSNOMIA_CONTAINERS_PATH; } else {})
|
||||
// (if config.environment.variables ? DYSNOMIA_MODULES_PATH then { inherit (config.environment.variables) DYSNOMIA_MODULES_PATH; } else {});
|
||||
|
||||
serviceConfig.ExecStart = "${cfg.package}/bin/disnix-service";
|
||||
};
|
||||
} // optionalAttrs cfg.publishAvahi {
|
||||
disnixAvahi = {
|
||||
description = "Disnix Avahi publisher";
|
||||
wants = [ "avahi-daemon.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
script = ''
|
||||
${pkgs.avahi}/bin/avahi-publish-service disnix-${config.networking.hostName} _disnix._tcp 22 \
|
||||
"mem=$(grep 'MemTotal:' /proc/meminfo | sed -e 's/kB//' -e 's/MemTotal://' -e 's/ //g')" \
|
||||
${concatMapStrings (infrastructureAttrName:
|
||||
let infrastructureAttrValue = getAttr infrastructureAttrName (cfg.infrastructure);
|
||||
in
|
||||
if isInt infrastructureAttrValue then
|
||||
''${infrastructureAttrName}=${toString infrastructureAttrValue} \
|
||||
''
|
||||
else
|
||||
''${infrastructureAttrName}=\"${infrastructureAttrValue}\" \
|
||||
''
|
||||
) (attrNames (cfg.infrastructure))}
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
217
nixos/modules/services/misc/dysnomia.nix
Normal file
217
nixos/modules/services/misc/dysnomia.nix
Normal file
@ -0,0 +1,217 @@
|
||||
{pkgs, lib, config, ...}:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.dysnomia;
|
||||
|
||||
printProperties = properties:
|
||||
concatMapStrings (propertyName:
|
||||
let
|
||||
property = properties."${propertyName}";
|
||||
in
|
||||
if isList property then "${propertyName}=(${lib.concatMapStrings (elem: "\"${toString elem}\" ") (properties."${propertyName}")})\n"
|
||||
else "${propertyName}=\"${toString property}\"\n"
|
||||
) (builtins.attrNames properties);
|
||||
|
||||
properties = pkgs.stdenv.mkDerivation {
|
||||
name = "dysnomia-properties";
|
||||
buildCommand = ''
|
||||
cat > $out << "EOF"
|
||||
${printProperties cfg.properties}
|
||||
EOF
|
||||
'';
|
||||
};
|
||||
|
||||
containersDir = pkgs.stdenv.mkDerivation {
|
||||
name = "dysnomia-containers";
|
||||
buildCommand = ''
|
||||
mkdir -p $out
|
||||
cd $out
|
||||
|
||||
${concatMapStrings (containerName:
|
||||
let
|
||||
containerProperties = cfg.containers."${containerName}";
|
||||
in
|
||||
''
|
||||
cat > ${containerName} <<EOF
|
||||
${printProperties containerProperties}
|
||||
type=${containerName}
|
||||
EOF
|
||||
''
|
||||
) (builtins.attrNames cfg.containers)}
|
||||
'';
|
||||
};
|
||||
|
||||
linkMutableComponents = {containerName}:
|
||||
''
|
||||
mkdir ${containerName}
|
||||
|
||||
${concatMapStrings (componentName:
|
||||
let
|
||||
component = cfg.components."${containerName}"."${componentName}";
|
||||
in
|
||||
"ln -s ${component} ${containerName}/${componentName}\n"
|
||||
) (builtins.attrNames (cfg.components."${containerName}" or {}))}
|
||||
'';
|
||||
|
||||
componentsDir = pkgs.stdenv.mkDerivation {
|
||||
name = "dysnomia-components";
|
||||
buildCommand = ''
|
||||
mkdir -p $out
|
||||
cd $out
|
||||
|
||||
${concatMapStrings (containerName:
|
||||
let
|
||||
components = cfg.components."${containerName}";
|
||||
in
|
||||
linkMutableComponents { inherit containerName; }
|
||||
) (builtins.attrNames cfg.components)}
|
||||
'';
|
||||
};
|
||||
in
|
||||
{
|
||||
options = {
|
||||
dysnomia = {
|
||||
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Whether to enable Dysnomia";
|
||||
};
|
||||
|
||||
enableAuthentication = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Whether to publish privacy-sensitive authentication credentials";
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
type = types.path;
|
||||
description = "The Dysnomia package";
|
||||
};
|
||||
|
||||
properties = mkOption {
|
||||
description = "An attribute set in which each attribute represents a machine property. Optionally, these values can be shell substitutions.";
|
||||
default = {};
|
||||
};
|
||||
|
||||
containers = mkOption {
|
||||
description = "An attribute set in which each key represents a container and each value an attribute set providing its configuration properties";
|
||||
default = {};
|
||||
};
|
||||
|
||||
components = mkOption {
|
||||
description = "An atttribute set in which each key represents a container and each value an attribute set in which each key represents a component and each value a derivation constructing its initial state";
|
||||
default = {};
|
||||
};
|
||||
|
||||
extraContainerProperties = mkOption {
|
||||
description = "An attribute set providing additional container settings in addition to the default properties";
|
||||
default = {};
|
||||
};
|
||||
|
||||
extraContainerPaths = mkOption {
|
||||
description = "A list of paths containing additional container configurations that are added to the search folders";
|
||||
default = [];
|
||||
};
|
||||
|
||||
extraModulePaths = mkOption {
|
||||
description = "A list of paths containing additional modules that are added to the search folders";
|
||||
default = [];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
environment.etc = {
|
||||
"dysnomia/containers" = {
|
||||
source = containersDir;
|
||||
};
|
||||
"dysnomia/components" = {
|
||||
source = componentsDir;
|
||||
};
|
||||
"dysnomia/properties" = {
|
||||
source = properties;
|
||||
};
|
||||
};
|
||||
|
||||
environment.variables = {
|
||||
DYSNOMIA_STATEDIR = "/var/state/dysnomia-nixos";
|
||||
DYSNOMIA_CONTAINERS_PATH = "${lib.concatMapStrings (containerPath: "${containerPath}:") cfg.extraContainerPaths}/etc/dysnomia/containers";
|
||||
DYSNOMIA_MODULES_PATH = "${lib.concatMapStrings (modulePath: "${modulePath}:") cfg.extraModulePaths}/etc/dysnomia/modules";
|
||||
};
|
||||
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
|
||||
dysnomia.package = pkgs.dysnomia.override (origArgs: {
|
||||
enableApacheWebApplication = config.services.httpd.enable;
|
||||
enableAxis2WebService = config.services.tomcat.axis2.enable;
|
||||
enableEjabberdDump = config.services.ejabberd.enable;
|
||||
enableMySQLDatabase = config.services.mysql.enable;
|
||||
enablePostgreSQLDatabase = config.services.postgresql.enable;
|
||||
enableSubversionRepository = config.services.svnserve.enable;
|
||||
enableTomcatWebApplication = config.services.tomcat.enable;
|
||||
enableMongoDatabase = config.services.mongodb.enable;
|
||||
});
|
||||
|
||||
dysnomia.properties = {
|
||||
hostname = config.networking.hostName;
|
||||
system = if config.nixpkgs.system == "" then builtins.currentSystem else config.nixpkgs.system;
|
||||
|
||||
supportedTypes = (import "${pkgs.stdenv.mkDerivation {
|
||||
name = "supportedtypes";
|
||||
buildCommand = ''
|
||||
( echo -n "[ "
|
||||
cd ${cfg.package}/libexec/dysnomia
|
||||
for i in *
|
||||
do
|
||||
echo -n "\"$i\" "
|
||||
done
|
||||
echo -n " ]") > $out
|
||||
'';
|
||||
}}");
|
||||
};
|
||||
|
||||
dysnomia.containers = lib.recursiveUpdate ({
|
||||
process = {};
|
||||
wrapper = {};
|
||||
}
|
||||
// lib.optionalAttrs (config.services.httpd.enable) { apache-webapplication = {
|
||||
documentRoot = config.services.httpd.documentRoot;
|
||||
}; }
|
||||
// lib.optionalAttrs (config.services.tomcat.axis2.enable) { axis2-webservice = {}; }
|
||||
// lib.optionalAttrs (config.services.ejabberd.enable) { ejabberd-dump = {
|
||||
ejabberdUser = config.services.ejabberd.user;
|
||||
}; }
|
||||
// lib.optionalAttrs (config.services.mysql.enable) { mysql-database = {
|
||||
mysqlPort = config.services.mysql.port;
|
||||
} // lib.optionalAttrs cfg.enableAuthentication {
|
||||
mysqlUsername = "root";
|
||||
mysqlPassword = builtins.readFile (config.services.mysql.rootPassword);
|
||||
};
|
||||
}
|
||||
// lib.optionalAttrs (config.services.postgresql.enable && cfg.enableAuthentication) { postgresql-database = {
|
||||
postgresqlUsername = "root";
|
||||
}; }
|
||||
// lib.optionalAttrs (config.services.tomcat.enable) { tomcat-webapplication = {
|
||||
tomcatPort = 8080;
|
||||
}; }
|
||||
// lib.optionalAttrs (config.services.mongodb.enable) { mongo-database = {}; }
|
||||
// lib.optionalAttrs (config.services.svnserve.enable) { subversion-repository = {
|
||||
svnBaseDir = config.services.svnserve.svnBaseDir;
|
||||
}; }) cfg.extraContainerProperties;
|
||||
|
||||
system.activationScripts.dysnomia = ''
|
||||
mkdir -p /etc/systemd-mutable/system
|
||||
if [ ! -f /etc/systemd-mutable/system/dysnomia.target ]
|
||||
then
|
||||
( echo "[Unit]"
|
||||
echo "Description=Services that are activated and deactivated by Dysnomia"
|
||||
echo "After=final.target"
|
||||
) > /etc/systemd-mutable/system/dysnomia.target
|
||||
fi
|
||||
'';
|
||||
};
|
||||
}
|
@ -115,7 +115,7 @@ in {
|
||||
|
||||
serviceConfig = {
|
||||
Type = "notify";
|
||||
ExecStart = "${pkgs.etcd}/bin/etcd";
|
||||
ExecStart = "${pkgs.etcd.bin}/bin/etcd";
|
||||
User = "etcd";
|
||||
PermissionsStartOnly = true;
|
||||
};
|
||||
|
@ -5,17 +5,31 @@ with lib;
|
||||
let
|
||||
cfg = config.services.matrix-synapse;
|
||||
logConfigFile = pkgs.writeText "log_config.yaml" cfg.logConfig;
|
||||
mkResource = r: ''{names: ${builtins.toJSON r.names}, compress: ${if r.compress then "true" else "false"}}'';
|
||||
mkListener = l: ''{port: ${toString l.port}, bind_address: "${l.bind_address}", type: ${l.type}, tls: ${if l.tls then "true" else "false"}, x_forwarded: ${if l.x_forwarded then "true" else "false"}, resources: [${concatStringsSep "," (map mkResource l.resources)}]}'';
|
||||
configFile = pkgs.writeText "homeserver.yaml" ''
|
||||
tls_certificate_path: "${cfg.tls_certificate_path}"
|
||||
${optionalString (cfg.tls_private_key_path != null) ''
|
||||
tls_private_key_path: "${cfg.tls_private_key_path}"
|
||||
''}
|
||||
tls_dh_params_path: "${cfg.tls_dh_params_path}"
|
||||
no_tls: ${if cfg.no_tls then "true" else "false"}
|
||||
${optionalString (cfg.bind_port != null) ''
|
||||
bind_port: ${toString cfg.bind_port}
|
||||
''}
|
||||
${optionalString (cfg.unsecure_port != null) ''
|
||||
unsecure_port: ${toString cfg.unsecure_port}
|
||||
''}
|
||||
${optionalString (cfg.bind_host != null) ''
|
||||
bind_host: "${cfg.bind_host}"
|
||||
''}
|
||||
server_name: "${cfg.server_name}"
|
||||
pid_file: "/var/run/matrix-synapse.pid"
|
||||
web_client: ${if cfg.web_client then "true" else "false"}
|
||||
${optionalString (cfg.public_baseurl != null) ''
|
||||
public_baseurl: "${cfg.public_baseurl}"
|
||||
''}
|
||||
listeners: [${concatStringsSep "," (map mkListener cfg.listeners)}]
|
||||
database: {
|
||||
name: "${cfg.database_type}",
|
||||
args: {
|
||||
@ -24,21 +38,41 @@ database: {
|
||||
)}
|
||||
}
|
||||
}
|
||||
event_cache_size: "${cfg.event_cache_size}"
|
||||
verbose: ${cfg.verbose}
|
||||
log_file: "/var/log/matrix-synapse/homeserver.log"
|
||||
log_config: "${logConfigFile}"
|
||||
rc_messages_per_second: ${cfg.rc_messages_per_second}
|
||||
rc_message_burst_count: ${cfg.rc_message_burst_count}
|
||||
federation_rc_window_size: ${cfg.federation_rc_window_size}
|
||||
federation_rc_sleep_limit: ${cfg.federation_rc_sleep_limit}
|
||||
federation_rc_sleep_delay: ${cfg.federation_rc_sleep_delay}
|
||||
federation_rc_reject_limit: ${cfg.federation_rc_reject_limit}
|
||||
federation_rc_concurrent: ${cfg.federation_rc_concurrent}
|
||||
media_store_path: "/var/lib/matrix-synapse/media"
|
||||
uploads_path: "/var/lib/matrix-synapse/uploads"
|
||||
max_upload_size: "${cfg.max_upload_size}"
|
||||
max_image_pixels: "${cfg.max_image_pixels}"
|
||||
dynamic_thumbnails: ${if cfg.dynamic_thumbnails then "true" else "false"}
|
||||
url_preview_enabled: False
|
||||
recaptcha_private_key: "${cfg.recaptcha_private_key}"
|
||||
recaptcha_public_key: "${cfg.recaptcha_public_key}"
|
||||
enable_registration_captcha: ${if cfg.enable_registration_captcha then "true" else "false"}
|
||||
turn_uris: ${if (length cfg.turn_uris) == 0 then "[]" else ("\n" + (concatStringsSep "\n" (map (s: "- " + s) cfg.turn_uris)))}
|
||||
turn_uris: ${builtins.toJSON cfg.turn_uris}
|
||||
turn_shared_secret: "${cfg.turn_shared_secret}"
|
||||
enable_registration: ${if cfg.enable_registration then "true" else "false"}
|
||||
${optionalString (cfg.registration_shared_secret != "") ''
|
||||
${optionalString (cfg.registration_shared_secret != null) ''
|
||||
registration_shared_secret: "${cfg.registration_shared_secret}"
|
||||
''}
|
||||
recaptcha_siteverify_api: "https://www.google.com/recaptcha/api/siteverify"
|
||||
turn_user_lifetime: "${cfg.turn_user_lifetime}"
|
||||
user_creation_max_duration: ${cfg.user_creation_max_duration}
|
||||
bcrypt_rounds: ${cfg.bcrypt_rounds}
|
||||
allow_guest_access: {if cfg.allow_guest_access then "true" else "false"}
|
||||
enable_metrics: ${if cfg.enable_metrics then "true" else "false"}
|
||||
report_stats: ${if cfg.report_stats then "true" else "false"}
|
||||
signing_key_path: "/var/lib/matrix-synapse/homeserver.signing.key"
|
||||
key_refresh_interval: "${cfg.key_refresh_interval}"
|
||||
perspectives:
|
||||
servers: {
|
||||
${concatStringsSep "},\n" (mapAttrsToList (n: v: ''
|
||||
@ -52,6 +86,8 @@ perspectives:
|
||||
'') cfg.servers)}
|
||||
}
|
||||
}
|
||||
app_service_config_files: ${builtins.toJSON cfg.app_service_config_files}
|
||||
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
in {
|
||||
@ -73,53 +109,65 @@ in {
|
||||
Don't bind to the https port
|
||||
'';
|
||||
};
|
||||
tls_certificate_path = mkOption {
|
||||
type = types.path;
|
||||
default = "/var/lib/matrix-synapse/homeserver.tls.crt";
|
||||
description = ''
|
||||
PEM encoded X509 certificate for TLS
|
||||
'';
|
||||
};
|
||||
tls_private_key_path = mkOption {
|
||||
type = types.path;
|
||||
default = "/var/lib/matrix-synapse/homeserver.tls.key";
|
||||
description = ''
|
||||
PEM encoded private key for TLS
|
||||
'';
|
||||
};
|
||||
tls_dh_params_path = mkOption {
|
||||
type = types.path;
|
||||
default = "/var/lib/matrix-synapse/homeserver.tls.dh";
|
||||
description = ''
|
||||
PEM dh parameters for ephemeral keys
|
||||
'';
|
||||
};
|
||||
bind_port = mkOption {
|
||||
type = types.int;
|
||||
default = 8448;
|
||||
type = types.nullOr types.int;
|
||||
default = null;
|
||||
example = 8448;
|
||||
description = ''
|
||||
DEPRECATED: Use listeners instead.
|
||||
The port to listen for HTTPS requests on.
|
||||
For when matrix traffic is sent directly to synapse.
|
||||
'';
|
||||
};
|
||||
unsecure_port = mkOption {
|
||||
type = types.int;
|
||||
default = 8008;
|
||||
type = types.nullOr types.int;
|
||||
default = null;
|
||||
example = 8008;
|
||||
description = ''
|
||||
DEPRECATED: Use listeners instead.
|
||||
The port to listen for HTTP requests on.
|
||||
For when matrix traffic passes through loadbalancer that unwraps TLS.
|
||||
'';
|
||||
};
|
||||
bind_host = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
DEPRECATED: Use listeners instead.
|
||||
Local interface to listen on.
|
||||
The empty string will cause synapse to listen on all interfaces.
|
||||
'';
|
||||
};
|
||||
tls_certificate_path = mkOption {
|
||||
type = types.str;
|
||||
default = "/var/lib/matrix-synapse/homeserver.tls.crt";
|
||||
description = ''
|
||||
PEM encoded X509 certificate for TLS.
|
||||
You can replace the self-signed certificate that synapse
|
||||
autogenerates on launch with your own SSL certificate + key pair
|
||||
if you like. Any required intermediary certificates can be
|
||||
appended after the primary certificate in hierarchical order.
|
||||
'';
|
||||
};
|
||||
tls_private_key_path = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = "/var/lib/matrix-synapse/homeserver.tls.key";
|
||||
example = null;
|
||||
description = ''
|
||||
PEM encoded private key for TLS. Specify null if synapse is not
|
||||
speaking TLS directly.
|
||||
'';
|
||||
};
|
||||
tls_dh_params_path = mkOption {
|
||||
type = types.str;
|
||||
default = "/var/lib/matrix-synapse/homeserver.tls.dh";
|
||||
description = ''
|
||||
PEM dh parameters for ephemeral keys
|
||||
'';
|
||||
};
|
||||
server_name = mkOption {
|
||||
type = types.str;
|
||||
example = "example.com";
|
||||
description = ''
|
||||
The domain name of the server, with optional explicit port.
|
||||
This is used by remote servers to connect to this server,
|
||||
@ -134,6 +182,145 @@ in {
|
||||
Whether to serve a web client from the HTTP/HTTPS root resource.
|
||||
'';
|
||||
};
|
||||
public_baseurl = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "https://example.com:8448/";
|
||||
description = ''
|
||||
The public-facing base URL for the client API (not including _matrix/...)
|
||||
'';
|
||||
};
|
||||
listeners = mkOption {
|
||||
type = types.listOf (types.submodule {
|
||||
options = {
|
||||
port = mkOption {
|
||||
type = types.int;
|
||||
example = 8448;
|
||||
description = ''
|
||||
The port to listen for HTTP(S) requests on.
|
||||
'';
|
||||
};
|
||||
bind_address = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
example = "203.0.113.42";
|
||||
description = ''
|
||||
Local interface to listen on.
|
||||
The empty string will cause synapse to listen on all interfaces.
|
||||
'';
|
||||
};
|
||||
type = mkOption {
|
||||
type = types.str;
|
||||
default = "http";
|
||||
description = ''
|
||||
Type of listener.
|
||||
'';
|
||||
};
|
||||
tls = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to listen for HTTPS connections rather than HTTP.
|
||||
'';
|
||||
};
|
||||
x_forwarded = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Use the X-Forwarded-For (XFF) header as the client IP and not the
|
||||
actual client IP.
|
||||
'';
|
||||
};
|
||||
resources = mkOption {
|
||||
type = types.listOf (types.submodule {
|
||||
options = {
|
||||
names = mkOption {
|
||||
type = types.listOf types.str;
|
||||
description = ''
|
||||
List of resources to host on this listener.
|
||||
'';
|
||||
example = ["client" "webclient" "federation"];
|
||||
};
|
||||
compress = mkOption {
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Should synapse compress HTTP responses to clients that support it?
|
||||
This should be disabled if running synapse behind a load balancer
|
||||
that can do automatic compression.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
description = ''
|
||||
List of HTTP resources to serve on this listener.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
default = [{
|
||||
port = 8448;
|
||||
bind_address = "";
|
||||
type = "http";
|
||||
tls = true;
|
||||
x_forwarded = false;
|
||||
resources = [
|
||||
{ names = ["client" "webclient"]; compress = true; }
|
||||
{ names = ["federation"]; compress = false; }
|
||||
];
|
||||
}];
|
||||
description = ''
|
||||
List of ports that Synapse should listen on, their purpose and their configuration.
|
||||
'';
|
||||
};
|
||||
verbose = mkOption {
|
||||
type = types.str;
|
||||
default = "0";
|
||||
description = "Logging verbosity level.";
|
||||
};
|
||||
rc_messages_per_second = mkOption {
|
||||
type = types.str;
|
||||
default = "0.2";
|
||||
description = "Number of messages a client can send per second";
|
||||
};
|
||||
rc_message_burst_count = mkOption {
|
||||
type = types.str;
|
||||
default = "10.0";
|
||||
description = "Number of message a client can send before being throttled";
|
||||
};
|
||||
federation_rc_window_size = mkOption {
|
||||
type = types.str;
|
||||
default = "1000";
|
||||
description = "The federation window size in milliseconds";
|
||||
};
|
||||
federation_rc_sleep_limit = mkOption {
|
||||
type = types.str;
|
||||
default = "10";
|
||||
description = ''
|
||||
The number of federation requests from a single server in a window
|
||||
before the server will delay processing the request.
|
||||
'';
|
||||
};
|
||||
federation_rc_sleep_delay = mkOption {
|
||||
type = types.str;
|
||||
default = "500";
|
||||
description = ''
|
||||
The duration in milliseconds to delay processing events from
|
||||
remote servers by if they go over the sleep limit.
|
||||
'';
|
||||
};
|
||||
federation_rc_reject_limit = mkOption {
|
||||
type = types.str;
|
||||
default = "50";
|
||||
description = ''
|
||||
The maximum number of concurrent federation requests allowed
|
||||
from a single server
|
||||
'';
|
||||
};
|
||||
federation_rc_concurrent = mkOption {
|
||||
type = types.str;
|
||||
default = "3";
|
||||
description = "The number of federation requests to concurrently process from a single server";
|
||||
};
|
||||
database_type = mkOption {
|
||||
type = types.enum [ "sqlite3" "psycopg2" ];
|
||||
default = "sqlite3";
|
||||
@ -150,6 +337,11 @@ in {
|
||||
Arguments to pass to the engine.
|
||||
'';
|
||||
};
|
||||
event_cache_size = mkOption {
|
||||
type = types.str;
|
||||
default = "10K";
|
||||
description = "Number of events to cache in memory.";
|
||||
};
|
||||
recaptcha_private_key = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
@ -187,6 +379,11 @@ in {
|
||||
The shared secret used to compute passwords for the TURN server
|
||||
'';
|
||||
};
|
||||
turn_user_lifetime = mkOption {
|
||||
type = types.str;
|
||||
default = "1h";
|
||||
description = "How long generated TURN credentials last";
|
||||
};
|
||||
enable_registration = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
@ -195,8 +392,8 @@ in {
|
||||
'';
|
||||
};
|
||||
registration_shared_secret = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
If set, allows registration by anyone who also has the shared
|
||||
secret, even if registration is otherwise disabled.
|
||||
@ -216,7 +413,7 @@ in {
|
||||
'';
|
||||
};
|
||||
servers = mkOption {
|
||||
type = types.attrs;
|
||||
type = types.attrsOf (types.attrsOf types.str);
|
||||
default = {
|
||||
"matrix.org" = {
|
||||
"ed25519:auto" = "Noi6WqcDj0QmPxCNQqgezwTlBKrfqehY1u2FyWP9uYw";
|
||||
@ -226,6 +423,69 @@ in {
|
||||
The trusted servers to download signing keys from.
|
||||
'';
|
||||
};
|
||||
max_upload_size = mkOption {
|
||||
type = types.str;
|
||||
default = "10M";
|
||||
description = "The largest allowed upload size in bytes";
|
||||
};
|
||||
max_image_pixels = mkOption {
|
||||
type = types.str;
|
||||
default = "32M";
|
||||
description = "Maximum number of pixels that will be thumbnailed";
|
||||
};
|
||||
dynamic_thumbnails = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to generate new thumbnails on the fly to precisely match
|
||||
the resolution requested by the client. If true then whenever
|
||||
a new resolution is requested by the client the server will
|
||||
generate a new thumbnail. If false the server will pick a thumbnail
|
||||
from a precalculated list.
|
||||
'';
|
||||
};
|
||||
user_creation_max_duration = mkOption {
|
||||
type = types.str;
|
||||
default = "1209600000";
|
||||
description = ''
|
||||
Sets the expiry for the short term user creation in
|
||||
milliseconds. The default value is two weeks.
|
||||
'';
|
||||
};
|
||||
bcrypt_rounds = mkOption {
|
||||
type = types.str;
|
||||
default = "12";
|
||||
description = ''
|
||||
Set the number of bcrypt rounds used to generate password hash.
|
||||
Larger numbers increase the work factor needed to generate the hash.
|
||||
'';
|
||||
};
|
||||
allow_guest_access = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Allows users to register as guests without a password/email/etc, and
|
||||
participate in rooms hosted on this server which have been made
|
||||
accessible to anonymous users.
|
||||
'';
|
||||
};
|
||||
key_refresh_interval = mkOption {
|
||||
type = types.str;
|
||||
default = "1d";
|
||||
description = ''
|
||||
How long key response published by this server is valid for.
|
||||
Used to set the valid_until_ts in /key/v2 APIs.
|
||||
Determines how quickly servers will query to check which keys
|
||||
are still valid.
|
||||
'';
|
||||
};
|
||||
app_service_config_files = mkOption {
|
||||
type = types.listOf types.path;
|
||||
default = [ ];
|
||||
description = ''
|
||||
A list of application service config file to use
|
||||
'';
|
||||
};
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
@ -265,7 +525,7 @@ in {
|
||||
mkdir -p /var/lib/matrix-synapse
|
||||
chmod 700 /var/lib/matrix-synapse
|
||||
chown -R matrix-synapse:matrix-synapse /var/lib/matrix-synapse
|
||||
${cfg.package}/bin/homeserver --config-path ${configFile} --generate-keys
|
||||
${cfg.package}/bin/homeserver --config-path ${configFile} --keys-directory /var/lib/matrix-synapse/ --generate-keys
|
||||
'';
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
|
@ -91,7 +91,7 @@ in
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
serviceConfig = {
|
||||
ExecStart = "${pkgs.nodePackages_0_10.parsoid}/lib/node_modules/parsoid/api/server.js -c ${confFile} -n ${toString cfg.workers}";
|
||||
ExecStart = "${pkgs.nodePackages.parsoid}/lib/node_modules/parsoid/api/server.js -c ${confFile} -n ${toString cfg.workers}";
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -152,8 +152,6 @@ let
|
||||
};
|
||||
};
|
||||
|
||||
mkShellStr = val: "'${replaceStrings ["'"] ["'\\''"] val}'";
|
||||
|
||||
certtool = "${pkgs.gnutls.bin}/bin/certtool";
|
||||
|
||||
nixos-taskserver = pkgs.buildPythonPackage {
|
||||
|
@ -148,7 +148,7 @@ in {
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
ExecStart = ''
|
||||
${cfg.package}/bin/bosun -c ${configFile}
|
||||
${cfg.package.bin}/bin/bosun -c ${configFile}
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
@ -228,7 +228,7 @@ in {
|
||||
after = ["networking.target"];
|
||||
environment = mapAttrs' (n: v: nameValuePair "GF_${n}" (toString v)) envOptions;
|
||||
serviceConfig = {
|
||||
ExecStart = "${cfg.package}/bin/grafana-server -homepath ${cfg.dataDir}";
|
||||
ExecStart = "${cfg.package.bin}/bin/grafana-server -homepath ${cfg.dataDir}";
|
||||
WorkingDirectory = cfg.dataDir;
|
||||
User = "grafana";
|
||||
};
|
||||
|
@ -119,7 +119,7 @@ in {
|
||||
PermissionsStartOnly = true;
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
ExecStart = "${cfg.package}/bin/scollector -conf=${conf} ${lib.concatStringsSep " " cfg.extraOpts}";
|
||||
ExecStart = "${cfg.package.bin}/bin/scollector -conf=${conf} ${lib.concatStringsSep " " cfg.extraOpts}";
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -24,6 +24,7 @@ let
|
||||
use-ipv4=${if ipv4 then "yes" else "no"}
|
||||
use-ipv6=${if ipv6 then "yes" else "no"}
|
||||
${optionalString (interfaces!=null) "allow-interfaces=${concatStringsSep "," interfaces}"}
|
||||
${optionalString (domainName!=null) "domain-name=${domainName}"}
|
||||
|
||||
[wide-area]
|
||||
enable-wide-area=${if wideArea then "yes" else "no"}
|
||||
@ -65,6 +66,14 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
domainName = mkOption {
|
||||
type = types.str;
|
||||
default = "local";
|
||||
description = ''
|
||||
Domain name for all advertisements.
|
||||
'';
|
||||
};
|
||||
|
||||
browseDomains = mkOption {
|
||||
default = [ "0pointer.de" "zeroconf.org" ];
|
||||
description = ''
|
||||
|
@ -178,14 +178,14 @@ in
|
||||
(filterAttrs (n: _: hasPrefix "consul.d/" n) config.environment.etc);
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = "@${cfg.package}/bin/consul consul agent -config-dir /etc/consul.d"
|
||||
ExecStart = "@${cfg.package.bin}/bin/consul consul agent -config-dir /etc/consul.d"
|
||||
+ concatMapStrings (n: " -config-file ${n}") configFiles;
|
||||
ExecReload = "${cfg.package}/bin/consul reload";
|
||||
ExecReload = "${cfg.package.bin}/bin/consul reload";
|
||||
PermissionsStartOnly = true;
|
||||
User = if cfg.dropPrivileges then "consul" else null;
|
||||
TimeoutStartSec = "0";
|
||||
} // (optionalAttrs (cfg.leaveOnStop) {
|
||||
ExecStop = "${cfg.package}/bin/consul leave";
|
||||
ExecStop = "${cfg.package.bin}/bin/consul leave";
|
||||
});
|
||||
|
||||
path = with pkgs; [ iproute gnugrep gawk consul ];
|
||||
@ -236,7 +236,7 @@ in
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = ''
|
||||
${cfg.alerts.package}/bin/consul-alerts start \
|
||||
${cfg.alerts.package.bin}/bin/consul-alerts start \
|
||||
--alert-addr=${cfg.alerts.listenAddr} \
|
||||
--consul-addr=${cfg.alerts.consulAddr} \
|
||||
${optionalString cfg.alerts.watchChecks "--watch-checks"} \
|
||||
|
327
nixos/modules/services/networking/coturn.nix
Normal file
327
nixos/modules/services/networking/coturn.nix
Normal file
@ -0,0 +1,327 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.services.coturn;
|
||||
pidfile = "/run/turnserver/turnserver.pid";
|
||||
configFile = pkgs.writeText "turnserver.conf" ''
|
||||
listening-port=${toString cfg.listening-port}
|
||||
tls-listening-port=${toString cfg.tls-listening-port}
|
||||
alt-listening-port=${toString cfg.alt-listening-port}
|
||||
alt-tls-listening-port=${toString cfg.alt-tls-listening-port}
|
||||
${concatStringsSep "\n" (map (x: "listening-ip=${x}") cfg.listening-ips)}
|
||||
${concatStringsSep "\n" (map (x: "relay-ip=${x}") cfg.relay-ips)}
|
||||
min-port=${toString cfg.min-port}
|
||||
max-port=${toString cfg.max-port}
|
||||
${lib.optionalString cfg.lt-cred-mech "lt-cred-mech"}
|
||||
${lib.optionalString cfg.no-auth "no-auth"}
|
||||
${lib.optionalString cfg.use-auth-secret "use-auth-secret"}
|
||||
${lib.optionalString (cfg.static-auth-secret != null) ("static-auth-secret=${cfg.static-auth-secret}")}
|
||||
realm=${cfg.realm}
|
||||
${lib.optionalString cfg.no-udp "no-udp"}
|
||||
${lib.optionalString cfg.no-tcp "no-tcp"}
|
||||
${lib.optionalString cfg.no-tls "no-tls"}
|
||||
${lib.optionalString cfg.no-dtls "no-dtls"}
|
||||
${lib.optionalString cfg.no-udp-relay "no-udp-relay"}
|
||||
${lib.optionalString cfg.no-tcp-relay "no-tcp-relay"}
|
||||
${lib.optionalString (cfg.cert != null) "cert=${cfg.cert}"}
|
||||
${lib.optionalString (cfg.pkey != null) "pkey=${cfg.pkey}"}
|
||||
${lib.optionalString (cfg.dh-file != null) ("dh-file=${cfg.dh-file}")}
|
||||
no-stdout-log
|
||||
syslog
|
||||
pidfile=${pidfile}
|
||||
${lib.optionalString cfg.secure-stun "secure-stun"}
|
||||
${lib.optionalString cfg.no-cli "no-cli"}
|
||||
cli-ip=${cfg.cli-ip}
|
||||
cli-port=${toString cfg.cli-port}
|
||||
${lib.optionalString (cfg.cli-password != null) ("cli-password=${cfg.cli-password}")}
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
in {
|
||||
options = {
|
||||
services.coturn = {
|
||||
enable = mkEnableOption "coturn TURN server";
|
||||
listening-port = mkOption {
|
||||
type = types.int;
|
||||
default = 3478;
|
||||
description = ''
|
||||
TURN listener port for UDP and TCP.
|
||||
Note: actually, TLS and DTLS sessions can connect to the
|
||||
"plain" TCP and UDP port(s), too - if allowed by configuration.
|
||||
'';
|
||||
};
|
||||
tls-listening-port = mkOption {
|
||||
type = types.int;
|
||||
default = 5349;
|
||||
description = ''
|
||||
TURN listener port for TLS.
|
||||
Note: actually, "plain" TCP and UDP sessions can connect to the TLS and
|
||||
DTLS port(s), too - if allowed by configuration. The TURN server
|
||||
"automatically" recognizes the type of traffic. Actually, two listening
|
||||
endpoints (the "plain" one and the "tls" one) are equivalent in terms of
|
||||
functionality; but we keep both endpoints to satisfy the RFC 5766 specs.
|
||||
For secure TCP connections, we currently support SSL version 3 and
|
||||
TLS version 1.0, 1.1 and 1.2.
|
||||
For secure UDP connections, we support DTLS version 1.
|
||||
'';
|
||||
};
|
||||
alt-listening-port = mkOption {
|
||||
type = types.int;
|
||||
default = cfg.listening-port + 1;
|
||||
defaultText = "listening-port + 1";
|
||||
description = ''
|
||||
Alternative listening port for UDP and TCP listeners;
|
||||
default (or zero) value means "listening port plus one".
|
||||
This is needed for RFC 5780 support
|
||||
(STUN extension specs, NAT behavior discovery). The TURN Server
|
||||
supports RFC 5780 only if it is started with more than one
|
||||
listening IP address of the same family (IPv4 or IPv6).
|
||||
RFC 5780 is supported only by UDP protocol, other protocols
|
||||
are listening to that endpoint only for "symmetry".
|
||||
'';
|
||||
};
|
||||
alt-tls-listening-port = mkOption {
|
||||
type = types.int;
|
||||
default = cfg.tls-listening-port + 1;
|
||||
defaultText = "tls-listening-port + 1";
|
||||
description = ''
|
||||
Alternative listening port for TLS and DTLS protocols.
|
||||
'';
|
||||
};
|
||||
listening-ips = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
example = [ "203.0.113.42" "2001:DB8::42" ];
|
||||
description = ''
|
||||
Listener IP addresses of relay server.
|
||||
If no IP(s) specified in the config file or in the command line options,
|
||||
then all IPv4 and IPv6 system IPs will be used for listening.
|
||||
'';
|
||||
};
|
||||
relay-ips = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
example = [ "203.0.113.42" "2001:DB8::42" ];
|
||||
description = ''
|
||||
Relay address (the local IP address that will be used to relay the
|
||||
packets to the peer).
|
||||
Multiple relay addresses may be used.
|
||||
The same IP(s) can be used as both listening IP(s) and relay IP(s).
|
||||
|
||||
If no relay IP(s) specified, then the turnserver will apply the default
|
||||
policy: it will decide itself which relay addresses to be used, and it
|
||||
will always be using the client socket IP address as the relay IP address
|
||||
of the TURN session (if the requested relay address family is the same
|
||||
as the family of the client socket).
|
||||
'';
|
||||
};
|
||||
min-port = mkOption {
|
||||
type = types.int;
|
||||
default = 49152;
|
||||
description = ''
|
||||
Lower bound of UDP relay endpoints
|
||||
'';
|
||||
};
|
||||
max-port = mkOption {
|
||||
type = types.int;
|
||||
default = 65535;
|
||||
description = ''
|
||||
Upper bound of UDP relay endpoints
|
||||
'';
|
||||
};
|
||||
lt-cred-mech = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Use long-term credential mechanism.
|
||||
'';
|
||||
};
|
||||
no-auth = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
This option is opposite to lt-cred-mech.
|
||||
(TURN Server with no-auth option allows anonymous access).
|
||||
If neither option is defined, and no users are defined,
|
||||
then no-auth is default. If at least one user is defined,
|
||||
in this file or in command line or in usersdb file, then
|
||||
lt-cred-mech is default.
|
||||
'';
|
||||
};
|
||||
use-auth-secret = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
TURN REST API flag.
|
||||
Flag that sets a special authorization option that is based upon authentication secret.
|
||||
This feature can be used with the long-term authentication mechanism, only.
|
||||
This feature purpose is to support "TURN Server REST API", see
|
||||
"TURN REST API" link in the project's page
|
||||
https://github.com/coturn/coturn/
|
||||
|
||||
This option is used with timestamp:
|
||||
|
||||
usercombo -> "timestamp:userid"
|
||||
turn user -> usercombo
|
||||
turn password -> base64(hmac(secret key, usercombo))
|
||||
|
||||
This allows TURN credentials to be accounted for a specific user id.
|
||||
If you don't have a suitable id, the timestamp alone can be used.
|
||||
This option is just turning on secret-based authentication.
|
||||
The actual value of the secret is defined either by option static-auth-secret,
|
||||
or can be found in the turn_secret table in the database.
|
||||
'';
|
||||
};
|
||||
static-auth-secret = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
'Static' authentication secret value (a string) for TURN REST API only.
|
||||
If not set, then the turn server
|
||||
will try to use the 'dynamic' value in turn_secret table
|
||||
in user database (if present). The database-stored value can be changed on-the-fly
|
||||
by a separate program, so this is why that other mode is 'dynamic'.
|
||||
'';
|
||||
};
|
||||
realm = mkOption {
|
||||
type = types.str;
|
||||
default = config.networking.hostName;
|
||||
example = "example.com";
|
||||
description = ''
|
||||
The default realm to be used for the users when no explicit
|
||||
origin/realm relationship was found in the database, or if the TURN
|
||||
server is not using any database (just the commands-line settings
|
||||
and the userdb file). Must be used with long-term credentials
|
||||
mechanism or with TURN REST API.
|
||||
'';
|
||||
};
|
||||
cert = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "/var/lib/acme/example.com/fullchain.pem";
|
||||
description = ''
|
||||
Certificate file in PEM format.
|
||||
'';
|
||||
};
|
||||
pkey = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "/var/lib/acme/example.com/key.pem";
|
||||
description = ''
|
||||
Private key file in PEM format.
|
||||
'';
|
||||
};
|
||||
dh-file = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Use custom DH TLS key, stored in PEM format in the file.
|
||||
'';
|
||||
};
|
||||
secure-stun = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Require authentication of the STUN Binding request.
|
||||
By default, the clients are allowed anonymous access to the STUN Binding functionality.
|
||||
'';
|
||||
};
|
||||
no-cli = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Turn OFF the CLI support.
|
||||
'';
|
||||
};
|
||||
cli-ip = mkOption {
|
||||
type = types.str;
|
||||
default = "127.0.0.1";
|
||||
description = ''
|
||||
Local system IP address to be used for CLI server endpoint.
|
||||
'';
|
||||
};
|
||||
cli-port = mkOption {
|
||||
type = types.int;
|
||||
default = 5766;
|
||||
description = ''
|
||||
CLI server port.
|
||||
'';
|
||||
};
|
||||
cli-password = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
CLI access password.
|
||||
For the security reasons, it is recommended to use the encrypted
|
||||
for of the password (see the -P command in the turnadmin utility).
|
||||
'';
|
||||
};
|
||||
no-udp = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Disable UDP client listener";
|
||||
};
|
||||
no-tcp = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Disable TCP client listener";
|
||||
};
|
||||
no-tls = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Disable TLS client listener";
|
||||
};
|
||||
no-dtls = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Disable DTLS client listener";
|
||||
};
|
||||
no-udp-relay = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Disable UDP relay endpoints";
|
||||
};
|
||||
no-tcp-relay = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Disable TCP relay endpoints";
|
||||
};
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = "Additional configuration options";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
users.extraUsers = [
|
||||
{ name = "turnserver";
|
||||
uid = config.ids.uids.turnserver;
|
||||
description = "coturn TURN server user";
|
||||
} ];
|
||||
users.extraGroups = [
|
||||
{ name = "turnserver";
|
||||
gid = config.ids.gids.turnserver;
|
||||
members = [ "turnserver" ];
|
||||
} ];
|
||||
|
||||
systemd.services.coturn = {
|
||||
description = "coturn TURN server";
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
unitConfig = {
|
||||
Documentation = "man:coturn(1) man:turnadmin(1) man:turnserver(1)";
|
||||
};
|
||||
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
ExecStart = "${pkgs.coturn}/bin/turnserver -c ${configFile}";
|
||||
RuntimeDirectory = "turnserver";
|
||||
User = "turnserver";
|
||||
Group = "turnserver";
|
||||
Restart = "on-abort";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
@ -7,22 +7,8 @@ let
|
||||
|
||||
stateDir = "/var/spool/ddclient";
|
||||
ddclientUser = "ddclient";
|
||||
ddclientFlags = "-foreground -verbose -noquiet -file ${ddclientCfg}";
|
||||
ddclientFlags = "-foreground -verbose -noquiet -file /etc/ddclient.conf";
|
||||
ddclientPIDFile = "${stateDir}/ddclient.pid";
|
||||
ddclientCfg = pkgs.writeText "ddclient.conf" ''
|
||||
daemon=600
|
||||
cache=${stateDir}/ddclient.cache
|
||||
pid=${ddclientPIDFile}
|
||||
use=${config.services.ddclient.use}
|
||||
login=${config.services.ddclient.username}
|
||||
password=${config.services.ddclient.password}
|
||||
protocol=${config.services.ddclient.protocol}
|
||||
server=${config.services.ddclient.server}
|
||||
ssl=${if config.services.ddclient.ssl then "yes" else "no"}
|
||||
wildcard=YES
|
||||
${config.services.ddclient.domain}
|
||||
${config.services.ddclient.extraConfig}
|
||||
'';
|
||||
|
||||
in
|
||||
|
||||
@ -122,10 +108,30 @@ in
|
||||
home = stateDir;
|
||||
};
|
||||
|
||||
environment.etc."ddclient.conf" = {
|
||||
uid = config.ids.uids.ddclient;
|
||||
mode = "0600";
|
||||
text = ''
|
||||
daemon=600
|
||||
cache=${stateDir}/ddclient.cache
|
||||
pid=${ddclientPIDFile}
|
||||
use=${config.services.ddclient.use}
|
||||
login=${config.services.ddclient.username}
|
||||
password=${config.services.ddclient.password}
|
||||
protocol=${config.services.ddclient.protocol}
|
||||
server=${config.services.ddclient.server}
|
||||
ssl=${if config.services.ddclient.ssl then "yes" else "no"}
|
||||
wildcard=YES
|
||||
${config.services.ddclient.domain}
|
||||
${config.services.ddclient.extraConfig}
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.services.ddclient = {
|
||||
description = "Dynamic DNS Client";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
restartTriggers = [ config.environment.etc."ddclient.conf".source ];
|
||||
|
||||
serviceConfig = {
|
||||
# Uncomment this if too many problems occur:
|
||||
|
@ -13,7 +13,7 @@ let
|
||||
|
||||
ectl = ''${cfg.package}/bin/ejabberdctl ${if cfg.configFile == null then "" else "--config ${cfg.configFile}"} --ctl-config "${ctlcfg}" --spool "${cfg.spoolDir}" --logs "${cfg.logsDir}"'';
|
||||
|
||||
dumps = lib.concatMapStringsSep " " lib.escapeShellArg cfg.loadDumps;
|
||||
dumps = lib.escapeShellArgs cfg.loadDumps;
|
||||
|
||||
in {
|
||||
|
||||
|
@ -231,11 +231,6 @@ in {
|
||||
users.extraUsers = [{
|
||||
name = "nm-openvpn";
|
||||
uid = config.ids.uids.nm-openvpn;
|
||||
}
|
||||
{
|
||||
# to enable link-local connections
|
||||
name = "avahi-autoipd";
|
||||
uid = config.ids.uids.avahi-autoipd;
|
||||
}];
|
||||
|
||||
systemd.packages = cfg.packages;
|
||||
|
73
nixos/modules/services/networking/offlineimap.nix
Normal file
73
nixos/modules/services/networking/offlineimap.nix
Normal file
@ -0,0 +1,73 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.offlineimap;
|
||||
in {
|
||||
|
||||
options.services.offlineimap = {
|
||||
enable = mkEnableOption "Offlineimap, a software to dispose your mailbox(es) as a local Maildir(s).";
|
||||
|
||||
install = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
example = true;
|
||||
description = ''
|
||||
Whether to install a user service for Offlineimap. Once
|
||||
the service is started, emails will be fetched automatically.
|
||||
|
||||
The service must be manually started for each user with
|
||||
"systemctl --user start offlineimap" or globally through
|
||||
<varname>services.offlineimap.enable</varname>.
|
||||
'';
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.offlineimap;
|
||||
defaultText = "pkgs.offlineimap";
|
||||
description = "Offlineimap derivation to use.";
|
||||
};
|
||||
|
||||
path = mkOption {
|
||||
type = types.listOf types.path;
|
||||
default = [];
|
||||
example = literalExample "[ pkgs.pass pkgs.bash pkgs.notmuch ]";
|
||||
description = "List of derivations to put in Offlineimap's path.";
|
||||
};
|
||||
|
||||
onCalendar = mkOption {
|
||||
type = types.str;
|
||||
default = "*:0/3"; # every 3 minutes
|
||||
description = "How often is offlineimap started. Default is '*:0/3' meaning every 3 minutes. See systemd.time(7) for more information about the format.";
|
||||
};
|
||||
|
||||
timeoutStartSec = mkOption {
|
||||
type = types.str;
|
||||
default = "120sec"; # Kill if still alive after 2 minutes
|
||||
description = "How long waiting for offlineimap before killing it. Default is '120sec' meaning every 2 minutes. See systemd.time(7) for more information about the format.";
|
||||
};
|
||||
};
|
||||
config = mkIf (cfg.enable || cfg.install) {
|
||||
systemd.user.services.offlineimap = {
|
||||
description = "Offlineimap: a software to dispose your mailbox(es) as a local Maildir(s)";
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "${cfg.package}/bin/offlineimap -u basic -o -1";
|
||||
TimeoutStartSec = cfg.timeoutStartSec;
|
||||
};
|
||||
path = cfg.path;
|
||||
};
|
||||
environment.systemPackages = [ "${cfg.package}" ];
|
||||
systemd.user.timers.offlineimap = {
|
||||
description = "offlineimap timer";
|
||||
timerConfig = {
|
||||
Unit = "offlineimap.service";
|
||||
OnCalendar = cfg.onCalendar;
|
||||
# start immediately after computer is started:
|
||||
Persistent = "true";
|
||||
};
|
||||
} // optionalAttrs cfg.enable { wantedBy = [ "default.target" ]; };
|
||||
};
|
||||
}
|
124
nixos/modules/services/networking/pptpd.nix
Normal file
124
nixos/modules/services/networking/pptpd.nix
Normal file
@ -0,0 +1,124 @@
|
||||
{ config, stdenv, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
options = {
|
||||
services.pptpd = {
|
||||
enable = mkEnableOption "Whether pptpd should be run on startup.";
|
||||
|
||||
serverIp = mkOption {
|
||||
type = types.string;
|
||||
description = "The server-side IP address.";
|
||||
default = "10.124.124.1";
|
||||
};
|
||||
|
||||
clientIpRange = mkOption {
|
||||
type = types.string;
|
||||
description = "The range from which client IPs are drawn.";
|
||||
default = "10.124.124.2-11";
|
||||
};
|
||||
|
||||
maxClients = mkOption {
|
||||
type = types.int;
|
||||
description = "The maximum number of simultaneous connections.";
|
||||
default = 10;
|
||||
};
|
||||
|
||||
extraPptpdOptions = mkOption {
|
||||
type = types.lines;
|
||||
description = "Adds extra lines to the pptpd configuration file.";
|
||||
default = "";
|
||||
};
|
||||
|
||||
extraPppdOptions = mkOption {
|
||||
type = types.lines;
|
||||
description = "Adds extra lines to the pppd options file.";
|
||||
default = "";
|
||||
example = ''
|
||||
ms-dns 8.8.8.8
|
||||
ms-dns 8.8.4.4
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf config.services.pptpd.enable {
|
||||
systemd.services.pptpd = let
|
||||
cfg = config.services.pptpd;
|
||||
|
||||
pptpd-conf = pkgs.writeText "pptpd.conf" ''
|
||||
# Inspired from pptpd-1.4.0/samples/pptpd.conf
|
||||
ppp ${ppp-pptpd-wrapped}/bin/pppd
|
||||
option ${pppd-options}
|
||||
pidfile /run/pptpd.pid
|
||||
localip ${cfg.serverIp}
|
||||
remoteip ${cfg.clientIpRange}
|
||||
connections ${toString cfg.maxClients} # (Will get harmless warning if inconsistent with IP range)
|
||||
|
||||
# Extra
|
||||
${cfg.extraPptpdOptions}
|
||||
'';
|
||||
|
||||
pppd-options = pkgs.writeText "ppp-options-pptpd.conf" ''
|
||||
# From: cat pptpd-1.4.0/samples/options.pptpd | grep -v ^# | grep -v ^$
|
||||
name pptpd
|
||||
refuse-pap
|
||||
refuse-chap
|
||||
refuse-mschap
|
||||
require-mschap-v2
|
||||
require-mppe-128
|
||||
proxyarp
|
||||
lock
|
||||
nobsdcomp
|
||||
novj
|
||||
novjccomp
|
||||
nologfd
|
||||
|
||||
# Extra:
|
||||
${cfg.extraPppdOptions}
|
||||
'';
|
||||
|
||||
ppp-pptpd-wrapped = pkgs.stdenv.mkDerivation {
|
||||
name = "ppp-pptpd-wrapped";
|
||||
phases = [ "installPhase" ];
|
||||
buildInputs = with pkgs; [ makeWrapper ];
|
||||
installPhase = ''
|
||||
mkdir -p $out/bin
|
||||
makeWrapper ${pkgs.ppp}/bin/pppd $out/bin/pppd \
|
||||
--set LD_PRELOAD "${pkgs.libredirect}/lib/libredirect.so" \
|
||||
--set NIX_REDIRECTS "/etc/ppp=/etc/ppp-pptpd"
|
||||
'';
|
||||
};
|
||||
in {
|
||||
description = "pptpd server";
|
||||
|
||||
requires = [ "network-online.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
preStart = ''
|
||||
mkdir -p -m 700 /etc/ppp-pptpd
|
||||
|
||||
secrets="/etc/ppp-pptpd/chap-secrets"
|
||||
|
||||
[ -f "$secrets" ] || cat > "$secrets" << EOF
|
||||
# From: pptpd-1.4.0/samples/chap-secrets
|
||||
# Secrets for authentication using CHAP
|
||||
# client server secret IP addresses
|
||||
#username pptpd password *
|
||||
EOF
|
||||
|
||||
chown root.root "$secrets"
|
||||
chmod 600 "$secrets"
|
||||
'';
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = "${pkgs.pptpd}/bin/pptpd --conf ${pptpd-conf}";
|
||||
KillMode = "process";
|
||||
Restart = "on-success";
|
||||
Type = "forking";
|
||||
PIDFile = "/run/pptpd.pid";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
@ -52,6 +52,8 @@ in
|
||||
config = mkIf config.services.shairport-sync.enable {
|
||||
|
||||
services.avahi.enable = true;
|
||||
services.avahi.publish.enable = true;
|
||||
services.avahi.publish.userServices = true;
|
||||
|
||||
users.extraUsers = singleton
|
||||
{ name = cfg.user;
|
||||
|
@ -83,7 +83,7 @@ in {
|
||||
SKYDNS_NAMESERVERS = concatStringsSep "," cfg.nameservers;
|
||||
};
|
||||
serviceConfig = {
|
||||
ExecStart = "${cfg.package}/bin/skydns";
|
||||
ExecStart = "${cfg.package.bin}/bin/skydns";
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -129,7 +129,7 @@ in {
|
||||
in {
|
||||
description = "WPA Supplicant";
|
||||
|
||||
after = [ "network-interfaces.target" ];
|
||||
after = [ "network-interfaces.target" ] ++ lib.concatMap deviceUnit ifaces;
|
||||
requires = lib.concatMap deviceUnit ifaces;
|
||||
wantedBy = [ "network.target" ];
|
||||
|
||||
|
143
nixos/modules/services/networking/xl2tpd.nix
Normal file
143
nixos/modules/services/networking/xl2tpd.nix
Normal file
@ -0,0 +1,143 @@
|
||||
{ config, stdenv, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
options = {
|
||||
services.xl2tpd = {
|
||||
enable = mkEnableOption "Whether xl2tpd should be run on startup.";
|
||||
|
||||
serverIp = mkOption {
|
||||
type = types.string;
|
||||
description = "The server-side IP address.";
|
||||
default = "10.125.125.1";
|
||||
};
|
||||
|
||||
clientIpRange = mkOption {
|
||||
type = types.string;
|
||||
description = "The range from which client IPs are drawn.";
|
||||
default = "10.125.125.2-11";
|
||||
};
|
||||
|
||||
extraXl2tpOptions = mkOption {
|
||||
type = types.lines;
|
||||
description = "Adds extra lines to the xl2tpd configuration file.";
|
||||
default = "";
|
||||
};
|
||||
|
||||
extraPppdOptions = mkOption {
|
||||
type = types.lines;
|
||||
description = "Adds extra lines to the pppd options file.";
|
||||
default = "";
|
||||
example = ''
|
||||
ms-dns 8.8.8.8
|
||||
ms-dns 8.8.4.4
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf config.services.xl2tpd.enable {
|
||||
systemd.services.xl2tpd = let
|
||||
cfg = config.services.xl2tpd;
|
||||
|
||||
# Config files from https://help.ubuntu.com/community/L2TPServer
|
||||
xl2tpd-conf = pkgs.writeText "xl2tpd.conf" ''
|
||||
[global]
|
||||
ipsec saref = no
|
||||
|
||||
[lns default]
|
||||
local ip = ${cfg.serverIp}
|
||||
ip range = ${cfg.clientIpRange}
|
||||
pppoptfile = ${pppd-options}
|
||||
length bit = yes
|
||||
|
||||
; Extra
|
||||
${cfg.extraXl2tpOptions}
|
||||
'';
|
||||
|
||||
pppd-options = pkgs.writeText "ppp-options-xl2tpd.conf" ''
|
||||
refuse-pap
|
||||
refuse-chap
|
||||
refuse-mschap
|
||||
require-mschap-v2
|
||||
# require-mppe-128
|
||||
asyncmap 0
|
||||
auth
|
||||
crtscts
|
||||
idle 1800
|
||||
mtu 1200
|
||||
mru 1200
|
||||
lock
|
||||
hide-password
|
||||
local
|
||||
# debug
|
||||
name xl2tpd
|
||||
# proxyarp
|
||||
lcp-echo-interval 30
|
||||
lcp-echo-failure 4
|
||||
|
||||
# Extra:
|
||||
${cfg.extraPppdOptions}
|
||||
'';
|
||||
|
||||
xl2tpd-ppp-wrapped = pkgs.stdenv.mkDerivation {
|
||||
name = "xl2tpd-ppp-wrapped";
|
||||
phases = [ "installPhase" ];
|
||||
buildInputs = with pkgs; [ makeWrapper ];
|
||||
installPhase = ''
|
||||
mkdir -p $out/bin
|
||||
|
||||
makeWrapper ${pkgs.ppp}/sbin/pppd $out/bin/pppd \
|
||||
--set LD_PRELOAD "${pkgs.libredirect}/lib/libredirect.so" \
|
||||
--set NIX_REDIRECTS "/etc/ppp=/etc/xl2tpd/ppp"
|
||||
|
||||
makeWrapper ${pkgs.xl2tpd}/bin/xl2tpd $out/bin/xl2tpd \
|
||||
--set LD_PRELOAD "${pkgs.libredirect}/lib/libredirect.so" \
|
||||
--set NIX_REDIRECTS "${pkgs.ppp}/sbin/pppd=$out/bin/pppd"
|
||||
'';
|
||||
};
|
||||
in {
|
||||
description = "xl2tpd server";
|
||||
|
||||
requires = [ "network-online.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
preStart = ''
|
||||
mkdir -p -m 700 /etc/xl2tpd
|
||||
|
||||
pushd /etc/xl2tpd > /dev/null
|
||||
|
||||
mkdir -p -m 700 ppp
|
||||
|
||||
[ -f ppp/chap-secrets ] || cat > ppp/chap-secrets << EOF
|
||||
# Secrets for authentication using CHAP
|
||||
# client server secret IP addresses
|
||||
#username xl2tpd password *
|
||||
EOF
|
||||
|
||||
chown root.root ppp/chap-secrets
|
||||
chmod 600 ppp/chap-secrets
|
||||
|
||||
# The documentation says this file should be present but doesn't explain why and things work even if not there:
|
||||
[ -f l2tp-secrets ] || (echo -n "* * "; ${pkgs.apg}/bin/apg -n 1 -m 32 -x 32 -a 1 -M LCN) > l2tp-secrets
|
||||
chown root.root l2tp-secrets
|
||||
chmod 600 l2tp-secrets
|
||||
|
||||
popd > /dev/null
|
||||
|
||||
mkdir -p /run/xl2tpd
|
||||
chown root.root /run/xl2tpd
|
||||
chmod 700 /run/xl2tpd
|
||||
'';
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = "${xl2tpd-ppp-wrapped}/bin/xl2tpd -D -c ${xl2tpd-conf} -s /etc/xl2tpd/l2tp-secrets -p /run/xl2tpd/pid -C /run/xl2tpd/control";
|
||||
KillMode = "process";
|
||||
Restart = "on-success";
|
||||
Type = "simple";
|
||||
PIDFile = "/run/xl2tpd/pid";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
@ -157,11 +157,14 @@ in {
|
||||
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
|
||||
users.extraUsers = singleton {
|
||||
name = "elasticsearch";
|
||||
uid = config.ids.uids.elasticsearch;
|
||||
description = "Elasticsearch daemon user";
|
||||
home = cfg.dataDir;
|
||||
users = {
|
||||
groups.elasticsearch.gid = config.ids.gids.elasticsearch;
|
||||
users.elasticsearch = {
|
||||
uid = config.ids.uids.elasticsearch;
|
||||
description = "Elasticsearch daemon user";
|
||||
home = cfg.dataDir;
|
||||
group = "elasticsearch";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ in {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = "${pkgs.hologram}/bin/hologram-server --debug --conf ${cfgFile}";
|
||||
ExecStart = "${pkgs.hologram.bin}/bin/hologram-server --debug --conf ${cfgFile}";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -515,7 +515,7 @@ in
|
||||
serviceConfig = {
|
||||
User = "oauth2_proxy";
|
||||
Restart = "always";
|
||||
ExecStart = "${cfg.package}/bin/oauth2_proxy ${mkCommandLine cfg}";
|
||||
ExecStart = "${cfg.package.bin}/bin/oauth2_proxy ${mkCommandLine cfg}";
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -65,10 +65,13 @@ in
|
||||
default = [ ];
|
||||
description = ''
|
||||
Packages whose D-Bus configuration files should be included in
|
||||
the configuration of the D-Bus system-wide message bus.
|
||||
Specifically, every file in
|
||||
the configuration of the D-Bus system-wide or session-wide
|
||||
message bus. Specifically, files in the following directories
|
||||
will be included into their respective DBus configuration paths:
|
||||
<filename><replaceable>pkg</replaceable>/etc/dbus-1/system.d</filename>
|
||||
is included.
|
||||
<filename><replaceable>pkg</replaceable>/share/dbus-1/system-services</filename>
|
||||
<filename><replaceable>pkg</replaceable>/etc/dbus-1/session.d</filename>
|
||||
<filename><replaceable>pkg</replaceable>/share/dbus-1/services</filename>
|
||||
'';
|
||||
};
|
||||
|
||||
|
@ -12,7 +12,9 @@ let
|
||||
|
||||
httpdConf = mainCfg.configFile;
|
||||
|
||||
php = pkgs.php.override { apacheHttpd = httpd.dev; /* otherwise it only gets .out */ };
|
||||
php = mainCfg.phpPackage.override { apacheHttpd = httpd.dev; /* otherwise it only gets .out */ };
|
||||
|
||||
phpMajorVersion = head (splitString "." php.version);
|
||||
|
||||
getPort = cfg: if cfg.port != 0 then cfg.port else if cfg.enableSSL then 443 else 80;
|
||||
|
||||
@ -337,7 +339,8 @@ let
|
||||
allModules =
|
||||
concatMap (svc: svc.extraModulesPre) allSubservices
|
||||
++ map (name: {inherit name; path = "${httpd}/modules/mod_${name}.so";}) apacheModules
|
||||
++ optional enablePHP { name = "php5"; path = "${php}/modules/libphp5.so"; }
|
||||
++ optional mainCfg.enableMellon { name = "auth_mellon"; path = "${pkgs.apacheHttpdPackages.mod_auth_mellon}/modules/mod_auth_mellon.so"; }
|
||||
++ optional enablePHP { name = "php${phpMajorVersion}"; path = "${php}/modules/libphp${phpMajorVersion}.so"; }
|
||||
++ concatMap (svc: svc.extraModules) allSubservices
|
||||
++ extraForeignModules;
|
||||
in concatMapStrings load allModules
|
||||
@ -541,12 +544,27 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
enableMellon = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Whether to enable the mod_auth_mellon module.";
|
||||
};
|
||||
|
||||
enablePHP = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Whether to enable the PHP module.";
|
||||
};
|
||||
|
||||
phpPackage = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.php;
|
||||
defaultText = "pkgs.php";
|
||||
description = ''
|
||||
Overridable attribute of the PHP package to use.
|
||||
'';
|
||||
};
|
||||
|
||||
phpOptions = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
@ -650,6 +668,7 @@ in
|
||||
|
||||
environment =
|
||||
optionalAttrs enablePHP { PHPRC = phpIni; }
|
||||
// optionalAttrs mainCfg.enableMellon { LD_LIBRARY_PATH = "${pkgs.xmlsec}/lib"; }
|
||||
// (listToAttrs (concatMap (svc: svc.globalEnvVars) allSubservices));
|
||||
|
||||
preStart =
|
||||
|
@ -33,7 +33,7 @@ in
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
ExecStart = "${pkgs.caddy}/bin/caddy -conf=${configFile} -email=${cfg.email}";
|
||||
ExecStart = "${pkgs.caddy.bin}/bin/caddy -conf=${configFile} -email=${cfg.email}";
|
||||
Type = "simple";
|
||||
User = "caddy";
|
||||
Group = "caddy";
|
||||
|
262
nixos/modules/services/web-servers/lighttpd/inginious.nix
Normal file
262
nixos/modules/services/web-servers/lighttpd/inginious.nix
Normal file
@ -0,0 +1,262 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.lighttpd.inginious;
|
||||
inginious = pkgs.inginious;
|
||||
execName = "inginious-${if cfg.useLTI then "lti" else "webapp"}";
|
||||
|
||||
inginiousConfigFile = if cfg.configFile != null then cfg.configFile else pkgs.writeText "inginious.yaml" ''
|
||||
# Backend; can be:
|
||||
# - "local" (run containers on the same machine)
|
||||
# - "remote" (connect to distant docker daemon and auto start agents) (choose this if you use boot2docker)
|
||||
# - "remote_manual" (connect to distant and manually installed agents)
|
||||
backend: "${cfg.backendType}"
|
||||
|
||||
## TODO (maybe): Add an option for the "remote" backend in this NixOS module.
|
||||
# List of remote docker daemon to which the backend will try
|
||||
# to connect (backend: remote only)
|
||||
#docker_daemons:
|
||||
# - # Host of the docker daemon *from the webapp*
|
||||
# remote_host: "some.remote.server"
|
||||
# # Port of the distant docker daemon *from the webapp*
|
||||
# remote_docker_port: "2375"
|
||||
# # A mandatory port used by the backend and the agent that will be automatically started.
|
||||
# # Needs to be available on the remote host, and to be open in the firewall.
|
||||
# remote_agent_port: "63456"
|
||||
# # Does the remote docker requires tls? Defaults to false.
|
||||
# # Parameter can be set to true or path to the certificates
|
||||
# #use_tls: false
|
||||
# # Link to the docker daemon *from the host that runs the docker daemon*. Defaults to:
|
||||
# #local_location: "unix:///var/run/docker.sock"
|
||||
# # Path to the cgroups "mount" *from the host that runs the docker daemon*. Defaults to:
|
||||
# #cgroups_location: "/sys/fs/cgroup"
|
||||
# # Name that will be used to reference the agent
|
||||
# #"agent_name": "inginious-agent"
|
||||
|
||||
# List of remote agents to which the backend will try
|
||||
# to connect (backend: remote_manual only)
|
||||
# Example:
|
||||
#agents:
|
||||
# - host: "192.168.59.103"
|
||||
# port: 5001
|
||||
agents:
|
||||
${lib.concatMapStrings (agent:
|
||||
" - host: \"${agent.host}\"\n" +
|
||||
" port: ${agent.port}\n"
|
||||
) cfg.remoteAgents}
|
||||
|
||||
# Location of the task directory
|
||||
tasks_directory: "${cfg.tasksDirectory}"
|
||||
|
||||
# Super admins: list of user names that can do everything in the backend
|
||||
superadmins:
|
||||
${lib.concatMapStrings (x: " - \"${x}\"\n") cfg.superadmins}
|
||||
|
||||
# Aliases for containers
|
||||
# Only containers listed here can be used by tasks
|
||||
containers:
|
||||
${lib.concatStrings (lib.mapAttrsToList (name: fullname:
|
||||
" ${name}: \"${fullname}\"\n"
|
||||
) cfg.containers)}
|
||||
|
||||
# Use single minified javascript file (production) or multiple files (dev) ?
|
||||
use_minified_js: true
|
||||
|
||||
## TODO (maybe): Add NixOS options for these parameters.
|
||||
|
||||
# MongoDB options
|
||||
#mongo_opt:
|
||||
# host: localhost
|
||||
# database: INGInious
|
||||
|
||||
# Disable INGInious?
|
||||
#maintenance: false
|
||||
|
||||
#smtp:
|
||||
# sendername: 'INGInious <no-reply@inginious.org>'
|
||||
# host: 'smtp.gmail.com'
|
||||
# port: 587
|
||||
# username: 'configme@gmail.com'
|
||||
# password: 'secret'
|
||||
# starttls: True
|
||||
|
||||
## NixOS extra config
|
||||
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
in
|
||||
{
|
||||
options.services.lighttpd.inginious = {
|
||||
enable = mkEnableOption "INGInious, an automated code testing and grading system.";
|
||||
|
||||
configFile = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
example = literalExample ''pkgs.writeText "configuration.yaml" "# custom config options ...";'';
|
||||
description = ''The path to an INGInious configuration file.'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
example = ''
|
||||
# Load the dummy auth plugin.
|
||||
plugins:
|
||||
- plugin_module: inginious.frontend.webapp.plugins.auth.demo_auth
|
||||
users:
|
||||
# register the user "test" with the password "someverycomplexpassword"
|
||||
test: someverycomplexpassword
|
||||
'';
|
||||
description = ''Extra option in YaML format, to be appended to the config file.'';
|
||||
};
|
||||
|
||||
tasksDirectory = mkOption {
|
||||
type = types.path;
|
||||
default = "${inginious}/lib/python2.7/site-packages/inginious/tasks";
|
||||
example = "/var/lib/INGInious/tasks";
|
||||
description = ''
|
||||
Path to the tasks folder.
|
||||
Defaults to the provided test tasks folder (readonly).
|
||||
'';
|
||||
};
|
||||
|
||||
useLTI = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''Whether to start the LTI frontend in place of the webapp.'';
|
||||
};
|
||||
|
||||
superadmins = mkOption {
|
||||
type = types.uniq (types.listOf types.str);
|
||||
default = [ "admin" ];
|
||||
example = [ "john" "pepe" "emilia" ];
|
||||
description = ''List of user logins allowed to administrate the whole server.'';
|
||||
};
|
||||
|
||||
containers = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = {
|
||||
default = "ingi/inginious-c-default";
|
||||
};
|
||||
example = {
|
||||
default = "ingi/inginious-c-default";
|
||||
sekexe = "ingi/inginious-c-sekexe";
|
||||
java = "ingi/inginious-c-java";
|
||||
oz = "ingi/inginious-c-oz";
|
||||
pythia1compat = "ingi/inginious-c-pythia1compat";
|
||||
};
|
||||
description = ''
|
||||
An attrset describing the required containers
|
||||
These containers will be available in INGInious using their short name (key)
|
||||
and will be automatically downloaded before INGInious starts.
|
||||
'';
|
||||
};
|
||||
|
||||
hostPattern = mkOption {
|
||||
type = types.str;
|
||||
default = "^inginious.";
|
||||
example = "^inginious.mydomain.xyz$";
|
||||
description = ''
|
||||
The domain that serves INGInious.
|
||||
INGInious uses absolute paths which makes it difficult to relocate in its own subdir.
|
||||
The default configuration will serve INGInious when the server is accessed with a hostname starting with "inginious.".
|
||||
If left blank, INGInious will take the precedence over all the other lighttpd sites, which is probably not what you want.
|
||||
'';
|
||||
};
|
||||
|
||||
backendType = mkOption {
|
||||
type = types.enum [ "local" "remote_manual" ]; # TODO: support backend "remote"
|
||||
default = "local";
|
||||
description = ''
|
||||
Select how INGINious accesses to grading containers.
|
||||
The default "local" option ensures that Docker is started and provisioned.
|
||||
Fore more information, see http://inginious.readthedocs.io/en/latest/install_doc/config_reference.html
|
||||
Not all backends are supported. Use services.inginious.configFile for full flexibility.
|
||||
'';
|
||||
};
|
||||
|
||||
remoteAgents = mkOption {
|
||||
type = types.listOf (types.attrsOf types.str);
|
||||
default = [];
|
||||
example = [ { host = "192.0.2.25"; port = "1345"; } ];
|
||||
description = ''A list of remote agents, used only when services.inginious.backendType is "remote_manual".'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable (
|
||||
mkMerge [
|
||||
# For a local install, we need docker.
|
||||
(mkIf (cfg.backendType == "local") {
|
||||
virtualisation.docker = {
|
||||
enable = true;
|
||||
# We need docker to listen on port 2375.
|
||||
extraOptions = "-H tcp://127.0.0.1:2375 -H unix:///var/run/docker.sock";
|
||||
storageDriver = mkDefault "overlay";
|
||||
socketActivation = false;
|
||||
};
|
||||
|
||||
users.extraUsers."lighttpd".extraGroups = [ "docker" ];
|
||||
|
||||
# Ensure that docker has pulled the required images.
|
||||
systemd.services.inginious-prefetch = {
|
||||
script = let
|
||||
images = lib.unique (
|
||||
[ "centos" "ingi/inginious-agent" ]
|
||||
++ lib.mapAttrsToList (_: image: image) cfg.containers
|
||||
);
|
||||
in lib.concatMapStrings (image: ''
|
||||
${pkgs.docker}/bin/docker pull ${image}
|
||||
'') images;
|
||||
|
||||
serviceConfig.Type = "oneshot";
|
||||
wants = [ "docker.service" ];
|
||||
after = [ "docker.service" ];
|
||||
wantedBy = [ "lighttpd.service" ];
|
||||
before = [ "lighttpd.service" ];
|
||||
};
|
||||
})
|
||||
|
||||
# Common
|
||||
{
|
||||
# To access inginous tools (like inginious-test-task)
|
||||
environment.systemPackages = [ inginious ];
|
||||
|
||||
services.mongodb.enable = true;
|
||||
|
||||
services.lighttpd.enable = true;
|
||||
services.lighttpd.enableModules = [ "mod_access" "mod_alias" "mod_fastcgi" "mod_redirect" "mod_rewrite" ];
|
||||
services.lighttpd.extraConfig = ''
|
||||
$HTTP["host"] =~ "${cfg.hostPattern}" {
|
||||
fastcgi.server = ( "/${execName}" =>
|
||||
((
|
||||
"socket" => "/run/lighttpd/inginious-fastcgi.socket",
|
||||
"bin-path" => "${inginious}/bin/${execName} --config=${inginiousConfigFile}",
|
||||
"max-procs" => 1,
|
||||
"bin-environment" => ( "REAL_SCRIPT_NAME" => "" ),
|
||||
"check-local" => "disable"
|
||||
))
|
||||
)
|
||||
url.rewrite-once = (
|
||||
"^/.well-known/.*" => "$0",
|
||||
"^/static/.*" => "$0",
|
||||
"^/.*$" => "/${execName}$0",
|
||||
"^/favicon.ico$" => "/static/common/favicon.ico",
|
||||
)
|
||||
alias.url += (
|
||||
"/static/webapp/" => "${inginious}/lib/python2.7/site-packages/inginious/frontend/webapp/static/",
|
||||
"/static/common/" => "${inginious}/lib/python2.7/site-packages/inginious/frontend/common/static/"
|
||||
)
|
||||
}
|
||||
'';
|
||||
|
||||
systemd.services.lighttpd.preStart = ''
|
||||
mkdir -p /run/lighttpd
|
||||
chown lighttpd.lighttpd /run/lighttpd
|
||||
'';
|
||||
|
||||
systemd.services.lighttpd.wants = [ "mongodb.service" "docker.service" ];
|
||||
systemd.services.lighttpd.after = [ "mongodb.service" "docker.service" ];
|
||||
}
|
||||
]);
|
||||
}
|
@ -78,6 +78,8 @@ in {
|
||||
type = types.listOf types.path;
|
||||
description = "List of packages for which gsettings are overridden.";
|
||||
};
|
||||
|
||||
debug = mkEnableOption "gnome-session debug messages";
|
||||
};
|
||||
|
||||
environment.gnome3.packageSet = mkOption {
|
||||
@ -117,7 +119,10 @@ in {
|
||||
services.telepathy.enable = mkDefault true;
|
||||
networking.networkmanager.enable = mkDefault true;
|
||||
services.upower.enable = config.powerManagement.enable;
|
||||
services.dbus.packages = mkIf config.services.printing.enable [ pkgs.system-config-printer ];
|
||||
services.colord.enable = mkDefault true;
|
||||
hardware.bluetooth.enable = mkDefault true;
|
||||
services.xserver.libinput.enable = mkDefault true; # for controlling touchpad settings via gnome control center
|
||||
|
||||
fonts.fonts = [ pkgs.dejavu_fonts pkgs.cantarell_fonts ];
|
||||
|
||||
@ -159,7 +164,7 @@ in {
|
||||
# Update user dirs as described in http://freedesktop.org/wiki/Software/xdg-user-dirs/
|
||||
${pkgs.xdg-user-dirs}/bin/xdg-user-dirs-update
|
||||
|
||||
${gnome3.gnome_session}/bin/gnome-session&
|
||||
${gnome3.gnome_session}/bin/gnome-session ${optionalString cfg.debug "--debug"} &
|
||||
waitPID=$!
|
||||
'';
|
||||
};
|
||||
|
@ -33,6 +33,14 @@ in
|
||||
default = false;
|
||||
description = "Don't install XFCE desktop components (xfdesktop, panel and notification daemon).";
|
||||
};
|
||||
|
||||
extraSessionCommands = mkOption {
|
||||
default = "";
|
||||
type = types.lines;
|
||||
description = ''
|
||||
Shell commands executed just before XFCE is started.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
@ -45,6 +53,8 @@ in
|
||||
bgSupport = true;
|
||||
start =
|
||||
''
|
||||
${cfg.extraSessionCommands}
|
||||
|
||||
# Set GTK_PATH so that GTK+ can find the theme engines.
|
||||
export GTK_PATH="${config.system.path}/lib/gtk-2.0:${config.system.path}/lib/gtk-3.0"
|
||||
|
||||
|
@ -3,37 +3,52 @@
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.xserver.windowManager.i3;
|
||||
wmCfg = config.services.xserver.windowManager;
|
||||
|
||||
i3option = name: {
|
||||
enable = mkEnableOption name;
|
||||
configFile = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.path;
|
||||
description = ''
|
||||
Path to the i3 configuration file.
|
||||
If left at the default value, $HOME/.i3/config will be used.
|
||||
'';
|
||||
};
|
||||
extraSessionCommands = mkOption {
|
||||
default = "";
|
||||
type = types.lines;
|
||||
description = ''
|
||||
Shell commands executed just before i3 is started.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
i3config = name: pkg: cfg: {
|
||||
services.xserver.windowManager.session = [{
|
||||
inherit name;
|
||||
start = ''
|
||||
${cfg.extraSessionCommands}
|
||||
|
||||
${pkg}/bin/i3 ${optionalString (cfg.configFile != null)
|
||||
"-c \"${cfg.configFile}\""
|
||||
} &
|
||||
waitPID=$!
|
||||
'';
|
||||
}];
|
||||
environment.systemPackages = [ pkg ];
|
||||
};
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
options = {
|
||||
services.xserver.windowManager.i3 = {
|
||||
enable = mkEnableOption "i3";
|
||||
|
||||
configFile = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.path;
|
||||
description = ''
|
||||
Path to the i3 configuration file.
|
||||
If left at the default value, $HOME/.i3/config will be used.
|
||||
'';
|
||||
};
|
||||
};
|
||||
options.services.xserver.windowManager = {
|
||||
i3 = i3option "i3";
|
||||
i3-gaps = i3option "i3-gaps";
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.xserver.windowManager = {
|
||||
session = [{
|
||||
name = "i3";
|
||||
start = ''
|
||||
${pkgs.i3}/bin/i3 ${optionalString (cfg.configFile != null)
|
||||
"-c \"${cfg.configFile}\""
|
||||
} &
|
||||
waitPID=$!
|
||||
'';
|
||||
}];
|
||||
};
|
||||
environment.systemPackages = with pkgs; [ i3 ];
|
||||
};
|
||||
config = mkMerge [
|
||||
(mkIf wmCfg.i3.enable (i3config "i3" pkgs.i3 wmCfg.i3))
|
||||
(mkIf wmCfg.i3-gaps.enable (i3config "i3-gaps" pkgs.i3-gaps wmCfg.i3-gaps))
|
||||
];
|
||||
}
|
||||
|
30
nixos/modules/services/x11/xbanish.nix
Normal file
30
nixos/modules/services/x11/xbanish.nix
Normal file
@ -0,0 +1,30 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let cfg = config.services.xbanish;
|
||||
|
||||
in {
|
||||
options.services.xbanish = {
|
||||
|
||||
enable = mkEnableOption "xbanish";
|
||||
|
||||
arguments = mkOption {
|
||||
description = "Arguments to pass to xbanish command";
|
||||
default = "";
|
||||
example = "-d -i shift";
|
||||
type = types.str;
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
systemd.user.services.xbanish = {
|
||||
description = "xbanish hides the mouse pointer";
|
||||
wantedBy = [ "default.target" ];
|
||||
serviceConfig.ExecStart = ''
|
||||
${pkgs.xbanish}/bin/xbanish ${cfg.arguments}
|
||||
'';
|
||||
serviceConfig.Restart = "always";
|
||||
};
|
||||
};
|
||||
}
|
@ -261,7 +261,7 @@ while (my ($unit, $state) = each %{$activePrev}) {
|
||||
|
||||
sub pathToUnitName {
|
||||
my ($path) = @_;
|
||||
open my $cmd, "-|", "systemd-escape", "--suffix=mount", "-p", $path
|
||||
open my $cmd, "-|", "@systemd@/bin/systemd-escape", "--suffix=mount", "-p", $path
|
||||
or die "Unable to escape $path!\n";
|
||||
my $escaped = join "", <$cmd>;
|
||||
chomp $escaped;
|
||||
|
@ -36,6 +36,8 @@ with lib;
|
||||
config = mkMerge [
|
||||
(mkIf config.systemd.coredump.enable {
|
||||
|
||||
systemd.additionalUpstreamSystemUnits = [ "systemd-coredump.socket" "systemd-coredump@.service" ];
|
||||
|
||||
environment.etc."systemd/coredump.conf".text =
|
||||
''
|
||||
[Coredump]
|
||||
@ -45,7 +47,7 @@ with lib;
|
||||
# Have the kernel pass core dumps to systemd's coredump helper binary.
|
||||
# From systemd's 50-coredump.conf file. See:
|
||||
# <https://github.com/systemd/systemd/blob/v218/sysctl.d/50-coredump.conf.in>
|
||||
boot.kernel.sysctl."kernel.core_pattern" = "|${pkgs.systemd}/lib/systemd/systemd-coredump %p %u %g %s %t %e";
|
||||
boot.kernel.sysctl."kernel.core_pattern" = "|${pkgs.systemd}/lib/systemd/systemd-coredump %P %u %g %s %t %c %e";
|
||||
})
|
||||
|
||||
(mkIf (!config.systemd.coredump.enable) {
|
||||
|
@ -100,9 +100,6 @@ in
|
||||
'';
|
||||
|
||||
boot.initrd.network.postCommands = ''
|
||||
mkdir /dev/pts
|
||||
mount -t devpts devpts /dev/pts
|
||||
|
||||
echo '${cfg.shell}' > /etc/shells
|
||||
echo 'root:x:0:0:root:/root:${cfg.shell}' > /etc/passwd
|
||||
echo 'passwd: files' > /etc/nsswitch.conf
|
||||
|
@ -5,5 +5,4 @@ pkgs.substituteAll {
|
||||
isExecutable = true;
|
||||
path = [pkgs.coreutils pkgs.gnused pkgs.gnugrep];
|
||||
inherit (pkgs) bash;
|
||||
kernelDTB = pkgs.stdenv.platform.kernelDTB or false;
|
||||
}
|
||||
|
@ -75,9 +75,10 @@ addEntry() {
|
||||
|
||||
copyToKernelsDir "$path/kernel"; kernel=$result
|
||||
copyToKernelsDir "$path/initrd"; initrd=$result
|
||||
if [ -n "@kernelDTB@" ]; then
|
||||
# XXX UGLY: maybe the system config should have a top-level "dtbs" entry?
|
||||
copyToKernelsDir $(readlink -m "$path/kernel/../dtbs"); dtbs=$result
|
||||
# XXX UGLY: maybe the system config should have a top-level "dtbs" entry?
|
||||
dtbDir=$(readlink -m "$path/kernel/../dtbs")
|
||||
if [ -d "$dtbDir" ]; then
|
||||
copyToKernelsDir "$dtbDir"; dtbs=$result
|
||||
fi
|
||||
|
||||
timestampEpoch=$(stat -L -c '%Z' $path)
|
||||
@ -95,7 +96,7 @@ addEntry() {
|
||||
fi
|
||||
echo " LINUX ../nixos/$(basename $kernel)"
|
||||
echo " INITRD ../nixos/$(basename $initrd)"
|
||||
if [ -n "@kernelDTB@" ]; then
|
||||
if [ -d "$dtbDir" ]; then
|
||||
echo " FDTDIR ../nixos/$(basename $dtbs)"
|
||||
fi
|
||||
echo " APPEND systemConfig=$path init=$path/init $extraParams"
|
||||
|
@ -501,7 +501,7 @@ sub getEfiTarget {
|
||||
my @deviceTargets = getDeviceTargets();
|
||||
my $efiTarget = getEfiTarget();
|
||||
my $prevGrubState = readGrubState();
|
||||
my @prevDeviceTargets = split/:/, $prevGrubState->devices;
|
||||
my @prevDeviceTargets = split/,/, $prevGrubState->devices;
|
||||
|
||||
my $devicesDiffer = scalar (List::Compare->new( '-u', '-a', \@deviceTargets, \@prevDeviceTargets)->get_symmetric_difference());
|
||||
my $nameDiffer = get("fullName") ne $prevGrubState->name;
|
||||
@ -549,7 +549,7 @@ if ($requireNewInstall != 0) {
|
||||
print FILE get("fullName"), "\n" or die;
|
||||
print FILE get("fullVersion"), "\n" or die;
|
||||
print FILE $efiTarget, "\n" or die;
|
||||
print FILE join( ":", @deviceTargets ), "\n" or die;
|
||||
print FILE join( ",", @deviceTargets ), "\n" or die;
|
||||
print FILE $efiSysMountPoint, "\n" or die;
|
||||
close FILE or die;
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ let
|
||||
${optionalString (header != null) "--header=${header}"} \
|
||||
${optionalString (keyFile != null) "--key-file=${keyFile} ${optionalString (keyFileSize != null) "--keyfile-size=${toString keyFileSize}"}"} \
|
||||
> /.luksopen_args
|
||||
cryptsetup-askpass
|
||||
get_password "Enter LUKS Passphrase" cryptsetup-askpass
|
||||
rm /.luksopen_args
|
||||
}
|
||||
|
||||
@ -78,9 +78,7 @@ let
|
||||
for try in $(seq 3); do
|
||||
|
||||
${optionalString yubikey.twoFactor ''
|
||||
echo -n "Enter two-factor passphrase: "
|
||||
read -s k_user
|
||||
echo
|
||||
k_user="$(get_password "Enter two-factor passphrase" cat)"
|
||||
''}
|
||||
|
||||
if [ ! -z "$k_user" ]; then
|
||||
@ -463,6 +461,26 @@ in
|
||||
''}
|
||||
'';
|
||||
|
||||
boot.initrd.preDeviceCommands = ''
|
||||
get_password() {
|
||||
local ret
|
||||
local reply
|
||||
local tty_stat
|
||||
|
||||
tty_stat="$(stty -g)"
|
||||
stty -echo
|
||||
for i in `seq 1 3`; do
|
||||
echo -n "$1: "
|
||||
read reply
|
||||
echo "$reply" | "$2"
|
||||
if [ "$?" = "0" ]; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
stty "$tty_stat"
|
||||
}
|
||||
'';
|
||||
|
||||
boot.initrd.preLVMCommands = concatStrings (mapAttrsToList openCommand preLVM);
|
||||
boot.initrd.postDeviceCommands = concatStrings (mapAttrsToList openCommand postLVM);
|
||||
|
||||
|
129
nixos/modules/system/boot/plymouth.nix
Normal file
129
nixos/modules/system/boot/plymouth.nix
Normal file
@ -0,0 +1,129 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
inherit (pkgs) plymouth;
|
||||
|
||||
cfg = config.boot.plymouth;
|
||||
|
||||
themesEnv = pkgs.buildEnv {
|
||||
name = "plymouth-themes";
|
||||
paths = [ plymouth ] ++ cfg.themePackages;
|
||||
};
|
||||
|
||||
configFile = pkgs.writeText "plymouthd.conf" ''
|
||||
[Daemon]
|
||||
ShowDelay=0
|
||||
Theme=${cfg.theme}
|
||||
'';
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
|
||||
options = {
|
||||
|
||||
boot.plymouth = {
|
||||
|
||||
enable = mkEnableOption "Plymouth boot splash screen";
|
||||
|
||||
themePackages = mkOption {
|
||||
default = [];
|
||||
type = types.listOf types.package;
|
||||
description = ''
|
||||
Extra theme packages for plymouth.
|
||||
'';
|
||||
};
|
||||
|
||||
theme = mkOption {
|
||||
default = "fade-in";
|
||||
type = types.str;
|
||||
description = ''
|
||||
Splash screen theme.
|
||||
'';
|
||||
};
|
||||
|
||||
logo = mkOption {
|
||||
type = types.path;
|
||||
default = pkgs.fetchurl {
|
||||
url = "https://nixos.org/logo/nixos-hires.png";
|
||||
sha256 = "1ivzgd7iz0i06y36p8m5w48fd8pjqwxhdaavc0pxs7w1g7mcy5si";
|
||||
};
|
||||
description = ''
|
||||
Logo which is displayed on the splash screen.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
boot.kernelParams = [ "splash" ];
|
||||
|
||||
# To be discoverable by systemd.
|
||||
environment.systemPackages = [ plymouth ];
|
||||
|
||||
environment.etc."plymouth/plymouthd.conf".source = configFile;
|
||||
environment.etc."plymouth/plymouthd.defaults".source = "${plymouth}/share/plymouth/plymouth.defaults";
|
||||
environment.etc."plymouth/logo.png".source = cfg.logo;
|
||||
environment.etc."plymouth/themes".source = "${themesEnv}/share/plymouth/themes";
|
||||
# XXX: Needed because we supply a different set of plugins in initrd.
|
||||
environment.etc."plymouth/plugins".source = "${plymouth}/lib/plymouth";
|
||||
|
||||
systemd.packages = [ plymouth ];
|
||||
|
||||
systemd.services.plymouth-kexec.wantedBy = [ "kexec.target" ];
|
||||
systemd.services.plymouth-halt.wantedBy = [ "halt.target" ];
|
||||
systemd.services.plymouth-quit = {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "display-manager.service" "multi-user.target" ];
|
||||
};
|
||||
systemd.services.plymouth-poweroff.wantedBy = [ "poweroff.target" ];
|
||||
systemd.services.plymouth-reboot.wantedBy = [ "reboot.target" ];
|
||||
systemd.services.plymouth-read-write.wantedBy = [ "sysinit.target" ];
|
||||
|
||||
boot.initrd.extraUtilsCommands = ''
|
||||
copy_bin_and_libs ${pkgs.plymouth}/bin/plymouthd
|
||||
copy_bin_and_libs ${pkgs.plymouth}/bin/plymouth
|
||||
|
||||
moduleName="$(sed -n 's,ModuleName *= *,,p' ${themesEnv}/share/plymouth/themes/${cfg.theme}/${cfg.theme}.plymouth)"
|
||||
|
||||
mkdir -p $out/lib/plymouth/renderers
|
||||
cp ${plymouth}/lib/plymouth/{text,details,$moduleName}.so $out/lib/plymouth
|
||||
cp ${plymouth}/lib/plymouth/renderers/{drm,frame-buffer}.so $out/lib/plymouth/renderers
|
||||
|
||||
mkdir -p $out/share/plymouth/themes
|
||||
cp ${plymouth}/share/plymouth/plymouthd.defaults $out/share/plymouth
|
||||
cp -r ${themesEnv}/share/plymouth/themes/{text,details,${cfg.theme}} $out/share/plymouth/themes
|
||||
cp ${cfg.logo} $out/share/plymouth/logo.png
|
||||
'';
|
||||
|
||||
boot.initrd.extraUtilsCommandsTest = ''
|
||||
$out/bin/plymouthd --help >/dev/null
|
||||
$out/bin/plymouth --help >/dev/null
|
||||
'';
|
||||
|
||||
boot.initrd.extraUdevRulesCommands = ''
|
||||
cp ${config.systemd.package}/lib/udev/rules.d/{70-uaccess,71-seat}.rules $out
|
||||
sed -i '/loginctl/d' $out/71-seat.rules
|
||||
'';
|
||||
|
||||
boot.initrd.preLVMCommands = mkAfter ''
|
||||
mkdir -p /etc/plymouth
|
||||
ln -s ${configFile} /etc/plymouth/plymouthd.conf
|
||||
ln -s $extraUtils/share/plymouth/plymouthd.defaults /etc/plymouth/plymouthd.defaults
|
||||
ln -s $extraUtils/share/plymouth/logo.png /etc/plymouth/logo.png
|
||||
ln -s $extraUtils/share/plymouth/themes /etc/plymouth/themes
|
||||
ln -s $extraUtils/lib/plymouth /etc/plymouth/plugins
|
||||
|
||||
plymouthd --mode=boot --pid-file=/run/plymouth/pid --attach-to-session
|
||||
plymouth --show-splash
|
||||
'';
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -1,7 +1,9 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.resolved;
|
||||
in
|
||||
{
|
||||
|
||||
options = {
|
||||
@ -14,9 +16,60 @@ with lib;
|
||||
'';
|
||||
};
|
||||
|
||||
services.resolved.fallbackDns = mkOption {
|
||||
default = [ ];
|
||||
example = [ "8.8.8.8" "2001:4860:4860::8844" ];
|
||||
type = types.listOf types.str;
|
||||
description = ''
|
||||
A list of IPv4 and IPv6 addresses to use as the fallback DNS servers.
|
||||
If this option is empty, a compiled-in list of DNS servers is used instead.
|
||||
'';
|
||||
};
|
||||
|
||||
services.resolved.domains = mkOption {
|
||||
default = config.networking.search;
|
||||
example = [ "example.com" ];
|
||||
type = types.listOf types.str;
|
||||
description = ''
|
||||
A list of domains. These domains are used as search suffixes when resolving single-label host names (domain names which contain no dot), in order to qualify them into fully-qualified domain names (FQDNs).
|
||||
For compatibility reasons, if this setting is not specified, the search domains listed in /etc/resolv.conf are used instead, if that file exists and any domains are configured in it.
|
||||
'';
|
||||
};
|
||||
|
||||
services.resolved.llmnr = mkOption {
|
||||
default = "true";
|
||||
example = "false";
|
||||
type = types.enum [ "true" "resolve" "false" ];
|
||||
description = ''
|
||||
Controls Link-Local Multicast Name Resolution support (RFC 4794) on the local host.
|
||||
If true, enables full LLMNR responder and resolver support.
|
||||
If false, disables both.
|
||||
If set to "resolve", only resolution support is enabled, but responding is disabled.
|
||||
'';
|
||||
};
|
||||
|
||||
services.resolved.dnssec = mkOption {
|
||||
default = "allow-downgrade";
|
||||
example = "true";
|
||||
type = types.enum [ "true" "allow-downgrade" "false" ];
|
||||
description = ''
|
||||
If true all DNS lookups are DNSSEC-validated locally (excluding LLMNR and Multicast DNS). Note that this mode requires a DNS server that supports DNSSEC. If the DNS server does not properly support DNSSEC all validations will fail.
|
||||
If set to "allow-downgrade" DNSSEC validation is attempted, but if the server does not support DNSSEC properly, DNSSEC mode is automatically disabled. Note that this mode makes DNSSEC validation vulnerable to "downgrade" attacks, where an attacker might be able to trigger a downgrade to non-DNSSEC mode by synthesizing a DNS response that suggests DNSSEC was not supported.
|
||||
If set to false, DNS lookups are not DNSSEC validated.
|
||||
'';
|
||||
};
|
||||
|
||||
services.resolved.extraConfig = mkOption {
|
||||
default = "";
|
||||
type = types.lines;
|
||||
description = ''
|
||||
Extra config to append to resolved.conf.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
config = mkIf config.services.resolved.enable {
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
systemd.additionalUpstreamSystemUnits = [ "systemd-resolved.service" ];
|
||||
|
||||
@ -27,7 +80,15 @@ with lib;
|
||||
|
||||
environment.etc."systemd/resolved.conf".text = ''
|
||||
[Resolve]
|
||||
DNS=${concatStringsSep " " config.networking.nameservers}
|
||||
${optionalString (config.networking.nameservers != [])
|
||||
"DNS=${concatStringsSep " " config.networking.nameservers}"}
|
||||
${optionalString (cfg.fallbackDns != [])
|
||||
"FallbackDNS=${concatStringsSep " " cfg.fallbackDns}"}
|
||||
${optionalString (cfg.domains != [])
|
||||
"Domains=${concatStringsSep " " cfg.domains}"}
|
||||
LLMNR=${cfg.llmnr}
|
||||
DNSSEC=${cfg.dnssec}
|
||||
${config.services.resolved.extraConfig}
|
||||
'';
|
||||
|
||||
};
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user