Merge staging-next into staging
This commit is contained in:
commit
bc9bd012c4
2
.github/CONTRIBUTING.md
vendored
2
.github/CONTRIBUTING.md
vendored
@ -20,6 +20,8 @@ under the terms of [COPYING](../COPYING), which is an MIT-like license.
|
||||
(Motivation for change. Additional information.)
|
||||
```
|
||||
|
||||
For consistency, there should not be a period at the end of the commit message.
|
||||
|
||||
Examples:
|
||||
|
||||
* nginx: init at 2.0.1
|
||||
|
@ -12,12 +12,12 @@ build daemon as so-called channels. To get channel information via git, add
|
||||
```
|
||||
|
||||
For stability and maximum binary package support, it is recommended to maintain
|
||||
custom changes on top of one of the channels, e.g. `nixos-18.03` for the latest
|
||||
custom changes on top of one of the channels, e.g. `nixos-18.09` for the latest
|
||||
release and `nixos-unstable` for the latest successful build of master:
|
||||
|
||||
```
|
||||
% git remote update channels
|
||||
% git rebase channels/nixos-18.03
|
||||
% git rebase channels/nixos-18.09
|
||||
```
|
||||
|
||||
For pull-requests, please rebase onto nixpkgs `master`.
|
||||
@ -31,9 +31,9 @@ For pull-requests, please rebase onto nixpkgs `master`.
|
||||
* [Manual (NixOS)](https://nixos.org/nixos/manual/)
|
||||
* [Community maintained wiki](https://nixos.wiki/)
|
||||
* [Continuous package builds for unstable/master](https://hydra.nixos.org/jobset/nixos/trunk-combined)
|
||||
* [Continuous package builds for 18.03 release](https://hydra.nixos.org/jobset/nixos/release-18.03)
|
||||
* [Continuous package builds for 18.09 release](https://hydra.nixos.org/jobset/nixos/release-18.09)
|
||||
* [Tests for unstable/master](https://hydra.nixos.org/job/nixos/trunk-combined/tested#tabs-constituents)
|
||||
* [Tests for 18.03 release](https://hydra.nixos.org/job/nixos/release-18.03/tested#tabs-constituents)
|
||||
* [Tests for 18.09 release](https://hydra.nixos.org/job/nixos/release-18.09/tested#tabs-constituents)
|
||||
|
||||
Communication:
|
||||
|
||||
|
@ -18,7 +18,7 @@ if ! builtins ? nixVersion || builtins.compareVersions requiredVersion builtins.
|
||||
|
||||
For more information, please see the NixOS release notes at
|
||||
https://nixos.org/nixos/manual or locally at
|
||||
${toString ./doc/manual/release-notes}.
|
||||
${toString ./nixos/doc/manual/release-notes}.
|
||||
|
||||
If you need further help, see https://nixos.org/nixos/support.html
|
||||
''
|
||||
|
1
doc/.gitignore
vendored
1
doc/.gitignore
vendored
@ -4,3 +4,4 @@
|
||||
out
|
||||
manual-full.xml
|
||||
highlightjs
|
||||
functions/library/locations.xml
|
||||
|
@ -19,7 +19,7 @@ fix-misc-xml:
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f ${MD_TARGETS} .version manual-full.xml
|
||||
rm -f ${MD_TARGETS} .version manual-full.xml functions/library/locations.xml
|
||||
rm -rf ./out/ ./highlightjs
|
||||
|
||||
.PHONY: validate
|
||||
@ -69,13 +69,17 @@ highlightjs:
|
||||
cp -r "$$HIGHLIGHTJS/loader.js" highlightjs/
|
||||
|
||||
|
||||
manual-full.xml: ${MD_TARGETS} .version *.xml
|
||||
manual-full.xml: ${MD_TARGETS} .version functions/library/locations.xml *.xml **/*.xml **/**/*.xml
|
||||
xmllint --nonet --xinclude --noxincludenode manual.xml --output manual-full.xml
|
||||
|
||||
.version:
|
||||
nix-instantiate --eval \
|
||||
-E '(import ../lib).version' > .version
|
||||
|
||||
functions/library/locations.xml:
|
||||
nix-build ./lib-function-locations.nix \
|
||||
--out-link ./functions/library/locations.xml
|
||||
|
||||
%.section.xml: %.section.md
|
||||
pandoc $^ -w docbook+smart \
|
||||
-f markdown+smart \
|
||||
|
@ -47,9 +47,10 @@
|
||||
|
||||
<para>
|
||||
In Nixpkgs, these three platforms are defined as attribute sets under the
|
||||
names <literal>buildPlatform</literal>, <literal>hostPlatform</literal>, and
|
||||
<literal>targetPlatform</literal>. They are always defined as attributes in
|
||||
the standard environment. That means one can access them like:
|
||||
names <literal>buildPlatform</literal>, <literal>hostPlatform</literal>,
|
||||
and <literal>targetPlatform</literal>. They are always defined as
|
||||
attributes in the standard environment. That means one can access them
|
||||
like:
|
||||
<programlisting>{ stdenv, fooDep, barDep, .. }: ...stdenv.buildPlatform...</programlisting>
|
||||
.
|
||||
</para>
|
||||
|
@ -1,6 +1,7 @@
|
||||
{ pkgs ? (import ./.. { }), nixpkgs ? { }}:
|
||||
let
|
||||
pkgs = import ./.. { };
|
||||
lib = pkgs.lib;
|
||||
locationsXml = import ./lib-function-locations.nix { inherit pkgs nixpkgs; };
|
||||
in
|
||||
pkgs.stdenv.mkDerivation {
|
||||
name = "nixpkgs-manual";
|
||||
@ -29,6 +30,8 @@ pkgs.stdenv.mkDerivation {
|
||||
];
|
||||
|
||||
postPatch = ''
|
||||
rm -rf ./functions/library/locations.xml
|
||||
ln -s ${locationsXml} ./functions/library/locations.xml
|
||||
echo ${lib.version} > .version
|
||||
'';
|
||||
|
||||
|
1019
doc/functions.xml
1019
doc/functions.xml
File diff suppressed because it is too large
Load Diff
21
doc/functions/debug.xml
Normal file
21
doc/functions/debug.xml
Normal file
@ -0,0 +1,21 @@
|
||||
<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-debug">
|
||||
<title>Debugging Nix Expressions</title>
|
||||
|
||||
<para>
|
||||
Nix is a unityped, dynamic language, this means every value can potentially
|
||||
appear anywhere. Since it is also non-strict, evaluation order and what
|
||||
ultimately is evaluated might surprise you. Therefore it is important to be
|
||||
able to debug nix expressions.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In the <literal>lib/debug.nix</literal> file you will find a number of
|
||||
functions that help (pretty-)printing values while evaluation is runnnig. You
|
||||
can even specify how deep these values should be printed recursively, and
|
||||
transform them on the fly. Please consult the docstrings in
|
||||
<literal>lib/debug.nix</literal> for usage information.
|
||||
</para>
|
||||
</section>
|
564
doc/functions/dockertools.xml
Normal file
564
doc/functions/dockertools.xml
Normal file
@ -0,0 +1,564 @@
|
||||
<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-dockerTools">
|
||||
<title>pkgs.dockerTools</title>
|
||||
|
||||
<para>
|
||||
<varname>pkgs.dockerTools</varname> is a set of functions for creating and
|
||||
manipulating Docker images according to the
|
||||
<link xlink:href="https://github.com/moby/moby/blob/master/image/spec/v1.2.md#docker-image-specification-v120">
|
||||
Docker Image Specification v1.2.0 </link>. Docker itself is not used to
|
||||
perform any of the operations done by these functions.
|
||||
</para>
|
||||
|
||||
<warning>
|
||||
<para>
|
||||
The <varname>dockerTools</varname> API is unstable and may be subject to
|
||||
backwards-incompatible changes in the future.
|
||||
</para>
|
||||
</warning>
|
||||
|
||||
<section xml:id="ssec-pkgs-dockerTools-buildImage">
|
||||
<title>buildImage</title>
|
||||
|
||||
<para>
|
||||
This function is analogous to the <command>docker build</command> command,
|
||||
in that can 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>
|
||||
|
||||
<para>
|
||||
The parameters of <varname>buildImage</varname> with relative example values
|
||||
are described below:
|
||||
</para>
|
||||
|
||||
<example xml:id='ex-dockerTools-buildImage'>
|
||||
<title>Docker build</title>
|
||||
<programlisting>
|
||||
buildImage {
|
||||
name = "redis"; <co xml:id='ex-dockerTools-buildImage-1' />
|
||||
tag = "latest"; <co xml:id='ex-dockerTools-buildImage-2' />
|
||||
|
||||
fromImage = someBaseImage; <co xml:id='ex-dockerTools-buildImage-3' />
|
||||
fromImageName = null; <co xml:id='ex-dockerTools-buildImage-4' />
|
||||
fromImageTag = "latest"; <co xml:id='ex-dockerTools-buildImage-5' />
|
||||
|
||||
contents = pkgs.redis; <co xml:id='ex-dockerTools-buildImage-6' />
|
||||
runAsRoot = '' <co xml:id='ex-dockerTools-buildImage-runAsRoot' />
|
||||
#!${stdenv.shell}
|
||||
mkdir -p /data
|
||||
'';
|
||||
|
||||
config = { <co xml:id='ex-dockerTools-buildImage-8' />
|
||||
Cmd = [ "/bin/redis-server" ];
|
||||
WorkingDir = "/data";
|
||||
Volumes = {
|
||||
"/data" = {};
|
||||
};
|
||||
};
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
The above example will build a Docker image <literal>redis/latest</literal>
|
||||
from the given base image. Loading and running this image in Docker results
|
||||
in <literal>redis-server</literal> being started automatically.
|
||||
</para>
|
||||
|
||||
<calloutlist>
|
||||
<callout arearefs='ex-dockerTools-buildImage-1'>
|
||||
<para>
|
||||
<varname>name</varname> specifies the name of the resulting image. This is
|
||||
the only required argument for <varname>buildImage</varname>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs='ex-dockerTools-buildImage-2'>
|
||||
<para>
|
||||
<varname>tag</varname> specifies the tag of the resulting image. By
|
||||
default it's <literal>null</literal>, which indicates that the nix output
|
||||
hash will be used as tag.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs='ex-dockerTools-buildImage-3'>
|
||||
<para>
|
||||
<varname>fromImage</varname> is the repository tarball containing the base
|
||||
image. It must be a valid Docker image, such as exported by
|
||||
<command>docker save</command>. By default it's <literal>null</literal>,
|
||||
which can be seen as equivalent to <literal>FROM scratch</literal> of a
|
||||
<filename>Dockerfile</filename>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs='ex-dockerTools-buildImage-4'>
|
||||
<para>
|
||||
<varname>fromImageName</varname> can be used to further specify the base
|
||||
image within the repository, in case it contains multiple images. By
|
||||
default it's <literal>null</literal>, in which case
|
||||
<varname>buildImage</varname> will peek the first image available in the
|
||||
repository.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs='ex-dockerTools-buildImage-5'>
|
||||
<para>
|
||||
<varname>fromImageTag</varname> can be used to further specify the tag of
|
||||
the base image within the repository, in case an image contains multiple
|
||||
tags. By default it's <literal>null</literal>, in which case
|
||||
<varname>buildImage</varname> will peek the first tag available for the
|
||||
base image.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs='ex-dockerTools-buildImage-6'>
|
||||
<para>
|
||||
<varname>contents</varname> is a derivation that will be copied in the new
|
||||
layer of the resulting image. This can be similarly seen as <command>ADD
|
||||
contents/ /</command> in a <filename>Dockerfile</filename>. By default
|
||||
it's <literal>null</literal>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs='ex-dockerTools-buildImage-runAsRoot'>
|
||||
<para>
|
||||
<varname>runAsRoot</varname> is a bash script that will run as root in an
|
||||
environment that overlays the existing layers of the base image with the
|
||||
new resulting layer, including the previously copied
|
||||
<varname>contents</varname> derivation. This can be similarly seen as
|
||||
<command>RUN ...</command> in a <filename>Dockerfile</filename>.
|
||||
<note>
|
||||
<para>
|
||||
Using this parameter requires the <literal>kvm</literal> device to be
|
||||
available.
|
||||
</para>
|
||||
</note>
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs='ex-dockerTools-buildImage-8'>
|
||||
<para>
|
||||
<varname>config</varname> is used to specify the configuration of the
|
||||
containers that will be started off the built image in Docker. The
|
||||
available options are listed in the
|
||||
<link xlink:href="https://github.com/moby/moby/blob/master/image/spec/v1.2.md#image-json-field-descriptions">
|
||||
Docker Image Specification v1.2.0 </link>.
|
||||
</para>
|
||||
</callout>
|
||||
</calloutlist>
|
||||
|
||||
<para>
|
||||
After the new layer has been created, its closure (to which
|
||||
<varname>contents</varname>, <varname>config</varname> and
|
||||
<varname>runAsRoot</varname> contribute) will be copied in the layer itself.
|
||||
Only new dependencies that are not already in the existing layers will be
|
||||
copied.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
At the end of the process, only one new single layer will be produced and
|
||||
added to the resulting image.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The resulting repository will only list the single image
|
||||
<varname>image/tag</varname>. In the case of
|
||||
<xref linkend='ex-dockerTools-buildImage'/> it would be
|
||||
<varname>redis/latest</varname>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
It is possible to inspect the arguments with which an image was built using
|
||||
its <varname>buildArgs</varname> attribute.
|
||||
</para>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
If you see errors similar to <literal>getProtocolByName: does not exist (no
|
||||
such protocol name: tcp)</literal> you may need to add
|
||||
<literal>pkgs.iana-etc</literal> to <varname>contents</varname>.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
If you see errors similar to <literal>Error_Protocol ("certificate has
|
||||
unknown CA",True,UnknownCa)</literal> you may need to add
|
||||
<literal>pkgs.cacert</literal> to <varname>contents</varname>.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
<example xml:id="example-pkgs-dockerTools-buildImage-creation-date">
|
||||
<title>Impurely Defining a Docker Layer's Creation Date</title>
|
||||
<para>
|
||||
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
|
||||
listed like this:
|
||||
</para>
|
||||
<screen><![CDATA[
|
||||
$ docker image list
|
||||
REPOSITORY TAG IMAGE ID CREATED SIZE
|
||||
hello latest 08c791c7846e 48 years ago 25.2MB
|
||||
]]></screen>
|
||||
<para>
|
||||
You can break binary reproducibility but have a sorted, meaningful
|
||||
<literal>CREATED</literal> column by setting <literal>created</literal> to
|
||||
<literal>now</literal>.
|
||||
</para>
|
||||
<programlisting><![CDATA[
|
||||
pkgs.dockerTools.buildImage {
|
||||
name = "hello";
|
||||
tag = "latest";
|
||||
created = "now";
|
||||
contents = pkgs.hello;
|
||||
|
||||
config.Cmd = [ "/bin/hello" ];
|
||||
}
|
||||
]]></programlisting>
|
||||
<para>
|
||||
and now the Docker CLI will display a reasonable date and sort the images
|
||||
as expected:
|
||||
<screen><![CDATA[
|
||||
$ docker image list
|
||||
REPOSITORY TAG IMAGE ID CREATED SIZE
|
||||
hello latest de2bf4786de6 About a minute ago 25.2MB
|
||||
]]></screen>
|
||||
however, the produced images will not be binary reproducible.
|
||||
</para>
|
||||
</example>
|
||||
</section>
|
||||
|
||||
<section xml:id="ssec-pkgs-dockerTools-buildLayeredImage">
|
||||
<title>buildLayeredImage</title>
|
||||
|
||||
<para>
|
||||
Create a Docker image with many of the store paths being on their own layer
|
||||
to improve sharing between images.
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>name</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The name of the resulting image.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>tag</varname> <emphasis>optional</emphasis>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Tag of the generated image.
|
||||
</para>
|
||||
<para>
|
||||
<emphasis>Default:</emphasis> the output path's hash
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>contents</varname> <emphasis>optional</emphasis>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Top level paths in the container. Either a single derivation, or a list
|
||||
of derivations.
|
||||
</para>
|
||||
<para>
|
||||
<emphasis>Default:</emphasis> <literal>[]</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>config</varname> <emphasis>optional</emphasis>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Run-time configuration of the container. A full list of the options are
|
||||
available at in the
|
||||
<link xlink:href="https://github.com/moby/moby/blob/master/image/spec/v1.2.md#image-json-field-descriptions">
|
||||
Docker Image Specification v1.2.0 </link>.
|
||||
</para>
|
||||
<para>
|
||||
<emphasis>Default:</emphasis> <literal>{}</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>created</varname> <emphasis>optional</emphasis>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Date and time the layers were created. Follows the same
|
||||
<literal>now</literal> exception supported by
|
||||
<literal>buildImage</literal>.
|
||||
</para>
|
||||
<para>
|
||||
<emphasis>Default:</emphasis> <literal>1970-01-01T00:00:01Z</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>maxLayers</varname> <emphasis>optional</emphasis>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Maximum number of layers to create.
|
||||
</para>
|
||||
<para>
|
||||
<emphasis>Default:</emphasis> <literal>24</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<section xml:id="dockerTools-buildLayeredImage-arg-contents">
|
||||
<title>Behavior of <varname>contents</varname> in the final image</title>
|
||||
|
||||
<para>
|
||||
Each path directly listed in <varname>contents</varname> will have a
|
||||
symlink in the root of the image.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For example:
|
||||
<programlisting><![CDATA[
|
||||
pkgs.dockerTools.buildLayeredImage {
|
||||
name = "hello";
|
||||
contents = [ pkgs.hello ];
|
||||
}
|
||||
]]></programlisting>
|
||||
will create symlinks for all the paths in the <literal>hello</literal>
|
||||
package:
|
||||
<screen><![CDATA[
|
||||
/bin/hello -> /nix/store/h1zb1padqbbb7jicsvkmrym3r6snphxg-hello-2.10/bin/hello
|
||||
/share/info/hello.info -> /nix/store/h1zb1padqbbb7jicsvkmrym3r6snphxg-hello-2.10/share/info/hello.info
|
||||
/share/locale/bg/LC_MESSAGES/hello.mo -> /nix/store/h1zb1padqbbb7jicsvkmrym3r6snphxg-hello-2.10/share/locale/bg/LC_MESSAGES/hello.mo
|
||||
]]></screen>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="dockerTools-buildLayeredImage-arg-config">
|
||||
<title>Automatic inclusion of <varname>config</varname> references</title>
|
||||
|
||||
<para>
|
||||
The closure of <varname>config</varname> is automatically included in the
|
||||
closure of the final image.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
This allows you to make very simple Docker images with very little code.
|
||||
This container will start up and run <command>hello</command>:
|
||||
<programlisting><![CDATA[
|
||||
pkgs.dockerTools.buildLayeredImage {
|
||||
name = "hello";
|
||||
config.Cmd = [ "${pkgs.hello}/bin/hello" ];
|
||||
}
|
||||
]]></programlisting>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="dockerTools-buildLayeredImage-arg-maxLayers">
|
||||
<title>Adjusting <varname>maxLayers</varname></title>
|
||||
|
||||
<para>
|
||||
Increasing the <varname>maxLayers</varname> increases the number of layers
|
||||
which have a chance to be shared between different images.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Modern Docker installations support up to 128 layers, however older
|
||||
versions support as few as 42.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If the produced image will not be extended by other Docker builds, it is
|
||||
safe to set <varname>maxLayers</varname> to <literal>128</literal>. However
|
||||
it will be impossible to extend the image further.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The first (<literal>maxLayers-2</literal>) most "popular" paths will have
|
||||
their own individual layers, then layer #<literal>maxLayers-1</literal>
|
||||
will contain all the remaining "unpopular" paths, and finally layer
|
||||
#<literal>maxLayers</literal> will contain the Image configuration.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Docker's Layers are not inherently ordered, they are content-addressable
|
||||
and are not explicitly layered until they are composed in to an Image.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section xml:id="ssec-pkgs-dockerTools-fetchFromRegistry">
|
||||
<title>pullImage</title>
|
||||
|
||||
<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
|
||||
<link xlink:href="https://hub.docker.com/">Docker Hub</link> is used to pull
|
||||
images.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Its parameters are described in the example below:
|
||||
</para>
|
||||
|
||||
<example xml:id='ex-dockerTools-pullImage'>
|
||||
<title>Docker pull</title>
|
||||
<programlisting>
|
||||
pullImage {
|
||||
imageName = "nixos/nix"; <co xml:id='ex-dockerTools-pullImage-1' />
|
||||
imageDigest = "sha256:20d9485b25ecfd89204e843a962c1bd70e9cc6858d65d7f5fadc340246e2116b"; <co xml:id='ex-dockerTools-pullImage-2' />
|
||||
finalImageTag = "1.11"; <co xml:id='ex-dockerTools-pullImage-3' />
|
||||
sha256 = "0mqjy3zq2v6rrhizgb9nvhczl87lcfphq9601wcprdika2jz7qh8"; <co xml:id='ex-dockerTools-pullImage-4' />
|
||||
os = "linux"; <co xml:id='ex-dockerTools-pullImage-5' />
|
||||
arch = "x86_64"; <co xml:id='ex-dockerTools-pullImage-6' />
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
<calloutlist>
|
||||
<callout arearefs='ex-dockerTools-pullImage-1'>
|
||||
<para>
|
||||
<varname>imageName</varname> specifies the name of the image to be
|
||||
downloaded, which can also include the registry namespace (e.g.
|
||||
<literal>nixos</literal>). This argument is required.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs='ex-dockerTools-pullImage-2'>
|
||||
<para>
|
||||
<varname>imageDigest</varname> specifies the digest of the image to be
|
||||
downloaded. Skopeo can be used to get the digest of an image, with its
|
||||
<varname>inspect</varname> subcommand. Since a given
|
||||
<varname>imageName</varname> may transparently refer to a manifest list of
|
||||
images which support multiple architectures and/or operating systems,
|
||||
supply the `--override-os` and `--override-arch` arguments to specify
|
||||
exactly which image you want. By default it will match the OS and
|
||||
architecture of the host the command is run on.
|
||||
<programlisting>
|
||||
$ nix-shell --packages skopeo jq --command "skopeo --override-os linux --override-arch x86_64 inspect docker://docker.io/nixos/nix:1.11 | jq -r '.Digest'"
|
||||
sha256:20d9485b25ecfd89204e843a962c1bd70e9cc6858d65d7f5fadc340246e2116b
|
||||
</programlisting>
|
||||
This argument is required.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs='ex-dockerTools-pullImage-3'>
|
||||
<para>
|
||||
<varname>finalImageTag</varname>, if specified, this is the tag of the
|
||||
image to be created. Note it is never used to fetch the image since we
|
||||
prefer to rely on the immutable digest ID. By default it's
|
||||
<literal>latest</literal>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs='ex-dockerTools-pullImage-4'>
|
||||
<para>
|
||||
<varname>sha256</varname> is the checksum of the whole fetched image. This
|
||||
argument is required.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs='ex-dockerTools-pullImage-5'>
|
||||
<para>
|
||||
<varname>os</varname>, if specified, is the operating system of the
|
||||
fetched image. By default it's <literal>linux</literal>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs='ex-dockerTools-pullImage-6'>
|
||||
<para>
|
||||
<varname>arch</varname>, if specified, is the cpu architecture of the
|
||||
fetched image. By default it's <literal>x86_64</literal>.
|
||||
</para>
|
||||
</callout>
|
||||
</calloutlist>
|
||||
</section>
|
||||
|
||||
<section xml:id="ssec-pkgs-dockerTools-exportImage">
|
||||
<title>exportImage</title>
|
||||
|
||||
<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
|
||||
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>.
|
||||
</para>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
Using this function requires the <literal>kvm</literal> device to be
|
||||
available.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
<para>
|
||||
The parameters of <varname>exportImage</varname> are the following:
|
||||
</para>
|
||||
|
||||
<example xml:id='ex-dockerTools-exportImage'>
|
||||
<title>Docker export</title>
|
||||
<programlisting>
|
||||
exportImage {
|
||||
fromImage = someLayeredImage;
|
||||
fromImageName = null;
|
||||
fromImageTag = null;
|
||||
|
||||
name = someLayeredImage.name;
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
The parameters relative to the base image have the same synopsis as
|
||||
described in <xref linkend='ssec-pkgs-dockerTools-buildImage'/>, except that
|
||||
<varname>fromImage</varname> is the only required argument in this case.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The <varname>name</varname> argument is the name of the derivation output,
|
||||
which defaults to <varname>fromImage.name</varname>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="ssec-pkgs-dockerTools-shadowSetup">
|
||||
<title>shadowSetup</title>
|
||||
|
||||
<para>
|
||||
This constant string is a helper for setting up the base files for managing
|
||||
users and groups, only if such files don't exist already. It is suitable for
|
||||
being used in a <varname>runAsRoot</varname>
|
||||
<xref linkend='ex-dockerTools-buildImage-runAsRoot'/> script for cases like
|
||||
in the example below:
|
||||
</para>
|
||||
|
||||
<example xml:id='ex-dockerTools-shadowSetup'>
|
||||
<title>Shadow base files</title>
|
||||
<programlisting>
|
||||
buildImage {
|
||||
name = "shadow-basic";
|
||||
|
||||
runAsRoot = ''
|
||||
#!${stdenv.shell}
|
||||
${shadowSetup}
|
||||
groupadd -r redis
|
||||
useradd -r -g redis redis
|
||||
mkdir /data
|
||||
chown redis:redis /data
|
||||
'';
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
Creating base files like <literal>/etc/passwd</literal> or
|
||||
<literal>/etc/login.defs</literal> are necessary for shadow-utils to
|
||||
manipulate users and groups.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
142
doc/functions/fhs-environments.xml
Normal file
142
doc/functions/fhs-environments.xml
Normal file
@ -0,0 +1,142 @@
|
||||
<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-fhs-environments">
|
||||
<title>buildFHSUserEnv</title>
|
||||
|
||||
<para>
|
||||
<function>buildFHSUserEnv</function> provides a way to build and run
|
||||
FHS-compatible lightweight sandboxes. It creates an isolated root with bound
|
||||
<filename>/nix/store</filename>, so its footprint in terms of disk space
|
||||
needed is quite small. This allows one to run software which is hard or
|
||||
unfeasible to patch for NixOS -- 3rd-party source trees with FHS assumptions,
|
||||
games distributed as tarballs, software with integrity checking and/or
|
||||
external self-updated binaries. It uses Linux namespaces feature to create
|
||||
temporary lightweight environments which are destroyed after all child
|
||||
processes exit, without root user rights requirement. Accepted arguments are:
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>name</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Environment name.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>targetPkgs</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Packages to be installed for the main host's architecture (i.e. x86_64 on
|
||||
x86_64 installations). Along with libraries binaries are also installed.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>multiPkgs</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Packages to be installed for all architectures supported by a host (i.e.
|
||||
i686 and x86_64 on x86_64 installations). Only libraries are installed by
|
||||
default.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>extraBuildCommands</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Additional commands to be executed for finalizing the directory structure.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>extraBuildCommandsMulti</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Like <literal>extraBuildCommands</literal>, but executed only on multilib
|
||||
architectures.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>extraOutputsToInstall</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Additional derivation outputs to be linked for both target and
|
||||
multi-architecture packages.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>extraInstallCommands</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Additional commands to be executed for finalizing the derivation with
|
||||
runner script.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>runScript</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
A command that would be executed inside the sandbox and passed all the
|
||||
command line arguments. It defaults to <literal>bash</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<para>
|
||||
One can create a simple environment using a <literal>shell.nix</literal> like
|
||||
that:
|
||||
</para>
|
||||
|
||||
<programlisting><![CDATA[
|
||||
{ pkgs ? import <nixpkgs> {} }:
|
||||
|
||||
(pkgs.buildFHSUserEnv {
|
||||
name = "simple-x11-env";
|
||||
targetPkgs = pkgs: (with pkgs;
|
||||
[ udev
|
||||
alsaLib
|
||||
]) ++ (with pkgs.xorg;
|
||||
[ libX11
|
||||
libXcursor
|
||||
libXrandr
|
||||
]);
|
||||
multiPkgs = pkgs: (with pkgs;
|
||||
[ udev
|
||||
alsaLib
|
||||
]);
|
||||
runScript = "bash";
|
||||
}).env
|
||||
]]></programlisting>
|
||||
|
||||
<para>
|
||||
Running <literal>nix-shell</literal> would then drop you into a shell with
|
||||
these libraries and binaries available. You can use this to run closed-source
|
||||
applications which expect FHS structure without hassles: simply change
|
||||
<literal>runScript</literal> to the application path, e.g.
|
||||
<filename>./bin/start.sh</filename> -- relative paths are supported.
|
||||
</para>
|
||||
</section>
|
89
doc/functions/generators.xml
Normal file
89
doc/functions/generators.xml
Normal file
@ -0,0 +1,89 @@
|
||||
<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-generators">
|
||||
<title>Generators</title>
|
||||
|
||||
<para>
|
||||
Generators are functions that create file formats from nix data structures,
|
||||
e. g. for configuration files. There are generators available for:
|
||||
<literal>INI</literal>, <literal>JSON</literal> and <literal>YAML</literal>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
All generators follow a similar call interface: <code>generatorName
|
||||
configFunctions data</code>, where <literal>configFunctions</literal> is an
|
||||
attrset of user-defined functions that format nested parts of the content.
|
||||
They each have common defaults, so often they do not need to be set manually.
|
||||
An example is <code>mkSectionName ? (name: libStr.escape [ "[" "]" ]
|
||||
name)</code> from the <literal>INI</literal> generator. It receives the name
|
||||
of a section and sanitizes it. The default <literal>mkSectionName</literal>
|
||||
escapes <literal>[</literal> and <literal>]</literal> with a backslash.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Generators can be fine-tuned to produce exactly the file format required by
|
||||
your application/service. One example is an INI-file format which uses
|
||||
<literal>: </literal> as separator, the strings
|
||||
<literal>"yes"</literal>/<literal>"no"</literal> as boolean values and
|
||||
requires all string values to be quoted:
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
with lib;
|
||||
let
|
||||
customToINI = generators.toINI {
|
||||
# specifies how to format a key/value pair
|
||||
mkKeyValue = generators.mkKeyValueDefault {
|
||||
# specifies the generated string for a subset of nix values
|
||||
mkValueString = v:
|
||||
if v == true then ''"yes"''
|
||||
else if v == false then ''"no"''
|
||||
else if isString v then ''"${v}"''
|
||||
# and delegats all other values to the default generator
|
||||
else generators.mkValueStringDefault {} v;
|
||||
} ":";
|
||||
};
|
||||
|
||||
# the INI file can now be given as plain old nix values
|
||||
in customToINI {
|
||||
main = {
|
||||
pushinfo = true;
|
||||
autopush = false;
|
||||
host = "localhost";
|
||||
port = 42;
|
||||
};
|
||||
mergetool = {
|
||||
merge = "diff3";
|
||||
};
|
||||
}
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
This will produce the following INI file as nix string:
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
[main]
|
||||
autopush:"no"
|
||||
host:"localhost"
|
||||
port:42
|
||||
pushinfo:"yes"
|
||||
str\:ange:"very::strange"
|
||||
|
||||
[mergetool]
|
||||
merge:"diff3"
|
||||
</programlisting>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
Nix store paths can be converted to strings by enclosing a derivation
|
||||
attribute like so: <code>"${drv}"</code>.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
<para>
|
||||
Detailed documentation for each generator can be found in
|
||||
<literal>lib/generators.nix</literal>.
|
||||
</para>
|
||||
</section>
|
15
doc/functions/library.xml
Normal file
15
doc/functions/library.xml
Normal file
@ -0,0 +1,15 @@
|
||||
<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-functions-library">
|
||||
<title>Nixpkgs Library Functions</title>
|
||||
|
||||
<para>
|
||||
Nixpkgs provides a standard library at <varname>pkgs.lib</varname>, or
|
||||
through <code>import <nixpkgs/lib></code>.
|
||||
</para>
|
||||
|
||||
<xi:include href="./library/asserts.xml" />
|
||||
|
||||
<xi:include href="./library/attrsets.xml" />
|
||||
</section>
|
117
doc/functions/library/asserts.xml
Normal file
117
doc/functions/library/asserts.xml
Normal file
@ -0,0 +1,117 @@
|
||||
<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-functions-library-asserts">
|
||||
<title>Assert functions</title>
|
||||
|
||||
<section xml:id="function-library-lib.asserts.assertMsg">
|
||||
<title><function>lib.asserts.assertMsg</function></title>
|
||||
|
||||
<subtitle><literal>assertMsg :: Bool -> String -> Bool</literal>
|
||||
</subtitle>
|
||||
|
||||
<xi:include href="./locations.xml" xpointer="lib.asserts.assertMsg" />
|
||||
|
||||
<para>
|
||||
Print a trace message if <literal>pred</literal> is false.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Intended to be used to augment asserts with helpful error messages.
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>pred</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Condition under which the <varname>msg</varname> should
|
||||
<emphasis>not</emphasis> be printed.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>msg</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Message to print.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<example xml:id="function-library-lib.asserts.assertMsg-example-false">
|
||||
<title>Printing when the predicate is false</title>
|
||||
<programlisting><![CDATA[
|
||||
assert lib.asserts.assertMsg ("foo" == "bar") "foo is not bar, silly"
|
||||
stderr> trace: foo is not bar, silly
|
||||
stderr> assert failed
|
||||
]]></programlisting>
|
||||
</example>
|
||||
</section>
|
||||
|
||||
<section xml:id="function-library-lib.asserts.assertOneOf">
|
||||
<title><function>lib.asserts.assertOneOf</function></title>
|
||||
|
||||
<subtitle><literal>assertOneOf :: String -> String ->
|
||||
StringList -> Bool</literal>
|
||||
</subtitle>
|
||||
|
||||
<xi:include href="./locations.xml" xpointer="lib.asserts.assertOneOf" />
|
||||
|
||||
<para>
|
||||
Specialized <function>asserts.assertMsg</function> for checking if
|
||||
<varname>val</varname> is one of the elements of <varname>xs</varname>.
|
||||
Useful for checking enums.
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>name</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The name of the variable the user entered <varname>val</varname> into,
|
||||
for inclusion in the error message.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>val</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The value of what the user provided, to be compared against the values in
|
||||
<varname>xs</varname>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>xs</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The list of valid values.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<example xml:id="function-library-lib.asserts.assertOneOf-example">
|
||||
<title>Ensuring a user provided a possible value</title>
|
||||
<programlisting><![CDATA[
|
||||
let sslLibrary = "bearssl";
|
||||
in lib.asserts.assertOneOf "sslLibrary" sslLibrary [ "openssl" "bearssl" ];
|
||||
=> false
|
||||
stderr> trace: sslLibrary must be one of "openssl", "libressl", but is: "bearssl"
|
||||
]]></programlisting>
|
||||
</example>
|
||||
</section>
|
||||
</section>
|
970
doc/functions/library/attrsets.xml
Normal file
970
doc/functions/library/attrsets.xml
Normal file
@ -0,0 +1,970 @@
|
||||
<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-functions-library-attrset">
|
||||
<title>Attribute-Set Functions</title>
|
||||
|
||||
<section xml:id="function-library-lib.attrsets.attrByPath">
|
||||
<title><function>lib.attrset.attrByPath</function></title>
|
||||
|
||||
<subtitle><literal>attrByPath :: [String] -> Any -> AttrSet</literal>
|
||||
</subtitle>
|
||||
|
||||
<xi:include href="./locations.xml" xpointer="lib.attrsets.attrByPath" />
|
||||
|
||||
<para>
|
||||
Return an attribute from within nested attribute sets.
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>attrPath</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
A list of strings representing the path through the nested attribute set
|
||||
<varname>set</varname>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>default</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Default value if <varname>attrPath</varname> does not resolve to an
|
||||
existing value.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>set</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The nested attributeset to select values from.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<example xml:id="function-library-lib.attrset.attrByPath-example-value-exists">
|
||||
<title>Extracting a value from a nested attribute set</title>
|
||||
<programlisting><![CDATA[
|
||||
let set = { a = { b = 3; }; };
|
||||
in lib.attrsets.attrByPath [ "a" "b" ] 0 set
|
||||
=> 3
|
||||
]]></programlisting>
|
||||
</example>
|
||||
|
||||
<example xml:id="function-library-lib.attrset.attrByPath-example-default-value">
|
||||
<title>No value at the path, instead using the default</title>
|
||||
<programlisting><![CDATA[
|
||||
lib.attrsets.attrByPath [ "a" "b" ] 0 {}
|
||||
=> 0
|
||||
]]></programlisting>
|
||||
</example>
|
||||
</section>
|
||||
|
||||
<section xml:id="function-library-lib.attrsets.hasAttrByPath">
|
||||
<title><function>lib.attrsets.hasAttrByPath</function></title>
|
||||
|
||||
<subtitle><literal>hasAttrByPath :: [String] -> AttrSet -> Bool</literal>
|
||||
</subtitle>
|
||||
|
||||
<xi:include href="./locations.xml" xpointer="lib.attrsets.hasAttrByPath" />
|
||||
|
||||
<para>
|
||||
Determine if an attribute exists within a nested attribute set.
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>attrPath</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
A list of strings representing the path through the nested attribute set
|
||||
<varname>set</varname>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>set</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The nested attributeset to check.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<example xml:id="function-library-lib.attrsets.hasAttrByPath-example">
|
||||
<title>A nested value does exist inside a set</title>
|
||||
<programlisting><![CDATA[
|
||||
lib.attrsets.hasAttrByPath
|
||||
[ "a" "b" "c" "d" ]
|
||||
{ a = { b = { c = { d = 123; }; }; }; }
|
||||
=> true
|
||||
]]></programlisting>
|
||||
</example>
|
||||
</section>
|
||||
|
||||
<section xml:id="function-library-lib.attrsets.setAttrByPath">
|
||||
<title><function>lib.attrsets.setAttrByPath</function></title>
|
||||
|
||||
<subtitle><literal>setAttrByPath :: [String] -> Any -> AttrSet</literal>
|
||||
</subtitle>
|
||||
|
||||
<xi:include href="./locations.xml" xpointer="lib.attrsets.setAttrByPath" />
|
||||
|
||||
<para>
|
||||
Create a new attribute set with <varname>value</varname> set at the nested
|
||||
attribute location specified in <varname>attrPath</varname>.
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>attrPath</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
A list of strings representing the path through the nested attribute set.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>value</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The value to set at the location described by
|
||||
<varname>attrPath</varname>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<example xml:id="function-library-lib.attrsets.setAttrByPath-example">
|
||||
<title>Creating a new nested attribute set</title>
|
||||
<programlisting><![CDATA[
|
||||
lib.attrsets.setAttrByPath [ "a" "b" ] 3
|
||||
=> { a = { b = 3; }; }
|
||||
]]></programlisting>
|
||||
</example>
|
||||
</section>
|
||||
|
||||
<section xml:id="function-library-lib.attrsets.getAttrFromPath">
|
||||
<title><function>lib.attrsets.getAttrFromPath</function></title>
|
||||
|
||||
<subtitle><literal>getAttrFromPath :: [String] -> AttrSet -> Value</literal>
|
||||
</subtitle>
|
||||
|
||||
<xi:include href="./locations.xml" xpointer="lib.attrsets.getAttrFromPath" />
|
||||
|
||||
<para>
|
||||
Like <xref linkend="function-library-lib.attrsets.attrByPath" /> except
|
||||
without a default, and it will throw if the value doesn't exist.
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>attrPath</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
A list of strings representing the path through the nested attribute set
|
||||
<varname>set</varname>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>set</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The nested attribute set to find the value in.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<example xml:id="function-library-lib.attrsets.getAttrPath-example-success">
|
||||
<title>Succesfully getting a value from an attribute set</title>
|
||||
<programlisting><![CDATA[
|
||||
lib.attrsets.getAttrFromPath [ "a" "b" ] { a = { b = 3; }; }
|
||||
=> 3
|
||||
]]></programlisting>
|
||||
</example>
|
||||
|
||||
<example xml:id="function-library-lib.attrsets.getAttrPath-example-throw">
|
||||
<title>Throwing after failing to get a value from an attribute set</title>
|
||||
<programlisting><![CDATA[
|
||||
lib.attrsets.getAttrFromPath [ "x" "y" ] { }
|
||||
=> error: cannot find attribute `x.y'
|
||||
]]></programlisting>
|
||||
</example>
|
||||
</section>
|
||||
|
||||
<section xml:id="function-library-lib.attrsets.attrVals">
|
||||
<title><function>lib.attrsets.attrVals</function></title>
|
||||
|
||||
<subtitle><literal>attrVals :: [String] -> AttrSet -> [Any]</literal>
|
||||
</subtitle>
|
||||
|
||||
<xi:include href="./locations.xml" xpointer="lib.attrsets.attrVals" />
|
||||
|
||||
<para>
|
||||
Return the specified attributes from a set. All values must exist.
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>nameList</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The list of attributes to fetch from <varname>set</varname>. Each
|
||||
attribute name must exist on the attrbitue set.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>set</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The set to get attribute values from.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<example xml:id="function-library-lib.attrsets.attrVals-example-success">
|
||||
<title>Getting several values from an attribute set</title>
|
||||
<programlisting><![CDATA[
|
||||
lib.attrsets.attrVals [ "a" "b" "c" ] { a = 1; b = 2; c = 3; }
|
||||
=> [ 1 2 3 ]
|
||||
]]></programlisting>
|
||||
</example>
|
||||
|
||||
<example xml:id="function-library-lib.attrsets.attrVals-failure">
|
||||
<title>Getting missing values from an attribute set</title>
|
||||
<programlisting><![CDATA[
|
||||
lib.attrsets.attrVals [ "d" ] { }
|
||||
error: attribute 'd' missing
|
||||
]]></programlisting>
|
||||
</example>
|
||||
</section>
|
||||
|
||||
<section xml:id="function-library-lib.attrsets.attrValues">
|
||||
<title><function>lib.attrsets.attrValues</function></title>
|
||||
|
||||
<subtitle><literal>attrValues :: AttrSet -> [Any]</literal>
|
||||
</subtitle>
|
||||
|
||||
<xi:include href="./locations.xml" xpointer="lib.attrsets.attrValues" />
|
||||
|
||||
<para>
|
||||
Get all the attribute values from an attribute set.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Provides a backwards-compatible interface of
|
||||
<function>builtins.attrValues</function> for Nix version older than 1.8.
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>attrs</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The attribute set.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<example xml:id="function-library-lib.attrsets.attrValues-example">
|
||||
<title></title>
|
||||
<programlisting><![CDATA[
|
||||
lib.attrsets.attrValues { a = 1; b = 2; c = 3; }
|
||||
=> [ 1 2 3 ]
|
||||
]]></programlisting>
|
||||
</example>
|
||||
</section>
|
||||
|
||||
<section xml:id="function-library-lib.attrsets.catAttrs">
|
||||
<title><function>lib.attrsets.catAttrs</function></title>
|
||||
|
||||
<subtitle><literal>catAttrs :: String -> AttrSet -> [Any]</literal>
|
||||
</subtitle>
|
||||
|
||||
<xi:include href="./locations.xml" xpointer="lib.attrsets.catAttrs" />
|
||||
|
||||
<para>
|
||||
Collect each attribute named `attr' from the list of attribute sets,
|
||||
<varname>sets</varname>. Sets that don't contain the named attribute are
|
||||
ignored.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Provides a backwards-compatible interface of
|
||||
<function>builtins.catAttrs</function> for Nix version older than 1.9.
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>attr</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Attribute name to select from each attribute set in
|
||||
<varname>sets</varname>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>sets</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The list of attribute sets to select <varname>attr</varname> from.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<example xml:id="function-library-lib.attrsets.catAttrs-example">
|
||||
<title>Collect an attribute from a list of attribute sets.</title>
|
||||
<para>
|
||||
Attribute sets which don't have the attribute are ignored.
|
||||
</para>
|
||||
<programlisting><![CDATA[
|
||||
catAttrs "a" [{a = 1;} {b = 0;} {a = 2;}]
|
||||
=> [ 1 2 ]
|
||||
]]></programlisting>
|
||||
</example>
|
||||
</section>
|
||||
|
||||
<section xml:id="function-library-lib.attrsets.filterAttrs">
|
||||
<title><function>lib.attrsets.filterAttrs</function></title>
|
||||
|
||||
<subtitle><literal>filterAttrs :: (String -> Any -> Bool) -> AttrSet -> AttrSet</literal>
|
||||
</subtitle>
|
||||
|
||||
<xi:include href="./locations.xml" xpointer="lib.attrsets.filterAttrs" />
|
||||
|
||||
<para>
|
||||
Filter an attribute set by removing all attributes for which the given
|
||||
predicate return false.
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>pred</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>String -> Any -> Bool</literal>
|
||||
</para>
|
||||
<para>
|
||||
Predicate which returns true to include an attribute, or returns false to
|
||||
exclude it.
|
||||
</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>name</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The attribute's name
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>value</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The attribute's value
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<para>
|
||||
Returns <literal>true</literal> to include the attribute,
|
||||
<literal>false</literal> to exclude the attribute.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>set</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The attribute set to filter
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<example xml:id="function-library-lib.attrsets.filterAttrs-example">
|
||||
<title>Filtering an attributeset</title>
|
||||
<programlisting><![CDATA[
|
||||
filterAttrs (n: v: n == "foo") { foo = 1; bar = 2; }
|
||||
=> { foo = 1; }
|
||||
]]></programlisting>
|
||||
</example>
|
||||
</section>
|
||||
|
||||
<section xml:id="function-library-lib.attrsets.filterAttrsRecursive">
|
||||
<title><function>lib.attrsets.filterAttrsRecursive</function></title>
|
||||
|
||||
<subtitle><literal>filterAttrsRecursive :: (String -> Any -> Bool) -> AttrSet -> AttrSet</literal>
|
||||
</subtitle>
|
||||
|
||||
<xi:include href="./locations.xml" xpointer="lib.attrsets.filterAttrsRecursive" />
|
||||
|
||||
<para>
|
||||
Filter an attribute set recursively by removing all attributes for which the
|
||||
given predicate return false.
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>pred</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>String -> Any -> Bool</literal>
|
||||
</para>
|
||||
<para>
|
||||
Predicate which returns true to include an attribute, or returns false to
|
||||
exclude it.
|
||||
</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>name</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The attribute's name
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>value</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The attribute's value
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<para>
|
||||
Returns <literal>true</literal> to include the attribute,
|
||||
<literal>false</literal> to exclude the attribute.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>set</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The attribute set to filter
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<example xml:id="function-library-lib.attrsets.filterAttrsRecursive-example">
|
||||
<title>Recursively filtering an attribute set</title>
|
||||
<programlisting><![CDATA[
|
||||
lib.attrsets.filterAttrsRecursive
|
||||
(n: v: v != null)
|
||||
{
|
||||
levelA = {
|
||||
example = "hi";
|
||||
levelB = {
|
||||
hello = "there";
|
||||
this-one-is-present = {
|
||||
this-is-excluded = null;
|
||||
};
|
||||
};
|
||||
this-one-is-also-excluded = null;
|
||||
};
|
||||
also-excluded = null;
|
||||
}
|
||||
=> {
|
||||
levelA = {
|
||||
example = "hi";
|
||||
levelB = {
|
||||
hello = "there";
|
||||
this-one-is-present = { };
|
||||
};
|
||||
};
|
||||
}
|
||||
]]></programlisting>
|
||||
</example>
|
||||
</section>
|
||||
|
||||
<section xml:id="function-library-lib.attrsets.foldAttrs">
|
||||
<title><function>lib.attrsets.foldAttrs</function></title>
|
||||
|
||||
<subtitle><literal>foldAttrs :: (Any -> Any -> Any) -> Any -> [AttrSets] -> Any</literal>
|
||||
</subtitle>
|
||||
|
||||
<xi:include href="./locations.xml" xpointer="lib.attrsets.foldAttrs" />
|
||||
|
||||
<para>
|
||||
Apply fold function to values grouped by key.
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>op</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>Any -> Any -> Any</literal>
|
||||
</para>
|
||||
<para>
|
||||
Given a value <varname>val</varname> and a collector
|
||||
<varname>col</varname>, combine the two.
|
||||
</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>val</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
An attribute's value
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>col</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<!-- TODO: make this not bad, use more fold-ey terms -->
|
||||
<para>
|
||||
The result of previous <function>op</function> calls with other values
|
||||
and <function>nul</function>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>nul</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The null-value, the starting value.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>list_of_attrs</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
A list of attribute sets to fold together by key.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<example xml:id="function-library-lib.attrsets.foldAttrs-example">
|
||||
<title>Combining an attribute of lists in to one attribute set</title>
|
||||
<programlisting><![CDATA[
|
||||
lib.attrsets.foldAttrs
|
||||
(n: a: [n] ++ a) []
|
||||
[
|
||||
{ a = 2; b = 7; }
|
||||
{ a = 3; }
|
||||
{ b = 6; }
|
||||
]
|
||||
=> { a = [ 2 3 ]; b = [ 7 6 ]; }
|
||||
]]></programlisting>
|
||||
</example>
|
||||
</section>
|
||||
|
||||
<section xml:id="function-library-lib.attrsets.collect">
|
||||
<title><function>lib.attrsets.collect</function></title>
|
||||
|
||||
<subtitle><literal>collect :: (Any -> Bool) -> AttrSet -> [Any]</literal>
|
||||
</subtitle>
|
||||
|
||||
<xi:include href="./locations.xml" xpointer="lib.attrsets.collect" />
|
||||
|
||||
<para>
|
||||
Recursively collect sets that verify a given predicate named
|
||||
<varname>pred</varname> from the set <varname>attrs</varname>. The recursion
|
||||
stops when <varname>pred</varname> returns <literal>true</literal>.
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>pred</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>Any -> Bool</literal>
|
||||
</para>
|
||||
<para>
|
||||
Given an attribute's value, determine if recursion should stop.
|
||||
</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>value</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The attribute set value.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>attrs</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The attribute set to recursively collect.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<example xml:id="function-library-lib.attrsets.collect-example-lists">
|
||||
<title>Collecting all lists from an attribute set</title>
|
||||
<programlisting><![CDATA[
|
||||
lib.attrsets.collect isList { a = { b = ["b"]; }; c = [1]; }
|
||||
=> [["b"] [1]]
|
||||
]]></programlisting>
|
||||
</example>
|
||||
|
||||
<example xml:id="function-library-lib.attrsets.collect-example-outpath">
|
||||
<title>Collecting all attribute-sets which contain the <literal>outPath</literal> attribute name.</title>
|
||||
<programlisting><![CDATA[
|
||||
collect (x: x ? outPath)
|
||||
{ a = { outPath = "a/"; }; b = { outPath = "b/"; }; }
|
||||
=> [{ outPath = "a/"; } { outPath = "b/"; }]
|
||||
]]></programlisting>
|
||||
</example>
|
||||
</section>
|
||||
|
||||
<section xml:id="function-library-lib.attrsets.nameValuePair">
|
||||
<title><function>lib.attrsets.nameValuePair</function></title>
|
||||
|
||||
<subtitle><literal>nameValuePair :: String -> Any -> AttrSet</literal>
|
||||
</subtitle>
|
||||
|
||||
<xi:include href="./locations.xml" xpointer="lib.attrsets.nameValuePair" />
|
||||
|
||||
<para>
|
||||
Utility function that creates a <literal>{name, value}</literal> pair as
|
||||
expected by <function>builtins.listToAttrs</function>.
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>name</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The attribute name.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>value</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The attribute value.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<example xml:id="function-library-lib.attrsets.nameValuePair-example">
|
||||
<title>Creating a name value pair</title>
|
||||
<programlisting><![CDATA[
|
||||
nameValuePair "some" 6
|
||||
=> { name = "some"; value = 6; }
|
||||
]]></programlisting>
|
||||
</example>
|
||||
</section>
|
||||
|
||||
<section xml:id="function-library-lib.attrsets.mapAttrs">
|
||||
<title><function>lib.attrsets.mapAttrs</function></title>
|
||||
|
||||
<subtitle><literal></literal>
|
||||
</subtitle>
|
||||
|
||||
<xi:include href="./locations.xml" xpointer="lib.attrsets.mapAttrs" />
|
||||
|
||||
<para>
|
||||
Apply a function to each element in an attribute set, creating a new
|
||||
attribute set.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Provides a backwards-compatible interface of
|
||||
<function>builtins.mapAttrs</function> for Nix version older than 2.1.
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>fn</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>String -> Any -> Any</literal>
|
||||
</para>
|
||||
<para>
|
||||
Given an attribute's name and value, return a new value.
|
||||
</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>name</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The name of the attribute.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>value</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The attribute's value.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<example xml:id="function-library-lib.attrsets.mapAttrs-example">
|
||||
<title>Modifying each value of an attribute set</title>
|
||||
<programlisting><![CDATA[
|
||||
lib.attrsets.mapAttrs
|
||||
(name: value: name + "-" value)
|
||||
{ x = "foo"; y = "bar"; }
|
||||
=> { x = "x-foo"; y = "y-bar"; }
|
||||
]]></programlisting>
|
||||
</example>
|
||||
</section>
|
||||
|
||||
<section xml:id="function-library-lib.attrsets.mapAttrs-prime">
|
||||
<title><function>lib.attrsets.mapAttrs'</function></title>
|
||||
|
||||
<subtitle><literal>mapAttrs' :: (String -> Any -> { name = String; value = Any }) -> AttrSet -> AttrSet</literal>
|
||||
</subtitle>
|
||||
|
||||
<xi:include href="./locations.xml" xpointer="lib.attrsets.mapAttrs-prime" />
|
||||
|
||||
<para>
|
||||
Like <function>mapAttrs</function>, but allows the name of each attribute to
|
||||
be changed in addition to the value. The applied function should return both
|
||||
the new name and value as a <function>nameValuePair</function>.
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>fn</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>String -> Any -> { name = String; value = Any }</literal>
|
||||
</para>
|
||||
<para>
|
||||
Given an attribute's name and value, return a new
|
||||
<link
|
||||
linkend="function-library-lib.attrsets.nameValuePair">name
|
||||
value pair</link>.
|
||||
</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>name</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The name of the attribute.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>value</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The attribute's value.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>set</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The attribute set to map over.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<example xml:id="function-library-lib.attrsets.mapAttrs-prime-example">
|
||||
<title>Change the name and value of each attribute of an attribute set</title>
|
||||
<programlisting><![CDATA[
|
||||
lib.attrsets.mapAttrs' (name: value: lib.attrsets.nameValuePair ("foo_" + name) ("bar-" + value))
|
||||
{ x = "a"; y = "b"; }
|
||||
=> { foo_x = "bar-a"; foo_y = "bar-b"; }
|
||||
|
||||
]]></programlisting>
|
||||
</example>
|
||||
</section>
|
||||
|
||||
<section xml:id="function-library-lib.attrsets.mapAttrsToList">
|
||||
<title><function>lib.attrsets.mapAttrsToList</function></title>
|
||||
|
||||
<subtitle><literal>mapAttrsToList :: (String -> Any -> Any) ->
|
||||
AttrSet -> Any</literal>
|
||||
</subtitle>
|
||||
|
||||
<xi:include href="./locations.xml" xpointer="lib.attrsets.mapAttrsToList" />
|
||||
|
||||
<para>
|
||||
Call <varname>fn</varname> for each attribute in the given
|
||||
<varname>set</varname> and return the result in a list.
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>fn</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>String -> Any -> Any</literal>
|
||||
</para>
|
||||
<para>
|
||||
Given an attribute's name and value, return a new value.
|
||||
</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>name</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The name of the attribute.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>value</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The attribute's value.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>set</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The attribute set to map over.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<example xml:id="function-library-lib.attrsets.mapAttrsToList-example">
|
||||
<title>Combine attribute values and names in to a list</title>
|
||||
<programlisting><![CDATA[
|
||||
lib.attrsets.mapAttrsToList (name: value: "${name}=${value}")
|
||||
{ x = "a"; y = "b"; }
|
||||
=> [ "x=a" "y=b" ]
|
||||
]]></programlisting>
|
||||
</example>
|
||||
</section>
|
||||
|
||||
<section xml:id="function-library-lib.attrsets.mapAttrsRecursive">
|
||||
<title><function>lib.attrsets.mapAttrsRecursive</function></title>
|
||||
|
||||
<subtitle><literal>mapAttrsRecursive :: ([String] > Any -> Any) -> AttrSet -> AttrSet</literal>
|
||||
</subtitle>
|
||||
|
||||
<xi:include href="./locations.xml" xpointer="lib.attrsets.mapAttrsRecursive" />
|
||||
|
||||
<para>
|
||||
Like <function>mapAttrs</function>, except that it recursively applies
|
||||
itself to attribute sets. Also, the first argument of the argument function
|
||||
is a <emphasis>list</emphasis> of the names of the containing attributes.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
203
doc/functions/overrides.xml
Normal file
203
doc/functions/overrides.xml
Normal file
@ -0,0 +1,203 @@
|
||||
<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-overrides">
|
||||
<title>Overriding</title>
|
||||
|
||||
<para>
|
||||
Sometimes one wants to override parts of <literal>nixpkgs</literal>, e.g.
|
||||
derivation attributes, the results of derivations or even the whole package
|
||||
set.
|
||||
</para>
|
||||
|
||||
<section xml:id="sec-pkg-override">
|
||||
<title><pkg>.override</title>
|
||||
|
||||
<para>
|
||||
The function <varname>override</varname> is usually available for all the
|
||||
derivations in the nixpkgs expression (<varname>pkgs</varname>).
|
||||
</para>
|
||||
|
||||
<para>
|
||||
It is used to override the arguments passed to a function.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Example usages:
|
||||
<programlisting>pkgs.foo.override { arg1 = val1; arg2 = val2; ... }</programlisting>
|
||||
<programlisting>
|
||||
import pkgs.path { overlays = [ (self: super: {
|
||||
foo = super.foo.override { barSupport = true ; };
|
||||
})]};
|
||||
</programlisting>
|
||||
<programlisting>
|
||||
mypkg = pkgs.callPackage ./mypkg.nix {
|
||||
mydep = pkgs.mydep.override { ... };
|
||||
}
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In the first example, <varname>pkgs.foo</varname> is the result of a
|
||||
function call with some default arguments, usually a derivation. Using
|
||||
<varname>pkgs.foo.override</varname> will call the same function with the
|
||||
given new arguments.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="sec-pkg-overrideAttrs">
|
||||
<title><pkg>.overrideAttrs</title>
|
||||
|
||||
<para>
|
||||
The function <varname>overrideAttrs</varname> allows overriding the
|
||||
attribute set passed to a <varname>stdenv.mkDerivation</varname> call,
|
||||
producing a new derivation based on the original one. This function is
|
||||
available on all derivations produced by the
|
||||
<varname>stdenv.mkDerivation</varname> function, which is most packages in
|
||||
the nixpkgs expression <varname>pkgs</varname>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Example usage:
|
||||
<programlisting>
|
||||
helloWithDebug = pkgs.hello.overrideAttrs (oldAttrs: rec {
|
||||
separateDebugInfo = true;
|
||||
});
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In the above example, the <varname>separateDebugInfo</varname> attribute is
|
||||
overridden to be true, thus building debug info for
|
||||
<varname>helloWithDebug</varname>, while all other attributes will be
|
||||
retained from the original <varname>hello</varname> package.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The argument <varname>oldAttrs</varname> is conventionally used to refer to
|
||||
the attr set originally passed to <varname>stdenv.mkDerivation</varname>.
|
||||
</para>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
Note that <varname>separateDebugInfo</varname> is processed only by the
|
||||
<varname>stdenv.mkDerivation</varname> function, not the generated, raw Nix
|
||||
derivation. Thus, using <varname>overrideDerivation</varname> will not work
|
||||
in this case, as it overrides only the attributes of the final derivation.
|
||||
It is for this reason that <varname>overrideAttrs</varname> should be
|
||||
preferred in (almost) all cases to <varname>overrideDerivation</varname>,
|
||||
i.e. to allow using <varname>sdenv.mkDerivation</varname> to process input
|
||||
arguments, as well as the fact that it is easier to use (you can use the
|
||||
same attribute names you see in your Nix code, instead of the ones
|
||||
generated (e.g. <varname>buildInputs</varname> vs
|
||||
<varname>nativeBuildInputs</varname>, and involves less typing.
|
||||
</para>
|
||||
</note>
|
||||
</section>
|
||||
|
||||
<section xml:id="sec-pkg-overrideDerivation">
|
||||
<title><pkg>.overrideDerivation</title>
|
||||
|
||||
<warning>
|
||||
<para>
|
||||
You should prefer <varname>overrideAttrs</varname> in almost all cases, see
|
||||
its documentation for the reasons why.
|
||||
<varname>overrideDerivation</varname> is not deprecated and will continue
|
||||
to work, but is less nice to use and does not have as many abilities as
|
||||
<varname>overrideAttrs</varname>.
|
||||
</para>
|
||||
</warning>
|
||||
|
||||
<warning>
|
||||
<para>
|
||||
Do not use this function in Nixpkgs as it evaluates a Derivation before
|
||||
modifying it, which breaks package abstraction and removes error-checking
|
||||
of function arguments. In addition, this evaluation-per-function
|
||||
application incurs a performance penalty, which can become a problem if
|
||||
many overrides are used. It is only intended for ad-hoc customisation, such
|
||||
as in <filename>~/.config/nixpkgs/config.nix</filename>.
|
||||
</para>
|
||||
</warning>
|
||||
|
||||
<para>
|
||||
The function <varname>overrideDerivation</varname> creates a new derivation
|
||||
based on an existing one by overriding the original's attributes with the
|
||||
attribute set produced by the specified function. This function is available
|
||||
on all derivations defined using the <varname>makeOverridable</varname>
|
||||
function. Most standard derivation-producing functions, such as
|
||||
<varname>stdenv.mkDerivation</varname>, are defined using this function,
|
||||
which means most packages in the nixpkgs expression,
|
||||
<varname>pkgs</varname>, have this function.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Example usage:
|
||||
<programlisting>
|
||||
mySed = pkgs.gnused.overrideDerivation (oldAttrs: {
|
||||
name = "sed-4.2.2-pre";
|
||||
src = fetchurl {
|
||||
url = ftp://alpha.gnu.org/gnu/sed/sed-4.2.2-pre.tar.bz2;
|
||||
sha256 = "11nq06d131y4wmf3drm0yk502d2xc6n5qy82cg88rb9nqd2lj41k";
|
||||
};
|
||||
patches = [];
|
||||
});
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In the above example, the <varname>name</varname>, <varname>src</varname>,
|
||||
and <varname>patches</varname> of the derivation will be overridden, while
|
||||
all other attributes will be retained from the original derivation.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The argument <varname>oldAttrs</varname> is used to refer to the attribute
|
||||
set of the original derivation.
|
||||
</para>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
A package's attributes are evaluated *before* being modified by the
|
||||
<varname>overrideDerivation</varname> function. For example, the
|
||||
<varname>name</varname> attribute reference in <varname>url =
|
||||
"mirror://gnu/hello/${name}.tar.gz";</varname> is filled-in *before* the
|
||||
<varname>overrideDerivation</varname> function modifies the attribute set.
|
||||
This means that overriding the <varname>name</varname> attribute, in this
|
||||
example, *will not* change the value of the <varname>url</varname>
|
||||
attribute. Instead, we need to override both the <varname>name</varname>
|
||||
*and* <varname>url</varname> attributes.
|
||||
</para>
|
||||
</note>
|
||||
</section>
|
||||
|
||||
<section xml:id="sec-lib-makeOverridable">
|
||||
<title>lib.makeOverridable</title>
|
||||
|
||||
<para>
|
||||
The function <varname>lib.makeOverridable</varname> is used to make the
|
||||
result of a function easily customizable. This utility only makes sense for
|
||||
functions that accept an argument set and return an attribute set.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Example usage:
|
||||
<programlisting>
|
||||
f = { a, b }: { result = a+b; };
|
||||
c = lib.makeOverridable f { a = 1; b = 2; };
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The variable <varname>c</varname> is the value of the <varname>f</varname>
|
||||
function applied with some default arguments. Hence the value of
|
||||
<varname>c.result</varname> is <literal>3</literal>, in this example.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The variable <varname>c</varname> however also has some additional
|
||||
functions, like <link linkend="sec-pkg-override">c.override</link> which can
|
||||
be used to override the default arguments. In this example the value of
|
||||
<varname>(c.override { a = 4; }).result</varname> is 6.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
26
doc/functions/shell.xml
Normal file
26
doc/functions/shell.xml
Normal file
@ -0,0 +1,26 @@
|
||||
<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-mkShell">
|
||||
<title>pkgs.mkShell</title>
|
||||
|
||||
<para>
|
||||
<function>pkgs.mkShell</function> is a special kind of derivation that is
|
||||
only useful when using it combined with <command>nix-shell</command>. It will
|
||||
in fact fail to instantiate when invoked with <command>nix-build</command>.
|
||||
</para>
|
||||
|
||||
<section xml:id="sec-pkgs-mkShell-usage">
|
||||
<title>Usage</title>
|
||||
|
||||
<programlisting><![CDATA[
|
||||
{ pkgs ? import <nixpkgs> {} }:
|
||||
pkgs.mkShell {
|
||||
# this will make all the build inputs from hello and gnutar
|
||||
# available to the shell environment
|
||||
inputsFrom = with pkgs; [ hello gnutar ];
|
||||
buildInputs = [ pkgs.gnumake ];
|
||||
}
|
||||
]]></programlisting>
|
||||
</section>
|
||||
</section>
|
85
doc/lib-function-locations.nix
Normal file
85
doc/lib-function-locations.nix
Normal file
@ -0,0 +1,85 @@
|
||||
{ pkgs ? (import ./.. { }), nixpkgs ? { }}:
|
||||
let
|
||||
revision = pkgs.lib.trivial.revisionWithDefault (nixpkgs.revision or "master");
|
||||
|
||||
libDefPos = set:
|
||||
builtins.map
|
||||
(name: {
|
||||
name = name;
|
||||
location = builtins.unsafeGetAttrPos name set;
|
||||
})
|
||||
(builtins.attrNames set);
|
||||
|
||||
libset = toplib:
|
||||
builtins.map
|
||||
(subsetname: {
|
||||
subsetname = subsetname;
|
||||
functions = libDefPos toplib."${subsetname}";
|
||||
})
|
||||
(builtins.filter
|
||||
(name: builtins.isAttrs toplib."${name}")
|
||||
(builtins.attrNames toplib));
|
||||
|
||||
nixpkgsLib = pkgs.lib;
|
||||
|
||||
flattenedLibSubset = { subsetname, functions }:
|
||||
builtins.map
|
||||
(fn: {
|
||||
name = "lib.${subsetname}.${fn.name}";
|
||||
value = fn.location;
|
||||
})
|
||||
functions;
|
||||
|
||||
locatedlibsets = libs: builtins.map flattenedLibSubset (libset libs);
|
||||
removeFilenamePrefix = prefix: filename:
|
||||
let
|
||||
prefixLen = (builtins.stringLength prefix) + 1; # +1 to remove the leading /
|
||||
filenameLen = builtins.stringLength filename;
|
||||
substr = builtins.substring prefixLen filenameLen filename;
|
||||
in substr;
|
||||
|
||||
removeNixpkgs = removeFilenamePrefix (builtins.toString pkgs.path);
|
||||
|
||||
liblocations =
|
||||
builtins.filter
|
||||
(elem: elem.value != null)
|
||||
(nixpkgsLib.lists.flatten
|
||||
(locatedlibsets nixpkgsLib));
|
||||
|
||||
fnLocationRelative = { name, value }:
|
||||
{
|
||||
inherit name;
|
||||
value = value // { file = removeNixpkgs value.file; };
|
||||
};
|
||||
|
||||
relativeLocs = (builtins.map fnLocationRelative liblocations);
|
||||
sanitizeId = builtins.replaceStrings
|
||||
[ "'" ]
|
||||
[ "-prime" ];
|
||||
|
||||
urlPrefix = "https://github.com/NixOS/nixpkgs/blob/${revision}";
|
||||
xmlstrings = (nixpkgsLib.strings.concatMapStrings
|
||||
({ name, value }:
|
||||
''
|
||||
<section><title>${name}</title>
|
||||
<para xml:id="${sanitizeId name}">
|
||||
Located at
|
||||
<link
|
||||
xlink:href="${urlPrefix}/${value.file}#L${builtins.toString value.line}">${value.file}:${builtins.toString value.line}</link>
|
||||
in <literal><nixpkgs></literal>.
|
||||
</para>
|
||||
</section>
|
||||
'')
|
||||
relativeLocs);
|
||||
|
||||
in pkgs.writeText
|
||||
"locations.xml"
|
||||
''
|
||||
<section xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
version="5">
|
||||
<title>All the locations for every lib function</title>
|
||||
<para>This file is only for inclusion by other files.</para>
|
||||
${xmlstrings}
|
||||
</section>
|
||||
''
|
@ -668,8 +668,9 @@ overrides = self: super: rec {
|
||||
plugins = with availablePlugins; [ python perl ];
|
||||
}
|
||||
}</programlisting>
|
||||
If the <literal>configure</literal> function returns an attrset without the <literal>plugins</literal>
|
||||
attribute, <literal>availablePlugins</literal> will be used automatically.
|
||||
If the <literal>configure</literal> function returns an attrset without the
|
||||
<literal>plugins</literal> attribute, <literal>availablePlugins</literal>
|
||||
will be used automatically.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -703,9 +704,11 @@ overrides = self: super: rec {
|
||||
}; }
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
WeeChat allows to set defaults on startup using the <literal>--run-command</literal>.
|
||||
The <literal>configure</literal> method can be used to pass commands to the program:
|
||||
WeeChat allows to set defaults on startup using the
|
||||
<literal>--run-command</literal>. The <literal>configure</literal> method
|
||||
can be used to pass commands to the program:
|
||||
<programlisting>weechat.override {
|
||||
configure = { availablePlugins, ... }: {
|
||||
init = ''
|
||||
@ -714,12 +717,14 @@ overrides = self: super: rec {
|
||||
'';
|
||||
};
|
||||
}</programlisting>
|
||||
Further values can be added to the list of commands when running
|
||||
<literal>weechat --run-command "your-commands"</literal>.
|
||||
Further values can be added to the list of commands when running
|
||||
<literal>weechat --run-command "your-commands"</literal>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Additionally it's possible to specify scripts to be loaded when starting <literal>weechat</literal>.
|
||||
These will be loaded before the commands from <literal>init</literal>:
|
||||
Additionally it's possible to specify scripts to be loaded when starting
|
||||
<literal>weechat</literal>. These will be loaded before the commands from
|
||||
<literal>init</literal>:
|
||||
<programlisting>weechat.override {
|
||||
configure = { availablePlugins, ... }: {
|
||||
scripts = with pkgs.weechatScripts; [
|
||||
@ -731,11 +736,13 @@ overrides = self: super: rec {
|
||||
};
|
||||
}</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In <literal>nixpkgs</literal> there's a subpackage which contains derivations for
|
||||
WeeChat scripts. Such derivations expect a <literal>passthru.scripts</literal> attribute
|
||||
which contains a list of all scripts inside the store path. Furthermore all scripts
|
||||
have to live in <literal>$out/share</literal>. An exemplary derivation looks like this:
|
||||
In <literal>nixpkgs</literal> there's a subpackage which contains
|
||||
derivations for WeeChat scripts. Such derivations expect a
|
||||
<literal>passthru.scripts</literal> attribute which contains a list of all
|
||||
scripts inside the store path. Furthermore all scripts have to live in
|
||||
<literal>$out/share</literal>. An exemplary derivation looks like this:
|
||||
<programlisting>{ stdenv, fetchurl }:
|
||||
|
||||
stdenv.mkDerivation {
|
||||
@ -814,20 +821,26 @@ citrix_receiver.override {
|
||||
<section xml:id="sec-ibus-typing-booster">
|
||||
<title>ibus-engines.typing-booster</title>
|
||||
|
||||
<para>This package is an ibus-based completion method to speed up typing.</para>
|
||||
<para>
|
||||
This package is an ibus-based completion method to speed up typing.
|
||||
</para>
|
||||
|
||||
<section xml:id="sec-ibus-typing-booster-activate">
|
||||
<title>Activating the engine</title>
|
||||
|
||||
<para>
|
||||
IBus needs to be configured accordingly to activate <literal>typing-booster</literal>. The configuration
|
||||
depends on the desktop manager in use. For detailed instructions, please refer to the
|
||||
<link xlink:href="https://mike-fabian.github.io/ibus-typing-booster/documentation.html">upstream docs</link>.
|
||||
IBus needs to be configured accordingly to activate
|
||||
<literal>typing-booster</literal>. The configuration depends on the desktop
|
||||
manager in use. For detailed instructions, please refer to the
|
||||
<link xlink:href="https://mike-fabian.github.io/ibus-typing-booster/documentation.html">upstream
|
||||
docs</link>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
On NixOS you need to explicitly enable <literal>ibus</literal> with given engines
|
||||
before customizing your desktop to use <literal>typing-booster</literal>. This can be achieved
|
||||
using the <literal>ibus</literal> module:
|
||||
On NixOS you need to explicitly enable <literal>ibus</literal> with given
|
||||
engines before customizing your desktop to use
|
||||
<literal>typing-booster</literal>. This can be achieved using the
|
||||
<literal>ibus</literal> module:
|
||||
<programlisting>{ pkgs, ... }: {
|
||||
i18n.inputMethod = {
|
||||
enabled = "ibus";
|
||||
@ -841,17 +854,20 @@ citrix_receiver.override {
|
||||
<title>Using custom hunspell dictionaries</title>
|
||||
|
||||
<para>
|
||||
The IBus engine is based on <literal>hunspell</literal> to support completion in many languages.
|
||||
By default the dictionaries <literal>de-de</literal>, <literal>en-us</literal>, <literal>es-es</literal>,
|
||||
<literal>it-it</literal>, <literal>sv-se</literal> and <literal>sv-fi</literal>
|
||||
are in use. To add another dictionary, the package can be overridden like this:
|
||||
The IBus engine is based on <literal>hunspell</literal> to support
|
||||
completion in many languages. By default the dictionaries
|
||||
<literal>de-de</literal>, <literal>en-us</literal>,
|
||||
<literal>es-es</literal>, <literal>it-it</literal>,
|
||||
<literal>sv-se</literal> and <literal>sv-fi</literal> are in use. To add
|
||||
another dictionary, the package can be overridden like this:
|
||||
<programlisting>ibus-engines.typing-booster.override {
|
||||
langs = [ "de-at" "en-gb" ];
|
||||
}</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<emphasis>Note: each language passed to <literal>langs</literal> must be an attribute name in
|
||||
<literal>pkgs.hunspellDicts</literal>.</emphasis>
|
||||
<emphasis>Note: each language passed to <literal>langs</literal> must be an
|
||||
attribute name in <literal>pkgs.hunspellDicts</literal>.</emphasis>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
@ -859,10 +875,12 @@ citrix_receiver.override {
|
||||
<title>Built-in emoji picker</title>
|
||||
|
||||
<para>
|
||||
The <literal>ibus-engines.typing-booster</literal> package contains a program
|
||||
named <literal>emoji-picker</literal>. To display all emojis correctly,
|
||||
a special font such as <literal>noto-fonts-emoji</literal> is needed:
|
||||
The <literal>ibus-engines.typing-booster</literal> package contains a
|
||||
program named <literal>emoji-picker</literal>. To display all emojis
|
||||
correctly, a special font such as <literal>noto-fonts-emoji</literal> is
|
||||
needed:
|
||||
</para>
|
||||
|
||||
<para>
|
||||
On NixOS it can be installed using the following expression:
|
||||
<programlisting>{ pkgs, ... }: {
|
||||
|
@ -1,5 +1,5 @@
|
||||
{ pkgs ? import ../. {} }:
|
||||
(import ./default.nix).overrideAttrs (x: {
|
||||
(import ./default.nix {}).overrideAttrs (x: {
|
||||
buildInputs = x.buildInputs ++ [ pkgs.xmloscopy pkgs.ruby ];
|
||||
|
||||
})
|
||||
|
@ -1,22 +0,0 @@
|
||||
---
|
||||
title: pkgs.mkShell
|
||||
author: zimbatm
|
||||
date: 2017-10-30
|
||||
---
|
||||
|
||||
# mkShell
|
||||
|
||||
pkgs.mkShell is a special kind of derivation that is only useful when using
|
||||
it combined with nix-shell. It will in fact fail to instantiate when invoked
|
||||
with nix-build.
|
||||
|
||||
## Usage
|
||||
|
||||
```nix
|
||||
{ pkgs ? import <nixpkgs> {} }:
|
||||
pkgs.mkShell {
|
||||
# this will make all the build inputs from hello and gnutar available to the shell environment
|
||||
inputsFrom = with pkgs; [ hello gnutar ];
|
||||
buildInputs = [ pkgs.gnumake ];
|
||||
}
|
||||
```
|
@ -8,7 +8,31 @@ with lib.strings;
|
||||
|
||||
rec {
|
||||
|
||||
# Returns true when the given argument is an option
|
||||
#
|
||||
# Examples:
|
||||
# isOption 1 // => false
|
||||
# isOption (mkOption {}) // => true
|
||||
isOption = lib.isType "option";
|
||||
|
||||
# Creates an Option attribute set. mkOption accepts an attribute set with the following keys:
|
||||
#
|
||||
# default: Default value used when no definition is given in the configuration.
|
||||
# defaultText: Textual representation of the default, for in the manual.
|
||||
# example: Example value used in the manual.
|
||||
# description: String describing the option.
|
||||
# type: Option type, providing type-checking and value merging.
|
||||
# apply: Function that converts the option value to something else.
|
||||
# internal: Whether the option is for NixOS developers only.
|
||||
# visible: Whether the option shows up in the manual.
|
||||
# readOnly: Whether the option can be set only once
|
||||
# options: Obsolete, used by types.optionSet.
|
||||
#
|
||||
# All keys default to `null` when not given.
|
||||
#
|
||||
# Examples:
|
||||
# mkOption { } // => { _type = "option"; }
|
||||
# mkOption { defaultText = "foo"; } // => { _type = "option"; defaultText = "foo"; }
|
||||
mkOption =
|
||||
{ default ? null # Default value used when no definition is given in the configuration.
|
||||
, defaultText ? null # Textual representation of the default, for in the manual.
|
||||
@ -24,6 +48,10 @@ rec {
|
||||
} @ attrs:
|
||||
attrs // { _type = "option"; };
|
||||
|
||||
# Creates a Option attribute set for a boolean value option i.e an option to be toggled on or off:
|
||||
#
|
||||
# Examples:
|
||||
# mkEnableOption "foo" // => { _type = "option"; default = false; description = "Whether to enable foo."; example = true; type = { ... }; }
|
||||
mkEnableOption = name: mkOption {
|
||||
default = false;
|
||||
example = true;
|
||||
@ -74,7 +102,18 @@ rec {
|
||||
else
|
||||
val) (head defs).value defs;
|
||||
|
||||
# Extracts values of all "value" keys of the given list
|
||||
#
|
||||
# Examples:
|
||||
# getValues [ { value = 1; } { value = 2; } ] // => [ 1 2 ]
|
||||
# getValues [ ] // => [ ]
|
||||
getValues = map (x: x.value);
|
||||
|
||||
# Extracts values of all "file" keys of the given list
|
||||
#
|
||||
# Examples:
|
||||
# getFiles [ { file = "file1"; } { file = "file2"; } ] // => [ "file1" "file2" ]
|
||||
# getFiles [ ] // => [ ]
|
||||
getFiles = map (x: x.file);
|
||||
|
||||
# Generate documentation template from the list of option declaration like
|
||||
|
@ -26,6 +26,10 @@ rec {
|
||||
(type == "symlink" && lib.hasPrefix "result" baseName)
|
||||
);
|
||||
|
||||
# Filters a source tree removing version control files and directories using cleanSourceWith
|
||||
#
|
||||
# Example:
|
||||
# cleanSource ./.
|
||||
cleanSource = src: cleanSourceWith { filter = cleanSourceFilter; inherit src; };
|
||||
|
||||
# Like `builtins.filterSource`, except it will compose with itself,
|
||||
|
@ -105,6 +105,16 @@ rec {
|
||||
then lib.strings.fileContents suffixFile
|
||||
else "pre-git";
|
||||
|
||||
# Attempt to get the revision nixpkgs is from
|
||||
revisionWithDefault = default:
|
||||
let
|
||||
revisionFile = "${toString ./..}/.git-revision";
|
||||
gitRepo = "${toString ./..}/.git";
|
||||
in if lib.pathIsDirectory gitRepo
|
||||
then lib.commitIdFromGitRepo gitRepo
|
||||
else if lib.pathExists revisionFile then lib.fileContents revisionFile
|
||||
else default;
|
||||
|
||||
nixpkgsVersion = builtins.trace "`lib.nixpkgsVersion` is deprecated, use `lib.version` instead!" version;
|
||||
|
||||
# Whether we're being called by nix-shell.
|
||||
|
@ -1135,6 +1135,11 @@
|
||||
github = "dtzWill";
|
||||
name = "Will Dietz";
|
||||
};
|
||||
dysinger = {
|
||||
email = "tim@dysinger.net";
|
||||
github = "dysinger";
|
||||
name = "Tim Dysinger";
|
||||
};
|
||||
dywedir = {
|
||||
email = "dywedir@protonmail.ch";
|
||||
github = "dywedir";
|
||||
@ -2199,6 +2204,11 @@
|
||||
github = "krav";
|
||||
name = "Kristoffer Thømt Ravneberg";
|
||||
};
|
||||
kroell = {
|
||||
email = "nixosmainter@makroell.de";
|
||||
github = "rokk4";
|
||||
name = "Matthias Axel Kröll";
|
||||
};
|
||||
kristoff3r = {
|
||||
email = "k.soeholm@gmail.com";
|
||||
github = "kristoff3r";
|
||||
@ -2442,6 +2452,11 @@
|
||||
github = "ma27";
|
||||
name = "Maximilian Bosch";
|
||||
};
|
||||
ma9e = {
|
||||
email = "sean@lfo.team";
|
||||
github = "ma9e";
|
||||
name = "Sean Haugh";
|
||||
};
|
||||
madjar = {
|
||||
email = "georges.dubus@compiletoi.net";
|
||||
github = "madjar";
|
||||
@ -3042,7 +3057,7 @@
|
||||
name = "Oliver Dunkl";
|
||||
};
|
||||
offline = {
|
||||
email = "jakahudoklin@gmail.com";
|
||||
email = "jaka@x-truder.net";
|
||||
github = "offlinehacker";
|
||||
name = "Jaka Hudoklin";
|
||||
};
|
||||
@ -3105,6 +3120,11 @@
|
||||
github = "oyren";
|
||||
name = "Moritz Scheuren";
|
||||
};
|
||||
pacien = {
|
||||
email = "b4gx3q.nixpkgs@pacien.net";
|
||||
github = "pacien";
|
||||
name = "Pacien Tran-Girard";
|
||||
};
|
||||
paholg = {
|
||||
email = "paho@paholg.com";
|
||||
github = "paholg";
|
||||
@ -3314,6 +3334,11 @@
|
||||
github = "proglodyte";
|
||||
name = "Proglodyte";
|
||||
};
|
||||
prusnak = {
|
||||
email = "stick@gk2.sk";
|
||||
github = "prusnak";
|
||||
name = "Pavol Rusnak";
|
||||
};
|
||||
pshendry = {
|
||||
email = "paul@pshendry.com";
|
||||
github = "pshendry";
|
||||
@ -4312,6 +4337,11 @@
|
||||
github = "uri-canva";
|
||||
name = "Uri Baghin";
|
||||
};
|
||||
uskudnik = {
|
||||
email = "urban.skudnik@gmail.com";
|
||||
github = "uskudnik";
|
||||
name = "Urban Skudnik";
|
||||
};
|
||||
utdemir = {
|
||||
email = "me@utdemir.com";
|
||||
github = "utdemir";
|
||||
@ -4648,6 +4678,11 @@
|
||||
github = "maggesi";
|
||||
name = "Marco Maggesi";
|
||||
};
|
||||
zachcoyle = {
|
||||
email = "zach.coyle@gmail.com";
|
||||
github = "zachcoyle";
|
||||
name = "Zach Coyle";
|
||||
};
|
||||
zagy = {
|
||||
email = "cz@flyingcircus.io";
|
||||
github = "zagy";
|
||||
|
@ -4,7 +4,7 @@ all: manual-combined.xml format
|
||||
.PHONY: debug
|
||||
debug: generated manual-combined.xml
|
||||
|
||||
manual-combined.xml: generated *.xml
|
||||
manual-combined.xml: generated *.xml **/*.xml
|
||||
rm -f ./manual-combined.xml
|
||||
nix-shell --packages xmloscopy \
|
||||
--run "xmloscopy --docbook5 ./manual.xml ./manual-combined.xml"
|
||||
|
@ -52,4 +52,7 @@ $ ping -c1 10.233.4.2
|
||||
networking.networkmanager.unmanaged = [ "interface-name:ve-*" ];
|
||||
</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
You may need to restart your system for the changes to take effect.
|
||||
</para>
|
||||
</section>
|
||||
|
@ -73,7 +73,8 @@ Linux foo 3.4.82 #1-NixOS SMP Thu Mar 20 14:44:05 UTC 2014 x86_64 GNU/Linux
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To change the configuration of the container, you can edit
|
||||
There are several ways to change the configuration of the container. First,
|
||||
on the host, you can edit
|
||||
<literal>/var/lib/container/<replaceable>name</replaceable>/etc/nixos/configuration.nix</literal>,
|
||||
and run
|
||||
<screen>
|
||||
@ -86,7 +87,8 @@ Linux foo 3.4.82 #1-NixOS SMP Thu Mar 20 14:44:05 UTC 2014 x86_64 GNU/Linux
|
||||
<xref linkend="opt-services.httpd.enable"/> = true;
|
||||
<xref linkend="opt-services.httpd.adminAddr"/> = "foo@example.org";
|
||||
<xref linkend="opt-networking.firewall.allowedTCPPorts"/> = [ 80 ];
|
||||
'
|
||||
'
|
||||
|
||||
# curl http://$(nixos-container show-ip foo)/
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">…
|
||||
</screen>
|
||||
@ -95,13 +97,11 @@ Linux foo 3.4.82 #1-NixOS SMP Thu Mar 20 14:44:05 UTC 2014 x86_64 GNU/Linux
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Note that in previous versions of NixOS (17.09 and earlier) one could also
|
||||
use all nix-related commands (like <command>nixos-rebuild switch</command>)
|
||||
from inside the container. However, since the release of Nix 2.0 this is not
|
||||
supported anymore. Supporting Nix commands inside the container might be
|
||||
possible again in future versions. See
|
||||
<link xlink:href="https://github.com/NixOS/nixpkgs/issues/40355">the github
|
||||
issue</link> for tracking progress on this issue.
|
||||
Alternatively, you can change the configuration from within the container
|
||||
itself by running <command>nixos-rebuild switch</command> inside the
|
||||
container. Note that the container by default does not have a copy of the
|
||||
NixOS channel, so you should run <command>nix-channel --update</command>
|
||||
first.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
|
@ -9,13 +9,12 @@
|
||||
For systems without CD drive, the NixOS live CD can be booted from a USB
|
||||
stick. You can use the <command>dd</command> utility to write the image:
|
||||
<command>dd if=<replaceable>path-to-image</replaceable>
|
||||
of=<replaceable>/dev/sdb</replaceable></command>. Be careful about specifying
|
||||
of=<replaceable>/dev/sdX</replaceable></command>. Be careful about specifying
|
||||
the correct drive; you can use the <command>lsblk</command> command to get a
|
||||
list of block devices.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
On macOS:
|
||||
<note>
|
||||
<title>On macOS</title>
|
||||
<para>
|
||||
<programlisting>
|
||||
$ diskutil list
|
||||
[..]
|
||||
@ -26,43 +25,16 @@ $ diskutil unmountDisk diskN
|
||||
Unmount of all volumes on diskN was successful
|
||||
$ sudo dd bs=1m if=nix.iso of=/dev/rdiskN
|
||||
</programlisting>
|
||||
Using the 'raw' <command>rdiskN</command> device instead of
|
||||
<command>diskN</command> completes in minutes instead of hours. After
|
||||
<command>dd</command> completes, a GUI dialog "The disk you inserted was not
|
||||
readable by this computer" will pop up, which can be ignored.
|
||||
Using the 'raw' <command>rdiskN</command> device instead of
|
||||
<command>diskN</command> completes in minutes instead of hours. After
|
||||
<command>dd</command> completes, a GUI dialog "The disk you inserted was
|
||||
not readable by this computer" will pop up, which can be ignored.
|
||||
</para>
|
||||
</note>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The <command>dd</command> utility will write the image verbatim to the drive,
|
||||
making it the recommended option for both UEFI and non-UEFI installations.
|
||||
For non-UEFI installations, you can alternatively use
|
||||
<link xlink:href="http://unetbootin.sourceforge.net/">unetbootin</link>. If
|
||||
you cannot use <command>dd</command> for a UEFI installation, you can also
|
||||
mount the ISO, copy its contents verbatim to your drive, then either:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Change the label of the disk partition to the label of the ISO (visible
|
||||
with the blkid command), or
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Edit <filename>loader/entries/nixos-livecd.conf</filename> on the drive
|
||||
and change the <literal>root=</literal> field in the
|
||||
<literal>options</literal> line to point to your drive (see the
|
||||
documentation on <literal>root=</literal> in
|
||||
<link xlink:href="https://www.kernel.org/doc/Documentation/admin-guide/kernel-parameters.txt">
|
||||
the kernel documentation</link> for more details).
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
If you want to load the contents of the ISO to ram after bootin (So you
|
||||
can remove the stick after bootup) you can append the parameter
|
||||
<literal>copytoram</literal> to the <literal>options</literal> field.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</section>
|
||||
|
@ -4,60 +4,46 @@
|
||||
version="5.0"
|
||||
xml:id="sec-installation">
|
||||
<title>Installing NixOS</title>
|
||||
<para>
|
||||
NixOS can be installed on BIOS or UEFI systems. The procedure for a UEFI
|
||||
installation is by and large the same as a BIOS installation. The differences
|
||||
are mentioned in the steps that follow.
|
||||
</para>
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Boot from the CD.
|
||||
</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
UEFI systems
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
You should boot the live CD in UEFI mode (consult your specific
|
||||
hardware's documentation for instructions). You may find the
|
||||
<link xlink:href="http://www.rodsbooks.com/refind">rEFInd boot
|
||||
manager</link> useful.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The CD contains a basic NixOS installation. (It also contains Memtest86+,
|
||||
useful if you want to test new hardware). When it’s finished booting, it
|
||||
should have detected most of your hardware.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The NixOS manual is available on virtual console 8 (press Alt+F8 to access)
|
||||
or by running <command>nixos-help</command>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
You get logged in as <literal>root</literal> (with empty password).
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
If you downloaded the graphical ISO image, you can run <command>systemctl
|
||||
start display-manager</command> to start KDE. If you want to continue on
|
||||
the terminal, you can use <command>loadkeys</command> to switch to your
|
||||
preferred keyboard layout. (We even provide neo2 via <command>loadkeys de
|
||||
neo</command>!)
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<section xml:id="sec-installation-booting">
|
||||
<title>Booting the system</title>
|
||||
|
||||
<para>
|
||||
NixOS can be installed on BIOS or UEFI systems. The procedure for a UEFI
|
||||
installation is by and large the same as a BIOS installation. The
|
||||
differences are mentioned in the steps that follow.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The installation media can be burned to a CD, or now more commonly, "burned"
|
||||
to a USB drive (see <xref linkend="sec-booting-from-usb"/>).
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The installation media contains a basic NixOS installation. When it’s
|
||||
finished booting, it should have detected most of your hardware.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The NixOS manual is available on virtual console 8 (press Alt+F8 to access)
|
||||
or by running <command>nixos-help</command>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
You are logged-in automatically as <literal>root</literal>. (The
|
||||
<literal>root</literal> user account has an empty password.)
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If you downloaded the graphical ISO image, you can run <command>systemctl
|
||||
start display-manager</command> to start KDE. If you want to continue on the
|
||||
terminal, you can use <command>loadkeys</command> to switch to your
|
||||
preferred keyboard layout. (We even provide neo2 via <command>loadkeys de
|
||||
neo</command>!)
|
||||
</para>
|
||||
|
||||
<section xml:id="sec-installation-booting-networking">
|
||||
<title>Networking in the installer</title>
|
||||
|
||||
<para>
|
||||
The boot process should have brought up networking (check <command>ip
|
||||
a</command>). Networking is necessary for the installer, since it will
|
||||
@ -65,58 +51,165 @@
|
||||
binaries). It’s best if you have a DHCP server on your network. Otherwise
|
||||
configure networking manually using <command>ifconfig</command>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To manually configure the network on the graphical installer, first disable
|
||||
network-manager with <command>systemctl stop network-manager</command>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To manually configure the wifi on the minimal installer, run
|
||||
<command>wpa_supplicant -B -i interface -c <(wpa_passphrase 'SSID'
|
||||
'key')</command>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
|
||||
<para>
|
||||
If you would like to continue the installation from a different machine you
|
||||
need to activate the SSH daemon via <literal>systemctl start
|
||||
sshd</literal>. In order to be able to login you also need to set a
|
||||
password for <literal>root</literal> using <literal>passwd</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
</section>
|
||||
</section>
|
||||
<section xml:id="sec-installation-partitioning">
|
||||
<title>Partitioning and formatting</title>
|
||||
|
||||
<para>
|
||||
The NixOS installer doesn’t do any partitioning or formatting, so you need
|
||||
to do that yourself.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The NixOS installer ships with multiple partitioning tools. The examples
|
||||
below use <command>parted</command>, but also provides
|
||||
<command>fdisk</command>, <command>gdisk</command>,
|
||||
<command>cfdisk</command>, and <command>cgdisk</command>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The recommended partition scheme differs depending if the computer uses
|
||||
<emphasis>Legacy Boot</emphasis> or <emphasis>UEFI</emphasis>.
|
||||
</para>
|
||||
|
||||
<section xml:id="sec-installation-partitioning-UEFI">
|
||||
<title>UEFI (GPT)</title>
|
||||
|
||||
<para>
|
||||
The NixOS installer doesn’t do any partitioning or formatting yet, so you
|
||||
need to do that yourself. Use the following commands:
|
||||
<itemizedlist>
|
||||
Here's an example partition scheme for UEFI, using
|
||||
<filename>/dev/sda</filename> as the device.
|
||||
<note>
|
||||
<para>
|
||||
You can safely ignore <command>parted</command>'s informational message
|
||||
about needing to update /etc/fstab.
|
||||
</para>
|
||||
</note>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
For partitioning: <command>fdisk</command>.
|
||||
<screen>
|
||||
# fdisk /dev/sda # <lineannotation>(or whatever device you want to install on)</lineannotation>
|
||||
-- for UEFI systems only
|
||||
> n # <lineannotation>(create a new partition for /boot)</lineannotation>
|
||||
> 3 # <lineannotation>(make it a partition number 3)</lineannotation>
|
||||
> # <lineannotation>(press enter to accept the default)</lineannotation>
|
||||
> +512M # <lineannotation>(the size of the UEFI boot partition)</lineannotation>
|
||||
> t # <lineannotation>(change the partition type ...)</lineannotation>
|
||||
> 3 # <lineannotation>(... of the boot partition ...)</lineannotation>
|
||||
> 1 # <lineannotation>(... to 'UEFI System')</lineannotation>
|
||||
-- for BIOS or UEFI systems
|
||||
> n # <lineannotation>(create a new partition for /swap)</lineannotation>
|
||||
> 2 # <lineannotation>(make it a partition number 2)</lineannotation>
|
||||
> # <lineannotation>(press enter to accept the default)</lineannotation>
|
||||
> +8G # <lineannotation>(the size of the swap partition, set to whatever you like)</lineannotation>
|
||||
> n # <lineannotation>(create a new partition for /)</lineannotation>
|
||||
> 1 # <lineannotation>(make it a partition number 1)</lineannotation>
|
||||
> # <lineannotation>(press enter to accept the default)</lineannotation>
|
||||
> # <lineannotation>(press enter to accept the default and use the rest of the remaining space)</lineannotation>
|
||||
> a # <lineannotation>(make the partition bootable)</lineannotation>
|
||||
> x # <lineannotation>(enter expert mode)</lineannotation>
|
||||
> f # <lineannotation>(fix up the partition ordering)</lineannotation>
|
||||
> r # <lineannotation>(exit expert mode)</lineannotation>
|
||||
> w # <lineannotation>(write the partition table to disk and exit)</lineannotation></screen>
|
||||
Create a <emphasis>GPT</emphasis> partition table.
|
||||
<screen language="commands"># parted /dev/sda -- mklabel gpt</screen>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Add a <emphasis>swap</emphasis> partition. The size required will vary
|
||||
according to needs, here a 8GiB one is created. The space left in front
|
||||
(512MiB) will be used by the boot partition.
|
||||
<screen language="commands"># parted /dev/sda -- mkpart primary linux-swap 512MiB 8.5GiB</screen>
|
||||
<note>
|
||||
<para>
|
||||
The swap partition size rules are no different than for other Linux
|
||||
distributions.
|
||||
</para>
|
||||
</note>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Next, add the <emphasis>root</emphasis> partition. This will fill the
|
||||
remainder ending part of the disk.
|
||||
<screen language="commands"># parted /dev/sda -- mkpart primary 8.5GiB -1MiB</screen>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Finally, the <emphasis>boot</emphasis> partition. NixOS by default uses
|
||||
the ESP (EFI system partition) as its <emphasis>/boot</emphasis>
|
||||
partition. It uses the initially reserved 512MiB at the start of the
|
||||
disk.
|
||||
<screen language="commands"># parted /dev/sda -- mkpart ESP fat32 1M 512MiB
|
||||
# parted /dev/sda -- set 3 boot on</screen>
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Once complete, you can follow with
|
||||
<xref linkend="sec-installation-partitioning-formatting"/>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="sec-installation-partitioning-MBR">
|
||||
<title>Legacy Boot (MBR)</title>
|
||||
|
||||
<para>
|
||||
Here's an example partition scheme for Legacy Boot, using
|
||||
<filename>/dev/sda</filename> as the device.
|
||||
<note>
|
||||
<para>
|
||||
You can safely ignore <command>parted</command>'s informational message
|
||||
about needing to update /etc/fstab.
|
||||
</para>
|
||||
</note>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Create a <emphasis>MBR</emphasis> partition table.
|
||||
<screen language="commands"># parted /dev/sda -- mklabel msdos</screen>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Add a <emphasis>swap</emphasis> partition. The size required will vary
|
||||
according to needs, here a 8GiB one is created.
|
||||
<screen language="commands"># parted /dev/sda -- mkpart primary linux-swap 1M 8GiB</screen>
|
||||
<note>
|
||||
<para>
|
||||
The swap partition size rules are no different than for other Linux
|
||||
distributions.
|
||||
</para>
|
||||
</note>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Finally, add the <emphasis>root</emphasis> partition. This will fill the
|
||||
remainder of the disk.
|
||||
<screen language="commands"># parted /dev/sda -- mkpart primary 8GiB -1s</screen>
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Once complete, you can follow with
|
||||
<xref linkend="sec-installation-partitioning-formatting"/>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="sec-installation-partitioning-formatting">
|
||||
<title>Formatting</title>
|
||||
|
||||
<para>
|
||||
Use the following commands:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
For initialising Ext4 partitions: <command>mkfs.ext4</command>. It is
|
||||
@ -169,242 +262,249 @@
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Mount the target file system on which NixOS should be installed on
|
||||
<filename>/mnt</filename>, e.g.
|
||||
</section>
|
||||
</section>
|
||||
<section xml:id="sec-installation-installing">
|
||||
<title>Installing</title>
|
||||
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Mount the target file system on which NixOS should be installed on
|
||||
<filename>/mnt</filename>, e.g.
|
||||
<screen>
|
||||
# mount /dev/disk/by-label/nixos /mnt
|
||||
</screen>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
UEFI systems
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Mount the boot file system on <filename>/mnt/boot</filename>, e.g.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
UEFI systems
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Mount the boot file system on <filename>/mnt/boot</filename>, e.g.
|
||||
<screen>
|
||||
# mkdir -p /mnt/boot
|
||||
# mount /dev/disk/by-label/boot /mnt/boot
|
||||
</screen>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
If your machine has a limited amount of memory, you may want to activate
|
||||
swap devices now (<command>swapon
|
||||
<replaceable>device</replaceable></command>). The installer (or rather, the
|
||||
build actions that it may spawn) may need quite a bit of RAM, depending on
|
||||
your configuration.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
If your machine has a limited amount of memory, you may want to activate
|
||||
swap devices now (<command>swapon
|
||||
<replaceable>device</replaceable></command>). The installer (or rather,
|
||||
the build actions that it may spawn) may need quite a bit of RAM,
|
||||
depending on your configuration.
|
||||
<screen>
|
||||
# swapon /dev/sda2</screen>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
You now need to create a file
|
||||
<filename>/mnt/etc/nixos/configuration.nix</filename> that specifies the
|
||||
intended configuration of the system. This is because NixOS has a
|
||||
<emphasis>declarative</emphasis> configuration model: you create or edit a
|
||||
description of the desired configuration of your system, and then NixOS
|
||||
takes care of making it happen. The syntax of the NixOS configuration file
|
||||
is described in <xref linkend="sec-configuration-syntax"/>, while a list of
|
||||
available configuration options appears in
|
||||
<xref
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
You now need to create a file
|
||||
<filename>/mnt/etc/nixos/configuration.nix</filename> that specifies the
|
||||
intended configuration of the system. This is because NixOS has a
|
||||
<emphasis>declarative</emphasis> configuration model: you create or edit a
|
||||
description of the desired configuration of your system, and then NixOS
|
||||
takes care of making it happen. The syntax of the NixOS configuration file
|
||||
is described in <xref linkend="sec-configuration-syntax"/>, while a list
|
||||
of available configuration options appears in
|
||||
<xref
|
||||
linkend="ch-options"/>. A minimal example is shown in
|
||||
<xref
|
||||
<xref
|
||||
linkend="ex-config"/>.
|
||||
</para>
|
||||
<para>
|
||||
The command <command>nixos-generate-config</command> can generate an
|
||||
initial configuration file for you:
|
||||
</para>
|
||||
<para>
|
||||
The command <command>nixos-generate-config</command> can generate an
|
||||
initial configuration file for you:
|
||||
<screen>
|
||||
# nixos-generate-config --root /mnt</screen>
|
||||
You should then edit <filename>/mnt/etc/nixos/configuration.nix</filename>
|
||||
to suit your needs:
|
||||
You should then edit <filename>/mnt/etc/nixos/configuration.nix</filename>
|
||||
to suit your needs:
|
||||
<screen>
|
||||
# nano /mnt/etc/nixos/configuration.nix
|
||||
</screen>
|
||||
If you’re using the graphical ISO image, other editors may be available
|
||||
(such as <command>vim</command>). If you have network access, you can also
|
||||
install other editors — for instance, you can install Emacs by running
|
||||
<literal>nix-env -i emacs</literal>.
|
||||
</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
BIOS systems
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
You <emphasis>must</emphasis> set the option
|
||||
<xref linkend="opt-boot.loader.grub.device"/> to specify on which disk
|
||||
the GRUB boot loader is to be installed. Without it, NixOS cannot boot.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
UEFI systems
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
You <emphasis>must</emphasis> set the option
|
||||
<xref linkend="opt-boot.loader.systemd-boot.enable"/> to
|
||||
<literal>true</literal>. <command>nixos-generate-config</command> should
|
||||
do this automatically for new configurations when booted in UEFI mode.
|
||||
</para>
|
||||
<para>
|
||||
You may want to look at the options starting with
|
||||
<option><link linkend="opt-boot.loader.efi.canTouchEfiVariables">boot.loader.efi</link></option>
|
||||
and
|
||||
<option><link linkend="opt-boot.loader.systemd-boot.enable">boot.loader.systemd</link></option>
|
||||
as well.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<para>
|
||||
If there are other operating systems running on the machine before
|
||||
installing NixOS, the <xref linkend="opt-boot.loader.grub.useOSProber"/>
|
||||
option can be set to <literal>true</literal> to automatically add them to
|
||||
the grub menu.
|
||||
</para>
|
||||
<para>
|
||||
Another critical option is <option>fileSystems</option>, specifying the
|
||||
file systems that need to be mounted by NixOS. However, you typically
|
||||
don’t need to set it yourself, because
|
||||
<command>nixos-generate-config</command> sets it automatically in
|
||||
<filename>/mnt/etc/nixos/hardware-configuration.nix</filename> from your
|
||||
currently mounted file systems. (The configuration file
|
||||
<filename>hardware-configuration.nix</filename> is included from
|
||||
<filename>configuration.nix</filename> and will be overwritten by future
|
||||
invocations of <command>nixos-generate-config</command>; thus, you
|
||||
generally should not modify it.)
|
||||
</para>
|
||||
<note>
|
||||
<para>
|
||||
Depending on your hardware configuration or type of file system, you may
|
||||
need to set the option <option>boot.initrd.kernelModules</option> to
|
||||
include the kernel modules that are necessary for mounting the root file
|
||||
system, otherwise the installed system will not be able to boot. (If this
|
||||
happens, boot from the CD again, mount the target file system on
|
||||
<filename>/mnt</filename>, fix
|
||||
<filename>/mnt/etc/nixos/configuration.nix</filename> and rerun
|
||||
<filename>nixos-install</filename>.) In most cases,
|
||||
<command>nixos-generate-config</command> will figure out the required
|
||||
modules.
|
||||
If you’re using the graphical ISO image, other editors may be available
|
||||
(such as <command>vim</command>). If you have network access, you can also
|
||||
install other editors — for instance, you can install Emacs by running
|
||||
<literal>nix-env -i emacs</literal>.
|
||||
</para>
|
||||
</note>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Do the installation:
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
BIOS systems
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
You <emphasis>must</emphasis> set the option
|
||||
<xref linkend="opt-boot.loader.grub.device"/> to specify on which disk
|
||||
the GRUB boot loader is to be installed. Without it, NixOS cannot boot.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
UEFI systems
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
You <emphasis>must</emphasis> set the option
|
||||
<xref linkend="opt-boot.loader.systemd-boot.enable"/> to
|
||||
<literal>true</literal>. <command>nixos-generate-config</command>
|
||||
should do this automatically for new configurations when booted in UEFI
|
||||
mode.
|
||||
</para>
|
||||
<para>
|
||||
You may want to look at the options starting with
|
||||
<option><link linkend="opt-boot.loader.efi.canTouchEfiVariables">boot.loader.efi</link></option>
|
||||
and
|
||||
<option><link linkend="opt-boot.loader.systemd-boot.enable">boot.loader.systemd</link></option>
|
||||
as well.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<para>
|
||||
If there are other operating systems running on the machine before
|
||||
installing NixOS, the <xref linkend="opt-boot.loader.grub.useOSProber"/>
|
||||
option can be set to <literal>true</literal> to automatically add them to
|
||||
the grub menu.
|
||||
</para>
|
||||
<para>
|
||||
Another critical option is <option>fileSystems</option>, specifying the
|
||||
file systems that need to be mounted by NixOS. However, you typically
|
||||
don’t need to set it yourself, because
|
||||
<command>nixos-generate-config</command> sets it automatically in
|
||||
<filename>/mnt/etc/nixos/hardware-configuration.nix</filename> from your
|
||||
currently mounted file systems. (The configuration file
|
||||
<filename>hardware-configuration.nix</filename> is included from
|
||||
<filename>configuration.nix</filename> and will be overwritten by future
|
||||
invocations of <command>nixos-generate-config</command>; thus, you
|
||||
generally should not modify it.)
|
||||
</para>
|
||||
<note>
|
||||
<para>
|
||||
Depending on your hardware configuration or type of file system, you may
|
||||
need to set the option <option>boot.initrd.kernelModules</option> to
|
||||
include the kernel modules that are necessary for mounting the root file
|
||||
system, otherwise the installed system will not be able to boot. (If this
|
||||
happens, boot from the installation media again, mount the target file
|
||||
system on <filename>/mnt</filename>, fix
|
||||
<filename>/mnt/etc/nixos/configuration.nix</filename> and rerun
|
||||
<filename>nixos-install</filename>.) In most cases,
|
||||
<command>nixos-generate-config</command> will figure out the required
|
||||
modules.
|
||||
</para>
|
||||
</note>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Do the installation:
|
||||
<screen>
|
||||
# nixos-install</screen>
|
||||
Cross fingers. If this fails due to a temporary problem (such as a network
|
||||
issue while downloading binaries from the NixOS binary cache), you can just
|
||||
re-run <command>nixos-install</command>. Otherwise, fix your
|
||||
<filename>configuration.nix</filename> and then re-run
|
||||
<command>nixos-install</command>.
|
||||
</para>
|
||||
<para>
|
||||
As the last step, <command>nixos-install</command> will ask you to set the
|
||||
password for the <literal>root</literal> user, e.g.
|
||||
Cross fingers. If this fails due to a temporary problem (such as a network
|
||||
issue while downloading binaries from the NixOS binary cache), you can
|
||||
just re-run <command>nixos-install</command>. Otherwise, fix your
|
||||
<filename>configuration.nix</filename> and then re-run
|
||||
<command>nixos-install</command>.
|
||||
</para>
|
||||
<para>
|
||||
As the last step, <command>nixos-install</command> will ask you to set the
|
||||
password for the <literal>root</literal> user, e.g.
|
||||
<screen>
|
||||
setting root password...
|
||||
Enter new UNIX password: ***
|
||||
Retype new UNIX password: ***
|
||||
</screen>
|
||||
<note>
|
||||
<para>
|
||||
For unattended installations, it is possible to use
|
||||
<command>nixos-install --no-root-passwd</command> in order to disable the
|
||||
password prompt entirely.
|
||||
</para>
|
||||
</note>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
If everything went well:
|
||||
Retype new UNIX password: ***</screen>
|
||||
<note>
|
||||
<para>
|
||||
For unattended installations, it is possible to use
|
||||
<command>nixos-install --no-root-passwd</command> in order to disable
|
||||
the password prompt entirely.
|
||||
</para>
|
||||
</note>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
If everything went well:
|
||||
<screen>
|
||||
# reboot</screen>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
You should now be able to boot into the installed NixOS. The GRUB boot menu
|
||||
shows a list of <emphasis>available configurations</emphasis> (initially
|
||||
just one). Every time you change the NixOS configuration (see
|
||||
<link
|
||||
# reboot</screen>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
You should now be able to boot into the installed NixOS. The GRUB boot
|
||||
menu shows a list of <emphasis>available configurations</emphasis>
|
||||
(initially just one). Every time you change the NixOS configuration (see
|
||||
<link
|
||||
linkend="sec-changing-config">Changing Configuration</link>
|
||||
), a new item is added to the menu. This allows you to easily roll back to
|
||||
a previous configuration if something goes wrong.
|
||||
</para>
|
||||
<para>
|
||||
You should log in and change the <literal>root</literal> password with
|
||||
<command>passwd</command>.
|
||||
</para>
|
||||
<para>
|
||||
You’ll probably want to create some user accounts as well, which can be
|
||||
done with <command>useradd</command>:
|
||||
), a new item is added to the menu. This allows you to easily roll back to
|
||||
a previous configuration if something goes wrong.
|
||||
</para>
|
||||
<para>
|
||||
You should log in and change the <literal>root</literal> password with
|
||||
<command>passwd</command>.
|
||||
</para>
|
||||
<para>
|
||||
You’ll probably want to create some user accounts as well, which can be
|
||||
done with <command>useradd</command>:
|
||||
<screen>
|
||||
$ useradd -c 'Eelco Dolstra' -m eelco
|
||||
$ passwd eelco</screen>
|
||||
</para>
|
||||
<para>
|
||||
You may also want to install some software. For instance,
|
||||
</para>
|
||||
<para>
|
||||
You may also want to install some software. For instance,
|
||||
<screen>
|
||||
$ nix-env -qa \*</screen>
|
||||
shows what packages are available, and
|
||||
shows what packages are available, and
|
||||
<screen>
|
||||
$ nix-env -i w3m</screen>
|
||||
install the <literal>w3m</literal> browser.
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
<para>
|
||||
To summarise, <xref linkend="ex-install-sequence" /> shows a typical sequence
|
||||
of commands for installing NixOS on an empty hard drive (here
|
||||
<filename>/dev/sda</filename>). <xref linkend="ex-config"
|
||||
install the <literal>w3m</literal> browser.
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
</section>
|
||||
<section xml:id="sec-installation-summary">
|
||||
<title>Installation summary</title>
|
||||
|
||||
<para>
|
||||
To summarise, <xref linkend="ex-install-sequence" /> shows a typical
|
||||
sequence of commands for installing NixOS on an empty hard drive (here
|
||||
<filename>/dev/sda</filename>). <xref linkend="ex-config"
|
||||
/> shows a
|
||||
corresponding configuration Nix expression.
|
||||
</para>
|
||||
<example xml:id='ex-install-sequence'>
|
||||
<title>Commands for Installing NixOS on <filename>/dev/sda</filename></title>
|
||||
<screen>
|
||||
# fdisk /dev/sda # <lineannotation>(or whatever device you want to install on)</lineannotation>
|
||||
-- for UEFI systems only
|
||||
> n # <lineannotation>(create a new partition for /boot)</lineannotation>
|
||||
> 3 # <lineannotation>(make it a partition number 3)</lineannotation>
|
||||
> # <lineannotation>(press enter to accept the default)</lineannotation>
|
||||
> +512M # <lineannotation>(the size of the UEFI boot partition)</lineannotation>
|
||||
> t # <lineannotation>(change the partition type ...)</lineannotation>
|
||||
> 3 # <lineannotation>(... of the boot partition ...)</lineannotation>
|
||||
> 1 # <lineannotation>(... to 'UEFI System')</lineannotation>
|
||||
-- for BIOS or UEFI systems
|
||||
> n # <lineannotation>(create a new partition for /swap)</lineannotation>
|
||||
> 2 # <lineannotation>(make it a partition number 2)</lineannotation>
|
||||
> # <lineannotation>(press enter to accept the default)</lineannotation>
|
||||
> +8G # <lineannotation>(the size of the swap partition)</lineannotation>
|
||||
> n # <lineannotation>(create a new partition for /)</lineannotation>
|
||||
> 1 # <lineannotation>(make it a partition number 1)</lineannotation>
|
||||
> # <lineannotation>(press enter to accept the default)</lineannotation>
|
||||
> # <lineannotation>(press enter to accept the default and use the rest of the remaining space)</lineannotation>
|
||||
> a # <lineannotation>(make the partition bootable)</lineannotation>
|
||||
> x # <lineannotation>(enter expert mode)</lineannotation>
|
||||
> f # <lineannotation>(fix up the partition ordering)</lineannotation>
|
||||
> r # <lineannotation>(exit expert mode)</lineannotation>
|
||||
> w # <lineannotation>(write the partition table to disk and exit)</lineannotation>
|
||||
corresponding configuration Nix expression.
|
||||
</para>
|
||||
|
||||
<example xml:id="ex-partition-scheme-MBR">
|
||||
<title>Example partition schemes for NixOS on <filename>/dev/sda</filename> (MBR)</title>
|
||||
<screen language="commands">
|
||||
# parted /dev/sda -- mklabel msdos
|
||||
# parted /dev/sda -- mkpart primary linux-swap 1M 8GiB
|
||||
# parted /dev/sda -- mkpart primary 8GiB -1s</screen>
|
||||
</example>
|
||||
|
||||
<example xml:id="ex-partition-scheme-UEFI">
|
||||
<title>Example partition schemes for NixOS on <filename>/dev/sda</filename> (UEFI)</title>
|
||||
<screen language="commands">
|
||||
# parted /dev/sda -- mklabel gpt
|
||||
# parted /dev/sda -- mkpart primary linux-swap 512MiB 8.5GiB
|
||||
# parted /dev/sda -- mkpart primary 8.5GiB -1MiB
|
||||
# parted /dev/sda -- mkpart ESP fat32 1M 512MiB
|
||||
# parted /dev/sda -- set 3 boot on</screen>
|
||||
</example>
|
||||
|
||||
<example xml:id="ex-install-sequence">
|
||||
<title>Commands for Installing NixOS on <filename>/dev/sda</filename></title>
|
||||
<para>
|
||||
With a partitioned disk.
|
||||
<screen language="commands">
|
||||
# mkfs.ext4 -L nixos /dev/sda1
|
||||
# mkswap -L swap /dev/sda2
|
||||
# swapon /dev/sda2
|
||||
@ -416,9 +516,11 @@ $ nix-env -i w3m</screen>
|
||||
# nano /mnt/etc/nixos/configuration.nix
|
||||
# nixos-install
|
||||
# reboot</screen>
|
||||
</example>
|
||||
<example xml:id='ex-config'>
|
||||
<title>NixOS Configuration</title>
|
||||
</para>
|
||||
</example>
|
||||
|
||||
<example xml:id='ex-config'>
|
||||
<title>NixOS Configuration</title>
|
||||
<screen>
|
||||
{ config, pkgs, ... }: {
|
||||
imports = [
|
||||
@ -438,10 +540,19 @@ $ nix-env -i w3m</screen>
|
||||
services.sshd.enable = true;
|
||||
}
|
||||
</screen>
|
||||
</example>
|
||||
<xi:include href="installing-usb.xml" />
|
||||
<xi:include href="installing-pxe.xml" />
|
||||
<xi:include href="installing-virtualbox-guest.xml" />
|
||||
<xi:include href="installing-from-other-distro.xml" />
|
||||
<xi:include href="installing-behind-a-proxy.xml" />
|
||||
</example>
|
||||
</section>
|
||||
<section xml:id="sec-installation-additional-notes">
|
||||
<title>Additional installation notes</title>
|
||||
|
||||
<xi:include href="installing-usb.xml" />
|
||||
|
||||
<xi:include href="installing-pxe.xml" />
|
||||
|
||||
<xi:include href="installing-virtualbox-guest.xml" />
|
||||
|
||||
<xi:include href="installing-from-other-distro.xml" />
|
||||
|
||||
<xi:include href="installing-behind-a-proxy.xml" />
|
||||
</section>
|
||||
</chapter>
|
||||
|
@ -3,7 +3,7 @@
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
version="5.0"
|
||||
xml:id="sec-release-18.09">
|
||||
<title>Release 18.09 (“Jellyfish”, 2018/09/??)</title>
|
||||
<title>Release 18.09 (“Jellyfish”, 2018/10/05)</title>
|
||||
|
||||
<section xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
@ -14,7 +14,45 @@
|
||||
|
||||
<para>
|
||||
In addition to numerous new and upgraded packages, this release has the
|
||||
following highlights:
|
||||
following notable updates:
|
||||
</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
End of support is planned for end of April 2019, handing over to 19.03.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Platform support: x86_64-linux and x86_64-darwin as always. Support for
|
||||
aarch64-linux is as with the previous releases, not equivalent to the
|
||||
x86-64-linux release, but with efforts to reach parity.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Nix has been updated to 2.1; see its
|
||||
<link xlink:href="https://nixos.org/nix/manual/#ssec-relnotes-2.1">release
|
||||
notes</link>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Core versions: linux: 4.14 LTS (unchanged), glibc: 2.26 → 2.27, gcc: 7
|
||||
(unchanged), systemd: 237 → 239.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Desktop version changes: gnome: 3.26 → 3.28, (KDE) plasma-desktop: 5.12
|
||||
→ 5.13.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>
|
||||
Notable changes and additions for 18.09 include:
|
||||
</para>
|
||||
|
||||
<itemizedlist>
|
||||
@ -70,7 +108,7 @@ $ nix-instantiate -E '(import <nixpkgsunstable> {}).gitFull'
|
||||
<title>New Services</title>
|
||||
|
||||
<para>
|
||||
The following new services were added since the last release:
|
||||
A curated selection of new services that were added since the last release:
|
||||
</para>
|
||||
|
||||
<itemizedlist>
|
||||
@ -125,6 +163,303 @@ $ nix-instantiate -E '(import <nixpkgsunstable> {}).gitFull'
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>
|
||||
Every new services:
|
||||
</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./config/xdg/autostart.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./config/xdg/icons.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./config/xdg/menus.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./config/xdg/mime.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./hardware/brightnessctl.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./hardware/onlykey.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./hardware/video/uvcvideo/default.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./misc/documentation.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./programs/firejail.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./programs/iftop.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./programs/sedutil.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./programs/singularity.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./programs/xss-lock.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./programs/zsh/zsh-autosuggestions.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/admin/oxidized.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/backup/duplicati.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/backup/restic.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/backup/restic-rest-server.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/cluster/hadoop/default.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/databases/aerospike.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/databases/monetdb.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/desktops/bamf.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/desktops/flatpak.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/desktops/zeitgeist.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/development/bloop.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/development/jupyter/default.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/hardware/lcd.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/hardware/undervolt.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/misc/clipmenu.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/misc/gitweb.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/misc/serviio.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/misc/safeeyes.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/misc/sysprof.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/misc/weechat.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/monitoring/datadog-agent.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/monitoring/incron.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/networking/dnsdist.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/networking/freeradius.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/networking/hans.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/networking/morty.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/networking/ndppd.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/networking/ocserv.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/networking/owamp.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/networking/quagga.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/networking/shadowsocks.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/networking/stubby.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/networking/zeronet.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/security/certmgr.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/security/cfssl.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/security/oauth2_proxy_nginx.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/web-apps/virtlyst.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/web-apps/youtrack.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/web-servers/hitch/default.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/web-servers/hydron.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/web-servers/meguca.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./services/web-servers/nginx/gitweb.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./virtualisation/kvmgt.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>./virtualisation/qemu-guest-agent.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
|
||||
<section xmlns="http://docbook.org/ns/docbook"
|
||||
|
@ -105,6 +105,14 @@
|
||||
<varname>rabbitmq-server</varname>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The <literal>light</literal> module no longer uses setuid binaries, but
|
||||
udev rules. As a consequence users of that module have to belong to the
|
||||
<literal>video</literal> group in order to use the executable
|
||||
(i.e. <literal>users.users.yourusername.extraGroups = ["video"];</literal>).
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
|
||||
|
@ -129,17 +129,17 @@ in
|
||||
message = "Option driSupport32Bit only makes sense on a 64-bit system.";
|
||||
};
|
||||
|
||||
system.activationScripts.setup-opengl =
|
||||
''
|
||||
ln -sfn ${package} /run/opengl-driver
|
||||
${if pkgs.stdenv.isi686 then ''
|
||||
ln -sfn opengl-driver /run/opengl-driver-32
|
||||
'' else if cfg.driSupport32Bit then ''
|
||||
ln -sfn ${package32} /run/opengl-driver-32
|
||||
'' else ''
|
||||
rm -f /run/opengl-driver-32
|
||||
''}
|
||||
'';
|
||||
systemd.tmpfiles.rules = [
|
||||
"L+ /run/opengl-driver - - - - ${package}"
|
||||
(
|
||||
if pkgs.stdenv.isi686 then
|
||||
"L+ /run/opengl-driver-32 - - - - opengl-driver"
|
||||
else if cfg.driSupport32Bit then
|
||||
"L+ /run/opengl-driver-32 - - - - ${package32}"
|
||||
else
|
||||
"r /run/opengl-driver-32"
|
||||
)
|
||||
];
|
||||
|
||||
environment.sessionVariables.LD_LIBRARY_PATH =
|
||||
[ "/run/opengl-driver/lib" ] ++ optional cfg.driSupport32Bit "/run/opengl-driver-32/lib";
|
||||
|
@ -26,9 +26,73 @@ let
|
||||
nvidia_libs32 = (nvidiaForKernel pkgs_i686.linuxPackages).override { libsOnly = true; kernel = null; };
|
||||
|
||||
enabled = nvidia_x11 != null;
|
||||
|
||||
cfg = config.hardware.nvidia;
|
||||
optimusCfg = cfg.optimus_prime;
|
||||
in
|
||||
|
||||
{
|
||||
options = {
|
||||
hardware.nvidia.modesetting.enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Enable kernel modesetting when using the NVIDIA proprietary driver.
|
||||
|
||||
Enabling this fixes screen tearing when using Optimus via PRIME (see
|
||||
<option>hardware.nvidia.optimus_prime.enable</option>. This is not enabled
|
||||
by default because it is not officially supported by NVIDIA and would not
|
||||
work with SLI.
|
||||
'';
|
||||
};
|
||||
|
||||
hardware.nvidia.optimus_prime.enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Enable NVIDIA Optimus support using the NVIDIA proprietary driver via PRIME.
|
||||
If enabled, the NVIDIA GPU will be always on and used for all rendering,
|
||||
while enabling output to displays attached only to the integrated Intel GPU
|
||||
without a multiplexer.
|
||||
|
||||
Note that this option only has any effect if the "nvidia" driver is specified
|
||||
in <option>services.xserver.videoDrivers</option>, and it should preferably
|
||||
be the only driver there.
|
||||
|
||||
If this is enabled, then the bus IDs of the NVIDIA and Intel GPUs have to be
|
||||
specified (<option>hardware.nvidia.optimus_prime.nvidiaBusId</option> and
|
||||
<option>hardware.nvidia.optimus_prime.intelBusId</option>).
|
||||
|
||||
If you enable this, you may want to also enable kernel modesetting for the
|
||||
NVIDIA driver (<option>hardware.nvidia.modesetting.enable</option>) in order
|
||||
to prevent tearing.
|
||||
|
||||
Note that this configuration will only be successful when a display manager
|
||||
for which the <option>services.xserver.displayManager.setupCommands</option>
|
||||
option is supported is used; notably, SLiM is not supported.
|
||||
'';
|
||||
};
|
||||
|
||||
hardware.nvidia.optimus_prime.nvidiaBusId = lib.mkOption {
|
||||
type = lib.types.string;
|
||||
default = "";
|
||||
example = "PCI:1:0:0";
|
||||
description = ''
|
||||
Bus ID of the NVIDIA GPU. You can find it using lspci; for example if lspci
|
||||
shows the NVIDIA GPU at "01:00.0", set this option to "PCI:1:0:0".
|
||||
'';
|
||||
};
|
||||
|
||||
hardware.nvidia.optimus_prime.intelBusId = lib.mkOption {
|
||||
type = lib.types.string;
|
||||
default = "";
|
||||
example = "PCI:0:2:0";
|
||||
description = ''
|
||||
Bus ID of the Intel GPU. You can find it using lspci; for example if lspci
|
||||
shows the Intel GPU at "00:02.0", set this option to "PCI:0:2:0".
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf enabled {
|
||||
assertions = [
|
||||
@ -36,15 +100,61 @@ in
|
||||
assertion = config.services.xserver.displayManager.gdm.wayland;
|
||||
message = "NVidia drivers don't support wayland";
|
||||
}
|
||||
{
|
||||
assertion = !optimusCfg.enable ||
|
||||
(optimusCfg.nvidiaBusId != "" && optimusCfg.intelBusId != "");
|
||||
message = ''
|
||||
When NVIDIA Optimus via PRIME is enabled, the GPU bus IDs must configured.
|
||||
'';
|
||||
}
|
||||
];
|
||||
|
||||
services.xserver.drivers = singleton
|
||||
{ name = "nvidia"; modules = [ nvidia_x11.bin ]; libPath = [ nvidia_x11 ]; };
|
||||
# If Optimus/PRIME is enabled, we:
|
||||
# - Specify the configured NVIDIA GPU bus ID in the Device section for the
|
||||
# "nvidia" driver.
|
||||
# - Add the AllowEmptyInitialConfiguration option to the Screen section for the
|
||||
# "nvidia" driver, in order to allow the X server to start without any outputs.
|
||||
# - Add a separate Device section for the Intel GPU, using the "modesetting"
|
||||
# driver and with the configured BusID.
|
||||
# - Reference that Device section from the ServerLayout section as an inactive
|
||||
# device.
|
||||
# - Configure the display manager to run specific `xrandr` commands which will
|
||||
# configure/enable displays connected to the Intel GPU.
|
||||
|
||||
services.xserver.screenSection =
|
||||
services.xserver.drivers = singleton {
|
||||
name = "nvidia";
|
||||
modules = [ nvidia_x11.bin ];
|
||||
libPath = [ nvidia_x11 ];
|
||||
deviceSection = optionalString optimusCfg.enable
|
||||
''
|
||||
BusID "${optimusCfg.nvidiaBusId}"
|
||||
'';
|
||||
screenSection =
|
||||
''
|
||||
Option "RandRRotation" "on"
|
||||
${optionalString optimusCfg.enable "Option \"AllowEmptyInitialConfiguration\""}
|
||||
'';
|
||||
};
|
||||
|
||||
services.xserver.extraConfig = optionalString optimusCfg.enable
|
||||
''
|
||||
Option "RandRRotation" "on"
|
||||
Section "Device"
|
||||
Identifier "nvidia-optimus-intel"
|
||||
Driver "modesetting"
|
||||
BusID "${optimusCfg.intelBusId}"
|
||||
Option "AccelMethod" "none"
|
||||
EndSection
|
||||
'';
|
||||
services.xserver.serverLayoutSection = optionalString optimusCfg.enable
|
||||
''
|
||||
Inactive "nvidia-optimus-intel"
|
||||
'';
|
||||
|
||||
services.xserver.displayManager.setupCommands = optionalString optimusCfg.enable ''
|
||||
# Added by nvidia configuration module for Optimus/PRIME.
|
||||
${pkgs.xorg.xrandr}/bin/xrandr --setprovideroutputsource modesetting NVIDIA-0
|
||||
${pkgs.xorg.xrandr}/bin/xrandr --auto
|
||||
'';
|
||||
|
||||
environment.etc."nvidia/nvidia-application-profiles-rc" = mkIf nvidia_x11.useProfiles {
|
||||
source = "${nvidia_x11.bin}/share/nvidia/nvidia-application-profiles-rc";
|
||||
@ -62,6 +172,8 @@ in
|
||||
boot.kernelModules = [ "nvidia-uvm" ] ++
|
||||
lib.optionals config.services.xserver.enable [ "nvidia" "nvidia_modeset" "nvidia_drm" ];
|
||||
|
||||
# If requested enable modesetting via kernel parameter.
|
||||
boot.kernelParams = optional cfg.modesetting.enable "nvidia-drm.modeset=1";
|
||||
|
||||
# Create /dev/nvidia-uvm when the nvidia-uvm module is loaded.
|
||||
services.udev.extraRules =
|
||||
|
@ -277,8 +277,7 @@ if ($virt eq "qemu" || $virt eq "kvm" || $virt eq "bochs") {
|
||||
|
||||
# Also for Hyper-V.
|
||||
if ($virt eq "microsoft") {
|
||||
push @initrdAvailableKernelModules, "hv_storvsc";
|
||||
$videoDriver = "fbdev";
|
||||
push @attrs, "virtualisation.hypervGuest.enable = true;"
|
||||
}
|
||||
|
||||
|
||||
|
@ -82,7 +82,7 @@ evalNix(){
|
||||
set -e
|
||||
|
||||
if test $exit_code -eq 0; then
|
||||
cat <<EOF
|
||||
sed '/^warning: Nix search path/d' <<EOF
|
||||
$result
|
||||
EOF
|
||||
return 0;
|
||||
@ -90,7 +90,7 @@ EOF
|
||||
sed -n '
|
||||
/^error/ { s/, at (string):[0-9]*:[0-9]*//; p; };
|
||||
/^warning: Nix search path/ { p; };
|
||||
' <<EOF
|
||||
' >&2 <<EOF
|
||||
$result
|
||||
EOF
|
||||
exit_code=1
|
||||
|
@ -5,7 +5,6 @@ with lib;
|
||||
let
|
||||
cfg = config.system.nixos;
|
||||
|
||||
revisionFile = "${toString pkgs.path}/.git-revision";
|
||||
gitRepo = "${toString pkgs.path}/.git";
|
||||
gitCommitId = lib.substring 0 7 (commitIdFromGitRepo gitRepo);
|
||||
in
|
||||
@ -37,9 +36,7 @@ in
|
||||
nixos.revision = mkOption {
|
||||
internal = true;
|
||||
type = types.str;
|
||||
default = if pathIsDirectory gitRepo then commitIdFromGitRepo gitRepo
|
||||
else if pathExists revisionFile then fileContents revisionFile
|
||||
else "master";
|
||||
default = lib.trivial.revisionWithDefault "master";
|
||||
description = "The Git revision from which this NixOS configuration was built.";
|
||||
};
|
||||
|
||||
|
@ -284,6 +284,7 @@
|
||||
./services/hardware/tlp.nix
|
||||
./services/hardware/thinkfan.nix
|
||||
./services/hardware/trezord.nix
|
||||
./services/hardware/triggerhappy.nix
|
||||
./services/hardware/u2f.nix
|
||||
./services/hardware/udev.nix
|
||||
./services/hardware/udisks2.nix
|
||||
@ -690,6 +691,7 @@
|
||||
./services/web-apps/codimd.nix
|
||||
./services/web-apps/frab.nix
|
||||
./services/web-apps/mattermost.nix
|
||||
./services/web-apps/nextcloud.nix
|
||||
./services/web-apps/nexus.nix
|
||||
./services/web-apps/pgpkeyserver-lite.nix
|
||||
./services/web-apps/matomo.nix
|
||||
|
@ -33,7 +33,7 @@ let
|
||||
'';
|
||||
|
||||
bashAliases = concatStringsSep "\n" (
|
||||
mapAttrsFlatten (k: v: "alias ${k}='${v}'") cfg.shellAliases
|
||||
mapAttrsFlatten (k: v: "alias ${k}=${escapeShellArg v}") cfg.shellAliases
|
||||
);
|
||||
|
||||
in
|
||||
|
@ -13,7 +13,8 @@ in
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to install Light backlight control with setuid wrapper.
|
||||
Whether to install Light backlight control command
|
||||
and udev rules granting access to members of the "video" group.
|
||||
'';
|
||||
};
|
||||
};
|
||||
@ -21,6 +22,6 @@ in
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
environment.systemPackages = [ pkgs.light ];
|
||||
security.wrappers.light.source = "${pkgs.light.out}/bin/light";
|
||||
services.udev.packages = [ pkgs.light ];
|
||||
};
|
||||
}
|
||||
|
@ -548,6 +548,13 @@ in
|
||||
environment.etc =
|
||||
mapAttrsToList (n: v: makePAMService v) config.security.pam.services;
|
||||
|
||||
systemd.tmpfiles.rules = optionals
|
||||
(any (s: s.updateWtmp) (attrValues config.security.pam.services))
|
||||
[
|
||||
"f /var/log/wtmp"
|
||||
"f /var/log/lastlog"
|
||||
];
|
||||
|
||||
security.pam.services =
|
||||
{ other.text =
|
||||
''
|
||||
|
@ -88,11 +88,11 @@ in
|
||||
"polkit-agent-helper-1".source = "${pkgs.polkit.out}/lib/polkit-1/polkit-agent-helper-1";
|
||||
};
|
||||
|
||||
system.activationScripts.polkit =
|
||||
''
|
||||
# Probably no more needed, clean up
|
||||
rm -rf /var/lib/{polkit-1,PolicyKit}
|
||||
'';
|
||||
systemd.tmpfiles.rules = [
|
||||
# Probably no more needed, clean up
|
||||
"R /var/lib/polkit-1"
|
||||
"R /var/lib/PolicyKit"
|
||||
];
|
||||
|
||||
users.users.polkituser = {
|
||||
description = "PolKit daemon";
|
||||
|
@ -4,22 +4,7 @@ with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.psd;
|
||||
|
||||
configFile = ''
|
||||
${optionalString (cfg.users != [ ]) ''
|
||||
USERS="${concatStringsSep " " cfg.users}"
|
||||
''}
|
||||
|
||||
${optionalString (cfg.browsers != [ ]) ''
|
||||
BROWSERS="${concatStringsSep " " cfg.browsers}"
|
||||
''}
|
||||
|
||||
${optionalString (cfg.volatile != "") "VOLATILE=${cfg.volatile}"}
|
||||
${optionalString (cfg.daemonFile != "") "DAEMON_FILE=${cfg.daemonFile}"}
|
||||
'';
|
||||
|
||||
in {
|
||||
|
||||
options.services.psd = with types; {
|
||||
enable = mkOption {
|
||||
type = bool;
|
||||
@ -28,32 +13,6 @@ in {
|
||||
Whether to enable the Profile Sync daemon.
|
||||
'';
|
||||
};
|
||||
|
||||
users = mkOption {
|
||||
type = listOf str;
|
||||
default = [ ];
|
||||
example = [ "demo" ];
|
||||
description = ''
|
||||
A list of users whose browser profiles should be sync'd to tmpfs.
|
||||
'';
|
||||
};
|
||||
|
||||
browsers = mkOption {
|
||||
type = listOf str;
|
||||
default = [ ];
|
||||
example = [ "chromium" "firefox" ];
|
||||
description = ''
|
||||
A list of browsers to sync. Available choices are:
|
||||
|
||||
chromium chromium-dev conkeror.mozdev.org epiphany firefox
|
||||
firefox-trunk google-chrome google-chrome-beta google-chrome-unstable
|
||||
heftig-aurora icecat luakit midori opera opera-developer opera-beta
|
||||
qupzilla palemoon rekonq seamonkey
|
||||
|
||||
An empty list will enable all browsers.
|
||||
'';
|
||||
};
|
||||
|
||||
resyncTimer = mkOption {
|
||||
type = str;
|
||||
default = "1h";
|
||||
@ -66,80 +25,53 @@ in {
|
||||
omitted.
|
||||
'';
|
||||
};
|
||||
|
||||
volatile = mkOption {
|
||||
type = str;
|
||||
default = "/run/psd-profiles";
|
||||
description = ''
|
||||
The directory where browser profiles should reside(this should be
|
||||
mounted as a tmpfs). Do not include a trailing backslash.
|
||||
'';
|
||||
};
|
||||
|
||||
daemonFile = mkOption {
|
||||
type = str;
|
||||
default = "/run/psd";
|
||||
description = ''
|
||||
Where the pid and backup configuration files will be stored.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
assertions = [
|
||||
{ assertion = cfg.users != [];
|
||||
message = "services.psd.users must contain at least one user";
|
||||
}
|
||||
];
|
||||
|
||||
systemd = {
|
||||
services = {
|
||||
psd = {
|
||||
description = "Profile Sync daemon";
|
||||
wants = [ "psd-resync.service" "local-fs.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
preStart = "mkdir -p ${cfg.volatile}";
|
||||
|
||||
path = with pkgs; [ glibc rsync gawk ];
|
||||
|
||||
unitConfig = {
|
||||
RequiresMountsFor = [ "/home/" ];
|
||||
user = {
|
||||
services = {
|
||||
psd = {
|
||||
enable = true;
|
||||
description = "Profile Sync daemon";
|
||||
wants = [ "psd-resync.service" "local-fs.target" ];
|
||||
wantedBy = [ "default.target" ];
|
||||
path = with pkgs; [ rsync kmod gawk nettools profile-sync-daemon ];
|
||||
unitConfig = {
|
||||
RequiresMountsFor = [ "/home/" ];
|
||||
};
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = "yes";
|
||||
ExecStart = "${pkgs.profile-sync-daemon}/bin/profile-sync-daemon sync";
|
||||
ExecStop = "${pkgs.profile-sync-daemon}/bin/profile-sync-daemon unsync";
|
||||
};
|
||||
};
|
||||
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = "yes";
|
||||
ExecStart = "${pkgs.profile-sync-daemon}/bin/profile-sync-daemon sync";
|
||||
ExecStop = "${pkgs.profile-sync-daemon}/bin/profile-sync-daemon unsync";
|
||||
psd-resync = {
|
||||
enable = true;
|
||||
description = "Timed profile resync";
|
||||
after = [ "psd.service" ];
|
||||
wants = [ "psd-resync.timer" ];
|
||||
partOf = [ "psd.service" ];
|
||||
wantedBy = [ "default.target" ];
|
||||
path = with pkgs; [ rsync kmod gawk nettools profile-sync-daemon ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "${pkgs.profile-sync-daemon}/bin/profile-sync-daemon resync";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
psd-resync = {
|
||||
description = "Timed profile resync";
|
||||
after = [ "psd.service" ];
|
||||
wants = [ "psd-resync.timer" ];
|
||||
partOf = [ "psd.service" ];
|
||||
timers.psd-resync = {
|
||||
description = "Timer for profile sync daemon - ${cfg.resyncTimer}";
|
||||
partOf = [ "psd-resync.service" "psd.service" ];
|
||||
|
||||
path = with pkgs; [ glibc rsync gawk ];
|
||||
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "${pkgs.profile-sync-daemon}/bin/profile-sync-daemon resync";
|
||||
timerConfig = {
|
||||
OnUnitActiveSec = "${cfg.resyncTimer}";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
timers.psd-resync = {
|
||||
description = "Timer for profile sync daemon - ${cfg.resyncTimer}";
|
||||
partOf = [ "psd-resync.service" "psd.service" ];
|
||||
|
||||
timerConfig = {
|
||||
OnUnitActiveSec = "${cfg.resyncTimer}";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
environment.etc."psd.conf".text = configFile;
|
||||
|
||||
};
|
||||
}
|
||||
|
114
nixos/modules/services/hardware/triggerhappy.nix
Normal file
114
nixos/modules/services/hardware/triggerhappy.nix
Normal file
@ -0,0 +1,114 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.triggerhappy;
|
||||
|
||||
socket = "/run/thd.socket";
|
||||
|
||||
configFile = pkgs.writeText "triggerhappy.conf" ''
|
||||
${concatMapStringsSep "\n"
|
||||
({ keys, event, cmd, ... }:
|
||||
''${concatMapStringsSep "+" (x: "KEY_" + x) keys} ${toString { press = 1; hold = 2; release = 0; }.${event}} ${cmd}''
|
||||
)
|
||||
cfg.bindings}
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
|
||||
bindingCfg = { config, ... }: {
|
||||
options = {
|
||||
|
||||
keys = mkOption {
|
||||
type = types.listOf types.str;
|
||||
description = "List of keys to match. Key names as defined in linux/input-event-codes.h";
|
||||
};
|
||||
|
||||
event = mkOption {
|
||||
type = types.enum ["press" "hold" "release"];
|
||||
default = "press";
|
||||
description = "Event to match.";
|
||||
};
|
||||
|
||||
cmd = mkOption {
|
||||
type = types.str;
|
||||
description = "What to run.";
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
|
||||
###### interface
|
||||
|
||||
options = {
|
||||
|
||||
services.triggerhappy = {
|
||||
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to enable the <command>triggerhappy</command> hotkey daemon.
|
||||
'';
|
||||
};
|
||||
|
||||
bindings = mkOption {
|
||||
type = types.listOf (types.submodule bindingCfg);
|
||||
default = [];
|
||||
example = lib.literalExample ''
|
||||
[ { keys = ["PLAYPAUSE"]; cmd = "''${pkgs.mpc_cli}/bin/mpc -q toggle"; } ]
|
||||
'';
|
||||
description = ''
|
||||
Key bindings for <command>triggerhappy</command>.
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Literal contents to append to the end of <command>triggerhappy</command> configuration file.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
systemd.sockets.triggerhappy = {
|
||||
description = "Triggerhappy Socket";
|
||||
wantedBy = [ "sockets.target" ];
|
||||
socketConfig.ListenDatagram = socket;
|
||||
};
|
||||
|
||||
systemd.services.triggerhappy = {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "local-fs.target" ];
|
||||
description = "Global hotkey daemon";
|
||||
serviceConfig = {
|
||||
ExecStart = "${pkgs.triggerhappy}/bin/thd --user nobody --socket ${socket} --triggers ${configFile} --deviceglob /dev/input/event*";
|
||||
};
|
||||
};
|
||||
|
||||
services.udev.packages = lib.singleton (pkgs.writeTextFile {
|
||||
name = "triggerhappy-udev-rules";
|
||||
destination = "/etc/udev/rules.d/61-triggerhappy.rules";
|
||||
text = ''
|
||||
ACTION=="add", SUBSYSTEM=="input", KERNEL=="event[0-9]*", ATTRS{name}!="triggerhappy", \
|
||||
RUN+="${pkgs.triggerhappy}/bin/th-cmd --socket ${socket} --passfd --udev"
|
||||
'';
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -55,7 +55,7 @@ in
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
PermissionsStartOnly = "true";
|
||||
ExecStart = "${pkgs.emby}/bin/MediaBrowser.Server.Mono";
|
||||
ExecStart = "${pkgs.emby}/bin/emby -programdata ${cfg.dataDir}";
|
||||
Restart = "on-failure";
|
||||
};
|
||||
};
|
||||
|
@ -9,6 +9,15 @@ let
|
||||
if cfg.configText != null then
|
||||
pkgs.writeText "alertmanager.yml" cfg.configText
|
||||
else mkConfigFile;
|
||||
cmdlineArgs = cfg.extraFlags ++ [
|
||||
"--config.file ${alertmanagerYml}"
|
||||
"--web.listen-address ${cfg.listenAddress}:${toString cfg.port}"
|
||||
"--log.level ${cfg.logLevel}"
|
||||
] ++ (optional (cfg.webExternalUrl != null)
|
||||
"--web.external-url ${cfg.webExternalUrl}"
|
||||
) ++ (optional (cfg.logFormat != null)
|
||||
"--log.format ${cfg.logFormat}"
|
||||
);
|
||||
in {
|
||||
options = {
|
||||
services.prometheus.alertmanager = {
|
||||
@ -99,6 +108,14 @@ in {
|
||||
Open port in firewall for incoming connections.
|
||||
'';
|
||||
};
|
||||
|
||||
extraFlags = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
description = ''
|
||||
Extra commandline options when launching the Alertmanager.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@ -111,11 +128,7 @@ in {
|
||||
after = [ "network.target" ];
|
||||
script = ''
|
||||
${pkgs.prometheus-alertmanager.bin}/bin/alertmanager \
|
||||
--config.file ${alertmanagerYml} \
|
||||
--web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
|
||||
--log.level ${cfg.logLevel} \
|
||||
${optionalString (cfg.webExternalUrl != null) ''--web.external-url ${cfg.webExternalUrl} \''}
|
||||
${optionalString (cfg.logFormat != null) "--log.format ${cfg.logFormat}"}
|
||||
${concatStringsSep " \\\n " cmdlineArgs}
|
||||
'';
|
||||
|
||||
serviceConfig = {
|
||||
|
@ -60,10 +60,10 @@ in
|
||||
DynamicUser = true;
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-snmp-exporter.bin}/bin/snmp_exporter \
|
||||
-config.file ${configFile} \
|
||||
-log.format ${cfg.logFormat} \
|
||||
-log.level ${cfg.logLevel} \
|
||||
-web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
|
||||
--config.file=${configFile} \
|
||||
--log.format=${cfg.logFormat} \
|
||||
--log.level=${cfg.logLevel} \
|
||||
--web.listen-address=${cfg.listenAddress}:${toString cfg.port} \
|
||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||
'';
|
||||
};
|
||||
|
@ -7,9 +7,10 @@ let
|
||||
cfg = config.services.bitlbee;
|
||||
bitlbeeUid = config.ids.uids.bitlbee;
|
||||
|
||||
bitlbeePkg = if cfg.libpurple_plugins == []
|
||||
then pkgs.bitlbee
|
||||
else pkgs.bitlbee.override { enableLibPurple = true; };
|
||||
bitlbeePkg = pkgs.bitlbee.override {
|
||||
enableLibPurple = cfg.libpurple_plugins != [];
|
||||
enablePam = cfg.authBackend == "pam";
|
||||
};
|
||||
|
||||
bitlbeeConfig = pkgs.writeText "bitlbee.conf"
|
||||
''
|
||||
@ -20,6 +21,7 @@ let
|
||||
DaemonInterface = ${cfg.interface}
|
||||
DaemonPort = ${toString cfg.portNumber}
|
||||
AuthMode = ${cfg.authMode}
|
||||
AuthBackend = ${cfg.authBackend}
|
||||
Plugindir = ${pkgs.bitlbee-plugins cfg.plugins}/lib/bitlbee
|
||||
${lib.optionalString (cfg.hostName != "") "HostName = ${cfg.hostName}"}
|
||||
${lib.optionalString (cfg.protocols != "") "Protocols = ${cfg.protocols}"}
|
||||
@ -70,6 +72,16 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
authBackend = mkOption {
|
||||
default = "storage";
|
||||
type = types.enum [ "storage" "pam" ];
|
||||
description = ''
|
||||
How users are authenticated
|
||||
storage -- save passwords internally
|
||||
pam -- Linux PAM authentication
|
||||
'';
|
||||
};
|
||||
|
||||
authMode = mkOption {
|
||||
default = "Open";
|
||||
type = types.enum [ "Open" "Closed" "Registered" ];
|
||||
@ -147,23 +159,22 @@ in
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf config.services.bitlbee.enable {
|
||||
|
||||
users.users = singleton
|
||||
{ name = "bitlbee";
|
||||
config = mkMerge [
|
||||
(mkIf config.services.bitlbee.enable {
|
||||
users.users = singleton {
|
||||
name = "bitlbee";
|
||||
uid = bitlbeeUid;
|
||||
description = "BitlBee user";
|
||||
home = "/var/lib/bitlbee";
|
||||
createHome = true;
|
||||
};
|
||||
|
||||
users.groups = singleton
|
||||
{ name = "bitlbee";
|
||||
users.groups = singleton {
|
||||
name = "bitlbee";
|
||||
gid = config.ids.gids.bitlbee;
|
||||
};
|
||||
|
||||
systemd.services.bitlbee =
|
||||
{
|
||||
systemd.services.bitlbee = {
|
||||
environment.PURPLE_PLUGIN_PATH = purple_plugin_path;
|
||||
description = "BitlBee IRC to other chat networks gateway";
|
||||
after = [ "network.target" ];
|
||||
@ -172,8 +183,12 @@ in
|
||||
serviceConfig.ExecStart = "${bitlbeePkg}/sbin/bitlbee -F -n -c ${bitlbeeConfig}";
|
||||
};
|
||||
|
||||
environment.systemPackages = [ bitlbeePkg ];
|
||||
environment.systemPackages = [ bitlbeePkg ];
|
||||
|
||||
};
|
||||
})
|
||||
(mkIf (config.services.bitlbee.authBackend == "pam") {
|
||||
security.pam.services.bitlbee = {};
|
||||
})
|
||||
];
|
||||
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ in
|
||||
BANDB_DBPATH = "${cfg.statedir}/ban.db";
|
||||
};
|
||||
serviceConfig = {
|
||||
ExecStart = "${charybdis}/bin/charybdis-ircd -foreground -logfile /dev/stdout -configfile ${configFile}";
|
||||
ExecStart = "${charybdis}/bin/charybdis -foreground -logfile /dev/stdout -configfile ${configFile}";
|
||||
Group = cfg.group;
|
||||
User = cfg.user;
|
||||
PermissionsStartOnly = true; # preStart needs to run with root permissions
|
||||
|
@ -57,32 +57,12 @@ in
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
# from miniupnpd/netfilter/iptables_init.sh
|
||||
networking.firewall.extraCommands = ''
|
||||
iptables -t nat -N MINIUPNPD
|
||||
iptables -t nat -A PREROUTING -i ${cfg.externalInterface} -j MINIUPNPD
|
||||
iptables -t mangle -N MINIUPNPD
|
||||
iptables -t mangle -A PREROUTING -i ${cfg.externalInterface} -j MINIUPNPD
|
||||
iptables -t filter -N MINIUPNPD
|
||||
iptables -t filter -A FORWARD -i ${cfg.externalInterface} ! -o ${cfg.externalInterface} -j MINIUPNPD
|
||||
iptables -t nat -N MINIUPNPD-PCP-PEER
|
||||
iptables -t nat -A POSTROUTING -o ${cfg.externalInterface} -j MINIUPNPD-PCP-PEER
|
||||
${pkgs.bash}/bin/bash -x ${pkgs.miniupnpd}/etc/miniupnpd/iptables_init.sh -i ${cfg.externalInterface}
|
||||
'';
|
||||
|
||||
# from miniupnpd/netfilter/iptables_removeall.sh
|
||||
networking.firewall.extraStopCommands = ''
|
||||
iptables -t nat -F MINIUPNPD
|
||||
iptables -t nat -D PREROUTING -i ${cfg.externalInterface} -j MINIUPNPD
|
||||
iptables -t nat -X MINIUPNPD
|
||||
iptables -t mangle -F MINIUPNPD
|
||||
iptables -t mangle -D PREROUTING -i ${cfg.externalInterface} -j MINIUPNPD
|
||||
iptables -t mangle -X MINIUPNPD
|
||||
iptables -t filter -F MINIUPNPD
|
||||
iptables -t filter -D FORWARD -i ${cfg.externalInterface} ! -o ${cfg.externalInterface} -j MINIUPNPD
|
||||
iptables -t filter -X MINIUPNPD
|
||||
iptables -t nat -F MINIUPNPD-PCP-PEER
|
||||
iptables -t nat -D POSTROUTING -o ${cfg.externalInterface} -j MINIUPNPD-PCP-PEER
|
||||
iptables -t nat -X MINIUPNPD-PCP-PEER
|
||||
${pkgs.bash}/bin/bash -x ${pkgs.miniupnpd}/etc/miniupnpd/iptables_removeall.sh -i ${cfg.externalInterface}
|
||||
'';
|
||||
|
||||
systemd.services.miniupnpd = {
|
||||
|
@ -50,7 +50,7 @@ in
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "If enabled, start the Murmur Service.";
|
||||
description = "If enabled, start the Murmur Mumble server.";
|
||||
};
|
||||
|
||||
autobanAttempts = mkOption {
|
||||
|
463
nixos/modules/services/web-apps/nextcloud.nix
Normal file
463
nixos/modules/services/web-apps/nextcloud.nix
Normal file
@ -0,0 +1,463 @@
|
||||
{ config, lib, pkgs, ... }@args:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.nextcloud;
|
||||
|
||||
toKeyValue = generators.toKeyValue {
|
||||
mkKeyValue = generators.mkKeyValueDefault {} " = ";
|
||||
};
|
||||
|
||||
phpOptionsExtensions = ''
|
||||
${optionalString cfg.caching.apcu "extension=${cfg.phpPackages.apcu}/lib/php/extensions/apcu.so"}
|
||||
${optionalString cfg.caching.redis "extension=${cfg.phpPackages.redis}/lib/php/extensions/redis.so"}
|
||||
${optionalString cfg.caching.memcached "extension=${cfg.phpPackages.memcached}/lib/php/extensions/memcached.so"}
|
||||
zend_extension = opcache.so
|
||||
opcache.enable = 1
|
||||
'';
|
||||
phpOptions = {
|
||||
upload_max_filesize = cfg.maxUploadSize;
|
||||
post_max_size = cfg.maxUploadSize;
|
||||
memory_limit = cfg.maxUploadSize;
|
||||
} // cfg.phpOptions;
|
||||
phpOptionsStr = phpOptionsExtensions + (toKeyValue phpOptions);
|
||||
|
||||
occ = pkgs.writeScriptBin "nextcloud-occ" ''
|
||||
#! ${pkgs.stdenv.shell}
|
||||
cd ${pkgs.nextcloud}
|
||||
exec /run/wrappers/bin/sudo -u nextcloud \
|
||||
NEXTCLOUD_CONFIG_DIR="${cfg.home}/config" \
|
||||
${config.services.phpfpm.phpPackage}/bin/php \
|
||||
-c ${pkgs.writeText "php.ini" phpOptionsStr}\
|
||||
occ $*
|
||||
'';
|
||||
|
||||
in {
|
||||
options.services.nextcloud = {
|
||||
enable = mkEnableOption "nextcloud";
|
||||
hostName = mkOption {
|
||||
type = types.str;
|
||||
description = "FQDN for the nextcloud instance.";
|
||||
};
|
||||
home = mkOption {
|
||||
type = types.str;
|
||||
default = "/var/lib/nextcloud";
|
||||
description = "Storage path of nextcloud.";
|
||||
};
|
||||
https = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Enable if there is a TLS terminating proxy in front of nextcloud.";
|
||||
};
|
||||
|
||||
maxUploadSize = mkOption {
|
||||
default = "512M";
|
||||
type = types.str;
|
||||
description = ''
|
||||
Defines the upload limit for files. This changes the relevant options
|
||||
in php.ini and nginx if enabled.
|
||||
'';
|
||||
};
|
||||
|
||||
skeletonDirectory = mkOption {
|
||||
default = "";
|
||||
type = types.str;
|
||||
description = ''
|
||||
The directory where the skeleton files are located. These files will be
|
||||
copied to the data directory of new users. Leave empty to not copy any
|
||||
skeleton files.
|
||||
'';
|
||||
};
|
||||
|
||||
nginx.enable = mkEnableOption "nginx vhost management";
|
||||
|
||||
webfinger = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Enable this option if you plan on using the webfinger plugin.
|
||||
The appropriate nginx rewrite rules will be added to your configuration.
|
||||
'';
|
||||
};
|
||||
|
||||
phpPackages = mkOption {
|
||||
type = types.attrs;
|
||||
default = pkgs.php71Packages;
|
||||
defaultText = "pkgs.php71Packages";
|
||||
description = ''
|
||||
Overridable attribute of the PHP packages set to use. If any caching
|
||||
module is enabled, it will be taken from here. Therefore it should
|
||||
match the version of PHP given to
|
||||
<literal>services.phpfpm.phpPackage</literal>.
|
||||
'';
|
||||
};
|
||||
|
||||
phpOptions = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = {
|
||||
"short_open_tag" = "Off";
|
||||
"expose_php" = "Off";
|
||||
"error_reporting" = "E_ALL & ~E_DEPRECATED & ~E_STRICT";
|
||||
"display_errors" = "stderr";
|
||||
"opcache.enable_cli" = "1";
|
||||
"opcache.interned_strings_buffer" = "8";
|
||||
"opcache.max_accelerated_files" = "10000";
|
||||
"opcache.memory_consumption" = "128";
|
||||
"opcache.revalidate_freq" = "1";
|
||||
"opcache.fast_shutdown" = "1";
|
||||
"openssl.cafile" = "/etc/ssl/certs/ca-certificates.crt";
|
||||
"catch_workers_output" = "yes";
|
||||
};
|
||||
description = ''
|
||||
Options for PHP's php.ini file for nextcloud.
|
||||
'';
|
||||
};
|
||||
|
||||
config = {
|
||||
dbtype = mkOption {
|
||||
type = types.enum [ "sqlite" "pgsql" "mysql" ];
|
||||
default = "sqlite";
|
||||
description = "Database type.";
|
||||
};
|
||||
dbname = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = "nextcloud";
|
||||
description = "Database name.";
|
||||
};
|
||||
dbuser = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = "nextcloud";
|
||||
description = "Database user.";
|
||||
};
|
||||
dbpass = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Database password. Use <literal>dbpassFile</literal> to avoid this
|
||||
being world-readable in the <literal>/nix/store</literal>.
|
||||
'';
|
||||
};
|
||||
dbpassFile = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
The full path to a file that contains the database password.
|
||||
'';
|
||||
};
|
||||
dbhost = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = "localhost";
|
||||
description = "Database host.";
|
||||
};
|
||||
dbport = mkOption {
|
||||
type = with types; nullOr (either int str);
|
||||
default = null;
|
||||
description = "Database port.";
|
||||
};
|
||||
dbtableprefix = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Table prefix in Nextcloud database.";
|
||||
};
|
||||
adminuser = mkOption {
|
||||
type = types.str;
|
||||
default = "root";
|
||||
description = "Admin username.";
|
||||
};
|
||||
adminpass = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Database password. Use <literal>adminpassFile</literal> to avoid this
|
||||
being world-readable in the <literal>/nix/store</literal>.
|
||||
'';
|
||||
};
|
||||
adminpassFile = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
The full path to a file that contains the admin's password.
|
||||
'';
|
||||
};
|
||||
|
||||
extraTrustedDomains = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
description = ''
|
||||
Trusted domains, from which the nextcloud installation will be
|
||||
acessible. You don't need to add
|
||||
<literal>services.nextcloud.hostname</literal> here.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
caching = {
|
||||
apcu = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to load the APCu module into PHP.
|
||||
'';
|
||||
};
|
||||
redis = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to load the Redis module into PHP.
|
||||
You still need to enable Redis in your config.php.
|
||||
See https://docs.nextcloud.com/server/14/admin_manual/configuration_server/caching_configuration.html
|
||||
'';
|
||||
};
|
||||
memcached = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to load the Memcached module into PHP.
|
||||
You still need to enable Memcached in your config.php.
|
||||
See https://docs.nextcloud.com/server/14/admin_manual/configuration_server/caching_configuration.html
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable (mkMerge [
|
||||
{ assertions = let acfg = cfg.config; in [
|
||||
{ assertion = !(acfg.dbpass != null && acfg.dbpassFile != null);
|
||||
message = "Please specify no more than one of dbpass or dbpassFile";
|
||||
}
|
||||
{ assertion = ((acfg.adminpass != null || acfg.adminpassFile != null)
|
||||
&& !(acfg.adminpass != null && acfg.adminpassFile != null));
|
||||
message = "Please specify exactly one of adminpass or adminpassFile";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
{ systemd.timers."nextcloud-cron" = {
|
||||
wantedBy = [ "timers.target" ];
|
||||
timerConfig.OnBootSec = "5m";
|
||||
timerConfig.OnUnitActiveSec = "15m";
|
||||
timerConfig.Unit = "nextcloud-cron.service";
|
||||
};
|
||||
|
||||
systemd.services = {
|
||||
"nextcloud-setup" = let
|
||||
overrideConfig = pkgs.writeText "nextcloud-config.php" ''
|
||||
<?php
|
||||
$CONFIG = [
|
||||
'apps_paths' => [
|
||||
[ 'path' => '${cfg.home}/apps', 'url' => '/apps', 'writable' => false ],
|
||||
[ 'path' => '${cfg.home}/store-apps', 'url' => '/store-apps', 'writable' => true ],
|
||||
],
|
||||
'datadirectory' => '${cfg.home}/data',
|
||||
'skeletondirectory' => '${cfg.skeletonDirectory}',
|
||||
${optionalString cfg.caching.apcu "'memcache.local' => '\\OC\\Memcache\\APCu',"}
|
||||
'log_type' => 'syslog',
|
||||
];
|
||||
'';
|
||||
occInstallCmd = let
|
||||
c = cfg.config;
|
||||
adminpass = if c.adminpassFile != null
|
||||
then ''"$(<"${toString c.adminpassFile}")"''
|
||||
else ''"${toString c.adminpass}"'';
|
||||
dbpass = if c.dbpassFile != null
|
||||
then ''"$(<"${toString c.dbpassFile}")"''
|
||||
else if c.dbpass != null
|
||||
then ''"${toString c.dbpass}"''
|
||||
else null;
|
||||
installFlags = concatStringsSep " \\\n "
|
||||
(mapAttrsToList (k: v: "${k} ${toString v}") {
|
||||
"--database" = ''"${c.dbtype}"'';
|
||||
# The following attributes are optional depending on the type of
|
||||
# database. Those that evaluate to null on the left hand side
|
||||
# will be omitted.
|
||||
${if c.dbname != null then "--database-name" else null} = ''"${c.dbname}"'';
|
||||
${if c.dbhost != null then "--database-host" else null} = ''"${c.dbhost}"'';
|
||||
${if c.dbport != null then "--database-port" else null} = ''"${toString c.dbport}"'';
|
||||
${if c.dbuser != null then "--database-user" else null} = ''"${c.dbuser}"'';
|
||||
${if (any (x: x != null) [c.dbpass c.dbpassFile])
|
||||
then "--database-pass" else null} = dbpass;
|
||||
${if c.dbtableprefix != null
|
||||
then "--database-table-prefix" else null} = ''"${toString c.dbtableprefix}"'';
|
||||
"--admin-user" = ''"${c.adminuser}"'';
|
||||
"--admin-pass" = adminpass;
|
||||
"--data-dir" = ''"${cfg.home}/data"'';
|
||||
});
|
||||
in ''
|
||||
${occ}/bin/nextcloud-occ maintenance:install \
|
||||
${installFlags}
|
||||
'';
|
||||
occSetTrustedDomainsCmd = concatStringsSep "\n" (imap0
|
||||
(i: v: ''
|
||||
${occ}/bin/nextcloud-occ config:system:set trusted_domains \
|
||||
${toString i} --value="${toString v}"
|
||||
'') ([ cfg.hostName ] ++ cfg.config.extraTrustedDomains));
|
||||
|
||||
in {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
before = [ "phpfpm-nextcloud.service" ];
|
||||
script = ''
|
||||
chmod og+x ${cfg.home}
|
||||
ln -sf ${pkgs.nextcloud}/apps ${cfg.home}/
|
||||
mkdir -p ${cfg.home}/config ${cfg.home}/data ${cfg.home}/store-apps
|
||||
ln -sf ${overrideConfig} ${cfg.home}/config/override.config.php
|
||||
|
||||
chown -R nextcloud:nginx ${cfg.home}/config ${cfg.home}/data ${cfg.home}/store-apps
|
||||
|
||||
# Do not install if already installed
|
||||
if [[ ! -e ${cfg.home}/config/config.php ]]; then
|
||||
${occInstallCmd}
|
||||
fi
|
||||
|
||||
${occ}/bin/nextcloud-occ upgrade
|
||||
|
||||
${occ}/bin/nextcloud-occ config:system:delete trusted_domains
|
||||
${occSetTrustedDomainsCmd}
|
||||
'';
|
||||
serviceConfig.Type = "oneshot";
|
||||
};
|
||||
"nextcloud-cron" = {
|
||||
environment.NEXTCLOUD_CONFIG_DIR = "${cfg.home}/config";
|
||||
serviceConfig.Type = "oneshot";
|
||||
serviceConfig.User = "nextcloud";
|
||||
serviceConfig.ExecStart = "${pkgs.php}/bin/php -f ${pkgs.nextcloud}/cron.php";
|
||||
};
|
||||
};
|
||||
|
||||
services.phpfpm = {
|
||||
phpOptions = phpOptionsExtensions;
|
||||
phpPackage = pkgs.php71;
|
||||
pools.nextcloud = let
|
||||
phpAdminValues = (toKeyValue
|
||||
(foldr (a: b: a // b) {}
|
||||
(mapAttrsToList (k: v: { "php_admin_value[${k}]" = v; })
|
||||
phpOptions)));
|
||||
in {
|
||||
listen = "/run/phpfpm/nextcloud";
|
||||
extraConfig = ''
|
||||
listen.owner = nginx
|
||||
listen.group = nginx
|
||||
user = nextcloud
|
||||
group = nginx
|
||||
pm = dynamic
|
||||
pm.max_children = 32
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 2
|
||||
pm.max_spare_servers = 4
|
||||
env[NEXTCLOUD_CONFIG_DIR] = ${cfg.home}/config
|
||||
env[PATH] = /run/wrappers/bin:/nix/var/nix/profiles/default/bin:/run/current-system/sw/bin:/usr/bin:/bin
|
||||
${phpAdminValues}
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
users.extraUsers.nextcloud = {
|
||||
home = "${cfg.home}";
|
||||
group = "nginx";
|
||||
createHome = true;
|
||||
};
|
||||
|
||||
environment.systemPackages = [ occ ];
|
||||
}
|
||||
|
||||
(mkIf cfg.nginx.enable {
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
virtualHosts = {
|
||||
"${cfg.hostName}" = {
|
||||
root = pkgs.nextcloud;
|
||||
locations = {
|
||||
"= /robots.txt" = {
|
||||
priority = 100;
|
||||
extraConfig = ''
|
||||
allow all;
|
||||
log_not_found off;
|
||||
access_log off;
|
||||
'';
|
||||
};
|
||||
"/" = {
|
||||
priority = 200;
|
||||
extraConfig = "rewrite ^ /index.php$uri;";
|
||||
};
|
||||
"~ ^/store-apps" = {
|
||||
priority = 201;
|
||||
extraConfig = "root ${cfg.home};";
|
||||
};
|
||||
"= /.well-known/carddav" = {
|
||||
priority = 210;
|
||||
extraConfig = "return 301 $scheme://$host/remote.php/dav;";
|
||||
};
|
||||
"= /.well-known/caldav" = {
|
||||
priority = 210;
|
||||
extraConfig = "return 301 $scheme://$host/remote.php/dav;";
|
||||
};
|
||||
"~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/" = {
|
||||
priority = 300;
|
||||
extraConfig = "deny all;";
|
||||
};
|
||||
"~ ^/(?:\\.|autotest|occ|issue|indie|db_|console)" = {
|
||||
priority = 300;
|
||||
extraConfig = "deny all;";
|
||||
};
|
||||
"~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+)\\.php(?:$|/)" = {
|
||||
priority = 500;
|
||||
extraConfig = ''
|
||||
include ${pkgs.nginxMainline}/conf/fastcgi.conf;
|
||||
fastcgi_split_path_info ^(.+\.php)(/.*)$;
|
||||
fastcgi_param PATH_INFO $fastcgi_path_info;
|
||||
fastcgi_param HTTPS ${if cfg.https then "on" else "off"};
|
||||
fastcgi_param modHeadersAvailable true;
|
||||
fastcgi_param front_controller_active true;
|
||||
fastcgi_pass unix:/run/phpfpm/nextcloud;
|
||||
fastcgi_intercept_errors on;
|
||||
fastcgi_request_buffering off;
|
||||
fastcgi_read_timeout 120s;
|
||||
'';
|
||||
};
|
||||
"~ ^/(?:updater|ocs-provider)(?:$|/)".extraConfig = ''
|
||||
try_files $uri/ =404;
|
||||
index index.php;
|
||||
'';
|
||||
"~ \\.(?:css|js|woff|svg|gif)$".extraConfig = ''
|
||||
try_files $uri /index.php$uri$is_args$args;
|
||||
add_header Cache-Control "public, max-age=15778463";
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
add_header X-Robots-Tag none;
|
||||
add_header X-Download-Options noopen;
|
||||
add_header X-Permitted-Cross-Domain-Policies none;
|
||||
access_log off;
|
||||
'';
|
||||
"~ \\.(?:png|html|ttf|ico|jpg|jpeg)$".extraConfig = ''
|
||||
try_files $uri /index.php$uri$is_args$args;
|
||||
access_log off;
|
||||
'';
|
||||
};
|
||||
extraConfig = ''
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
add_header X-Robots-Tag none;
|
||||
add_header X-Download-Options noopen;
|
||||
add_header X-Permitted-Cross-Domain-Policies none;
|
||||
error_page 403 /core/templates/403.php;
|
||||
error_page 404 /core/templates/404.php;
|
||||
client_max_body_size ${cfg.maxUploadSize};
|
||||
fastcgi_buffers 64 4K;
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_comp_level 4;
|
||||
gzip_min_length 256;
|
||||
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
|
||||
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
|
||||
|
||||
${optionalString cfg.webfinger ''
|
||||
rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
|
||||
rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;
|
||||
''}
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
})
|
||||
]);
|
||||
}
|
@ -624,7 +624,11 @@ let
|
||||
};
|
||||
|
||||
users = optionalAttrs (cfg.user == "tt_rss") {
|
||||
users.tt_rss.group = "tt_rss";
|
||||
users.tt_rss = {
|
||||
description = "tt-rss service user";
|
||||
isSystemUser = true;
|
||||
group = "tt_rss";
|
||||
};
|
||||
groups.tt_rss = {};
|
||||
};
|
||||
};
|
||||
|
@ -245,8 +245,8 @@ let
|
||||
}
|
||||
''
|
||||
) virtualHosts);
|
||||
mkLocations = locations: concatStringsSep "\n" (mapAttrsToList (location: config: ''
|
||||
location ${location} {
|
||||
mkLocations = locations: concatStringsSep "\n" (map (config: ''
|
||||
location ${config.location} {
|
||||
${optionalString (config.proxyPass != null && !cfg.proxyResolveWhileRunning)
|
||||
"proxy_pass ${config.proxyPass};"
|
||||
}
|
||||
@ -266,7 +266,18 @@ let
|
||||
${config.extraConfig}
|
||||
${optionalString (config.proxyPass != null && cfg.recommendedProxySettings) "include ${recommendedProxyConfig};"}
|
||||
}
|
||||
'') locations);
|
||||
'') (sortProperties (mapAttrsToList (k: v: v // { location = k; }) locations)));
|
||||
mkBasicAuth = vhostName: authDef: let
|
||||
htpasswdFile = pkgs.writeText "${vhostName}.htpasswd" (
|
||||
concatStringsSep "\n" (mapAttrsToList (user: password: ''
|
||||
${user}:{PLAIN}${password}
|
||||
'') authDef)
|
||||
);
|
||||
in ''
|
||||
auth_basic secured;
|
||||
auth_basic_user_file ${htpasswdFile};
|
||||
'';
|
||||
|
||||
mkHtpasswd = vhostName: authDef: pkgs.writeText "${vhostName}.htpasswd" (
|
||||
concatStringsSep "\n" (mapAttrsToList (user: password: ''
|
||||
${user}:{PLAIN}${password}
|
||||
|
@ -71,6 +71,16 @@ with lib;
|
||||
These lines go to the end of the location verbatim.
|
||||
'';
|
||||
};
|
||||
|
||||
priority = mkOption {
|
||||
type = types.int;
|
||||
default = 1000;
|
||||
description = ''
|
||||
Order of this location block in relation to the others in the vhost.
|
||||
The semantics are the same as with `lib.mkOrder`. Smaller values have
|
||||
a greater priority.
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,7 @@ in
|
||||
};
|
||||
|
||||
security.wrappers = {
|
||||
kcheckpass.source = "${lib.getBin plasma5.plasma-workspace}/lib/libexec/kcheckpass";
|
||||
kcheckpass.source = "${lib.getBin plasma5.kscreenlocker}/lib/libexec/kcheckpass";
|
||||
"start_kdeinit".source = "${lib.getBin pkgs.kinit}/lib/libexec/kf5/start_kdeinit";
|
||||
kwin_wayland = {
|
||||
source = "${lib.getBin plasma5.kwin}/bin/kwin_wayland";
|
||||
@ -225,11 +225,8 @@ in
|
||||
security.pam.services.sddm.enableKwallet = true;
|
||||
security.pam.services.slim.enableKwallet = true;
|
||||
|
||||
# Update the start menu for each user that has `isNormalUser` set.
|
||||
system.activationScripts.plasmaSetup = stringAfter [ "users" "groups" ]
|
||||
(concatStringsSep "\n"
|
||||
(mapAttrsToList (name: value: "${pkgs.su}/bin/su ${name} -c ${pkgs.libsForQt5.kservice}/bin/kbuildsycoca5")
|
||||
(filterAttrs (n: v: v.isNormalUser) config.users.users)));
|
||||
# Update the start menu for each user that is currently logged in
|
||||
system.userActivationScripts.plasmaSetup = "${pkgs.libsForQt5.kservice}/bin/kbuildsycoca5";
|
||||
})
|
||||
];
|
||||
|
||||
|
@ -222,6 +222,17 @@ in
|
||||
description = "List of arguments for the X server.";
|
||||
};
|
||||
|
||||
setupCommands = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Shell commands executed just after the X server has started.
|
||||
|
||||
This option is only effective for display managers for which this feature
|
||||
is supported; currently these are LightDM, GDM and SDDM.
|
||||
'';
|
||||
};
|
||||
|
||||
sessionCommands = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
|
@ -7,6 +7,13 @@ let
|
||||
cfg = config.services.xserver.displayManager;
|
||||
gdm = pkgs.gnome3.gdm;
|
||||
|
||||
xSessionWrapper = if (cfg.setupCommands == "") then null else
|
||||
pkgs.writeScript "gdm-x-session-wrapper" ''
|
||||
#!${pkgs.bash}/bin/bash
|
||||
${cfg.setupCommands}
|
||||
exec "$@"
|
||||
'';
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
@ -112,6 +119,11 @@ in
|
||||
GDM_SESSIONS_DIR = "${cfg.session.desktops}/share/xsessions";
|
||||
# Find the mouse
|
||||
XCURSOR_PATH = "~/.icons:${pkgs.gnome3.adwaita-icon-theme}/share/icons";
|
||||
} // optionalAttrs (xSessionWrapper != null) {
|
||||
# Make GDM use this wrapper before running the session, which runs the
|
||||
# configured setupCommands. This relies on a patched GDM which supports
|
||||
# this environment variable.
|
||||
GDM_X_SESSION_WRAPPER = "${xSessionWrapper}";
|
||||
};
|
||||
execCmd = "exec ${gdm}/bin/gdm";
|
||||
};
|
||||
|
@ -0,0 +1,159 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
dmcfg = config.services.xserver.displayManager;
|
||||
ldmcfg = dmcfg.lightdm;
|
||||
cfg = ldmcfg.greeters.enso;
|
||||
|
||||
theme = cfg.theme.package;
|
||||
icons = cfg.iconTheme.package;
|
||||
cursors = cfg.cursorTheme.package;
|
||||
|
||||
# We need a few things in the environment for the greeter to run with
|
||||
# fonts/icons.
|
||||
wrappedEnsoGreeter = pkgs.runCommand "lightdm-enso-os-greeter"
|
||||
{ buildInputs = [ pkgs.makeWrapper ]; }
|
||||
''
|
||||
# This wrapper ensures that we actually get themes
|
||||
makeWrapper ${pkgs.lightdm-enso-os-greeter}/bin/pantheon-greeter \
|
||||
$out/greeter \
|
||||
--prefix PATH : "${pkgs.glibc.bin}/bin" \
|
||||
--set GDK_PIXBUF_MODULE_FILE "${pkgs.librsvg.out}/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache" \
|
||||
--set GTK_PATH "${theme}:${pkgs.gtk3.out}" \
|
||||
--set GTK_EXE_PREFIX "${theme}" \
|
||||
--set GTK_DATA_PREFIX "${theme}" \
|
||||
--set XDG_DATA_DIRS "${theme}/share:${icons}/share:${cursors}/share" \
|
||||
--set XDG_CONFIG_HOME "${theme}/share"
|
||||
|
||||
cat - > $out/lightdm-enso-os-greeter.desktop << EOF
|
||||
[Desktop Entry]
|
||||
Name=LightDM Greeter
|
||||
Comment=This runs the LightDM Greeter
|
||||
Exec=$out/greeter
|
||||
Type=Application
|
||||
EOF
|
||||
'';
|
||||
|
||||
ensoGreeterConf = pkgs.writeText "lightdm-enso-os-greeter.conf" ''
|
||||
[greeter]
|
||||
default-wallpaper=${ldmcfg.background}
|
||||
gtk-theme=${cfg.theme.name}
|
||||
icon-theme=${cfg.iconTheme.name}
|
||||
cursor-theme=${cfg.cursorTheme.name}
|
||||
blur=${toString cfg.blur}
|
||||
brightness=${toString cfg.brightness}
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
in {
|
||||
options = {
|
||||
services.xserver.displayManager.lightdm.greeters.enso = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to enable enso-os-greeter as the lightdm greeter
|
||||
'';
|
||||
};
|
||||
|
||||
theme = {
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.gnome3.gnome-themes-extra;
|
||||
defaultText = "pkgs.gnome3.gnome-themes-extra";
|
||||
description = ''
|
||||
The package path that contains the theme given in the name option.
|
||||
'';
|
||||
};
|
||||
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
default = "Adwaita";
|
||||
description = ''
|
||||
Name of the theme to use for the lightdm-enso-os-greeter
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
iconTheme = {
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.papirus-icon-theme;
|
||||
defaultText = "pkgs.papirus-icon-theme";
|
||||
description = ''
|
||||
The package path that contains the icon theme given in the name option.
|
||||
'';
|
||||
};
|
||||
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
default = "ePapirus";
|
||||
description = ''
|
||||
Name of the icon theme to use for the lightdm-enso-os-greeter
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
cursorTheme = {
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.capitaine-cursors;
|
||||
defaultText = "pkgs.capitaine-cursors";
|
||||
description = ''
|
||||
The package path that contains the cursor theme given in the name option.
|
||||
'';
|
||||
};
|
||||
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
default = "capitane-cursors";
|
||||
description = ''
|
||||
Name of the cursor theme to use for the lightdm-enso-os-greeter
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
blur = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether or not to enable blur
|
||||
'';
|
||||
};
|
||||
|
||||
brightness = mkOption {
|
||||
type = types.int;
|
||||
default = 7;
|
||||
description = ''
|
||||
Brightness
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Extra configuration that should be put in the greeter.conf
|
||||
configuration file
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf (ldmcfg.enable && cfg.enable) {
|
||||
environment.etc."lightdm/greeter.conf".source = ensoGreeterConf;
|
||||
|
||||
services.xserver.displayManager.lightdm = {
|
||||
greeter = mkDefault {
|
||||
package = wrappedEnsoGreeter;
|
||||
name = "lightdm-enso-os-greeter";
|
||||
};
|
||||
|
||||
greeters = {
|
||||
gtk = {
|
||||
enable = mkDefault false;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
@ -62,6 +62,12 @@ let
|
||||
${optionalString hasDefaultUserSession ''
|
||||
user-session=${defaultSessionName}
|
||||
''}
|
||||
${optionalString (dmcfg.setupCommands != "") ''
|
||||
display-setup-script=${pkgs.writeScript "lightdm-display-setup" ''
|
||||
#!${pkgs.bash}/bin/bash
|
||||
${dmcfg.setupCommands}
|
||||
''}
|
||||
''}
|
||||
${cfg.extraSeatDefaults}
|
||||
'';
|
||||
|
||||
@ -74,6 +80,7 @@ in
|
||||
imports = [
|
||||
./lightdm-greeters/gtk.nix
|
||||
./lightdm-greeters/mini.nix
|
||||
./lightdm-greeters/enso-os.nix
|
||||
];
|
||||
|
||||
options = {
|
||||
|
@ -20,6 +20,7 @@ let
|
||||
Xsetup = pkgs.writeScript "Xsetup" ''
|
||||
#!/bin/sh
|
||||
${cfg.setupScript}
|
||||
${dmcfg.setupCommands}
|
||||
'';
|
||||
|
||||
Xstop = pkgs.writeScript "Xstop" ''
|
||||
@ -137,7 +138,8 @@ in
|
||||
xrandr --auto
|
||||
'';
|
||||
description = ''
|
||||
A script to execute when starting the display server.
|
||||
A script to execute when starting the display server. DEPRECATED, please
|
||||
use <option>services.xserver.displayManager.setupCommands</option>.
|
||||
'';
|
||||
};
|
||||
|
||||
|
@ -374,6 +374,12 @@ in
|
||||
description = "Contents of the first Monitor section of the X server configuration file.";
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = "Additional contents (sections) included in the X server configuration file";
|
||||
};
|
||||
|
||||
xrandrHeads = mkOption {
|
||||
default = [];
|
||||
example = [
|
||||
@ -754,6 +760,7 @@ in
|
||||
Driver "${driver.driverName or driver.name}"
|
||||
${if cfg.useGlamor then ''Option "AccelMethod" "glamor"'' else ""}
|
||||
${cfg.deviceSection}
|
||||
${driver.deviceSection or ""}
|
||||
${xrandrDeviceSection}
|
||||
EndSection
|
||||
|
||||
@ -765,6 +772,7 @@ in
|
||||
''}
|
||||
|
||||
${cfg.screenSection}
|
||||
${driver.screenSection or ""}
|
||||
|
||||
${optionalString (cfg.defaultDepth != 0) ''
|
||||
DefaultDepth ${toString cfg.defaultDepth}
|
||||
@ -794,6 +802,8 @@ in
|
||||
'')}
|
||||
|
||||
${xrandrMonitorSections}
|
||||
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
|
||||
fonts.enableDefaultFonts = mkDefault true;
|
||||
|
@ -100,6 +100,52 @@ in
|
||||
exit $_status
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
system.userActivationScripts = mkOption {
|
||||
default = {};
|
||||
|
||||
example = literalExample ''
|
||||
{ plasmaSetup = {
|
||||
text = '''
|
||||
${pkgs.libsForQt5.kservice}/bin/kbuildsycoca5"
|
||||
''';
|
||||
deps = [];
|
||||
};
|
||||
}
|
||||
'';
|
||||
|
||||
description = ''
|
||||
A set of shell script fragments that are executed by a systemd user
|
||||
service when a NixOS system configuration is activated. Examples are
|
||||
rebuilding the .desktop file cache for showing applications in the menu.
|
||||
Since these are executed every time you run
|
||||
<command>nixos-rebuild</command>, it's important that they are
|
||||
idempotent and fast.
|
||||
'';
|
||||
|
||||
type = types.attrsOf types.unspecified;
|
||||
|
||||
apply = set: {
|
||||
script = ''
|
||||
unset PATH
|
||||
for i in ${toString path}; do
|
||||
PATH=$PATH:$i/bin:$i/sbin
|
||||
done
|
||||
|
||||
_status=0
|
||||
trap "_status=1 _localstatus=\$?" ERR
|
||||
|
||||
${
|
||||
let
|
||||
set' = mapAttrs (n: v: if isString v then noDepEntry v else v) set;
|
||||
withHeadlines = addAttributeName set';
|
||||
in textClosureMap id (withHeadlines) (attrNames withHeadlines)
|
||||
}
|
||||
|
||||
exit $_status
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
@ -128,14 +174,6 @@ in
|
||||
''
|
||||
# Various log/runtime directories.
|
||||
|
||||
mkdir -m 0755 -p /run/nix/current-load # for distributed builds
|
||||
mkdir -m 0700 -p /run/nix/remote-stores
|
||||
|
||||
mkdir -m 0755 -p /var/log
|
||||
|
||||
touch /var/log/wtmp /var/log/lastlog # must exist
|
||||
chmod 644 /var/log/wtmp /var/log/lastlog
|
||||
|
||||
mkdir -m 1777 -p /var/tmp
|
||||
|
||||
# Empty, immutable home directory of many system accounts.
|
||||
@ -177,6 +215,14 @@ in
|
||||
source ${config.system.build.earlyMountScript}
|
||||
'';
|
||||
|
||||
systemd.user = {
|
||||
services.nixos-activation = {
|
||||
description = "Run user specific NixOS activation";
|
||||
script = config.system.userActivationScripts.script;
|
||||
unitConfig.ConditionUser = "!@system";
|
||||
serviceConfig.Type = "oneshot";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -419,7 +419,8 @@ while (my $f = <$listActiveUsers>) {
|
||||
my ($uid, $name) = ($+{uid}, $+{user});
|
||||
print STDERR "reloading user units for $name...\n";
|
||||
|
||||
system("su", "-s", "@shell@", "-l", $name, "-c", "XDG_RUNTIME_DIR=/run/user/$uid @systemd@/bin/systemctl --user daemon-reload");
|
||||
system("@su@", "-s", "@shell@", "-l", $name, "-c", "XDG_RUNTIME_DIR=/run/user/$uid @systemd@/bin/systemctl --user daemon-reload");
|
||||
system("@su@", "-s", "@shell@", "-l", $name, "-c", "XDG_RUNTIME_DIR=/run/user/$uid @systemd@/bin/systemctl --user start nixos-activation.service");
|
||||
}
|
||||
|
||||
close $listActiveUsers;
|
||||
|
@ -109,6 +109,7 @@ let
|
||||
inherit (pkgs) utillinux coreutils;
|
||||
systemd = config.systemd.package;
|
||||
shell = "${pkgs.bash}/bin/sh";
|
||||
su = "${pkgs.shadow.su}/bin/su";
|
||||
|
||||
inherit children;
|
||||
kernelParams = config.boot.kernelParams;
|
||||
|
@ -6,11 +6,22 @@ let
|
||||
|
||||
cfg = config.boot.initrd.network;
|
||||
|
||||
dhcpinterfaces = lib.attrNames (lib.filterAttrs (iface: v: v.useDHCP == true) (config.networking.interfaces or {}));
|
||||
|
||||
udhcpcScript = pkgs.writeScript "udhcp-script"
|
||||
''
|
||||
#! /bin/sh
|
||||
if [ "$1" = bound ]; then
|
||||
ip address add "$ip/$mask" dev "$interface"
|
||||
if [ -n "$mtu" ]; then
|
||||
ip link set mtu "$mtu" dev "$interface"
|
||||
fi
|
||||
if [ -n "$staticroutes" ]; then
|
||||
echo "$staticroutes" \
|
||||
| sed -r "s@(\S+) (\S+)@ ip route add \"\1\" via \"\2\" dev \"$interface\" ; @g" \
|
||||
| sed -r "s@ via \"0\.0\.0\.0\"@@g" \
|
||||
| /bin/sh
|
||||
fi
|
||||
if [ -n "$router" ]; then
|
||||
ip route add "$router" dev "$interface" # just in case if "$router" is not within "$ip/$mask" (e.g. Hetzner Cloud)
|
||||
ip route add default via "$router" dev "$interface"
|
||||
@ -93,18 +104,24 @@ in
|
||||
''
|
||||
|
||||
# Otherwise, use DHCP.
|
||||
+ optionalString config.networking.useDHCP ''
|
||||
+ optionalString (config.networking.useDHCP || dhcpinterfaces != []) ''
|
||||
if [ -z "$hasNetwork" ]; then
|
||||
|
||||
# Bring up all interfaces.
|
||||
for iface in $(cd /sys/class/net && ls); do
|
||||
for iface in $(ls /sys/class/net/); do
|
||||
echo "bringing up network interface $iface..."
|
||||
ip link set "$iface" up
|
||||
done
|
||||
|
||||
# Acquire a DHCP lease.
|
||||
echo "acquiring IP address via DHCP..."
|
||||
udhcpc --quit --now --script ${udhcpcScript} ${udhcpcArgs} && hasNetwork=1
|
||||
# Acquire DHCP leases.
|
||||
for iface in ${ if config.networking.useDHCP then
|
||||
"$(ls /sys/class/net/ | grep -v ^lo$)"
|
||||
else
|
||||
lib.concatMapStringsSep " " lib.escapeShellArg dhcpinterfaces
|
||||
}; do
|
||||
echo "acquiring IP address via DHCP on $iface..."
|
||||
udhcpc --quit --now -i $iface -O staticroutes --script ${udhcpcScript} ${udhcpcArgs} && hasNetwork=1
|
||||
done
|
||||
fi
|
||||
''
|
||||
|
||||
|
@ -152,6 +152,14 @@ ln -sfn /run/booted-system /nix/var/nix/gcroots/booted-system
|
||||
@shell@ @postBootCommands@
|
||||
|
||||
|
||||
# Ensure systemd doesn't try to populate /etc, by forcing its first-boot
|
||||
# heuristic off. It doesn't matter what's in /etc/machine-id for this purpose,
|
||||
# and systemd will immediately fill in the file when it starts, so just
|
||||
# creating it is enough. This `: >>` pattern avoids forking and avoids changing
|
||||
# the mtime if the file already exists.
|
||||
: >> /etc/machine-id
|
||||
|
||||
|
||||
# Reset the logging file descriptors.
|
||||
exec 1>&$logOutFd 2>&$logErrFd
|
||||
exec {logOutFd}>&- {logErrFd}>&-
|
||||
|
@ -63,7 +63,7 @@ in rec {
|
||||
|
||||
assertValueOneOf = name: values: group: attr:
|
||||
optional (attr ? ${name} && !elem attr.${name} values)
|
||||
"Systemd ${group} field `${name}' cannot have value `${attr.${name}}'.";
|
||||
"Systemd ${group} field `${name}' cannot have value `${toString attr.${name}}'.";
|
||||
|
||||
assertHasField = name: group: attr:
|
||||
optional (!(attr ? ${name}))
|
||||
|
@ -394,7 +394,7 @@ in rec {
|
||||
Each attribute in this set specifies an option in the
|
||||
<literal>[Timer]</literal> section of the unit. See
|
||||
<citerefentry><refentrytitle>systemd.timer</refentrytitle>
|
||||
<manvolnum>7</manvolnum></citerefentry> and
|
||||
<manvolnum>5</manvolnum></citerefentry> and
|
||||
<citerefentry><refentrytitle>systemd.time</refentrytitle>
|
||||
<manvolnum>7</manvolnum></citerefentry> for details.
|
||||
'';
|
||||
|
@ -747,6 +747,7 @@ in
|
||||
|
||||
"systemd/journald.conf".text = ''
|
||||
[Journal]
|
||||
Storage=persistent
|
||||
RateLimitInterval=${config.services.journald.rateLimitInterval}
|
||||
RateLimitBurst=${toString config.services.journald.rateLimitBurst}
|
||||
${optionalString (config.services.journald.console != "") ''
|
||||
@ -783,19 +784,6 @@ in
|
||||
|
||||
services.dbus.enable = true;
|
||||
|
||||
system.activationScripts.systemd = stringAfter [ "groups" ]
|
||||
''
|
||||
mkdir -m 0755 -p /var/lib/udev
|
||||
|
||||
if ! [ -e /etc/machine-id ]; then
|
||||
${systemd}/bin/systemd-machine-id-setup
|
||||
fi
|
||||
|
||||
# Keep a persistent journal. Note that systemd-tmpfiles will
|
||||
# set proper ownership/permissions.
|
||||
mkdir -m 0700 -p /var/log/journal
|
||||
'';
|
||||
|
||||
users.users.systemd-network.uid = config.ids.uids.systemd-network;
|
||||
users.groups.systemd-network.gid = config.ids.gids.systemd-network;
|
||||
users.users.systemd-resolve.uid = config.ids.uids.systemd-resolve;
|
||||
|
@ -22,6 +22,13 @@ with lib;
|
||||
# Not supported in systemd-nspawn containers.
|
||||
security.audit.enable = false;
|
||||
|
||||
# Make sure that root user in container will talk to host nix-daemon
|
||||
environment.etc."profile".text = ''
|
||||
export NIX_REMOTE=daemon
|
||||
'';
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -9,20 +9,47 @@ in {
|
||||
options = {
|
||||
virtualisation.hypervGuest = {
|
||||
enable = mkEnableOption "Hyper-V Guest Support";
|
||||
|
||||
videoMode = mkOption {
|
||||
type = types.str;
|
||||
default = "1152x864";
|
||||
example = "1024x768";
|
||||
description = ''
|
||||
Resolution at which to initialize the video adapter.
|
||||
|
||||
Supports screen resolution up to Full HD 1920x1080 with 32 bit color
|
||||
on Windows Server 2012, and 1600x1200 with 16 bit color on Windows
|
||||
Server 2008 R2 or earlier.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
boot = {
|
||||
initrd.kernelModules = [
|
||||
"hv_balloon" "hv_netvsc" "hv_storvsc" "hv_utils" "hv_vmbus"
|
||||
];
|
||||
|
||||
kernelParams = [
|
||||
"video=hyperv_fb:${cfg.videoMode}"
|
||||
];
|
||||
};
|
||||
|
||||
environment.systemPackages = [ config.boot.kernelPackages.hyperv-daemons.bin ];
|
||||
|
||||
security.rngd.enable = false;
|
||||
|
||||
# enable hotadding memory
|
||||
# enable hotadding cpu/memory
|
||||
services.udev.packages = lib.singleton (pkgs.writeTextFile {
|
||||
name = "hyperv-memory-hotadd-udev-rules";
|
||||
destination = "/etc/udev/rules.d/99-hyperv-memory-hotadd.rules";
|
||||
name = "hyperv-cpu-and-memory-hotadd-udev-rules";
|
||||
destination = "/etc/udev/rules.d/99-hyperv-cpu-and-memory-hotadd.rules";
|
||||
text = ''
|
||||
ACTION="add", SUBSYSTEM=="memory", ATTR{state}="online"
|
||||
# Memory hotadd
|
||||
SUBSYSTEM=="memory", ACTION=="add", DEVPATH=="/devices/system/memory/memory[0-9]*", TEST=="state", ATTR{state}="online"
|
||||
|
||||
# CPU hotadd
|
||||
SUBSYSTEM=="cpu", ACTION=="add", DEVPATH=="/devices/system/cpu/cpu[0-9]*", TEST=="online", ATTR{online}="1"
|
||||
'';
|
||||
});
|
||||
|
||||
|
@ -12,7 +12,7 @@ in {
|
||||
virtualbox = {
|
||||
baseImageSize = mkOption {
|
||||
type = types.int;
|
||||
default = 10 * 1024;
|
||||
default = 100 * 1024;
|
||||
description = ''
|
||||
The size of the VirtualBox base image in MiB.
|
||||
'';
|
||||
|
@ -250,6 +250,7 @@ in rec {
|
||||
tests.acme = callTest tests/acme.nix {};
|
||||
tests.avahi = callTest tests/avahi.nix {};
|
||||
tests.beegfs = callTest tests/beegfs.nix {};
|
||||
tests.upnp = callTest tests/upnp.nix {};
|
||||
tests.bittorrent = callTest tests/bittorrent.nix {};
|
||||
tests.bind = callTest tests/bind.nix {};
|
||||
#tests.blivet = callTest tests/blivet.nix {}; # broken since 2017-07024
|
||||
@ -362,6 +363,7 @@ in rec {
|
||||
tests.netdata = callTest tests/netdata.nix { };
|
||||
tests.networking.networkd = callSubTests tests/networking.nix { networkd = true; };
|
||||
tests.networking.scripted = callSubTests tests/networking.nix { networkd = false; };
|
||||
tests.nextcloud = callSubTests tests/nextcloud { };
|
||||
# TODO: put in networking.nix after the test becomes more complete
|
||||
tests.networkingProxy = callTest tests/networking-proxy.nix {};
|
||||
tests.nexus = callTest tests/nexus.nix { };
|
||||
|
@ -13,57 +13,95 @@ let
|
||||
# Some random file to serve.
|
||||
file = pkgs.hello.src;
|
||||
|
||||
miniupnpdConf = nodes: pkgs.writeText "miniupnpd.conf"
|
||||
''
|
||||
ext_ifname=eth1
|
||||
listening_ip=${(pkgs.lib.head nodes.router.config.networking.interfaces.eth2.ipv4.addresses).address}/24
|
||||
allow 1024-65535 192.168.2.0/24 1024-65535
|
||||
'';
|
||||
|
||||
internalRouterAddress = "192.168.3.1";
|
||||
internalClient1Address = "192.168.3.2";
|
||||
externalRouterAddress = "80.100.100.1";
|
||||
externalClient2Address = "80.100.100.2";
|
||||
externalTrackerAddress = "80.100.100.3";
|
||||
in
|
||||
|
||||
{
|
||||
name = "bittorrent";
|
||||
meta = with pkgs.stdenv.lib.maintainers; {
|
||||
maintainers = [ domenkozar eelco chaoflow rob wkennington ];
|
||||
maintainers = [ domenkozar eelco chaoflow rob wkennington bobvanderlinden ];
|
||||
};
|
||||
|
||||
nodes =
|
||||
{ tracker =
|
||||
{ pkgs, ... }:
|
||||
{ environment.systemPackages = [ pkgs.transmission pkgs.opentracker ];
|
||||
{ environment.systemPackages = [ pkgs.transmission ];
|
||||
|
||||
virtualisation.vlans = [ 1 ];
|
||||
networking.interfaces.eth1.ipv4.addresses = [
|
||||
{ address = externalTrackerAddress; prefixLength = 24; }
|
||||
];
|
||||
|
||||
# We need Apache on the tracker to serve the torrents.
|
||||
services.httpd.enable = true;
|
||||
services.httpd.adminAddr = "foo@example.org";
|
||||
services.httpd.documentRoot = "/tmp";
|
||||
|
||||
networking.firewall.enable = false; # FIXME: figure out what ports we actually need
|
||||
networking.firewall.enable = false;
|
||||
|
||||
services.opentracker.enable = true;
|
||||
|
||||
services.transmission.enable = true;
|
||||
services.transmission.settings.dht-enabled = false;
|
||||
services.transmission.settings.port-forwaring-enabled = false;
|
||||
};
|
||||
|
||||
router =
|
||||
{ pkgs, ... }:
|
||||
{ environment.systemPackages = [ pkgs.miniupnpd ];
|
||||
virtualisation.vlans = [ 1 2 ];
|
||||
{ pkgs, nodes, ... }:
|
||||
{ virtualisation.vlans = [ 1 2 ];
|
||||
networking.nat.enable = true;
|
||||
networking.nat.internalInterfaces = [ "eth2" ];
|
||||
networking.nat.externalInterface = "eth1";
|
||||
networking.firewall.enable = false;
|
||||
networking.firewall.enable = true;
|
||||
networking.firewall.trustedInterfaces = [ "eth2" ];
|
||||
networking.interfaces.eth0.ipv4.addresses = [];
|
||||
networking.interfaces.eth1.ipv4.addresses = [
|
||||
{ address = externalRouterAddress; prefixLength = 24; }
|
||||
];
|
||||
networking.interfaces.eth2.ipv4.addresses = [
|
||||
{ address = internalRouterAddress; prefixLength = 24; }
|
||||
];
|
||||
services.miniupnpd = {
|
||||
enable = true;
|
||||
externalInterface = "eth1";
|
||||
internalIPs = [ "eth2" ];
|
||||
appendConfig = ''
|
||||
ext_ip=${externalRouterAddress}
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
client1 =
|
||||
{ pkgs, nodes, ... }:
|
||||
{ environment.systemPackages = [ pkgs.transmission ];
|
||||
{ environment.systemPackages = [ pkgs.transmission pkgs.miniupnpc ];
|
||||
virtualisation.vlans = [ 2 ];
|
||||
networking.defaultGateway =
|
||||
(pkgs.lib.head nodes.router.config.networking.interfaces.eth2.ipv4.addresses).address;
|
||||
networking.interfaces.eth0.ipv4.addresses = [];
|
||||
networking.interfaces.eth1.ipv4.addresses = [
|
||||
{ address = internalClient1Address; prefixLength = 24; }
|
||||
];
|
||||
networking.defaultGateway = internalRouterAddress;
|
||||
networking.firewall.enable = false;
|
||||
services.transmission.enable = true;
|
||||
services.transmission.settings.dht-enabled = false;
|
||||
services.transmission.settings.message-level = 3;
|
||||
};
|
||||
|
||||
client2 =
|
||||
{ pkgs, ... }:
|
||||
{ environment.systemPackages = [ pkgs.transmission ];
|
||||
virtualisation.vlans = [ 1 ];
|
||||
networking.interfaces.eth0.ipv4.addresses = [];
|
||||
networking.interfaces.eth1.ipv4.addresses = [
|
||||
{ address = externalClient2Address; prefixLength = 24; }
|
||||
];
|
||||
networking.firewall.enable = false;
|
||||
services.transmission.enable = true;
|
||||
services.transmission.settings.dht-enabled = false;
|
||||
services.transmission.settings.port-forwaring-enabled = false;
|
||||
};
|
||||
};
|
||||
|
||||
@ -72,43 +110,38 @@ in
|
||||
''
|
||||
startAll;
|
||||
|
||||
# Enable NAT on the router and start miniupnpd.
|
||||
$router->waitForUnit("nat");
|
||||
$router->succeed(
|
||||
"iptables -w -t nat -N MINIUPNPD",
|
||||
"iptables -w -t nat -A PREROUTING -i eth1 -j MINIUPNPD",
|
||||
"echo 1 > /proc/sys/net/ipv4/ip_forward",
|
||||
"miniupnpd -f ${miniupnpdConf nodes}"
|
||||
);
|
||||
# Wait for network and miniupnpd.
|
||||
$router->waitForUnit("network-online.target");
|
||||
$router->waitForUnit("miniupnpd");
|
||||
|
||||
# Create the torrent.
|
||||
$tracker->succeed("mkdir /tmp/data");
|
||||
$tracker->succeed("cp ${file} /tmp/data/test.tar.bz2");
|
||||
$tracker->succeed("transmission-create /tmp/data/test.tar.bz2 -p -t http://${(pkgs.lib.head nodes.tracker.config.networking.interfaces.eth1.ipv4.addresses).address}:6969/announce -o /tmp/test.torrent");
|
||||
$tracker->succeed("transmission-create /tmp/data/test.tar.bz2 --private --tracker http://${externalTrackerAddress}:6969/announce --outfile /tmp/test.torrent");
|
||||
$tracker->succeed("chmod 644 /tmp/test.torrent");
|
||||
|
||||
# Start the tracker. !!! use a less crappy tracker
|
||||
$tracker->waitForUnit("network.target");
|
||||
$tracker->succeed("opentracker -p 6969 >&2 &");
|
||||
$tracker->waitForUnit("network-online.target");
|
||||
$tracker->waitForUnit("opentracker.service");
|
||||
$tracker->waitForOpenPort(6969);
|
||||
|
||||
# Start the initial seeder.
|
||||
my $pid = $tracker->succeed("transmission-cli /tmp/test.torrent -M -w /tmp/data >&2 & echo \$!");
|
||||
$tracker->succeed("transmission-remote --add /tmp/test.torrent --no-portmap --no-dht --download-dir /tmp/data");
|
||||
|
||||
# Now we should be able to download from the client behind the NAT.
|
||||
$tracker->waitForUnit("httpd");
|
||||
$client1->waitForUnit("network.target");
|
||||
$client1->succeed("transmission-cli http://tracker/test.torrent -w /tmp >&2 &");
|
||||
$client1->waitForUnit("network-online.target");
|
||||
$client1->succeed("transmission-remote --add http://${externalTrackerAddress}/test.torrent --download-dir /tmp >&2 &");
|
||||
$client1->waitForFile("/tmp/test.tar.bz2");
|
||||
$client1->succeed("cmp /tmp/test.tar.bz2 ${file}");
|
||||
|
||||
# Bring down the initial seeder.
|
||||
$tracker->succeed("kill -9 $pid");
|
||||
# $tracker->stopJob("transmission");
|
||||
|
||||
# Now download from the second client. This can only succeed if
|
||||
# the first client created a NAT hole in the router.
|
||||
$client2->waitForUnit("network.target");
|
||||
$client2->succeed("transmission-cli http://tracker/test.torrent -M -w /tmp >&2 &");
|
||||
$client2->waitForUnit("network-online.target");
|
||||
$client2->succeed("transmission-remote --add http://${externalTrackerAddress}/test.torrent --no-portmap --no-dht --download-dir /tmp >&2 &");
|
||||
$client2->waitForFile("/tmp/test.tar.bz2");
|
||||
$client2->succeed("cmp /tmp/test.tar.bz2 ${file}");
|
||||
'';
|
||||
|
@ -86,6 +86,9 @@ import ./make-test.nix ({ pkgs, ...} : {
|
||||
# Execute commands via the root shell.
|
||||
$machine->succeed("nixos-container run $id1 -- uname") =~ /Linux/ or die;
|
||||
|
||||
# Execute a nix command via the root shell. (regression test for #40355)
|
||||
$machine->succeed("nixos-container run $id1 -- nix-instantiate -E 'derivation { name = \"empty\"; builder = \"false\"; system = \"false\"; }'");
|
||||
|
||||
# Stop and start (regression test for #4989)
|
||||
$machine->succeed("nixos-container stop $id1");
|
||||
$machine->succeed("nixos-container start $id1");
|
||||
|
@ -78,6 +78,8 @@ import ./make-test.nix ({ pkgs, ...} : rec {
|
||||
|
||||
# Test whether we have a reboot record in wtmp.
|
||||
subtest "reboot-wtmp", sub {
|
||||
$machine->shutdown;
|
||||
$machine->waitForUnit('multi-user.target');
|
||||
$machine->succeed("last | grep reboot >&2");
|
||||
};
|
||||
|
||||
|
56
nixos/tests/nextcloud/basic.nix
Normal file
56
nixos/tests/nextcloud/basic.nix
Normal file
@ -0,0 +1,56 @@
|
||||
import ../make-test.nix ({ pkgs, ...}: let
|
||||
adminpass = "notproduction";
|
||||
adminuser = "root";
|
||||
in {
|
||||
name = "nextcloud-basic";
|
||||
meta = with pkgs.stdenv.lib.maintainers; {
|
||||
maintainers = [ globin eqyiel ];
|
||||
};
|
||||
|
||||
nodes = {
|
||||
# The only thing the client needs to do is download a file.
|
||||
client = { ... }: {};
|
||||
|
||||
nextcloud = { config, pkgs, ... }: {
|
||||
networking.firewall.allowedTCPPorts = [ 80 ];
|
||||
|
||||
services.nextcloud = {
|
||||
enable = true;
|
||||
nginx.enable = true;
|
||||
hostName = "nextcloud";
|
||||
config = {
|
||||
# Don't inherit adminuser since "root" is supposed to be the default
|
||||
inherit adminpass;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
testScript = let
|
||||
withRcloneEnv = pkgs.writeScript "with-rclone-env" ''
|
||||
#!${pkgs.stdenv.shell}
|
||||
export RCLONE_CONFIG_NEXTCLOUD_TYPE=webdav
|
||||
export RCLONE_CONFIG_NEXTCLOUD_URL="http://nextcloud/remote.php/webdav/"
|
||||
export RCLONE_CONFIG_NEXTCLOUD_VENDOR="nextcloud"
|
||||
export RCLONE_CONFIG_NEXTCLOUD_USER="${adminuser}"
|
||||
export RCLONE_CONFIG_NEXTCLOUD_PASS="$(${pkgs.rclone}/bin/rclone obscure ${adminpass})"
|
||||
"''${@}"
|
||||
'';
|
||||
copySharedFile = pkgs.writeScript "copy-shared-file" ''
|
||||
#!${pkgs.stdenv.shell}
|
||||
echo 'hi' | ${withRcloneEnv} ${pkgs.rclone}/bin/rclone rcat nextcloud:test-shared-file
|
||||
'';
|
||||
|
||||
diffSharedFile = pkgs.writeScript "diff-shared-file" ''
|
||||
#!${pkgs.stdenv.shell}
|
||||
diff <(echo 'hi') <(${pkgs.rclone}/bin/rclone cat nextcloud:test-shared-file)
|
||||
'';
|
||||
in ''
|
||||
startAll();
|
||||
$nextcloud->waitForUnit("multi-user.target");
|
||||
$nextcloud->succeed("curl -sSf http://nextcloud/login");
|
||||
$nextcloud->succeed("${withRcloneEnv} ${copySharedFile}");
|
||||
$client->waitForUnit("multi-user.target");
|
||||
$client->succeed("${withRcloneEnv} ${diffSharedFile}");
|
||||
'';
|
||||
})
|
6
nixos/tests/nextcloud/default.nix
Normal file
6
nixos/tests/nextcloud/default.nix
Normal file
@ -0,0 +1,6 @@
|
||||
{ system ? builtins.currentSystem }:
|
||||
{
|
||||
basic = import ./basic.nix { inherit system; };
|
||||
with-postgresql-and-redis = import ./with-postgresql-and-redis.nix { inherit system; };
|
||||
with-mysql-and-memcached = import ./with-mysql-and-memcached.nix { inherit system; };
|
||||
}
|
97
nixos/tests/nextcloud/with-mysql-and-memcached.nix
Normal file
97
nixos/tests/nextcloud/with-mysql-and-memcached.nix
Normal file
@ -0,0 +1,97 @@
|
||||
import ../make-test.nix ({ pkgs, ...}: let
|
||||
adminpass = "hunter2";
|
||||
adminuser = "root";
|
||||
in {
|
||||
name = "nextcloud-with-mysql-and-memcached";
|
||||
meta = with pkgs.stdenv.lib.maintainers; {
|
||||
maintainers = [ eqyiel ];
|
||||
};
|
||||
|
||||
nodes = {
|
||||
# The only thing the client needs to do is download a file.
|
||||
client = { ... }: {};
|
||||
|
||||
nextcloud = { config, pkgs, ... }: {
|
||||
networking.firewall.allowedTCPPorts = [ 80 ];
|
||||
|
||||
services.nextcloud = {
|
||||
enable = true;
|
||||
hostName = "nextcloud";
|
||||
nginx.enable = true;
|
||||
https = true;
|
||||
caching = {
|
||||
apcu = true;
|
||||
redis = false;
|
||||
memcached = true;
|
||||
};
|
||||
config = {
|
||||
dbtype = "mysql";
|
||||
dbname = "nextcloud";
|
||||
dbuser = "nextcloud";
|
||||
dbhost = "127.0.0.1";
|
||||
dbport = 3306;
|
||||
dbpass = "hunter2";
|
||||
# Don't inherit adminuser since "root" is supposed to be the default
|
||||
inherit adminpass;
|
||||
};
|
||||
};
|
||||
|
||||
services.mysql = {
|
||||
enable = true;
|
||||
bind = "127.0.0.1";
|
||||
package = pkgs.mariadb;
|
||||
initialScript = pkgs.writeText "mysql-init" ''
|
||||
CREATE USER 'nextcloud'@'localhost' IDENTIFIED BY 'hunter2';
|
||||
CREATE DATABASE IF NOT EXISTS nextcloud;
|
||||
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER,
|
||||
CREATE TEMPORARY TABLES ON nextcloud.* TO 'nextcloud'@'localhost'
|
||||
IDENTIFIED BY 'hunter2';
|
||||
FLUSH privileges;
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.services."nextcloud-setup"= {
|
||||
requires = ["mysql.service"];
|
||||
after = ["mysql.service"];
|
||||
};
|
||||
|
||||
services.memcached.enable = true;
|
||||
};
|
||||
};
|
||||
|
||||
testScript = let
|
||||
configureMemcached = pkgs.writeScript "configure-memcached" ''
|
||||
#!${pkgs.stdenv.shell}
|
||||
nextcloud-occ config:system:set memcached_servers 0 0 --value 127.0.0.1 --type string
|
||||
nextcloud-occ config:system:set memcached_servers 0 1 --value 11211 --type integer
|
||||
nextcloud-occ config:system:set memcache.local --value '\OC\Memcache\APCu' --type string
|
||||
nextcloud-occ config:system:set memcache.distributed --value '\OC\Memcache\Memcached' --type string
|
||||
'';
|
||||
withRcloneEnv = pkgs.writeScript "with-rclone-env" ''
|
||||
#!${pkgs.stdenv.shell}
|
||||
export RCLONE_CONFIG_NEXTCLOUD_TYPE=webdav
|
||||
export RCLONE_CONFIG_NEXTCLOUD_URL="http://nextcloud/remote.php/webdav/"
|
||||
export RCLONE_CONFIG_NEXTCLOUD_VENDOR="nextcloud"
|
||||
export RCLONE_CONFIG_NEXTCLOUD_USER="${adminuser}"
|
||||
export RCLONE_CONFIG_NEXTCLOUD_PASS="$(${pkgs.rclone}/bin/rclone obscure ${adminpass})"
|
||||
'';
|
||||
copySharedFile = pkgs.writeScript "copy-shared-file" ''
|
||||
#!${pkgs.stdenv.shell}
|
||||
echo 'hi' | ${pkgs.rclone}/bin/rclone rcat nextcloud:test-shared-file
|
||||
'';
|
||||
|
||||
diffSharedFile = pkgs.writeScript "diff-shared-file" ''
|
||||
#!${pkgs.stdenv.shell}
|
||||
diff <(echo 'hi') <(${pkgs.rclone}/bin/rclone cat nextcloud:test-shared-file)
|
||||
'';
|
||||
in ''
|
||||
startAll();
|
||||
$nextcloud->waitForUnit("multi-user.target");
|
||||
$nextcloud->succeed("${configureMemcached}");
|
||||
$nextcloud->succeed("curl -sSf http://nextcloud/login");
|
||||
$nextcloud->succeed("${withRcloneEnv} ${copySharedFile}");
|
||||
$client->waitForUnit("multi-user.target");
|
||||
$client->succeed("${withRcloneEnv} ${diffSharedFile}");
|
||||
|
||||
'';
|
||||
})
|
130
nixos/tests/nextcloud/with-postgresql-and-redis.nix
Normal file
130
nixos/tests/nextcloud/with-postgresql-and-redis.nix
Normal file
@ -0,0 +1,130 @@
|
||||
import ../make-test.nix ({ pkgs, ...}: let
|
||||
adminpass = "hunter2";
|
||||
adminuser = "custom-admin-username";
|
||||
in {
|
||||
name = "nextcloud-with-postgresql-and-redis";
|
||||
meta = with pkgs.stdenv.lib.maintainers; {
|
||||
maintainers = [ eqyiel ];
|
||||
};
|
||||
|
||||
nodes = {
|
||||
# The only thing the client needs to do is download a file.
|
||||
client = { ... }: {};
|
||||
|
||||
nextcloud = { config, pkgs, ... }: {
|
||||
networking.firewall.allowedTCPPorts = [ 80 ];
|
||||
|
||||
services.nextcloud = {
|
||||
enable = true;
|
||||
hostName = "nextcloud";
|
||||
nginx.enable = true;
|
||||
caching = {
|
||||
apcu = false;
|
||||
redis = true;
|
||||
memcached = false;
|
||||
};
|
||||
config = {
|
||||
dbtype = "pgsql";
|
||||
dbname = "nextcloud";
|
||||
dbuser = "nextcloud";
|
||||
dbhost = "localhost";
|
||||
dbpassFile = toString (pkgs.writeText "db-pass-file" ''
|
||||
hunter2
|
||||
'');
|
||||
inherit adminuser;
|
||||
adminpassFile = toString (pkgs.writeText "admin-pass-file" ''
|
||||
${adminpass}
|
||||
'');
|
||||
};
|
||||
};
|
||||
|
||||
services.redis = {
|
||||
unixSocket = "/var/run/redis/redis.sock";
|
||||
enable = true;
|
||||
extraConfig = ''
|
||||
unixsocketperm 770
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.services.redis = {
|
||||
preStart = ''
|
||||
mkdir -p /var/run/redis
|
||||
chown ${config.services.redis.user}:${config.services.nginx.group} /var/run/redis
|
||||
'';
|
||||
serviceConfig.PermissionsStartOnly = true;
|
||||
};
|
||||
|
||||
systemd.services."nextcloud-setup"= {
|
||||
requires = ["postgresql.service"];
|
||||
after = [
|
||||
"postgresql.service"
|
||||
"chown-redis-socket.service"
|
||||
];
|
||||
};
|
||||
|
||||
# At the time of writing, redis creates its socket with the "nobody"
|
||||
# group. I figure this is slightly less bad than making the socket world
|
||||
# readable.
|
||||
systemd.services."chown-redis-socket" = {
|
||||
enable = true;
|
||||
script = ''
|
||||
until ${pkgs.redis}/bin/redis-cli ping; do
|
||||
echo "waiting for redis..."
|
||||
sleep 1
|
||||
done
|
||||
chown ${config.services.redis.user}:${config.services.nginx.group} /var/run/redis/redis.sock
|
||||
'';
|
||||
after = [ "redis.service" ];
|
||||
requires = [ "redis.service" ];
|
||||
wantedBy = [ "redis.service" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
};
|
||||
};
|
||||
|
||||
services.postgresql = {
|
||||
enable = true;
|
||||
initialScript = pkgs.writeText "psql-init" ''
|
||||
create role nextcloud with login password 'hunter2';
|
||||
create database nextcloud with owner nextcloud;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
testScript = let
|
||||
configureRedis = pkgs.writeScript "configure-redis" ''
|
||||
#!${pkgs.stdenv.shell}
|
||||
nextcloud-occ config:system:set redis 'host' --value '/var/run/redis/redis.sock' --type string
|
||||
nextcloud-occ config:system:set redis 'port' --value 0 --type integer
|
||||
nextcloud-occ config:system:set memcache.local --value '\OC\Memcache\Redis' --type string
|
||||
nextcloud-occ config:system:set memcache.locking --value '\OC\Memcache\Redis' --type string
|
||||
'';
|
||||
withRcloneEnv = pkgs.writeScript "with-rclone-env" ''
|
||||
#!${pkgs.stdenv.shell}
|
||||
export RCLONE_CONFIG_NEXTCLOUD_TYPE=webdav
|
||||
export RCLONE_CONFIG_NEXTCLOUD_URL="http://nextcloud/remote.php/webdav/"
|
||||
export RCLONE_CONFIG_NEXTCLOUD_VENDOR="nextcloud"
|
||||
export RCLONE_CONFIG_NEXTCLOUD_USER="${adminuser}"
|
||||
export RCLONE_CONFIG_NEXTCLOUD_PASS="$(${pkgs.rclone}/bin/rclone obscure ${adminpass})"
|
||||
"''${@}"
|
||||
'';
|
||||
copySharedFile = pkgs.writeScript "copy-shared-file" ''
|
||||
#!${pkgs.stdenv.shell}
|
||||
echo 'hi' | ${pkgs.rclone}/bin/rclone rcat nextcloud:test-shared-file
|
||||
'';
|
||||
|
||||
diffSharedFile = pkgs.writeScript "diff-shared-file" ''
|
||||
#!${pkgs.stdenv.shell}
|
||||
diff <(echo 'hi') <(${pkgs.rclone}/bin/rclone cat nextcloud:test-shared-file)
|
||||
'';
|
||||
in ''
|
||||
startAll();
|
||||
$nextcloud->waitForUnit("multi-user.target");
|
||||
$nextcloud->succeed("${configureRedis}");
|
||||
$nextcloud->succeed("curl -sSf http://nextcloud/login");
|
||||
$nextcloud->succeed("${withRcloneEnv} ${copySharedFile}");
|
||||
$client->waitForUnit("multi-user.target");
|
||||
$client->succeed("${withRcloneEnv} ${diffSharedFile}");
|
||||
'';
|
||||
})
|
94
nixos/tests/upnp.nix
Normal file
94
nixos/tests/upnp.nix
Normal file
@ -0,0 +1,94 @@
|
||||
# This tests whether UPnP port mappings can be created using Miniupnpd
|
||||
# and Miniupnpc.
|
||||
# It runs a Miniupnpd service on one machine, and verifies
|
||||
# a client can indeed create a port mapping using Miniupnpc. If
|
||||
# this succeeds an external client will try to connect to the port
|
||||
# mapping.
|
||||
|
||||
import ./make-test.nix ({ pkgs, ... }:
|
||||
|
||||
let
|
||||
internalRouterAddress = "192.168.3.1";
|
||||
internalClient1Address = "192.168.3.2";
|
||||
externalRouterAddress = "80.100.100.1";
|
||||
externalClient2Address = "80.100.100.2";
|
||||
in
|
||||
{
|
||||
name = "upnp";
|
||||
meta = with pkgs.stdenv.lib.maintainers; {
|
||||
maintainers = [ bobvanderlinden ];
|
||||
};
|
||||
|
||||
nodes =
|
||||
{
|
||||
router =
|
||||
{ pkgs, nodes, ... }:
|
||||
{ virtualisation.vlans = [ 1 2 ];
|
||||
networking.nat.enable = true;
|
||||
networking.nat.internalInterfaces = [ "eth2" ];
|
||||
networking.nat.externalInterface = "eth1";
|
||||
networking.firewall.enable = true;
|
||||
networking.firewall.trustedInterfaces = [ "eth2" ];
|
||||
networking.interfaces.eth1.ipv4.addresses = [
|
||||
{ address = externalRouterAddress; prefixLength = 24; }
|
||||
];
|
||||
networking.interfaces.eth2.ipv4.addresses = [
|
||||
{ address = internalRouterAddress; prefixLength = 24; }
|
||||
];
|
||||
services.miniupnpd = {
|
||||
enable = true;
|
||||
externalInterface = "eth1";
|
||||
internalIPs = [ "eth2" ];
|
||||
appendConfig = ''
|
||||
ext_ip=${externalRouterAddress}
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
client1 =
|
||||
{ pkgs, nodes, ... }:
|
||||
{ environment.systemPackages = [ pkgs.miniupnpc pkgs.netcat ];
|
||||
virtualisation.vlans = [ 2 ];
|
||||
networking.defaultGateway = internalRouterAddress;
|
||||
networking.interfaces.eth1.ipv4.addresses = [
|
||||
{ address = internalClient1Address; prefixLength = 24; }
|
||||
];
|
||||
networking.firewall.enable = false;
|
||||
|
||||
services.httpd.enable = true;
|
||||
services.httpd.listen = [{ ip = "*"; port = 9000; }];
|
||||
services.httpd.adminAddr = "foo@example.org";
|
||||
services.httpd.documentRoot = "/tmp";
|
||||
};
|
||||
|
||||
client2 =
|
||||
{ pkgs, ... }:
|
||||
{ environment.systemPackages = [ pkgs.miniupnpc ];
|
||||
virtualisation.vlans = [ 1 ];
|
||||
networking.interfaces.eth1.ipv4.addresses = [
|
||||
{ address = externalClient2Address; prefixLength = 24; }
|
||||
];
|
||||
networking.firewall.enable = false;
|
||||
};
|
||||
};
|
||||
|
||||
testScript =
|
||||
{ nodes, ... }:
|
||||
''
|
||||
startAll;
|
||||
|
||||
# Wait for network and miniupnpd.
|
||||
$router->waitForUnit("network-online.target");
|
||||
# $router->waitForUnit("nat");
|
||||
$router->waitForUnit("firewall.service");
|
||||
$router->waitForUnit("miniupnpd");
|
||||
|
||||
$client1->waitForUnit("network-online.target");
|
||||
|
||||
$client1->succeed("upnpc -a ${internalClient1Address} 9000 9000 TCP");
|
||||
|
||||
$client1->waitForUnit("httpd");
|
||||
$client2->waitUntilSucceeds("curl http://${externalRouterAddress}:9000/");
|
||||
'';
|
||||
|
||||
})
|
@ -1,20 +1,21 @@
|
||||
{ stdenv, fetchurl, pkgconfig, autoreconfHook, openssl, db48, boost, zeromq
|
||||
, zlib, miniupnpc, qtbase ? null, qttools ? null, utillinux, protobuf, qrencode, libevent
|
||||
, zlib, miniupnpc, qtbase ? null, qttools ? null, utillinux, protobuf, python3, qrencode, libevent
|
||||
, withGui }:
|
||||
|
||||
with stdenv.lib;
|
||||
stdenv.mkDerivation rec{
|
||||
name = "bitcoin" + (toString (optional (!withGui) "d")) + "-" + version;
|
||||
version = "0.16.3";
|
||||
version = "0.17.0";
|
||||
|
||||
src = fetchurl {
|
||||
urls = [ "https://bitcoincore.org/bin/bitcoin-core-${version}/bitcoin-${version}.tar.gz"
|
||||
"https://bitcoin.org/bin/bitcoin-core-${version}/bitcoin-${version}.tar.gz"
|
||||
];
|
||||
sha256 = "060223dzzk2izfzhxwlzzd0fhbgglvbgps2nyc4zz767vybysvl3";
|
||||
sha256 = "0pkq28d2dj22qrxyyg9kh0whmhj7ghyabnhyqldbljv4a7l3kvwq";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ pkgconfig autoreconfHook ];
|
||||
nativeBuildInputs = [ pkgconfig autoreconfHook ]
|
||||
++ optionals doCheck [ python3 ];
|
||||
buildInputs = [ openssl db48 boost zlib zeromq
|
||||
miniupnpc protobuf libevent]
|
||||
++ optionals stdenv.isLinux [ utillinux ]
|
||||
@ -30,9 +31,11 @@ stdenv.mkDerivation rec{
|
||||
"--with-qt-bindir=${qtbase.dev}/bin:${qttools.dev}/bin"
|
||||
];
|
||||
|
||||
# Fails with "This application failed to start because it could not
|
||||
# find or load the Qt platform plugin "minimal""
|
||||
doCheck = false;
|
||||
doCheck = true;
|
||||
|
||||
# QT_PLUGIN_PATH needs to be set when executing QT, which is needed when testing Bitcoin's GUI.
|
||||
# See also https://github.com/NixOS/nixpkgs/issues/24256
|
||||
checkFlags = optionals withGui [ "QT_PLUGIN_PATH=${qtbase}/lib/qt-5.${versions.minor qtbase.version}/plugins" ];
|
||||
|
||||
enableParallelBuilding = true;
|
||||
|
||||
|
@ -11,13 +11,13 @@ with stdenv.lib;
|
||||
stdenv.mkDerivation rec {
|
||||
|
||||
name = "litecoin" + (toString (optional (!withGui) "d")) + "-" + version;
|
||||
version = "0.16.0";
|
||||
version = "0.16.2";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "litecoin-project";
|
||||
repo = "litecoin";
|
||||
rev = "v${version}";
|
||||
sha256 = "1g79sbplkn2bnb17i2kyh1d64bjl3ihbx83n0xssvjaajn56hbzw";
|
||||
sha256 = "0xfwh7cxxz6w8kgr4kl48w3zm81n1hv8fxb5l9zx3460im1ffgy6";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ pkgconfig autoreconfHook ];
|
||||
|
@ -3,13 +3,13 @@
|
||||
stdenv.mkDerivation rec {
|
||||
|
||||
name = "nano-wallet-${version}";
|
||||
version = "16.0";
|
||||
version = "16.1";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "nanocurrency";
|
||||
repo = "raiblocks";
|
||||
rev = "V${version}";
|
||||
sha256 = "0fk8jlas3khdh3nlv40krsjdifxp9agblvzap6k93wmm9y34h41c";
|
||||
sha256 = "0sk9g4fv494a5w75vs5a3s5c139lxzz1svz0cn1hkhxqlmz8w081";
|
||||
fetchSubmodules = true;
|
||||
};
|
||||
|
||||
|
@ -6,11 +6,11 @@ uiEnv = pkgs.callPackage ./env.nix { };
|
||||
|
||||
in stdenv.mkDerivation rec {
|
||||
name = "parity-ui-${version}";
|
||||
version = "0.2.8";
|
||||
version = "0.3.4";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://github.com/parity-js/shell/releases/download/v${version}/parity-ui_${version}_amd64.deb";
|
||||
sha256 = "1nyarq73jdknhax68cq2i868sznghzj70kvk4ixypxnjb1q6a53a";
|
||||
sha256 = "1xbd00r9ph8w2d6d2c5xg4b5l74ljzs50rpc6kahfznypmh4kr73";
|
||||
name = "${name}.deb";
|
||||
};
|
||||
|
||||
|
37
pkgs/applications/audio/FIL-plugins/default.nix
Normal file
37
pkgs/applications/audio/FIL-plugins/default.nix
Normal file
@ -0,0 +1,37 @@
|
||||
{ stdenv, fetchurl, ladspaH
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
name = "FIL-plugins-${version}";
|
||||
version = "0.3.0";
|
||||
src = fetchurl {
|
||||
url = "http://kokkinizita.linuxaudio.org/linuxaudio/downloads/${name}.tar.bz2";
|
||||
sha256 = "1scfv9j7jrp50r565haa4rvxn1vk2ss86xssl5qgcr8r45qz42qw";
|
||||
};
|
||||
|
||||
buildInputs = [ ladspaH ];
|
||||
|
||||
patchPhase = ''
|
||||
sed -i 's@/usr/bin/install@install@g' Makefile
|
||||
sed -i 's@/bin/rm@rm@g' Makefile
|
||||
sed -i 's@/usr/lib/ladspa@$(out)/lib/ladspa@g' Makefile
|
||||
'';
|
||||
|
||||
preInstall="mkdir -p $out/lib/ladspa";
|
||||
|
||||
meta = {
|
||||
description = ''a four-band parametric equaliser, which has the nice property of being stable even while parameters are being changed'';
|
||||
longDescription = ''
|
||||
Each section has an active/bypass switch, frequency, bandwidth and gain controls.
|
||||
There is also a global bypass switch and gain control.
|
||||
The 2nd order resonant filters are implemented using a Mitra-Regalia style lattice filter.
|
||||
All switches and controls are internally smoothed, so they can be used 'live' whithout any clicks or zipper noises.
|
||||
This should make this plugin a good candidate for use in systems that allow automation of plugin control ports, such as Ardour, or for stage use.
|
||||
'';
|
||||
version = "${version}";
|
||||
homepage = http://kokkinizita.linuxaudio.org/linuxaudio/ladspa/index.html;
|
||||
license = stdenv.lib.licenses.gpl2Plus;
|
||||
maintainers = [ stdenv.lib.maintainers.magnetophon ];
|
||||
platforms = stdenv.lib.platforms.linux;
|
||||
};
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
Two changes:
|
||||
|
||||
* Add an alias for `which', so abcde can find things in store
|
||||
* Choose the right CDROM reader syntax for `cd-paranoia'
|
||||
|
||||
--- abcde-2.5.4/abcde~ 2012-09-18 06:09:31.000000000 -0700
|
||||
+++ abcde-2.5.4/abcde 2012-10-27 00:08:48.000862364 -0700
|
||||
@@ -17,6 +17,11 @@
|
||||
|
||||
VERSION='2.5.4'
|
||||
|
||||
+which ()
|
||||
+{
|
||||
+ type -P $1
|
||||
+}
|
||||
+
|
||||
usage ()
|
||||
{
|
||||
echo "This is abcde v$VERSION."
|
||||
@@ -3497,6 +3502,10 @@
|
||||
for DEFAULT_CDROMREADER in $DEFAULT_CDROMREADERS; do
|
||||
if new_checkexec $DEFAULT_CDROMREADER; then
|
||||
CDROMREADERSYNTAX=$DEFAULT_CDROMREADER
|
||||
+ case "$DEFAULT_CDROMREADER" in
|
||||
+ cd-paranoia) CDROMREADERSYNTAX=cdparanoia;;
|
||||
+ *) CDROMREADERSYNTAX=$DEFAULT_CDROMREADER;;
|
||||
+ esac
|
||||
break
|
||||
fi
|
||||
done
|
@ -3,60 +3,58 @@
|
||||
, perl, MusicBrainz, MusicBrainzDiscID
|
||||
, makeWrapper }:
|
||||
|
||||
let version = "2.8.1";
|
||||
let version = "2.9.2";
|
||||
in
|
||||
stdenv.mkDerivation {
|
||||
name = "abcde-${version}";
|
||||
src = fetchurl {
|
||||
url = "https://abcde.einval.com/download/abcde-${version}.tar.gz";
|
||||
sha256 = "0f9bjs0phk23vry7gvh0cll9vl6kmc1y4fwwh762scfdvpbp3774";
|
||||
sha256 = "13c5yvp87ckqgha160ym5rdr1a4divgvyqbjh0yb6ffclip6qd9l";
|
||||
};
|
||||
|
||||
# FIXME: This package does not support `distmp3', `eject', etc.
|
||||
|
||||
patches = [ ./abcde.patch ];
|
||||
|
||||
configurePhase = ''
|
||||
sed -i "s|^[[:blank:]]*prefix *=.*$|prefix = $out|g ;
|
||||
s|^[[:blank:]]*etcdir *=.*$|etcdir = $out/etc|g ;
|
||||
s|^[[:blank:]]*INSTALL *=.*$|INSTALL = install -c|g" \
|
||||
"Makefile";
|
||||
|
||||
# We use `cd-paranoia' from GNU libcdio, which contains a hyphen
|
||||
# in its name, unlike Xiph's cdparanoia.
|
||||
sed -i "s|^[[:blank:]]*CDPARANOIA=.*$|CDPARANOIA=cd-paranoia|g ;
|
||||
s|^[[:blank:]]*DEFAULT_CDROMREADERS=.*$|DEFAULT_CDROMREADERS=\"cd-paranoia cdda2wav\"|g" \
|
||||
"abcde"
|
||||
echo 'CDPARANOIA=${libcdio-paranoia}/bin/cd-paranoia' >>abcde.conf
|
||||
echo CDROMREADERSYNTAX=cdparanoia >>abcde.conf
|
||||
|
||||
substituteInPlace "abcde" \
|
||||
--replace "/etc/abcde.conf" "$out/etc/abcde.conf"
|
||||
|
||||
'';
|
||||
|
||||
buildInputs = [ makeWrapper ];
|
||||
nativeBuildInputs = [ makeWrapper ];
|
||||
|
||||
propagatedBuildInputs = [ perl MusicBrainz MusicBrainzDiscID ];
|
||||
buildInputs = [ perl MusicBrainz MusicBrainzDiscID ];
|
||||
|
||||
installFlags = [ "sysconfdir=$(out)/etc" ];
|
||||
|
||||
postFixup = ''
|
||||
for cmd in abcde cddb-tool abcde-musicbrainz-tool; do
|
||||
wrapProgram "$out/bin/$cmd" --prefix PATH ":" \
|
||||
${stdenv.lib.makeBinPath [ "$out" which libcdio-paranoia cddiscid wget vorbis-tools id3v2 eyeD3 lame flac glyr ]}
|
||||
wrapProgram "$out/bin/$cmd" \
|
||||
--prefix PERL5LIB : "$PERL5LIB" \
|
||||
--prefix PATH ":" ${stdenv.lib.makeBinPath [
|
||||
"$out" which libcdio-paranoia cddiscid wget
|
||||
vorbis-tools id3v2 eyeD3 lame flac glyr
|
||||
]}
|
||||
done
|
||||
'';
|
||||
|
||||
meta = {
|
||||
meta = with stdenv.lib; {
|
||||
homepage = http://abcde.einval.com/wiki/;
|
||||
license = stdenv.lib.licenses.gpl2Plus;
|
||||
license = licenses.gpl2Plus;
|
||||
maintainers = with maintainers; [ gebner ];
|
||||
description = "Command-line audio CD ripper";
|
||||
|
||||
longDescription = ''
|
||||
abcde is a front-end command-line utility (actually, a shell
|
||||
script) that grabs tracks off a CD, encodes them to
|
||||
Ogg/Vorbis, MP3, FLAC, Ogg/Speex and/or MPP/MP+ (Musepack)
|
||||
format, and tags them, all in one go.
|
||||
'';
|
||||
platforms = stdenv.lib.platforms.linux;
|
||||
platforms = platforms.linux;
|
||||
};
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ in stdenv.mkDerivation rec {
|
||||
name = "${pname}-${version}";
|
||||
|
||||
src = fetchurl {
|
||||
url = "mirror://gnome/sources/${pname}/${gnome3.versionBranch version}/${name}.tar.xz";
|
||||
url = "mirror://gnome/sources/${pname}/${stdenv.lib.versions.majorMinor version}/${name}.tar.xz";
|
||||
sha256 = "1mbxnqrw1fwcgraa1bgik25vdzvf97vma5pzknbwbqq5ly9fwlgw";
|
||||
};
|
||||
|
||||
|
@ -7,13 +7,13 @@
|
||||
|
||||
mkDerivation rec {
|
||||
name = "elisa-${version}";
|
||||
version = "0.2.80";
|
||||
version = "0.3.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "KDE";
|
||||
repo = "elisa";
|
||||
rev = "v${version}";
|
||||
sha256 = "0wc2kkp28gp1rfgg14a769lalwd44yz7jxkrzanh91v5j2kkln07";
|
||||
sha256 = "0bpkr5rp9nfa2wzm6w3xkhsfgf5dbgxbmhckjh9wkxal3mncpkg4";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ extra-cmake-modules kdoctools wrapGAppsHook ];
|
||||
|
24
pkgs/applications/audio/eteroj.lv2/default.nix
Normal file
24
pkgs/applications/audio/eteroj.lv2/default.nix
Normal file
@ -0,0 +1,24 @@
|
||||
{ stdenv, fetchFromGitHub, cmake, pkgconfig, libuv, lv2 }:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "eteroj.lv2";
|
||||
version = "0.4.0";
|
||||
name = "${pname}-${version}";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "OpenMusicKontrollers";
|
||||
repo = pname;
|
||||
rev = version;
|
||||
sha256 = "0lzdk7hlz3vqgshrfpj0izjad1fmsnzk2vxqrry70xgz8xglvnmn";
|
||||
};
|
||||
|
||||
buildInputs = [ libuv lv2 ];
|
||||
nativeBuildInputs = [ cmake pkgconfig ];
|
||||
|
||||
meta = with stdenv.lib; {
|
||||
description = "OSC injection/ejection from/to UDP/TCP/Serial for LV2";
|
||||
homepage = https://open-music-kontrollers.ch/lv2/eteroj;
|
||||
license = licenses.artistic2;
|
||||
maintainers = with maintainers; [ magnetophon ];
|
||||
};
|
||||
}
|
160
pkgs/applications/audio/lsp-plugins/default.nix
Normal file
160
pkgs/applications/audio/lsp-plugins/default.nix
Normal file
@ -0,0 +1,160 @@
|
||||
{ stdenv, fetchFromGitHub, pkgconfig, makeWrapper
|
||||
, libsndfile, jack2Full
|
||||
, libGLU, libGL, lv2, cairo
|
||||
, ladspaH, php, expat }:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "lsp-plugins";
|
||||
version = "1.1.4";
|
||||
name = "${pname}-${version}";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "sadko4u";
|
||||
repo = "${pname}";
|
||||
rev = "${name}";
|
||||
sha256 = "0vb8ax0w4d2a153wxrhkpi21fxsv7c24k57vhfgmm1lqwv6pbl69";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ pkgconfig php expat ];
|
||||
buildInputs = [ jack2Full libsndfile libGLU libGL lv2 cairo ladspaH makeWrapper ];
|
||||
|
||||
makeFlags = [
|
||||
"BIN_PATH=$(out)/bin"
|
||||
"LIB_PATH=$(out)/lib"
|
||||
"DOC_PATH=$(out)/share/doc"
|
||||
];
|
||||
|
||||
NIX_CFLAGS_COMPILE = [ "-DLSP_NO_EXPERIMENTAL" ];
|
||||
|
||||
patchPhase = ''
|
||||
runHook prePatch
|
||||
substituteInPlace Makefile --replace "/usr/lib" "$out/lib"
|
||||
substituteInPlace ./include/container/jack/main.h --replace "/usr/lib" "$out/lib"
|
||||
substituteInPlace ./include/container/vst/main.h --replace "/usr/lib" "$out/lib"
|
||||
# for https://github.com/sadko4u/lsp-plugins/issues/7#issuecomment-426561549 :
|
||||
sed -i '/X11__NET_WM_WINDOW_TYPE_DOCK;/d' ./src/ui/ws/x11/X11Window.cpp
|
||||
runHook postPatch
|
||||
'';
|
||||
|
||||
doCheck = true;
|
||||
|
||||
checkPhase = ''
|
||||
runHook preCheck
|
||||
TEST_PATH=$(pwd)".build-test"
|
||||
make OBJDIR=$TEST_PATH test
|
||||
$TEST_PATH/lsp-plugins-test utest
|
||||
runHook postCheck
|
||||
'';
|
||||
|
||||
buildFlags = "release";
|
||||
|
||||
meta = with stdenv.lib;
|
||||
{ description = "Collection of open-source audio plugins";
|
||||
longDescription = ''
|
||||
Compatible with follwing formats:
|
||||
|
||||
- LADSPA - set of plugins for Linux Audio Developer's Simple Plugin API
|
||||
- LV2 - set of plugins and UIs for Linux Audio Developer's Simple Plugin API (LADSPA) version 2
|
||||
- LinuxVST - set of plugins and UIs for Steinberg's VST 2.4 format ported on GNU/Linux Platform
|
||||
- JACK - Standalone versions for JACK Audio connection Kit with UI
|
||||
|
||||
Contains the following plugins:
|
||||
|
||||
- Limiter Mono - Begrenzer Mono
|
||||
- Limiter Stereo - Begrenzer Stereo
|
||||
- Dynamic Processor LeftRight - Dynamikprozessor LeftRight
|
||||
- Dynamic Processor MidSide - Dynamikprozessor MidSide
|
||||
- Dynamic Processor Mono - Dynamikprozessor Mono
|
||||
- Dynamic Processor Stereo - Dynamikprozessor Stereo
|
||||
- Expander LeftRight - Expander LeftRight
|
||||
- Expander MidSide - Expander MidSide
|
||||
- Expander Mono - Expander Mono
|
||||
- Expander Stereo - Expander Stereo
|
||||
- Gate LeftRight - Gate LeftRight
|
||||
- Gate MidSide - Gate MidSide
|
||||
- Gate Mono - Gate Mono
|
||||
- Gate Stereo - Gate Stereo
|
||||
- Graphic Equalizer x16 LeftRight - Grafischer Entzerrer x16 LeftRight
|
||||
- Graphic Equalizer x16 MidSide - Grafischer Entzerrer x16 MidSide
|
||||
- Graphic Equalizer x16 Mono - Grafischer Entzerrer x16 Mono
|
||||
- Graphic Equalizer x16 Stereo - Grafischer Entzerrer x16 Stereo
|
||||
- Graphic Equalizer x32 LeftRight - Grafischer Entzerrer x32 LeftRight
|
||||
- Graphic Equalizer x32 MidSide - Grafischer Entzerrer x32 MidSide
|
||||
- Graphic Equalizer x32 Mono - Grafischer Entzerrer x32 Mono
|
||||
- Graphic Equalizer x32 Stereo - Grafischer Entzerrer x32 Stereo
|
||||
- Impulse Responses Mono - Impulsantworten Mono
|
||||
- Impulse Responses Stereo - Impulsantworten Stereo
|
||||
- Impulse Reverb Mono - Impulsnachhall Mono
|
||||
- Impulse Reverb Stereo - Impulsnachhall Stereo
|
||||
- Sampler Mono - Klangerzeuger Mono
|
||||
- Sampler Stereo - Klangerzeuger Stereo
|
||||
- Compressor LeftRight - Kompressor LeftRight
|
||||
- Compressor MidSide - Kompressor MidSide
|
||||
- Compressor Mono - Kompressor Mono
|
||||
- Compressor Stereo - Kompressor Stereo
|
||||
- Latency Meter - Latenzmessgerät
|
||||
- Multiband Compressor LeftRight x8 - Multi-band Kompressor LeftRight x8
|
||||
- Multiband Compressor MidSide x8 - Multi-band Kompressor MidSide x8
|
||||
- Multiband Compressor Mono x8 - Multi-band Kompressor Mono x8
|
||||
- Multiband Compressor Stereo x8 - Multi-band Kompressor Stereo x8
|
||||
- Oscillator Mono - Oszillator Mono
|
||||
- Parametric Equalizer x16 LeftRight - Parametrischer Entzerrer x16 LeftRight
|
||||
- Parametric Equalizer x16 MidSide - Parametrischer Entzerrer x16 MidSide
|
||||
- Parametric Equalizer x16 Mono - Parametrischer Entzerrer x16 Mono
|
||||
- Parametric Equalizer x16 Stereo - Parametrischer Entzerrer x16 Stereo
|
||||
- Parametric Equalizer x32 LeftRight - Parametrischer Entzerrer x32 LeftRight
|
||||
- Parametric Equalizer x32 MidSide - Parametrischer Entzerrer x32 MidSide
|
||||
- Parametric Equalizer x32 Mono - Parametrischer Entzerrer x32 Mono
|
||||
- Parametric Equalizer x32 Stereo - Parametrischer Entzerrer x32 Stereo
|
||||
- Phase Detector - Phasendetektor
|
||||
- Profiler Mono - Profiler Mono
|
||||
- Multi-Sampler x12 DirectOut - Schlagzeug x12 Direktausgabe
|
||||
- Multi-Sampler x12 Stereo - Schlagzeug x12 Stereo
|
||||
- Multi-Sampler x24 DirectOut - Schlagzeug x24 Direktausgabe
|
||||
- Multi-Sampler x24 Stereo - Schlagzeug x24 Stereo
|
||||
- Multi-Sampler x48 DirectOut - Schlagzeug x48 Direktausgabe
|
||||
- Multi-Sampler x48 Stereo - Schlagzeug x48 Stereo
|
||||
- Sidechain Multiband Compressor LeftRight x8 - Sidechain Multi-band Kompressor LeftRight x8
|
||||
- Sidechain Multiband Compressor MidSide x8 - Sidechain Multi-band Kompressor MidSide x8
|
||||
- Sidechain Multiband Compressor Mono x8 - Sidechain Multi-band Kompressor Mono x8
|
||||
- Sidechain Multiband Compressor Stereo x8 - Sidechain Multi-band Kompressor Stereo x8
|
||||
- Sidechain Limiter Mono - Sidechain-Begrenzer Mono
|
||||
- Sidechain Limiter Stereo - Sidechain-Begrenzer Stereo
|
||||
- Sidechain Dynamic Processor LeftRight - Sidechain-Dynamikprozessor LeftRight
|
||||
- Sidechain Dynamic Processor MidSide - Sidechain-Dynamikprozessor MidSide
|
||||
- Sidechain Dynamic Processor Mono - Sidechain-Dynamikprozessor Mono
|
||||
- Sidechain Dynamic Processor Stereo - Sidechain-Dynamikprozessor Stereo
|
||||
- Sidechain Expander LeftRight - Sidechain-Expander LeftRight
|
||||
- Sidechain Expander MidSide - Sidechain-Expander MidSide
|
||||
- Sidechain Expander Mono - Sidechain-Expander Mono
|
||||
- Sidechain Expander Stereo - Sidechain-Expander Stereo
|
||||
- Sidechain Gate LeftRight - Sidechain-Gate LeftRight
|
||||
- Sidechain Gate MidSide - Sidechain-Gate MidSide
|
||||
- Sidechain Gate Mono - Sidechain-Gate Mono
|
||||
- Sidechain Gate Stereo - Sidechain-Gate Stereo
|
||||
- Sidechain Compressor LeftRight - Sidechain-Kompressor LeftRight
|
||||
- Sidechain Compressor MidSide - Sidechain-Kompressor MidSide
|
||||
- Sidechain Compressor Mono - Sidechain-Kompressor Mono
|
||||
- Sidechain Compressor Stereo - Sidechain-Kompressor Stereo
|
||||
- Slapback Delay Mono - Slapback-Delay Mono
|
||||
- Slapback Delay Stereo - Slapback-Delay Stereo
|
||||
- Spectrum Analyzer x1 - Spektrumanalysator x1
|
||||
- Spectrum Analyzer x12 - Spektrumanalysator x12
|
||||
- Spectrum Analyzer x16 - Spektrumanalysator x16
|
||||
- Spectrum Analyzer x2 - Spektrumanalysator x2
|
||||
- Spectrum Analyzer x4 - Spektrumanalysator x4
|
||||
- Spectrum Analyzer x8 - Spektrumanalysator x8
|
||||
- Trigger MIDI Mono - Triggersensor MIDI Mono
|
||||
- Trigger MIDI Stereo - Triggersensor MIDI Stereo
|
||||
- Trigger Mono - Triggersensor Mono
|
||||
- Trigger Stereo - Triggersensor Stereo
|
||||
- Delay Compensator Mono - Verzögerungsausgleicher Mono
|
||||
- Delay Compensator Stereo - Verzögerungsausgleicher Stereo
|
||||
- Delay Compensator x2 Stereo - Verzögerungsausgleicher x2 Stereo
|
||||
'';
|
||||
homepage = http://lsp-plug.in;
|
||||
maintainers = with maintainers; [ magnetophon ];
|
||||
license = licenses.gpl2;
|
||||
platforms = platforms.linux;
|
||||
};
|
||||
}
|
@ -1,23 +1,24 @@
|
||||
{ stdenv, fetchurl, makeWrapper, SDL, alsaLib, autoreconfHook, gtk2, libjack2, ladspaH
|
||||
{ stdenv, fetchFromGitHub, makeWrapper, SDL, alsaLib, autoreconfHook, gtk2, libjack2, ladspaH
|
||||
, ladspaPlugins, libsamplerate, libsndfile, pkgconfig, libpulseaudio, lame
|
||||
, vorbis-tools }:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
stdenv.mkDerivation rec {
|
||||
name = "mhwaveedit-${version}";
|
||||
version = "1.4.23";
|
||||
version = "1.4.24";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://github.com/magnush/mhwaveedit/archive/v${version}.tar.gz";
|
||||
sha256 = "1lvd54d8kpxwl4gihhznx1b5skhibz4vfxi9k2kwqg808jfgz37l";
|
||||
src = fetchFromGitHub {
|
||||
owner = "magnush";
|
||||
repo = "mhwaveedit";
|
||||
rev = "v${version}";
|
||||
sha256 = "037pbq23kh8hsih994x2sv483imglwcrqrx6m8visq9c46fi0j1y";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ autoreconfHook ];
|
||||
nativeBuildInputs = [ autoreconfHook makeWrapper pkgconfig ];
|
||||
|
||||
preAutoreconf = "(cd docgen && sh gendocs.sh)";
|
||||
|
||||
buildInputs = [
|
||||
SDL alsaLib gtk2 libjack2 ladspaH libsamplerate libsndfile
|
||||
pkgconfig libpulseaudio makeWrapper
|
||||
SDL alsaLib gtk2 libjack2 ladspaH libsamplerate libsndfile libpulseaudio
|
||||
];
|
||||
|
||||
configureFlags = [ "--with-default-ladspa-path=${ladspaPlugins}/lib/ladspa" ];
|
||||
@ -30,7 +31,7 @@ stdenv.mkDerivation rec {
|
||||
|
||||
meta = with stdenv.lib; {
|
||||
description = "Graphical program for editing, playing and recording sound files";
|
||||
homepage = https://gna.org/projects/mhwaveedit;
|
||||
homepage = https://github.com/magnush/mhwaveedit;
|
||||
license = licenses.gpl2Plus;
|
||||
platforms = platforms.linux;
|
||||
maintainers = [ maintainers.goibhniu ];
|
||||
|
60
pkgs/applications/audio/midisheetmusic/default.nix
Normal file
60
pkgs/applications/audio/midisheetmusic/default.nix
Normal file
@ -0,0 +1,60 @@
|
||||
{ stdenv, fetchurl
|
||||
, mono, dotnetPackages, makeWrapper
|
||||
, gtk2, cups, timidity }:
|
||||
|
||||
let
|
||||
version = "2.6";
|
||||
in stdenv.mkDerivation {
|
||||
name = "midisheetmusic";
|
||||
|
||||
src = fetchurl {
|
||||
url = "mirror://sourceforge/midisheetmusic/MidiSheetMusic-${version}-linux-src.tar.gz";
|
||||
sha256 = "05c6zskj50g29f51lx8fvgzsi3f31z01zj6ssjjrgr7jfs7ak70p";
|
||||
};
|
||||
|
||||
checkInputs = (with dotnetPackages; [ NUnitConsole ]);
|
||||
nativeBuildInputs = [ mono makeWrapper ];
|
||||
|
||||
buildPhase = ''
|
||||
for i in Classes/MidiPlayer.cs Classes/MidiSheetMusic.cs
|
||||
do
|
||||
substituteInPlace $i --replace "/usr/bin/timidity" "${timidity}/bin/timidity"
|
||||
done
|
||||
|
||||
./build.sh
|
||||
'';
|
||||
|
||||
# include missing file with unit tests for building
|
||||
# switch from mono nunit dll to standalone dll otherwise mono compiler barks
|
||||
# run via nunit3 console, because mono nunit console wants access $HOME
|
||||
checkPhase = ''
|
||||
substituteInPlace UnitTestDLL.csproj \
|
||||
--replace "</Compile>" '</Compile><Compile Include="Classes\UnitTest.cs"/>' \
|
||||
--replace nunit.framework.dll "${dotnetPackages.NUnit}/lib/dotnet/NUnit/nunit.framework.dll"
|
||||
./build_unit_test.sh
|
||||
nunit3-console bin/Debug/UnitTest.dll
|
||||
'';
|
||||
|
||||
# 2 tests of 47 are still failing
|
||||
doCheck = false;
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out/share/applications $out/share/pixmaps $out/bin
|
||||
|
||||
cp deb/midisheetmusic.desktop $out/share/applications
|
||||
cp NotePair.png $out/share/pixmaps/midisheetmusic.png
|
||||
cp bin/Debug/MidiSheetMusic.exe $out/bin/.MidiSheetMusic.exe
|
||||
|
||||
makeWrapper ${mono}/bin/mono $out/bin/midisheetmusic.mono.exe \
|
||||
--prefix LD_LIBRARY_PATH : ${stdenv.lib.makeLibraryPath [ gtk2 cups ]} \
|
||||
--add-flags $out/bin/.MidiSheetMusic.exe
|
||||
'';
|
||||
|
||||
meta = with stdenv.lib; {
|
||||
description = "Convert MIDI Files to Piano Sheet Music for two hands";
|
||||
homepage = http://midisheetmusic.com;
|
||||
license = licenses.gpl2;
|
||||
maintainers = [ maintainers.gnidorah ];
|
||||
platforms = platforms.linux;
|
||||
};
|
||||
}
|
@ -44,13 +44,13 @@ let
|
||||
];
|
||||
in stdenv.mkDerivation rec {
|
||||
name = "pulseeffects-${version}";
|
||||
version = "4.3.5";
|
||||
version = "4.3.7";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "wwmm";
|
||||
repo = "pulseeffects";
|
||||
rev = "v${version}";
|
||||
sha256 = "01jxkz4s3m8cqsn6wcbrw7bzr7sr7hqsp9950018riilpni7k4bd";
|
||||
sha256 = "1x1jnbpbc9snya9k2xq39gssf0k4lnd1hr4cjrnwscg5rqybxqsk";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
@ -20,7 +20,7 @@ in stdenv.mkDerivation rec {
|
||||
name = "${pname}-${version}";
|
||||
|
||||
src = fetchurl {
|
||||
url = "mirror://gnome/sources/${pname}/${gnome3.versionBranch version}/${name}.tar.xz";
|
||||
url = "mirror://gnome/sources/${pname}/${stdenv.lib.versions.majorMinor version}/${name}.tar.xz";
|
||||
sha256 = "0hzcns8gf5yb0rm4ss8jd8qzarcaplp5cylk6plwilsqfvxj4xn2";
|
||||
};
|
||||
|
||||
|
@ -9,7 +9,7 @@ in stdenv.mkDerivation rec{
|
||||
name = "${pname}-${version}";
|
||||
|
||||
src = fetchurl {
|
||||
url = "mirror://gnome/sources/${pname}/${gnome3.versionBranch version}/${name}.tar.xz";
|
||||
url = "mirror://gnome/sources/${pname}/${stdenv.lib.versions.majorMinor version}/${name}.tar.xz";
|
||||
sha256 = "0mx6n901vb97hsv0cwaafjffj75s1kcp8jsqay90dy3099849dyz";
|
||||
};
|
||||
|
||||
|
34
pkgs/applications/audio/tambura/default.nix
Normal file
34
pkgs/applications/audio/tambura/default.nix
Normal file
@ -0,0 +1,34 @@
|
||||
{ stdenv, fetchFromGitHub, faust2jaqt, faust2lv2 }:
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "Tambura";
|
||||
name = "${pname}-${version}";
|
||||
version = "1.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "olilarkin";
|
||||
repo = "${pname}";
|
||||
rev = "v${version}";
|
||||
sha256 = "1w80cmiyzca1wirf5gypg3hcix1ky777id8wnd3k92mn1jf4a24y";
|
||||
};
|
||||
|
||||
buildInputs = [ faust2jaqt faust2lv2 ];
|
||||
|
||||
buildPhase = ''
|
||||
faust2jaqt -vec -time -t 99999 ${pname}.dsp
|
||||
faust2lv2 -vec -time -gui -t 99999 ${pname}.dsp
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out/bin
|
||||
cp ${pname} $out/bin/
|
||||
mkdir -p $out/lib/lv2
|
||||
cp -r ${pname}.lv2/ $out/lib/lv2
|
||||
'';
|
||||
|
||||
meta = with stdenv.lib; {
|
||||
description = "A FAUST patch inspired by the Indian Tambura/Tanpura - a four string drone instrument, known for its unique rich harmonic timbre";
|
||||
homepage = https://github.com/olilarkin/Tambura;
|
||||
license = licenses.gpl2;
|
||||
maintainers = [ maintainers.magnetophon ];
|
||||
};
|
||||
}
|
@ -14,7 +14,7 @@ python2.pkgs.buildPythonApplication rec {
|
||||
|
||||
pythonPath = with python2.pkgs; [
|
||||
pygobject2 musicbrainzngs urllib3 chardet
|
||||
pycdio setuptools mutagen
|
||||
pycdio setuptools mutagen CDDB
|
||||
requests
|
||||
];
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user