Merge branch 'master' into singularity
This commit is contained in:
commit
05ab1a6e5a
20
doc/Makefile
20
doc/Makefile
|
@ -9,8 +9,10 @@ debug:
|
|||
|
||||
.PHONY: format
|
||||
format:
|
||||
find . -iname '*.xml' -type f -print0 | xargs -0 -I{} -n1 \
|
||||
xmlformat --config-file "$$XMLFORMAT_CONFIG" -i {}
|
||||
find . -iname '*.xml' -type f | while read f; do \
|
||||
echo $$f ;\
|
||||
xmlformat --config-file "$$XMLFORMAT_CONFIG" -i $$f ;\
|
||||
done
|
||||
|
||||
.PHONY: fix-misc-xml
|
||||
fix-misc-xml:
|
||||
|
@ -19,7 +21,7 @@ fix-misc-xml:
|
|||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f ${MD_TARGETS} .version manual-full.xml functions/library/locations.xml
|
||||
rm -f ${MD_TARGETS} .version manual-full.xml functions/library/locations.xml functions/library/generated
|
||||
rm -rf ./out/ ./highlightjs
|
||||
|
||||
.PHONY: validate
|
||||
|
@ -69,16 +71,22 @@ highlightjs:
|
|||
cp -r "$$HIGHLIGHTJS/loader.js" highlightjs/
|
||||
|
||||
|
||||
manual-full.xml: ${MD_TARGETS} .version functions/library/locations.xml *.xml **/*.xml **/**/*.xml
|
||||
manual-full.xml: ${MD_TARGETS} .version functions/library/locations.xml functions/library/generated *.xml **/*.xml **/**/*.xml
|
||||
xmllint --nonet --xinclude --noxincludenode manual.xml --output manual-full.xml
|
||||
|
||||
.version:
|
||||
nix-instantiate --eval \
|
||||
-E '(import ../lib).version' > .version
|
||||
|
||||
function_locations := $(shell nix-build --no-out-link ./lib-function-locations.nix)
|
||||
|
||||
functions/library/locations.xml:
|
||||
nix-build ./lib-function-locations.nix \
|
||||
--out-link ./functions/library/locations.xml
|
||||
ln -s $(function_locations) ./functions/library/locations.xml
|
||||
|
||||
functions/library/generated:
|
||||
nix-build ./lib-function-docs.nix \
|
||||
--arg locationsXml $(function_locations)\
|
||||
--out-link ./functions/library/generated
|
||||
|
||||
%.section.xml: %.section.md
|
||||
pandoc $^ -w docbook+smart \
|
||||
|
|
|
@ -814,7 +814,7 @@ args.stdenv.mkDerivation (args // {
|
|||
|
||||
<para>
|
||||
There are multiple ways to fetch a package source in nixpkgs. The general
|
||||
guideline is that you should package sources with a high degree of
|
||||
guideline is that you should package reproducible sources with a high degree of
|
||||
availability. Right now there is only one fetcher which has mirroring
|
||||
support and that is <literal>fetchurl</literal>. Note that you should also
|
||||
prefer protocols which have a corresponding proxy environment variable.
|
||||
|
@ -876,6 +876,123 @@ src = fetchFromGitHub {
|
|||
</itemizedlist>
|
||||
</para>
|
||||
</section>
|
||||
<section xml:id="sec-source-hashes">
|
||||
<title>Obtaining source hash</title>
|
||||
|
||||
<para>
|
||||
Preferred source hash type is sha256. There are several ways to get it.
|
||||
</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Prefetch URL (with <literal>nix-prefetch-<replaceable>XXX</replaceable>
|
||||
<replaceable>URL</replaceable></literal>, where
|
||||
<replaceable>XXX</replaceable> is one of <literal>url</literal>,
|
||||
<literal>git</literal>, <literal>hg</literal>, <literal>cvs</literal>,
|
||||
<literal>bzr</literal>, <literal>svn</literal>). Hash is printed to
|
||||
stdout.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Prefetch by package source (with <literal>nix-prefetch-url
|
||||
'<nixpkgs>' -A <replaceable>PACKAGE</replaceable>.src</literal>,
|
||||
where <replaceable>PACKAGE</replaceable> is package attribute name). Hash
|
||||
is printed to stdout.
|
||||
</para>
|
||||
<para>
|
||||
This works well when you've upgraded existing package version and want to
|
||||
find out new hash, but is useless if package can't be accessed by
|
||||
attribute or package has multiple sources (<literal>.srcs</literal>,
|
||||
architecture-dependent sources, etc).
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Upstream provided hash: use it when upstream provides
|
||||
<literal>sha256</literal> or <literal>sha512</literal> (when upstream
|
||||
provides <literal>md5</literal>, don't use it, compute
|
||||
<literal>sha256</literal> instead).
|
||||
</para>
|
||||
<para>
|
||||
A little nuance is that <literal>nix-prefetch-*</literal> tools produce
|
||||
hash encoded with <literal>base32</literal>, but upstream usually provides
|
||||
hexadecimal (<literal>base16</literal>) encoding. Fetchers understand both
|
||||
formats. Nixpkgs does not standardize on any one format.
|
||||
</para>
|
||||
<para>
|
||||
You can convert between formats with nix-hash, for example:
|
||||
<screen>
|
||||
$ nix-hash --type sha256 --to-base32 <replaceable>HASH</replaceable>
|
||||
</screen>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Extracting hash from local source tarball can be done with
|
||||
<literal>sha256sum</literal>. Use <literal>nix-prefetch-url
|
||||
file:///path/to/tarball </literal> if you want base32 hash.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Fake hash: set fake hash in package expression, perform build and extract
|
||||
correct hash from error Nix prints.
|
||||
</para>
|
||||
<para>
|
||||
For package updates it is enough to change one symbol to make hash fake.
|
||||
For new packages, you can use <literal>lib.fakeSha256</literal>,
|
||||
<literal>lib.fakeSha512</literal> or any other fake hash.
|
||||
</para>
|
||||
<para>
|
||||
This is last resort method when reconstructing source URL is non-trivial
|
||||
and <literal>nix-prefetch-url -A</literal> isn't applicable (for example,
|
||||
<link xlink:href="https://github.com/NixOS/nixpkgs/blob/d2ab091dd308b99e4912b805a5eb088dd536adb9/pkgs/applications/video/kodi/default.nix#L73">
|
||||
one of <literal>kodi</literal> dependencies</link>). The easiest way then
|
||||
would be replace hash with a fake one and rebuild. Nix build will fail and
|
||||
error message will contain desired hash.
|
||||
</para>
|
||||
<warning><para>This method has security problems. Check below for details.</para></warning>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
|
||||
<section xml:id="sec-source-hashes-security">
|
||||
<title>Obtaining hashes securely</title>
|
||||
<para>
|
||||
Let's say Man-in-the-Middle (MITM) sits close to your network. Then instead of fetching
|
||||
source you can fetch malware, and instead of source hash you get hash of malware. Here are
|
||||
security considerations for this scenario:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>http://</literal> URLs are not secure to prefetch hash from;
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
hashes from upstream (in method 3) should be obtained via secure protocol;
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>https://</literal> URLs are secure in methods 1, 2, 3;
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>https://</literal> URLs are not secure in method 5. When obtaining hashes
|
||||
with fake hash method, TLS checks are disabled. So
|
||||
refetch source hash from several different networks to exclude MITM scenario.
|
||||
Alternatively, use fake hash method to make Nix error, but instead of extracting
|
||||
hash from error, extract <literal>https://</literal> URL and prefetch it
|
||||
with method 1.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
</section>
|
||||
<section xml:id="sec-patches">
|
||||
<title>Patches</title>
|
||||
|
||||
|
|
|
@ -180,7 +180,11 @@
|
|||
code:
|
||||
<programlisting>
|
||||
{
|
||||
allowUnfreePredicate = (pkg: builtins.elem (builtins.parseDrvName pkg.name).name [ "flashplayer" "vscode" ]);
|
||||
allowUnfreePredicate = (pkg: builtins.elem
|
||||
(builtins.parseDrvName pkg.name).name [
|
||||
"flashplayer"
|
||||
"vscode"
|
||||
]);
|
||||
}
|
||||
</programlisting>
|
||||
</para>
|
||||
|
@ -322,7 +326,18 @@
|
|||
packageOverrides = pkgs: with pkgs; {
|
||||
myPackages = pkgs.buildEnv {
|
||||
name = "my-packages";
|
||||
paths = [ aspell bc coreutils gdb ffmpeg nixUnstable emscripten jq nox silver-searcher ];
|
||||
paths = [
|
||||
aspell
|
||||
bc
|
||||
coreutils
|
||||
gdb
|
||||
ffmpeg
|
||||
nixUnstable
|
||||
emscripten
|
||||
jq
|
||||
nox
|
||||
silver-searcher
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -343,7 +358,18 @@
|
|||
packageOverrides = pkgs: with pkgs; {
|
||||
myPackages = pkgs.buildEnv {
|
||||
name = "my-packages";
|
||||
paths = [ aspell bc coreutils gdb ffmpeg nixUnstable emscripten jq nox silver-searcher ];
|
||||
paths = [
|
||||
aspell
|
||||
bc
|
||||
coreutils
|
||||
gdb
|
||||
ffmpeg
|
||||
nixUnstable
|
||||
emscripten
|
||||
jq
|
||||
nox
|
||||
silver-searcher
|
||||
];
|
||||
pathsToLink = [ "/share" "/bin" ];
|
||||
};
|
||||
};
|
||||
|
@ -378,7 +404,17 @@
|
|||
packageOverrides = pkgs: with pkgs; {
|
||||
myPackages = pkgs.buildEnv {
|
||||
name = "my-packages";
|
||||
paths = [ aspell bc coreutils ffmpeg nixUnstable emscripten jq nox silver-searcher ];
|
||||
paths = [
|
||||
aspell
|
||||
bc
|
||||
coreutils
|
||||
ffmpeg
|
||||
nixUnstable
|
||||
emscripten
|
||||
jq
|
||||
nox
|
||||
silver-searcher
|
||||
];
|
||||
pathsToLink = [ "/share/man" "/share/doc" "/bin" ];
|
||||
extraOutputsToInstall = [ "man" "doc" ];
|
||||
};
|
||||
|
|
|
@ -11,7 +11,10 @@
|
|||
<xi:include href="functions/overrides.xml" />
|
||||
<xi:include href="functions/generators.xml" />
|
||||
<xi:include href="functions/debug.xml" />
|
||||
<xi:include href="functions/fetchers.xml" />
|
||||
<xi:include href="functions/trivial-builders.xml" />
|
||||
<xi:include href="functions/fhs-environments.xml" />
|
||||
<xi:include href="functions/shell.xml" />
|
||||
<xi:include href="functions/dockertools.xml" />
|
||||
<xi:include href="functions/prefer-remote-fetch.xml" />
|
||||
</chapter>
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
<para>
|
||||
This function is analogous to the <command>docker build</command> command,
|
||||
in that can used to build a Docker-compatible repository tarball containing
|
||||
in that it can be used to build a Docker-compatible repository tarball containing
|
||||
a single image with one or multiple layers. As such, the result is suitable
|
||||
for being loaded in Docker with <command>docker load</command>.
|
||||
</para>
|
||||
|
@ -190,11 +190,11 @@ buildImage {
|
|||
By default <function>buildImage</function> will use a static date of one
|
||||
second past the UNIX Epoch. This allows <function>buildImage</function> to
|
||||
produce binary reproducible images. When listing images with
|
||||
<command>docker list images</command>, the newly created images will be
|
||||
<command>docker images</command>, the newly created images will be
|
||||
listed like this:
|
||||
</para>
|
||||
<screen><![CDATA[
|
||||
$ docker image list
|
||||
$ docker images
|
||||
REPOSITORY TAG IMAGE ID CREATED SIZE
|
||||
hello latest 08c791c7846e 48 years ago 25.2MB
|
||||
]]></screen>
|
||||
|
@ -217,7 +217,7 @@ pkgs.dockerTools.buildImage {
|
|||
and now the Docker CLI will display a reasonable date and sort the images
|
||||
as expected:
|
||||
<screen><![CDATA[
|
||||
$ docker image list
|
||||
$ docker images
|
||||
REPOSITORY TAG IMAGE ID CREATED SIZE
|
||||
hello latest de2bf4786de6 About a minute ago 25.2MB
|
||||
]]></screen>
|
||||
|
@ -402,7 +402,7 @@ pkgs.dockerTools.buildLayeredImage {
|
|||
|
||||
<para>
|
||||
This function is analogous to the <command>docker pull</command> command, in
|
||||
that can be used to pull a Docker image from a Docker registry. By default
|
||||
that it can be used to pull a Docker image from a Docker registry. By default
|
||||
<link xlink:href="https://hub.docker.com/">Docker Hub</link> is used to pull
|
||||
images.
|
||||
</para>
|
||||
|
@ -484,7 +484,7 @@ sha256:20d9485b25ecfd89204e843a962c1bd70e9cc6858d65d7f5fadc340246e2116b
|
|||
|
||||
<para>
|
||||
This function is analogous to the <command>docker export</command> command,
|
||||
in that can used to flatten a Docker image that contains multiple layers. It
|
||||
in that it can be used to flatten a Docker image that contains multiple layers. It
|
||||
is in fact the result of the merge of all the layers of the image. As such,
|
||||
the result is suitable for being imported in Docker with <command>docker
|
||||
import</command>.
|
||||
|
@ -557,7 +557,7 @@ buildImage {
|
|||
|
||||
<para>
|
||||
Creating base files like <literal>/etc/passwd</literal> or
|
||||
<literal>/etc/login.defs</literal> are necessary for shadow-utils to
|
||||
<literal>/etc/login.defs</literal> is necessary for shadow-utils to
|
||||
manipulate users and groups.
|
||||
</para>
|
||||
</section>
|
||||
|
|
206
doc/functions/fetchers.xml
Normal file
206
doc/functions/fetchers.xml
Normal file
|
@ -0,0 +1,206 @@
|
|||
<section xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
xml:id="sec-pkgs-fetchers">
|
||||
<title>Fetcher functions</title>
|
||||
|
||||
<para>
|
||||
When using Nix, you will frequently need to download source code
|
||||
and other files from the internet. Nixpkgs comes with a few helper
|
||||
functions that allow you to fetch fixed-output derivations in a
|
||||
structured way.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The two fetcher primitives are <function>fetchurl</function> and
|
||||
<function>fetchzip</function>. Both of these have two required
|
||||
arguments, a URL and a hash. The hash is typically
|
||||
<literal>sha256</literal>, although many more hash algorithms are
|
||||
supported. Nixpkgs contributors are currently recommended to use
|
||||
<literal>sha256</literal>. This hash will be used by Nix to
|
||||
identify your source. A typical usage of fetchurl is provided
|
||||
below.
|
||||
</para>
|
||||
|
||||
<programlisting><![CDATA[
|
||||
{ stdenv, fetchurl }:
|
||||
|
||||
stdenv.mkDerivation {
|
||||
name = "hello";
|
||||
src = fetchurl {
|
||||
url = "http://www.example.org/hello.tar.gz";
|
||||
sha256 = "1111111111111111111111111111111111111111111111111111";
|
||||
};
|
||||
}
|
||||
]]></programlisting>
|
||||
|
||||
<para>
|
||||
The main difference between <function>fetchurl</function> and
|
||||
<function>fetchzip</function> is in how they store the contents.
|
||||
<function>fetchurl</function> will store the unaltered contents of
|
||||
the URL within the Nix store. <function>fetchzip</function> on the
|
||||
other hand will decompress the archive for you, making files and
|
||||
directories directly accessible in the future.
|
||||
<function>fetchzip</function> can only be used with archives.
|
||||
Despite the name, <function>fetchzip</function> is not limited to
|
||||
.zip files and can also be used with any tarball.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<function>fetchpatch</function> works very similarly to
|
||||
<function>fetchurl</function> with the same arguments expected. It
|
||||
expects patch files as a source and and performs normalization on
|
||||
them before computing the checksum. For example it will remove
|
||||
comments or other unstable parts that are sometimes added by
|
||||
version control systems and can change over time.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Other fetcher functions allow you to add source code directly from
|
||||
a VCS such as subversion or git. These are mostly straightforward
|
||||
names based on the name of the command used with the VCS system.
|
||||
Because they give you a working repository, they act most like
|
||||
<function>fetchzip</function>.
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>fetchsvn</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Used with Subversion. Expects <literal>url</literal> to a
|
||||
Subversion directory, <literal>rev</literal>, and
|
||||
<literal>sha256</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>fetchgit</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Used with Git. Expects <literal>url</literal> to a Git repo,
|
||||
<literal>rev</literal>, and <literal>sha256</literal>.
|
||||
<literal>rev</literal> in this case can be full the git commit
|
||||
id (SHA1 hash) or a tag name like
|
||||
<literal>refs/tags/v1.0</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>fetchfossil</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Used with Fossil. Expects <literal>url</literal> to a Fossil
|
||||
archive, <literal>rev</literal>, and <literal>sha256</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>fetchcvs</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Used with CVS. Expects <literal>cvsRoot</literal>,
|
||||
<literal>tag</literal>, and <literal>sha256</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>fetchhg</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Used with Mercurial. Expects <literal>url</literal>,
|
||||
<literal>rev</literal>, and <literal>sha256</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<para>
|
||||
A number of fetcher functions wrap part of
|
||||
<function>fetchurl</function> and <function>fetchzip</function>.
|
||||
They are mainly convenience functions intended for commonly used
|
||||
destinations of source code in Nixpkgs. These wrapper fetchers are
|
||||
listed below.
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>fetchFromGitHub</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
<function>fetchFromGitHub</function> expects four arguments.
|
||||
<literal>owner</literal> is a string corresponding to the
|
||||
GitHub user or organization that controls this repository.
|
||||
<literal>repo</literal> corresponds to the name of the
|
||||
software repository. These are located at the top of every
|
||||
GitHub HTML page as
|
||||
<literal>owner</literal>/<literal>repo</literal>.
|
||||
<literal>rev</literal> corresponds to the Git commit hash or
|
||||
tag (e.g <literal>v1.0</literal>) that will be downloaded from
|
||||
Git. Finally, <literal>sha256</literal> corresponds to the
|
||||
hash of the extracted directory. Again, other hash algorithms
|
||||
are also available but <literal>sha256</literal> is currently
|
||||
preferred.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>fetchFromGitLab</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
This is used with GitLab repositories. The arguments expected
|
||||
are very similar to fetchFromGitHub above.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>fetchFromBitbucket</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
This is used with BitBucket repositories. The arguments expected
|
||||
are very similar to fetchFromGitHub above.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>fetchFromSavannah</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
This is used with Savannah repositories. The arguments expected
|
||||
are very similar to fetchFromGitHub above.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>fetchFromRepoOrCz</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
This is used with repo.or.cz repositories. The arguments
|
||||
expected are very similar to fetchFromGitHub above.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
|
||||
</section>
|
27
doc/functions/prefer-remote-fetch.xml
Normal file
27
doc/functions/prefer-remote-fetch.xml
Normal file
|
@ -0,0 +1,27 @@
|
|||
<section xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/xinclude"
|
||||
xml:id="sec-prefer-remote-fetch">
|
||||
<title>prefer-remote-fetch overlay</title>
|
||||
|
||||
<para>
|
||||
<function>prefer-remote-fetch</function> is an overlay that download sources
|
||||
on remote builder. This is useful when the evaluating machine has a slow
|
||||
upload while the builder can fetch faster directly from the source.
|
||||
To use it, put the following snippet as a new overlay:
|
||||
<programlisting>
|
||||
self: super:
|
||||
(super.prefer-remote-fetch self super)
|
||||
</programlisting>
|
||||
|
||||
A full configuration example for that sets the overlay up for your own account,
|
||||
could look like this
|
||||
|
||||
<programlisting>
|
||||
$ mkdir ~/.config/nixpkgs/overlays/
|
||||
$ cat > ~/.config/nixpkgs/overlays/prefer-remote-fetch.nix <<EOF
|
||||
self: super: super.prefer-remote-fetch self super
|
||||
EOF
|
||||
</programlisting>
|
||||
</para>
|
||||
</section>
|
124
doc/functions/trivial-builders.xml
Normal file
124
doc/functions/trivial-builders.xml
Normal file
|
@ -0,0 +1,124 @@
|
|||
<section xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
xml:id="sec-trivial-builders">
|
||||
<title>Trivial builders</title>
|
||||
|
||||
<para>
|
||||
Nixpkgs provides a couple of functions that help with building
|
||||
derivations. The most important one,
|
||||
<function>stdenv.mkDerivation</function>, has already been
|
||||
documented above. The following functions wrap
|
||||
<function>stdenv.mkDerivation</function>, making it easier to use
|
||||
in certain cases.
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>runCommand</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
This takes three arguments, <literal>name</literal>,
|
||||
<literal>env</literal>, and <literal>buildCommand</literal>.
|
||||
<literal>name</literal> is just the name that Nix will append
|
||||
to the store path in the same way that
|
||||
<literal>stdenv.mkDerivation</literal> uses its
|
||||
<literal>name</literal> attribute. <literal>env</literal> is an
|
||||
attribute set specifying environment variables that will be set
|
||||
for this derivation. These attributes are then passed to the
|
||||
wrapped <literal>stdenv.mkDerivation</literal>.
|
||||
<literal>buildCommand</literal> specifies the commands that
|
||||
will be run to create this derivation. Note that you will need
|
||||
to create <literal>$out</literal> for Nix to register the
|
||||
command as successful.
|
||||
</para>
|
||||
<para>
|
||||
An example of using <literal>runCommand</literal> is provided
|
||||
below.
|
||||
</para>
|
||||
<programlisting>
|
||||
(import <nixpkgs> {}).runCommand "my-example" {} ''
|
||||
echo My example command is running
|
||||
|
||||
mkdir $out
|
||||
|
||||
echo I can write data to the Nix store > $out/message
|
||||
|
||||
echo I can also run basic commands like:
|
||||
|
||||
echo ls
|
||||
ls
|
||||
|
||||
echo whoami
|
||||
whoami
|
||||
|
||||
echo date
|
||||
date
|
||||
''
|
||||
</programlisting>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>runCommandCC</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
This works just like <literal>runCommand</literal>. The only
|
||||
difference is that it also provides a C compiler in
|
||||
<literal>buildCommand</literal>’s environment. To minimize your
|
||||
dependencies, you should only use this if you are sure you will
|
||||
need a C compiler as part of running your command.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>writeTextFile</literal>, <literal>writeText</literal>,
|
||||
<literal>writeTextDir</literal>, <literal>writeScript</literal>,
|
||||
<literal>writeScriptBin</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
These functions write <literal>text</literal> to the Nix store.
|
||||
This is useful for creating scripts from Nix expressions.
|
||||
<literal>writeTextFile</literal> takes an attribute set and
|
||||
expects two arguments, <literal>name</literal> and
|
||||
<literal>text</literal>. <literal>name</literal> corresponds to
|
||||
the name used in the Nix store path. <literal>text</literal>
|
||||
will be the contents of the file. You can also set
|
||||
<literal>executable</literal> to true to make this file have
|
||||
the executable bit set.
|
||||
</para>
|
||||
<para>
|
||||
Many more commands wrap <literal>writeTextFile</literal>
|
||||
including <literal>writeText</literal>,
|
||||
<literal>writeTextDir</literal>,
|
||||
<literal>writeScript</literal>, and
|
||||
<literal>writeScriptBin</literal>. These are convenience
|
||||
functions over <literal>writeTextFile</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>symlinkJoin</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
This can be used to put many derivations into the same directory
|
||||
structure. It works by creating a new derivation and adding
|
||||
symlinks to each of the paths listed. It expects two arguments,
|
||||
<literal>name</literal>, and <literal>paths</literal>.
|
||||
<literal>name</literal> is the name used in the Nix store path
|
||||
for the created derivation. <literal>paths</literal> is a list of
|
||||
paths that will be symlinked. These paths can be to Nix store
|
||||
derivations or any other subdirectory contained within.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
</section>
|
|
@ -352,9 +352,9 @@ you want them to come from. Add the following to `configuration.nix`.
|
|||
|
||||
```nix
|
||||
services.hoogle = {
|
||||
enable = true;
|
||||
packages = (hpkgs: with hpkgs; [text cryptonite]);
|
||||
haskellPackages = pkgs.haskellPackages;
|
||||
enable = true;
|
||||
packages = (hpkgs: with hpkgs; [text cryptonite]);
|
||||
haskellPackages = pkgs.haskellPackages;
|
||||
};
|
||||
```
|
||||
|
||||
|
|
|
@ -605,11 +605,11 @@ policy.
|
|||
-->
|
||||
|
||||
<para>
|
||||
In a case a contributor leaves definitively the Nix community, he should
|
||||
In a case a contributor definitively leaves the Nix community, they should
|
||||
create an issue or post on
|
||||
<link
|
||||
xlink:href="https://discourse.nixos.org">Discourse</link> with
|
||||
references of packages and modules he maintains so the maintainership can be
|
||||
references of packages and modules they maintain so the maintainership can be
|
||||
taken over by other contributors.
|
||||
</para>
|
||||
</section>
|
||||
|
|
155
doc/stdenv.xml
155
doc/stdenv.xml
|
@ -1279,7 +1279,9 @@ makeFlags = [ "PREFIX=$(out)" ];
|
|||
<command>make</command>. You must use this instead of
|
||||
<varname>makeFlags</varname> if the arguments contain spaces, e.g.
|
||||
<programlisting>
|
||||
makeFlagsArray=(CFLAGS="-O0 -g" LDFLAGS="-lfoo -lbar")
|
||||
preBuild = ''
|
||||
makeFlagsArray+=(CFLAGS="-O0 -g" LDFLAGS="-lfoo -lbar")
|
||||
'';
|
||||
</programlisting>
|
||||
Note that shell arrays cannot be passed through environment variables,
|
||||
so you cannot set <varname>makeFlagsArray</varname> in a derivation
|
||||
|
@ -1662,6 +1664,18 @@ installTargets = "install-bin install-doc";</programlisting>
|
|||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>dontPruneLibtoolFiles</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
If set, libtool <literal>.la</literal> files associated with shared
|
||||
libraries won't have their <literal>dependency_libs</literal> field
|
||||
cleared.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>forceShare</varname>
|
||||
|
@ -1798,7 +1812,7 @@ set debug-file-directory ~/.nix-profile/lib/debug
|
|||
<listitem>
|
||||
<para>
|
||||
A list of dependencies used by the phase. This gets included in
|
||||
<varname>buildInputs</varname> when <varname>doInstallCheck</varname> is
|
||||
<varname>nativeBuildInputs</varname> when <varname>doInstallCheck</varname> is
|
||||
set.
|
||||
</para>
|
||||
</listitem>
|
||||
|
@ -2190,10 +2204,130 @@ addEnvHooks "$hostOffset" myBashFunction
|
|||
</para>
|
||||
|
||||
<para>
|
||||
Here are some packages that provide a setup hook. Since the mechanism is
|
||||
modular, this probably isn't an exhaustive list. Then again, since the
|
||||
mechanism is only to be used as a last resort, it might be.
|
||||
<variablelist>
|
||||
First, let’s cover some setup hooks that are part of Nixpkgs
|
||||
default stdenv. This means that they are run for every package
|
||||
built using <function>stdenv.mkDerivation</function>. Some of
|
||||
these are platform specific, so they may run on Linux but not
|
||||
Darwin or vice-versa.
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>move-docs.sh</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
This setup hook moves any installed documentation to the
|
||||
<literal>/share</literal> subdirectory directory. This includes
|
||||
the man, doc and info directories. This is needed for legacy
|
||||
programs that do not know how to use the
|
||||
<literal>share</literal> subdirectory.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>compress-man-pages.sh</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
This setup hook compresses any man pages that have been
|
||||
installed. The compression is done using the gzip program. This
|
||||
helps to reduce the installed size of packages.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>strip.sh</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
This runs the strip command on installed binaries and
|
||||
libraries. This removes unnecessary information like debug
|
||||
symbols when they are not needed. This also helps to reduce the
|
||||
installed size of packages.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>patch-shebangs.sh</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
This setup hook patches installed scripts to use the full path
|
||||
to the shebang interpreter. A shebang interpreter is the first
|
||||
commented line of a script telling the operating system which
|
||||
program will run the script (e.g <literal>#!/bin/bash</literal>). In
|
||||
Nix, we want an exact path to that interpreter to be used. This
|
||||
often replaces <literal>/bin/sh</literal> with a path in the
|
||||
Nix store.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>audit-tmpdir.sh</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
This verifies that no references are left from the install
|
||||
binaries to the directory used to build those binaries. This
|
||||
ensures that the binaries do not need things outside the Nix
|
||||
store. This is currently supported in Linux only.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>multiple-outputs.sh</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
This setup hook adds configure flags that tell packages to
|
||||
install files into any one of the proper outputs listed in
|
||||
<literal>outputs</literal>. This behavior can be turned off by setting
|
||||
<literal>setOutputFlags</literal> to false in the derivation
|
||||
environment. See <xref linkend="chap-multiple-output"/> for
|
||||
more information.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>move-sbin.sh</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
This setup hook moves any binaries installed in the sbin
|
||||
subdirectory into bin. In addition, a link is provided from
|
||||
sbin to bin for compatibility.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>move-lib64.sh</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
This setup hook moves any libraries installed in the lib64
|
||||
subdirectory into lib. In addition, a link is provided from
|
||||
lib64 to lib for compatibility.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>set-source-date-epoch-to-latest.sh</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
This sets <literal>SOURCE_DATE_EPOCH</literal> to the
|
||||
modification time of the most recent file.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
Bintools Wrapper
|
||||
|
@ -2300,6 +2434,15 @@ addEnvHooks "$hostOffset" myBashFunction
|
|||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Here are some more packages that provide a setup hook. Since the
|
||||
list of hooks is extensible, this is not an exhaustive list the
|
||||
mechanism is only to be used as a last resort, it might cover most
|
||||
uses.
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
Perl
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
body
|
||||
{
|
||||
font-family: "Nimbus Sans L", sans-serif;
|
||||
font-size: 1em;
|
||||
background: white;
|
||||
margin: 2em 1em 2em 1em;
|
||||
}
|
||||
|
@ -28,6 +29,25 @@ h2 /* chapters, appendices, subtitle */
|
|||
font-size: 180%;
|
||||
}
|
||||
|
||||
div.book
|
||||
{
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
div.book > div
|
||||
{
|
||||
/*
|
||||
* based on https://medium.com/@zkareemz/golden-ratio-62b3b6d4282a
|
||||
* we do 70 characters per line to fit code listings better
|
||||
* 70 * (font-size / 1.618)
|
||||
* expression for emacs:
|
||||
* (* 70 (/ 1 1.618))
|
||||
*/
|
||||
max-width: 43.2em;
|
||||
text-align: left;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
/* Extra space between chapters, appendices. */
|
||||
div.chapter > div.titlepage h2, div.appendix > div.titlepage h2
|
||||
{
|
||||
|
@ -102,8 +122,8 @@ pre.screen, pre.programlisting
|
|||
{
|
||||
border: 1px solid #b0b0b0;
|
||||
padding: 3px 3px;
|
||||
margin-left: 1.5em;
|
||||
margin-right: 1.5em;
|
||||
margin-left: 0.5em;
|
||||
margin-right: 0.5em;
|
||||
|
||||
background: #f4f4f8;
|
||||
font-family: monospace;
|
||||
|
|
|
@ -121,7 +121,7 @@ rec {
|
|||
auto = builtins.intersectAttrs (lib.functionArgs f) autoArgs;
|
||||
origArgs = auto // args;
|
||||
pkgs = f origArgs;
|
||||
mkAttrOverridable = name: pkg: makeOverridable (newArgs: (f newArgs).${name}) origArgs;
|
||||
mkAttrOverridable = name: _: makeOverridable (newArgs: (f newArgs).${name}) origArgs;
|
||||
in lib.mapAttrs mkAttrOverridable pkgs;
|
||||
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ let
|
|||
callPackageWith callPackagesWith extendDerivation hydraJob
|
||||
makeScope;
|
||||
inherit (meta) addMetaAttrs dontDistribute setName updateName
|
||||
appendToName mapDerivationAttrset lowPrio lowPrioSet hiPrio
|
||||
appendToName mapDerivationAttrset setPrio lowPrio lowPrioSet hiPrio
|
||||
hiPrioSet;
|
||||
inherit (sources) pathType pathIsDirectory cleanSourceFilter
|
||||
cleanSource sourceByRegex sourceFilesBySuffices
|
||||
|
@ -109,7 +109,7 @@ let
|
|||
mkFixStrictness mkOrder mkBefore mkAfter mkAliasDefinitions
|
||||
mkAliasAndWrapDefinitions fixMergeModules mkRemovedOptionModule
|
||||
mkRenamedOptionModule mkMergedOptionModule mkChangedOptionModule
|
||||
mkAliasOptionModule doRename filterModules;
|
||||
mkAliasOptionModule mkAliasOptionModuleWithPriority doRename filterModules;
|
||||
inherit (options) isOption mkEnableOption mkSinkUndeclaredOptions
|
||||
mergeDefaultOption mergeOneOption mergeEqualOption getValues
|
||||
getFiles optionAttrSetToDocList optionAttrSetToDocList'
|
||||
|
@ -132,6 +132,7 @@ let
|
|||
mergeAttrsWithFunc mergeAttrsConcatenateValues
|
||||
mergeAttrsNoOverride mergeAttrByFunc mergeAttrsByFuncDefaults
|
||||
mergeAttrsByFuncDefaultsClean mergeAttrBy
|
||||
fakeSha256 fakeSha512
|
||||
nixType imap;
|
||||
});
|
||||
in lib
|
||||
|
|
|
@ -270,4 +270,8 @@ rec {
|
|||
starting at zero.
|
||||
*/
|
||||
imap = imap1;
|
||||
|
||||
# Fake hashes. Can be used as hash placeholders, when computing hash ahead isn't trivial
|
||||
fakeSha256 = "0000000000000000000000000000000000000000000000000000000000000000";
|
||||
fakeSha512 = "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
|
||||
}
|
||||
|
|
|
@ -1,57 +1,21 @@
|
|||
{ lib
|
||||
# we pass the kernel version here to keep a nice syntax `whenOlder "4.13"`
|
||||
# kernelVersion, e.g., config.boot.kernelPackages.version
|
||||
, version
|
||||
, mkValuePreprocess ? null
|
||||
}:
|
||||
{ lib, version }:
|
||||
|
||||
with lib;
|
||||
rec {
|
||||
# Common patterns
|
||||
when = cond: opt: if cond then opt else null;
|
||||
whenAtLeast = ver: when (versionAtLeast version ver);
|
||||
whenOlder = ver: when (versionOlder version ver);
|
||||
whenBetween = verLow: verHigh: when (versionAtLeast version verLow && versionOlder version verHigh);
|
||||
# Common patterns/legacy
|
||||
whenAtLeast = ver: mkIf (versionAtLeast version ver);
|
||||
whenOlder = ver: mkIf (versionOlder version ver);
|
||||
# range is (inclusive, exclusive)
|
||||
whenBetween = verLow: verHigh: mkIf (versionAtLeast version verLow && versionOlder version verHigh);
|
||||
|
||||
|
||||
# Keeping these around in case we decide to change this horrible implementation :)
|
||||
option = x: if x == null then null else "?${x}";
|
||||
yes = "y";
|
||||
no = "n";
|
||||
module = "m";
|
||||
option = x:
|
||||
x // { optional = true; };
|
||||
|
||||
mkValue = val:
|
||||
let
|
||||
isNumber = c: elem c ["0" "1" "2" "3" "4" "5" "6" "7" "8" "9"];
|
||||
in
|
||||
if val == "" then "\"\""
|
||||
else if val == yes || val == module || val == no then val
|
||||
else if all isNumber (stringToCharacters val) then val
|
||||
else if substring 0 2 val == "0x" then val
|
||||
else val; # FIXME: fix quoting one day
|
||||
yes = { tristate = "y"; };
|
||||
no = { tristate = "n"; };
|
||||
module = { tristate = "m"; };
|
||||
freeform = x: { freeform = x; };
|
||||
|
||||
|
||||
# generate nix intermediate kernel config file of the form
|
||||
#
|
||||
# VIRTIO_MMIO m
|
||||
# VIRTIO_BLK y
|
||||
# VIRTIO_CONSOLE n
|
||||
# NET_9P_VIRTIO? y
|
||||
#
|
||||
# Use mkValuePreprocess to preprocess option values, aka mark 'modules' as
|
||||
# 'yes' or vice-versa
|
||||
# Borrowed from copumpkin https://github.com/NixOS/nixpkgs/pull/12158
|
||||
# returns a string, expr should be an attribute set
|
||||
generateNixKConf = exprs: mkValuePreprocess:
|
||||
let
|
||||
mkConfigLine = key: rawval:
|
||||
let
|
||||
val = if builtins.isFunction mkValuePreprocess then mkValuePreprocess rawval else rawval;
|
||||
in
|
||||
if val == null
|
||||
then ""
|
||||
else if hasPrefix "?" val
|
||||
then "${key}? ${mkValue (removePrefix "?" val)}\n"
|
||||
else "${key} ${mkValue val}\n";
|
||||
mkConf = cfg: concatStrings (mapAttrsToList mkConfigLine cfg);
|
||||
in mkConf exprs;
|
||||
}
|
||||
|
|
11
lib/meta.nix
11
lib/meta.nix
|
@ -41,16 +41,18 @@ rec {
|
|||
let x = builtins.parseDrvName name; in "${x.name}-${suffix}-${x.version}");
|
||||
|
||||
|
||||
/* Apply a function to each derivation and only to derivations in an attrset
|
||||
/* Apply a function to each derivation and only to derivations in an attrset.
|
||||
*/
|
||||
mapDerivationAttrset = f: set: lib.mapAttrs (name: pkg: if lib.isDerivation pkg then (f pkg) else pkg) set;
|
||||
|
||||
/* Set the nix-env priority of the package.
|
||||
*/
|
||||
setPrio = priority: addMetaAttrs { inherit priority; };
|
||||
|
||||
/* Decrease the nix-env priority of the package, i.e., other
|
||||
versions/variants of the package will be preferred.
|
||||
*/
|
||||
lowPrio = drv: addMetaAttrs { priority = 10; } drv;
|
||||
|
||||
lowPrio = setPrio 10;
|
||||
|
||||
/* Apply lowPrio to an attrset with derivations
|
||||
*/
|
||||
|
@ -60,8 +62,7 @@ rec {
|
|||
/* Increase the nix-env priority of the package, i.e., this
|
||||
version/variant of the package will be preferred.
|
||||
*/
|
||||
hiPrio = drv: addMetaAttrs { priority = -10; } drv;
|
||||
|
||||
hiPrio = setPrio (-10);
|
||||
|
||||
/* Apply hiPrio to an attrset with derivations
|
||||
*/
|
||||
|
|
|
@ -214,23 +214,25 @@ rec {
|
|||
qux = [ "module.hidden=baz,value=bar" "module.hidden=fli,value=gne" ];
|
||||
}
|
||||
*/
|
||||
byName = attr: f: modules: foldl' (acc: module:
|
||||
foldl' (inner: name:
|
||||
inner // { ${name} = (acc.${name} or []) ++ (f module module.${attr}.${name}); }
|
||||
) acc (attrNames module.${attr})
|
||||
) {} modules;
|
||||
byName = attr: f: modules:
|
||||
foldl' (acc: module:
|
||||
acc // (mapAttrs (n: v:
|
||||
(acc.${n} or []) ++ f module v
|
||||
) module.${attr}
|
||||
)
|
||||
) {} modules;
|
||||
# an attrset 'name' => list of submodules that declare ‘name’.
|
||||
declsByName = byName "options"
|
||||
(module: option: [{ inherit (module) file; options = option; }])
|
||||
options;
|
||||
declsByName = byName "options" (module: option:
|
||||
[{ inherit (module) file; options = option; }]
|
||||
) options;
|
||||
# an attrset 'name' => list of submodules that define ‘name’.
|
||||
defnsByName = byName "config" (module: value:
|
||||
map (config: { inherit (module) file; inherit config; }) (pushDownProperties value)
|
||||
map (config: { inherit (module) file; inherit config; }) (pushDownProperties value)
|
||||
) configs;
|
||||
# extract the definitions for each loc
|
||||
defnsByName' = byName "config"
|
||||
(module: value: [{ inherit (module) file; inherit value; }])
|
||||
configs;
|
||||
defnsByName' = byName "config" (module: value:
|
||||
[{ inherit (module) file; inherit value; }]
|
||||
) configs;
|
||||
in
|
||||
(flip mapAttrs declsByName (name: decls:
|
||||
# We're descending into attribute ‘name’.
|
||||
|
@ -362,7 +364,6 @@ rec {
|
|||
values = defs''';
|
||||
inherit (defs'') highestPrio;
|
||||
};
|
||||
|
||||
defsFinal = defsFinal'.values;
|
||||
|
||||
# Type-check the remaining definitions, and merge them.
|
||||
|
@ -450,8 +451,7 @@ rec {
|
|||
|
||||
filterOverrides' = defs:
|
||||
let
|
||||
defaultPrio = 100;
|
||||
getPrio = def: if def.value._type or "" == "override" then def.value.priority else defaultPrio;
|
||||
getPrio = def: if def.value._type or "" == "override" then def.value.priority else defaultPriority;
|
||||
highestPrio = foldl' (prio: def: min (getPrio def) prio) 9999 defs;
|
||||
strip = def: if def.value._type or "" == "override" then def // { value = def.value.content; } else def;
|
||||
in {
|
||||
|
@ -476,22 +476,8 @@ rec {
|
|||
optionSet to options of type submodule. FIXME: remove
|
||||
eventually. */
|
||||
fixupOptionType = loc: opt:
|
||||
let
|
||||
options = opt.options or
|
||||
(throw "Option `${showOption loc'}' has type optionSet but has no option attribute, in ${showFiles opt.declarations}.");
|
||||
f = tp:
|
||||
let optionSetIn = type: (tp.name == type) && (tp.functor.wrapped.name == "optionSet");
|
||||
in
|
||||
if tp.name == "option set" || tp.name == "submodule" then
|
||||
throw "The option ${showOption loc} uses submodules without a wrapping type, in ${showFiles opt.declarations}."
|
||||
else if optionSetIn "attrsOf" then types.attrsOf (types.submodule options)
|
||||
else if optionSetIn "loaOf" then types.loaOf (types.submodule options)
|
||||
else if optionSetIn "listOf" then types.listOf (types.submodule options)
|
||||
else if optionSetIn "nullOr" then types.nullOr (types.submodule options)
|
||||
else tp;
|
||||
in
|
||||
if opt.type.getSubModules or null == null
|
||||
then opt // { type = f (opt.type or types.unspecified); }
|
||||
if opt.type.getSubModules or null == null
|
||||
then opt // { type = opt.type or types.unspecified; }
|
||||
else opt // { type = opt.type.substSubModules opt.options; options = []; };
|
||||
|
||||
|
||||
|
@ -534,6 +520,8 @@ rec {
|
|||
mkBefore = mkOrder 500;
|
||||
mkAfter = mkOrder 1500;
|
||||
|
||||
# The default priority for things that don't have a priority specified.
|
||||
defaultPriority = 100;
|
||||
|
||||
# Convenient property used to transfer all definitions and their
|
||||
# properties from one option to another. This property is useful for
|
||||
|
@ -556,8 +544,20 @@ rec {
|
|||
#
|
||||
mkAliasDefinitions = mkAliasAndWrapDefinitions id;
|
||||
mkAliasAndWrapDefinitions = wrap: option:
|
||||
mkIf (isOption option && option.isDefined) (wrap (mkMerge option.definitions));
|
||||
mkAliasIfDef option (wrap (mkMerge option.definitions));
|
||||
|
||||
# Similar to mkAliasAndWrapDefinitions but copies over the priority from the
|
||||
# option as well.
|
||||
#
|
||||
# If a priority is not set, it assumes a priority of defaultPriority.
|
||||
mkAliasAndWrapDefsWithPriority = wrap: option:
|
||||
let
|
||||
prio = option.highestPrio or defaultPriority;
|
||||
defsWithPrio = map (mkOverride prio) option.definitions;
|
||||
in mkAliasIfDef option (wrap (mkMerge defsWithPrio));
|
||||
|
||||
mkAliasIfDef = option:
|
||||
mkIf (isOption option && option.isDefined);
|
||||
|
||||
/* Compatibility. */
|
||||
fixMergeModules = modules: args: evalModules { inherit modules args; check = false; };
|
||||
|
@ -690,7 +690,16 @@ rec {
|
|||
use = id;
|
||||
};
|
||||
|
||||
doRename = { from, to, visible, warn, use }:
|
||||
/* Like ‘mkAliasOptionModule’, but copy over the priority of the option as well. */
|
||||
mkAliasOptionModuleWithPriority = from: to: doRename {
|
||||
inherit from to;
|
||||
visible = true;
|
||||
warn = false;
|
||||
use = id;
|
||||
withPriority = true;
|
||||
};
|
||||
|
||||
doRename = { from, to, visible, warn, use, withPriority ? false }:
|
||||
{ config, options, ... }:
|
||||
let
|
||||
fromOpt = getAttrFromPath from options;
|
||||
|
@ -708,7 +717,9 @@ rec {
|
|||
warnings = optional (warn && fromOpt.isDefined)
|
||||
"The option `${showOption from}' defined in ${showFiles fromOpt.files} has been renamed to `${showOption to}'.";
|
||||
}
|
||||
(mkAliasAndWrapDefinitions (setAttrByPath to) fromOpt)
|
||||
(if withPriority
|
||||
then mkAliasAndWrapDefsWithPriority (setAttrByPath to) fromOpt
|
||||
else mkAliasAndWrapDefinitions (setAttrByPath to) fromOpt)
|
||||
];
|
||||
};
|
||||
|
||||
|
|
|
@ -48,8 +48,6 @@ rec {
|
|||
visible ? null,
|
||||
# Whether the option can be set only once
|
||||
readOnly ? null,
|
||||
# Obsolete, used by types.optionSet.
|
||||
options ? null
|
||||
} @ attrs:
|
||||
attrs // { _type = "option"; };
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@ rec {
|
|||
"netbsd" = "NetBSD";
|
||||
"freebsd" = "FreeBSD";
|
||||
"openbsd" = "OpenBSD";
|
||||
"wasm" = "Wasm";
|
||||
}.${final.parsed.kernel.name} or null;
|
||||
|
||||
# uname -p
|
||||
|
|
|
@ -9,7 +9,8 @@ let abis = lib.mapAttrs (_: abi: builtins.removeAttrs abi [ "assertions" ]) abis
|
|||
rec {
|
||||
patterns = rec {
|
||||
isi686 = { cpu = cpuTypes.i686; };
|
||||
isx86_64 = { cpu = cpuTypes.x86_64; };
|
||||
isx86_32 = { cpu = { family = "x86"; bits = 32; }; };
|
||||
isx86_64 = { cpu = { family = "x86"; bits = 64; }; };
|
||||
isPowerPC = { cpu = cpuTypes.powerpc; };
|
||||
isPower = { cpu = { family = "power"; }; };
|
||||
isx86 = { cpu = { family = "x86"; }; };
|
||||
|
|
|
@ -467,6 +467,8 @@ rec {
|
|||
};
|
||||
|
||||
selectBySystem = system: {
|
||||
"i486-linux" = pc32;
|
||||
"i586-linux" = pc32;
|
||||
"i686-linux" = pc32;
|
||||
"x86_64-linux" = pc64;
|
||||
"armv5tel-linux" = sheevaplug;
|
||||
|
|
|
@ -149,6 +149,12 @@ checkConfigOutput "1 2 3 4 5 6 7 8 9 10" config.result ./loaOf-with-long-list.ni
|
|||
# Check loaOf with many merges of lists.
|
||||
checkConfigOutput "1 2 3 4 5 6 7 8 9 10" config.result ./loaOf-with-many-list-merges.nix
|
||||
|
||||
# Check mkAliasOptionModuleWithPriority.
|
||||
checkConfigOutput "true" config.enable ./alias-with-priority.nix
|
||||
checkConfigOutput "true" config.enableAlias ./alias-with-priority.nix
|
||||
checkConfigOutput "false" config.enable ./alias-with-priority-can-override.nix
|
||||
checkConfigOutput "false" config.enableAlias ./alias-with-priority-can-override.nix
|
||||
|
||||
cat <<EOF
|
||||
====== module tests ======
|
||||
$pass Pass
|
||||
|
|
52
lib/tests/modules/alias-with-priority-can-override.nix
Normal file
52
lib/tests/modules/alias-with-priority-can-override.nix
Normal file
|
@ -0,0 +1,52 @@
|
|||
# This is a test to show that mkAliasOptionModule sets the priority correctly
|
||||
# for aliased options.
|
||||
|
||||
{ config, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
options = {
|
||||
# A simple boolean option that can be enabled or disabled.
|
||||
enable = lib.mkOption {
|
||||
type = types.nullOr types.bool;
|
||||
default = null;
|
||||
example = true;
|
||||
description = ''
|
||||
Some descriptive text
|
||||
'';
|
||||
};
|
||||
|
||||
# mkAliasOptionModule sets warnings, so this has to be defined.
|
||||
warnings = mkOption {
|
||||
internal = true;
|
||||
default = [];
|
||||
type = types.listOf types.str;
|
||||
example = [ "The `foo' service is deprecated and will go away soon!" ];
|
||||
description = ''
|
||||
This option allows modules to show warnings to users during
|
||||
the evaluation of the system configuration.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
imports = [
|
||||
# Create an alias for the "enable" option.
|
||||
(mkAliasOptionModuleWithPriority [ "enableAlias" ] [ "enable" ])
|
||||
|
||||
# Disable the aliased option, but with a default (low) priority so it
|
||||
# should be able to be overridden by the next import.
|
||||
( { config, lib, ... }:
|
||||
{
|
||||
enableAlias = lib.mkForce false;
|
||||
}
|
||||
)
|
||||
|
||||
# Enable the normal (non-aliased) option.
|
||||
( { config, lib, ... }:
|
||||
{
|
||||
enable = true;
|
||||
}
|
||||
)
|
||||
];
|
||||
}
|
52
lib/tests/modules/alias-with-priority.nix
Normal file
52
lib/tests/modules/alias-with-priority.nix
Normal file
|
@ -0,0 +1,52 @@
|
|||
# This is a test to show that mkAliasOptionModule sets the priority correctly
|
||||
# for aliased options.
|
||||
|
||||
{ config, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
options = {
|
||||
# A simple boolean option that can be enabled or disabled.
|
||||
enable = lib.mkOption {
|
||||
type = types.nullOr types.bool;
|
||||
default = null;
|
||||
example = true;
|
||||
description = ''
|
||||
Some descriptive text
|
||||
'';
|
||||
};
|
||||
|
||||
# mkAliasOptionModule sets warnings, so this has to be defined.
|
||||
warnings = mkOption {
|
||||
internal = true;
|
||||
default = [];
|
||||
type = types.listOf types.str;
|
||||
example = [ "The `foo' service is deprecated and will go away soon!" ];
|
||||
description = ''
|
||||
This option allows modules to show warnings to users during
|
||||
the evaluation of the system configuration.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
imports = [
|
||||
# Create an alias for the "enable" option.
|
||||
(mkAliasOptionModuleWithPriority [ "enableAlias" ] [ "enable" ])
|
||||
|
||||
# Disable the aliased option, but with a default (low) priority so it
|
||||
# should be able to be overridden by the next import.
|
||||
( { config, lib, ... }:
|
||||
{
|
||||
enableAlias = lib.mkDefault false;
|
||||
}
|
||||
)
|
||||
|
||||
# Enable the normal (non-aliased) option.
|
||||
( { config, lib, ... }:
|
||||
{
|
||||
enable = true;
|
||||
}
|
||||
)
|
||||
];
|
||||
}
|
|
@ -284,8 +284,7 @@ rec {
|
|||
(mergeDefinitions (loc ++ [name]) elemType defs).optionalValue
|
||||
)
|
||||
# Push down position info.
|
||||
(map (def: listToAttrs (mapAttrsToList (n: def':
|
||||
{ name = n; value = { inherit (def) file; value = def'; }; }) def.value)) defs)));
|
||||
(map (def: mapAttrs (n: v: { inherit (def) file; value = v; }) def.value) defs)));
|
||||
getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["<name>"]);
|
||||
getSubModules = elemType.getSubModules;
|
||||
substSubModules = m: attrsOf (elemType.substSubModules m);
|
||||
|
@ -470,10 +469,7 @@ rec {
|
|||
# Obsolete alternative to configOf. It takes its option
|
||||
# declarations from the ‘options’ attribute of containing option
|
||||
# declaration.
|
||||
optionSet = mkOptionType {
|
||||
name = builtins.trace "types.optionSet is deprecated; use types.submodule instead" "optionSet";
|
||||
description = "option set";
|
||||
};
|
||||
optionSet = builtins.throw "types.optionSet is deprecated; use types.submodule instead" "optionSet";
|
||||
|
||||
# Augment the given type with an additional type check function.
|
||||
addCheck = elemType: check: elemType // { check = x: elemType.check x && check x; };
|
||||
|
|
|
@ -1,21 +1,41 @@
|
|||
/* List of NixOS maintainers.
|
||||
|
||||
handle = {
|
||||
name = "Real name";
|
||||
# Required
|
||||
name = "Your name";
|
||||
email = "address@example.org";
|
||||
|
||||
# Optional
|
||||
github = "GithubUsername";
|
||||
keys = [{
|
||||
longkeyid = "rsa2048/0x0123456789ABCDEF";
|
||||
fingerprint = "AAAA BBBB CCCC DDDD EEEE FFFF 0000 1111 2222 3333";
|
||||
}];
|
||||
};
|
||||
|
||||
where `name` is your real name, `email` is your maintainer email
|
||||
address and `github` is your GitHub handle (as it appears in the
|
||||
URL of your profile page, `https://github.com/<userhandle>`).
|
||||
address
|
||||
The only required fields are `name` and `email`.
|
||||
where
|
||||
|
||||
- `handle` is the handle you are going to use in nixpkgs expressions,
|
||||
- `name` is your, preferably real, name,
|
||||
- `email` is your maintainer email address, and
|
||||
- `github` is your GitHub handle (as it appears in the URL of your profile page, `https://github.com/<userhandle>`),
|
||||
- `keys` is a list of your PGP/GPG key IDs and fingerprints.
|
||||
|
||||
`handle == github` is strongly preferred whenever `github` is an acceptable attribute name and is short and convenient.
|
||||
|
||||
Add PGP/GPG keys only if you actually use them to sign commits and/or mail.
|
||||
|
||||
To get the required PGP/GPG values for a key run
|
||||
```shell
|
||||
gpg --keyid-format 0xlong --fingerprint <email> | head -n 2
|
||||
```
|
||||
|
||||
!!! Note that PGP/GPG values stored here are for informational purposes only, don't use this file as a source of truth.
|
||||
|
||||
More fields may be added in the future.
|
||||
|
||||
Please keep the list alphabetically sorted.
|
||||
See `../maintainers/scripts/check-maintainer-github-handles.sh`
|
||||
for an example on how to work with this data.
|
||||
See `./scripts/check-maintainer-github-handles.sh` for an example on how to work with this data.
|
||||
*/
|
||||
{
|
||||
"1000101" = {
|
||||
|
@ -48,6 +68,11 @@
|
|||
github = "abbradar";
|
||||
name = "Nikolay Amiantov";
|
||||
};
|
||||
abhi18av = {
|
||||
email = "abhi18av@gmail.com";
|
||||
github = "abhi18av";
|
||||
name = "Abhinav Sharma";
|
||||
};
|
||||
abigailbuccaneer = {
|
||||
email = "abigailbuccaneer@gmail.com";
|
||||
github = "abigailbuccaneer";
|
||||
|
@ -216,8 +241,13 @@
|
|||
email = "nix-commits@lists.science.uu.nl";
|
||||
name = "Nix Committers";
|
||||
};
|
||||
allonsy = {
|
||||
email = "linuxbash8@gmail.com";
|
||||
github = "allonsy";
|
||||
name = "Alec Snyder";
|
||||
};
|
||||
alunduil = {
|
||||
email = "alunduil@alunduil.com";
|
||||
email = "alunduil@gmail.com";
|
||||
github = "alunduil";
|
||||
name = "Alex Brandt";
|
||||
};
|
||||
|
@ -341,6 +371,11 @@
|
|||
github = "apeyroux";
|
||||
name = "Alexandre Peyroux";
|
||||
};
|
||||
ar1a = {
|
||||
email = "aria@ar1as.space";
|
||||
github = "ar1a";
|
||||
name = "Aria Edmonds";
|
||||
};
|
||||
arcadio = {
|
||||
email = "arc@well.ox.ac.uk";
|
||||
github = "arcadio";
|
||||
|
@ -475,6 +510,11 @@
|
|||
github = "bandresen";
|
||||
name = "Benjamin Andresen";
|
||||
};
|
||||
baracoder = {
|
||||
email = "baracoder@googlemail.com";
|
||||
github = "baracoder";
|
||||
name = "Herman Fries";
|
||||
};
|
||||
barrucadu = {
|
||||
email = "mike@barrucadu.co.uk";
|
||||
github = "barrucadu";
|
||||
|
@ -753,6 +793,11 @@
|
|||
github = "caugner";
|
||||
name = "Claas Augner";
|
||||
};
|
||||
cbley = {
|
||||
email = "claudio.bley@gmail.com";
|
||||
github = "avdv";
|
||||
name = "Claudio Bley";
|
||||
};
|
||||
cdepillabout = {
|
||||
email = "cdep.illabout@gmail.com";
|
||||
github = "cdepillabout";
|
||||
|
@ -862,6 +907,11 @@
|
|||
github = "cko";
|
||||
name = "Christine Koppelt";
|
||||
};
|
||||
clacke = {
|
||||
email = "claes.wallin@greatsinodevelopment.com";
|
||||
github = "clacke";
|
||||
name = "Claes Wallin";
|
||||
};
|
||||
cleverca22 = {
|
||||
email = "cleverca22@gmail.com";
|
||||
github = "cleverca22";
|
||||
|
@ -1235,6 +1285,11 @@
|
|||
github = "eadwu";
|
||||
name = "Edmund Wu";
|
||||
};
|
||||
eamsden = {
|
||||
email = "edward@blackriversoft.com";
|
||||
github = "eamsden";
|
||||
name = "Edward Amsden";
|
||||
};
|
||||
earldouglas = {
|
||||
email = "james@earldouglas.com";
|
||||
github = "earldouglas";
|
||||
|
@ -1260,6 +1315,11 @@
|
|||
github = "edef1c";
|
||||
name = "edef";
|
||||
};
|
||||
embr = {
|
||||
email = "hi@liclac.eu";
|
||||
github = "liclac";
|
||||
name = "embr";
|
||||
};
|
||||
ederoyd46 = {
|
||||
email = "matt@ederoyd.co.uk";
|
||||
github = "ederoyd46";
|
||||
|
@ -1397,6 +1457,10 @@
|
|||
email = "justin.humm@posteo.de";
|
||||
github = "erictapen";
|
||||
name = "Justin Humm";
|
||||
keys = [{
|
||||
longkeyid = "rsa4096/0x438871E000AA178E";
|
||||
fingerprint = "984E 4BAD 9127 4D0E AE47 FF03 4388 71E0 00AA 178E";
|
||||
}];
|
||||
};
|
||||
erikryb = {
|
||||
email = "erik.rybakken@math.ntnu.no";
|
||||
|
@ -1426,6 +1490,10 @@
|
|||
email = "elis@hirwing.se";
|
||||
github = "etu";
|
||||
name = "Elis Hirwing";
|
||||
keys = [{
|
||||
longkeyid = "rsa4096/0xD57EFA625C9A925F";
|
||||
fingerprint = "67FE 98F2 8C44 CF22 1828 E12F D57E FA62 5C9A 925F";
|
||||
}];
|
||||
};
|
||||
evck = {
|
||||
email = "eric@evenchick.com";
|
||||
|
@ -1452,6 +1520,11 @@
|
|||
github = "expipiplus1";
|
||||
name = "Joe Hermaszewski";
|
||||
};
|
||||
eyjhb = {
|
||||
email = "eyjhbb@gmail.com";
|
||||
github = "eyJhb";
|
||||
name = "eyJhb";
|
||||
};
|
||||
f--t = {
|
||||
email = "git@f-t.me";
|
||||
github = "f--t";
|
||||
|
@ -1483,7 +1556,7 @@
|
|||
name = "Felipe Espinoza";
|
||||
};
|
||||
fgaz = {
|
||||
email = "francygazz@gmail.com";
|
||||
email = "fgaz@fgaz.me";
|
||||
github = "fgaz";
|
||||
name = "Francesco Gazzetta";
|
||||
};
|
||||
|
@ -1581,6 +1654,11 @@
|
|||
email = "eocallaghan@alterapraxis.com";
|
||||
name = "Edward O'Callaghan";
|
||||
};
|
||||
fusion809 = {
|
||||
email = "brentonhorne77@gmail.com";
|
||||
github = "fusion809";
|
||||
name = "Brenton Horne";
|
||||
};
|
||||
fuuzetsu = {
|
||||
email = "fuuzetsu@fuuzetsu.co.uk";
|
||||
github = "fuuzetsu";
|
||||
|
@ -1725,6 +1803,11 @@
|
|||
github = "dguibert";
|
||||
name = "David Guibert";
|
||||
};
|
||||
groodt = {
|
||||
email = "groodt@gmail.com";
|
||||
github = "groodt";
|
||||
name = "Greg Roodt";
|
||||
};
|
||||
guibou = {
|
||||
email = "guillaum.bouchard@gmail.com";
|
||||
github = "guibou";
|
||||
|
@ -1754,6 +1837,11 @@
|
|||
email = "commits@schurr.at";
|
||||
github = "hansjoergschurr";
|
||||
name = "Hans-Jörg Schurr";
|
||||
};
|
||||
HaoZeke = {
|
||||
email = "r95g10@gmail.com";
|
||||
github = "haozeke";
|
||||
name = "Rohit Goswami";
|
||||
};
|
||||
haslersn = {
|
||||
email = "haslersn@fius.informatik.uni-stuttgart.de";
|
||||
|
@ -1879,6 +1967,11 @@
|
|||
github = "ikervagyok";
|
||||
name = "Balázs Lengyel";
|
||||
};
|
||||
ilikeavocadoes = {
|
||||
email = "ilikeavocadoes@hush.com";
|
||||
github = "ilikeavocadoes";
|
||||
name = "Lassi Haasio";
|
||||
};
|
||||
illegalprime = {
|
||||
email = "themichaeleden@gmail.com";
|
||||
github = "illegalprime";
|
||||
|
@ -1909,6 +2002,11 @@
|
|||
github = "infinisil";
|
||||
name = "Silvan Mosberger";
|
||||
};
|
||||
ingenieroariel = {
|
||||
email = "ariel@nunez.co";
|
||||
github = "ingenieroariel";
|
||||
name = "Ariel Nunez";
|
||||
};
|
||||
ironpinguin = {
|
||||
email = "michele@catalano.de";
|
||||
github = "ironpinguin";
|
||||
|
@ -1923,6 +2021,15 @@
|
|||
email = "tkatchev@gmail.com";
|
||||
name = "Ivan Tkatchev";
|
||||
};
|
||||
ivegotasthma = {
|
||||
email = "ivegotasthma@protonmail.com";
|
||||
github = "ivegotasthma";
|
||||
name = "John Doe";
|
||||
keys = [{
|
||||
longkeyid = "rsa4096/09AC52AEA87817A4";
|
||||
fingerprint = "4008 2A5B 56A4 79B9 83CB 95FD 09AC 52AE A878 17A4";
|
||||
}];
|
||||
};
|
||||
ixmatus = {
|
||||
email = "parnell@digitalmentat.com";
|
||||
github = "ixmatus";
|
||||
|
@ -1953,6 +2060,11 @@
|
|||
github = "jakelogemann";
|
||||
name = "Jake Logemann";
|
||||
};
|
||||
jakewaksbaum = {
|
||||
email = "jake.waksbaum@gmail.com";
|
||||
github = "jbaum98";
|
||||
name = "Jake Waksbaum";
|
||||
};
|
||||
jammerful = {
|
||||
email = "jammerful@gmail.com";
|
||||
github = "jammerful";
|
||||
|
@ -2175,6 +2287,11 @@
|
|||
github = "joncojonathan";
|
||||
name = "Jonathan Haddock";
|
||||
};
|
||||
jorsn = {
|
||||
name = "Johannes Rosenberger";
|
||||
email = "johannes@jorsn.eu";
|
||||
github = "jorsn";
|
||||
};
|
||||
jpdoyle = {
|
||||
email = "joethedoyle@gmail.com";
|
||||
github = "jpdoyle";
|
||||
|
@ -2818,6 +2935,11 @@
|
|||
email = "joerg@thalheim.io";
|
||||
github = "mic92";
|
||||
name = "Jörg Thalheim";
|
||||
keys = [{
|
||||
# compare with https://keybase.io/Mic92
|
||||
longkeyid = "rsa4096/0x003F2096411B5F92";
|
||||
fingerprint = "3DEE 1C55 6E1C 3DC5 54F5 875A 003F 2096 411B 5F92";
|
||||
}];
|
||||
};
|
||||
michaelpj = {
|
||||
email = "michaelpj@gmail.com";
|
||||
|
@ -3062,6 +3184,11 @@
|
|||
github = "nadrieril";
|
||||
name = "Nadrieril Feneanar";
|
||||
};
|
||||
nalbyuites = {
|
||||
email = "ashijit007@gmail.com";
|
||||
github = "nalbyuites";
|
||||
name = "Ashijit Pramanik";
|
||||
};
|
||||
namore = {
|
||||
email = "namor@hemio.de";
|
||||
github = "namore";
|
||||
|
@ -3106,6 +3233,11 @@
|
|||
github = "nequissimus";
|
||||
name = "Tim Steinbach";
|
||||
};
|
||||
netixx = {
|
||||
email = "dev.espinetfrancois@gmail.com";
|
||||
github = "netixx";
|
||||
name = "François Espinet";
|
||||
};
|
||||
nikitavoloboev = {
|
||||
email = "nikita.voloboev@gmail.com";
|
||||
github = "nikitavoloboev";
|
||||
|
@ -3220,6 +3352,11 @@
|
|||
github = "nyarly";
|
||||
name = "Judson Lester";
|
||||
};
|
||||
nzhang-zh = {
|
||||
email = "n.zhang.hp.au@gmail.com";
|
||||
github = "nzhang-zh";
|
||||
name = "Ning Zhang";
|
||||
};
|
||||
obadz = {
|
||||
email = "obadz-nixos@obadz.com";
|
||||
github = "obadz";
|
||||
|
@ -3298,6 +3435,10 @@
|
|||
email = "oxij@oxij.org";
|
||||
github = "oxij";
|
||||
name = "Jan Malakhovski";
|
||||
keys = [{
|
||||
longkeyid = "rsa2048/0x0E6CA66E5C557AA8";
|
||||
fingerprint = "514B B966 B46E 3565 0508 86E8 0E6C A66E 5C55 7AA8";
|
||||
}];
|
||||
};
|
||||
oyren = {
|
||||
email = "m.scheuren@oyra.eu";
|
||||
|
@ -3379,6 +3520,11 @@
|
|||
github = "pesterhazy";
|
||||
name = "Paulus Esterhazy";
|
||||
};
|
||||
petabyteboy = {
|
||||
email = "me@pbb.lc";
|
||||
github = "petabyteboy";
|
||||
name = "Milan Pässler";
|
||||
};
|
||||
peterhoeg = {
|
||||
email = "peter@hoeg.com";
|
||||
github = "peterhoeg";
|
||||
|
@ -3522,6 +3668,14 @@
|
|||
email = "dev.primeos@gmail.com";
|
||||
github = "primeos";
|
||||
name = "Michael Weiss";
|
||||
keys = [
|
||||
{ longkeyid = "ed25519/0x130826A6C2A389FD"; # Git only
|
||||
fingerprint = "86A7 4A55 07D0 58D1 322E 37FD 1308 26A6 C2A3 89FD";
|
||||
}
|
||||
{ longkeyid = "rsa3072/0xBCA9943DD1DF4C04"; # Email, etc.
|
||||
fingerprint = "AF85 991C C950 49A2 4205 1933 BCA9 943D D1DF 4C04";
|
||||
}
|
||||
];
|
||||
};
|
||||
Profpatsch = {
|
||||
email = "mail@profpatsch.de";
|
||||
|
@ -3559,9 +3713,14 @@
|
|||
};
|
||||
psyanticy = {
|
||||
email = "iuns@outlook.fr";
|
||||
github = "Assassinkin";
|
||||
github = "PsyanticY";
|
||||
name = "Psyanticy";
|
||||
};
|
||||
ptival = {
|
||||
email = "valentin.robert.42@gmail.com";
|
||||
github = "Ptival";
|
||||
name = "Valentin Robert";
|
||||
};
|
||||
puffnfresh = {
|
||||
email = "brian@brianmckenna.org";
|
||||
github = "puffnfresh";
|
||||
|
@ -3590,6 +3749,10 @@
|
|||
email = "hi@alyssa.is";
|
||||
github = "alyssais";
|
||||
name = "Alyssa Ross";
|
||||
keys = [{
|
||||
longkeyid = "rsa4096/736CCDF9EF51BD97";
|
||||
fingerprint = "7573 56D7 79BB B888 773E 415E 736C CDF9 EF51 BD97";
|
||||
}];
|
||||
};
|
||||
ragge = {
|
||||
email = "r.dahlen@gmail.com";
|
||||
|
@ -3910,6 +4073,11 @@
|
|||
github = "sauyon";
|
||||
name = "Sauyon Lee";
|
||||
};
|
||||
sb0 = {
|
||||
email = "sb@m-labs.hk";
|
||||
github = "sbourdeauducq";
|
||||
name = "Sébastien Bourdeauducq";
|
||||
};
|
||||
sboosali = {
|
||||
email = "SamBoosalis@gmail.com";
|
||||
github = "sboosali";
|
||||
|
@ -4033,6 +4201,11 @@
|
|||
github = "shlevy";
|
||||
name = "Shea Levy";
|
||||
};
|
||||
shou = {
|
||||
email = "x+g@shou.io";
|
||||
github = "Shou";
|
||||
name = "Benedict Aas";
|
||||
};
|
||||
siddharthist = {
|
||||
email = "langston.barrett@gmail.com";
|
||||
github = "siddharthist";
|
||||
|
@ -4100,6 +4273,10 @@
|
|||
email = "sebastien.maret@icloud.com";
|
||||
github = "smaret";
|
||||
name = "Sébastien Maret";
|
||||
keys = [{
|
||||
longkeyid = "rsa4096/0x86E30E5A0F5FC59C";
|
||||
fingerprint = "4242 834C D401 86EF 8281 4093 86E3 0E5A 0F5F C59C";
|
||||
}];
|
||||
};
|
||||
smironov = {
|
||||
email = "grrwlf@gmail.com";
|
||||
|
@ -4286,6 +4463,15 @@
|
|||
github = "t184256";
|
||||
name = "Alexander Sosedkin";
|
||||
};
|
||||
tadeokondrak = {
|
||||
email = "me@tadeo.ca";
|
||||
github = "tadeokondrak";
|
||||
name = "Tadeo Kondrak";
|
||||
keys = [{
|
||||
longkeyid = "ed25519/0xFBE607FCC49516D3";
|
||||
fingerprint = "0F2B C0C7 E77C 5B42 AC5B 4C18 FBE6 07FC C495 16D3";
|
||||
}];
|
||||
};
|
||||
tadfisher = {
|
||||
email = "tadfisher@gmail.com";
|
||||
github = "tadfisher";
|
||||
|
@ -4351,6 +4537,11 @@
|
|||
github = "tazjin";
|
||||
name = "Vincent Ambo";
|
||||
};
|
||||
tbenst = {
|
||||
email = "nix@tylerbenster.com";
|
||||
github = "tbenst";
|
||||
name = "Tyler Benster";
|
||||
};
|
||||
teh = {
|
||||
email = "tehunger@gmail.com";
|
||||
github = "teh";
|
||||
|
@ -4492,7 +4683,7 @@
|
|||
name = "Thomas Bereknyei";
|
||||
};
|
||||
tomsmeets = {
|
||||
email = "tom@tsmeets.nl";
|
||||
email = "tom.tsmeets@gmail.com";
|
||||
github = "tomsmeets";
|
||||
name = "Tom Smeets";
|
||||
};
|
||||
|
@ -4536,7 +4727,7 @@
|
|||
name = "Thomas Tuegel";
|
||||
};
|
||||
tv = {
|
||||
email = "tv@shackspace.de";
|
||||
email = "tv@krebsco.de";
|
||||
github = "4z3";
|
||||
name = "Tomislav Viljetić";
|
||||
};
|
||||
|
@ -4786,11 +4977,6 @@
|
|||
github = "wjlroe";
|
||||
name = "William Roe";
|
||||
};
|
||||
wkennington = {
|
||||
email = "william@wkennington.com";
|
||||
github = "wkennington";
|
||||
name = "William A. Kennington III";
|
||||
};
|
||||
wmertens = {
|
||||
email = "Wout.Mertens@gmail.com";
|
||||
github = "wmertens";
|
||||
|
@ -5015,4 +5201,9 @@
|
|||
github = "mredaelli";
|
||||
name = "Massimo Redaelli";
|
||||
};
|
||||
shmish111 = {
|
||||
email = "shmish111@gmail.com";
|
||||
github = "shmish111";
|
||||
name = "David Smith";
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#! /usr/bin/env nix-shell
|
||||
#! nix-shell -i perl -p perl perlPackages.NetAmazonS3 perlPackages.FileSlurp nixUnstable nixUnstable.perl-bindings
|
||||
#! nix-shell -i perl -p perl perlPackages.NetAmazonS3 perlPackages.FileSlurp perlPackages.JSON perlPackages.LWPProtocolHttps nixUnstable nixUnstable.perl-bindings
|
||||
|
||||
# This command uploads tarballs to tarballs.nixos.org, the
|
||||
# content-addressed cache used by fetchurl as a fallback for when
|
||||
|
@ -101,8 +101,8 @@ sub uploadFile {
|
|||
my ($name, $dest) = @_;
|
||||
#print STDERR "linking $name to $dest...\n";
|
||||
$bucket->add_key($name, "", {
|
||||
'x-amz-website-redirect-location' => "/" . $dest,
|
||||
'x-amz-acl' => "public-read"
|
||||
'x-amz-website-redirect-location' => "/" . $dest,
|
||||
'x-amz-acl' => "public-read"
|
||||
})
|
||||
or die "failed to create redirect from $name to $dest\n";
|
||||
$cache{$name} = 1;
|
||||
|
@ -116,8 +116,8 @@ sub uploadFile {
|
|||
# Upload the file as sha512/<hash-in-base-16>.
|
||||
print STDERR "uploading $fn to $mainKey...\n";
|
||||
$bucket->add_key_filename($mainKey, $fn, {
|
||||
'x-amz-meta-original-name' => $name,
|
||||
'x-amz-acl' => "public-read"
|
||||
'x-amz-meta-original-name' => $name,
|
||||
'x-amz-acl' => "public-read"
|
||||
})
|
||||
or die "failed to upload $fn to $mainKey\n";
|
||||
$cache{$mainKey} = 1;
|
||||
|
|
|
@ -4,4 +4,8 @@ if [[ -z "$VERBOSE" ]]; then
|
|||
echo "You may set VERBOSE=1 to see debug output or to any other non-empty string to make this script completely silent"
|
||||
fi
|
||||
unset HOME NIXPKGS_CONFIG # Force empty config
|
||||
|
||||
# With the default heap size (380MB), nix-instantiate fails:
|
||||
# Too many heap sections: Increase MAXHINCR or MAX_HEAP_SECTS
|
||||
export GC_INITIAL_HEAP_SIZE=${GC_INITIAL_HEAP_SIZE:-2000000000} # 2GB
|
||||
nix-instantiate --strict --eval-only --xml --show-trace "$(dirname "$0")"/eval-release.nix 2>&1 > /dev/null
|
|
@ -31,7 +31,7 @@ let
|
|||
if !canEval x then []
|
||||
else if isDerivation x then optional (canEval x.drvPath) x
|
||||
else if isList x then concatLists (map derivationsIn' x)
|
||||
else if isAttrs x then concatLists (mapAttrsToList (n: v: derivationsIn' v) x)
|
||||
else if isAttrs x then concatLists (mapAttrsToList (n: v: addErrorContext "while finding tarballs in '${n}':" (derivationsIn' v)) x)
|
||||
else [ ];
|
||||
|
||||
keyDrv = drv: if canEval drv.drvPath then { key = drv.drvPath; value = drv; } else { };
|
||||
|
|
32
maintainers/scripts/luarocks-packages.csv
Normal file
32
maintainers/scripts/luarocks-packages.csv
Normal file
|
@ -0,0 +1,32 @@
|
|||
ansicolors,
|
||||
argparse,
|
||||
basexx,
|
||||
cqueues
|
||||
dkjson
|
||||
fifo
|
||||
inspect
|
||||
lgi
|
||||
lpeg_patterns
|
||||
lpty
|
||||
lrexlib-gnu,
|
||||
lrexlib-posix,
|
||||
ltermbox,
|
||||
lua-cmsgpack,
|
||||
lua_cliargs,
|
||||
lua-iconv,
|
||||
lua-term,
|
||||
luabitop,
|
||||
luaevent,
|
||||
luacheck
|
||||
luaffi,http://luarocks.org/dev,
|
||||
luuid,
|
||||
penlight,
|
||||
say,
|
||||
luv,
|
||||
luasystem,
|
||||
mediator_lua,http://luarocks.org/manifests/teto
|
||||
mpack,http://luarocks.org/manifests/teto
|
||||
nvim-client,http://luarocks.org/manifests/teto
|
||||
busted,http://luarocks.org/manifests/teto
|
||||
luassert,http://luarocks.org/manifests/teto
|
||||
coxpcall,https://luarocks.org/manifests/hisham,1.17.0-1
|
|
112
maintainers/scripts/update-luarocks-packages
Executable file
112
maintainers/scripts/update-luarocks-packages
Executable file
|
@ -0,0 +1,112 @@
|
|||
#!/usr/bin/env nix-shell
|
||||
#!nix-shell -p nix-prefetch-scripts luarocks-nix -i bash
|
||||
|
||||
# You'll likely want to use
|
||||
# ``
|
||||
# nixpkgs $ maintainers/scripts/update-luarocks-packages pkgs/development/lua-modules/generated-packages.nix
|
||||
# ``
|
||||
# to update all libraries in that folder.
|
||||
# to debug, redirect stderr to stdout with 2>&1
|
||||
|
||||
|
||||
# stop the script upon C-C
|
||||
set -eu -o pipefail
|
||||
|
||||
if [ $# -lt 1 ]; then
|
||||
print_help
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CSV_FILE="maintainers/scripts/luarocks-packages.csv"
|
||||
TMP_FILE="$(mktemp)"
|
||||
|
||||
exit_trap()
|
||||
{
|
||||
local lc="$BASH_COMMAND" rc=$?
|
||||
test $rc -eq 0 || echo -e "*** error $rc: $lc.\nGenerated temporary file in $TMP_FILE" >&2
|
||||
}
|
||||
trap exit_trap EXIT
|
||||
|
||||
print_help() {
|
||||
echo "Usage: $0 <GENERATED_FILE>"
|
||||
echo "(most likely pkgs/development/lua-modules/generated-packages.nix)"
|
||||
echo ""
|
||||
echo " -c <CSV_FILE> to set the list of luarocks package to generate"
|
||||
exit 1
|
||||
}
|
||||
|
||||
|
||||
while getopts ":hc:" opt; do
|
||||
case $opt in
|
||||
h)
|
||||
print_help
|
||||
;;
|
||||
c)
|
||||
echo "Loading package list from $OPTARG !" >&2
|
||||
CSV_FILE="$OPTARG"
|
||||
;;
|
||||
\?)
|
||||
echo "Invalid option: -$OPTARG" >&2
|
||||
;;
|
||||
esac
|
||||
shift $((OPTIND-1))
|
||||
done
|
||||
|
||||
GENERATED_NIXFILE="$1"
|
||||
|
||||
HEADER="
|
||||
/* ${GENERATED_NIXFILE} is an auto-generated file -- DO NOT EDIT!
|
||||
Regenerate it with:
|
||||
nixpkgs$ ${0} ${GENERATED_NIXFILE}
|
||||
|
||||
These packages are manually refined in lua-overrides.nix
|
||||
*/
|
||||
{ self, lua, stdenv, fetchurl, fetchgit, pkgs, ... } @ args:
|
||||
self: super:
|
||||
with self;
|
||||
{
|
||||
"
|
||||
|
||||
FOOTER="
|
||||
}
|
||||
/* GENERATED */
|
||||
"
|
||||
|
||||
|
||||
function convert_pkg () {
|
||||
pkg="$1"
|
||||
server=""
|
||||
if [ ! -z "$2" ]; then
|
||||
server=" --server=$2"
|
||||
fi
|
||||
|
||||
version="${3:-}"
|
||||
|
||||
echo "looking at $pkg (version $version) from server [$server]" >&2
|
||||
cmd="luarocks nix $server $pkg $version"
|
||||
drv="$($cmd)"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Failed to convert $pkg" >&2
|
||||
echo "$drv" >&2
|
||||
else
|
||||
echo "$drv" | tee -a "$TMP_FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
# params needed when called via callPackage
|
||||
echo "$HEADER" | tee "$TMP_FILE"
|
||||
|
||||
# list of packages with format
|
||||
# name,server,version
|
||||
while IFS=, read -r pkg_name server version
|
||||
do
|
||||
if [ -z "$pkg_name" ]; then
|
||||
echo "Skipping empty package name" >&2
|
||||
fi
|
||||
convert_pkg "$pkg_name" "$server" "$version"
|
||||
done < "$CSV_FILE"
|
||||
|
||||
# close the set
|
||||
echo "$FOOTER" | tee -a "$TMP_FILE"
|
||||
|
||||
cp "$TMP_FILE" "$GENERATED_NIXFILE"
|
|
@ -29,7 +29,10 @@
|
|||
networks are set, it will default to using a configuration file at
|
||||
<literal>/etc/wpa_supplicant.conf</literal>. You should edit this file
|
||||
yourself to define wireless networks, WPA keys and so on (see
|
||||
wpa_supplicant.conf(5)).
|
||||
<citerefentry>
|
||||
<refentrytitle>wpa_supplicant.conf</refentrytitle>
|
||||
<manvolnum>5</manvolnum>
|
||||
</citerefentry>).
|
||||
</para>
|
||||
|
||||
<para>
|
||||
|
|
|
@ -35,11 +35,11 @@
|
|||
</para>
|
||||
<para>
|
||||
NixOS’s default <emphasis>display manager</emphasis> (the program that
|
||||
provides a graphical login prompt and manages the X server) is SLiM. You can
|
||||
provides a graphical login prompt and manages the X server) is LightDM. You can
|
||||
select an alternative one by picking one of the following lines:
|
||||
<programlisting>
|
||||
<xref linkend="opt-services.xserver.displayManager.sddm.enable"/> = true;
|
||||
<xref linkend="opt-services.xserver.displayManager.lightdm.enable"/> = true;
|
||||
<xref linkend="opt-services.xserver.displayManager.slim.enable"/> = true;
|
||||
</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
|
|
|
@ -265,6 +265,7 @@ in rec {
|
|||
xsltproc \
|
||||
${manualXsltprocOptions} \
|
||||
--stringparam target.database.document "${olinkDB}/olinkdb.xml" \
|
||||
--stringparam id.warnings "1" \
|
||||
--nonet --output $dst/ \
|
||||
${docbook_xsl_ns}/xml/xsl/docbook/xhtml/chunktoc.xsl \
|
||||
${manual-combined}/manual-combined.xml
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
<section xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
version="5.0"
|
||||
xml:id="sec-debugging-nixos-tests">
|
||||
<title>Debugging NixOS tests</title>
|
||||
|
||||
<para>
|
||||
Tests may fail and infrastructure offers access to inspect machine state.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To prevent test from stopping and cleaning up, insert a sleep command:
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
$machine->succeed("sleep 84000");
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
As soon as machine starts run as root:
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
nix-shell -p socat --run "socat STDIO,raw,echo=0,escape=0x11 UNIX:/tmp/nix-build-vm-test-run-*.drv-0/vm-state-machine/backdoor"
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
You may need to find the correct path, replacing <literal>/tmp</literal>,
|
||||
<literal>*</literal> or <literal>machine</literal>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Press "enter" to open up console and login as "root". After you're done,
|
||||
press "ctrl-q" to exit the console.
|
||||
</para>
|
||||
</section>
|
|
@ -16,5 +16,4 @@ xlink:href="https://github.com/NixOS/nixpkgs/tree/master/nixos/tests">nixos/test
|
|||
<xi:include href="writing-nixos-tests.xml" />
|
||||
<xi:include href="running-nixos-tests.xml" />
|
||||
<xi:include href="running-nixos-tests-interactively.xml" />
|
||||
<xi:include href="debugging-nixos-tests.xml" />
|
||||
</chapter>
|
||||
|
|
|
@ -23,7 +23,7 @@ $ diskutil list
|
|||
[..]
|
||||
$ diskutil unmountDisk diskN
|
||||
Unmount of all volumes on diskN was successful
|
||||
$ sudo dd bs=1m if=nix.iso of=/dev/rdiskN
|
||||
$ sudo dd if=nix.iso of=/dev/rdiskN
|
||||
</programlisting>
|
||||
Using the 'raw' <command>rdiskN</command> device instead of
|
||||
<command>diskN</command> completes in minutes instead of hours. After
|
||||
|
|
|
@ -77,18 +77,22 @@
|
|||
Shared folders can be given a name and a path in the host system in the
|
||||
VirtualBox settings (Machine / Settings / Shared Folders, then click on the
|
||||
"Add" icon). Add the following to the
|
||||
<literal>/etc/nixos/configuration.nix</literal> to auto-mount them:
|
||||
<literal>/etc/nixos/configuration.nix</literal> to auto-mount them. If you
|
||||
do not add <literal>"nofail"</literal>, the system will no boot properly.
|
||||
The same goes for disabling <literal>rngd</literal> which is normally used
|
||||
to get randomness but this does not work in virtual machines.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
{ config, pkgs, ...} :
|
||||
{
|
||||
security.rngd.enable = false; // otherwise vm will not boot
|
||||
...
|
||||
|
||||
fileSystems."/virtualboxshare" = {
|
||||
fsType = "vboxsf";
|
||||
device = "nameofthesharedfolder";
|
||||
options = [ "rw" ];
|
||||
options = [ "rw" "nofail" ];
|
||||
};
|
||||
}
|
||||
</programlisting>
|
||||
|
|
|
@ -13,35 +13,35 @@
|
|||
</refnamediv>
|
||||
<refsynopsisdiv>
|
||||
<cmdsynopsis>
|
||||
<command>nixos-rebuild</command><group choice='req'>
|
||||
<command>nixos-rebuild</command><group choice='req'>
|
||||
<arg choice='plain'>
|
||||
<option>switch</option>
|
||||
</arg>
|
||||
|
||||
|
||||
<arg choice='plain'>
|
||||
<option>boot</option>
|
||||
</arg>
|
||||
|
||||
|
||||
<arg choice='plain'>
|
||||
<option>test</option>
|
||||
</arg>
|
||||
|
||||
|
||||
<arg choice='plain'>
|
||||
<option>build</option>
|
||||
</arg>
|
||||
|
||||
|
||||
<arg choice='plain'>
|
||||
<option>dry-build</option>
|
||||
</arg>
|
||||
|
||||
|
||||
<arg choice='plain'>
|
||||
<option>dry-activate</option>
|
||||
</arg>
|
||||
|
||||
|
||||
<arg choice='plain'>
|
||||
<option>build-vm</option>
|
||||
</arg>
|
||||
|
||||
|
||||
<arg choice='plain'>
|
||||
<option>build-vm-with-bootloader</option>
|
||||
</arg>
|
||||
|
@ -50,29 +50,33 @@
|
|||
<arg>
|
||||
<option>--upgrade</option>
|
||||
</arg>
|
||||
|
||||
|
||||
<arg>
|
||||
<option>--install-bootloader</option>
|
||||
</arg>
|
||||
|
||||
|
||||
<arg>
|
||||
<option>--no-build-nix</option>
|
||||
</arg>
|
||||
|
||||
|
||||
<arg>
|
||||
<option>--fast</option>
|
||||
</arg>
|
||||
|
||||
|
||||
<arg>
|
||||
<option>--rollback</option>
|
||||
</arg>
|
||||
<arg>
|
||||
<option>--builders</option>
|
||||
<replaceable>builder-spec</replaceable>
|
||||
</arg>
|
||||
<sbr />
|
||||
<arg>
|
||||
<group choice='req'>
|
||||
<group choice='req'>
|
||||
<arg choice='plain'>
|
||||
<option>--profile-name</option>
|
||||
</arg>
|
||||
|
||||
|
||||
<arg choice='plain'>
|
||||
<option>-p</option>
|
||||
</arg>
|
||||
|
@ -315,6 +319,27 @@ $ ./result/bin/run-*-vm
|
|||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--builders</option>
|
||||
<replaceable>builder-spec</replaceable>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Allow ad-hoc remote builders for building the new system.
|
||||
This requires the user executing <command>nixos-rebuild</command> (usually
|
||||
root) to be configured as a trusted user in the Nix daemon. This can be
|
||||
achieved by using the <literal>nix.trustedUsers</literal> NixOS option.
|
||||
Examples values for that option are described in the
|
||||
<literal>Remote builds chapter</literal> in the Nix manual,
|
||||
(i.e. <command>--builders "ssh://bigbrother x86_64-linux"</command>).
|
||||
By specifying an empty string existing builders specified in
|
||||
<filename>/etc/nix/machines</filename> can be ignored:
|
||||
<command>--builders ""</command> for example when they are not
|
||||
reachable due to network connectivity.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--profile-name</option>
|
||||
|
|
|
@ -331,17 +331,29 @@
|
|||
<para>
|
||||
The <literal>pam_unix</literal> account module is now loaded with its
|
||||
control field set to <literal>required</literal> instead of
|
||||
<literal>sufficient</literal>, so that later pam account modules that
|
||||
<literal>sufficient</literal>, so that later PAM account modules that
|
||||
might do more extensive checks are being executed.
|
||||
Previously, the whole account module verification was exited prematurely
|
||||
in case a nss module provided the account name to
|
||||
<literal>pam_unix</literal>.
|
||||
The LDAP and SSSD NixOS modules already add their NSS modules when
|
||||
enabled. In case your setup breaks due to some later pam account module
|
||||
enabled. In case your setup breaks due to some later PAM account module
|
||||
previosuly shadowed, or failing NSS lookups, please file a bug. You can
|
||||
get back the old behaviour by manually setting
|
||||
<literal><![CDATA[security.pam.services.<name?>.text]]></literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The <literal>pam_unix</literal> password module is now loaded with its
|
||||
control field set to <literal>sufficient</literal> instead of
|
||||
<literal>required</literal>, so that password managed only
|
||||
by later PAM password modules are being executed.
|
||||
Previously, for example, changing an LDAP account's password through PAM
|
||||
was not possible: the whole password module verification
|
||||
was exited prematurely by <literal>pam_unix</literal>,
|
||||
preventing <literal>pam_ldap</literal> to manage the password as it should.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
|
@ -350,6 +362,39 @@
|
|||
See the <literal>fish</literal> <link xlink:href="https://github.com/fish-shell/fish-shell/releases/tag/3.0.0">release notes</link> for more information.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The ibus-table input method has had a change in config format, which
|
||||
causes all previous settings to be lost. See
|
||||
<link xlink:href="https://github.com/mike-fabian/ibus-table/commit/f9195f877c5212fef0dfa446acb328c45ba5852b">this commit message</link>
|
||||
for details.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Support for NixOS module system type <literal>types.optionSet</literal> and
|
||||
<literal>lib.mkOption</literal> argument <literal>options</literal> is removed.
|
||||
Use <literal>types.submodule</literal> instead.
|
||||
(<link xlink:href="https://github.com/NixOS/nixpkgs/pull/54637">#54637</link>)
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>matrix-synapse</literal> has been updated to version 0.99. It will
|
||||
<link xlink:href="https://github.com/matrix-org/synapse/pull/4509">no longer generate a self-signed certificate on first launch</link>
|
||||
and will be <link xlink:href="https://matrix.org/blog/2019/02/05/synapse-0-99-0/">the last version to accept self-signed certificates</link>.
|
||||
As such, it is now recommended to use a proper certificate verified by a
|
||||
root CA (for example Let's Encrypt).
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>mailutils</literal> now works by default when
|
||||
<literal>sendmail</literal> is not in a setuid wrapper. As a consequence,
|
||||
the <literal>sendmailPath</literal> argument, having lost its main use, has
|
||||
been removed.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
|
||||
|
@ -367,6 +412,23 @@
|
|||
<option>services.matomo.package</option> which determines the used
|
||||
Matomo version.
|
||||
</para>
|
||||
<para>
|
||||
The Matomo module now also comes with the systemd service <literal>matomo-archive-processing.service</literal>
|
||||
and a timer that automatically triggers archive processing every hour.
|
||||
This means that you can safely
|
||||
<link xlink:href="https://matomo.org/docs/setup-auto-archiving/#disable-browser-triggers-for-matomo-archiving-and-limit-matomo-reports-to-updating-every-hour">
|
||||
disable browser triggers for Matomo archiving
|
||||
</link> at <literal>Administration > System > General Settings</literal>.
|
||||
</para>
|
||||
<para>
|
||||
Additionally, you can enable to
|
||||
<link xlink:href="https://matomo.org/docs/privacy/#step-2-delete-old-visitors-logs">
|
||||
delete old visitor logs
|
||||
</link> at <literal>Administration > System > Privacy</literal>,
|
||||
but make sure that you run <literal>systemctl start matomo-archive-processing.service</literal>
|
||||
at least once without errors if you have already collected data before,
|
||||
so that the reports get archived before the source data gets deleted.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
|
@ -402,12 +464,74 @@
|
|||
of maintainers.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The astah-community package was removed from nixpkgs due to it being discontinued and the downloads not being available anymore.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The httpd service now saves log files with a .log file extension by default for
|
||||
easier integration with the logrotate service.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The owncloud server packages and httpd subservice module were removed
|
||||
from nixpkgs due to the lack of maintainers.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
It is possible now to uze ZRAM devices as general purpose ephemeral block devices,
|
||||
not only as swap. Using more than 1 device as ZRAM swap is no longer recommended,
|
||||
but is still possible by setting <literal>zramSwap.swapDevices</literal> explicitly.
|
||||
</para>
|
||||
<para>
|
||||
Default algorithm for ZRAM swap was changed to <literal>zstd</literal>.
|
||||
</para>
|
||||
<para>
|
||||
Changes to ZRAM algorithm are applied during <literal>nixos-rebuild switch</literal>,
|
||||
so make sure you have enough swap space on disk to survive ZRAM device rebuild. Alternatively,
|
||||
use <literal>nixos-rebuild boot; reboot</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Flat volumes are now disabled by default in <literal>hardware.pulseaudio</literal>.
|
||||
This has been done to prevent applications, which are unaware of this feature, setting
|
||||
their volumes to 100% on startup causing harm to your audio hardware and potentially your ears.
|
||||
</para>
|
||||
<note>
|
||||
<para>
|
||||
With this change application specific volumes are relative to the master volume which can be
|
||||
adjusted independently, whereas before they were absolute; meaning that in effect, it scaled the
|
||||
device-volume with the volume of the loudest application.
|
||||
</para>
|
||||
</note>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The <link xlink:href="https://github.com/DanielAdolfsson/ndppd"><literal>ndppd</literal></link> module
|
||||
now supports <link linkend="opt-services.ndppd.enable">all config options</link> provided by the current
|
||||
upstream version as service options. Additionally the <literal>ndppd</literal> package doesn't contain
|
||||
the systemd unit configuration from upstream anymore, the unit is completely configured by the NixOS module now.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
New installs of NixOS will default to the Redmine 4.x series unless otherwise specified in
|
||||
<literal>services.redmine.package</literal> while existing installs of NixOS will default to
|
||||
the Redmine 3.x series.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The <link linkend="opt-services.grafana.enable">Grafana module</link> now supports declarative
|
||||
<link xlink:href="http://docs.grafana.org/administration/provisioning/">datasource and dashboard</link>
|
||||
provisioning.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
</section>
|
||||
|
|
|
@ -83,6 +83,8 @@ rec {
|
|||
(m': let config = (getAttr m' nodes).config; in
|
||||
optionalString (config.networking.primaryIPAddress != "")
|
||||
("${config.networking.primaryIPAddress} " +
|
||||
optionalString (config.networking.domain != null)
|
||||
"${config.networking.hostName}.${config.networking.domain} " +
|
||||
"${config.networking.hostName}\n"));
|
||||
|
||||
virtualisation.qemu.options =
|
||||
|
|
|
@ -27,6 +27,9 @@
|
|||
, # The root file system type.
|
||||
fsType ? "ext4"
|
||||
|
||||
, # Filesystem label
|
||||
label ? "nixos"
|
||||
|
||||
, # The initial NixOS configuration file to be copied to
|
||||
# /etc/nixos/configuration.nix.
|
||||
configFile ? null
|
||||
|
@ -134,9 +137,9 @@ let format' = format; in let
|
|||
# Get start & length of the root partition in sectors to $START and $SECTORS.
|
||||
eval $(partx $diskImage -o START,SECTORS --nr ${rootPartition} --pairs)
|
||||
|
||||
mkfs.${fsType} -F -L nixos $diskImage -E offset=$(sectorsToBytes $START) $(sectorsToKilobytes $SECTORS)K
|
||||
mkfs.${fsType} -F -L ${label} $diskImage -E offset=$(sectorsToBytes $START) $(sectorsToKilobytes $SECTORS)K
|
||||
'' else ''
|
||||
mkfs.${fsType} -F -L nixos $diskImage
|
||||
mkfs.${fsType} -F -L ${label} $diskImage
|
||||
''}
|
||||
|
||||
root="$PWD/root"
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
, # The root directory of the squashfs filesystem is filled with the
|
||||
# closures of the Nix store paths listed here.
|
||||
storeContents ? []
|
||||
, # Compression parameters.
|
||||
# For zstd compression you can use "zstd -Xcompression-level 6".
|
||||
comp ? "xz -Xdict-size 100%"
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation {
|
||||
|
@ -20,6 +23,6 @@ stdenv.mkDerivation {
|
|||
|
||||
# Generate the squashfs image.
|
||||
mksquashfs nix-path-registration $(cat $closureInfo/store-paths) $out \
|
||||
-keep-as-directory -all-root -b 1048576 -comp xz -Xdict-size 100%
|
||||
-keep-as-directory -all-root -b 1048576 -comp ${comp}
|
||||
'';
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ use strict;
|
|||
use Thread::Queue;
|
||||
use XML::Writer;
|
||||
use Encode qw(decode encode);
|
||||
use Time::HiRes qw(clock_gettime CLOCK_MONOTONIC);
|
||||
|
||||
sub new {
|
||||
my ($class) = @_;
|
||||
|
@ -46,10 +47,12 @@ sub nest {
|
|||
print STDERR maybePrefix("$msg\n", $attrs);
|
||||
$self->{log}->startTag("nest");
|
||||
$self->{log}->dataElement("head", $msg, %{$attrs});
|
||||
my $now = clock_gettime(CLOCK_MONOTONIC);
|
||||
$self->drainLogQueue();
|
||||
eval { &$coderef };
|
||||
my $res = $@;
|
||||
$self->drainLogQueue();
|
||||
$self->log(sprintf("(%.2f seconds)", clock_gettime(CLOCK_MONOTONIC) - $now));
|
||||
$self->{log}->endTag("nest");
|
||||
die $@ if $@;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ use Cwd;
|
|||
use File::Basename;
|
||||
use File::Path qw(make_path);
|
||||
use File::Slurp;
|
||||
use Time::HiRes qw(clock_gettime CLOCK_MONOTONIC);
|
||||
|
||||
|
||||
my $showGraphics = defined $ENV{'DISPLAY'};
|
||||
|
@ -155,10 +156,8 @@ sub start {
|
|||
$ENV{USE_TMPDIR} = 1;
|
||||
$ENV{QEMU_OPTS} =
|
||||
($self->{allowReboot} ? "" : "-no-reboot ") .
|
||||
"-monitor unix:./monitor " .
|
||||
"-chardev socket,id=shell,path=./shell -device virtio-serial -device virtconsole,chardev=shell " .
|
||||
# socket backdoor, see "Debugging NixOS tests" section in NixOS manual
|
||||
"-chardev socket,id=backdoor,path=./backdoor,server,nowait -device virtio-serial -device virtconsole,chardev=backdoor " .
|
||||
"-monitor unix:./monitor -chardev socket,id=shell,path=./shell " .
|
||||
"-device virtio-serial -device virtconsole,chardev=shell " .
|
||||
"-device virtio-rng-pci " .
|
||||
($showGraphics ? "-serial stdio" : "-nographic") . " " . ($ENV{QEMU_OPTS} || "");
|
||||
chdir $self->{stateDir} or die;
|
||||
|
@ -249,12 +248,15 @@ sub connect {
|
|||
|
||||
$self->start;
|
||||
|
||||
my $now = clock_gettime(CLOCK_MONOTONIC);
|
||||
local $SIG{ALRM} = sub { die "timed out waiting for the VM to connect\n"; };
|
||||
alarm 300;
|
||||
alarm 600;
|
||||
readline $self->{socket} or die "the VM quit before connecting\n";
|
||||
alarm 0;
|
||||
|
||||
$self->log("connected to guest root shell");
|
||||
# We're interested in tracking how close we are to `alarm`.
|
||||
$self->log(sprintf("(connecting took %.2f seconds)", clock_gettime(CLOCK_MONOTONIC) - $now));
|
||||
$self->{connected} = 1;
|
||||
|
||||
});
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
# Use a minimal kernel?
|
||||
, minimal ? false
|
||||
# Ignored
|
||||
, config ? null
|
||||
, config ? {}
|
||||
# Modules to add to each VM
|
||||
, extraConfigurations ? [] }:
|
||||
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
# nix-build '<nixpkgs/nixos>' -A config.system.build.novaImage --arg configuration "{ imports = [ ./nixos/maintainers/scripts/openstack/nova-image.nix ]; }"
|
||||
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
imports =
|
||||
[ ../../../modules/installer/cd-dvd/channel.nix
|
||||
../../../modules/virtualisation/nova-config.nix
|
||||
];
|
||||
|
||||
system.build.novaImage = import ../../../lib/make-disk-image.nix {
|
||||
inherit lib config;
|
||||
pkgs = import ../../../.. { inherit (pkgs) system; }; # ensure we use the regular qemu-kvm package
|
||||
diskSize = 8192;
|
||||
format = "qcow2";
|
||||
configFile = pkgs.writeText "configuration.nix"
|
||||
''
|
||||
{
|
||||
imports = [ <nixpkgs/nixos/modules/virtualisation/nova-config.nix> ];
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
}
|
26
nixos/maintainers/scripts/openstack/openstack-image.nix
Normal file
26
nixos/maintainers/scripts/openstack/openstack-image.nix
Normal file
|
@ -0,0 +1,26 @@
|
|||
# nix-build '<nixpkgs/nixos>' -A config.system.build.openstackImage --arg configuration "{ imports = [ ./nixos/maintainers/scripts/openstack/openstack-image.nix ]; }"
|
||||
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
imports =
|
||||
[ ../../../modules/installer/cd-dvd/channel.nix
|
||||
../../../modules/virtualisation/openstack-config.nix
|
||||
];
|
||||
|
||||
system.build.openstackImage = import ../../../lib/make-disk-image.nix {
|
||||
inherit lib config;
|
||||
pkgs = import ../../../.. { inherit (pkgs) system; }; # ensure we use the regular qemu-kvm package
|
||||
diskSize = 8192;
|
||||
format = "qcow2";
|
||||
configFile = pkgs.writeText "configuration.nix"
|
||||
''
|
||||
{
|
||||
imports = [ <nixpkgs/nixos/modules/virtualisation/openstack-config.nix> ];
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
}
|
|
@ -38,6 +38,8 @@ let
|
|||
bind_timelimit ${toString cfg.bind.timeLimit}
|
||||
${optionalString (cfg.bind.distinguishedName != "")
|
||||
"binddn ${cfg.bind.distinguishedName}" }
|
||||
${optionalString (cfg.daemon.rootpwmoddn != "")
|
||||
"rootpwmoddn ${cfg.daemon.rootpwmoddn}" }
|
||||
${optionalString (cfg.daemon.extraConfig != "") cfg.daemon.extraConfig }
|
||||
'';
|
||||
};
|
||||
|
@ -126,6 +128,26 @@ in
|
|||
the end of the nslcd configuration file (nslcd.conf).
|
||||
'' ;
|
||||
} ;
|
||||
|
||||
rootpwmoddn = mkOption {
|
||||
default = "";
|
||||
example = "cn=admin,dc=example,dc=com";
|
||||
type = types.str;
|
||||
description = ''
|
||||
The distinguished name to use to bind to the LDAP server
|
||||
when the root user tries to modify a user's password.
|
||||
'';
|
||||
};
|
||||
|
||||
rootpwmodpw = mkOption {
|
||||
default = "";
|
||||
example = "/run/keys/nslcd.rootpwmodpw";
|
||||
type = types.str;
|
||||
description = ''
|
||||
The path to a file containing the credentials with which
|
||||
to bind to the LDAP server if the root user tries to change a user's password
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
bind = {
|
||||
|
@ -203,9 +225,11 @@ in
|
|||
system.activationScripts = mkIf insertLdapPassword {
|
||||
ldap = stringAfter [ "etc" "groups" "users" ] ''
|
||||
if test -f "${cfg.bind.password}" ; then
|
||||
echo "bindpw "$(cat ${cfg.bind.password})"" | cat ${ldapConfig.source} - > /etc/ldap.conf.bindpw
|
||||
mv -fT /etc/ldap.conf.bindpw /etc/ldap.conf
|
||||
chmod 600 /etc/ldap.conf
|
||||
umask 0077
|
||||
conf="$(mktemp)"
|
||||
printf 'bindpw %s\n' "$(cat ${cfg.bind.password})" |
|
||||
cat ${ldapConfig.source} - >"$conf"
|
||||
mv -fT "$conf" /etc/ldap.conf
|
||||
fi
|
||||
'';
|
||||
};
|
||||
|
@ -232,21 +256,31 @@ in
|
|||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
preStart = ''
|
||||
mkdir -p /run/nslcd
|
||||
rm -f /run/nslcd/nslcd.pid;
|
||||
chown nslcd.nslcd /run/nslcd
|
||||
${optionalString (cfg.bind.distinguishedName != "") ''
|
||||
if test -s "${cfg.bind.password}" ; then
|
||||
ln -sfT "${cfg.bind.password}" /run/nslcd/bindpw
|
||||
fi
|
||||
''}
|
||||
umask 0077
|
||||
conf="$(mktemp)"
|
||||
{
|
||||
cat ${nslcdConfig.source}
|
||||
test -z '${cfg.bind.distinguishedName}' -o ! -f '${cfg.bind.password}' ||
|
||||
printf 'bindpw %s\n' "$(cat '${cfg.bind.password}')"
|
||||
test -z '${cfg.daemon.rootpwmoddn}' -o ! -f '${cfg.daemon.rootpwmodpw}' ||
|
||||
printf 'rootpwmodpw %s\n' "$(cat '${cfg.daemon.rootpwmodpw}')"
|
||||
} >"$conf"
|
||||
mv -fT "$conf" /etc/nslcd.conf
|
||||
'';
|
||||
|
||||
# NOTE: because one cannot pass a custom config path to `nslcd`
|
||||
# (which is only able to use `/etc/nslcd.conf`)
|
||||
# changes in `nslcdConfig` won't change `serviceConfig`,
|
||||
# and thus won't restart `nslcd`.
|
||||
# Therefore `restartTriggers` is used on `/etc/nslcd.conf`.
|
||||
restartTriggers = [ nslcdConfig.source ];
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = "${nss_pam_ldapd}/sbin/nslcd";
|
||||
Type = "forking";
|
||||
PIDFile = "/run/nslcd/nslcd.pid";
|
||||
Restart = "always";
|
||||
RuntimeDirectory = [ "nslcd" ];
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -180,7 +180,7 @@ in {
|
|||
type = types.attrsOf types.unspecified;
|
||||
default = {};
|
||||
description = ''Config of the pulse daemon. See <literal>man pulse-daemon.conf</literal>.'';
|
||||
example = literalExample ''{ flat-volumes = "no"; }'';
|
||||
example = literalExample ''{ realtime-scheduling = "yes"; }'';
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -242,6 +242,9 @@ in {
|
|||
source = writeText "libao.conf" "default_driver=pulse"; }
|
||||
];
|
||||
|
||||
# Disable flat volumes to enable relative ones
|
||||
hardware.pulseaudio.daemon.config.flat-volumes = mkDefault "no";
|
||||
|
||||
# Allow PulseAudio to get realtime priority using rtkit.
|
||||
security.rtkit.enable = true;
|
||||
|
||||
|
|
|
@ -6,10 +6,27 @@ let
|
|||
|
||||
cfg = config.zramSwap;
|
||||
|
||||
devices = map (nr: "zram${toString nr}") (range 0 (cfg.numDevices - 1));
|
||||
# don't set swapDevices as mkDefault, so we can detect user had read our warning
|
||||
# (see below) and made an action (or not)
|
||||
devicesCount = if cfg.swapDevices != null then cfg.swapDevices else cfg.numDevices;
|
||||
|
||||
devices = map (nr: "zram${toString nr}") (range 0 (devicesCount - 1));
|
||||
|
||||
modprobe = "${pkgs.kmod}/bin/modprobe";
|
||||
|
||||
warnings =
|
||||
assert cfg.swapDevices != null -> cfg.numDevices >= cfg.swapDevices;
|
||||
flatten [
|
||||
(optional (cfg.numDevices > 1 && cfg.swapDevices == null) ''
|
||||
Using several small zram devices as swap is no better than using one large.
|
||||
Set either zramSwap.numDevices = 1 or explicitly set zramSwap.swapDevices.
|
||||
|
||||
Previously multiple zram devices were used to enable multithreaded
|
||||
compression. Linux supports multithreaded compression for 1 device
|
||||
since 3.15. See https://lkml.org/lkml/2014/2/28/404 for details.
|
||||
'')
|
||||
];
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
|
@ -24,9 +41,11 @@ in
|
|||
default = false;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Enable in-memory compressed swap space provided by the zram kernel
|
||||
module.
|
||||
See https://www.kernel.org/doc/Documentation/blockdev/zram.txt
|
||||
Enable in-memory compressed devices and swap space provided by the zram
|
||||
kernel module.
|
||||
See <link xlink:href="https://www.kernel.org/doc/Documentation/blockdev/zram.txt">
|
||||
https://www.kernel.org/doc/Documentation/blockdev/zram.txt
|
||||
</link>.
|
||||
'';
|
||||
};
|
||||
|
||||
|
@ -34,7 +53,19 @@ in
|
|||
default = 1;
|
||||
type = types.int;
|
||||
description = ''
|
||||
Number of zram swap devices to create.
|
||||
Number of zram devices to create. See also
|
||||
<literal>zramSwap.swapDevices</literal>
|
||||
'';
|
||||
};
|
||||
|
||||
swapDevices = mkOption {
|
||||
default = null;
|
||||
example = 1;
|
||||
type = with types; nullOr int;
|
||||
description = ''
|
||||
Number of zram devices to be used as swap. Must be
|
||||
<literal><= zramSwap.numDevices</literal>.
|
||||
Default is same as <literal>zramSwap.numDevices</literal>, recommended is 1.
|
||||
'';
|
||||
};
|
||||
|
||||
|
@ -44,7 +75,8 @@ in
|
|||
description = ''
|
||||
Maximum amount of memory that can be used by the zram swap devices
|
||||
(as a percentage of your total memory). Defaults to 1/2 of your total
|
||||
RAM.
|
||||
RAM. Run <literal>zramctl</literal> to check how good memory is
|
||||
compressed.
|
||||
'';
|
||||
};
|
||||
|
||||
|
@ -58,12 +90,26 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
algorithm = mkOption {
|
||||
default = "zstd";
|
||||
example = "lzo";
|
||||
type = with types; either (enum [ "lzo" "lz4" "zstd" ]) str;
|
||||
description = ''
|
||||
Compression algorithm. <literal>lzo</literal> has good compression,
|
||||
but is slow. <literal>lz4</literal> has bad compression, but is fast.
|
||||
<literal>zstd</literal> is both good compression and fast.
|
||||
You can check what other algorithms are supported by your zram device with
|
||||
<programlisting>cat /sys/class/block/zram*/comp_algorithm</programlisting>
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
inherit warnings;
|
||||
|
||||
system.requiredKernelConfig = with config.lib.kernelConfig; [
|
||||
(isModule "ZRAM")
|
||||
];
|
||||
|
@ -85,25 +131,25 @@ in
|
|||
createZramInitService = dev:
|
||||
nameValuePair "zram-init-${dev}" {
|
||||
description = "Init swap on zram-based device ${dev}";
|
||||
bindsTo = [ "dev-${dev}.swap" ];
|
||||
after = [ "dev-${dev}.device" "zram-reloader.service" ];
|
||||
requires = [ "dev-${dev}.device" "zram-reloader.service" ];
|
||||
before = [ "dev-${dev}.swap" ];
|
||||
requiredBy = [ "dev-${dev}.swap" ];
|
||||
unitConfig.DefaultDependencies = false; # needed to prevent a cycle
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
ExecStop = "${pkgs.runtimeShell} -c 'echo 1 > /sys/class/block/${dev}/reset'";
|
||||
};
|
||||
script = ''
|
||||
set -u
|
||||
set -o pipefail
|
||||
|
||||
# Calculate memory to use for zram
|
||||
totalmem=$(${pkgs.gnugrep}/bin/grep 'MemTotal: ' /proc/meminfo | ${pkgs.gawk}/bin/awk '{print $2}')
|
||||
mem=$(((totalmem * ${toString cfg.memoryPercent} / 100 / ${toString cfg.numDevices}) * 1024))
|
||||
set -euo pipefail
|
||||
|
||||
echo $mem > /sys/class/block/${dev}/disksize
|
||||
# Calculate memory to use for zram
|
||||
mem=$(${pkgs.gawk}/bin/awk '/MemTotal: / {
|
||||
print int($2*${toString cfg.memoryPercent}/100.0/${toString devicesCount}*1024)
|
||||
}' /proc/meminfo)
|
||||
|
||||
${pkgs.utillinux}/sbin/zramctl --size $mem --algorithm ${cfg.algorithm} /dev/${dev}
|
||||
${pkgs.utillinux}/sbin/mkswap /dev/${dev}
|
||||
'';
|
||||
restartIfChanged = false;
|
||||
|
@ -111,6 +157,9 @@ in
|
|||
in listToAttrs ((map createZramInitService devices) ++ [(nameValuePair "zram-reloader"
|
||||
{
|
||||
description = "Reload zram kernel module when number of devices changes";
|
||||
wants = [ "systemd-udevd.service" ];
|
||||
after = [ "systemd-udevd.service" ];
|
||||
unitConfig.DefaultDependencies = false; # needed to prevent a cycle
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
|
@ -118,7 +167,11 @@ in
|
|||
ExecStart = "${modprobe} zram";
|
||||
ExecStop = "${modprobe} -r zram";
|
||||
};
|
||||
restartTriggers = [ cfg.numDevices ];
|
||||
restartTriggers = [
|
||||
cfg.numDevices
|
||||
cfg.algorithm
|
||||
cfg.memoryPercent
|
||||
];
|
||||
restartIfChanged = true;
|
||||
})]);
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ in {
|
|||
firmwareLinuxNonfree
|
||||
intel2200BGFirmware
|
||||
rtl8192su-firmware
|
||||
] ++ optional (pkgs.stdenv.isAarch32 || pkgs.stdenv.isAarch64) raspberrypiWirelessFirmware
|
||||
] ++ optional (pkgs.stdenv.hostPlatform.isAarch32 || pkgs.stdenv.hostPlatform.isAarch64) raspberrypiWirelessFirmware
|
||||
++ optionals (versionOlder config.boot.kernelPackages.kernel.version "4.13") [
|
||||
rtl8723bs-firmware
|
||||
];
|
||||
|
|
|
@ -124,10 +124,14 @@ in
|
|||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
assertions = lib.singleton {
|
||||
assertion = cfg.driSupport32Bit -> pkgs.stdenv.isx86_64;
|
||||
message = "Option driSupport32Bit only makes sense on a 64-bit system.";
|
||||
};
|
||||
assertions = [
|
||||
{ assertion = cfg.driSupport32Bit -> pkgs.stdenv.isx86_64;
|
||||
message = "Option driSupport32Bit only makes sense on a 64-bit system.";
|
||||
}
|
||||
{ assertion = cfg.driSupport32Bit -> (config.boot.kernelPackages.kernel.features.ia32Emulation or false);
|
||||
message = "Option driSupport32Bit requires a kernel that supports 32bit emulation";
|
||||
}
|
||||
];
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"L+ /run/opengl-driver - - - - ${package}"
|
||||
|
|
|
@ -339,11 +339,11 @@ let
|
|||
# dates (cp -p, touch, mcopy -m, faketime for label), IDs (mkfs.vfat -i)
|
||||
''
|
||||
mkdir ./contents && cd ./contents
|
||||
cp -rp "${efiDir}"/* .
|
||||
cp -rp "${efiDir}"/EFI .
|
||||
mkdir ./boot
|
||||
cp -p "${config.boot.kernelPackages.kernel}/${config.system.boot.loader.kernelFile}" \
|
||||
"${config.system.build.initialRamdisk}/${config.system.boot.loader.initrdFile}" ./boot/
|
||||
touch --date=@0 ./*
|
||||
touch --date=@0 ./EFI ./boot
|
||||
|
||||
usage_size=$(du -sb --apparent-size . | tr -cd '[:digit:]')
|
||||
# Make the image 110% as big as the files need to make up for FAT overhead
|
||||
|
@ -355,7 +355,7 @@ let
|
|||
echo "Image size: $image_size"
|
||||
truncate --size=$image_size "$out"
|
||||
${pkgs.libfaketime}/bin/faketime "2000-01-01 00:00:00" ${pkgs.dosfstools}/sbin/mkfs.vfat -i 12345678 -n EFIBOOT "$out"
|
||||
mcopy -psvm -i "$out" ./* ::
|
||||
mcopy -psvm -i "$out" ./EFI ./boot ::
|
||||
# Verify the FAT partition.
|
||||
${pkgs.dosfstools}/sbin/fsck.vfat -vn "$out"
|
||||
''; # */
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
let
|
||||
extlinux-conf-builder =
|
||||
import ../../system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix {
|
||||
inherit pkgs;
|
||||
pkgs = pkgs.buildPackages;
|
||||
};
|
||||
in
|
||||
{
|
||||
|
@ -15,13 +15,6 @@ in
|
|||
./sd-image.nix
|
||||
];
|
||||
|
||||
assertions = lib.singleton {
|
||||
assertion = pkgs.stdenv.hostPlatform.system == "aarch64-linux"
|
||||
&& pkgs.stdenv.hostPlatform.system == pkgs.stdenv.buildPlatform.system;
|
||||
message = "sd-image-aarch64.nix can be only built natively on Aarch64 / ARM64; " +
|
||||
"it cannot be cross compiled";
|
||||
};
|
||||
|
||||
boot.loader.grub.enable = false;
|
||||
boot.loader.generic-extlinux-compatible.enable = true;
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
let
|
||||
extlinux-conf-builder =
|
||||
import ../../system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix {
|
||||
inherit pkgs;
|
||||
pkgs = pkgs.buildPackages;
|
||||
};
|
||||
in
|
||||
{
|
||||
|
@ -15,13 +15,6 @@ in
|
|||
./sd-image.nix
|
||||
];
|
||||
|
||||
assertions = lib.singleton {
|
||||
assertion = pkgs.stdenv.hostPlatform.system == "armv7l-linux"
|
||||
&& pkgs.stdenv.hostPlatform.system == pkgs.stdenv.buildPlatform.system;
|
||||
message = "sd-image-armv7l-multiplatform.nix can be only built natively on ARMv7; " +
|
||||
"it cannot be cross compiled";
|
||||
};
|
||||
|
||||
boot.loader.grub.enable = false;
|
||||
boot.loader.generic-extlinux-compatible.enable = true;
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
let
|
||||
extlinux-conf-builder =
|
||||
import ../../system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix {
|
||||
inherit pkgs;
|
||||
pkgs = pkgs.buildPackages;
|
||||
};
|
||||
in
|
||||
{
|
||||
|
@ -15,13 +15,6 @@ in
|
|||
./sd-image.nix
|
||||
];
|
||||
|
||||
assertions = lib.singleton {
|
||||
assertion = pkgs.stdenv.hostPlatform.system == "armv6l-linux"
|
||||
&& pkgs.stdenv.hostPlatform.system == pkgs.stdenv.buildPlatform.system;
|
||||
message = "sd-image-raspberrypi.nix can be only built natively on ARMv6; " +
|
||||
"it cannot be cross compiled";
|
||||
};
|
||||
|
||||
boot.loader.grub.enable = false;
|
||||
boot.loader.generic-extlinux-compatible.enable = true;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
x86_64-linux = "/nix/store/cdcia67siabmj6li7vyffgv2cry86fq8-nix-2.1.3";
|
||||
i686-linux = "/nix/store/6q3xi6y5qnsv7d62b8n00hqfxi8rs2xs-nix-2.1.3";
|
||||
aarch64-linux = "/nix/store/2v93d0vimlm28jg0ms6v1i6lc0fq13pn-nix-2.1.3";
|
||||
x86_64-darwin = "/nix/store/dkjlfkrknmxbjmpfk3dg4q3nmb7m3zvk-nix-2.1.3";
|
||||
x86_64-linux = "/nix/store/pid1yakjasch4pwl63nzbj22z9zf0q26-nix-2.2";
|
||||
i686-linux = "/nix/store/qpkl0cxy0xh4h432lv2qsjrmhvx5x2vy-nix-2.2";
|
||||
aarch64-linux = "/nix/store/0jg7h94x986d8cskg6gcfza9x67spdbp-nix-2.2";
|
||||
x86_64-darwin = "/nix/store/a48whqkmxnsfhwbk6nay74iyc1cf0lr2-nix-2.2";
|
||||
}
|
||||
|
|
|
@ -340,6 +340,8 @@ foreach my $fs (read_file("/proc/self/mountinfo")) {
|
|||
chomp $fs;
|
||||
my @fields = split / /, $fs;
|
||||
my $mountPoint = $fields[4];
|
||||
$mountPoint =~ s/\\040/ /g; # account for mount points with spaces in the name (\040 is the escape character)
|
||||
$mountPoint =~ s/\\011/\t/g; # account for mount points with tabs in the name (\011 is the escape character)
|
||||
next unless -d $mountPoint;
|
||||
my @mountOptions = split /,/, $fields[5];
|
||||
|
||||
|
@ -355,6 +357,8 @@ foreach my $fs (read_file("/proc/self/mountinfo")) {
|
|||
my $fsType = $fields[$n];
|
||||
my $device = $fields[$n + 1];
|
||||
my @superOptions = split /,/, $fields[$n + 2];
|
||||
$device =~ s/\\040/ /g; # account for devices with spaces in the name (\040 is the escape character)
|
||||
$device =~ s/\\011/\t/g; # account for mount points with tabs in the name (\011 is the escape character)
|
||||
|
||||
# Skip the read-only bind-mount on /nix/store.
|
||||
next if $mountPoint eq "/nix/store" && (grep { $_ eq "rw" } @superOptions) && (grep { $_ eq "ro" } @mountOptions);
|
||||
|
@ -449,7 +453,11 @@ EOF
|
|||
if (-e $slave) {
|
||||
my $dmName = read_file("/sys/class/block/$deviceName/dm/name");
|
||||
chomp $dmName;
|
||||
$fileSystems .= " boot.initrd.luks.devices.\"$dmName\".device = \"${\(findStableDevPath $slave)}\";\n\n";
|
||||
# Ensure to add an entry only once
|
||||
my $luksDevice = " boot.initrd.luks.devices.\"$dmName\".device";
|
||||
if ($fileSystems !~ /^\Q$luksDevice\E/m) {
|
||||
$fileSystems .= "$luksDevice = \"${\(findStableDevPath $slave)}\";\n\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -631,9 +639,9 @@ $bootLoaderConfig
|
|||
# services.xserver.desktopManager.plasma5.enable = true;
|
||||
|
||||
# Define a user account. Don't forget to set a password with ‘passwd’.
|
||||
# users.users.guest = {
|
||||
# users.users.jane = {
|
||||
# isNormalUser = true;
|
||||
# uid = 1000;
|
||||
# extraGroups = [ "wheel" ]; # Enable ‘sudo’ for the user.
|
||||
# };
|
||||
|
||||
# This value determines the NixOS release with which your system is to be
|
||||
|
|
|
@ -314,13 +314,13 @@ else
|
|||
# echo 1>&2 "Warning: This value is not an option."
|
||||
|
||||
result=$(evalCfg "")
|
||||
if names=$(attrNames "$result" 2> /dev/null); then
|
||||
if [ ! -z "$result" ]; then
|
||||
names=$(attrNames "$result" 2> /dev/null)
|
||||
echo 1>&2 "This attribute set contains:"
|
||||
escapeQuotes () { eval echo "$1"; }
|
||||
nixMap escapeQuotes "$names"
|
||||
else
|
||||
echo 1>&2 "An error occurred while looking for attribute names."
|
||||
echo $result
|
||||
echo 1>&2 "An error occurred while looking for attribute names. Are you sure that '$option' exists?"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
|
|
@ -53,11 +53,11 @@ while [ "$#" -gt 0 ]; do
|
|||
repair=1
|
||||
extraBuildFlags+=("$i")
|
||||
;;
|
||||
--max-jobs|-j|--cores|-I)
|
||||
--max-jobs|-j|--cores|-I|--builders)
|
||||
j="$1"; shift 1
|
||||
extraBuildFlags+=("$i" "$j")
|
||||
;;
|
||||
--show-trace|--no-build-hook|--keep-failed|-K|--keep-going|-k|--verbose|-v|-vv|-vvv|-vvvv|-vvvvv|--fallback|--repair|--no-build-output|-Q|-j*)
|
||||
--show-trace|--keep-failed|-K|--keep-going|-k|--verbose|-v|-vv|-vvv|-vvvv|-vvvvv|--fallback|--repair|--no-build-output|-Q|-j*)
|
||||
extraBuildFlags+=("$i")
|
||||
;;
|
||||
--option)
|
||||
|
|
|
@ -156,6 +156,7 @@ in
|
|||
environment.systemPackages = [ pkgs.man-db ];
|
||||
environment.pathsToLink = [ "/share/man" ];
|
||||
environment.extraOutputsToInstall = [ "man" ] ++ optional cfg.dev.enable "devman";
|
||||
environment.etc."man.conf".source = "${pkgs.man-db}/etc/man_db.conf";
|
||||
})
|
||||
|
||||
(mkIf cfg.info.enable {
|
||||
|
|
|
@ -306,7 +306,7 @@
|
|||
rslsync = 279;
|
||||
minio = 280;
|
||||
kanboard = 281;
|
||||
pykms = 282;
|
||||
# pykms = 282; # DynamicUser = true
|
||||
kodi = 283;
|
||||
restya-board = 284;
|
||||
mighttpd2 = 285;
|
||||
|
@ -338,6 +338,7 @@
|
|||
minetest = 311;
|
||||
rss2email = 312;
|
||||
cockroachdb = 313;
|
||||
zoneminder = 314;
|
||||
|
||||
# When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
|
||||
|
||||
|
@ -604,7 +605,7 @@
|
|||
rslsync = 279;
|
||||
minio = 280;
|
||||
kanboard = 281;
|
||||
pykms = 282;
|
||||
# pykms = 282; # DynamicUser = true
|
||||
kodi = 283;
|
||||
restya-board = 284;
|
||||
mighttpd2 = 285;
|
||||
|
@ -636,6 +637,7 @@
|
|||
minetest = 311;
|
||||
rss2email = 312;
|
||||
cockroachdb = 313;
|
||||
zoneminder = 314;
|
||||
|
||||
# When adding a gid, make sure it doesn't match an existing
|
||||
# uid. Users and groups with the same name should have equal
|
||||
|
|
|
@ -55,7 +55,7 @@ let
|
|||
check = builtins.isAttrs;
|
||||
};
|
||||
|
||||
defaultPkgs = import ../../../pkgs/top-level/default.nix {
|
||||
defaultPkgs = import ../../.. {
|
||||
inherit (cfg) config overlays localSystem crossSystem;
|
||||
};
|
||||
|
||||
|
@ -68,7 +68,7 @@ in
|
|||
|
||||
pkgs = mkOption {
|
||||
defaultText = literalExample
|
||||
''import "''${nixos}/../pkgs/top-level" {
|
||||
''import "''${nixos}/.." {
|
||||
inherit (cfg) config overlays localSystem crossSystem;
|
||||
}
|
||||
'';
|
||||
|
|
|
@ -36,14 +36,14 @@ in
|
|||
nixos.revision = mkOption {
|
||||
internal = true;
|
||||
type = types.str;
|
||||
default = lib.trivial.revisionWithDefault "master";
|
||||
default = trivial.revisionWithDefault "master";
|
||||
description = "The Git revision from which this NixOS configuration was built.";
|
||||
};
|
||||
|
||||
nixos.codeName = mkOption {
|
||||
readOnly = true;
|
||||
type = types.str;
|
||||
default = lib.trivial.codeName;
|
||||
default = trivial.codeName;
|
||||
description = "The NixOS release code name (e.g. <literal>Emu</literal>).";
|
||||
};
|
||||
|
||||
|
|
|
@ -101,6 +101,7 @@
|
|||
./programs/gnupg.nix
|
||||
./programs/gphoto2.nix
|
||||
./programs/iftop.nix
|
||||
./programs/iotop.nix
|
||||
./programs/java.nix
|
||||
./programs/kbdlight.nix
|
||||
./programs/less.nix
|
||||
|
@ -248,6 +249,7 @@
|
|||
./services/desktops/gnome3/at-spi2-core.nix
|
||||
./services/desktops/gnome3/chrome-gnome-shell.nix
|
||||
./services/desktops/gnome3/evolution-data-server.nix
|
||||
./services/desktops/gnome3/file-roller.nix
|
||||
./services/desktops/gnome3/gnome-disks.nix
|
||||
./services/desktops/gnome3/gnome-documents.nix
|
||||
./services/desktops/gnome3/gnome-keyring.nix
|
||||
|
@ -432,6 +434,7 @@
|
|||
./services/misc/uhub.nix
|
||||
./services/misc/weechat.nix
|
||||
./services/misc/xmr-stak.nix
|
||||
./services/misc/zoneminder.nix
|
||||
./services/misc/zookeeper.nix
|
||||
./services/monitoring/alerta.nix
|
||||
./services/monitoring/apcupsd.nix
|
||||
|
@ -679,6 +682,7 @@
|
|||
./services/security/hologram-server.nix
|
||||
./services/security/hologram-agent.nix
|
||||
./services/security/munge.nix
|
||||
./services/security/nginx-sso.nix
|
||||
./services/security/oauth2_proxy.nix
|
||||
./services/security/oauth2_proxy_nginx.nix
|
||||
./services/security/physlock.nix
|
||||
|
@ -712,6 +716,8 @@
|
|||
./services/web-apps/atlassian/jira.nix
|
||||
./services/web-apps/codimd.nix
|
||||
./services/web-apps/frab.nix
|
||||
./services/web-apps/icingaweb2/icingaweb2.nix
|
||||
./services/web-apps/icingaweb2/module-monitoring.nix
|
||||
./services/web-apps/mattermost.nix
|
||||
./services/web-apps/nextcloud.nix
|
||||
./services/web-apps/nexus.nix
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
with lib;
|
||||
|
||||
{
|
||||
sound.enable = false;
|
||||
boot.vesa = false;
|
||||
|
||||
# Don't start a tty on the serial consoles.
|
||||
|
|
|
@ -13,5 +13,5 @@ with lib;
|
|||
|
||||
documentation.enable = mkDefault false;
|
||||
|
||||
sound.enable = mkDefault false;
|
||||
documentation.nixos.enable = mkDefault false;
|
||||
}
|
||||
|
|
17
nixos/modules/programs/iotop.nix
Normal file
17
nixos/modules/programs/iotop.nix
Normal file
|
@ -0,0 +1,17 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.programs.iotop;
|
||||
in {
|
||||
options = {
|
||||
programs.iotop.enable = mkEnableOption "iotop + setcap wrapper";
|
||||
};
|
||||
config = mkIf cfg.enable {
|
||||
security.wrappers.iotop = {
|
||||
source = "${pkgs.iotop}/bin/iotop";
|
||||
capabilities = "cap_net_admin+p";
|
||||
};
|
||||
};
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
let
|
||||
cfg = config.programs.nano;
|
||||
LF = "\n";
|
||||
in
|
||||
|
||||
{
|
||||
|
@ -33,9 +34,9 @@ in
|
|||
|
||||
###### implementation
|
||||
|
||||
config = lib.mkIf (cfg.nanorc != "") {
|
||||
config = lib.mkIf (cfg.nanorc != "" || cfg.syntaxHighlight) {
|
||||
environment.etc."nanorc".text = lib.concatStrings [ cfg.nanorc
|
||||
(lib.optionalString cfg.syntaxHighlight ''include "${pkgs.nano}/share/nano/*.nanorc"'') ];
|
||||
(lib.optionalString cfg.syntaxHighlight ''${LF}include "${pkgs.nano}/share/nano/*.nanorc"'') ];
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -167,16 +167,16 @@ in
|
|||
The set of system-wide known SSH hosts.
|
||||
'';
|
||||
example = literalExample ''
|
||||
[
|
||||
{
|
||||
{
|
||||
myhost = {
|
||||
hostNames = [ "myhost" "myhost.mydomain.com" "10.10.1.4" ];
|
||||
publicKeyFile = ./pubkeys/myhost_ssh_host_dsa_key.pub;
|
||||
}
|
||||
{
|
||||
};
|
||||
myhost2 = {
|
||||
hostNames = [ "myhost2" ];
|
||||
publicKeyFile = ./pubkeys/myhost2_ssh_host_dsa_key.pub;
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
|
|
|
@ -60,10 +60,11 @@ in {
|
|||
extraPackages = mkOption {
|
||||
type = with types; listOf package;
|
||||
default = with pkgs; [
|
||||
swaylock swayidle
|
||||
xwayland rxvt_unicode dmenu
|
||||
];
|
||||
defaultText = literalExample ''
|
||||
with pkgs; [ xwayland rxvt_unicode dmenu ];
|
||||
with pkgs; [ swaylock swayidle xwayland rxvt_unicode dmenu ];
|
||||
'';
|
||||
example = literalExample ''
|
||||
with pkgs; [
|
||||
|
|
|
@ -8,7 +8,7 @@ let
|
|||
|
||||
wcWrapped = pkgs.writeShellScriptBin "way-cooler" ''
|
||||
${cfg.extraSessionCommands}
|
||||
exec ${pkgs.dbus.dbus-launch} --exit-with-session ${way-cooler}/bin/way-cooler
|
||||
exec ${pkgs.dbus}/bin/dbus-run-session ${way-cooler}/bin/way-cooler
|
||||
'';
|
||||
wcJoined = pkgs.symlinkJoin {
|
||||
name = "way-cooler-wrapped";
|
||||
|
|
|
@ -48,6 +48,23 @@ in
|
|||
https://github.com/zsh-users/zsh-syntax-highlighting/blob/master/docs/highlighters/pattern.md
|
||||
'';
|
||||
};
|
||||
styles = mkOption {
|
||||
default = {};
|
||||
type = types.attrsOf types.string;
|
||||
|
||||
example = literalExample ''
|
||||
{
|
||||
"alias" = "fg=magenta,bold";
|
||||
}
|
||||
'';
|
||||
|
||||
description = ''
|
||||
Specifies custom styles to be highlighted by zsh-syntax-highlighting.
|
||||
|
||||
Please refer to the docs for more information about the usage:
|
||||
https://github.com/zsh-users/zsh-syntax-highlighting/blob/master/docs/highlighters/main.md
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -73,6 +90,11 @@ in
|
|||
pattern: design:
|
||||
"ZSH_HIGHLIGHT_PATTERNS+=('${pattern}' '${design}')"
|
||||
) cfg.patterns)
|
||||
++ optionals (length(attrNames cfg.styles) > 0)
|
||||
(mapAttrsToList (
|
||||
styles: design:
|
||||
"ZSH_HIGHLIGHT_STYLES[${styles}]='${design}'"
|
||||
) cfg.styles)
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -69,6 +69,9 @@ with lib;
|
|||
(mkRemovedOptionModule [ "security" "setuidOwners" ] "Use security.wrappers instead")
|
||||
(mkRemovedOptionModule [ "security" "setuidPrograms" ] "Use security.wrappers instead")
|
||||
|
||||
# PAM
|
||||
(mkRenamedOptionModule [ "security" "pam" "enableU2F" ] [ "security" "pam" "u2f" "enable" ])
|
||||
|
||||
(mkRemovedOptionModule [ "services" "rmilter" "bindInetSockets" ] "Use services.rmilter.bindSocket.* instead")
|
||||
(mkRemovedOptionModule [ "services" "rmilter" "bindUnixSockets" ] "Use services.rmilter.bindSocket.* instead")
|
||||
|
||||
|
|
|
@ -37,12 +37,14 @@ let
|
|||
};
|
||||
|
||||
u2fAuth = mkOption {
|
||||
default = config.security.pam.enableU2F;
|
||||
default = config.security.pam.u2f.enable;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
If set, users listed in
|
||||
<filename>~/.config/Yubico/u2f_keys</filename> are able to log in
|
||||
with the associated U2F key.
|
||||
<filename>$XDG_CONFIG_HOME/Yubico/u2f_keys</filename> (or
|
||||
<filename>$HOME/.config/Yubico/u2f_keys</filename> if XDG variable is
|
||||
not set) are able to log in with the associated U2F key. Path can be
|
||||
changed using <option>security.pam.u2f.authFile</option> option.
|
||||
'';
|
||||
};
|
||||
|
||||
|
@ -320,8 +322,8 @@ let
|
|||
"auth sufficient ${pkgs.pam_ssh_agent_auth}/libexec/pam_ssh_agent_auth.so file=~/.ssh/authorized_keys:~/.ssh/authorized_keys2:/etc/ssh/authorized_keys.d/%u"}
|
||||
${optionalString cfg.fprintAuth
|
||||
"auth sufficient ${pkgs.fprintd}/lib/security/pam_fprintd.so"}
|
||||
${optionalString cfg.u2fAuth
|
||||
"auth sufficient ${pkgs.pam_u2f}/lib/security/pam_u2f.so"}
|
||||
${let u2f = config.security.pam.u2f; in optionalString cfg.u2fAuth
|
||||
"auth ${u2f.control} ${pkgs.pam_u2f}/lib/security/pam_u2f.so ${optionalString u2f.debug "debug"} ${optionalString (u2f.authFile != null) "authfile=${u2f.authFile}"} ${optionalString u2f.interactive "interactive"} ${optionalString u2f.cue "cue"}"}
|
||||
${optionalString cfg.usbAuth
|
||||
"auth sufficient ${pkgs.pam_usb}/lib/security/pam_usb.so"}
|
||||
${let oath = config.security.pam.oath; in optionalString cfg.oathAuth
|
||||
|
@ -368,7 +370,7 @@ let
|
|||
auth required pam_deny.so
|
||||
|
||||
# Password management.
|
||||
password requisite pam_unix.so nullok sha512
|
||||
password sufficient pam_unix.so nullok sha512
|
||||
${optionalString config.security.pam.enableEcryptfs
|
||||
"password optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so"}
|
||||
${optionalString cfg.pamMount
|
||||
|
@ -527,11 +529,96 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
security.pam.enableU2F = mkOption {
|
||||
default = false;
|
||||
description = ''
|
||||
Enable the U2F PAM module.
|
||||
'';
|
||||
security.pam.u2f = {
|
||||
enable = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Enables U2F PAM (<literal>pam-u2f</literal>) module.
|
||||
|
||||
If set, users listed in
|
||||
<filename>$XDG_CONFIG_HOME/Yubico/u2f_keys</filename> (or
|
||||
<filename>$HOME/.config/Yubico/u2f_keys</filename> if XDG variable is
|
||||
not set) are able to log in with the associated U2F key. The path can
|
||||
be changed using <option>security.pam.u2f.authFile</option> option.
|
||||
|
||||
File format is:
|
||||
<literal>username:first_keyHandle,first_public_key: second_keyHandle,second_public_key</literal>
|
||||
This file can be generated using <command>pamu2fcfg</command> command.
|
||||
|
||||
More information can be found <link
|
||||
xlink:href="https://developers.yubico.com/pam-u2f/">here</link>.
|
||||
'';
|
||||
};
|
||||
|
||||
authFile = mkOption {
|
||||
default = null;
|
||||
type = with types; nullOr path;
|
||||
description = ''
|
||||
By default <literal>pam-u2f</literal> module reads the keys from
|
||||
<filename>$XDG_CONFIG_HOME/Yubico/u2f_keys</filename> (or
|
||||
<filename>$HOME/.config/Yubico/u2f_keys</filename> if XDG variable is
|
||||
not set).
|
||||
|
||||
If you want to change auth file locations or centralize database (for
|
||||
example use <filename>/etc/u2f-mappings</filename>) you can set this
|
||||
option.
|
||||
|
||||
File format is:
|
||||
<literal>username:first_keyHandle,first_public_key: second_keyHandle,second_public_key</literal>
|
||||
This file can be generated using <command>pamu2fcfg</command> command.
|
||||
|
||||
More information can be found <link
|
||||
xlink:href="https://developers.yubico.com/pam-u2f/">here</link>.
|
||||
'';
|
||||
};
|
||||
|
||||
control = mkOption {
|
||||
default = "sufficient";
|
||||
type = types.enum [ "required" "requisite" "sufficient" "optional" ];
|
||||
description = ''
|
||||
This option sets pam "control".
|
||||
If you want to have multi factor authentication, use "required".
|
||||
If you want to use U2F device instead of regular password, use "sufficient".
|
||||
|
||||
Read
|
||||
<citerefentry>
|
||||
<refentrytitle>pam.conf</refentrytitle>
|
||||
<manvolnum>5</manvolnum>
|
||||
</citerefentry>
|
||||
for better understanding of this option.
|
||||
'';
|
||||
};
|
||||
|
||||
debug = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Debug output to stderr.
|
||||
'';
|
||||
};
|
||||
|
||||
interactive = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Set to prompt a message and wait before testing the presence of a U2F device.
|
||||
Recommended if your device doesn’t have a tactile trigger.
|
||||
'';
|
||||
};
|
||||
|
||||
cue = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
By default <literal>pam-u2f</literal> module does not inform user
|
||||
that he needs to use the u2f device, it just waits without a prompt.
|
||||
|
||||
If you set this option to <literal>true</literal>,
|
||||
<literal>cue</literal> option is added to <literal>pam-u2f</literal>
|
||||
module and reminder message will be displayed.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
security.pam.enableEcryptfs = mkOption {
|
||||
|
@ -563,7 +650,7 @@ in
|
|||
++ optionals config.krb5.enable [pam_krb5 pam_ccreds]
|
||||
++ optionals config.security.pam.enableOTPW [ pkgs.otpw ]
|
||||
++ optionals config.security.pam.oath.enable [ pkgs.oathToolkit ]
|
||||
++ optionals config.security.pam.enableU2F [ pkgs.pam_u2f ];
|
||||
++ optionals config.security.pam.u2f.enable [ pkgs.pam_u2f ];
|
||||
|
||||
boot.supportedFilesystems = optionals config.security.pam.enableEcryptfs [ "ecryptfs" ];
|
||||
|
||||
|
|
|
@ -191,10 +191,9 @@ in {
|
|||
options = {
|
||||
|
||||
paths = mkOption {
|
||||
type = with types; either path (listOf str);
|
||||
type = with types; coercedTo str lib.singleton (listOf str);
|
||||
description = "Path(s) to back up.";
|
||||
example = "/home/user";
|
||||
apply = x: if isList x then x else [ x ];
|
||||
};
|
||||
|
||||
repo = mkOption {
|
||||
|
|
|
@ -6,11 +6,11 @@ let
|
|||
|
||||
cfg = config.services.postgresqlBackup;
|
||||
|
||||
postgresqlBackupService = db :
|
||||
postgresqlBackupService = db: dumpCmd:
|
||||
{
|
||||
enable = true;
|
||||
|
||||
description = "Backup of database ${db}";
|
||||
description = "Backup of ${db} database(s)";
|
||||
|
||||
requires = [ "postgresql.service" ];
|
||||
|
||||
|
@ -26,7 +26,7 @@ let
|
|||
${pkgs.coreutils}/bin/mv ${cfg.location}/${db}.sql.gz ${cfg.location}/${db}.prev.sql.gz
|
||||
fi
|
||||
|
||||
${config.services.postgresql.package}/bin/pg_dump ${cfg.pgdumpOptions} ${db} | \
|
||||
${dumpCmd} | \
|
||||
${pkgs.gzip}/bin/gzip -c > ${cfg.location}/${db}.sql.gz
|
||||
'';
|
||||
|
||||
|
@ -42,9 +42,7 @@ let
|
|||
in {
|
||||
|
||||
options = {
|
||||
|
||||
services.postgresqlBackup = {
|
||||
|
||||
enable = mkOption {
|
||||
default = false;
|
||||
description = ''
|
||||
|
@ -61,6 +59,19 @@ in {
|
|||
'';
|
||||
};
|
||||
|
||||
backupAll = mkOption {
|
||||
default = cfg.databases == [];
|
||||
defaultText = "services.postgresqlBackup.databases == []";
|
||||
type = lib.types.bool;
|
||||
description = ''
|
||||
Backup all databases using pg_dumpall.
|
||||
This option is mutual exclusive to
|
||||
<literal>services.postgresqlBackup.databases</literal>.
|
||||
The resulting backup dump will have the name all.sql.gz.
|
||||
This option is the default if no databases are specified.
|
||||
'';
|
||||
};
|
||||
|
||||
databases = mkOption {
|
||||
default = [];
|
||||
description = ''
|
||||
|
@ -79,18 +90,36 @@ in {
|
|||
type = types.string;
|
||||
default = "-Cbo";
|
||||
description = ''
|
||||
Command line options for pg_dump.
|
||||
Command line options for pg_dump. This options is not used
|
||||
if <literal>config.services.postgresqlBackup.backupAll</literal> is enabled.
|
||||
Note that config.services.postgresqlBackup.backupAll is also active,
|
||||
when no databases where specified.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
config = mkIf config.services.postgresqlBackup.enable {
|
||||
|
||||
systemd.services = listToAttrs (map (db : {
|
||||
config = mkMerge [
|
||||
{
|
||||
assertions = [{
|
||||
assertion = cfg.backupAll -> cfg.databases == [];
|
||||
message = "config.services.postgresqlBackup.backupAll cannot be used together with config.services.postgresqlBackup.databases";
|
||||
}];
|
||||
}
|
||||
(mkIf (cfg.enable && cfg.backupAll) {
|
||||
systemd.services.postgresqlBackup =
|
||||
postgresqlBackupService "all" "${config.services.postgresql.package}/bin/pg_dumpall";
|
||||
})
|
||||
(mkIf (cfg.enable && !cfg.backupAll) {
|
||||
systemd.services = listToAttrs (map (db:
|
||||
let
|
||||
cmd = "${config.services.postgresql.package}/bin/pg_dump ${cfg.pgdumpOptions} ${db}";
|
||||
in {
|
||||
name = "postgresqlBackup-${db}";
|
||||
value = postgresqlBackupService db; } ) cfg.databases);
|
||||
};
|
||||
value = postgresqlBackupService db cmd;
|
||||
}) cfg.databases);
|
||||
})
|
||||
];
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
# Type for a valid systemd unit option. Needed for correctly passing "timerConfig" to "systemd.timers"
|
||||
unitOption = (import ../../system/boot/systemd-unit-options.nix { inherit config lib; }).unitOption;
|
||||
in
|
||||
{
|
||||
options.services.restic.backups = mkOption {
|
||||
description = ''
|
||||
|
@ -47,7 +52,7 @@ with lib;
|
|||
};
|
||||
|
||||
timerConfig = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
type = types.attrsOf unitOption;
|
||||
default = {
|
||||
OnCalendar = "daily";
|
||||
};
|
||||
|
|
|
@ -249,6 +249,7 @@ in
|
|||
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
restartTriggers = [ config.environment.etc."my.cnf".source ];
|
||||
|
||||
unitConfig.RequiresMountsFor = "${cfg.dataDir}";
|
||||
|
||||
|
@ -274,7 +275,8 @@ in
|
|||
serviceConfig = {
|
||||
Type = if hasNotify then "notify" else "simple";
|
||||
RuntimeDirectory = "mysqld";
|
||||
ExecStart = "${mysql}/bin/mysqld --defaults-file=/etc/my.cnf ${mysqldOptions}";
|
||||
# The last two environment variables are used for starting Galera clusters
|
||||
ExecStart = "${mysql}/bin/mysqld --defaults-file=/etc/my.cnf ${mysqldOptions} $_WSREP_NEW_CLUSTER $_WSREP_START_POSITION";
|
||||
};
|
||||
|
||||
postStart = ''
|
||||
|
@ -362,7 +364,7 @@ in
|
|||
${optionalString (cfg.ensureDatabases != []) ''
|
||||
(
|
||||
${concatMapStrings (database: ''
|
||||
echo "CREATE DATABASE IF NOT EXISTS ${database};"
|
||||
echo "CREATE DATABASE IF NOT EXISTS \`${database}\`;"
|
||||
'') cfg.ensureDatabases}
|
||||
) | ${mysql}/bin/mysql -u root -N
|
||||
''}
|
||||
|
|
32
nixos/modules/services/desktops/gnome3/file-roller.nix
Normal file
32
nixos/modules/services/desktops/gnome3/file-roller.nix
Normal file
|
@ -0,0 +1,32 @@
|
|||
# File Roller.
|
||||
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
|
||||
###### interface
|
||||
|
||||
options = {
|
||||
|
||||
services.gnome3.file-roller = {
|
||||
|
||||
enable = mkEnableOption "File Roller, an archive manager for GNOME";
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf config.services.gnome3.file-roller.enable {
|
||||
|
||||
environment.systemPackages = [ pkgs.gnome3.file-roller ];
|
||||
|
||||
services.dbus.packages = [ pkgs.gnome3.file-roller ];
|
||||
|
||||
};
|
||||
|
||||
}
|
|
@ -4,8 +4,41 @@ with lib;
|
|||
|
||||
let
|
||||
cfg = config.services.minecraft-server;
|
||||
in
|
||||
{
|
||||
|
||||
# We don't allow eula=false anyways
|
||||
eulaFile = builtins.toFile "eula.txt" ''
|
||||
# eula.txt managed by NixOS Configuration
|
||||
eula=true
|
||||
'';
|
||||
|
||||
whitelistFile = pkgs.writeText "whitelist.json"
|
||||
(builtins.toJSON
|
||||
(mapAttrsToList (n: v: { name = n; uuid = v; }) cfg.whitelist));
|
||||
|
||||
cfgToString = v: if builtins.isBool v then boolToString v else toString v;
|
||||
|
||||
serverPropertiesFile = pkgs.writeText "server.properties" (''
|
||||
# server.properties managed by NixOS configuration
|
||||
'' + concatStringsSep "\n" (mapAttrsToList
|
||||
(n: v: "${n}=${cfgToString v}") cfg.serverProperties));
|
||||
|
||||
|
||||
# To be able to open the firewall, we need to read out port values in the
|
||||
# server properties, but fall back to the defaults when those don't exist.
|
||||
# These defaults are from https://minecraft.gamepedia.com/Server.properties#Java_Edition_3
|
||||
defaultServerPort = 25565;
|
||||
|
||||
serverPort = cfg.serverProperties.server-port or defaultServerPort;
|
||||
|
||||
rconPort = if cfg.serverProperties.enable-rcon or false
|
||||
then cfg.serverProperties."rcon.port" or 25575
|
||||
else null;
|
||||
|
||||
queryPort = if cfg.serverProperties.enable-query or false
|
||||
then cfg.serverProperties."query.port" or 25565
|
||||
else null;
|
||||
|
||||
in {
|
||||
options = {
|
||||
services.minecraft-server = {
|
||||
|
||||
|
@ -13,10 +46,32 @@ in
|
|||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
If enabled, start a Minecraft Server. The listening port for
|
||||
the server is always <literal>25565</literal>. The server
|
||||
If enabled, start a Minecraft Server. The server
|
||||
data will be loaded from and saved to
|
||||
<literal>${cfg.dataDir}</literal>.
|
||||
<option>services.minecraft-server.dataDir</option>.
|
||||
'';
|
||||
};
|
||||
|
||||
declarative = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to use a declarative Minecraft server configuration.
|
||||
Only if set to <literal>true</literal>, the options
|
||||
<option>services.minecraft-server.whitelist</option> and
|
||||
<option>services.minecraft-server.serverProperties</option> will be
|
||||
applied.
|
||||
'';
|
||||
};
|
||||
|
||||
eula = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether you agree to
|
||||
<link xlink:href="https://account.mojang.com/documents/minecraft_eula">
|
||||
Mojangs EULA</link>. This option must be set to
|
||||
<literal>true</literal> to run Minecraft server.
|
||||
'';
|
||||
};
|
||||
|
||||
|
@ -24,7 +79,7 @@ in
|
|||
type = types.path;
|
||||
default = "/var/lib/minecraft";
|
||||
description = ''
|
||||
Directory to store minecraft database and other state/data files.
|
||||
Directory to store Minecraft database and other state/data files.
|
||||
'';
|
||||
};
|
||||
|
||||
|
@ -32,21 +87,84 @@ in
|
|||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to open ports in the firewall (if enabled) for the server.
|
||||
Whether to open ports in the firewall for the server.
|
||||
'';
|
||||
};
|
||||
|
||||
whitelist = mkOption {
|
||||
type = let
|
||||
minecraftUUID = types.strMatching
|
||||
"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}" // {
|
||||
description = "Minecraft UUID";
|
||||
};
|
||||
in types.attrsOf minecraftUUID;
|
||||
default = {};
|
||||
description = ''
|
||||
Whitelisted players, only has an effect when
|
||||
<option>services.minecraft-server.declarative</option> is
|
||||
<literal>true</literal> and the whitelist is enabled
|
||||
via <option>services.minecraft-server.serverProperties</option> by
|
||||
setting <literal>white-list</literal> to <literal>true</literal>.
|
||||
This is a mapping from Minecraft usernames to UUIDs.
|
||||
You can use <link xlink:href="https://mcuuid.net/"/> to get a
|
||||
Minecraft UUID for a username.
|
||||
'';
|
||||
example = literalExample ''
|
||||
{
|
||||
username1 = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
|
||||
username2 = "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy";
|
||||
};
|
||||
'';
|
||||
};
|
||||
|
||||
serverProperties = mkOption {
|
||||
type = with types; attrsOf (either bool (either int str));
|
||||
default = {};
|
||||
example = literalExample ''
|
||||
{
|
||||
server-port = 43000;
|
||||
difficulty = 3;
|
||||
gamemode = 1;
|
||||
max-players = 5;
|
||||
motd = "NixOS Minecraft server!";
|
||||
white-list = true;
|
||||
enable-rcon = true;
|
||||
"rcon.password" = "hunter2";
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Minecraft server properties for the server.properties file. Only has
|
||||
an effect when <option>services.minecraft-server.declarative</option>
|
||||
is set to <literal>true</literal>. See
|
||||
<link xlink:href="https://minecraft.gamepedia.com/Server.properties#Java_Edition_3"/>
|
||||
for documentation on these values.
|
||||
'';
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.minecraft-server;
|
||||
defaultText = "pkgs.minecraft-server";
|
||||
example = literalExample "pkgs.minecraft-server_1_12_2";
|
||||
description = "Version of minecraft-server to run.";
|
||||
};
|
||||
|
||||
jvmOpts = mkOption {
|
||||
type = types.str;
|
||||
type = types.separatedString " ";
|
||||
default = "-Xmx2048M -Xms2048M";
|
||||
description = "JVM options for the Minecraft Service.";
|
||||
# Example options from https://minecraft.gamepedia.com/Tutorials/Server_startup_script
|
||||
example = "-Xmx2048M -Xms4092M -XX:+UseG1GC -XX:+CMSIncrementalPacing "
|
||||
+ "-XX:+CMSClassUnloadingEnabled -XX:ParallelGCThreads=2 "
|
||||
+ "-XX:MinHeapFreeRatio=5 -XX:MaxHeapFreeRatio=10";
|
||||
description = "JVM options for the Minecraft server.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
users.users.minecraft = {
|
||||
description = "Minecraft Server Service user";
|
||||
description = "Minecraft server service user";
|
||||
home = cfg.dataDir;
|
||||
createHome = true;
|
||||
uid = config.ids.uids.minecraft;
|
||||
|
@ -57,17 +175,60 @@ in
|
|||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
|
||||
serviceConfig.Restart = "always";
|
||||
serviceConfig.User = "minecraft";
|
||||
script = ''
|
||||
cd ${cfg.dataDir}
|
||||
exec ${pkgs.minecraft-server}/bin/minecraft-server ${cfg.jvmOpts}
|
||||
'';
|
||||
serviceConfig = {
|
||||
ExecStart = "${cfg.package}/bin/minecraft-server ${cfg.jvmOpts}";
|
||||
Restart = "always";
|
||||
User = "minecraft";
|
||||
WorkingDirectory = cfg.dataDir;
|
||||
};
|
||||
|
||||
preStart = ''
|
||||
ln -sf ${eulaFile} eula.txt
|
||||
'' + (if cfg.declarative then ''
|
||||
|
||||
if [ -e .declarative ]; then
|
||||
|
||||
# Was declarative before, no need to back up anything
|
||||
ln -sf ${whitelistFile} whitelist.json
|
||||
cp -f ${serverPropertiesFile} server.properties
|
||||
|
||||
else
|
||||
|
||||
# Declarative for the first time, backup stateful files
|
||||
ln -sb --suffix=.stateful ${whitelistFile} whitelist.json
|
||||
cp -b --suffix=.stateful ${serverPropertiesFile} server.properties
|
||||
|
||||
# server.properties must have write permissions, because every time
|
||||
# the server starts it first parses the file and then regenerates it..
|
||||
chmod +w server.properties
|
||||
echo "Autogenerated file that signifies that this server configuration is managed declaratively by NixOS" \
|
||||
> .declarative
|
||||
|
||||
fi
|
||||
'' else ''
|
||||
if [ -e .declarative ]; then
|
||||
rm .declarative
|
||||
fi
|
||||
'');
|
||||
};
|
||||
|
||||
networking.firewall = mkIf cfg.openFirewall {
|
||||
allowedUDPPorts = [ 25565 ];
|
||||
allowedTCPPorts = [ 25565 ];
|
||||
};
|
||||
networking.firewall = mkIf cfg.openFirewall (if cfg.declarative then {
|
||||
allowedUDPPorts = [ serverPort ];
|
||||
allowedTCPPorts = [ serverPort ]
|
||||
++ optional (! isNull queryPort) queryPort
|
||||
++ optional (! isNull rconPort) rconPort;
|
||||
} else {
|
||||
allowedUDPPorts = [ defaultServerPort ];
|
||||
allowedTCPPorts = [ defaultServerPort ];
|
||||
});
|
||||
|
||||
assertions = [
|
||||
{ assertion = cfg.eula;
|
||||
message = "You must agree to Mojangs EULA to run minecraft-server."
|
||||
+ " Read https://account.mojang.com/documents/minecraft_eula and"
|
||||
+ " set `services.minecraft-server.eula` to `true` if you agree.";
|
||||
}
|
||||
];
|
||||
|
||||
};
|
||||
}
|
||||
|
|
|
@ -15,6 +15,19 @@ let
|
|||
mkName = p: "pki/fwupd/${baseNameOf (toString p)}";
|
||||
mkEtcFile = p: nameValuePair (mkName p) { source = p; };
|
||||
in listToAttrs (map mkEtcFile cfg.extraTrustedKeys);
|
||||
|
||||
# We cannot include the file in $out and rely on filesInstalledToEtc
|
||||
# to install it because it would create a cyclic dependency between
|
||||
# the outputs. We also need to enable the remote,
|
||||
# which should not be done by default.
|
||||
testRemote = if cfg.enableTestRemote then {
|
||||
"fwupd/remotes.d/fwupd-tests.conf" = {
|
||||
source = pkgs.runCommand "fwupd-tests-enabled.conf" {} ''
|
||||
sed "s,^Enabled=false,Enabled=true," \
|
||||
"${pkgs.fwupd.installedTests}/etc/fwupd/remotes.d/fwupd-tests.conf" > "$out"
|
||||
'';
|
||||
};
|
||||
} else {};
|
||||
in {
|
||||
|
||||
###### interface
|
||||
|
@ -40,7 +53,7 @@ in {
|
|||
|
||||
blacklistPlugins = mkOption {
|
||||
type = types.listOf types.string;
|
||||
default = [];
|
||||
default = [ "test" ];
|
||||
example = [ "udev" ];
|
||||
description = ''
|
||||
Allow blacklisting specific plugins
|
||||
|
@ -55,6 +68,15 @@ in {
|
|||
Installing a public key allows firmware signed with a matching private key to be recognized as trusted, which may require less authentication to install than for untrusted files. By default trusted firmware can be upgraded (but not downgraded) without the user or administrator password. Only very few keys are installed by default.
|
||||
'';
|
||||
};
|
||||
|
||||
enableTestRemote = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to enable test remote. This is used by
|
||||
<link xlink:href="https://github.com/hughsie/fwupd/blob/master/data/installed-tests/README.md">installed tests</link>.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -78,7 +100,7 @@ in {
|
|||
'';
|
||||
};
|
||||
|
||||
} // originalEtc // extraTrustedKeys;
|
||||
} // originalEtc // extraTrustedKeys // testRemote;
|
||||
|
||||
services.dbus.packages = [ pkgs.fwupd ];
|
||||
|
||||
|
|
|
@ -25,6 +25,20 @@ in
|
|||
description = "Hostname to use for the nginx vhost";
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.roundcube;
|
||||
|
||||
example = literalExample ''
|
||||
roundcube.withPlugins (plugins: [ plugins.persistent_login ])
|
||||
'';
|
||||
|
||||
description = ''
|
||||
The package which contains roundcube's sources. Can be overriden to create
|
||||
an environment which contains roundcube and third-party plugins.
|
||||
'';
|
||||
};
|
||||
|
||||
database = {
|
||||
username = mkOption {
|
||||
type = types.str;
|
||||
|
@ -86,7 +100,7 @@ in
|
|||
forceSSL = mkDefault true;
|
||||
enableACME = mkDefault true;
|
||||
locations."/" = {
|
||||
root = pkgs.roundcube;
|
||||
root = cfg.package;
|
||||
index = "index.php";
|
||||
extraConfig = ''
|
||||
location ~* \.php$ {
|
||||
|
@ -140,12 +154,12 @@ in
|
|||
${pkgs.sudo}/bin/sudo -u ${pgSuperUser} psql postgres -c "create database ${cfg.database.dbname} with owner ${cfg.database.username}";
|
||||
fi
|
||||
PGPASSWORD=${cfg.database.password} ${pkgs.postgresql}/bin/psql -U ${cfg.database.username} \
|
||||
-f ${pkgs.roundcube}/SQL/postgres.initial.sql \
|
||||
-f ${cfg.package}/SQL/postgres.initial.sql \
|
||||
-h ${cfg.database.host} ${cfg.database.dbname}
|
||||
touch /var/lib/roundcube/db-created
|
||||
fi
|
||||
|
||||
${pkgs.php}/bin/php ${pkgs.roundcube}/bin/update.sh
|
||||
${pkgs.php}/bin/php ${cfg.package}/bin/update.sh
|
||||
'';
|
||||
serviceConfig.Type = "oneshot";
|
||||
};
|
||||
|
|
|
@ -25,6 +25,14 @@ in {
|
|||
'';
|
||||
};
|
||||
|
||||
virtualHost = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Name of the nginx virtualhost to use and setup. If null, do not setup any virtualhost.
|
||||
'';
|
||||
};
|
||||
|
||||
listenAddress = mkOption {
|
||||
type = types.string;
|
||||
default = "127.0.0.1";
|
||||
|
@ -116,6 +124,8 @@ in {
|
|||
-Dserver.port=${toString cfg.port} \
|
||||
-Dairsonic.contextPath=${cfg.contextPath} \
|
||||
-Djava.awt.headless=true \
|
||||
${optionalString (cfg.virtualHost != null)
|
||||
"-Dserver.use-forward-headers=true"} \
|
||||
${toString cfg.jvmOptions} \
|
||||
-verbose:gc \
|
||||
-jar ${pkgs.airsonic}/webapps/airsonic.war
|
||||
|
@ -126,6 +136,13 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
services.nginx = mkIf (cfg.virtualHost != null) {
|
||||
enable = true;
|
||||
virtualHosts."${cfg.virtualHost}" = {
|
||||
locations."${cfg.contextPath}".proxyPass = "http://${cfg.listenAddress}:${toString cfg.port}";
|
||||
};
|
||||
};
|
||||
|
||||
users.users.airsonic = {
|
||||
description = "Airsonic service user";
|
||||
name = cfg.user;
|
||||
|
|
|
@ -18,7 +18,7 @@ let
|
|||
delete.enabled = cfg.enableDelete;
|
||||
};
|
||||
http = {
|
||||
addr = ":${builtins.toString cfg.port}";
|
||||
addr = "${cfg.listenAddress}:${builtins.toString cfg.port}";
|
||||
headers.X-Content-Type-Options = ["nosniff"];
|
||||
};
|
||||
health.storagedriver = {
|
||||
|
|
|
@ -46,6 +46,9 @@ let
|
|||
ROOT_PATH = ${cfg.log.rootPath}
|
||||
LEVEL = ${cfg.log.level}
|
||||
|
||||
[service]
|
||||
DISABLE_REGISTRATION = ${boolToString cfg.disableRegistration}
|
||||
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
in
|
||||
|
@ -248,6 +251,18 @@ in
|
|||
description = "Upper level of template and static files path.";
|
||||
};
|
||||
|
||||
disableRegistration = mkEnableOption "the registration lock" // {
|
||||
description = ''
|
||||
By default any user can create an account on this <literal>gitea</literal> instance.
|
||||
This can be disabled by using this option.
|
||||
|
||||
<emphasis>Note:</emphasis> please keep in mind that this should be added after the initial
|
||||
deploy unless <link linkend="opt-services.gitea.useWizard">services.gitea.useWizard</link>
|
||||
is <literal>true</literal> as the first registered user will be the administrator if
|
||||
no install wizard is used.
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
|
@ -263,7 +278,7 @@ in
|
|||
description = "gitea";
|
||||
after = [ "network.target" ] ++ lib.optional usePostgresql "postgresql.service" ++ lib.optional useMysql "mysql.service";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
path = [ gitea.bin ];
|
||||
path = [ gitea.bin pkgs.gitAndTools.git ];
|
||||
|
||||
preStart = let
|
||||
runConfig = "${cfg.stateDir}/custom/conf/app.ini";
|
||||
|
|
|
@ -497,7 +497,12 @@ in {
|
|||
systemd.services.gitaly = {
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
path = with pkgs; [ gitAndTools.git cfg.packages.gitaly.rubyEnv cfg.packages.gitaly.rubyEnv.wrappedRuby ];
|
||||
path = with pkgs; [
|
||||
openssh
|
||||
gitAndTools.git
|
||||
cfg.packages.gitaly.rubyEnv
|
||||
cfg.packages.gitaly.rubyEnv.wrappedRuby
|
||||
];
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
User = cfg.user;
|
||||
|
|
|
@ -6,9 +6,18 @@ let
|
|||
cfg = config.services.home-assistant;
|
||||
|
||||
# cfg.config != null can be assumed here
|
||||
configFile = pkgs.writeText "configuration.json"
|
||||
configJSON = pkgs.writeText "configuration.json"
|
||||
(builtins.toJSON (if cfg.applyDefaultConfig then
|
||||
(lib.recursiveUpdate defaultConfig cfg.config) else cfg.config));
|
||||
(recursiveUpdate defaultConfig cfg.config) else cfg.config));
|
||||
configFile = pkgs.runCommand "configuration.yaml" { } ''
|
||||
${pkgs.remarshal}/bin/json2yaml -i ${configJSON} -o $out
|
||||
'';
|
||||
|
||||
lovelaceConfigJSON = pkgs.writeText "ui-lovelace.json"
|
||||
(builtins.toJSON cfg.lovelaceConfig);
|
||||
lovelaceConfigFile = pkgs.runCommand "ui-lovelace.yaml" { } ''
|
||||
${pkgs.remarshal}/bin/json2yaml -i ${lovelaceConfigJSON} -o $out
|
||||
'';
|
||||
|
||||
availableComponents = pkgs.home-assistant.availableComponents;
|
||||
|
||||
|
@ -44,7 +53,9 @@ let
|
|||
# If you are changing this, please update the description in applyDefaultConfig
|
||||
defaultConfig = {
|
||||
homeassistant.time_zone = config.time.timeZone;
|
||||
http.server_port = (toString cfg.port);
|
||||
http.server_port = cfg.port;
|
||||
} // optionalAttrs (cfg.lovelaceConfig != null) {
|
||||
lovelace.mode = "yaml";
|
||||
};
|
||||
|
||||
in {
|
||||
|
@ -99,6 +110,53 @@ in {
|
|||
'';
|
||||
};
|
||||
|
||||
configWritable = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to make <filename>configuration.yaml</filename> writable.
|
||||
This only has an effect if <option>config</option> is set.
|
||||
This will allow you to edit it from Home Assistant's web interface.
|
||||
However, bear in mind that it will be overwritten at every start of the service.
|
||||
'';
|
||||
};
|
||||
|
||||
lovelaceConfig = mkOption {
|
||||
default = null;
|
||||
type = with types; nullOr attrs;
|
||||
# from https://www.home-assistant.io/lovelace/yaml-mode/
|
||||
example = literalExample ''
|
||||
{
|
||||
title = "My Awesome Home";
|
||||
views = [ {
|
||||
title = "Example";
|
||||
cards = [ {
|
||||
type = "markdown";
|
||||
title = "Lovelace";
|
||||
content = "Welcome to your **Lovelace UI**.";
|
||||
} ];
|
||||
} ];
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Your <filename>ui-lovelace.yaml</filename> as a Nix attribute set.
|
||||
Setting this option will automatically add
|
||||
<literal>lovelace.mode = "yaml";</literal> to your <option>config</option>.
|
||||
Beware that setting this option will delete your previous <filename>ui-lovelace.yaml</filename>
|
||||
'';
|
||||
};
|
||||
|
||||
lovelaceConfigWritable = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to make <filename>ui-lovelace.yaml</filename> writable.
|
||||
This only has an effect if <option>lovelaceConfig</option> is set.
|
||||
This will allow you to edit it from Home Assistant's web interface.
|
||||
However, bear in mind that it will be overwritten at every start of the service.
|
||||
'';
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
default = pkgs.home-assistant;
|
||||
defaultText = "pkgs.home-assistant";
|
||||
|
@ -144,12 +202,17 @@ in {
|
|||
systemd.services.home-assistant = {
|
||||
description = "Home Assistant";
|
||||
after = [ "network.target" ];
|
||||
preStart = lib.optionalString (cfg.config != null) ''
|
||||
config=${cfg.configDir}/configuration.yaml
|
||||
rm -f $config
|
||||
${pkgs.remarshal}/bin/json2yaml -i ${configFile} -o $config
|
||||
chmod 444 $config
|
||||
'';
|
||||
preStart = optionalString (cfg.config != null) (if cfg.configWritable then ''
|
||||
cp --no-preserve=mode ${configFile} "${cfg.configDir}/configuration.yaml"
|
||||
'' else ''
|
||||
rm -f "${cfg.configDir}/configuration.yaml"
|
||||
ln -s ${configFile} "${cfg.configDir}/configuration.yaml"
|
||||
'') + optionalString (cfg.lovelaceConfig != null) (if cfg.lovelaceConfigWritable then ''
|
||||
cp --no-preserve=mode ${lovelaceConfigFile} "${cfg.configDir}/ui-lovelace.yaml"
|
||||
'' else ''
|
||||
rm -f "${cfg.configDir}/ui-lovelace.yaml"
|
||||
ln -s ${lovelaceConfigFile} "${cfg.configDir}/ui-lovelace.yaml"
|
||||
'');
|
||||
serviceConfig = {
|
||||
ExecStart = "${package}/bin/hass --config '${cfg.configDir}'";
|
||||
User = "hass";
|
||||
|
|
|
@ -651,12 +651,16 @@ in {
|
|||
|
||||
services.postgresql.enable = mkIf usePostgresql (mkDefault true);
|
||||
|
||||
systemd.services.matrix-synapse = {
|
||||
systemd.services.matrix-synapse =
|
||||
let
|
||||
python = (pkgs.python3.withPackages (ps: with ps; [ (ps.toPythonModule cfg.package) ]));
|
||||
in
|
||||
{
|
||||
description = "Synapse Matrix homeserver";
|
||||
after = [ "network.target" "postgresql.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
preStart = ''
|
||||
${cfg.package}/bin/homeserver \
|
||||
${python.interpreter} -m synapse.app.homeserver \
|
||||
--config-path ${configFile} \
|
||||
--keys-directory ${cfg.dataDir} \
|
||||
--generate-keys
|
||||
|
@ -687,10 +691,11 @@ in {
|
|||
WorkingDirectory = cfg.dataDir;
|
||||
PermissionsStartOnly = true;
|
||||
ExecStart = ''
|
||||
${cfg.package}/bin/homeserver \
|
||||
${python.interpreter} -m synapse.app.homeserver \
|
||||
${ concatMapStringsSep "\n " (x: "--config-path ${x} \\") ([ configFile ] ++ cfg.extraConfigFiles) }
|
||||
--keys-directory ${cfg.dataDir}
|
||||
'';
|
||||
ExecReload = "${pkgs.utillinux}/bin/kill -HUP $MAINPID";
|
||||
Restart = "on-failure";
|
||||
};
|
||||
};
|
||||
|
|
|
@ -4,6 +4,7 @@ with lib;
|
|||
|
||||
let
|
||||
cfg = config.services.nzbget;
|
||||
dataDir = builtins.dirOf cfg.configFile;
|
||||
in {
|
||||
options = {
|
||||
services.nzbget = {
|
||||
|
@ -16,6 +17,20 @@ in {
|
|||
description = "The NZBGet package to use";
|
||||
};
|
||||
|
||||
dataDir = mkOption {
|
||||
type = types.str;
|
||||
default = "/var/lib/nzbget";
|
||||
description = "The directory where NZBGet stores its configuration files.";
|
||||
};
|
||||
|
||||
openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Open ports in the firewall for the NZBGet web interface
|
||||
'';
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
default = "nzbget";
|
||||
|
@ -27,6 +42,12 @@ in {
|
|||
default = "nzbget";
|
||||
description = "Group under which NZBGet runs";
|
||||
};
|
||||
|
||||
configFile = mkOption {
|
||||
type = types.str;
|
||||
default = "/var/lib/nzbget/nzbget.conf";
|
||||
description = "Path for NZBGet's config file. (If this doesn't exist, the default config template is copied here.)";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -40,35 +61,25 @@ in {
|
|||
p7zip
|
||||
];
|
||||
preStart = ''
|
||||
datadir=/var/lib/nzbget
|
||||
cfgtemplate=${cfg.package}/share/nzbget/nzbget.conf
|
||||
test -d $datadir || {
|
||||
echo "Creating nzbget data directory in $datadir"
|
||||
mkdir -p $datadir
|
||||
}
|
||||
test -f $configfile || {
|
||||
echo "nzbget.conf not found. Copying default config $cfgtemplate to $configfile"
|
||||
cp $cfgtemplate $configfile
|
||||
echo "Setting $configfile permissions to 0700 (needs to be written and contains plaintext credentials)"
|
||||
chmod 0700 $configfile
|
||||
if [ ! -f ${cfg.configFile} ]; then
|
||||
echo "${cfg.configFile} not found. Copying default config $cfgtemplate to ${cfg.configFile}"
|
||||
install -m 0700 $cfgtemplate ${cfg.configFile}
|
||||
echo "Setting temporary \$MAINDIR variable in default config required in order to allow nzbget to complete initial start"
|
||||
echo "Remember to change this to a proper value once NZBGet startup has been completed"
|
||||
sed -i -e 's/MainDir=.*/MainDir=\/tmp/g' $configfile
|
||||
}
|
||||
echo "Ensuring proper ownership of $datadir (${cfg.user}:${cfg.group})."
|
||||
chown -R ${cfg.user}:${cfg.group} $datadir
|
||||
sed -i -e 's/MainDir=.*/MainDir=\/tmp/g' ${cfg.configFile}
|
||||
fi
|
||||
'';
|
||||
|
||||
script = ''
|
||||
configfile=/var/lib/nzbget/nzbget.conf
|
||||
args="--daemon --configfile $configfile"
|
||||
# The script in preStart (above) copies nzbget's config template to datadir on first run, containing paths that point to the nzbget derivation installed at the time.
|
||||
# These paths break when nzbget is upgraded & the original derivation is garbage collected. If such broken paths are found in the config file, override them to point to
|
||||
args="--daemon --configfile ${cfg.configFile}"
|
||||
# The script in preStart (above) copies nzbget's config template to datadir on first run, containing paths that point to the nzbget derivation installed at the time.
|
||||
# These paths break when nzbget is upgraded & the original derivation is garbage collected. If such broken paths are found in the config file, override them to point to
|
||||
# the currently installed nzbget derivation.
|
||||
cfgfallback () {
|
||||
local hit=`grep -Po "(?<=^$1=).*+" "$configfile" | sed 's/[ \t]*$//'` # Strip trailing whitespace
|
||||
local hit=`grep -Po "(?<=^$1=).*+" "${cfg.configFile}" | sed 's/[ \t]*$//'` # Strip trailing whitespace
|
||||
( test $hit && test -e $hit ) || {
|
||||
echo "In $configfile, valid $1 not found; falling back to $1=$2"
|
||||
echo "In ${cfg.configFile}, valid $1 not found; falling back to $1=$2"
|
||||
args+=" -o $1=$2"
|
||||
}
|
||||
}
|
||||
|
@ -78,6 +89,8 @@ in {
|
|||
'';
|
||||
|
||||
serviceConfig = {
|
||||
StateDirectory = dataDir;
|
||||
StateDirectoryMode = "0700";
|
||||
Type = "forking";
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
|
@ -86,6 +99,10 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
networking.firewall = mkIf cfg.openFirewall {
|
||||
allowedTCPPorts = [ 8989 ];
|
||||
};
|
||||
|
||||
users.users = mkIf (cfg.user == "nzbget") {
|
||||
nzbget = {
|
||||
group = cfg.group;
|
||||
|
|
|
@ -145,7 +145,8 @@ in
|
|||
PLEX_MEDIA_SERVER_HOME="${cfg.package}/usr/lib/plexmediaserver";
|
||||
PLEX_MEDIA_SERVER_MAX_PLUGIN_PROCS="6";
|
||||
PLEX_MEDIA_SERVER_TMPDIR="/tmp";
|
||||
LD_LIBRARY_PATH="${cfg.package}/usr/lib/plexmediaserver";
|
||||
PLEX_MEDIA_SERVER_USE_SYSLOG="true";
|
||||
LD_LIBRARY_PATH="/run/opengl-driver/lib:${cfg.package}/usr/lib/plexmediaserver";
|
||||
LC_ALL="en_US.UTF-8";
|
||||
LANG="en_US.UTF-8";
|
||||
};
|
||||
|
|
|
@ -5,20 +5,8 @@ with lib;
|
|||
let
|
||||
cfg = config.services.pykms;
|
||||
|
||||
home = "/var/lib/pykms";
|
||||
|
||||
services = {
|
||||
serviceConfig = {
|
||||
Restart = "on-failure";
|
||||
RestartSec = "10s";
|
||||
StartLimitInterval = "1min";
|
||||
PrivateTmp = true;
|
||||
ProtectSystem = "full";
|
||||
ProtectHome = true;
|
||||
};
|
||||
};
|
||||
|
||||
in {
|
||||
meta.maintainers = with lib.maintainers; [ peterhoeg ];
|
||||
|
||||
options = {
|
||||
services.pykms = rec {
|
||||
|
@ -51,39 +39,38 @@ in {
|
|||
default = false;
|
||||
description = "Whether the listening port should be opened automatically.";
|
||||
};
|
||||
|
||||
memoryLimit = mkOption {
|
||||
type = types.str;
|
||||
default = "64M";
|
||||
description = "How much memory to use at most.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewallPort [ cfg.port ];
|
||||
|
||||
systemd.services = {
|
||||
pykms = services // {
|
||||
description = "Python KMS";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = with pkgs; {
|
||||
User = "pykms";
|
||||
Group = "pykms";
|
||||
ExecStartPre = "${getBin pykms}/bin/create_pykms_db.sh ${home}/clients.db";
|
||||
ExecStart = "${getBin pykms}/bin/server.py ${optionalString cfg.verbose "--verbose"} ${cfg.listenAddress} ${toString cfg.port}";
|
||||
WorkingDirectory = home;
|
||||
MemoryLimit = "64M";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
users = {
|
||||
users.pykms = {
|
||||
name = "pykms";
|
||||
group = "pykms";
|
||||
home = home;
|
||||
createHome = true;
|
||||
uid = config.ids.uids.pykms;
|
||||
description = "PyKMS daemon user";
|
||||
};
|
||||
|
||||
groups.pykms = {
|
||||
gid = config.ids.gids.pykms;
|
||||
systemd.services.pykms = let
|
||||
home = "/var/lib/pykms";
|
||||
in {
|
||||
description = "Python KMS";
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
# python programs with DynamicUser = true require HOME to be set
|
||||
environment.HOME = home;
|
||||
serviceConfig = with pkgs; {
|
||||
DynamicUser = true;
|
||||
StateDirectory = baseNameOf home;
|
||||
ExecStartPre = "${getBin pykms}/bin/create_pykms_db.sh ${home}/clients.db";
|
||||
ExecStart = lib.concatStringsSep " " ([
|
||||
"${getBin pykms}/bin/server.py"
|
||||
cfg.listenAddress
|
||||
(toString cfg.port)
|
||||
] ++ lib.optional cfg.verbose "--verbose");
|
||||
WorkingDirectory = home;
|
||||
Restart = "on-failure";
|
||||
MemoryLimit = cfg.memoryLimit;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -30,6 +30,13 @@ let
|
|||
${cfg.extraConfig}
|
||||
'';
|
||||
|
||||
additionalEnvironment = pkgs.writeText "additional_environment.rb" ''
|
||||
config.logger = Logger.new("${cfg.stateDir}/log/production.log", 14, 1048576)
|
||||
config.logger.level = Logger::INFO
|
||||
|
||||
${cfg.extraEnv}
|
||||
'';
|
||||
|
||||
unpackTheme = unpack "theme";
|
||||
unpackPlugin = unpack "plugin";
|
||||
unpack = id: (name: source:
|
||||
|
@ -54,12 +61,20 @@ in
|
|||
description = "Enable the Redmine service.";
|
||||
};
|
||||
|
||||
# default to the 4.x series not forcing major version upgrade of those on the 3.x series
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.redmine;
|
||||
default = if versionAtLeast config.system.stateVersion "19.03"
|
||||
then pkgs.redmine_4
|
||||
else pkgs.redmine
|
||||
;
|
||||
defaultText = "pkgs.redmine";
|
||||
description = "Which Redmine package to use.";
|
||||
example = "pkgs.redmine.override { ruby = pkgs.ruby_2_3; }";
|
||||
description = ''
|
||||
Which Redmine package to use. This defaults to version 3.x if
|
||||
<literal>system.stateVersion < 19.03</literal> and version 4.x
|
||||
otherwise.
|
||||
'';
|
||||
example = "pkgs.redmine_4.override { ruby = pkgs.ruby_2_4; }";
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
|
@ -103,6 +118,19 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
extraEnv = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Extra configuration in additional_environment.rb.
|
||||
|
||||
See https://svn.redmine.org/redmine/trunk/config/additional_environment.rb.example
|
||||
'';
|
||||
example = literalExample ''
|
||||
config.logger.level = Logger::DEBUG
|
||||
'';
|
||||
};
|
||||
|
||||
themes = mkOption {
|
||||
type = types.attrsOf types.path;
|
||||
default = {};
|
||||
|
@ -249,6 +277,9 @@ in
|
|||
# link in the application configuration
|
||||
ln -fs ${configurationYml} "${cfg.stateDir}/config/configuration.yml"
|
||||
|
||||
# link in the additional environment configuration
|
||||
ln -fs ${additionalEnvironment} "${cfg.stateDir}/config/additional_environment.rb"
|
||||
|
||||
|
||||
# link in all user specified themes
|
||||
rm -rf "${cfg.stateDir}/public/themes/"*
|
||||
|
@ -292,6 +323,7 @@ in
|
|||
# execute redmine required commands prior to starting the application
|
||||
# NOTE: su required in case using mysql socket authentication
|
||||
/run/wrappers/bin/su -s ${pkgs.bash}/bin/bash -m -l redmine -c '${bundle} exec rake db:migrate'
|
||||
/run/wrappers/bin/su -s ${pkgs.bash}/bin/bash -m -l redmine -c '${bundle} exec rake redmine:plugins:migrate'
|
||||
/run/wrappers/bin/su -s ${pkgs.bash}/bin/bash -m -l redmine -c '${bundle} exec rake redmine:load_default_data'
|
||||
|
||||
|
||||
|
|
|
@ -85,70 +85,70 @@ let
|
|||
portOptions = { name, ...}: {
|
||||
options = {
|
||||
name = mkOption {
|
||||
internal = true;
|
||||
default = name;
|
||||
internal = true;
|
||||
default = name;
|
||||
};
|
||||
|
||||
ip = mkOption {
|
||||
default = "127.0.0.1";
|
||||
description = "Ip where rippled listens.";
|
||||
type = types.str;
|
||||
default = "127.0.0.1";
|
||||
description = "Ip where rippled listens.";
|
||||
type = types.str;
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
description = "Port where rippled listens.";
|
||||
type = types.int;
|
||||
description = "Port where rippled listens.";
|
||||
type = types.int;
|
||||
};
|
||||
|
||||
protocol = mkOption {
|
||||
description = "Protocols expose by rippled.";
|
||||
type = types.listOf (types.enum ["http" "https" "ws" "wss" "peer"]);
|
||||
description = "Protocols expose by rippled.";
|
||||
type = types.listOf (types.enum ["http" "https" "ws" "wss" "peer"]);
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
description = "When set, these credentials will be required on HTTP/S requests.";
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = "When set, these credentials will be required on HTTP/S requests.";
|
||||
type = types.str;
|
||||
default = "";
|
||||
};
|
||||
|
||||
password = mkOption {
|
||||
description = "When set, these credentials will be required on HTTP/S requests.";
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = "When set, these credentials will be required on HTTP/S requests.";
|
||||
type = types.str;
|
||||
default = "";
|
||||
};
|
||||
|
||||
admin = mkOption {
|
||||
description = "A comma-separated list of admin IP addresses.";
|
||||
type = types.listOf types.str;
|
||||
default = ["127.0.0.1"];
|
||||
description = "A comma-separated list of admin IP addresses.";
|
||||
type = types.listOf types.str;
|
||||
default = ["127.0.0.1"];
|
||||
};
|
||||
|
||||
ssl = {
|
||||
key = mkOption {
|
||||
description = ''
|
||||
Specifies the filename holding the SSL key in PEM format.
|
||||
'';
|
||||
default = null;
|
||||
type = types.nullOr types.path;
|
||||
};
|
||||
key = mkOption {
|
||||
description = ''
|
||||
Specifies the filename holding the SSL key in PEM format.
|
||||
'';
|
||||
default = null;
|
||||
type = types.nullOr types.path;
|
||||
};
|
||||
|
||||
cert = mkOption {
|
||||
description = ''
|
||||
Specifies the path to the SSL certificate file in PEM format.
|
||||
This is not needed if the chain includes it.
|
||||
'';
|
||||
default = null;
|
||||
type = types.nullOr types.path;
|
||||
};
|
||||
cert = mkOption {
|
||||
description = ''
|
||||
Specifies the path to the SSL certificate file in PEM format.
|
||||
This is not needed if the chain includes it.
|
||||
'';
|
||||
default = null;
|
||||
type = types.nullOr types.path;
|
||||
};
|
||||
|
||||
chain = mkOption {
|
||||
description = ''
|
||||
If you need a certificate chain, specify the path to the
|
||||
certificate chain here. The chain may include the end certificate.
|
||||
'';
|
||||
default = null;
|
||||
type = types.nullOr types.path;
|
||||
};
|
||||
chain = mkOption {
|
||||
description = ''
|
||||
If you need a certificate chain, specify the path to the
|
||||
certificate chain here. The chain may include the end certificate.
|
||||
'';
|
||||
default = null;
|
||||
type = types.nullOr types.path;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -175,14 +175,14 @@ let
|
|||
|
||||
onlineDelete = mkOption {
|
||||
description = "Enable automatic purging of older ledger information.";
|
||||
type = types.addCheck (types.nullOr types.int) (v: v > 256);
|
||||
type = types.nullOr (types.addCheck types.int (v: v > 256));
|
||||
default = cfg.ledgerHistory;
|
||||
};
|
||||
|
||||
advisoryDelete = mkOption {
|
||||
description = ''
|
||||
If set, then require administrative RPC call "can_delete"
|
||||
to enable online deletion of ledger records.
|
||||
If set, then require administrative RPC call "can_delete"
|
||||
to enable online deletion of ledger records.
|
||||
'';
|
||||
type = types.nullOr types.bool;
|
||||
default = null;
|
||||
|
@ -207,168 +207,168 @@ in
|
|||
enable = mkEnableOption "rippled";
|
||||
|
||||
package = mkOption {
|
||||
description = "Which rippled package to use.";
|
||||
type = types.package;
|
||||
default = pkgs.rippled;
|
||||
defaultText = "pkgs.rippled";
|
||||
description = "Which rippled package to use.";
|
||||
type = types.package;
|
||||
default = pkgs.rippled;
|
||||
defaultText = "pkgs.rippled";
|
||||
};
|
||||
|
||||
ports = mkOption {
|
||||
description = "Ports exposed by rippled";
|
||||
type = with types; attrsOf (submodule portOptions);
|
||||
default = {
|
||||
rpc = {
|
||||
port = 5005;
|
||||
admin = ["127.0.0.1"];
|
||||
protocol = ["http"];
|
||||
};
|
||||
description = "Ports exposed by rippled";
|
||||
type = with types; attrsOf (submodule portOptions);
|
||||
default = {
|
||||
rpc = {
|
||||
port = 5005;
|
||||
admin = ["127.0.0.1"];
|
||||
protocol = ["http"];
|
||||
};
|
||||
|
||||
peer = {
|
||||
port = 51235;
|
||||
ip = "0.0.0.0";
|
||||
protocol = ["peer"];
|
||||
};
|
||||
peer = {
|
||||
port = 51235;
|
||||
ip = "0.0.0.0";
|
||||
protocol = ["peer"];
|
||||
};
|
||||
|
||||
ws_public = {
|
||||
port = 5006;
|
||||
ip = "0.0.0.0";
|
||||
protocol = ["ws" "wss"];
|
||||
};
|
||||
};
|
||||
ws_public = {
|
||||
port = 5006;
|
||||
ip = "0.0.0.0";
|
||||
protocol = ["ws" "wss"];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
nodeDb = mkOption {
|
||||
description = "Rippled main database options.";
|
||||
type = with types; nullOr (submodule dbOptions);
|
||||
default = {
|
||||
type = "rocksdb";
|
||||
extraOpts = ''
|
||||
open_files=2000
|
||||
filter_bits=12
|
||||
cache_mb=256
|
||||
file_size_pb=8
|
||||
file_size_mult=2;
|
||||
'';
|
||||
};
|
||||
description = "Rippled main database options.";
|
||||
type = with types; nullOr (submodule dbOptions);
|
||||
default = {
|
||||
type = "rocksdb";
|
||||
extraOpts = ''
|
||||
open_files=2000
|
||||
filter_bits=12
|
||||
cache_mb=256
|
||||
file_size_pb=8
|
||||
file_size_mult=2;
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
tempDb = mkOption {
|
||||
description = "Rippled temporary database options.";
|
||||
type = with types; nullOr (submodule dbOptions);
|
||||
default = null;
|
||||
description = "Rippled temporary database options.";
|
||||
type = with types; nullOr (submodule dbOptions);
|
||||
default = null;
|
||||
};
|
||||
|
||||
importDb = mkOption {
|
||||
description = "Settings for performing a one-time import.";
|
||||
type = with types; nullOr (submodule dbOptions);
|
||||
default = null;
|
||||
description = "Settings for performing a one-time import.";
|
||||
type = with types; nullOr (submodule dbOptions);
|
||||
default = null;
|
||||
};
|
||||
|
||||
nodeSize = mkOption {
|
||||
description = ''
|
||||
Rippled size of the node you are running.
|
||||
"tiny", "small", "medium", "large", and "huge"
|
||||
'';
|
||||
type = types.enum ["tiny" "small" "medium" "large" "huge"];
|
||||
default = "small";
|
||||
description = ''
|
||||
Rippled size of the node you are running.
|
||||
"tiny", "small", "medium", "large", and "huge"
|
||||
'';
|
||||
type = types.enum ["tiny" "small" "medium" "large" "huge"];
|
||||
default = "small";
|
||||
};
|
||||
|
||||
ips = mkOption {
|
||||
description = ''
|
||||
List of hostnames or ips where the Ripple protocol is served.
|
||||
For a starter list, you can either copy entries from:
|
||||
https://ripple.com/ripple.txt or if you prefer you can let it
|
||||
default to r.ripple.com 51235
|
||||
description = ''
|
||||
List of hostnames or ips where the Ripple protocol is served.
|
||||
For a starter list, you can either copy entries from:
|
||||
https://ripple.com/ripple.txt or if you prefer you can let it
|
||||
default to r.ripple.com 51235
|
||||
|
||||
A port may optionally be specified after adding a space to the
|
||||
address. By convention, if known, IPs are listed in from most
|
||||
to least trusted.
|
||||
'';
|
||||
type = types.listOf types.str;
|
||||
default = ["r.ripple.com 51235"];
|
||||
A port may optionally be specified after adding a space to the
|
||||
address. By convention, if known, IPs are listed in from most
|
||||
to least trusted.
|
||||
'';
|
||||
type = types.listOf types.str;
|
||||
default = ["r.ripple.com 51235"];
|
||||
};
|
||||
|
||||
ipsFixed = mkOption {
|
||||
description = ''
|
||||
List of IP addresses or hostnames to which rippled should always
|
||||
attempt to maintain peer connections with. This is useful for
|
||||
manually forming private networks, for example to configure a
|
||||
validation server that connects to the Ripple network through a
|
||||
public-facing server, or for building a set of cluster peers.
|
||||
description = ''
|
||||
List of IP addresses or hostnames to which rippled should always
|
||||
attempt to maintain peer connections with. This is useful for
|
||||
manually forming private networks, for example to configure a
|
||||
validation server that connects to the Ripple network through a
|
||||
public-facing server, or for building a set of cluster peers.
|
||||
|
||||
A port may optionally be specified after adding a space to the address
|
||||
'';
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
A port may optionally be specified after adding a space to the address
|
||||
'';
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
};
|
||||
|
||||
validators = mkOption {
|
||||
description = ''
|
||||
List of nodes to always accept as validators. Nodes are specified by domain
|
||||
or public key.
|
||||
'';
|
||||
type = types.listOf types.str;
|
||||
default = [
|
||||
"n949f75evCHwgyP4fPVgaHqNHxUVN15PsJEZ3B3HnXPcPjcZAoy7 RL1"
|
||||
"n9MD5h24qrQqiyBC8aeqqCWvpiBiYQ3jxSr91uiDvmrkyHRdYLUj RL2"
|
||||
"n9L81uNCaPgtUJfaHh89gmdvXKAmSt5Gdsw2g1iPWaPkAHW5Nm4C RL3"
|
||||
"n9KiYM9CgngLvtRCQHZwgC2gjpdaZcCcbt3VboxiNFcKuwFVujzS RL4"
|
||||
"n9LdgEtkmGB9E2h3K4Vp7iGUaKuq23Zr32ehxiU8FWY7xoxbWTSA RL5"
|
||||
];
|
||||
description = ''
|
||||
List of nodes to always accept as validators. Nodes are specified by domain
|
||||
or public key.
|
||||
'';
|
||||
type = types.listOf types.str;
|
||||
default = [
|
||||
"n949f75evCHwgyP4fPVgaHqNHxUVN15PsJEZ3B3HnXPcPjcZAoy7 RL1"
|
||||
"n9MD5h24qrQqiyBC8aeqqCWvpiBiYQ3jxSr91uiDvmrkyHRdYLUj RL2"
|
||||
"n9L81uNCaPgtUJfaHh89gmdvXKAmSt5Gdsw2g1iPWaPkAHW5Nm4C RL3"
|
||||
"n9KiYM9CgngLvtRCQHZwgC2gjpdaZcCcbt3VboxiNFcKuwFVujzS RL4"
|
||||
"n9LdgEtkmGB9E2h3K4Vp7iGUaKuq23Zr32ehxiU8FWY7xoxbWTSA RL5"
|
||||
];
|
||||
};
|
||||
|
||||
databasePath = mkOption {
|
||||
description = ''
|
||||
Path to the ripple database.
|
||||
'';
|
||||
type = types.path;
|
||||
default = "/var/lib/rippled";
|
||||
description = ''
|
||||
Path to the ripple database.
|
||||
'';
|
||||
type = types.path;
|
||||
default = "/var/lib/rippled";
|
||||
};
|
||||
|
||||
validationQuorum = mkOption {
|
||||
description = ''
|
||||
The minimum number of trusted validations a ledger must have before
|
||||
the server considers it fully validated.
|
||||
'';
|
||||
type = types.int;
|
||||
default = 3;
|
||||
description = ''
|
||||
The minimum number of trusted validations a ledger must have before
|
||||
the server considers it fully validated.
|
||||
'';
|
||||
type = types.int;
|
||||
default = 3;
|
||||
};
|
||||
|
||||
ledgerHistory = mkOption {
|
||||
description = ''
|
||||
The number of past ledgers to acquire on server startup and the minimum
|
||||
to maintain while running.
|
||||
'';
|
||||
type = types.either types.int (types.enum ["full"]);
|
||||
default = 1296000; # 1 month
|
||||
description = ''
|
||||
The number of past ledgers to acquire on server startup and the minimum
|
||||
to maintain while running.
|
||||
'';
|
||||
type = types.either types.int (types.enum ["full"]);
|
||||
default = 1296000; # 1 month
|
||||
};
|
||||
|
||||
fetchDepth = mkOption {
|
||||
description = ''
|
||||
The number of past ledgers to serve to other peers that request historical
|
||||
ledger data (or "full" for no limit).
|
||||
'';
|
||||
type = types.either types.int (types.enum ["full"]);
|
||||
default = "full";
|
||||
description = ''
|
||||
The number of past ledgers to serve to other peers that request historical
|
||||
ledger data (or "full" for no limit).
|
||||
'';
|
||||
type = types.either types.int (types.enum ["full"]);
|
||||
default = "full";
|
||||
};
|
||||
|
||||
sntpServers = mkOption {
|
||||
description = ''
|
||||
IP address or domain of NTP servers to use for time synchronization.;
|
||||
'';
|
||||
type = types.listOf types.str;
|
||||
default = [
|
||||
"time.windows.com"
|
||||
"time.apple.com"
|
||||
"time.nist.gov"
|
||||
"pool.ntp.org"
|
||||
];
|
||||
description = ''
|
||||
IP address or domain of NTP servers to use for time synchronization.;
|
||||
'';
|
||||
type = types.listOf types.str;
|
||||
default = [
|
||||
"time.windows.com"
|
||||
"time.apple.com"
|
||||
"time.nist.gov"
|
||||
"pool.ntp.org"
|
||||
];
|
||||
};
|
||||
|
||||
logLevel = mkOption {
|
||||
description = "Logging verbosity.";
|
||||
type = types.enum ["debug" "error" "info"];
|
||||
default = "error";
|
||||
type = types.enum ["debug" "error" "info"];
|
||||
default = "error";
|
||||
};
|
||||
|
||||
statsd = {
|
||||
|
@ -389,14 +389,14 @@ in
|
|||
|
||||
extraConfig = mkOption {
|
||||
default = "";
|
||||
description = ''
|
||||
Extra lines to be added verbatim to the rippled.cfg configuration file.
|
||||
'';
|
||||
description = ''
|
||||
Extra lines to be added verbatim to the rippled.cfg configuration file.
|
||||
'';
|
||||
};
|
||||
|
||||
config = mkOption {
|
||||
internal = true;
|
||||
default = pkgs.writeText "rippled.conf" rippledCfg;
|
||||
internal = true;
|
||||
default = pkgs.writeText "rippled.conf" rippledCfg;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -410,8 +410,8 @@ in
|
|||
{ name = "rippled";
|
||||
description = "Ripple server user";
|
||||
uid = config.ids.uids.rippled;
|
||||
home = cfg.databasePath;
|
||||
createHome = true;
|
||||
home = cfg.databasePath;
|
||||
createHome = true;
|
||||
};
|
||||
|
||||
systemd.services.rippled = {
|
||||
|
@ -421,8 +421,8 @@ in
|
|||
serviceConfig = {
|
||||
ExecStart = "${cfg.package}/bin/rippled --fg --conf ${cfg.config}";
|
||||
User = "rippled";
|
||||
Restart = "on-failure";
|
||||
LimitNOFILE=10000;
|
||||
Restart = "on-failure";
|
||||
LimitNOFILE=10000;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -9,6 +9,32 @@ in
|
|||
options = {
|
||||
services.sonarr = {
|
||||
enable = mkEnableOption "Sonarr";
|
||||
|
||||
dataDir = mkOption {
|
||||
type = types.str;
|
||||
default = "/var/lib/sonarr/.config/NzbDrone";
|
||||
description = "The directory where Sonarr stores its data files.";
|
||||
};
|
||||
|
||||
openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Open ports in the firewall for the Sonarr web interface
|
||||
'';
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
default = "sonarr";
|
||||
description = "User account under which Sonaar runs.";
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
default = "sonarr";
|
||||
description = "Group under which Sonaar runs.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -18,30 +44,38 @@ in
|
|||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
preStart = ''
|
||||
test -d /var/lib/sonarr/ || {
|
||||
echo "Creating sonarr data directory in /var/lib/sonarr/"
|
||||
mkdir -p /var/lib/sonarr/
|
||||
test -d ${cfg.dataDir} || {
|
||||
echo "Creating sonarr data directory in ${cfg.dataDir}"
|
||||
mkdir -p ${cfg.dataDir}
|
||||
}
|
||||
chown -R sonarr:sonarr /var/lib/sonarr/
|
||||
chmod 0700 /var/lib/sonarr/
|
||||
chown -R ${cfg.user}:${cfg.group} ${cfg.dataDir}
|
||||
chmod 0700 ${cfg.dataDir}
|
||||
'';
|
||||
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
User = "sonarr";
|
||||
Group = "sonarr";
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
PermissionsStartOnly = "true";
|
||||
ExecStart = "${pkgs.sonarr}/bin/NzbDrone --no-browser";
|
||||
ExecStart = "${pkgs.sonarr}/bin/NzbDrone -nobrowser -data='${cfg.dataDir}'";
|
||||
Restart = "on-failure";
|
||||
};
|
||||
};
|
||||
|
||||
users.users.sonarr = {
|
||||
uid = config.ids.uids.sonarr;
|
||||
home = "/var/lib/sonarr";
|
||||
group = "sonarr";
|
||||
networking.firewall = mkIf cfg.openFirewall {
|
||||
allowedTCPPorts = [ 8989 ];
|
||||
};
|
||||
users.groups.sonarr.gid = config.ids.gids.sonarr;
|
||||
|
||||
users.users = mkIf (cfg.user == "sonarr") {
|
||||
sonarr = {
|
||||
group = cfg.group;
|
||||
home = cfg.dataDir;
|
||||
uid = config.ids.uids.sonarr;
|
||||
};
|
||||
};
|
||||
|
||||
users.groups = mkIf (cfg.group == "sonarr") {
|
||||
sonarr.gid = config.ids.gids.sonarr;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<link xlink:href="https://weechat.org/">WeeChat</link> is a fast and
|
||||
extensible IRC client.
|
||||
</para>
|
||||
<section>
|
||||
<section xml:id="module-services-weechat-basic-usage">
|
||||
<title>Basic Usage</title>
|
||||
|
||||
<para>
|
||||
|
@ -35,7 +35,7 @@
|
|||
in the state directory <literal>/var/lib/weechat</literal>.
|
||||
</para>
|
||||
</section>
|
||||
<section>
|
||||
<section xml:id="module-services-weechat-reattach">
|
||||
<title>Re-attaching to WeeChat</title>
|
||||
|
||||
<para>
|
||||
|
|
360
nixos/modules/services/misc/zoneminder.nix
Normal file
360
nixos/modules/services/misc/zoneminder.nix
Normal file
|
@ -0,0 +1,360 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
cfg = config.services.zoneminder;
|
||||
pkg = pkgs.zoneminder;
|
||||
|
||||
dirName = pkg.dirName;
|
||||
|
||||
user = "zoneminder";
|
||||
group = {
|
||||
nginx = config.services.nginx.group;
|
||||
none = user;
|
||||
}."${cfg.webserver}";
|
||||
|
||||
useNginx = cfg.webserver == "nginx";
|
||||
|
||||
defaultDir = "/var/lib/${user}";
|
||||
home = if useCustomDir then cfg.storageDir else defaultDir;
|
||||
|
||||
useCustomDir = !(builtins.isNull cfg.storageDir);
|
||||
|
||||
socket = "/run/phpfpm/${dirName}.sock";
|
||||
|
||||
zms = "/cgi-bin/zms";
|
||||
|
||||
dirs = dirList: [ dirName ] ++ map (e: "${dirName}/${e}") dirList;
|
||||
|
||||
cacheDirs = [ "swap" ];
|
||||
libDirs = [ "events" "exports" "images" "sounds" ];
|
||||
|
||||
dirStanzas = baseDir:
|
||||
lib.concatStringsSep "\n" (map (e:
|
||||
"ZM_DIR_${lib.toUpper e}=${baseDir}/${e}"
|
||||
) libDirs);
|
||||
|
||||
defaultsFile = pkgs.writeText "60-defaults.conf" ''
|
||||
# 01-system-paths.conf
|
||||
${dirStanzas home}
|
||||
ZM_PATH_ARP=${lib.getBin pkgs.nettools}/bin/arp
|
||||
ZM_PATH_LOGS=/var/log/${dirName}
|
||||
ZM_PATH_MAP=/dev/shm
|
||||
ZM_PATH_SOCKS=/run/${dirName}
|
||||
ZM_PATH_SWAP=/var/cache/${dirName}/swap
|
||||
ZM_PATH_ZMS=${zms}
|
||||
|
||||
# 02-multiserver.conf
|
||||
ZM_SERVER_HOST=
|
||||
|
||||
# Database
|
||||
ZM_DB_TYPE=mysql
|
||||
ZM_DB_HOST=${cfg.database.host}
|
||||
ZM_DB_NAME=${cfg.database.name}
|
||||
ZM_DB_USER=${cfg.database.username}
|
||||
ZM_DB_PASS=${cfg.database.password}
|
||||
|
||||
# Web
|
||||
ZM_WEB_USER=${user}
|
||||
ZM_WEB_GROUP=${group}
|
||||
'';
|
||||
|
||||
configFile = pkgs.writeText "80-nixos.conf" ''
|
||||
# You can override defaults here
|
||||
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
|
||||
phpExtensions = with pkgs.phpPackages; [
|
||||
{ pkg = apcu; name = "apcu"; }
|
||||
];
|
||||
|
||||
in {
|
||||
options = {
|
||||
services.zoneminder = with lib; {
|
||||
enable = lib.mkEnableOption ''
|
||||
ZoneMinder
|
||||
</para><para>
|
||||
If you intend to run the database locally, you should set
|
||||
`config.services.zoneminder.database.createLocally` to true. Otherwise,
|
||||
when set to `false` (the default), you will have to create the database
|
||||
and database user as well as populate the database yourself.
|
||||
'';
|
||||
|
||||
webserver = mkOption {
|
||||
type = types.enum [ "nginx" "none" ];
|
||||
default = "nginx";
|
||||
description = ''
|
||||
The webserver to configure for the PHP frontend.
|
||||
</para>
|
||||
<para>
|
||||
|
||||
Set it to `none` if you want to configure it yourself. PRs are welcome
|
||||
for support for other web servers.
|
||||
'';
|
||||
};
|
||||
|
||||
hostname = mkOption {
|
||||
type = types.str;
|
||||
default = "localhost";
|
||||
description = ''
|
||||
The hostname on which to listen.
|
||||
'';
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.int;
|
||||
default = 8095;
|
||||
description = ''
|
||||
The port on which to listen.
|
||||
'';
|
||||
};
|
||||
|
||||
openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Open the firewall port(s).
|
||||
'';
|
||||
};
|
||||
|
||||
database = {
|
||||
createLocally = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Create the database and database user locally.
|
||||
'';
|
||||
};
|
||||
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
default = "localhost";
|
||||
description = ''
|
||||
Hostname hosting the database.
|
||||
'';
|
||||
};
|
||||
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
default = "zm";
|
||||
description = ''
|
||||
Name of database.
|
||||
'';
|
||||
};
|
||||
|
||||
username = mkOption {
|
||||
type = types.str;
|
||||
default = "zmuser";
|
||||
description = ''
|
||||
Username for accessing the database.
|
||||
'';
|
||||
};
|
||||
|
||||
password = mkOption {
|
||||
type = types.str;
|
||||
default = "zmpass";
|
||||
description = ''
|
||||
Username for accessing the database.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
cameras = mkOption {
|
||||
type = types.int;
|
||||
default = 1;
|
||||
description = ''
|
||||
Set this to the number of cameras you expect to support.
|
||||
'';
|
||||
};
|
||||
|
||||
storageDir = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "/storage/tank";
|
||||
description = ''
|
||||
ZoneMinder can generate quite a lot of data, so in case you don't want
|
||||
to use the default ${home}, you can override the path here.
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Additional configuration added verbatim to the configuration file.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
environment.etc = {
|
||||
"zoneminder/60-defaults.conf".source = defaultsFile;
|
||||
"zoneminder/80-nixos.conf".source = configFile;
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall [ cfg.port ];
|
||||
|
||||
services = {
|
||||
fcgiwrap = lib.mkIf useNginx {
|
||||
enable = true;
|
||||
preforkProcesses = cfg.cameras;
|
||||
inherit user group;
|
||||
};
|
||||
|
||||
mysql = lib.mkIf cfg.database.createLocally {
|
||||
ensureDatabases = [ cfg.database.name ];
|
||||
ensureUsers = [{
|
||||
name = cfg.database.username;
|
||||
ensurePermissions = { "${cfg.database.name}.*" = "ALL PRIVILEGES"; };
|
||||
initialDatabases = [
|
||||
{ inherit (cfg.database) name; schema = "${pkg}/share/zoneminder/db/zm_create.sql"; }
|
||||
];
|
||||
}];
|
||||
};
|
||||
|
||||
nginx = lib.mkIf useNginx {
|
||||
enable = true;
|
||||
virtualHosts = {
|
||||
"${cfg.hostname}" = {
|
||||
default = true;
|
||||
root = "${pkg}/share/zoneminder/www";
|
||||
listen = [ { addr = "0.0.0.0"; inherit (cfg) port; } ];
|
||||
extraConfig = let
|
||||
fcgi = config.services.fcgiwrap;
|
||||
in ''
|
||||
index index.php;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php?$args =404;
|
||||
|
||||
location ~ /api/(css|img|ico) {
|
||||
rewrite ^/api(.+)$ /api/app/webroot/$1 break;
|
||||
try_files $uri $uri/ =404;
|
||||
}
|
||||
|
||||
location ~ \.(gif|ico|jpg|jpeg|png)$ {
|
||||
access_log off;
|
||||
expires 30d;
|
||||
}
|
||||
|
||||
location /api {
|
||||
rewrite ^/api(.+)$ /api/app/webroot/index.php?p=$1 last;
|
||||
}
|
||||
|
||||
location /cgi-bin {
|
||||
gzip off;
|
||||
|
||||
include ${pkgs.nginx}/conf/fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME ${pkg}/libexec/zoneminder/${zms};
|
||||
fastcgi_param HTTP_PROXY "";
|
||||
fastcgi_intercept_errors on;
|
||||
|
||||
fastcgi_pass ${fcgi.socketType}:${fcgi.socketAddress};
|
||||
}
|
||||
|
||||
location /cache {
|
||||
alias /var/cache/${dirName};
|
||||
}
|
||||
|
||||
location ~ \.php$ {
|
||||
try_files $uri =404;
|
||||
fastcgi_index index.php;
|
||||
|
||||
include ${pkgs.nginx}/conf/fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME $request_filename;
|
||||
fastcgi_param HTTP_PROXY "";
|
||||
|
||||
fastcgi_pass unix:${socket};
|
||||
}
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
phpfpm = lib.mkIf useNginx {
|
||||
phpOptions = ''
|
||||
date.timezone = "${config.time.timeZone}"
|
||||
|
||||
${lib.concatStringsSep "\n" (map (e:
|
||||
"extension=${e.pkg}/lib/php/extensions/${e.name}.so") phpExtensions)}
|
||||
'';
|
||||
pools.zoneminder = {
|
||||
listen = socket;
|
||||
extraConfig = ''
|
||||
user = ${user}
|
||||
group = ${group}
|
||||
|
||||
listen.owner = ${user}
|
||||
listen.group = ${group}
|
||||
listen.mode = 0660
|
||||
|
||||
pm = dynamic
|
||||
pm.start_servers = 1
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 2
|
||||
pm.max_requests = 500
|
||||
pm.max_children = 5
|
||||
pm.status_path = /$pool-status
|
||||
ping.path = /$pool-ping
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services = {
|
||||
zoneminder = with pkgs; rec {
|
||||
inherit (zoneminder.meta) description;
|
||||
documentation = [ "https://zoneminder.readthedocs.org/en/latest/" ];
|
||||
path = [
|
||||
coreutils
|
||||
procps
|
||||
psmisc
|
||||
];
|
||||
after = [ "mysql.service" "nginx.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
restartTriggers = [ defaultsFile configFile ];
|
||||
preStart = lib.mkIf useCustomDir ''
|
||||
install -dm775 -o ${user} -g ${group} ${cfg.storageDir}/{${lib.concatStringsSep "," libDirs}}
|
||||
'';
|
||||
serviceConfig = {
|
||||
User = user;
|
||||
Group = group;
|
||||
SupplementaryGroups = [ "video" ];
|
||||
ExecStart = "${zoneminder}/bin/zmpkg.pl start";
|
||||
ExecStop = "${zoneminder}/bin/zmpkg.pl stop";
|
||||
ExecReload = "${zoneminder}/bin/zmpkg.pl restart";
|
||||
PIDFile = "/run/${dirName}/zm.pid";
|
||||
Type = "forking";
|
||||
Restart = "on-failure";
|
||||
RestartSec = "10s";
|
||||
CacheDirectory = dirs cacheDirs;
|
||||
RuntimeDirectory = dirName;
|
||||
ReadWriteDirectories = lib.mkIf useCustomDir [ cfg.storageDir ];
|
||||
StateDirectory = dirs (if useCustomDir then [] else libDirs);
|
||||
LogsDirectory = dirName;
|
||||
PrivateTmp = true;
|
||||
ProtectSystem = "strict";
|
||||
ProtectKernelTunables = true;
|
||||
SystemCallArchitectures = "native";
|
||||
NoNewPrivileges = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
users.groups."${user}" = {
|
||||
gid = config.ids.gids.zoneminder;
|
||||
};
|
||||
|
||||
users.users."${user}" = {
|
||||
uid = config.ids.uids.zoneminder;
|
||||
group = user;
|
||||
inherit home;
|
||||
inherit (pkgs.zoneminder.meta) description;
|
||||
};
|
||||
};
|
||||
|
||||
meta.maintainers = with lib.maintainers; [ peterhoeg ];
|
||||
}
|
|
@ -88,6 +88,8 @@ in {
|
|||
ExecStart = "${cfg.package}/sbin/collectd -C ${conf} -f";
|
||||
User = cfg.user;
|
||||
PermissionsStartOnly = true;
|
||||
Restart = "on-failure";
|
||||
RestartSec = 3;
|
||||
};
|
||||
|
||||
preStart = ''
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue