uboot: (firmwareOdroidC2/C4) don't invoke patch tool, use patches = [] instead
https://github.com/NixOS/nixpkgs/blob/master/pkgs/stdenv/generic/setup.sh#L948 this can do it nicely. Signed-off-by: Anton Arapov <anton@deadbeef.mx>
This commit is contained in:
commit
56de2bcd43
30691 changed files with 3076956 additions and 0 deletions
18
nixos/COPYING
Normal file
18
nixos/COPYING
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
5
nixos/README
Normal file
5
nixos/README
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
*** NixOS ***
|
||||
|
||||
NixOS is a Linux distribution based on the purely functional package
|
||||
management system Nix. More information can be found at
|
||||
https://nixos.org/nixos and in the manual in doc/manual.
|
||||
20
nixos/default.nix
Normal file
20
nixos/default.nix
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{ configuration ? import ./lib/from-env.nix "NIXOS_CONFIG" <nixos-config>
|
||||
, system ? builtins.currentSystem
|
||||
}:
|
||||
|
||||
let
|
||||
|
||||
eval = import ./lib/eval-config.nix {
|
||||
inherit system;
|
||||
modules = [ configuration ];
|
||||
};
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
inherit (eval) pkgs config options;
|
||||
|
||||
system = eval.config.system.build.toplevel;
|
||||
|
||||
inherit (eval.config.system.build) vm vmWithBootLoader;
|
||||
}
|
||||
2
nixos/doc/manual/.gitignore
vendored
Normal file
2
nixos/doc/manual/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
generated
|
||||
manual-combined.xml
|
||||
30
nixos/doc/manual/Makefile
Normal file
30
nixos/doc/manual/Makefile
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
.PHONY: all
|
||||
all: manual-combined.xml
|
||||
|
||||
.PHONY: debug
|
||||
debug: generated manual-combined.xml
|
||||
|
||||
manual-combined.xml: generated *.xml **/*.xml
|
||||
rm -f ./manual-combined.xml
|
||||
nix-shell --pure -Q --packages xmloscopy \
|
||||
--run "xmloscopy --docbook5 ./manual.xml ./manual-combined.xml"
|
||||
|
||||
.PHONY: format
|
||||
format:
|
||||
nix-shell --pure -Q --packages xmlformat \
|
||||
--run "find ../../ -iname '*.xml' -type f -print0 | xargs -0 -I{} -n1 \
|
||||
xmlformat --config-file '../xmlformat.conf' -i {}"
|
||||
|
||||
.PHONY: fix-misc-xml
|
||||
fix-misc-xml:
|
||||
find . -iname '*.xml' -type f \
|
||||
-exec ../varlistentry-fixer.rb {} ';'
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f manual-combined.xml generated
|
||||
|
||||
generated:
|
||||
nix-build ../../release.nix \
|
||||
--attr manualGeneratedSources.x86_64-linux \
|
||||
--out-link ./generated
|
||||
3
nixos/doc/manual/README.md
Normal file
3
nixos/doc/manual/README.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[Moved to ./contributing-to-this-manual.chapter.md](./contributing-to-this-manual.chapter.md). Link:
|
||||
|
||||
https://nixos.org/manual/nixos/unstable/#chap-contributing
|
||||
41
nixos/doc/manual/administration/boot-problems.section.md
Normal file
41
nixos/doc/manual/administration/boot-problems.section.md
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
# Boot Problems {#sec-boot-problems}
|
||||
|
||||
If NixOS fails to boot, there are a number of kernel command line parameters that may help you to identify or fix the issue. You can add these parameters in the GRUB boot menu by pressing “e” to modify the selected boot entry and editing the line starting with `linux`. The following are some useful kernel command line parameters that are recognised by the NixOS boot scripts or by systemd:
|
||||
|
||||
`boot.shell_on_fail`
|
||||
|
||||
: Allows the user to start a root shell if something goes wrong in stage 1 of the boot process (the initial ramdisk). This is disabled by default because there is no authentication for the root shell.
|
||||
|
||||
`boot.debug1`
|
||||
|
||||
: Start an interactive shell in stage 1 before anything useful has been done. That is, no modules have been loaded and no file systems have been mounted, except for `/proc` and `/sys`.
|
||||
|
||||
`boot.debug1devices`
|
||||
|
||||
: Like `boot.debug1`, but runs stage1 until kernel modules are loaded and device nodes are created. This may help with e.g. making the keyboard work.
|
||||
|
||||
`boot.debug1mounts`
|
||||
|
||||
: Like `boot.debug1` or `boot.debug1devices`, but runs stage1 until all filesystems that are mounted during initrd are mounted (see [neededForBoot](#opt-fileSystems._name_.neededForBoot)). As a motivating example, this could be useful if you've forgotten to set [neededForBoot](#opt-fileSystems._name_.neededForBoot) on a file system.
|
||||
|
||||
`boot.trace`
|
||||
|
||||
: Print every shell command executed by the stage 1 and 2 boot scripts.
|
||||
|
||||
`single`
|
||||
|
||||
: Boot into rescue mode (a.k.a. single user mode). This will cause systemd to start nothing but the unit `rescue.target`, which runs `sulogin` to prompt for the root password and start a root login shell. Exiting the shell causes the system to continue with the normal boot process.
|
||||
|
||||
`systemd.log_level=debug` `systemd.log_target=console`
|
||||
|
||||
: Make systemd very verbose and send log messages to the console instead of the journal. For more parameters recognised by systemd, see systemd(1).
|
||||
|
||||
In addition, these arguments are recognised by the live image only:
|
||||
|
||||
`live.nixos.passwd=password`
|
||||
|
||||
: Set the password for the `nixos` live user. This can be used for SSH access if there are issues using the terminal.
|
||||
|
||||
Notice that for `boot.shell_on_fail`, `boot.debug1`, `boot.debug1devices`, and `boot.debug1mounts`, if you did **not** select "start the new shell as pid 1", and you `exit` from the new shell, boot will proceed normally from the point where it failed, as if you'd chosen "ignore the error and continue".
|
||||
|
||||
If no login prompts or X11 login screens appear (e.g. due to hanging dependencies), you can press Alt+ArrowUp. If you’re lucky, this will start rescue mode (described above). (Also note that since most units have a 90-second timeout before systemd gives up on them, the `agetty` login prompts should appear eventually unless something is very wrong.)
|
||||
62
nixos/doc/manual/administration/cleaning-store.chapter.md
Normal file
62
nixos/doc/manual/administration/cleaning-store.chapter.md
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
# Cleaning the Nix Store {#sec-nix-gc}
|
||||
|
||||
Nix has a purely functional model, meaning that packages are never
|
||||
upgraded in place. Instead new versions of packages end up in a
|
||||
different location in the Nix store (`/nix/store`). You should
|
||||
periodically run Nix's *garbage collector* to remove old, unreferenced
|
||||
packages. This is easy:
|
||||
|
||||
```ShellSession
|
||||
$ nix-collect-garbage
|
||||
```
|
||||
|
||||
Alternatively, you can use a systemd unit that does the same in the
|
||||
background:
|
||||
|
||||
```ShellSession
|
||||
# systemctl start nix-gc.service
|
||||
```
|
||||
|
||||
You can tell NixOS in `configuration.nix` to run this unit automatically
|
||||
at certain points in time, for instance, every night at 03:15:
|
||||
|
||||
```nix
|
||||
nix.gc.automatic = true;
|
||||
nix.gc.dates = "03:15";
|
||||
```
|
||||
|
||||
The commands above do not remove garbage collector roots, such as old
|
||||
system configurations. Thus they do not remove the ability to roll back
|
||||
to previous configurations. The following command deletes old roots,
|
||||
removing the ability to roll back to them:
|
||||
|
||||
```ShellSession
|
||||
$ nix-collect-garbage -d
|
||||
```
|
||||
|
||||
You can also do this for specific profiles, e.g.
|
||||
|
||||
```ShellSession
|
||||
$ nix-env -p /nix/var/nix/profiles/per-user/eelco/profile --delete-generations old
|
||||
```
|
||||
|
||||
Note that NixOS system configurations are stored in the profile
|
||||
`/nix/var/nix/profiles/system`.
|
||||
|
||||
Another way to reclaim disk space (often as much as 40% of the size of
|
||||
the Nix store) is to run Nix's store optimiser, which seeks out
|
||||
identical files in the store and replaces them with hard links to a
|
||||
single copy.
|
||||
|
||||
```ShellSession
|
||||
$ nix-store --optimise
|
||||
```
|
||||
|
||||
Since this command needs to read the entire Nix store, it can take quite
|
||||
a while to finish.
|
||||
|
||||
## NixOS Boot Entries {#sect-nixos-gc-boot-entries}
|
||||
|
||||
If your `/boot` partition runs out of space, after clearing old profiles
|
||||
you must rebuild your system with `nixos-rebuild boot` or `nixos-rebuild
|
||||
switch` to update the `/boot` partition and clear space.
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
# Container Networking {#sec-container-networking}
|
||||
|
||||
When you create a container using `nixos-container create`, it gets it
|
||||
own private IPv4 address in the range `10.233.0.0/16`. You can get the
|
||||
container's IPv4 address as follows:
|
||||
|
||||
```ShellSession
|
||||
# nixos-container show-ip foo
|
||||
10.233.4.2
|
||||
|
||||
$ ping -c1 10.233.4.2
|
||||
64 bytes from 10.233.4.2: icmp_seq=1 ttl=64 time=0.106 ms
|
||||
```
|
||||
|
||||
Networking is implemented using a pair of virtual Ethernet devices. The
|
||||
network interface in the container is called `eth0`, while the matching
|
||||
interface in the host is called `ve-container-name` (e.g., `ve-foo`).
|
||||
The container has its own network namespace and the `CAP_NET_ADMIN`
|
||||
capability, so it can perform arbitrary network configuration such as
|
||||
setting up firewall rules, without affecting or having access to the
|
||||
host's network.
|
||||
|
||||
By default, containers cannot talk to the outside network. If you want
|
||||
that, you should set up Network Address Translation (NAT) rules on the
|
||||
host to rewrite container traffic to use your external IP address. This
|
||||
can be accomplished using the following configuration on the host:
|
||||
|
||||
```nix
|
||||
networking.nat.enable = true;
|
||||
networking.nat.internalInterfaces = ["ve-+"];
|
||||
networking.nat.externalInterface = "eth0";
|
||||
```
|
||||
|
||||
where `eth0` should be replaced with the desired external interface.
|
||||
Note that `ve-+` is a wildcard that matches all container interfaces.
|
||||
|
||||
If you are using Network Manager, you need to explicitly prevent it from
|
||||
managing container interfaces:
|
||||
|
||||
```nix
|
||||
networking.networkmanager.unmanaged = [ "interface-name:ve-*" ];
|
||||
```
|
||||
|
||||
You may need to restart your system for the changes to take effect.
|
||||
28
nixos/doc/manual/administration/containers.chapter.md
Normal file
28
nixos/doc/manual/administration/containers.chapter.md
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
# Container Management {#ch-containers}
|
||||
|
||||
NixOS allows you to easily run other NixOS instances as *containers*.
|
||||
Containers are a light-weight approach to virtualisation that runs
|
||||
software in the container at the same speed as in the host system. NixOS
|
||||
containers share the Nix store of the host, making container creation
|
||||
very efficient.
|
||||
|
||||
::: {.warning}
|
||||
Currently, NixOS containers are not perfectly isolated from the host
|
||||
system. This means that a user with root access to the container can do
|
||||
things that affect the host. So you should not give container root
|
||||
access to untrusted users.
|
||||
:::
|
||||
|
||||
NixOS containers can be created in two ways: imperatively, using the
|
||||
command `nixos-container`, and declaratively, by specifying them in your
|
||||
`configuration.nix`. The declarative approach implies that containers
|
||||
get upgraded along with your host system when you run `nixos-rebuild`,
|
||||
which is often not what you want. By contrast, in the imperative
|
||||
approach, containers are configured and updated independently from the
|
||||
host system.
|
||||
|
||||
```{=docbook}
|
||||
<xi:include href="imperative-containers.section.xml" />
|
||||
<xi:include href="declarative-containers.section.xml" />
|
||||
<xi:include href="container-networking.section.xml" />
|
||||
```
|
||||
59
nixos/doc/manual/administration/control-groups.chapter.md
Normal file
59
nixos/doc/manual/administration/control-groups.chapter.md
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
# Control Groups {#sec-cgroups}
|
||||
|
||||
To keep track of the processes in a running system, systemd uses
|
||||
*control groups* (cgroups). A control group is a set of processes used
|
||||
to allocate resources such as CPU, memory or I/O bandwidth. There can be
|
||||
multiple control group hierarchies, allowing each kind of resource to be
|
||||
managed independently.
|
||||
|
||||
The command `systemd-cgls` lists all control groups in the `systemd`
|
||||
hierarchy, which is what systemd uses to keep track of the processes
|
||||
belonging to each service or user session:
|
||||
|
||||
```ShellSession
|
||||
$ systemd-cgls
|
||||
├─user
|
||||
│ └─eelco
|
||||
│ └─c1
|
||||
│ ├─ 2567 -:0
|
||||
│ ├─ 2682 kdeinit4: kdeinit4 Running...
|
||||
│ ├─ ...
|
||||
│ └─10851 sh -c less -R
|
||||
└─system
|
||||
├─httpd.service
|
||||
│ ├─2444 httpd -f /nix/store/3pyacby5cpr55a03qwbnndizpciwq161-httpd.conf -DNO_DETACH
|
||||
│ └─...
|
||||
├─dhcpcd.service
|
||||
│ └─2376 dhcpcd --config /nix/store/f8dif8dsi2yaa70n03xir8r653776ka6-dhcpcd.conf
|
||||
└─ ...
|
||||
```
|
||||
|
||||
Similarly, `systemd-cgls cpu` shows the cgroups in the CPU hierarchy,
|
||||
which allows per-cgroup CPU scheduling priorities. By default, every
|
||||
systemd service gets its own CPU cgroup, while all user sessions are in
|
||||
the top-level CPU cgroup. This ensures, for instance, that a thousand
|
||||
run-away processes in the `httpd.service` cgroup cannot starve the CPU
|
||||
for one process in the `postgresql.service` cgroup. (By contrast, it
|
||||
they were in the same cgroup, then the PostgreSQL process would get
|
||||
1/1001 of the cgroup's CPU time.) You can limit a service's CPU share in
|
||||
`configuration.nix`:
|
||||
|
||||
```nix
|
||||
systemd.services.httpd.serviceConfig.CPUShares = 512;
|
||||
```
|
||||
|
||||
By default, every cgroup has 1024 CPU shares, so this will halve the CPU
|
||||
allocation of the `httpd.service` cgroup.
|
||||
|
||||
There also is a `memory` hierarchy that controls memory allocation
|
||||
limits; by default, all processes are in the top-level cgroup, so any
|
||||
service or session can exhaust all available memory. Per-cgroup memory
|
||||
limits can be specified in `configuration.nix`; for instance, to limit
|
||||
`httpd.service` to 512 MiB of RAM (excluding swap):
|
||||
|
||||
```nix
|
||||
systemd.services.httpd.serviceConfig.MemoryLimit = "512M";
|
||||
```
|
||||
|
||||
The command `systemd-cgtop` shows a continuously updated list of all
|
||||
cgroups with their CPU and memory usage.
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
# Declarative Container Specification {#sec-declarative-containers}
|
||||
|
||||
You can also specify containers and their configuration in the host's
|
||||
`configuration.nix`. For example, the following specifies that there
|
||||
shall be a container named `database` running PostgreSQL:
|
||||
|
||||
```nix
|
||||
containers.database =
|
||||
{ config =
|
||||
{ config, pkgs, ... }:
|
||||
{ services.postgresql.enable = true;
|
||||
services.postgresql.package = pkgs.postgresql_10;
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
If you run `nixos-rebuild switch`, the container will be built. If the
|
||||
container was already running, it will be updated in place, without
|
||||
rebooting. The container can be configured to start automatically by
|
||||
setting `containers.database.autoStart = true` in its configuration.
|
||||
|
||||
By default, declarative containers share the network namespace of the
|
||||
host, meaning that they can listen on (privileged) ports. However, they
|
||||
cannot change the network configuration. You can give a container its
|
||||
own network as follows:
|
||||
|
||||
```nix
|
||||
containers.database = {
|
||||
privateNetwork = true;
|
||||
hostAddress = "192.168.100.10";
|
||||
localAddress = "192.168.100.11";
|
||||
};
|
||||
```
|
||||
|
||||
This gives the container a private virtual Ethernet interface with IP
|
||||
address `192.168.100.11`, which is hooked up to a virtual Ethernet
|
||||
interface on the host with IP address `192.168.100.10`. (See the next
|
||||
section for details on container networking.)
|
||||
|
||||
To disable the container, just remove it from `configuration.nix` and
|
||||
run `nixos-rebuild
|
||||
switch`. Note that this will not delete the root directory of the
|
||||
container in `/var/lib/nixos-containers`. Containers can be destroyed using
|
||||
the imperative method: `nixos-container destroy foo`.
|
||||
|
||||
Declarative containers can be started and stopped using the
|
||||
corresponding systemd service, e.g.
|
||||
`systemctl start container@database`.
|
||||
115
nixos/doc/manual/administration/imperative-containers.section.md
Normal file
115
nixos/doc/manual/administration/imperative-containers.section.md
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
# Imperative Container Management {#sec-imperative-containers}
|
||||
|
||||
We'll cover imperative container management using `nixos-container`
|
||||
first. Be aware that container management is currently only possible as
|
||||
`root`.
|
||||
|
||||
You create a container with identifier `foo` as follows:
|
||||
|
||||
```ShellSession
|
||||
# nixos-container create foo
|
||||
```
|
||||
|
||||
This creates the container's root directory in `/var/lib/nixos-containers/foo`
|
||||
and a small configuration file in `/etc/nixos-containers/foo.conf`. It also
|
||||
builds the container's initial system configuration and stores it in
|
||||
`/nix/var/nix/profiles/per-container/foo/system`. You can modify the
|
||||
initial configuration of the container on the command line. For
|
||||
instance, to create a container that has `sshd` running, with the given
|
||||
public key for `root`:
|
||||
|
||||
```ShellSession
|
||||
# nixos-container create foo --config '
|
||||
services.openssh.enable = true;
|
||||
users.users.root.openssh.authorizedKeys.keys = ["ssh-dss AAAAB3N…"];
|
||||
'
|
||||
```
|
||||
|
||||
By default the next free address in the `10.233.0.0/16` subnet will be
|
||||
chosen as container IP. This behavior can be altered by setting
|
||||
`--host-address` and `--local-address`:
|
||||
|
||||
```ShellSession
|
||||
# nixos-container create test --config-file test-container.nix \
|
||||
--local-address 10.235.1.2 --host-address 10.235.1.1
|
||||
```
|
||||
|
||||
Creating a container does not start it. To start the container, run:
|
||||
|
||||
```ShellSession
|
||||
# nixos-container start foo
|
||||
```
|
||||
|
||||
This command will return as soon as the container has booted and has
|
||||
reached `multi-user.target`. On the host, the container runs within a
|
||||
systemd unit called `container@container-name.service`. Thus, if
|
||||
something went wrong, you can get status info using `systemctl`:
|
||||
|
||||
```ShellSession
|
||||
# systemctl status container@foo
|
||||
```
|
||||
|
||||
If the container has started successfully, you can log in as root using
|
||||
the `root-login` operation:
|
||||
|
||||
```ShellSession
|
||||
# nixos-container root-login foo
|
||||
[root@foo:~]#
|
||||
```
|
||||
|
||||
Note that only root on the host can do this (since there is no
|
||||
authentication). You can also get a regular login prompt using the
|
||||
`login` operation, which is available to all users on the host:
|
||||
|
||||
```ShellSession
|
||||
# nixos-container login foo
|
||||
foo login: alice
|
||||
Password: ***
|
||||
```
|
||||
|
||||
With `nixos-container run`, you can execute arbitrary commands in the
|
||||
container:
|
||||
|
||||
```ShellSession
|
||||
# nixos-container run foo -- uname -a
|
||||
Linux foo 3.4.82 #1-NixOS SMP Thu Mar 20 14:44:05 UTC 2014 x86_64 GNU/Linux
|
||||
```
|
||||
|
||||
There are several ways to change the configuration of the container.
|
||||
First, on the host, you can edit
|
||||
`/var/lib/container/name/etc/nixos/configuration.nix`, and run
|
||||
|
||||
```ShellSession
|
||||
# nixos-container update foo
|
||||
```
|
||||
|
||||
This will build and activate the new configuration. You can also specify
|
||||
a new configuration on the command line:
|
||||
|
||||
```ShellSession
|
||||
# nixos-container update foo --config '
|
||||
services.httpd.enable = true;
|
||||
services.httpd.adminAddr = "foo@example.org";
|
||||
networking.firewall.allowedTCPPorts = [ 80 ];
|
||||
'
|
||||
|
||||
# curl http://$(nixos-container show-ip foo)/
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">…
|
||||
```
|
||||
|
||||
However, note that this will overwrite the container's
|
||||
`/etc/nixos/configuration.nix`.
|
||||
|
||||
Alternatively, you can change the configuration from within the
|
||||
container itself by running `nixos-rebuild switch` inside the container.
|
||||
Note that the container by default does not have a copy of the NixOS
|
||||
channel, so you should run `nix-channel --update` first.
|
||||
|
||||
Containers can be stopped and started using `nixos-container
|
||||
stop` and `nixos-container start`, respectively, or by using
|
||||
`systemctl` on the container's service unit. To destroy a container,
|
||||
including its file system, do
|
||||
|
||||
```ShellSession
|
||||
# nixos-container destroy foo
|
||||
```
|
||||
38
nixos/doc/manual/administration/logging.chapter.md
Normal file
38
nixos/doc/manual/administration/logging.chapter.md
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
# Logging {#sec-logging}
|
||||
|
||||
System-wide logging is provided by systemd's *journal*, which subsumes
|
||||
traditional logging daemons such as syslogd and klogd. Log entries are
|
||||
kept in binary files in `/var/log/journal/`. The command `journalctl`
|
||||
allows you to see the contents of the journal. For example,
|
||||
|
||||
```ShellSession
|
||||
$ journalctl -b
|
||||
```
|
||||
|
||||
shows all journal entries since the last reboot. (The output of
|
||||
`journalctl` is piped into `less` by default.) You can use various
|
||||
options and match operators to restrict output to messages of interest.
|
||||
For instance, to get all messages from PostgreSQL:
|
||||
|
||||
```ShellSession
|
||||
$ journalctl -u postgresql.service
|
||||
-- Logs begin at Mon, 2013-01-07 13:28:01 CET, end at Tue, 2013-01-08 01:09:57 CET. --
|
||||
...
|
||||
Jan 07 15:44:14 hagbard postgres[2681]: [2-1] LOG: database system is shut down
|
||||
-- Reboot --
|
||||
Jan 07 15:45:10 hagbard postgres[2532]: [1-1] LOG: database system was shut down at 2013-01-07 15:44:14 CET
|
||||
Jan 07 15:45:13 hagbard postgres[2500]: [1-1] LOG: database system is ready to accept connections
|
||||
```
|
||||
|
||||
Or to get all messages since the last reboot that have at least a
|
||||
"critical" severity level:
|
||||
|
||||
```ShellSession
|
||||
$ journalctl -b -p crit
|
||||
Dec 17 21:08:06 mandark sudo[3673]: pam_unix(sudo:auth): auth could not identify password for [alice]
|
||||
Dec 29 01:30:22 mandark kernel[6131]: [1053513.909444] CPU6: Core temperature above threshold, cpu clock throttled (total events = 1)
|
||||
```
|
||||
|
||||
The system journal is readable by root and by users in the `wheel` and
|
||||
`systemd-journal` groups. All users have a private journal that can be
|
||||
read using `journalctl`.
|
||||
11
nixos/doc/manual/administration/maintenance-mode.section.md
Normal file
11
nixos/doc/manual/administration/maintenance-mode.section.md
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
# Maintenance Mode {#sec-maintenance-mode}
|
||||
|
||||
You can enter rescue mode by running:
|
||||
|
||||
```ShellSession
|
||||
# systemctl rescue
|
||||
```
|
||||
|
||||
This will eventually give you a single-user root shell. Systemd will
|
||||
stop (almost) all system services. To get out of maintenance mode, just
|
||||
exit from the rescue shell.
|
||||
21
nixos/doc/manual/administration/network-problems.section.md
Normal file
21
nixos/doc/manual/administration/network-problems.section.md
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
# Network Problems {#sec-nix-network-issues}
|
||||
|
||||
Nix uses a so-called *binary cache* to optimise building a package from
|
||||
source into downloading it as a pre-built binary. That is, whenever a
|
||||
command like `nixos-rebuild` needs a path in the Nix store, Nix will try
|
||||
to download that path from the Internet rather than build it from
|
||||
source. The default binary cache is `https://cache.nixos.org/`. If this
|
||||
cache is unreachable, Nix operations may take a long time due to HTTP
|
||||
connection timeouts. You can disable the use of the binary cache by
|
||||
adding `--option use-binary-caches false`, e.g.
|
||||
|
||||
```ShellSession
|
||||
# nixos-rebuild switch --option use-binary-caches false
|
||||
```
|
||||
|
||||
If you have an alternative binary cache at your disposal, you can use it
|
||||
instead:
|
||||
|
||||
```ShellSession
|
||||
# nixos-rebuild switch --option binary-caches http://my-cache.example.org/
|
||||
```
|
||||
30
nixos/doc/manual/administration/rebooting.chapter.md
Normal file
30
nixos/doc/manual/administration/rebooting.chapter.md
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
# Rebooting and Shutting Down {#sec-rebooting}
|
||||
|
||||
The system can be shut down (and automatically powered off) by doing:
|
||||
|
||||
```ShellSession
|
||||
# shutdown
|
||||
```
|
||||
|
||||
This is equivalent to running `systemctl poweroff`.
|
||||
|
||||
To reboot the system, run
|
||||
|
||||
```ShellSession
|
||||
# reboot
|
||||
```
|
||||
|
||||
which is equivalent to `systemctl reboot`. Alternatively, you can
|
||||
quickly reboot the system using `kexec`, which bypasses the BIOS by
|
||||
directly loading the new kernel into memory:
|
||||
|
||||
```ShellSession
|
||||
# systemctl kexec
|
||||
```
|
||||
|
||||
The machine can be suspended to RAM (if supported) using `systemctl suspend`,
|
||||
and suspended to disk using `systemctl hibernate`.
|
||||
|
||||
These commands can be run by any user who is logged in locally, i.e. on
|
||||
a virtual console or in X11; otherwise, the user is asked for
|
||||
authentication.
|
||||
38
nixos/doc/manual/administration/rollback.section.md
Normal file
38
nixos/doc/manual/administration/rollback.section.md
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
# Rolling Back Configuration Changes {#sec-rollback}
|
||||
|
||||
After running `nixos-rebuild` to switch to a new configuration, you may
|
||||
find that the new configuration doesn't work very well. In that case,
|
||||
there are several ways to return to a previous configuration.
|
||||
|
||||
First, the GRUB boot manager allows you to boot into any previous
|
||||
configuration that hasn't been garbage-collected. These configurations
|
||||
can be found under the GRUB submenu "NixOS - All configurations". This
|
||||
is especially useful if the new configuration fails to boot. After the
|
||||
system has booted, you can make the selected configuration the default
|
||||
for subsequent boots:
|
||||
|
||||
```ShellSession
|
||||
# /run/current-system/bin/switch-to-configuration boot
|
||||
```
|
||||
|
||||
Second, you can switch to the previous configuration in a running
|
||||
system:
|
||||
|
||||
```ShellSession
|
||||
# nixos-rebuild switch --rollback
|
||||
```
|
||||
|
||||
This is equivalent to running:
|
||||
|
||||
```ShellSession
|
||||
# /nix/var/nix/profiles/system-N-link/bin/switch-to-configuration switch
|
||||
```
|
||||
|
||||
where `N` is the number of the NixOS system configuration. To get a
|
||||
list of the available configurations, do:
|
||||
|
||||
```ShellSession
|
||||
$ ls -l /nix/var/nix/profiles/system-*-link
|
||||
...
|
||||
lrwxrwxrwx 1 root root 78 Aug 12 13:54 /nix/var/nix/profiles/system-268-link -> /nix/store/202b...-nixos-13.07pre4932_5a676e4-4be1055
|
||||
```
|
||||
21
nixos/doc/manual/administration/running.xml
Normal file
21
nixos/doc/manual/administration/running.xml
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<part xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
version="5.0"
|
||||
xml:id="ch-running">
|
||||
<title>Administration</title>
|
||||
<partintro xml:id="ch-running-intro">
|
||||
<para>
|
||||
This chapter describes various aspects of managing a running NixOS system,
|
||||
such as how to use the <command>systemd</command> service manager.
|
||||
</para>
|
||||
</partintro>
|
||||
<xi:include href="../from_md/administration/service-mgmt.chapter.xml" />
|
||||
<xi:include href="../from_md/administration/rebooting.chapter.xml" />
|
||||
<xi:include href="../from_md/administration/user-sessions.chapter.xml" />
|
||||
<xi:include href="../from_md/administration/control-groups.chapter.xml" />
|
||||
<xi:include href="../from_md/administration/logging.chapter.xml" />
|
||||
<xi:include href="../from_md/administration/cleaning-store.chapter.xml" />
|
||||
<xi:include href="../from_md/administration/containers.chapter.xml" />
|
||||
<xi:include href="../from_md/administration/troubleshooting.chapter.xml" />
|
||||
</part>
|
||||
120
nixos/doc/manual/administration/service-mgmt.chapter.md
Normal file
120
nixos/doc/manual/administration/service-mgmt.chapter.md
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
# Service Management {#sec-systemctl}
|
||||
|
||||
In NixOS, all system services are started and monitored using the
|
||||
systemd program. systemd is the "init" process of the system (i.e. PID
|
||||
1), the parent of all other processes. It manages a set of so-called
|
||||
"units", which can be things like system services (programs), but also
|
||||
mount points, swap files, devices, targets (groups of units) and more.
|
||||
Units can have complex dependencies; for instance, one unit can require
|
||||
that another unit must be successfully started before the first unit can
|
||||
be started. When the system boots, it starts a unit named
|
||||
`default.target`; the dependencies of this unit cause all system
|
||||
services to be started, file systems to be mounted, swap files to be
|
||||
activated, and so on.
|
||||
|
||||
## Interacting with a running systemd {#sect-nixos-systemd-general}
|
||||
|
||||
The command `systemctl` is the main way to interact with `systemd`. The
|
||||
following paragraphs demonstrate ways to interact with any OS running
|
||||
systemd as init system. NixOS is of no exception. The [next section
|
||||
](#sect-nixos-systemd-nixos) explains NixOS specific things worth
|
||||
knowing.
|
||||
|
||||
Without any arguments, `systemctl` the status of active units:
|
||||
|
||||
```ShellSession
|
||||
$ systemctl
|
||||
-.mount loaded active mounted /
|
||||
swapfile.swap loaded active active /swapfile
|
||||
sshd.service loaded active running SSH Daemon
|
||||
graphical.target loaded active active Graphical Interface
|
||||
...
|
||||
```
|
||||
|
||||
You can ask for detailed status information about a unit, for instance,
|
||||
the PostgreSQL database service:
|
||||
|
||||
```ShellSession
|
||||
$ systemctl status postgresql.service
|
||||
postgresql.service - PostgreSQL Server
|
||||
Loaded: loaded (/nix/store/pn3q73mvh75gsrl8w7fdlfk3fq5qm5mw-unit/postgresql.service)
|
||||
Active: active (running) since Mon, 2013-01-07 15:55:57 CET; 9h ago
|
||||
Main PID: 2390 (postgres)
|
||||
CGroup: name=systemd:/system/postgresql.service
|
||||
├─2390 postgres
|
||||
├─2418 postgres: writer process
|
||||
├─2419 postgres: wal writer process
|
||||
├─2420 postgres: autovacuum launcher process
|
||||
├─2421 postgres: stats collector process
|
||||
└─2498 postgres: zabbix zabbix [local] idle
|
||||
|
||||
Jan 07 15:55:55 hagbard postgres[2394]: [1-1] LOG: database system was shut down at 2013-01-07 15:55:05 CET
|
||||
Jan 07 15:55:57 hagbard postgres[2390]: [1-1] LOG: database system is ready to accept connections
|
||||
Jan 07 15:55:57 hagbard postgres[2420]: [1-1] LOG: autovacuum launcher started
|
||||
Jan 07 15:55:57 hagbard systemd[1]: Started PostgreSQL Server.
|
||||
```
|
||||
|
||||
Note that this shows the status of the unit (active and running), all
|
||||
the processes belonging to the service, as well as the most recent log
|
||||
messages from the service.
|
||||
|
||||
Units can be stopped, started or restarted:
|
||||
|
||||
```ShellSession
|
||||
# systemctl stop postgresql.service
|
||||
# systemctl start postgresql.service
|
||||
# systemctl restart postgresql.service
|
||||
```
|
||||
|
||||
These operations are synchronous: they wait until the service has
|
||||
finished starting or stopping (or has failed). Starting a unit will
|
||||
cause the dependencies of that unit to be started as well (if
|
||||
necessary).
|
||||
|
||||
## systemd in NixOS {#sect-nixos-systemd-nixos}
|
||||
|
||||
Packages in Nixpkgs sometimes provide systemd units with them, usually
|
||||
in e.g `#pkg-out#/lib/systemd/`. Putting such a package in
|
||||
`environment.systemPackages` doesn\'t make the service available to
|
||||
users or the system.
|
||||
|
||||
In order to enable a systemd *system* service with provided upstream
|
||||
package, use (e.g):
|
||||
|
||||
```nix
|
||||
systemd.packages = [ pkgs.packagekit ];
|
||||
```
|
||||
|
||||
Usually NixOS modules written by the community do the above, plus take
|
||||
care of other details. If a module was written for a service you are
|
||||
interested in, you\'d probably need only to use
|
||||
`services.#name#.enable = true;`. These services are defined in
|
||||
Nixpkgs\' [ `nixos/modules/` directory
|
||||
](https://github.com/NixOS/nixpkgs/tree/master/nixos/modules). In case
|
||||
the service is simple enough, the above method should work, and start
|
||||
the service on boot.
|
||||
|
||||
*User* systemd services on the other hand, should be treated
|
||||
differently. Given a package that has a systemd unit file at
|
||||
`#pkg-out#/lib/systemd/user/`, using [](#opt-systemd.packages) will
|
||||
make you able to start the service via `systemctl --user start`, but it
|
||||
won\'t start automatically on login. However, You can imperatively
|
||||
enable it by adding the package\'s attribute to
|
||||
[](#opt-systemd.packages) and then do this (e.g):
|
||||
|
||||
```ShellSession
|
||||
$ mkdir -p ~/.config/systemd/user/default.target.wants
|
||||
$ ln -s /run/current-system/sw/lib/systemd/user/syncthing.service ~/.config/systemd/user/default.target.wants/
|
||||
$ systemctl --user daemon-reload
|
||||
$ systemctl --user enable syncthing.service
|
||||
```
|
||||
|
||||
If you are interested in a timer file, use `timers.target.wants` instead
|
||||
of `default.target.wants` in the 1st and 2nd command.
|
||||
|
||||
Using `systemctl --user enable syncthing.service` instead of the above,
|
||||
will work, but it\'ll use the absolute path of `syncthing.service` for
|
||||
the symlink, and this path is in `/nix/store/.../lib/systemd/user/`.
|
||||
Hence [garbage collection](#sec-nix-gc) will remove that file and you
|
||||
will wind up with a broken symlink in your systemd configuration, which
|
||||
in turn will not make the service / timer start on login.
|
||||
28
nixos/doc/manual/administration/store-corruption.section.md
Normal file
28
nixos/doc/manual/administration/store-corruption.section.md
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
# Nix Store Corruption {#sec-nix-store-corruption}
|
||||
|
||||
After a system crash, it's possible for files in the Nix store to become
|
||||
corrupted. (For instance, the Ext4 file system has the tendency to
|
||||
replace un-synced files with zero bytes.) NixOS tries hard to prevent
|
||||
this from happening: it performs a `sync` before switching to a new
|
||||
configuration, and Nix's database is fully transactional. If corruption
|
||||
still occurs, you may be able to fix it automatically.
|
||||
|
||||
If the corruption is in a path in the closure of the NixOS system
|
||||
configuration, you can fix it by doing
|
||||
|
||||
```ShellSession
|
||||
# nixos-rebuild switch --repair
|
||||
```
|
||||
|
||||
This will cause Nix to check every path in the closure, and if its
|
||||
cryptographic hash differs from the hash recorded in Nix's database, the
|
||||
path is rebuilt or redownloaded.
|
||||
|
||||
You can also scan the entire Nix store for corrupt paths:
|
||||
|
||||
```ShellSession
|
||||
# nix-store --verify --check-contents --repair
|
||||
```
|
||||
|
||||
Any corrupt paths will be redownloaded if they're available in a binary
|
||||
cache; otherwise, they cannot be repaired.
|
||||
12
nixos/doc/manual/administration/troubleshooting.chapter.md
Normal file
12
nixos/doc/manual/administration/troubleshooting.chapter.md
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
# Troubleshooting {#ch-troubleshooting}
|
||||
|
||||
This chapter describes solutions to common problems you might encounter
|
||||
when you manage your NixOS system.
|
||||
|
||||
```{=docbook}
|
||||
<xi:include href="boot-problems.section.xml" />
|
||||
<xi:include href="maintenance-mode.section.xml" />
|
||||
<xi:include href="rollback.section.xml" />
|
||||
<xi:include href="store-corruption.section.xml" />
|
||||
<xi:include href="network-problems.section.xml" />
|
||||
```
|
||||
43
nixos/doc/manual/administration/user-sessions.chapter.md
Normal file
43
nixos/doc/manual/administration/user-sessions.chapter.md
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
# User Sessions {#sec-user-sessions}
|
||||
|
||||
Systemd keeps track of all users who are logged into the system (e.g. on
|
||||
a virtual console or remotely via SSH). The command `loginctl` allows
|
||||
querying and manipulating user sessions. For instance, to list all user
|
||||
sessions:
|
||||
|
||||
```ShellSession
|
||||
$ loginctl
|
||||
SESSION UID USER SEAT
|
||||
c1 500 eelco seat0
|
||||
c3 0 root seat0
|
||||
c4 500 alice
|
||||
```
|
||||
|
||||
This shows that two users are logged in locally, while another is logged
|
||||
in remotely. ("Seats" are essentially the combinations of displays and
|
||||
input devices attached to the system; usually, there is only one seat.)
|
||||
To get information about a session:
|
||||
|
||||
```ShellSession
|
||||
$ loginctl session-status c3
|
||||
c3 - root (0)
|
||||
Since: Tue, 2013-01-08 01:17:56 CET; 4min 42s ago
|
||||
Leader: 2536 (login)
|
||||
Seat: seat0; vc3
|
||||
TTY: /dev/tty3
|
||||
Service: login; type tty; class user
|
||||
State: online
|
||||
CGroup: name=systemd:/user/root/c3
|
||||
├─ 2536 /nix/store/10mn4xip9n7y9bxqwnsx7xwx2v2g34xn-shadow-4.1.5.1/bin/login --
|
||||
├─10339 -bash
|
||||
└─10355 w3m nixos.org
|
||||
```
|
||||
|
||||
This shows that the user is logged in on virtual console 3. It also
|
||||
lists the processes belonging to this session. Since systemd keeps track
|
||||
of this, you can terminate a session in a way that ensures that all the
|
||||
session's processes are gone:
|
||||
|
||||
```ShellSession
|
||||
# loginctl terminate-session c3
|
||||
```
|
||||
80
nixos/doc/manual/configuration/abstractions.section.md
Normal file
80
nixos/doc/manual/configuration/abstractions.section.md
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
# Abstractions {#sec-module-abstractions}
|
||||
|
||||
If you find yourself repeating yourself over and over, it’s time to abstract. Take, for instance, this Apache HTTP Server configuration:
|
||||
|
||||
```nix
|
||||
{
|
||||
services.httpd.virtualHosts =
|
||||
{ "blog.example.org" = {
|
||||
documentRoot = "/webroot/blog.example.org";
|
||||
adminAddr = "alice@example.org";
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
enablePHP = true;
|
||||
};
|
||||
"wiki.example.org" = {
|
||||
documentRoot = "/webroot/wiki.example.org";
|
||||
adminAddr = "alice@example.org";
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
enablePHP = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
It defines two virtual hosts with nearly identical configuration; the only difference is the document root directories. To prevent this duplication, we can use a `let`:
|
||||
```nix
|
||||
let
|
||||
commonConfig =
|
||||
{ adminAddr = "alice@example.org";
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
};
|
||||
in
|
||||
{
|
||||
services.httpd.virtualHosts =
|
||||
{ "blog.example.org" = (commonConfig // { documentRoot = "/webroot/blog.example.org"; });
|
||||
"wiki.example.org" = (commonConfig // { documentRoot = "/webroot/wiki.example.com"; });
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
The `let commonConfig = ...` defines a variable named `commonConfig`. The `//` operator merges two attribute sets, so the configuration of the second virtual host is the set `commonConfig` extended with the document root option.
|
||||
|
||||
You can write a `let` wherever an expression is allowed. Thus, you also could have written:
|
||||
|
||||
```nix
|
||||
{
|
||||
services.httpd.virtualHosts =
|
||||
let commonConfig = ...; in
|
||||
{ "blog.example.org" = (commonConfig // { ... })
|
||||
"wiki.example.org" = (commonConfig // { ... })
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
but not `{ let commonConfig = ...; in ...; }` since attributes (as opposed to attribute values) are not expressions.
|
||||
|
||||
**Functions** provide another method of abstraction. For instance, suppose that we want to generate lots of different virtual hosts, all with identical configuration except for the document root. This can be done as follows:
|
||||
|
||||
```nix
|
||||
{
|
||||
services.httpd.virtualHosts =
|
||||
let
|
||||
makeVirtualHost = webroot:
|
||||
{ documentRoot = webroot;
|
||||
adminAddr = "alice@example.org";
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
};
|
||||
in
|
||||
{ "example.org" = (makeVirtualHost "/webroot/example.org");
|
||||
"example.com" = (makeVirtualHost "/webroot/example.com");
|
||||
"example.gov" = (makeVirtualHost "/webroot/example.gov");
|
||||
"example.nl" = (makeVirtualHost "/webroot/example.nl");
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Here, `makeVirtualHost` is a function that takes a single argument `webroot` and returns the configuration for a virtual host. That function is then called for several names to produce the list of virtual host configurations.
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
# Ad-Hoc Configuration {#ad-hoc-network-config}
|
||||
|
||||
You can use [](#opt-networking.localCommands) to
|
||||
specify shell commands to be run at the end of `network-setup.service`. This
|
||||
is useful for doing network configuration not covered by the existing NixOS
|
||||
modules. For instance, to statically configure an IPv6 address:
|
||||
|
||||
```nix
|
||||
networking.localCommands =
|
||||
''
|
||||
ip -6 addr add 2001:610:685:1::1/64 dev eth0
|
||||
'';
|
||||
```
|
||||
51
nixos/doc/manual/configuration/ad-hoc-packages.section.md
Normal file
51
nixos/doc/manual/configuration/ad-hoc-packages.section.md
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
# Ad-Hoc Package Management {#sec-ad-hoc-packages}
|
||||
|
||||
With the command `nix-env`, you can install and uninstall packages from
|
||||
the command line. For instance, to install Mozilla Thunderbird:
|
||||
|
||||
```ShellSession
|
||||
$ nix-env -iA nixos.thunderbird
|
||||
```
|
||||
|
||||
If you invoke this as root, the package is installed in the Nix profile
|
||||
`/nix/var/nix/profiles/default` and visible to all users of the system;
|
||||
otherwise, the package ends up in
|
||||
`/nix/var/nix/profiles/per-user/username/profile` and is not visible to
|
||||
other users. The `-A` flag specifies the package by its attribute name;
|
||||
without it, the package is installed by matching against its package
|
||||
name (e.g. `thunderbird`). The latter is slower because it requires
|
||||
matching against all available Nix packages, and is ambiguous if there
|
||||
are multiple matching packages.
|
||||
|
||||
Packages come from the NixOS channel. You typically upgrade a package by
|
||||
updating to the latest version of the NixOS channel:
|
||||
|
||||
```ShellSession
|
||||
$ nix-channel --update nixos
|
||||
```
|
||||
|
||||
and then running `nix-env -i` again. Other packages in the profile are
|
||||
*not* affected; this is the crucial difference with the declarative
|
||||
style of package management, where running `nixos-rebuild switch` causes
|
||||
all packages to be updated to their current versions in the NixOS
|
||||
channel. You can however upgrade all packages for which there is a newer
|
||||
version by doing:
|
||||
|
||||
```ShellSession
|
||||
$ nix-env -u '*'
|
||||
```
|
||||
|
||||
A package can be uninstalled using the `-e` flag:
|
||||
|
||||
```ShellSession
|
||||
$ nix-env -e thunderbird
|
||||
```
|
||||
|
||||
Finally, you can roll back an undesirable `nix-env` action:
|
||||
|
||||
```ShellSession
|
||||
$ nix-env --rollback
|
||||
```
|
||||
|
||||
`nix-env` has many more flags. For details, see the nix-env(1) manpage or
|
||||
the Nix manual.
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
# Adding Custom Packages {#sec-custom-packages}
|
||||
|
||||
It's possible that a package you need is not available in NixOS. In that
|
||||
case, you can do two things. First, you can clone the Nixpkgs
|
||||
repository, add the package to your clone, and (optionally) submit a
|
||||
patch or pull request to have it accepted into the main Nixpkgs repository.
|
||||
This is described in detail in the [Nixpkgs manual](https://nixos.org/nixpkgs/manual).
|
||||
In short, you clone Nixpkgs:
|
||||
|
||||
```ShellSession
|
||||
$ git clone https://github.com/NixOS/nixpkgs
|
||||
$ cd nixpkgs
|
||||
```
|
||||
|
||||
Then you write and test the package as described in the Nixpkgs manual.
|
||||
Finally, you add it to [](#opt-environment.systemPackages), e.g.
|
||||
|
||||
```nix
|
||||
environment.systemPackages = [ pkgs.my-package ];
|
||||
```
|
||||
|
||||
and you run `nixos-rebuild`, specifying your own Nixpkgs tree:
|
||||
|
||||
```ShellSession
|
||||
# nixos-rebuild switch -I nixpkgs=/path/to/my/nixpkgs
|
||||
```
|
||||
|
||||
The second possibility is to add the package outside of the Nixpkgs
|
||||
tree. For instance, here is how you specify a build of the
|
||||
[GNU Hello](https://www.gnu.org/software/hello/) package directly in
|
||||
`configuration.nix`:
|
||||
|
||||
```nix
|
||||
environment.systemPackages =
|
||||
let
|
||||
my-hello = with pkgs; stdenv.mkDerivation rec {
|
||||
name = "hello-2.8";
|
||||
src = fetchurl {
|
||||
url = "mirror://gnu/hello/${name}.tar.gz";
|
||||
sha256 = "0wqd8sjmxfskrflaxywc7gqw7sfawrfvdxd9skxawzfgyy0pzdz6";
|
||||
};
|
||||
};
|
||||
in
|
||||
[ my-hello ];
|
||||
```
|
||||
|
||||
Of course, you can also move the definition of `my-hello` into a
|
||||
separate Nix expression, e.g.
|
||||
|
||||
```nix
|
||||
environment.systemPackages = [ (import ./my-hello.nix) ];
|
||||
```
|
||||
|
||||
where `my-hello.nix` contains:
|
||||
|
||||
```nix
|
||||
with import <nixpkgs> {}; # bring all of Nixpkgs into scope
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
name = "hello-2.8";
|
||||
src = fetchurl {
|
||||
url = "mirror://gnu/hello/${name}.tar.gz";
|
||||
sha256 = "0wqd8sjmxfskrflaxywc7gqw7sfawrfvdxd9skxawzfgyy0pzdz6";
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
This allows testing the package easily:
|
||||
|
||||
```ShellSession
|
||||
$ nix-build my-hello.nix
|
||||
$ ./result/bin/hello
|
||||
Hello, world!
|
||||
```
|
||||
175
nixos/doc/manual/configuration/config-file.section.md
Normal file
175
nixos/doc/manual/configuration/config-file.section.md
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
# NixOS Configuration File {#sec-configuration-file}
|
||||
|
||||
The NixOS configuration file generally looks like this:
|
||||
|
||||
```nix
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
{ option definitions
|
||||
}
|
||||
```
|
||||
|
||||
The first line (`{ config, pkgs, ... }:`) denotes that this is actually
|
||||
a function that takes at least the two arguments `config` and `pkgs`.
|
||||
(These are explained later, in chapter [](#sec-writing-modules)) The
|
||||
function returns a *set* of option definitions (`{ ... }`).
|
||||
These definitions have the form `name = value`, where `name` is the
|
||||
name of an option and `value` is its value. For example,
|
||||
|
||||
```nix
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
{ services.httpd.enable = true;
|
||||
services.httpd.adminAddr = "alice@example.org";
|
||||
services.httpd.virtualHosts.localhost.documentRoot = "/webroot";
|
||||
}
|
||||
```
|
||||
|
||||
defines a configuration with three option definitions that together
|
||||
enable the Apache HTTP Server with `/webroot` as the document root.
|
||||
|
||||
Sets can be nested, and in fact dots in option names are shorthand for
|
||||
defining a set containing another set. For instance,
|
||||
[](#opt-services.httpd.enable) defines a set named
|
||||
`services` that contains a set named `httpd`, which in turn contains an
|
||||
option definition named `enable` with value `true`. This means that the
|
||||
example above can also be written as:
|
||||
|
||||
```nix
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
{ services = {
|
||||
httpd = {
|
||||
enable = true;
|
||||
adminAddr = "alice@example.org";
|
||||
virtualHosts = {
|
||||
localhost = {
|
||||
documentRoot = "/webroot";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
which may be more convenient if you have lots of option definitions that
|
||||
share the same prefix (such as `services.httpd`).
|
||||
|
||||
NixOS checks your option definitions for correctness. For instance, if
|
||||
you try to define an option that doesn't exist (that is, doesn't have a
|
||||
corresponding *option declaration*), `nixos-rebuild` will give an error
|
||||
like:
|
||||
|
||||
```plain
|
||||
The option `services.httpd.enable' defined in `/etc/nixos/configuration.nix' does not exist.
|
||||
```
|
||||
|
||||
Likewise, values in option definitions must have a correct type. For
|
||||
instance, `services.httpd.enable` must be a Boolean (`true` or `false`).
|
||||
Trying to give it a value of another type, such as a string, will cause
|
||||
an error:
|
||||
|
||||
```plain
|
||||
The option value `services.httpd.enable' in `/etc/nixos/configuration.nix' is not a boolean.
|
||||
```
|
||||
|
||||
Options have various types of values. The most important are:
|
||||
|
||||
Strings
|
||||
|
||||
: Strings are enclosed in double quotes, e.g.
|
||||
|
||||
```nix
|
||||
networking.hostName = "dexter";
|
||||
```
|
||||
|
||||
Special characters can be escaped by prefixing them with a backslash
|
||||
(e.g. `\"`).
|
||||
|
||||
Multi-line strings can be enclosed in *double single quotes*, e.g.
|
||||
|
||||
```nix
|
||||
networking.extraHosts =
|
||||
''
|
||||
127.0.0.2 other-localhost
|
||||
10.0.0.1 server
|
||||
'';
|
||||
```
|
||||
|
||||
The main difference is that it strips from each line a number of
|
||||
spaces equal to the minimal indentation of the string as a whole
|
||||
(disregarding the indentation of empty lines), and that characters
|
||||
like `"` and `\` are not special (making it more convenient for
|
||||
including things like shell code). See more info about this in the
|
||||
Nix manual [here](https://nixos.org/nix/manual/#ssec-values).
|
||||
|
||||
Booleans
|
||||
|
||||
: These can be `true` or `false`, e.g.
|
||||
|
||||
```nix
|
||||
networking.firewall.enable = true;
|
||||
networking.firewall.allowPing = false;
|
||||
```
|
||||
|
||||
Integers
|
||||
|
||||
: For example,
|
||||
|
||||
```nix
|
||||
boot.kernel.sysctl."net.ipv4.tcp_keepalive_time" = 60;
|
||||
```
|
||||
|
||||
(Note that here the attribute name `net.ipv4.tcp_keepalive_time` is
|
||||
enclosed in quotes to prevent it from being interpreted as a set
|
||||
named `net` containing a set named `ipv4`, and so on. This is
|
||||
because it's not a NixOS option but the literal name of a Linux
|
||||
kernel setting.)
|
||||
|
||||
Sets
|
||||
|
||||
: Sets were introduced above. They are name/value pairs enclosed in
|
||||
braces, as in the option definition
|
||||
|
||||
```nix
|
||||
fileSystems."/boot" =
|
||||
{ device = "/dev/sda1";
|
||||
fsType = "ext4";
|
||||
options = [ "rw" "data=ordered" "relatime" ];
|
||||
};
|
||||
```
|
||||
|
||||
Lists
|
||||
|
||||
: The important thing to note about lists is that list elements are
|
||||
separated by whitespace, like this:
|
||||
|
||||
```nix
|
||||
boot.kernelModules = [ "fuse" "kvm-intel" "coretemp" ];
|
||||
```
|
||||
|
||||
List elements can be any other type, e.g. sets:
|
||||
|
||||
```nix
|
||||
swapDevices = [ { device = "/dev/disk/by-label/swap"; } ];
|
||||
```
|
||||
|
||||
Packages
|
||||
|
||||
: Usually, the packages you need are already part of the Nix Packages
|
||||
collection, which is a set that can be accessed through the function
|
||||
argument `pkgs`. Typical uses:
|
||||
|
||||
```nix
|
||||
environment.systemPackages =
|
||||
[ pkgs.thunderbird
|
||||
pkgs.emacs
|
||||
];
|
||||
|
||||
services.postgresql.package = pkgs.postgresql_10;
|
||||
```
|
||||
|
||||
The latter option definition changes the default PostgreSQL package
|
||||
used by NixOS's PostgreSQL service to 10.x. For more information on
|
||||
packages, including how to add new ones, see
|
||||
[](#sec-custom-packages).
|
||||
19
nixos/doc/manual/configuration/config-syntax.chapter.md
Normal file
19
nixos/doc/manual/configuration/config-syntax.chapter.md
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# Configuration Syntax {#sec-configuration-syntax}
|
||||
|
||||
The NixOS configuration file `/etc/nixos/configuration.nix` is actually
|
||||
a *Nix expression*, which is the Nix package manager's purely functional
|
||||
language for describing how to build packages and configurations. This
|
||||
means you have all the expressive power of that language at your
|
||||
disposal, including the ability to abstract over common patterns, which
|
||||
is very useful when managing complex systems. The syntax and semantics
|
||||
of the Nix language are fully described in the [Nix
|
||||
manual](https://nixos.org/nix/manual/#chap-writing-nix-expressions), but
|
||||
here we give a short overview of the most important constructs useful in
|
||||
NixOS configuration files.
|
||||
|
||||
```{=docbook}
|
||||
<xi:include href="config-file.section.xml" />
|
||||
<xi:include href="abstractions.section.xml" />
|
||||
<xi:include href="modularity.section.xml" />
|
||||
<xi:include href="summary.section.xml" />
|
||||
```
|
||||
31
nixos/doc/manual/configuration/configuration.xml
Normal file
31
nixos/doc/manual/configuration/configuration.xml
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<part xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
version="5.0"
|
||||
xml:id="ch-configuration">
|
||||
<title>Configuration</title>
|
||||
<partintro xml:id="ch-configuration-intro">
|
||||
<para>
|
||||
This chapter describes how to configure various aspects of a NixOS machine
|
||||
through the configuration file
|
||||
<filename>/etc/nixos/configuration.nix</filename>. As described in
|
||||
<xref linkend="sec-changing-config" />, changes to this file only take
|
||||
effect after you run <command>nixos-rebuild</command>.
|
||||
</para>
|
||||
</partintro>
|
||||
<xi:include href="../from_md/configuration/config-syntax.chapter.xml" />
|
||||
<xi:include href="../from_md/configuration/package-mgmt.chapter.xml" />
|
||||
<xi:include href="../from_md/configuration/user-mgmt.chapter.xml" />
|
||||
<xi:include href="../from_md/configuration/file-systems.chapter.xml" />
|
||||
<xi:include href="../from_md/configuration/x-windows.chapter.xml" />
|
||||
<xi:include href="../from_md/configuration/wayland.chapter.xml" />
|
||||
<xi:include href="../from_md/configuration/gpu-accel.chapter.xml" />
|
||||
<xi:include href="../from_md/configuration/xfce.chapter.xml" />
|
||||
<xi:include href="../from_md/configuration/networking.chapter.xml" />
|
||||
<xi:include href="../from_md/configuration/linux-kernel.chapter.xml" />
|
||||
<xi:include href="../from_md/configuration/subversion.chapter.xml" />
|
||||
<xi:include href="../generated/modules.xml" xpointer="xpointer(//section[@id='modules']/*)" />
|
||||
<xi:include href="../from_md/configuration/profiles.chapter.xml" />
|
||||
<xi:include href="../from_md/configuration/kubernetes.chapter.xml" />
|
||||
<!-- Apache; libvirtd virtualisation -->
|
||||
</part>
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
# Customising Packages {#sec-customising-packages}
|
||||
|
||||
Some packages in Nixpkgs have options to enable or disable optional
|
||||
functionality or change other aspects of the package. For instance, the
|
||||
Firefox wrapper package (which provides Firefox with a set of plugins
|
||||
such as the Adobe Flash player) has an option to enable the Google Talk
|
||||
plugin. It can be set in `configuration.nix` as follows:
|
||||
`nixpkgs.config.firefox.enableGoogleTalkPlugin = true;`
|
||||
|
||||
::: {.warning}
|
||||
Unfortunately, Nixpkgs currently lacks a way to query available
|
||||
configuration options.
|
||||
:::
|
||||
|
||||
Apart from high-level options, it's possible to tweak a package in
|
||||
almost arbitrary ways, such as changing or disabling dependencies of a
|
||||
package. For instance, the Emacs package in Nixpkgs by default has a
|
||||
dependency on GTK 2. If you want to build it against GTK 3, you can
|
||||
specify that as follows:
|
||||
|
||||
```nix
|
||||
environment.systemPackages = [ (pkgs.emacs.override { gtk = pkgs.gtk3; }) ];
|
||||
```
|
||||
|
||||
The function `override` performs the call to the Nix function that
|
||||
produces Emacs, with the original arguments amended by the set of
|
||||
arguments specified by you. So here the function argument `gtk` gets the
|
||||
value `pkgs.gtk3`, causing Emacs to depend on GTK 3. (The parentheses
|
||||
are necessary because in Nix, function application binds more weakly
|
||||
than list construction, so without them,
|
||||
[](#opt-environment.systemPackages)
|
||||
would be a list with two elements.)
|
||||
|
||||
Even greater customisation is possible using the function
|
||||
`overrideAttrs`. While the `override` mechanism above overrides the
|
||||
arguments of a package function, `overrideAttrs` allows changing the
|
||||
*attributes* passed to `mkDerivation`. This permits changing any aspect
|
||||
of the package, such as the source code. For instance, if you want to
|
||||
override the source code of Emacs, you can say:
|
||||
|
||||
```nix
|
||||
environment.systemPackages = [
|
||||
(pkgs.emacs.overrideAttrs (oldAttrs: {
|
||||
name = "emacs-25.0-pre";
|
||||
src = /path/to/my/emacs/tree;
|
||||
}))
|
||||
];
|
||||
```
|
||||
|
||||
Here, `overrideAttrs` takes the Nix derivation specified by `pkgs.emacs`
|
||||
and produces a new derivation in which the original's `name` and `src`
|
||||
attribute have been replaced by the given values by re-calling
|
||||
`stdenv.mkDerivation`. The original attributes are accessible via the
|
||||
function argument, which is conventionally named `oldAttrs`.
|
||||
|
||||
The overrides shown above are not global. They do not affect the
|
||||
original package; other packages in Nixpkgs continue to depend on the
|
||||
original rather than the customised package. This means that if another
|
||||
package in your system depends on the original package, you end up with
|
||||
two instances of the package. If you want to have everything depend on
|
||||
your customised instance, you can apply a *global* override as follows:
|
||||
|
||||
```nix
|
||||
nixpkgs.config.packageOverrides = pkgs:
|
||||
{ emacs = pkgs.emacs.override { gtk = pkgs.gtk3; };
|
||||
};
|
||||
```
|
||||
|
||||
The effect of this definition is essentially equivalent to modifying the
|
||||
`emacs` attribute in the Nixpkgs source tree. Any package in Nixpkgs
|
||||
that depends on `emacs` will be passed your customised instance.
|
||||
(However, the value `pkgs.emacs` in `nixpkgs.config.packageOverrides`
|
||||
refers to the original rather than overridden instance, to prevent an
|
||||
infinite recursion.)
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
# Declarative Package Management {#sec-declarative-package-mgmt}
|
||||
|
||||
With declarative package management, you specify which packages you want
|
||||
on your system by setting the option
|
||||
[](#opt-environment.systemPackages). For instance, adding the
|
||||
following line to `configuration.nix` enables the Mozilla Thunderbird
|
||||
email application:
|
||||
|
||||
```nix
|
||||
environment.systemPackages = [ pkgs.thunderbird ];
|
||||
```
|
||||
|
||||
The effect of this specification is that the Thunderbird package from
|
||||
Nixpkgs will be built or downloaded as part of the system when you run
|
||||
`nixos-rebuild switch`.
|
||||
|
||||
::: {.note}
|
||||
Some packages require additional global configuration such as D-Bus or
|
||||
systemd service registration so adding them to
|
||||
[](#opt-environment.systemPackages) might not be sufficient. You are
|
||||
advised to check the [list of options](#ch-options) whether a NixOS
|
||||
module for the package does not exist.
|
||||
:::
|
||||
|
||||
You can get a list of the available packages as follows:
|
||||
|
||||
```ShellSession
|
||||
$ nix-env -qaP '*' --description
|
||||
nixos.firefox firefox-23.0 Mozilla Firefox - the browser, reloaded
|
||||
...
|
||||
```
|
||||
|
||||
The first column in the output is the *attribute name*, such as
|
||||
`nixos.thunderbird`.
|
||||
|
||||
Note: the `nixos` prefix tells us that we want to get the package from
|
||||
the `nixos` channel and works only in CLI tools. In declarative
|
||||
configuration use `pkgs` prefix (variable).
|
||||
|
||||
To "uninstall" a package, simply remove it from
|
||||
[](#opt-environment.systemPackages) and run `nixos-rebuild switch`.
|
||||
|
||||
```{=docbook}
|
||||
<xi:include href="customizing-packages.section.xml" />
|
||||
<xi:include href="adding-custom-packages.section.xml" />
|
||||
```
|
||||
42
nixos/doc/manual/configuration/file-systems.chapter.md
Normal file
42
nixos/doc/manual/configuration/file-systems.chapter.md
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
# File Systems {#ch-file-systems}
|
||||
|
||||
You can define file systems using the `fileSystems` configuration
|
||||
option. For instance, the following definition causes NixOS to mount the
|
||||
Ext4 file system on device `/dev/disk/by-label/data` onto the mount
|
||||
point `/data`:
|
||||
|
||||
```nix
|
||||
fileSystems."/data" =
|
||||
{ device = "/dev/disk/by-label/data";
|
||||
fsType = "ext4";
|
||||
};
|
||||
```
|
||||
|
||||
This will create an entry in `/etc/fstab`, which will generate a
|
||||
corresponding [systemd.mount](https://www.freedesktop.org/software/systemd/man/systemd.mount.html)
|
||||
unit via [systemd-fstab-generator](https://www.freedesktop.org/software/systemd/man/systemd-fstab-generator.html).
|
||||
The filesystem will be mounted automatically unless `"noauto"` is
|
||||
present in [options](#opt-fileSystems._name_.options). `"noauto"`
|
||||
filesystems can be mounted explicitly using `systemctl` e.g.
|
||||
`systemctl start data.mount`. Mount points are created automatically if they don't
|
||||
already exist. For `device`, it's best to use the topology-independent
|
||||
device aliases in `/dev/disk/by-label` and `/dev/disk/by-uuid`, as these
|
||||
don't change if the topology changes (e.g. if a disk is moved to another
|
||||
IDE controller).
|
||||
|
||||
You can usually omit the file system type (`fsType`), since `mount` can
|
||||
usually detect the type and load the necessary kernel module
|
||||
automatically. However, if the file system is needed at early boot (in
|
||||
the initial ramdisk) and is not `ext2`, `ext3` or `ext4`, then it's best
|
||||
to specify `fsType` to ensure that the kernel module is available.
|
||||
|
||||
::: {.note}
|
||||
System startup will fail if any of the filesystems fails to mount,
|
||||
dropping you to the emergency shell. You can make a mount asynchronous
|
||||
and non-critical by adding `options = [ "nofail" ];`.
|
||||
:::
|
||||
|
||||
```{=docbook}
|
||||
<xi:include href="luks-file-systems.section.xml" />
|
||||
<xi:include href="sshfs-file-systems.section.xml" />
|
||||
```
|
||||
32
nixos/doc/manual/configuration/firewall.section.md
Normal file
32
nixos/doc/manual/configuration/firewall.section.md
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
# Firewall {#sec-firewall}
|
||||
|
||||
NixOS has a simple stateful firewall that blocks incoming connections
|
||||
and other unexpected packets. The firewall applies to both IPv4 and IPv6
|
||||
traffic. It is enabled by default. It can be disabled as follows:
|
||||
|
||||
```nix
|
||||
networking.firewall.enable = false;
|
||||
```
|
||||
|
||||
If the firewall is enabled, you can open specific TCP ports to the
|
||||
outside world:
|
||||
|
||||
```nix
|
||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||
```
|
||||
|
||||
Note that TCP port 22 (ssh) is opened automatically if the SSH daemon is
|
||||
enabled (`services.openssh.enable = true`). UDP ports can be opened through
|
||||
[](#opt-networking.firewall.allowedUDPPorts).
|
||||
|
||||
To open ranges of TCP ports:
|
||||
|
||||
```nix
|
||||
networking.firewall.allowedTCPPortRanges = [
|
||||
{ from = 4000; to = 4007; }
|
||||
{ from = 8000; to = 8010; }
|
||||
];
|
||||
```
|
||||
|
||||
Similarly, UDP port ranges can be opened through
|
||||
[](#opt-networking.firewall.allowedUDPPortRanges).
|
||||
204
nixos/doc/manual/configuration/gpu-accel.chapter.md
Normal file
204
nixos/doc/manual/configuration/gpu-accel.chapter.md
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
# GPU acceleration {#sec-gpu-accel}
|
||||
|
||||
NixOS provides various APIs that benefit from GPU hardware acceleration,
|
||||
such as VA-API and VDPAU for video playback; OpenGL and Vulkan for 3D
|
||||
graphics; and OpenCL for general-purpose computing. This chapter
|
||||
describes how to set up GPU hardware acceleration (as far as this is not
|
||||
done automatically) and how to verify that hardware acceleration is
|
||||
indeed used.
|
||||
|
||||
Most of the aforementioned APIs are agnostic with regards to which
|
||||
display server is used. Consequently, these instructions should apply
|
||||
both to the X Window System and Wayland compositors.
|
||||
|
||||
## OpenCL {#sec-gpu-accel-opencl}
|
||||
|
||||
[OpenCL](https://en.wikipedia.org/wiki/OpenCL) is a general compute API.
|
||||
It is used by various applications such as Blender and Darktable to
|
||||
accelerate certain operations.
|
||||
|
||||
OpenCL applications load drivers through the *Installable Client Driver*
|
||||
(ICD) mechanism. In this mechanism, an ICD file specifies the path to
|
||||
the OpenCL driver for a particular GPU family. In NixOS, there are two
|
||||
ways to make ICD files visible to the ICD loader. The first is through
|
||||
the `OCL_ICD_VENDORS` environment variable. This variable can contain a
|
||||
directory which is scanned by the ICL loader for ICD files. For example:
|
||||
|
||||
```ShellSession
|
||||
$ export \
|
||||
OCL_ICD_VENDORS=`nix-build '<nixpkgs>' --no-out-link -A rocm-opencl-icd`/etc/OpenCL/vendors/
|
||||
```
|
||||
|
||||
The second mechanism is to add the OpenCL driver package to
|
||||
[](#opt-hardware.opengl.extraPackages).
|
||||
This links the ICD file under `/run/opengl-driver`, where it will be visible
|
||||
to the ICD loader.
|
||||
|
||||
The proper installation of OpenCL drivers can be verified through the
|
||||
`clinfo` command of the clinfo package. This command will report the
|
||||
number of hardware devices that is found and give detailed information
|
||||
for each device:
|
||||
|
||||
```ShellSession
|
||||
$ clinfo | head -n3
|
||||
Number of platforms 1
|
||||
Platform Name AMD Accelerated Parallel Processing
|
||||
Platform Vendor Advanced Micro Devices, Inc.
|
||||
```
|
||||
|
||||
### AMD {#sec-gpu-accel-opencl-amd}
|
||||
|
||||
Modern AMD [Graphics Core
|
||||
Next](https://en.wikipedia.org/wiki/Graphics_Core_Next) (GCN) GPUs are
|
||||
supported through the rocm-opencl-icd package. Adding this package to
|
||||
[](#opt-hardware.opengl.extraPackages)
|
||||
enables OpenCL support:
|
||||
|
||||
```nix
|
||||
hardware.opengl.extraPackages = [
|
||||
rocm-opencl-icd
|
||||
];
|
||||
```
|
||||
|
||||
### Intel {#sec-gpu-accel-opencl-intel}
|
||||
|
||||
[Intel Gen8 and later
|
||||
GPUs](https://en.wikipedia.org/wiki/List_of_Intel_graphics_processing_units#Gen8)
|
||||
are supported by the Intel NEO OpenCL runtime that is provided by the
|
||||
intel-compute-runtime package. For Gen7 GPUs, the deprecated Beignet
|
||||
runtime can be used, which is provided by the beignet package. The
|
||||
proprietary Intel OpenCL runtime, in the intel-ocl package, is an
|
||||
alternative for Gen7 GPUs.
|
||||
|
||||
The intel-compute-runtime, beignet, or intel-ocl package can be added to
|
||||
[](#opt-hardware.opengl.extraPackages)
|
||||
to enable OpenCL support. For example, for Gen8 and later GPUs, the following
|
||||
configuration can be used:
|
||||
|
||||
```nix
|
||||
hardware.opengl.extraPackages = [
|
||||
intel-compute-runtime
|
||||
];
|
||||
```
|
||||
|
||||
## Vulkan {#sec-gpu-accel-vulkan}
|
||||
|
||||
[Vulkan](https://en.wikipedia.org/wiki/Vulkan_(API)) is a graphics and
|
||||
compute API for GPUs. It is used directly by games or indirectly though
|
||||
compatibility layers like
|
||||
[DXVK](https://github.com/doitsujin/dxvk/wiki).
|
||||
|
||||
By default, if [](#opt-hardware.opengl.driSupport)
|
||||
is enabled, mesa is installed and provides Vulkan for supported hardware.
|
||||
|
||||
Similar to OpenCL, Vulkan drivers are loaded through the *Installable
|
||||
Client Driver* (ICD) mechanism. ICD files for Vulkan are JSON files that
|
||||
specify the path to the driver library and the supported Vulkan version.
|
||||
All successfully loaded drivers are exposed to the application as
|
||||
different GPUs. In NixOS, there are two ways to make ICD files visible
|
||||
to Vulkan applications: an environment variable and a module option.
|
||||
|
||||
The first option is through the `VK_ICD_FILENAMES` environment variable.
|
||||
This variable can contain multiple JSON files, separated by `:`. For
|
||||
example:
|
||||
|
||||
```ShellSession
|
||||
$ export \
|
||||
VK_ICD_FILENAMES=`nix-build '<nixpkgs>' --no-out-link -A amdvlk`/share/vulkan/icd.d/amd_icd64.json
|
||||
```
|
||||
|
||||
The second mechanism is to add the Vulkan driver package to
|
||||
[](#opt-hardware.opengl.extraPackages).
|
||||
This links the ICD file under `/run/opengl-driver`, where it will be
|
||||
visible to the ICD loader.
|
||||
|
||||
The proper installation of Vulkan drivers can be verified through the
|
||||
`vulkaninfo` command of the vulkan-tools package. This command will
|
||||
report the hardware devices and drivers found, in this example output
|
||||
amdvlk and radv:
|
||||
|
||||
```ShellSession
|
||||
$ vulkaninfo | grep GPU
|
||||
GPU id : 0 (Unknown AMD GPU)
|
||||
GPU id : 1 (AMD RADV NAVI10 (LLVM 9.0.1))
|
||||
...
|
||||
GPU0:
|
||||
deviceType = PHYSICAL_DEVICE_TYPE_DISCRETE_GPU
|
||||
deviceName = Unknown AMD GPU
|
||||
GPU1:
|
||||
deviceType = PHYSICAL_DEVICE_TYPE_DISCRETE_GPU
|
||||
```
|
||||
|
||||
A simple graphical application that uses Vulkan is `vkcube` from the
|
||||
vulkan-tools package.
|
||||
|
||||
### AMD {#sec-gpu-accel-vulkan-amd}
|
||||
|
||||
Modern AMD [Graphics Core
|
||||
Next](https://en.wikipedia.org/wiki/Graphics_Core_Next) (GCN) GPUs are
|
||||
supported through either radv, which is part of mesa, or the amdvlk
|
||||
package. Adding the amdvlk package to
|
||||
[](#opt-hardware.opengl.extraPackages)
|
||||
makes amdvlk the default driver and hides radv and lavapipe from the device list.
|
||||
A specific driver can be forced as follows:
|
||||
|
||||
```nix
|
||||
hardware.opengl.extraPackages = [
|
||||
pkgs.amdvlk
|
||||
];
|
||||
|
||||
# To enable Vulkan support for 32-bit applications, also add:
|
||||
hardware.opengl.extraPackages32 = [
|
||||
pkgs.driversi686Linux.amdvlk
|
||||
];
|
||||
|
||||
# Force radv
|
||||
environment.variables.AMD_VULKAN_ICD = "RADV";
|
||||
# Or
|
||||
environment.variables.VK_ICD_FILENAMES =
|
||||
"/run/opengl-driver/share/vulkan/icd.d/radeon_icd.x86_64.json";
|
||||
```
|
||||
|
||||
## Common issues {#sec-gpu-accel-common-issues}
|
||||
|
||||
### User permissions {#sec-gpu-accel-common-issues-permissions}
|
||||
|
||||
Except where noted explicitly, it should not be necessary to adjust user
|
||||
permissions to use these acceleration APIs. In the default
|
||||
configuration, GPU devices have world-read/write permissions
|
||||
(`/dev/dri/renderD*`) or are tagged as `uaccess` (`/dev/dri/card*`). The
|
||||
access control lists of devices with the `uaccess` tag will be updated
|
||||
automatically when a user logs in through `systemd-logind`. For example,
|
||||
if the user *jane* is logged in, the access control list should look as
|
||||
follows:
|
||||
|
||||
```ShellSession
|
||||
$ getfacl /dev/dri/card0
|
||||
# file: dev/dri/card0
|
||||
# owner: root
|
||||
# group: video
|
||||
user::rw-
|
||||
user:jane:rw-
|
||||
group::rw-
|
||||
mask::rw-
|
||||
other::---
|
||||
```
|
||||
|
||||
If you disabled (this functionality of) `systemd-logind`, you may need
|
||||
to add the user to the `video` group and log in again.
|
||||
|
||||
### Mixing different versions of nixpkgs {#sec-gpu-accel-common-issues-mixing-nixpkgs}
|
||||
|
||||
The *Installable Client Driver* (ICD) mechanism used by OpenCL and
|
||||
Vulkan loads runtimes into its address space using `dlopen`. Mixing an
|
||||
ICD loader mechanism and runtimes from different version of nixpkgs may
|
||||
not work. For example, if the ICD loader uses an older version of glibc
|
||||
than the runtime, the runtime may not be loadable due to missing
|
||||
symbols. Unfortunately, the loader will generally be quiet about such
|
||||
issues.
|
||||
|
||||
If you suspect that you are running into library version mismatches
|
||||
between an ICL loader and a runtime, you could run an application with
|
||||
the `LD_DEBUG` variable set to get more diagnostic information. For
|
||||
example, OpenCL can be tested with `LD_DEBUG=files clinfo`, which should
|
||||
report missing symbols.
|
||||
35
nixos/doc/manual/configuration/ipv4-config.section.md
Normal file
35
nixos/doc/manual/configuration/ipv4-config.section.md
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
# IPv4 Configuration {#sec-ipv4}
|
||||
|
||||
By default, NixOS uses DHCP (specifically, `dhcpcd`) to automatically
|
||||
configure network interfaces. However, you can configure an interface
|
||||
manually as follows:
|
||||
|
||||
```nix
|
||||
networking.interfaces.eth0.ipv4.addresses = [ {
|
||||
address = "192.168.1.2";
|
||||
prefixLength = 24;
|
||||
} ];
|
||||
```
|
||||
|
||||
Typically you'll also want to set a default gateway and set of name
|
||||
servers:
|
||||
|
||||
```nix
|
||||
networking.defaultGateway = "192.168.1.1";
|
||||
networking.nameservers = [ "8.8.8.8" ];
|
||||
```
|
||||
|
||||
::: {.note}
|
||||
Statically configured interfaces are set up by the systemd service
|
||||
`interface-name-cfg.service`. The default gateway and name server
|
||||
configuration is performed by `network-setup.service`.
|
||||
:::
|
||||
|
||||
The host name is set using [](#opt-networking.hostName):
|
||||
|
||||
```nix
|
||||
networking.hostName = "cartman";
|
||||
```
|
||||
|
||||
The default host name is `nixos`. Set it to the empty string (`""`) to
|
||||
allow the DHCP server to provide the host name.
|
||||
42
nixos/doc/manual/configuration/ipv6-config.section.md
Normal file
42
nixos/doc/manual/configuration/ipv6-config.section.md
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
# IPv6 Configuration {#sec-ipv6}
|
||||
|
||||
IPv6 is enabled by default. Stateless address autoconfiguration is used
|
||||
to automatically assign IPv6 addresses to all interfaces, and Privacy
|
||||
Extensions (RFC 4946) are enabled by default. You can adjust the default
|
||||
for this by setting [](#opt-networking.tempAddresses). This option
|
||||
may be overridden on a per-interface basis by
|
||||
[](#opt-networking.interfaces._name_.tempAddress). You can disable
|
||||
IPv6 support globally by setting:
|
||||
|
||||
```nix
|
||||
networking.enableIPv6 = false;
|
||||
```
|
||||
|
||||
You can disable IPv6 on a single interface using a normal sysctl (in
|
||||
this example, we use interface `eth0`):
|
||||
|
||||
```nix
|
||||
boot.kernel.sysctl."net.ipv6.conf.eth0.disable_ipv6" = true;
|
||||
```
|
||||
|
||||
As with IPv4 networking interfaces are automatically configured via
|
||||
DHCPv6. You can configure an interface manually:
|
||||
|
||||
```nix
|
||||
networking.interfaces.eth0.ipv6.addresses = [ {
|
||||
address = "fe00:aa:bb:cc::2";
|
||||
prefixLength = 64;
|
||||
} ];
|
||||
```
|
||||
|
||||
For configuring a gateway, optionally with explicitly specified
|
||||
interface:
|
||||
|
||||
```nix
|
||||
networking.defaultGateway6 = {
|
||||
address = "fe00::1";
|
||||
interface = "enp0s3";
|
||||
};
|
||||
```
|
||||
|
||||
See [](#sec-ipv4) for similar examples and additional information.
|
||||
104
nixos/doc/manual/configuration/kubernetes.chapter.md
Normal file
104
nixos/doc/manual/configuration/kubernetes.chapter.md
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
# Kubernetes {#sec-kubernetes}
|
||||
|
||||
The NixOS Kubernetes module is a collective term for a handful of
|
||||
individual submodules implementing the Kubernetes cluster components.
|
||||
|
||||
There are generally two ways of enabling Kubernetes on NixOS. One way is
|
||||
to enable and configure cluster components appropriately by hand:
|
||||
|
||||
```nix
|
||||
services.kubernetes = {
|
||||
apiserver.enable = true;
|
||||
controllerManager.enable = true;
|
||||
scheduler.enable = true;
|
||||
addonManager.enable = true;
|
||||
proxy.enable = true;
|
||||
flannel.enable = true;
|
||||
};
|
||||
```
|
||||
|
||||
Another way is to assign cluster roles (\"master\" and/or \"node\") to
|
||||
the host. This enables apiserver, controllerManager, scheduler,
|
||||
addonManager, kube-proxy and etcd:
|
||||
|
||||
```nix
|
||||
services.kubernetes.roles = [ "master" ];
|
||||
```
|
||||
|
||||
While this will enable the kubelet and kube-proxy only:
|
||||
|
||||
```nix
|
||||
services.kubernetes.roles = [ "node" ];
|
||||
```
|
||||
|
||||
Assigning both the master and node roles is usable if you want a single
|
||||
node Kubernetes cluster for dev or testing purposes:
|
||||
|
||||
```nix
|
||||
services.kubernetes.roles = [ "master" "node" ];
|
||||
```
|
||||
|
||||
Note: Assigning either role will also default both
|
||||
[](#opt-services.kubernetes.flannel.enable)
|
||||
and [](#opt-services.kubernetes.easyCerts)
|
||||
to true. This sets up flannel as CNI and activates automatic PKI bootstrapping.
|
||||
|
||||
As of kubernetes 1.10.X it has been deprecated to open non-tls-enabled
|
||||
ports on kubernetes components. Thus, from NixOS 19.03 all plain HTTP
|
||||
ports have been disabled by default. While opening insecure ports is
|
||||
still possible, it is recommended not to bind these to other interfaces
|
||||
than loopback. To re-enable the insecure port on the apiserver, see options:
|
||||
[](#opt-services.kubernetes.apiserver.insecurePort) and
|
||||
[](#opt-services.kubernetes.apiserver.insecureBindAddress)
|
||||
|
||||
::: {.note}
|
||||
As of NixOS 19.03, it is mandatory to configure:
|
||||
[](#opt-services.kubernetes.masterAddress).
|
||||
The masterAddress must be resolveable and routeable by all cluster nodes.
|
||||
In single node clusters, this can be set to `localhost`.
|
||||
:::
|
||||
|
||||
Role-based access control (RBAC) authorization mode is enabled by
|
||||
default. This means that anonymous requests to the apiserver secure port
|
||||
will expectedly cause a permission denied error. All cluster components
|
||||
must therefore be configured with x509 certificates for two-way tls
|
||||
communication. The x509 certificate subject section determines the roles
|
||||
and permissions granted by the apiserver to perform clusterwide or
|
||||
namespaced operations. See also: [ Using RBAC
|
||||
Authorization](https://kubernetes.io/docs/reference/access-authn-authz/rbac/).
|
||||
|
||||
The NixOS kubernetes module provides an option for automatic certificate
|
||||
bootstrapping and configuration,
|
||||
[](#opt-services.kubernetes.easyCerts).
|
||||
The PKI bootstrapping process involves setting up a certificate authority (CA)
|
||||
daemon (cfssl) on the kubernetes master node. cfssl generates a CA-cert
|
||||
for the cluster, and uses the CA-cert for signing subordinate certs issued
|
||||
to each of the cluster components. Subsequently, the certmgr daemon monitors
|
||||
active certificates and renews them when needed. For single node Kubernetes
|
||||
clusters, setting [](#opt-services.kubernetes.easyCerts)
|
||||
= true is sufficient and no further action is required. For joining extra node
|
||||
machines to an existing cluster on the other hand, establishing initial
|
||||
trust is mandatory.
|
||||
|
||||
To add new nodes to the cluster: On any (non-master) cluster node where
|
||||
[](#opt-services.kubernetes.easyCerts)
|
||||
is enabled, the helper script `nixos-kubernetes-node-join` is available on PATH.
|
||||
Given a token on stdin, it will copy the token to the kubernetes secrets directory
|
||||
and restart the certmgr service. As requested certificates are issued, the
|
||||
script will restart kubernetes cluster components as needed for them to
|
||||
pick up new keypairs.
|
||||
|
||||
::: {.note}
|
||||
Multi-master (HA) clusters are not supported by the easyCerts module.
|
||||
:::
|
||||
|
||||
In order to interact with an RBAC-enabled cluster as an administrator,
|
||||
one needs to have cluster-admin privileges. By default, when easyCerts
|
||||
is enabled, a cluster-admin kubeconfig file is generated and linked into
|
||||
`/etc/kubernetes/cluster-admin.kubeconfig` as determined by
|
||||
[](#opt-services.kubernetes.pki.etcClusterAdminKubeconfig).
|
||||
`export KUBECONFIG=/etc/kubernetes/cluster-admin.kubeconfig` will make
|
||||
kubectl use this kubeconfig to access and authenticate the cluster. The
|
||||
cluster-admin kubeconfig references an auto-generated keypair owned by
|
||||
root. Thus, only root on the kubernetes master may obtain cluster-admin
|
||||
rights by means of this file.
|
||||
140
nixos/doc/manual/configuration/linux-kernel.chapter.md
Normal file
140
nixos/doc/manual/configuration/linux-kernel.chapter.md
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
# Linux Kernel {#sec-kernel-config}
|
||||
|
||||
You can override the Linux kernel and associated packages using the
|
||||
option `boot.kernelPackages`. For instance, this selects the Linux 3.10
|
||||
kernel:
|
||||
|
||||
```nix
|
||||
boot.kernelPackages = pkgs.linuxKernel.packages.linux_3_10;
|
||||
```
|
||||
|
||||
Note that this not only replaces the kernel, but also packages that are
|
||||
specific to the kernel version, such as the NVIDIA video drivers. This
|
||||
ensures that driver packages are consistent with the kernel.
|
||||
|
||||
While `pkgs.linuxKernel.packages` contains all available kernel packages,
|
||||
you may want to use one of the unversioned `pkgs.linuxPackages_*` aliases
|
||||
such as `pkgs.linuxPackages_latest`, that are kept up to date with new
|
||||
versions.
|
||||
|
||||
The default Linux kernel configuration should be fine for most users.
|
||||
You can see the configuration of your current kernel with the following
|
||||
command:
|
||||
|
||||
```ShellSession
|
||||
zcat /proc/config.gz
|
||||
```
|
||||
|
||||
If you want to change the kernel configuration, you can use the
|
||||
`packageOverrides` feature (see [](#sec-customising-packages)). For
|
||||
instance, to enable support for the kernel debugger KGDB:
|
||||
|
||||
```nix
|
||||
nixpkgs.config.packageOverrides = pkgs: pkgs.lib.recursiveUpdate pkgs {
|
||||
linuxKernel.kernels.linux_5_10 = pkgs.linuxKernel.kernels.linux_5_10.override {
|
||||
extraConfig = ''
|
||||
KGDB y
|
||||
'';
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
`extraConfig` takes a list of Linux kernel configuration options, one
|
||||
per line. The name of the option should not include the prefix
|
||||
`CONFIG_`. The option value is typically `y`, `n` or `m` (to build
|
||||
something as a kernel module).
|
||||
|
||||
Kernel modules for hardware devices are generally loaded automatically
|
||||
by `udev`. You can force a module to be loaded via
|
||||
[](#opt-boot.kernelModules), e.g.
|
||||
|
||||
```nix
|
||||
boot.kernelModules = [ "fuse" "kvm-intel" "coretemp" ];
|
||||
```
|
||||
|
||||
If the module is required early during the boot (e.g. to mount the root
|
||||
file system), you can use [](#opt-boot.initrd.kernelModules):
|
||||
|
||||
```nix
|
||||
boot.initrd.kernelModules = [ "cifs" ];
|
||||
```
|
||||
|
||||
This causes the specified modules and their dependencies to be added to
|
||||
the initial ramdisk.
|
||||
|
||||
Kernel runtime parameters can be set through
|
||||
[](#opt-boot.kernel.sysctl), e.g.
|
||||
|
||||
```nix
|
||||
boot.kernel.sysctl."net.ipv4.tcp_keepalive_time" = 120;
|
||||
```
|
||||
|
||||
sets the kernel's TCP keepalive time to 120 seconds. To see the
|
||||
available parameters, run `sysctl -a`.
|
||||
|
||||
## Customize your kernel {#sec-linux-config-customizing}
|
||||
|
||||
The first step before compiling the kernel is to generate an appropriate
|
||||
`.config` configuration. Either you pass your own config via the
|
||||
`configfile` setting of `linuxKernel.manualConfig`:
|
||||
|
||||
```nix
|
||||
custom-kernel = let base_kernel = linuxKernel.kernels.linux_4_9;
|
||||
in super.linuxKernel.manualConfig {
|
||||
inherit (super) stdenv hostPlatform;
|
||||
inherit (base_kernel) src;
|
||||
version = "${base_kernel.version}-custom";
|
||||
|
||||
configfile = /home/me/my_kernel_config;
|
||||
allowImportFromDerivation = true;
|
||||
};
|
||||
```
|
||||
|
||||
You can edit the config with this snippet (by default `make
|
||||
menuconfig` won\'t work out of the box on nixos):
|
||||
|
||||
```ShellSession
|
||||
nix-shell -E 'with import <nixpkgs> {}; kernelToOverride.overrideAttrs (o: {nativeBuildInputs=o.nativeBuildInputs ++ [ pkg-config ncurses ];})'
|
||||
```
|
||||
|
||||
or you can let nixpkgs generate the configuration. Nixpkgs generates it
|
||||
via answering the interactive kernel utility `make config`. The answers
|
||||
depend on parameters passed to
|
||||
`pkgs/os-specific/linux/kernel/generic.nix` (which you can influence by
|
||||
overriding `extraConfig, autoModules,
|
||||
modDirVersion, preferBuiltin, extraConfig`).
|
||||
|
||||
```nix
|
||||
mptcp93.override ({
|
||||
name="mptcp-local";
|
||||
|
||||
ignoreConfigErrors = true;
|
||||
autoModules = false;
|
||||
kernelPreferBuiltin = true;
|
||||
|
||||
enableParallelBuilding = true;
|
||||
|
||||
extraConfig = ''
|
||||
DEBUG_KERNEL y
|
||||
FRAME_POINTER y
|
||||
KGDB y
|
||||
KGDB_SERIAL_CONSOLE y
|
||||
DEBUG_INFO y
|
||||
'';
|
||||
});
|
||||
```
|
||||
|
||||
## Developing kernel modules {#sec-linux-config-developing-modules}
|
||||
|
||||
When developing kernel modules it\'s often convenient to run
|
||||
edit-compile-run loop as quickly as possible. See below snippet as an
|
||||
example of developing `mellanox` drivers.
|
||||
|
||||
```ShellSession
|
||||
$ nix-build '<nixpkgs>' -A linuxPackages.kernel.dev
|
||||
$ nix-shell '<nixpkgs>' -A linuxPackages.kernel
|
||||
$ unpackPhase
|
||||
$ cd linux-*
|
||||
$ make -C $dev/lib/modules/*/build M=$(pwd)/drivers/net/ethernet/mellanox modules
|
||||
# insmod ./drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.ko
|
||||
```
|
||||
77
nixos/doc/manual/configuration/luks-file-systems.section.md
Normal file
77
nixos/doc/manual/configuration/luks-file-systems.section.md
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
# LUKS-Encrypted File Systems {#sec-luks-file-systems}
|
||||
|
||||
NixOS supports file systems that are encrypted using *LUKS* (Linux
|
||||
Unified Key Setup). For example, here is how you create an encrypted
|
||||
Ext4 file system on the device
|
||||
`/dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d`:
|
||||
|
||||
```ShellSession
|
||||
# cryptsetup luksFormat /dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d
|
||||
|
||||
WARNING!
|
||||
========
|
||||
This will overwrite data on /dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d irrevocably.
|
||||
|
||||
Are you sure? (Type uppercase yes): YES
|
||||
Enter LUKS passphrase: ***
|
||||
Verify passphrase: ***
|
||||
|
||||
# cryptsetup luksOpen /dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d crypted
|
||||
Enter passphrase for /dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d: ***
|
||||
|
||||
# mkfs.ext4 /dev/mapper/crypted
|
||||
```
|
||||
|
||||
The LUKS volume should be automatically picked up by
|
||||
`nixos-generate-config`, but you might want to verify that your
|
||||
`hardware-configuration.nix` looks correct. To manually ensure that the
|
||||
system is automatically mounted at boot time as `/`, add the following
|
||||
to `configuration.nix`:
|
||||
|
||||
```nix
|
||||
boot.initrd.luks.devices.crypted.device = "/dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d";
|
||||
fileSystems."/".device = "/dev/mapper/crypted";
|
||||
```
|
||||
|
||||
Should grub be used as bootloader, and `/boot` is located on an
|
||||
encrypted partition, it is necessary to add the following grub option:
|
||||
|
||||
```nix
|
||||
boot.loader.grub.enableCryptodisk = true;
|
||||
```
|
||||
|
||||
## FIDO2 {#sec-luks-file-systems-fido2}
|
||||
|
||||
NixOS also supports unlocking your LUKS-Encrypted file system using a
|
||||
FIDO2 compatible token. In the following example, we will create a new
|
||||
FIDO2 credential and add it as a new key to our existing device
|
||||
`/dev/sda2`:
|
||||
|
||||
```ShellSession
|
||||
# export FIDO2_LABEL="/dev/sda2 @ $HOSTNAME"
|
||||
# fido2luks credential "$FIDO2_LABEL"
|
||||
f1d00200108b9d6e849a8b388da457688e3dd653b4e53770012d8f28e5d3b269865038c346802f36f3da7278b13ad6a3bb6a1452e24ebeeaa24ba40eef559b1b287d2a2f80b7
|
||||
|
||||
# fido2luks -i add-key /dev/sda2 f1d00200108b9d6e849a8b388da457688e3dd653b4e53770012d8f28e5d3b269865038c346802f36f3da7278b13ad6a3bb6a1452e24ebeeaa24ba40eef559b1b287d2a2f80b7
|
||||
Password:
|
||||
Password (again):
|
||||
Old password:
|
||||
Old password (again):
|
||||
Added to key to device /dev/sda2, slot: 2
|
||||
```
|
||||
|
||||
To ensure that this file system is decrypted using the FIDO2 compatible
|
||||
key, add the following to `configuration.nix`:
|
||||
|
||||
```nix
|
||||
boot.initrd.luks.fido2Support = true;
|
||||
boot.initrd.luks.devices."/dev/sda2".fido2.credential = "f1d00200108b9d6e849a8b388da457688e3dd653b4e53770012d8f28e5d3b269865038c346802f36f3da7278b13ad6a3bb6a1452e24ebeeaa24ba40eef559b1b287d2a2f80b7";
|
||||
```
|
||||
|
||||
You can also use the FIDO2 passwordless setup, but for security reasons,
|
||||
you might want to enable it only when your device is PIN protected, such
|
||||
as [Trezor](https://trezor.io/).
|
||||
|
||||
```nix
|
||||
boot.initrd.luks.devices."/dev/sda2".fido2.passwordLess = true;
|
||||
```
|
||||
133
nixos/doc/manual/configuration/modularity.section.md
Normal file
133
nixos/doc/manual/configuration/modularity.section.md
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
# Modularity {#sec-modularity}
|
||||
|
||||
The NixOS configuration mechanism is modular. If your
|
||||
`configuration.nix` becomes too big, you can split it into multiple
|
||||
files. Likewise, if you have multiple NixOS configurations (e.g. for
|
||||
different computers) with some commonality, you can move the common
|
||||
configuration into a shared file.
|
||||
|
||||
Modules have exactly the same syntax as `configuration.nix`. In fact,
|
||||
`configuration.nix` is itself a module. You can use other modules by
|
||||
including them from `configuration.nix`, e.g.:
|
||||
|
||||
```nix
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
{ imports = [ ./vpn.nix ./kde.nix ];
|
||||
services.httpd.enable = true;
|
||||
environment.systemPackages = [ pkgs.emacs ];
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Here, we include two modules from the same directory, `vpn.nix` and
|
||||
`kde.nix`. The latter might look like this:
|
||||
|
||||
```nix
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
{ services.xserver.enable = true;
|
||||
services.xserver.displayManager.sddm.enable = true;
|
||||
services.xserver.desktopManager.plasma5.enable = true;
|
||||
environment.systemPackages = [ pkgs.vim ];
|
||||
}
|
||||
```
|
||||
|
||||
Note that both `configuration.nix` and `kde.nix` define the option
|
||||
[](#opt-environment.systemPackages). When multiple modules define an
|
||||
option, NixOS will try to *merge* the definitions. In the case of
|
||||
[](#opt-environment.systemPackages), that's easy: the lists of
|
||||
packages can simply be concatenated. The value in `configuration.nix` is
|
||||
merged last, so for list-type options, it will appear at the end of the
|
||||
merged list. If you want it to appear first, you can use `mkBefore`:
|
||||
|
||||
```nix
|
||||
boot.kernelModules = mkBefore [ "kvm-intel" ];
|
||||
```
|
||||
|
||||
This causes the `kvm-intel` kernel module to be loaded before any other
|
||||
kernel modules.
|
||||
|
||||
For other types of options, a merge may not be possible. For instance,
|
||||
if two modules define [](#opt-services.httpd.adminAddr),
|
||||
`nixos-rebuild` will give an error:
|
||||
|
||||
```plain
|
||||
The unique option `services.httpd.adminAddr' is defined multiple times, in `/etc/nixos/httpd.nix' and `/etc/nixos/configuration.nix'.
|
||||
```
|
||||
|
||||
When that happens, it's possible to force one definition take precedence
|
||||
over the others:
|
||||
|
||||
```nix
|
||||
services.httpd.adminAddr = pkgs.lib.mkForce "bob@example.org";
|
||||
```
|
||||
|
||||
When using multiple modules, you may need to access configuration values
|
||||
defined in other modules. This is what the `config` function argument is
|
||||
for: it contains the complete, merged system configuration. That is,
|
||||
`config` is the result of combining the configurations returned by every
|
||||
module [^1] . For example, here is a module that adds some packages to
|
||||
[](#opt-environment.systemPackages) only if
|
||||
[](#opt-services.xserver.enable) is set to `true` somewhere else:
|
||||
|
||||
```nix
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
{ environment.systemPackages =
|
||||
if config.services.xserver.enable then
|
||||
[ pkgs.firefox
|
||||
pkgs.thunderbird
|
||||
]
|
||||
else
|
||||
[ ];
|
||||
}
|
||||
```
|
||||
|
||||
With multiple modules, it may not be obvious what the final value of a
|
||||
configuration option is. The command `nixos-option` allows you to find
|
||||
out:
|
||||
|
||||
```ShellSession
|
||||
$ nixos-option services.xserver.enable
|
||||
true
|
||||
|
||||
$ nixos-option boot.kernelModules
|
||||
[ "tun" "ipv6" "loop" ... ]
|
||||
```
|
||||
|
||||
Interactive exploration of the configuration is possible using `nix
|
||||
repl`, a read-eval-print loop for Nix expressions. A typical use:
|
||||
|
||||
```ShellSession
|
||||
$ nix repl '<nixpkgs/nixos>'
|
||||
|
||||
nix-repl> config.networking.hostName
|
||||
"mandark"
|
||||
|
||||
nix-repl> map (x: x.hostName) config.services.httpd.virtualHosts
|
||||
[ "example.org" "example.gov" ]
|
||||
```
|
||||
|
||||
While abstracting your configuration, you may find it useful to generate
|
||||
modules using code, instead of writing files. The example below would
|
||||
have the same effect as importing a file which sets those options.
|
||||
|
||||
```nix
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
let netConfig = hostName: {
|
||||
networking.hostName = hostName;
|
||||
networking.useDHCP = false;
|
||||
};
|
||||
|
||||
in
|
||||
|
||||
{ imports = [ (netConfig "nixos.localdomain") ]; }
|
||||
```
|
||||
|
||||
[^1]: If you're wondering how it's possible that the (indirect) *result*
|
||||
of a function is passed as an *input* to that same function: that's
|
||||
because Nix is a "lazy" language --- it only computes values when
|
||||
they are needed. This works as long as no individual configuration
|
||||
value depends on itself.
|
||||
42
nixos/doc/manual/configuration/network-manager.section.md
Normal file
42
nixos/doc/manual/configuration/network-manager.section.md
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
# NetworkManager {#sec-networkmanager}
|
||||
|
||||
To facilitate network configuration, some desktop environments use
|
||||
NetworkManager. You can enable NetworkManager by setting:
|
||||
|
||||
```nix
|
||||
networking.networkmanager.enable = true;
|
||||
```
|
||||
|
||||
some desktop managers (e.g., GNOME) enable NetworkManager automatically
|
||||
for you.
|
||||
|
||||
All users that should have permission to change network settings must
|
||||
belong to the `networkmanager` group:
|
||||
|
||||
```nix
|
||||
users.users.alice.extraGroups = [ "networkmanager" ];
|
||||
```
|
||||
|
||||
NetworkManager is controlled using either `nmcli` or `nmtui`
|
||||
(curses-based terminal user interface). See their manual pages for
|
||||
details on their usage. Some desktop environments (GNOME, KDE) have
|
||||
their own configuration tools for NetworkManager. On XFCE, there is no
|
||||
configuration tool for NetworkManager by default: by enabling
|
||||
[](#opt-programs.nm-applet.enable), the graphical applet will be
|
||||
installed and will launch automatically when the graphical session is
|
||||
started.
|
||||
|
||||
::: {.note}
|
||||
`networking.networkmanager` and `networking.wireless` (WPA Supplicant)
|
||||
can be used together if desired. To do this you need to instruct
|
||||
NetworkManager to ignore those interfaces like:
|
||||
|
||||
```nix
|
||||
networking.networkmanager.unmanaged = [
|
||||
"*" "except:type:wwan" "except:type:gsm"
|
||||
];
|
||||
```
|
||||
|
||||
Refer to the option description for the exact syntax and references to
|
||||
external documentation.
|
||||
:::
|
||||
16
nixos/doc/manual/configuration/networking.chapter.md
Normal file
16
nixos/doc/manual/configuration/networking.chapter.md
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
# Networking {#sec-networking}
|
||||
|
||||
This section describes how to configure networking components
|
||||
on your NixOS machine.
|
||||
|
||||
```{=docbook}
|
||||
<xi:include href="network-manager.section.xml" />
|
||||
<xi:include href="ssh.section.xml" />
|
||||
<xi:include href="ipv4-config.section.xml" />
|
||||
<xi:include href="ipv6-config.section.xml" />
|
||||
<xi:include href="firewall.section.xml" />
|
||||
<xi:include href="wireless.section.xml" />
|
||||
<xi:include href="ad-hoc-network-config.section.xml" />
|
||||
<xi:include href="renaming-interfaces.section.xml" />
|
||||
```
|
||||
<!-- TODO: OpenVPN, NAT -->
|
||||
18
nixos/doc/manual/configuration/package-mgmt.chapter.md
Normal file
18
nixos/doc/manual/configuration/package-mgmt.chapter.md
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# Package Management {#sec-package-management}
|
||||
|
||||
This section describes how to add additional packages to your system.
|
||||
NixOS has two distinct styles of package management:
|
||||
|
||||
- *Declarative*, where you declare what packages you want in your
|
||||
`configuration.nix`. Every time you run `nixos-rebuild`, NixOS will
|
||||
ensure that you get a consistent set of binaries corresponding to
|
||||
your specification.
|
||||
|
||||
- *Ad hoc*, where you install, upgrade and uninstall packages via the
|
||||
`nix-env` command. This style allows mixing packages from different
|
||||
Nixpkgs versions. It's the only choice for non-root users.
|
||||
|
||||
```{=docbook}
|
||||
<xi:include href="declarative-packages.section.xml" />
|
||||
<xi:include href="ad-hoc-packages.section.xml" />
|
||||
```
|
||||
34
nixos/doc/manual/configuration/profiles.chapter.md
Normal file
34
nixos/doc/manual/configuration/profiles.chapter.md
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
# Profiles {#ch-profiles}
|
||||
|
||||
In some cases, it may be desirable to take advantage of commonly-used,
|
||||
predefined configurations provided by nixpkgs, but different from those
|
||||
that come as default. This is a role fulfilled by NixOS\'s Profiles,
|
||||
which come as files living in `<nixpkgs/nixos/modules/profiles>`. That
|
||||
is to say, expected usage is to add them to the imports list of your
|
||||
`/etc/configuration.nix` as such:
|
||||
|
||||
```nix
|
||||
imports = [
|
||||
<nixpkgs/nixos/modules/profiles/profile-name.nix>
|
||||
];
|
||||
```
|
||||
|
||||
Even if some of these profiles seem only useful in the context of
|
||||
install media, many are actually intended to be used in real installs.
|
||||
|
||||
What follows is a brief explanation on the purpose and use-case for each
|
||||
profile. Detailing each option configured by each one is out of scope.
|
||||
|
||||
```{=docbook}
|
||||
<xi:include href="profiles/all-hardware.section.xml" />
|
||||
<xi:include href="profiles/base.section.xml" />
|
||||
<xi:include href="profiles/clone-config.section.xml" />
|
||||
<xi:include href="profiles/demo.section.xml" />
|
||||
<xi:include href="profiles/docker-container.section.xml" />
|
||||
<xi:include href="profiles/graphical.section.xml" />
|
||||
<xi:include href="profiles/hardened.section.xml" />
|
||||
<xi:include href="profiles/headless.section.xml" />
|
||||
<xi:include href="profiles/installation-device.section.xml" />
|
||||
<xi:include href="profiles/minimal.section.xml" />
|
||||
<xi:include href="profiles/qemu-guest.section.xml" />
|
||||
```
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
# All Hardware {#sec-profile-all-hardware}
|
||||
|
||||
Enables all hardware supported by NixOS: i.e., all firmware is included, and
|
||||
all devices from which one may boot are enabled in the initrd. Its primary
|
||||
use is in the NixOS installation CDs.
|
||||
|
||||
The enabled kernel modules include support for SATA and PATA, SCSI
|
||||
(partially), USB, Firewire (untested), Virtio (QEMU, KVM, etc.), VMware, and
|
||||
Hyper-V. Additionally, [](#opt-hardware.enableAllFirmware) is
|
||||
enabled, and the firmware for the ZyDAS ZD1211 chipset is specifically
|
||||
installed.
|
||||
7
nixos/doc/manual/configuration/profiles/base.section.md
Normal file
7
nixos/doc/manual/configuration/profiles/base.section.md
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# Base {#sec-profile-base}
|
||||
|
||||
Defines the software packages included in the "minimal" installation CD. It
|
||||
installs several utilities useful in a simple recovery or install media, such
|
||||
as a text-mode web browser, and tools for manipulating block devices,
|
||||
networking, hardware diagnostics, and filesystems (with their respective
|
||||
kernel modules).
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
# Clone Config {#sec-profile-clone-config}
|
||||
|
||||
This profile is used in installer images. It provides an editable
|
||||
configuration.nix that imports all the modules that were also used when
|
||||
creating the image in the first place. As a result it allows users to edit
|
||||
and rebuild the live-system.
|
||||
|
||||
On images where the installation media also becomes an installation target,
|
||||
copying over `configuration.nix` should be disabled by
|
||||
setting `installer.cloneConfig` to `false`.
|
||||
For example, this is done in `sd-image-aarch64-installer.nix`.
|
||||
4
nixos/doc/manual/configuration/profiles/demo.section.md
Normal file
4
nixos/doc/manual/configuration/profiles/demo.section.md
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
# Demo {#sec-profile-demo}
|
||||
|
||||
This profile just enables a `demo` user, with password `demo`, uid `1000`, `wheel` group and
|
||||
[autologin in the SDDM display manager](#opt-services.xserver.displayManager.autoLogin).
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
# Docker Container {#sec-profile-docker-container}
|
||||
|
||||
This is the profile from which the Docker images are generated. It prepares a
|
||||
working system by importing the [Minimal](#sec-profile-minimal) and
|
||||
[Clone Config](#sec-profile-clone-config) profiles, and
|
||||
setting appropriate configuration options that are useful inside a container
|
||||
context, like [](#opt-boot.isContainer).
|
||||
10
nixos/doc/manual/configuration/profiles/graphical.section.md
Normal file
10
nixos/doc/manual/configuration/profiles/graphical.section.md
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# Graphical {#sec-profile-graphical}
|
||||
|
||||
Defines a NixOS configuration with the Plasma 5 desktop. It's used by the
|
||||
graphical installation CD.
|
||||
|
||||
It sets [](#opt-services.xserver.enable),
|
||||
[](#opt-services.xserver.displayManager.sddm.enable),
|
||||
[](#opt-services.xserver.desktopManager.plasma5.enable),
|
||||
and [](#opt-services.xserver.libinput.enable) to true. It also
|
||||
includes glxinfo and firefox in the system packages list.
|
||||
20
nixos/doc/manual/configuration/profiles/hardened.section.md
Normal file
20
nixos/doc/manual/configuration/profiles/hardened.section.md
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
# Hardened {#sec-profile-hardened}
|
||||
|
||||
A profile with most (vanilla) hardening options enabled by default,
|
||||
potentially at the cost of stability, features and performance.
|
||||
|
||||
This includes a hardened kernel, and limiting the system information
|
||||
available to processes through the `/sys` and
|
||||
`/proc` filesystems. It also disables the User Namespaces
|
||||
feature of the kernel, which stops Nix from being able to build anything
|
||||
(this particular setting can be overriden via
|
||||
[](#opt-security.allowUserNamespaces)). See the
|
||||
[profile source](https://github.com/nixos/nixpkgs/tree/master/nixos/modules/profiles/hardened.nix)
|
||||
for further detail on which settings are altered.
|
||||
|
||||
::: {.warning}
|
||||
This profile enables options that are known to affect system
|
||||
stability. If you experience any stability issues when using the
|
||||
profile, try disabling it. If you report an issue and use this
|
||||
profile, always mention that you do.
|
||||
:::
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
# Headless {#sec-profile-headless}
|
||||
|
||||
Common configuration for headless machines (e.g., Amazon EC2 instances).
|
||||
|
||||
Disables [sound](#opt-sound.enable),
|
||||
[vesa](#opt-boot.vesa), serial consoles,
|
||||
[emergency mode](#opt-systemd.enableEmergencyMode),
|
||||
[grub splash images](#opt-boot.loader.grub.splashImage)
|
||||
and configures the kernel to reboot automatically on panic.
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
# Installation Device {#sec-profile-installation-device}
|
||||
|
||||
Provides a basic configuration for installation devices like CDs.
|
||||
This enables redistributable firmware, includes the
|
||||
[Clone Config profile](#sec-profile-clone-config)
|
||||
and a copy of the Nixpkgs channel, so `nixos-install`
|
||||
works out of the box.
|
||||
|
||||
Documentation for [Nixpkgs](#opt-documentation.enable)
|
||||
and [NixOS](#opt-documentation.nixos.enable) are
|
||||
forcefully enabled (to override the
|
||||
[Minimal profile](#sec-profile-minimal) preference); the
|
||||
NixOS manual is shown automatically on TTY 8, udisks is disabled.
|
||||
Autologin is enabled as `nixos` user, while passwordless
|
||||
login as both `root` and `nixos` is possible.
|
||||
Passwordless `sudo` is enabled too.
|
||||
[wpa_supplicant](#opt-networking.wireless.enable) is
|
||||
enabled, but configured to not autostart.
|
||||
|
||||
It is explained how to login, start the ssh server, and if available,
|
||||
how to start the display manager.
|
||||
|
||||
Several settings are tweaked so that the installer has a better chance of
|
||||
succeeding under low-memory environments.
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
# Minimal {#sec-profile-minimal}
|
||||
|
||||
This profile defines a small NixOS configuration. It does not contain any
|
||||
graphical stuff. It's a very short file that enables
|
||||
[noXlibs](#opt-environment.noXlibs), sets
|
||||
[](#opt-i18n.supportedLocales) to
|
||||
only support the user-selected locale,
|
||||
[disables packages' documentation](#opt-documentation.enable),
|
||||
and [disables sound](#opt-sound.enable).
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
# QEMU Guest {#sec-profile-qemu-guest}
|
||||
|
||||
This profile contains common configuration for virtual machines running under
|
||||
QEMU (using virtio).
|
||||
|
||||
It makes virtio modules available on the initrd and sets the system time from
|
||||
the hardware clock to work around a bug in qemu-kvm.
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
# Renaming network interfaces {#sec-rename-ifs}
|
||||
|
||||
NixOS uses the udev [predictable naming
|
||||
scheme](https://systemd.io/PREDICTABLE_INTERFACE_NAMES/) to assign names
|
||||
to network interfaces. This means that by default cards are not given
|
||||
the traditional names like `eth0` or `eth1`, whose order can change
|
||||
unpredictably across reboots. Instead, relying on physical locations and
|
||||
firmware information, the scheme produces names like `ens1`, `enp2s0`,
|
||||
etc.
|
||||
|
||||
These names are predictable but less memorable and not necessarily
|
||||
stable: for example installing new hardware or changing firmware
|
||||
settings can result in a [name
|
||||
change](https://github.com/systemd/systemd/issues/3715#issue-165347602).
|
||||
If this is undesirable, for example if you have a single ethernet card,
|
||||
you can revert to the traditional scheme by setting
|
||||
[](#opt-networking.usePredictableInterfaceNames)
|
||||
to `false`.
|
||||
|
||||
## Assigning custom names {#sec-custom-ifnames}
|
||||
|
||||
In case there are multiple interfaces of the same type, it's better to
|
||||
assign custom names based on the device hardware address. For example,
|
||||
we assign the name `wan` to the interface with MAC address
|
||||
`52:54:00:12:01:01` using a netword link unit:
|
||||
|
||||
```nix
|
||||
systemd.network.links."10-wan" = {
|
||||
matchConfig.PermanentMACAddress = "52:54:00:12:01:01";
|
||||
linkConfig.Name = "wan";
|
||||
};
|
||||
```
|
||||
|
||||
Note that links are directly read by udev, *not networkd*, and will work
|
||||
even if networkd is disabled.
|
||||
|
||||
Alternatively, we can use a plain old udev rule:
|
||||
|
||||
```nix
|
||||
services.udev.initrdRules = ''
|
||||
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", \
|
||||
ATTR{address}=="52:54:00:12:01:01", KERNEL=="eth*", NAME="wan"
|
||||
'';
|
||||
```
|
||||
|
||||
::: {.warning}
|
||||
The rule must be installed in the initrd using
|
||||
`services.udev.initrdRules`, not the usual `services.udev.extraRules`
|
||||
option. This is to avoid race conditions with other programs controlling
|
||||
the interface.
|
||||
:::
|
||||
19
nixos/doc/manual/configuration/ssh.section.md
Normal file
19
nixos/doc/manual/configuration/ssh.section.md
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# Secure Shell Access {#sec-ssh}
|
||||
|
||||
Secure shell (SSH) access to your machine can be enabled by setting:
|
||||
|
||||
```nix
|
||||
services.openssh.enable = true;
|
||||
```
|
||||
|
||||
By default, root logins using a password are disallowed. They can be
|
||||
disabled entirely by setting
|
||||
[](#opt-services.openssh.permitRootLogin) to `"no"`.
|
||||
|
||||
You can declaratively specify authorised RSA/DSA public keys for a user
|
||||
as follows:
|
||||
|
||||
```nix
|
||||
users.users.alice.openssh.authorizedKeys.keys =
|
||||
[ "ssh-dss AAAAB3NzaC1kc3MAAACBAPIkGWVEt4..." ];
|
||||
```
|
||||
104
nixos/doc/manual/configuration/sshfs-file-systems.section.md
Normal file
104
nixos/doc/manual/configuration/sshfs-file-systems.section.md
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
# SSHFS File Systems {#sec-sshfs-file-systems}
|
||||
|
||||
[SSHFS][sshfs] is a [FUSE][fuse] filesystem that allows easy access to directories on a remote machine using the SSH File Transfer Protocol (SFTP).
|
||||
It means that if you have SSH access to a machine, no additional setup is needed to mount a directory.
|
||||
|
||||
[sshfs]: https://github.com/libfuse/sshfs
|
||||
[fuse]: https://en.wikipedia.org/wiki/Filesystem_in_Userspace
|
||||
|
||||
## Interactive mounting {#sec-sshfs-interactive}
|
||||
|
||||
In NixOS, SSHFS is packaged as <package>sshfs</package>.
|
||||
Once installed, mounting a directory interactively is simple as running:
|
||||
```ShellSession
|
||||
$ sshfs my-user@example.com:/my-dir /mnt/my-dir
|
||||
```
|
||||
Like any other FUSE file system, the directory is unmounted using:
|
||||
```ShellSession
|
||||
$ fusermount -u /mnt/my-dir
|
||||
```
|
||||
|
||||
## Non-interactive mounting {#sec-sshfs-non-interactive}
|
||||
|
||||
Mounting non-interactively requires some precautions because `sshfs` will run at boot and under a different user (root).
|
||||
For obvious reason, you can't input a password, so public key authentication using an unencrypted key is needed.
|
||||
To create a new key without a passphrase you can do:
|
||||
```ShellSession
|
||||
$ ssh-keygen -t ed25519 -P '' -f example-key
|
||||
Generating public/private ed25519 key pair.
|
||||
Your identification has been saved in test-key
|
||||
Your public key has been saved in test-key.pub
|
||||
The key fingerprint is:
|
||||
SHA256:yjxl3UbTn31fLWeyLYTAKYJPRmzknjQZoyG8gSNEoIE my-user@workstation
|
||||
```
|
||||
To keep the key safe, change the ownership to `root:root` and make sure the permissions are `600`:
|
||||
OpenSSH normally refuses to use the key if it's not well-protected.
|
||||
|
||||
The file system can be configured in NixOS via the usual [fileSystems](#opt-fileSystems) option.
|
||||
Here's a typical setup:
|
||||
```nix
|
||||
{
|
||||
system.fsPackages = [ pkgs.sshfs ];
|
||||
|
||||
fileSystems."/mnt/my-dir" = {
|
||||
device = "my-user@example.com:/my-dir/";
|
||||
fsType = "sshfs";
|
||||
options =
|
||||
[ # Filesystem options
|
||||
"allow_other" # for non-root access
|
||||
"_netdev" # this is a network fs
|
||||
"x-systemd.automount" # mount on demand
|
||||
|
||||
# SSH options
|
||||
"reconnect" # handle connection drops
|
||||
"ServerAliveInterval=15" # keep connections alive
|
||||
"IdentityFile=/var/secrets/example-key"
|
||||
];
|
||||
};
|
||||
}
|
||||
```
|
||||
More options from `ssh_config(5)` can be given as well, for example you can change the default SSH port or specify a jump proxy:
|
||||
```nix
|
||||
{
|
||||
options =
|
||||
[ "ProxyJump=bastion@example.com"
|
||||
"Port=22"
|
||||
];
|
||||
}
|
||||
```
|
||||
It's also possible to change the `ssh` command used by SSHFS to connect to the server.
|
||||
For example:
|
||||
```nix
|
||||
{
|
||||
options =
|
||||
[ (builtins.replaceStrings [" "] ["\\040"]
|
||||
"ssh_command=${pkgs.openssh}/bin/ssh -v -L 8080:localhost:80")
|
||||
];
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
::: {.note}
|
||||
The escaping of spaces is needed because every option is written to the `/etc/fstab` file, which is a space-separated table.
|
||||
:::
|
||||
|
||||
### Troubleshooting {#sec-sshfs-troubleshooting}
|
||||
|
||||
If you're having a hard time figuring out why mounting is failing, you can add the option `"debug"`.
|
||||
This enables a verbose log in SSHFS that you can access via:
|
||||
```ShellSession
|
||||
$ journalctl -u $(systemd-escape -p /mnt/my-dir/).mount
|
||||
Jun 22 11:41:18 workstation mount[87790]: SSHFS version 3.7.1
|
||||
Jun 22 11:41:18 workstation mount[87793]: executing <ssh> <-x> <-a> <-oClearAllForwardings=yes> <-oServerAliveInterval=15> <-oIdentityFile=/var/secrets/wrong-key> <-2> <my-user@example.com> <-s> <sftp>
|
||||
Jun 22 11:41:19 workstation mount[87793]: my-user@example.com: Permission denied (publickey).
|
||||
Jun 22 11:41:19 workstation mount[87790]: read: Connection reset by peer
|
||||
Jun 22 11:41:19 workstation systemd[1]: mnt-my\x2ddir.mount: Mount process exited, code=exited, status=1/FAILURE
|
||||
Jun 22 11:41:19 workstation systemd[1]: mnt-my\x2ddir.mount: Failed with result 'exit-code'.
|
||||
Jun 22 11:41:19 workstation systemd[1]: Failed to mount /mnt/my-dir.
|
||||
Jun 22 11:41:19 workstation systemd[1]: mnt-my\x2ddir.mount: Consumed 54ms CPU time, received 2.3K IP traffic, sent 2.7K IP traffic.
|
||||
```
|
||||
|
||||
::: {.note}
|
||||
If the mount point contains special characters it needs to be escaped using `systemd-escape`.
|
||||
This is due to the way systemd converts paths into unit names.
|
||||
:::
|
||||
102
nixos/doc/manual/configuration/subversion.chapter.md
Normal file
102
nixos/doc/manual/configuration/subversion.chapter.md
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
# Subversion {#module-services-subversion}
|
||||
|
||||
[Subversion](https://subversion.apache.org/) is a centralized
|
||||
version-control system. It can use a [variety of
|
||||
protocols](http://svnbook.red-bean.com/en/1.7/svn-book.html#svn.serverconfig.choosing)
|
||||
for communication between client and server.
|
||||
|
||||
## Subversion inside Apache HTTP {#module-services-subversion-apache-httpd}
|
||||
|
||||
This section focuses on configuring a web-based server on top of the
|
||||
Apache HTTP server, which uses
|
||||
[WebDAV](http://www.webdav.org/)/[DeltaV](http://www.webdav.org/deltav/WWW10/deltav-intro.htm)
|
||||
for communication.
|
||||
|
||||
For more information on the general setup, please refer to the [the
|
||||
appropriate section of the Subversion
|
||||
book](http://svnbook.red-bean.com/en/1.7/svn-book.html#svn.serverconfig.httpd).
|
||||
|
||||
To configure, include in `/etc/nixos/configuration.nix` code to activate
|
||||
Apache HTTP, setting [](#opt-services.httpd.adminAddr)
|
||||
appropriately:
|
||||
|
||||
```nix
|
||||
services.httpd.enable = true;
|
||||
services.httpd.adminAddr = ...;
|
||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||
```
|
||||
|
||||
For a simple Subversion server with basic authentication, configure the
|
||||
Subversion module for Apache as follows, setting `hostName` and
|
||||
`documentRoot` appropriately, and `SVNParentPath` to the parent
|
||||
directory of the repositories, `AuthzSVNAccessFile` to the location of
|
||||
the `.authz` file describing access permission, and `AuthUserFile` to
|
||||
the password file.
|
||||
|
||||
```nix
|
||||
services.httpd.extraModules = [
|
||||
# note that order is *super* important here
|
||||
{ name = "dav_svn"; path = "${pkgs.apacheHttpdPackages.subversion}/modules/mod_dav_svn.so"; }
|
||||
{ name = "authz_svn"; path = "${pkgs.apacheHttpdPackages.subversion}/modules/mod_authz_svn.so"; }
|
||||
];
|
||||
services.httpd.virtualHosts = {
|
||||
"svn" = {
|
||||
hostName = HOSTNAME;
|
||||
documentRoot = DOCUMENTROOT;
|
||||
locations."/svn".extraConfig = ''
|
||||
DAV svn
|
||||
SVNParentPath REPO_PARENT
|
||||
AuthzSVNAccessFile ACCESS_FILE
|
||||
AuthName "SVN Repositories"
|
||||
AuthType Basic
|
||||
AuthUserFile PASSWORD_FILE
|
||||
Require valid-user
|
||||
'';
|
||||
}
|
||||
```
|
||||
|
||||
The key `"svn"` is just a symbolic name identifying the virtual host.
|
||||
The `"/svn"` in `locations."/svn".extraConfig` is the path underneath
|
||||
which the repositories will be served.
|
||||
|
||||
[This page](https://wiki.archlinux.org/index.php/Subversion) explains
|
||||
how to set up the Subversion configuration itself. This boils down to
|
||||
the following:
|
||||
|
||||
Underneath `REPO_PARENT` repositories can be set up as follows:
|
||||
|
||||
```ShellSession
|
||||
$ svn create REPO_NAME
|
||||
```
|
||||
|
||||
Repository files need to be accessible by `wwwrun`:
|
||||
|
||||
```ShellSession
|
||||
$ chown -R wwwrun:wwwrun REPO_PARENT
|
||||
```
|
||||
|
||||
The password file `PASSWORD_FILE` can be created as follows:
|
||||
|
||||
```ShellSession
|
||||
$ htpasswd -cs PASSWORD_FILE USER_NAME
|
||||
```
|
||||
|
||||
Additional users can be set up similarly, omitting the `c` flag:
|
||||
|
||||
```ShellSession
|
||||
$ htpasswd -s PASSWORD_FILE USER_NAME
|
||||
```
|
||||
|
||||
The file describing access permissions `ACCESS_FILE` will look something
|
||||
like the following:
|
||||
|
||||
```nix
|
||||
[/]
|
||||
* = r
|
||||
|
||||
[REPO_NAME:/]
|
||||
USER_NAME = rw
|
||||
```
|
||||
|
||||
The Subversion repositories will be accessible as
|
||||
`http://HOSTNAME/svn/REPO_NAME`.
|
||||
46
nixos/doc/manual/configuration/summary.section.md
Normal file
46
nixos/doc/manual/configuration/summary.section.md
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
# Syntax Summary {#sec-nix-syntax-summary}
|
||||
|
||||
Below is a summary of the most important syntactic constructs in the Nix
|
||||
expression language. It's not complete. In particular, there are many
|
||||
other built-in functions. See the [Nix
|
||||
manual](https://nixos.org/nix/manual/#chap-writing-nix-expressions) for
|
||||
the rest.
|
||||
|
||||
| Example | Description |
|
||||
|-----------------------------------------------|--------------------------------------------------------------------------------------------------------------------|
|
||||
| *Basic values* | |
|
||||
| `"Hello world"` | A string |
|
||||
| `"${pkgs.bash}/bin/sh"` | A string containing an expression (expands to `"/nix/store/hash-bash-version/bin/sh"`) |
|
||||
| `true`, `false` | Booleans |
|
||||
| `123` | An integer |
|
||||
| `./foo.png` | A path (relative to the containing Nix expression) |
|
||||
| *Compound values* | |
|
||||
| `{ x = 1; y = 2; }` | A set with attributes named `x` and `y` |
|
||||
| `{ foo.bar = 1; }` | A nested set, equivalent to `{ foo = { bar = 1; }; }` |
|
||||
| `rec { x = "foo"; y = x + "bar"; }` | A recursive set, equivalent to `{ x = "foo"; y = "foobar"; }` |
|
||||
| `[ "foo" "bar" ]` | A list with two elements |
|
||||
| *Operators* | |
|
||||
| `"foo" + "bar"` | String concatenation |
|
||||
| `1 + 2` | Integer addition |
|
||||
| `"foo" == "f" + "oo"` | Equality test (evaluates to `true`) |
|
||||
| `"foo" != "bar"` | Inequality test (evaluates to `true`) |
|
||||
| `!true` | Boolean negation |
|
||||
| `{ x = 1; y = 2; }.x` | Attribute selection (evaluates to `1`) |
|
||||
| `{ x = 1; y = 2; }.z or 3` | Attribute selection with default (evaluates to `3`) |
|
||||
| `{ x = 1; y = 2; } // { z = 3; }` | Merge two sets (attributes in the right-hand set taking precedence) |
|
||||
| *Control structures* | |
|
||||
| `if 1 + 1 == 2 then "yes!" else "no!"` | Conditional expression |
|
||||
| `assert 1 + 1 == 2; "yes!"` | Assertion check (evaluates to `"yes!"`). See [](#sec-assertions) for using assertions in modules |
|
||||
| `let x = "foo"; y = "bar"; in x + y` | Variable definition |
|
||||
| `with pkgs.lib; head [ 1 2 3 ]` | Add all attributes from the given set to the scope (evaluates to `1`) |
|
||||
| *Functions (lambdas)* | |
|
||||
| `x: x + 1` | A function that expects an integer and returns it increased by 1 |
|
||||
| `(x: x + 1) 100` | A function call (evaluates to 101) |
|
||||
| `let inc = x: x + 1; in inc (inc (inc 100))` | A function bound to a variable and subsequently called by name (evaluates to 103) |
|
||||
| `{ x, y }: x + y` | A function that expects a set with required attributes `x` and `y` and concatenates them |
|
||||
| `{ x, y ? "bar" }: x + y` | A function that expects a set with required attribute `x` and optional `y`, using `"bar"` as default value for `y` |
|
||||
| `{ x, y, ... }: x + y` | A function that expects a set with required attributes `x` and `y` and ignores any other attributes |
|
||||
| `{ x, y } @ args: x + y` | A function that expects a set with required attributes `x` and `y`, and binds the whole set to `args` |
|
||||
| *Built-in functions* | |
|
||||
| `import ./foo.nix` | Load and return Nix expression in given file |
|
||||
| `map (x: x + x) [ 1 2 3 ]` | Apply a function to every element of a list (evaluates to `[ 2 4 6 ]`) |
|
||||
92
nixos/doc/manual/configuration/user-mgmt.chapter.md
Normal file
92
nixos/doc/manual/configuration/user-mgmt.chapter.md
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
# User Management {#sec-user-management}
|
||||
|
||||
NixOS supports both declarative and imperative styles of user
|
||||
management. In the declarative style, users are specified in
|
||||
`configuration.nix`. For instance, the following states that a user
|
||||
account named `alice` shall exist:
|
||||
|
||||
```nix
|
||||
users.users.alice = {
|
||||
isNormalUser = true;
|
||||
home = "/home/alice";
|
||||
description = "Alice Foobar";
|
||||
extraGroups = [ "wheel" "networkmanager" ];
|
||||
openssh.authorizedKeys.keys = [ "ssh-dss AAAAB3Nza... alice@foobar" ];
|
||||
};
|
||||
```
|
||||
|
||||
Note that `alice` is a member of the `wheel` and `networkmanager`
|
||||
groups, which allows her to use `sudo` to execute commands as `root` and
|
||||
to configure the network, respectively. Also note the SSH public key
|
||||
that allows remote logins with the corresponding private key. Users
|
||||
created in this way do not have a password by default, so they cannot
|
||||
log in via mechanisms that require a password. However, you can use the
|
||||
`passwd` program to set a password, which is retained across invocations
|
||||
of `nixos-rebuild`.
|
||||
|
||||
If you set [](#opt-users.mutableUsers) to
|
||||
false, then the contents of `/etc/passwd` and `/etc/group` will be congruent
|
||||
to your NixOS configuration. For instance, if you remove a user from
|
||||
[](#opt-users.users) and run nixos-rebuild, the user
|
||||
account will cease to exist. Also, imperative commands for managing users and
|
||||
groups, such as useradd, are no longer available. Passwords may still be
|
||||
assigned by setting the user\'s
|
||||
[hashedPassword](#opt-users.users._name_.hashedPassword) option. A
|
||||
hashed password can be generated using `mkpasswd -m
|
||||
sha-512`.
|
||||
|
||||
A user ID (uid) is assigned automatically. You can also specify a uid
|
||||
manually by adding
|
||||
|
||||
```nix
|
||||
uid = 1000;
|
||||
```
|
||||
|
||||
to the user specification.
|
||||
|
||||
Groups can be specified similarly. The following states that a group
|
||||
named `students` shall exist:
|
||||
|
||||
```nix
|
||||
users.groups.students.gid = 1000;
|
||||
```
|
||||
|
||||
As with users, the group ID (gid) is optional and will be assigned
|
||||
automatically if it's missing.
|
||||
|
||||
In the imperative style, users and groups are managed by commands such
|
||||
as `useradd`, `groupmod` and so on. For instance, to create a user
|
||||
account named `alice`:
|
||||
|
||||
```ShellSession
|
||||
# useradd -m alice
|
||||
```
|
||||
|
||||
To make all nix tools available to this new user use \`su - USER\` which
|
||||
opens a login shell (==shell that loads the profile) for given user.
|
||||
This will create the \~/.nix-defexpr symlink. So run:
|
||||
|
||||
```ShellSession
|
||||
# su - alice -c "true"
|
||||
```
|
||||
|
||||
The flag `-m` causes the creation of a home directory for the new user,
|
||||
which is generally what you want. The user does not have an initial
|
||||
password and therefore cannot log in. A password can be set using the
|
||||
`passwd` utility:
|
||||
|
||||
```ShellSession
|
||||
# passwd alice
|
||||
Enter new UNIX password: ***
|
||||
Retype new UNIX password: ***
|
||||
```
|
||||
|
||||
A user can be deleted using `userdel`:
|
||||
|
||||
```ShellSession
|
||||
# userdel -r alice
|
||||
```
|
||||
|
||||
The flag `-r` deletes the user's home directory. Accounts can be
|
||||
modified using `usermod`. Unix groups can be managed using `groupadd`,
|
||||
`groupmod` and `groupdel`.
|
||||
27
nixos/doc/manual/configuration/wayland.chapter.md
Normal file
27
nixos/doc/manual/configuration/wayland.chapter.md
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# Wayland {#sec-wayland}
|
||||
|
||||
While X11 (see [](#sec-x11)) is still the primary display technology
|
||||
on NixOS, Wayland support is steadily improving. Where X11 separates the
|
||||
X Server and the window manager, on Wayland those are combined: a
|
||||
Wayland Compositor is like an X11 window manager, but also embeds the
|
||||
Wayland \'Server\' functionality. This means it is sufficient to install
|
||||
a Wayland Compositor such as sway without separately enabling a Wayland
|
||||
server:
|
||||
|
||||
```nix
|
||||
programs.sway.enable = true;
|
||||
```
|
||||
|
||||
This installs the sway compositor along with some essential utilities.
|
||||
Now you can start sway from the TTY console.
|
||||
|
||||
If you are using a wlroots-based compositor, like sway, and want to be
|
||||
able to share your screen, you might want to activate this option:
|
||||
|
||||
```nix
|
||||
xdg.portal.wlr.enable = true;
|
||||
```
|
||||
|
||||
and configure Pipewire using
|
||||
[](#opt-services.pipewire.enable)
|
||||
and related options.
|
||||
67
nixos/doc/manual/configuration/wireless.section.md
Normal file
67
nixos/doc/manual/configuration/wireless.section.md
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
# Wireless Networks {#sec-wireless}
|
||||
|
||||
For a desktop installation using NetworkManager (e.g., GNOME), you just
|
||||
have to make sure the user is in the `networkmanager` group and you can
|
||||
skip the rest of this section on wireless networks.
|
||||
|
||||
NixOS will start wpa_supplicant for you if you enable this setting:
|
||||
|
||||
```nix
|
||||
networking.wireless.enable = true;
|
||||
```
|
||||
|
||||
NixOS lets you specify networks for wpa_supplicant declaratively:
|
||||
|
||||
```nix
|
||||
networking.wireless.networks = {
|
||||
echelon = { # SSID with no spaces or special characters
|
||||
psk = "abcdefgh";
|
||||
};
|
||||
"echelon's AP" = { # SSID with spaces and/or special characters
|
||||
psk = "ijklmnop";
|
||||
};
|
||||
echelon = { # Hidden SSID
|
||||
hidden = true;
|
||||
psk = "qrstuvwx";
|
||||
};
|
||||
free.wifi = {}; # Public wireless network
|
||||
};
|
||||
```
|
||||
|
||||
Be aware that keys will be written to the nix store in plaintext! When
|
||||
no networks are set, it will default to using a configuration file at
|
||||
`/etc/wpa_supplicant.conf`. You should edit this file yourself to define
|
||||
wireless networks, WPA keys and so on (see wpa_supplicant.conf(5)).
|
||||
|
||||
If you are using WPA2 you can generate pskRaw key using
|
||||
`wpa_passphrase`:
|
||||
|
||||
```ShellSession
|
||||
$ wpa_passphrase ESSID PSK
|
||||
network={
|
||||
ssid="echelon"
|
||||
#psk="abcdefgh"
|
||||
psk=dca6d6ed41f4ab5a984c9f55f6f66d4efdc720ebf66959810f4329bb391c5435
|
||||
}
|
||||
```
|
||||
|
||||
```nix
|
||||
networking.wireless.networks = {
|
||||
echelon = {
|
||||
pskRaw = "dca6d6ed41f4ab5a984c9f55f6f66d4efdc720ebf66959810f4329bb391c5435";
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
or you can use it to directly generate the `wpa_supplicant.conf`:
|
||||
|
||||
```ShellSession
|
||||
# wpa_passphrase ESSID PSK > /etc/wpa_supplicant.conf
|
||||
```
|
||||
|
||||
After you have edited the `wpa_supplicant.conf`, you need to restart the
|
||||
wpa_supplicant service.
|
||||
|
||||
```ShellSession
|
||||
# systemctl restart wpa_supplicant.service
|
||||
```
|
||||
337
nixos/doc/manual/configuration/x-windows.chapter.md
Normal file
337
nixos/doc/manual/configuration/x-windows.chapter.md
Normal file
|
|
@ -0,0 +1,337 @@
|
|||
# X Window System {#sec-x11}
|
||||
|
||||
The X Window System (X11) provides the basis of NixOS' graphical user
|
||||
interface. It can be enabled as follows:
|
||||
|
||||
```nix
|
||||
services.xserver.enable = true;
|
||||
```
|
||||
|
||||
The X server will automatically detect and use the appropriate video
|
||||
driver from a set of X.org drivers (such as `vesa` and `intel`). You can
|
||||
also specify a driver manually, e.g.
|
||||
|
||||
```nix
|
||||
services.xserver.videoDrivers = [ "r128" ];
|
||||
```
|
||||
|
||||
to enable X.org's `xf86-video-r128` driver.
|
||||
|
||||
You also need to enable at least one desktop or window manager.
|
||||
Otherwise, you can only log into a plain undecorated `xterm` window.
|
||||
Thus you should pick one or more of the following lines:
|
||||
|
||||
```nix
|
||||
services.xserver.desktopManager.plasma5.enable = true;
|
||||
services.xserver.desktopManager.xfce.enable = true;
|
||||
services.xserver.desktopManager.gnome.enable = true;
|
||||
services.xserver.desktopManager.mate.enable = true;
|
||||
services.xserver.windowManager.xmonad.enable = true;
|
||||
services.xserver.windowManager.twm.enable = true;
|
||||
services.xserver.windowManager.icewm.enable = true;
|
||||
services.xserver.windowManager.i3.enable = true;
|
||||
services.xserver.windowManager.herbstluftwm.enable = true;
|
||||
```
|
||||
|
||||
NixOS's default *display manager* (the program that provides a graphical
|
||||
login prompt and manages the X server) is LightDM. You can select an
|
||||
alternative one by picking one of the following lines:
|
||||
|
||||
```nix
|
||||
services.xserver.displayManager.sddm.enable = true;
|
||||
services.xserver.displayManager.gdm.enable = true;
|
||||
```
|
||||
|
||||
You can set the keyboard layout (and optionally the layout variant):
|
||||
|
||||
```nix
|
||||
services.xserver.layout = "de";
|
||||
services.xserver.xkbVariant = "neo";
|
||||
```
|
||||
|
||||
The X server is started automatically at boot time. If you don't want
|
||||
this to happen, you can set:
|
||||
|
||||
```nix
|
||||
services.xserver.autorun = false;
|
||||
```
|
||||
|
||||
The X server can then be started manually:
|
||||
|
||||
```ShellSession
|
||||
# systemctl start display-manager.service
|
||||
```
|
||||
|
||||
On 64-bit systems, if you want OpenGL for 32-bit programs such as in
|
||||
Wine, you should also set the following:
|
||||
|
||||
```nix
|
||||
hardware.opengl.driSupport32Bit = true;
|
||||
```
|
||||
|
||||
## Auto-login {#sec-x11-auto-login .unnumbered}
|
||||
|
||||
The x11 login screen can be skipped entirely, automatically logging you
|
||||
into your window manager and desktop environment when you boot your
|
||||
computer.
|
||||
|
||||
This is especially helpful if you have disk encryption enabled. Since
|
||||
you already have to provide a password to decrypt your disk, entering a
|
||||
second password to login can be redundant.
|
||||
|
||||
To enable auto-login, you need to define your default window manager and
|
||||
desktop environment. If you wanted no desktop environment and i3 as your
|
||||
your window manager, you\'d define:
|
||||
|
||||
```nix
|
||||
services.xserver.displayManager.defaultSession = "none+i3";
|
||||
```
|
||||
|
||||
Every display manager in NixOS supports auto-login, here is an example
|
||||
using lightdm for a user `alice`:
|
||||
|
||||
```nix
|
||||
services.xserver.displayManager.lightdm.enable = true;
|
||||
services.xserver.displayManager.autoLogin.enable = true;
|
||||
services.xserver.displayManager.autoLogin.user = "alice";
|
||||
```
|
||||
|
||||
## Intel Graphics drivers {#sec-x11--graphics-cards-intel .unnumbered}
|
||||
|
||||
There are two choices for Intel Graphics drivers in X.org: `modesetting`
|
||||
(included in the xorg-server itself) and `intel` (provided by the
|
||||
package xf86-video-intel).
|
||||
|
||||
The default and recommended is `modesetting`. It is a generic driver
|
||||
which uses the kernel [mode
|
||||
setting](https://en.wikipedia.org/wiki/Mode_setting) (KMS) mechanism. It
|
||||
supports Glamor (2D graphics acceleration via OpenGL) and is actively
|
||||
maintained but may perform worse in some cases (like in old chipsets).
|
||||
|
||||
The second driver, `intel`, is specific to Intel GPUs, but not
|
||||
recommended by most distributions: it lacks several modern features (for
|
||||
example, it doesn\'t support Glamor) and the package hasn\'t been
|
||||
officially updated since 2015.
|
||||
|
||||
The results vary depending on the hardware, so you may have to try both
|
||||
drivers. Use the option
|
||||
[](#opt-services.xserver.videoDrivers)
|
||||
to set one. The recommended configuration for modern systems is:
|
||||
|
||||
```nix
|
||||
services.xserver.videoDrivers = [ "modesetting" ];
|
||||
services.xserver.useGlamor = true;
|
||||
```
|
||||
|
||||
If you experience screen tearing no matter what, this configuration was
|
||||
reported to resolve the issue:
|
||||
|
||||
```nix
|
||||
services.xserver.videoDrivers = [ "intel" ];
|
||||
services.xserver.deviceSection = ''
|
||||
Option "DRI" "2"
|
||||
Option "TearFree" "true"
|
||||
'';
|
||||
```
|
||||
|
||||
Note that this will likely downgrade the performance compared to
|
||||
`modesetting` or `intel` with DRI 3 (default).
|
||||
|
||||
## Proprietary NVIDIA drivers {#sec-x11-graphics-cards-nvidia .unnumbered}
|
||||
|
||||
NVIDIA provides a proprietary driver for its graphics cards that has
|
||||
better 3D performance than the X.org drivers. It is not enabled by
|
||||
default because it's not free software. You can enable it as follows:
|
||||
|
||||
```nix
|
||||
services.xserver.videoDrivers = [ "nvidia" ];
|
||||
```
|
||||
|
||||
Or if you have an older card, you may have to use one of the legacy
|
||||
drivers:
|
||||
|
||||
```nix
|
||||
services.xserver.videoDrivers = [ "nvidiaLegacy390" ];
|
||||
services.xserver.videoDrivers = [ "nvidiaLegacy340" ];
|
||||
services.xserver.videoDrivers = [ "nvidiaLegacy304" ];
|
||||
```
|
||||
|
||||
You may need to reboot after enabling this driver to prevent a clash
|
||||
with other kernel modules.
|
||||
|
||||
## Proprietary AMD drivers {#sec-x11--graphics-cards-amd .unnumbered}
|
||||
|
||||
AMD provides a proprietary driver for its graphics cards that is not
|
||||
enabled by default because it's not Free Software, is often broken in
|
||||
nixpkgs and as of this writing doesn\'t offer more features or
|
||||
performance. If you still want to use it anyway, you need to explicitly
|
||||
set:
|
||||
|
||||
```nix
|
||||
services.xserver.videoDrivers = [ "amdgpu-pro" ];
|
||||
```
|
||||
|
||||
You will need to reboot after enabling this driver to prevent a clash
|
||||
with other kernel modules.
|
||||
|
||||
## Touchpads {#sec-x11-touchpads .unnumbered}
|
||||
|
||||
Support for Synaptics touchpads (found in many laptops such as the Dell
|
||||
Latitude series) can be enabled as follows:
|
||||
|
||||
```nix
|
||||
services.xserver.libinput.enable = true;
|
||||
```
|
||||
|
||||
The driver has many options (see [](#ch-options)).
|
||||
For instance, the following disables tap-to-click behavior:
|
||||
|
||||
```nix
|
||||
services.xserver.libinput.touchpad.tapping = false;
|
||||
```
|
||||
|
||||
Note: the use of `services.xserver.synaptics` is deprecated since NixOS
|
||||
17.09.
|
||||
|
||||
## GTK/Qt themes {#sec-x11-gtk-and-qt-themes .unnumbered}
|
||||
|
||||
GTK themes can be installed either to user profile or system-wide (via
|
||||
`environment.systemPackages`). To make Qt 5 applications look similar to
|
||||
GTK ones, you can use the following configuration:
|
||||
|
||||
```nix
|
||||
qt5.enable = true;
|
||||
qt5.platformTheme = "gtk2";
|
||||
qt5.style = "gtk2";
|
||||
```
|
||||
|
||||
## Custom XKB layouts {#custom-xkb-layouts .unnumbered}
|
||||
|
||||
It is possible to install custom [ XKB
|
||||
](https://en.wikipedia.org/wiki/X_keyboard_extension) keyboard layouts
|
||||
using the option `services.xserver.extraLayouts`.
|
||||
|
||||
As a first example, we are going to create a layout based on the basic
|
||||
US layout, with an additional layer to type some greek symbols by
|
||||
pressing the right-alt key.
|
||||
|
||||
Create a file called `us-greek` with the following content (under a
|
||||
directory called `symbols`; it\'s an XKB peculiarity that will help with
|
||||
testing):
|
||||
|
||||
```nix
|
||||
xkb_symbols "us-greek"
|
||||
{
|
||||
include "us(basic)" // includes the base US keys
|
||||
include "level3(ralt_switch)" // configures right alt as a third level switch
|
||||
|
||||
key <LatA> { [ a, A, Greek_alpha ] };
|
||||
key <LatB> { [ b, B, Greek_beta ] };
|
||||
key <LatG> { [ g, G, Greek_gamma ] };
|
||||
key <LatD> { [ d, D, Greek_delta ] };
|
||||
key <LatZ> { [ z, Z, Greek_zeta ] };
|
||||
};
|
||||
```
|
||||
|
||||
A minimal layout specification must include the following:
|
||||
|
||||
```nix
|
||||
services.xserver.extraLayouts.us-greek = {
|
||||
description = "US layout with alt-gr greek";
|
||||
languages = [ "eng" ];
|
||||
symbolsFile = /yourpath/symbols/us-greek;
|
||||
};
|
||||
```
|
||||
|
||||
::: {.note}
|
||||
The name (after `extraLayouts.`) should match the one given to the
|
||||
`xkb_symbols` block.
|
||||
:::
|
||||
|
||||
Applying this customization requires rebuilding several packages, and a
|
||||
broken XKB file can lead to the X session crashing at login. Therefore,
|
||||
you\'re strongly advised to **test your layout before applying it**:
|
||||
|
||||
```ShellSession
|
||||
$ nix-shell -p xorg.xkbcomp
|
||||
$ setxkbmap -I/yourpath us-greek -print | xkbcomp -I/yourpath - $DISPLAY
|
||||
```
|
||||
|
||||
You can inspect the predefined XKB files for examples:
|
||||
|
||||
```ShellSession
|
||||
$ echo "$(nix-build --no-out-link '<nixpkgs>' -A xorg.xkeyboardconfig)/etc/X11/xkb/"
|
||||
```
|
||||
|
||||
Once the configuration is applied, and you did a logout/login cycle, the
|
||||
layout should be ready to use. You can try it by e.g. running
|
||||
`setxkbmap us-greek` and then type `<alt>+a` (it may not get applied in
|
||||
your terminal straight away). To change the default, the usual
|
||||
`services.xserver.layout` option can still be used.
|
||||
|
||||
A layout can have several other components besides `xkb_symbols`, for
|
||||
example we will define new keycodes for some multimedia key and bind
|
||||
these to some symbol.
|
||||
|
||||
Use the *xev* utility from `pkgs.xorg.xev` to find the codes of the keys
|
||||
of interest, then create a `media-key` file to hold the keycodes
|
||||
definitions
|
||||
|
||||
```nix
|
||||
xkb_keycodes "media"
|
||||
{
|
||||
<volUp> = 123;
|
||||
<volDown> = 456;
|
||||
}
|
||||
```
|
||||
|
||||
Now use the newly define keycodes in `media-sym`:
|
||||
|
||||
```nix
|
||||
xkb_symbols "media"
|
||||
{
|
||||
key.type = "ONE_LEVEL";
|
||||
key <volUp> { [ XF86AudioLowerVolume ] };
|
||||
key <volDown> { [ XF86AudioRaiseVolume ] };
|
||||
}
|
||||
```
|
||||
|
||||
As before, to install the layout do
|
||||
|
||||
```nix
|
||||
services.xserver.extraLayouts.media = {
|
||||
description = "Multimedia keys remapping";
|
||||
languages = [ "eng" ];
|
||||
symbolsFile = /path/to/media-key;
|
||||
keycodesFile = /path/to/media-sym;
|
||||
};
|
||||
```
|
||||
|
||||
::: {.note}
|
||||
The function `pkgs.writeText <filename> <content>` can be useful if you
|
||||
prefer to keep the layout definitions inside the NixOS configuration.
|
||||
:::
|
||||
|
||||
Unfortunately, the Xorg server does not (currently) support setting a
|
||||
keymap directly but relies instead on XKB rules to select the matching
|
||||
components (keycodes, types, \...) of a layout. This means that
|
||||
components other than symbols won\'t be loaded by default. As a
|
||||
workaround, you can set the keymap using `setxkbmap` at the start of the
|
||||
session with:
|
||||
|
||||
```nix
|
||||
services.xserver.displayManager.sessionCommands = "setxkbmap -keycodes media";
|
||||
```
|
||||
|
||||
If you are manually starting the X server, you should set the argument
|
||||
`-xkbdir /etc/X11/xkb`, otherwise X won\'t find your layout files. For
|
||||
example with `xinit` run
|
||||
|
||||
```ShellSession
|
||||
$ xinit -- -xkbdir /etc/X11/xkb
|
||||
```
|
||||
|
||||
To learn how to write layouts take a look at the XKB [documentation
|
||||
](https://www.x.org/releases/current/doc/xorg-docs/input/XKB-Enhancing.html#Defining_New_Layouts).
|
||||
More example layouts can also be found [here
|
||||
](https://wiki.archlinux.org/index.php/X_KeyBoard_extension#Basic_examples).
|
||||
52
nixos/doc/manual/configuration/xfce.chapter.md
Normal file
52
nixos/doc/manual/configuration/xfce.chapter.md
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
# Xfce Desktop Environment {#sec-xfce}
|
||||
|
||||
To enable the Xfce Desktop Environment, set
|
||||
|
||||
```nix
|
||||
services.xserver.desktopManager.xfce.enable = true;
|
||||
services.xserver.displayManager.defaultSession = "xfce";
|
||||
```
|
||||
|
||||
Optionally, *picom* can be enabled for nice graphical effects, some
|
||||
example settings:
|
||||
|
||||
```nix
|
||||
services.picom = {
|
||||
enable = true;
|
||||
fade = true;
|
||||
inactiveOpacity = 0.9;
|
||||
shadow = true;
|
||||
fadeDelta = 4;
|
||||
};
|
||||
```
|
||||
|
||||
Some Xfce programs are not installed automatically. To install them
|
||||
manually (system wide), put them into your
|
||||
[](#opt-environment.systemPackages) from `pkgs.xfce`.
|
||||
|
||||
## Thunar Plugins {#sec-xfce-thunar-plugins .unnumbered}
|
||||
|
||||
If you\'d like to add extra plugins to Thunar, add them to
|
||||
[](#opt-services.xserver.desktopManager.xfce.thunarPlugins).
|
||||
You shouldn\'t just add them to [](#opt-environment.systemPackages).
|
||||
|
||||
## Troubleshooting {#sec-xfce-troubleshooting .unnumbered}
|
||||
|
||||
Even after enabling udisks2, volume management might not work. Thunar
|
||||
and/or the desktop takes time to show up. Thunar will spit out this kind
|
||||
of message on start (look at `journalctl --user -b`).
|
||||
|
||||
```plain
|
||||
Thunar:2410): GVFS-RemoteVolumeMonitor-WARNING **: remote volume monitor with dbus name org.gtk.Private.UDisks2VolumeMonitor is not supported
|
||||
```
|
||||
|
||||
This is caused by some needed GNOME services not running. This is all
|
||||
fixed by enabling \"Launch GNOME services on startup\" in the Advanced
|
||||
tab of the Session and Startup settings panel. Alternatively, you can
|
||||
run this command to do the same thing.
|
||||
|
||||
```ShellSession
|
||||
$ xfconf-query -c xfce4-session -p /compat/LaunchGNOME -s true
|
||||
```
|
||||
|
||||
A log-out and re-log will be needed for this to take effect.
|
||||
13
nixos/doc/manual/contributing-to-this-manual.chapter.md
Normal file
13
nixos/doc/manual/contributing-to-this-manual.chapter.md
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# Contributing to this manual {#chap-contributing}
|
||||
|
||||
The DocBook and CommonMark sources of NixOS' manual are in the [nixos/doc/manual](https://github.com/NixOS/nixpkgs/tree/master/nixos/doc/manual) subdirectory of the [Nixpkgs](https://github.com/NixOS/nixpkgs) repository.
|
||||
|
||||
You can quickly check your edits with the following:
|
||||
|
||||
```ShellSession
|
||||
$ cd /path/to/nixpkgs
|
||||
$ ./nixos/doc/manual/md-to-db.sh
|
||||
$ nix-build nixos/release.nix -A manual.x86_64-linux
|
||||
```
|
||||
|
||||
If the build succeeds, the manual will be in `./result/share/doc/nixos/index.html`.
|
||||
268
nixos/doc/manual/default.nix
Normal file
268
nixos/doc/manual/default.nix
Normal file
|
|
@ -0,0 +1,268 @@
|
|||
{ pkgs
|
||||
, options
|
||||
, config
|
||||
, version
|
||||
, revision
|
||||
, extraSources ? []
|
||||
, baseOptionsJSON ? null
|
||||
, warningsAreErrors ? true
|
||||
, prefix ? ../../..
|
||||
}:
|
||||
|
||||
with pkgs;
|
||||
|
||||
let
|
||||
lib = pkgs.lib;
|
||||
|
||||
docbook_xsl_ns = pkgs.docbook-xsl-ns.override {
|
||||
withManOptDedupPatch = true;
|
||||
};
|
||||
|
||||
# We need to strip references to /nix/store/* from options,
|
||||
# including any `extraSources` if some modules came from elsewhere,
|
||||
# or else the build will fail.
|
||||
#
|
||||
# E.g. if some `options` came from modules in ${pkgs.customModules}/nix,
|
||||
# you'd need to include `extraSources = [ pkgs.customModules ]`
|
||||
prefixesToStrip = map (p: "${toString p}/") ([ prefix ] ++ extraSources);
|
||||
stripAnyPrefixes = lib.flip (lib.foldr lib.removePrefix) prefixesToStrip;
|
||||
|
||||
optionsDoc = buildPackages.nixosOptionsDoc {
|
||||
inherit options revision baseOptionsJSON warningsAreErrors;
|
||||
transformOptions = opt: opt // {
|
||||
# Clean up declaration sites to not refer to the NixOS source tree.
|
||||
declarations = map stripAnyPrefixes opt.declarations;
|
||||
};
|
||||
};
|
||||
|
||||
sources = lib.sourceFilesBySuffices ./. [".xml"];
|
||||
|
||||
modulesDoc = builtins.toFile "modules.xml" ''
|
||||
<section xmlns:xi="http://www.w3.org/2001/XInclude" id="modules">
|
||||
${(lib.concatMapStrings (path: ''
|
||||
<xi:include href="${path}" />
|
||||
'') (lib.catAttrs "value" config.meta.doc))}
|
||||
</section>
|
||||
'';
|
||||
|
||||
generatedSources = runCommand "generated-docbook" {} ''
|
||||
mkdir $out
|
||||
ln -s ${modulesDoc} $out/modules.xml
|
||||
ln -s ${optionsDoc.optionsDocBook} $out/options-db.xml
|
||||
printf "%s" "${version}" > $out/version
|
||||
'';
|
||||
|
||||
copySources =
|
||||
''
|
||||
cp -prd $sources/* . # */
|
||||
ln -s ${generatedSources} ./generated
|
||||
chmod -R u+w .
|
||||
'';
|
||||
|
||||
toc = builtins.toFile "toc.xml"
|
||||
''
|
||||
<toc role="chunk-toc">
|
||||
<d:tocentry xmlns:d="http://docbook.org/ns/docbook" linkend="book-nixos-manual"><?dbhtml filename="index.html"?>
|
||||
<d:tocentry linkend="ch-options"><?dbhtml filename="options.html"?></d:tocentry>
|
||||
<d:tocentry linkend="ch-release-notes"><?dbhtml filename="release-notes.html"?></d:tocentry>
|
||||
</d:tocentry>
|
||||
</toc>
|
||||
'';
|
||||
|
||||
manualXsltprocOptions = toString [
|
||||
"--param section.autolabel 1"
|
||||
"--param section.label.includes.component.label 1"
|
||||
"--stringparam html.stylesheet 'style.css overrides.css highlightjs/mono-blue.css'"
|
||||
"--stringparam html.script './highlightjs/highlight.pack.js ./highlightjs/loader.js'"
|
||||
"--param xref.with.number.and.title 1"
|
||||
"--param toc.section.depth 0"
|
||||
"--param generate.consistent.ids 1"
|
||||
"--stringparam admon.style ''"
|
||||
"--stringparam callout.graphics.extension .svg"
|
||||
"--stringparam current.docid manual"
|
||||
"--param chunk.section.depth 0"
|
||||
"--param chunk.first.sections 1"
|
||||
"--param use.id.as.filename 1"
|
||||
"--stringparam chunk.toc ${toc}"
|
||||
];
|
||||
|
||||
manual-combined = runCommand "nixos-manual-combined"
|
||||
{ inherit sources;
|
||||
nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin ];
|
||||
meta.description = "The NixOS manual as plain docbook XML";
|
||||
}
|
||||
''
|
||||
${copySources}
|
||||
|
||||
xmllint --xinclude --output ./manual-combined.xml ./manual.xml
|
||||
xmllint --xinclude --noxincludenode \
|
||||
--output ./man-pages-combined.xml ./man-pages.xml
|
||||
|
||||
# outputs the context of an xmllint error output
|
||||
# LEN lines around the failing line are printed
|
||||
function context {
|
||||
# length of context
|
||||
local LEN=6
|
||||
# lines to print before error line
|
||||
local BEFORE=4
|
||||
|
||||
# xmllint output lines are:
|
||||
# file.xml:1234: there was an error on line 1234
|
||||
while IFS=':' read -r file line rest; do
|
||||
echo
|
||||
if [[ -n "$rest" ]]; then
|
||||
echo "$file:$line:$rest"
|
||||
local FROM=$(($line>$BEFORE ? $line - $BEFORE : 1))
|
||||
# number lines & filter context
|
||||
nl --body-numbering=a "$file" | sed -n "$FROM,+$LEN p"
|
||||
else
|
||||
if [[ -n "$line" ]]; then
|
||||
echo "$file:$line"
|
||||
else
|
||||
echo "$file"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
function lintrng {
|
||||
xmllint --debug --noout --nonet \
|
||||
--relaxng ${docbook5}/xml/rng/docbook/docbook.rng \
|
||||
"$1" \
|
||||
2>&1 | context 1>&2
|
||||
# ^ redirect assumes xmllint doesn’t print to stdout
|
||||
}
|
||||
|
||||
lintrng manual-combined.xml
|
||||
lintrng man-pages-combined.xml
|
||||
|
||||
mkdir $out
|
||||
cp manual-combined.xml $out/
|
||||
cp man-pages-combined.xml $out/
|
||||
'';
|
||||
|
||||
olinkDB = runCommand "manual-olinkdb"
|
||||
{ inherit sources;
|
||||
nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin ];
|
||||
}
|
||||
''
|
||||
xsltproc \
|
||||
${manualXsltprocOptions} \
|
||||
--stringparam collect.xref.targets only \
|
||||
--stringparam targets.filename "$out/manual.db" \
|
||||
--nonet \
|
||||
${docbook_xsl_ns}/xml/xsl/docbook/xhtml/chunktoc.xsl \
|
||||
${manual-combined}/manual-combined.xml
|
||||
|
||||
cat > "$out/olinkdb.xml" <<EOF
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE targetset SYSTEM
|
||||
"file://${docbook_xsl_ns}/xml/xsl/docbook/common/targetdatabase.dtd" [
|
||||
<!ENTITY manualtargets SYSTEM "file://$out/manual.db">
|
||||
]>
|
||||
<targetset>
|
||||
<targetsetinfo>
|
||||
Allows for cross-referencing olinks between the manpages
|
||||
and manual.
|
||||
</targetsetinfo>
|
||||
|
||||
<document targetdoc="manual">&manualtargets;</document>
|
||||
</targetset>
|
||||
EOF
|
||||
'';
|
||||
|
||||
in rec {
|
||||
inherit generatedSources;
|
||||
|
||||
inherit (optionsDoc) optionsJSON optionsNix optionsDocBook;
|
||||
|
||||
# Generate the NixOS manual.
|
||||
manualHTML = runCommand "nixos-manual-html"
|
||||
{ inherit sources;
|
||||
nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin ];
|
||||
meta.description = "The NixOS manual in HTML format";
|
||||
allowedReferences = ["out"];
|
||||
}
|
||||
''
|
||||
# Generate the HTML manual.
|
||||
dst=$out/share/doc/nixos
|
||||
mkdir -p $dst
|
||||
xsltproc \
|
||||
${manualXsltprocOptions} \
|
||||
--stringparam target.database.document "${olinkDB}/olinkdb.xml" \
|
||||
--stringparam id.warnings "1" \
|
||||
--nonet --output $dst/ \
|
||||
${docbook_xsl_ns}/xml/xsl/docbook/xhtml/chunktoc.xsl \
|
||||
${manual-combined}/manual-combined.xml \
|
||||
|& tee xsltproc.out
|
||||
grep "^ID recommended on" xsltproc.out &>/dev/null && echo "error: some IDs are missing" && false
|
||||
rm xsltproc.out
|
||||
|
||||
mkdir -p $dst/images/callouts
|
||||
cp ${docbook_xsl_ns}/xml/xsl/docbook/images/callouts/*.svg $dst/images/callouts/
|
||||
|
||||
cp ${../../../doc/style.css} $dst/style.css
|
||||
cp ${../../../doc/overrides.css} $dst/overrides.css
|
||||
cp -r ${pkgs.documentation-highlighter} $dst/highlightjs
|
||||
|
||||
mkdir -p $out/nix-support
|
||||
echo "nix-build out $out" >> $out/nix-support/hydra-build-products
|
||||
echo "doc manual $dst" >> $out/nix-support/hydra-build-products
|
||||
''; # */
|
||||
|
||||
# Alias for backward compatibility. TODO(@oxij): remove eventually.
|
||||
manual = manualHTML;
|
||||
|
||||
# Index page of the NixOS manual.
|
||||
manualHTMLIndex = "${manualHTML}/share/doc/nixos/index.html";
|
||||
|
||||
manualEpub = runCommand "nixos-manual-epub"
|
||||
{ inherit sources;
|
||||
nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin buildPackages.zip ];
|
||||
}
|
||||
''
|
||||
# Generate the epub manual.
|
||||
dst=$out/share/doc/nixos
|
||||
|
||||
xsltproc \
|
||||
${manualXsltprocOptions} \
|
||||
--stringparam target.database.document "${olinkDB}/olinkdb.xml" \
|
||||
--nonet --xinclude --output $dst/epub/ \
|
||||
${docbook_xsl_ns}/xml/xsl/docbook/epub/docbook.xsl \
|
||||
${manual-combined}/manual-combined.xml
|
||||
|
||||
mkdir -p $dst/epub/OEBPS/images/callouts
|
||||
cp -r ${docbook_xsl_ns}/xml/xsl/docbook/images/callouts/*.svg $dst/epub/OEBPS/images/callouts # */
|
||||
echo "application/epub+zip" > mimetype
|
||||
manual="$dst/nixos-manual.epub"
|
||||
zip -0Xq "$manual" mimetype
|
||||
cd $dst/epub && zip -Xr9D "$manual" *
|
||||
|
||||
rm -rf $dst/epub
|
||||
|
||||
mkdir -p $out/nix-support
|
||||
echo "doc-epub manual $manual" >> $out/nix-support/hydra-build-products
|
||||
'';
|
||||
|
||||
|
||||
# Generate the NixOS manpages.
|
||||
manpages = runCommand "nixos-manpages"
|
||||
{ inherit sources;
|
||||
nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin ];
|
||||
allowedReferences = ["out"];
|
||||
}
|
||||
''
|
||||
# Generate manpages.
|
||||
mkdir -p $out/share/man
|
||||
xsltproc --nonet \
|
||||
--maxdepth 6000 \
|
||||
--param man.output.in.separate.dir 1 \
|
||||
--param man.output.base.dir "'$out/share/man/'" \
|
||||
--param man.endnotes.are.numbered 0 \
|
||||
--param man.break.after.slash 1 \
|
||||
--stringparam target.database.document "${olinkDB}/olinkdb.xml" \
|
||||
${docbook_xsl_ns}/xml/xsl/docbook/manpages/docbook.xsl \
|
||||
${manual-combined}/man-pages-combined.xml
|
||||
'';
|
||||
|
||||
}
|
||||
72
nixos/doc/manual/development/activation-script.section.md
Normal file
72
nixos/doc/manual/development/activation-script.section.md
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
# Activation script {#sec-activation-script}
|
||||
|
||||
The activation script is a bash script called to activate the new
|
||||
configuration which resides in a NixOS system in `$out/activate`. Since its
|
||||
contents depend on your system configuration, the contents may differ.
|
||||
This chapter explains how the script works in general and some common NixOS
|
||||
snippets. Please be aware that the script is executed on every boot and system
|
||||
switch, so tasks that can be performed in other places should be performed
|
||||
there (for example letting a directory of a service be created by systemd using
|
||||
mechanisms like `StateDirectory`, `CacheDirectory`, ... or if that's not
|
||||
possible using `preStart` of the service).
|
||||
|
||||
Activation scripts are defined as snippets using
|
||||
[](#opt-system.activationScripts). They can either be a simple multiline string
|
||||
or an attribute set that can depend on other snippets. The builder for the
|
||||
activation script will take these dependencies into account and order the
|
||||
snippets accordingly. As a simple example:
|
||||
|
||||
```nix
|
||||
system.activationScripts.my-activation-script = {
|
||||
deps = [ "etc" ];
|
||||
# supportsDryActivation = true;
|
||||
text = ''
|
||||
echo "Hallo i bims"
|
||||
'';
|
||||
};
|
||||
```
|
||||
|
||||
This example creates an activation script snippet that is run after the `etc`
|
||||
snippet. The special variable `supportsDryActivation` can be set so the snippet
|
||||
is also run when `nixos-rebuild dry-activate` is run. To differentiate between
|
||||
real and dry activation, the `$NIXOS_ACTION` environment variable can be
|
||||
read which is set to `dry-activate` when a dry activation is done.
|
||||
|
||||
An activation script can write to special files instructing
|
||||
`switch-to-configuration` to restart/reload units. The script will take these
|
||||
requests into account and will incorperate the unit configuration as described
|
||||
above. This means that the activation script will "fake" a modified unit file
|
||||
and `switch-to-configuration` will act accordingly. By doing so, configuration
|
||||
like [systemd.services.\<name\>.restartIfChanged](#opt-systemd.services) is
|
||||
respected. Since the activation script is run **after** services are already
|
||||
stopped, [systemd.services.\<name\>.stopIfChanged](#opt-systemd.services)
|
||||
cannot be taken into account anymore and the unit is always restarted instead
|
||||
of being stopped and started afterwards.
|
||||
|
||||
The files that can be written to are `/run/nixos/activation-restart-list` and
|
||||
`/run/nixos/activation-reload-list` with their respective counterparts for
|
||||
dry activation being `/run/nixos/dry-activation-restart-list` and
|
||||
`/run/nixos/dry-activation-reload-list`. Those files can contain
|
||||
newline-separated lists of unit names where duplicates are being ignored. These
|
||||
files are not create automatically and activation scripts must take the
|
||||
possiblility into account that they have to create them first.
|
||||
|
||||
## NixOS snippets {#sec-activation-script-nixos-snippets}
|
||||
|
||||
There are some snippets NixOS enables by default because disabling them would
|
||||
most likely break you system. This section lists a few of them and what they
|
||||
do:
|
||||
|
||||
- `binsh` creates `/bin/sh` which points to the runtime shell
|
||||
- `etc` sets up the contents of `/etc`, this includes systemd units and
|
||||
excludes `/etc/passwd`, `/etc/group`, and `/etc/shadow` (which are managed by
|
||||
the `users` snippet)
|
||||
- `hostname` sets the system's hostname in the kernel (not in `/etc`)
|
||||
- `modprobe` sets the path to the `modprobe` binary for module auto-loading
|
||||
- `nix` prepares the nix store and adds a default initial channel
|
||||
- `specialfs` is responsible for mounting filesystems like `/proc` and `sys`
|
||||
- `users` creates and removes users and groups by managing `/etc/passwd`,
|
||||
`/etc/group` and `/etc/shadow`. This also creates home directories
|
||||
- `usrbinenv` creates `/usr/bin/env`
|
||||
- `var` creates some directories in `/var` that are not service-specific
|
||||
- `wrappers` creates setuid wrappers like `ping` and `sudo`
|
||||
40
nixos/doc/manual/development/assertions.section.md
Normal file
40
nixos/doc/manual/development/assertions.section.md
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
# Warnings and Assertions {#sec-assertions}
|
||||
|
||||
When configuration problems are detectable in a module, it is a good idea to write an assertion or warning. Doing so provides clear feedback to the user and prevents errors after the build.
|
||||
|
||||
Although Nix has the `abort` and `builtins.trace` [functions](https://nixos.org/nix/manual/#ssec-builtins) to perform such tasks, they are not ideally suited for NixOS modules. Instead of these functions, you can declare your warnings and assertions using the NixOS module system.
|
||||
|
||||
## Warnings {#sec-assertions-warnings}
|
||||
|
||||
This is an example of using `warnings`.
|
||||
|
||||
```nix
|
||||
{ config, lib, ... }:
|
||||
{
|
||||
config = lib.mkIf config.services.foo.enable {
|
||||
warnings =
|
||||
if config.services.foo.bar
|
||||
then [ ''You have enabled the bar feature of the foo service.
|
||||
This is known to cause some specific problems in certain situations.
|
||||
'' ]
|
||||
else [];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Assertions {#sec-assertions-assetions}
|
||||
|
||||
This example, extracted from the [`syslogd` module](https://github.com/NixOS/nixpkgs/blob/release-17.09/nixos/modules/services/logging/syslogd.nix) shows how to use `assertions`. Since there can only be one active syslog daemon at a time, an assertion is useful to prevent such a broken system from being built.
|
||||
|
||||
```nix
|
||||
{ config, lib, ... }:
|
||||
{
|
||||
config = lib.mkIf config.services.syslogd.enable {
|
||||
assertions =
|
||||
[ { assertion = !config.services.rsyslogd.enable;
|
||||
message = "rsyslogd conflicts with syslogd";
|
||||
}
|
||||
];
|
||||
}
|
||||
}
|
||||
```
|
||||
74
nixos/doc/manual/development/building-parts.chapter.md
Normal file
74
nixos/doc/manual/development/building-parts.chapter.md
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
# Building Specific Parts of NixOS {#sec-building-parts}
|
||||
|
||||
With the command `nix-build`, you can build specific parts of your NixOS
|
||||
configuration. This is done as follows:
|
||||
|
||||
```ShellSession
|
||||
$ cd /path/to/nixpkgs/nixos
|
||||
$ nix-build -A config.option
|
||||
```
|
||||
|
||||
where `option` is a NixOS option with type "derivation" (i.e. something
|
||||
that can be built). Attributes of interest include:
|
||||
|
||||
`system.build.toplevel`
|
||||
|
||||
: The top-level option that builds the entire NixOS system. Everything
|
||||
else in your configuration is indirectly pulled in by this option.
|
||||
This is what `nixos-rebuild` builds and what `/run/current-system`
|
||||
points to afterwards.
|
||||
|
||||
A shortcut to build this is:
|
||||
|
||||
```ShellSession
|
||||
$ nix-build -A system
|
||||
```
|
||||
|
||||
`system.build.manual.manualHTML`
|
||||
|
||||
: The NixOS manual.
|
||||
|
||||
`system.build.etc`
|
||||
|
||||
: A tree of symlinks that form the static parts of `/etc`.
|
||||
|
||||
`system.build.initialRamdisk` , `system.build.kernel`
|
||||
|
||||
: The initial ramdisk and kernel of the system. This allows a quick
|
||||
way to test whether the kernel and the initial ramdisk boot
|
||||
correctly, by using QEMU's `-kernel` and `-initrd` options:
|
||||
|
||||
```ShellSession
|
||||
$ nix-build -A config.system.build.initialRamdisk -o initrd
|
||||
$ nix-build -A config.system.build.kernel -o kernel
|
||||
$ qemu-system-x86_64 -kernel ./kernel/bzImage -initrd ./initrd/initrd -hda /dev/null
|
||||
```
|
||||
|
||||
`system.build.nixos-rebuild` , `system.build.nixos-install` , `system.build.nixos-generate-config`
|
||||
|
||||
: These build the corresponding NixOS commands.
|
||||
|
||||
`systemd.units.unit-name.unit`
|
||||
|
||||
: This builds the unit with the specified name. Note that since unit
|
||||
names contain dots (e.g. `httpd.service`), you need to put them
|
||||
between quotes, like this:
|
||||
|
||||
```ShellSession
|
||||
$ nix-build -A 'config.systemd.units."httpd.service".unit'
|
||||
```
|
||||
|
||||
You can also test individual units, without rebuilding the whole
|
||||
system, by putting them in `/run/systemd/system`:
|
||||
|
||||
```ShellSession
|
||||
$ cp $(nix-build -A 'config.systemd.units."httpd.service".unit')/httpd.service \
|
||||
/run/systemd/system/tmp-httpd.service
|
||||
# systemctl daemon-reload
|
||||
# systemctl start tmp-httpd.service
|
||||
```
|
||||
|
||||
Note that the unit must not have the same name as any unit in
|
||||
`/etc/systemd/system` since those take precedence over
|
||||
`/run/systemd/system`. That's why the unit is installed as
|
||||
`tmp-httpd.service` here.
|
||||
19
nixos/doc/manual/development/development.xml
Normal file
19
nixos/doc/manual/development/development.xml
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<part xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
version="5.0"
|
||||
xml:id="ch-development">
|
||||
<title>Development</title>
|
||||
<partintro xml:id="ch-development-intro">
|
||||
<para>
|
||||
This chapter describes how you can modify and extend NixOS.
|
||||
</para>
|
||||
</partintro>
|
||||
<xi:include href="../from_md/development/sources.chapter.xml" />
|
||||
<xi:include href="../from_md/development/writing-modules.chapter.xml" />
|
||||
<xi:include href="../from_md/development/building-parts.chapter.xml" />
|
||||
<xi:include href="../from_md/development/what-happens-during-a-system-switch.chapter.xml" />
|
||||
<xi:include href="../from_md/development/writing-documentation.chapter.xml" />
|
||||
<xi:include href="../from_md/development/nixos-tests.chapter.xml" />
|
||||
<xi:include href="../from_md/development/testing-installer.chapter.xml" />
|
||||
</part>
|
||||
79
nixos/doc/manual/development/freeform-modules.section.md
Normal file
79
nixos/doc/manual/development/freeform-modules.section.md
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
# Freeform modules {#sec-freeform-modules}
|
||||
|
||||
Freeform modules allow you to define values for option paths that have
|
||||
not been declared explicitly. This can be used to add attribute-specific
|
||||
types to what would otherwise have to be `attrsOf` options in order to
|
||||
accept all attribute names.
|
||||
|
||||
This feature can be enabled by using the attribute `freeformType` to
|
||||
define a freeform type. By doing this, all assignments without an
|
||||
associated option will be merged using the freeform type and combined
|
||||
into the resulting `config` set. Since this feature nullifies name
|
||||
checking for entire option trees, it is only recommended for use in
|
||||
submodules.
|
||||
|
||||
::: {#ex-freeform-module .example}
|
||||
::: {.title}
|
||||
**Example: Freeform submodule**
|
||||
:::
|
||||
The following shows a submodule assigning a freeform type that allows
|
||||
arbitrary attributes with `str` values below `settings`, but also
|
||||
declares an option for the `settings.port` attribute to have it
|
||||
type-checked and assign a default value. See
|
||||
[Example: Declaring a type-checked `settings` attribute](#ex-settings-typed-attrs)
|
||||
for a more complete example.
|
||||
|
||||
```nix
|
||||
{ lib, config, ... }: {
|
||||
|
||||
options.settings = lib.mkOption {
|
||||
type = lib.types.submodule {
|
||||
|
||||
freeformType = with lib.types; attrsOf str;
|
||||
|
||||
# We want this attribute to be checked for the correct type
|
||||
options.port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
# Declaring the option also allows defining a default value
|
||||
default = 8080;
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
And the following shows what such a module then allows
|
||||
|
||||
```nix
|
||||
{
|
||||
# Not a declared option, but the freeform type allows this
|
||||
settings.logLevel = "debug";
|
||||
|
||||
# Not allowed because the the freeform type only allows strings
|
||||
# settings.enable = true;
|
||||
|
||||
# Allowed because there is a port option declared
|
||||
settings.port = 80;
|
||||
|
||||
# Not allowed because the port option doesn't allow strings
|
||||
# settings.port = "443";
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
::: {.note}
|
||||
Freeform attributes cannot depend on other attributes of the same set
|
||||
without infinite recursion:
|
||||
|
||||
```nix
|
||||
{
|
||||
# This throws infinite recursion encountered
|
||||
settings.logLevel = lib.mkIf (config.settings.port == 80) "debug";
|
||||
}
|
||||
```
|
||||
|
||||
To prevent this, declare options for all attributes that need to depend
|
||||
on others. For above example this means to declare `logLevel` to be an
|
||||
option.
|
||||
:::
|
||||
46
nixos/doc/manual/development/importing-modules.section.md
Normal file
46
nixos/doc/manual/development/importing-modules.section.md
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
# Importing Modules {#sec-importing-modules}
|
||||
|
||||
Sometimes NixOS modules need to be used in configuration but exist
|
||||
outside of Nixpkgs. These modules can be imported:
|
||||
|
||||
```nix
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
imports =
|
||||
[ # Use a locally-available module definition in
|
||||
# ./example-module/default.nix
|
||||
./example-module
|
||||
];
|
||||
|
||||
services.exampleModule.enable = true;
|
||||
}
|
||||
```
|
||||
|
||||
The environment variable `NIXOS_EXTRA_MODULE_PATH` is an absolute path
|
||||
to a NixOS module that is included alongside the Nixpkgs NixOS modules.
|
||||
Like any NixOS module, this module can import additional modules:
|
||||
|
||||
```nix
|
||||
# ./module-list/default.nix
|
||||
[
|
||||
./example-module1
|
||||
./example-module2
|
||||
]
|
||||
```
|
||||
|
||||
```nix
|
||||
# ./extra-module/default.nix
|
||||
{ imports = import ./module-list.nix; }
|
||||
```
|
||||
|
||||
```nix
|
||||
# NIXOS_EXTRA_MODULE_PATH=/absolute/path/to/extra-module
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
# No `imports` needed
|
||||
|
||||
services.exampleModule1.enable = true;
|
||||
}
|
||||
```
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
# Linking NixOS tests to packages {#sec-linking-nixos-tests-to-packages}
|
||||
|
||||
You can link NixOS module tests to the packages that they exercised,
|
||||
so that the tests can be run automatically during code review when the package gets changed.
|
||||
This is
|
||||
[described in the nixpkgs manual](https://nixos.org/manual/nixpkgs/stable/#ssec-nixos-tests-linking).
|
||||
66
nixos/doc/manual/development/meta-attributes.section.md
Normal file
66
nixos/doc/manual/development/meta-attributes.section.md
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
# Meta Attributes {#sec-meta-attributes}
|
||||
|
||||
Like Nix packages, NixOS modules can declare meta-attributes to provide
|
||||
extra information. Module meta attributes are defined in the `meta.nix`
|
||||
special module.
|
||||
|
||||
`meta` is a top level attribute like `options` and `config`. Available
|
||||
meta-attributes are `maintainers`, `doc`, and `buildDocsInSandbox`.
|
||||
|
||||
Each of the meta-attributes must be defined at most once per module
|
||||
file.
|
||||
|
||||
```nix
|
||||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
options = {
|
||||
...
|
||||
};
|
||||
|
||||
config = {
|
||||
...
|
||||
};
|
||||
|
||||
meta = {
|
||||
maintainers = with lib.maintainers; [ ericsagnes ];
|
||||
doc = ./default.xml;
|
||||
buildDocsInSandbox = true;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
- `maintainers` contains a list of the module maintainers.
|
||||
|
||||
- `doc` points to a valid DocBook file containing the module
|
||||
documentation. Its contents is automatically added to
|
||||
[](#ch-configuration). Changes to a module documentation have to
|
||||
be checked to not break building the NixOS manual:
|
||||
|
||||
```ShellSession
|
||||
$ nix-build nixos/release.nix -A manual.x86_64-linux
|
||||
```
|
||||
|
||||
- `buildDocsInSandbox` indicates whether the option documentation for the
|
||||
module can be built in a derivation sandbox. This option is currently only
|
||||
honored for modules shipped by nixpkgs. User modules and modules taken from
|
||||
`NIXOS_EXTRA_MODULE_PATH` are always built outside of the sandbox, as has
|
||||
been the case in previous releases.
|
||||
|
||||
Building NixOS option documentation in a sandbox allows caching of the built
|
||||
documentation, which greatly decreases the amount of time needed to evaluate
|
||||
a system configuration that has NixOS documentation enabled. The sandbox also
|
||||
restricts which attributes may be referenced by documentation attributes
|
||||
(such as option descriptions) to the `options` and `lib` module arguments and
|
||||
the `pkgs.formats` attribute of the `pkgs` argument, `config` and the rest of
|
||||
`pkgs` are disallowed and will cause doc build failures when used. This
|
||||
restriction is necessary because we cannot reproduce the full nixpkgs
|
||||
instantiation with configuration and overlays from a system configuration
|
||||
inside the sandbox. The `options` argument only includes options of modules
|
||||
that are also built inside the sandbox, referencing an option of a module
|
||||
that isn't built in the sandbox is also forbidden.
|
||||
|
||||
The default is `true` and should usually not be changed; set it to `false`
|
||||
only if the module requires access to `pkgs` in its documentation (e.g.
|
||||
because it loads information from a linked package to build an option type)
|
||||
or if its documentation depends on other modules that also aren't sandboxed
|
||||
(e.g. by using types defined in the other module).
|
||||
13
nixos/doc/manual/development/nixos-tests.chapter.md
Normal file
13
nixos/doc/manual/development/nixos-tests.chapter.md
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# NixOS Tests {#sec-nixos-tests}
|
||||
|
||||
When you add some feature to NixOS, you should write a test for it.
|
||||
NixOS tests are kept in the directory `nixos/tests`, and are executed
|
||||
(using Nix) by a testing framework that automatically starts one or more
|
||||
virtual machines containing the NixOS system(s) required for the test.
|
||||
|
||||
```{=docbook}
|
||||
<xi:include href="writing-nixos-tests.section.xml" />
|
||||
<xi:include href="running-nixos-tests.section.xml" />
|
||||
<xi:include href="running-nixos-tests-interactively.section.xml" />
|
||||
<xi:include href="linking-nixos-tests-to-packages.section.xml" />
|
||||
```
|
||||
221
nixos/doc/manual/development/option-declarations.section.md
Normal file
221
nixos/doc/manual/development/option-declarations.section.md
Normal file
|
|
@ -0,0 +1,221 @@
|
|||
# Option Declarations {#sec-option-declarations}
|
||||
|
||||
An option declaration specifies the name, type and description of a
|
||||
NixOS configuration option. It is invalid to define an option that
|
||||
hasn't been declared in any module. An option declaration generally
|
||||
looks like this:
|
||||
|
||||
```nix
|
||||
options = {
|
||||
name = mkOption {
|
||||
type = type specification;
|
||||
default = default value;
|
||||
example = example value;
|
||||
description = "Description for use in the NixOS manual.";
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
The attribute names within the `name` attribute path must be camel
|
||||
cased in general but should, as an exception, match the [ package
|
||||
attribute name](https://nixos.org/nixpkgs/manual/#sec-package-naming)
|
||||
when referencing a Nixpkgs package. For example, the option
|
||||
`services.nix-serve.bindAddress` references the `nix-serve` Nixpkgs
|
||||
package.
|
||||
|
||||
The function `mkOption` accepts the following arguments.
|
||||
|
||||
`type`
|
||||
|
||||
: The type of the option (see [](#sec-option-types)). This
|
||||
argument is mandatory for nixpkgs modules. Setting this is highly
|
||||
recommended for the sake of documentation and type checking. In case it is
|
||||
not set, a fallback type with unspecified behavior is used.
|
||||
|
||||
`default`
|
||||
|
||||
: The default value used if no value is defined by any module. A
|
||||
default is not required; but if a default is not given, then users
|
||||
of the module will have to define the value of the option, otherwise
|
||||
an error will be thrown.
|
||||
|
||||
`defaultText`
|
||||
|
||||
: A textual representation of the default value to be rendered verbatim in
|
||||
the manual. Useful if the default value is a complex expression or depends
|
||||
on other values or packages.
|
||||
Use `lib.literalExpression` for a Nix expression, `lib.literalDocBook` for
|
||||
a plain English description in DocBook format.
|
||||
|
||||
`example`
|
||||
|
||||
: An example value that will be shown in the NixOS manual.
|
||||
You can use `lib.literalExpression` and `lib.literalDocBook` in the same way
|
||||
as in `defaultText`.
|
||||
|
||||
`description`
|
||||
|
||||
: A textual description of the option, in DocBook format, that will be
|
||||
included in the NixOS manual.
|
||||
|
||||
## Utility functions for common option patterns {#sec-option-declarations-util}
|
||||
|
||||
### `mkEnableOption` {#sec-option-declarations-util-mkEnableOption}
|
||||
|
||||
Creates an Option attribute set for a boolean value option i.e an
|
||||
option to be toggled on or off.
|
||||
|
||||
This function takes a single string argument, the name of the thing to be toggled.
|
||||
|
||||
The option's description is "Whether to enable \<name\>.".
|
||||
|
||||
For example:
|
||||
|
||||
::: {#ex-options-declarations-util-mkEnableOption-magic .example}
|
||||
```nix
|
||||
lib.mkEnableOption "magic"
|
||||
# is like
|
||||
lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
example = true;
|
||||
description = "Whether to enable magic.";
|
||||
}
|
||||
```
|
||||
|
||||
### `mkPackageOption` {#sec-option-declarations-util-mkPackageOption}
|
||||
|
||||
Usage:
|
||||
|
||||
```nix
|
||||
mkPackageOption pkgs "name" { default = [ "path" "in" "pkgs" ]; example = "literal example"; }
|
||||
```
|
||||
|
||||
Creates an Option attribute set for an option that specifies the package a module should use for some purpose.
|
||||
|
||||
**Note**: You shouldn’t necessarily make package options for all of your modules. You can always overwrite a specific package throughout nixpkgs by using [nixpkgs overlays](https://nixos.org/manual/nixpkgs/stable/#chap-overlays).
|
||||
|
||||
The default package is specified as a list of strings representing its attribute path in nixpkgs. Because of this, you need to pass nixpkgs itself as the first argument.
|
||||
|
||||
The second argument is the name of the option, used in the description "The \<name\> package to use.". You can also pass an example value, either a literal string or a package's attribute path.
|
||||
|
||||
You can omit the default path if the name of the option is also attribute path in nixpkgs.
|
||||
|
||||
::: {#ex-options-declarations-util-mkPackageOption .title}
|
||||
Examples:
|
||||
|
||||
::: {#ex-options-declarations-util-mkPackageOption-hello .example}
|
||||
```nix
|
||||
lib.mkPackageOption pkgs "hello" { }
|
||||
# is like
|
||||
lib.mkOption {
|
||||
type = lib.types.package;
|
||||
default = pkgs.hello;
|
||||
defaultText = lib.literalExpression "pkgs.hello";
|
||||
description = "The hello package to use.";
|
||||
}
|
||||
```
|
||||
|
||||
::: {#ex-options-declarations-util-mkPackageOption-ghc .example}
|
||||
```nix
|
||||
lib.mkPackageOption pkgs "GHC" {
|
||||
default = [ "ghc" ];
|
||||
example = "pkgs.haskell.package.ghc923.ghc.withPackages (hkgs: [ hkgs.primes ])";
|
||||
}
|
||||
# is like
|
||||
lib.mkOption {
|
||||
type = lib.types.package;
|
||||
default = pkgs.ghc;
|
||||
defaultText = lib.literalExpression "pkgs.ghc";
|
||||
example = lib.literalExpression "pkgs.haskell.package.ghc923.ghc.withPackages (hkgs: [ hkgs.primes ])";
|
||||
description = "The GHC package to use.";
|
||||
}
|
||||
```
|
||||
|
||||
## Extensible Option Types {#sec-option-declarations-eot}
|
||||
|
||||
Extensible option types is a feature that allow to extend certain types
|
||||
declaration through multiple module files. This feature only work with a
|
||||
restricted set of types, namely `enum` and `submodules` and any composed
|
||||
forms of them.
|
||||
|
||||
Extensible option types can be used for `enum` options that affects
|
||||
multiple modules, or as an alternative to related `enable` options.
|
||||
|
||||
As an example, we will take the case of display managers. There is a
|
||||
central display manager module for generic display manager options and a
|
||||
module file per display manager backend (sddm, gdm \...).
|
||||
|
||||
There are two approaches we could take with this module structure:
|
||||
|
||||
- Configuring the display managers independently by adding an enable
|
||||
option to every display manager module backend. (NixOS)
|
||||
|
||||
- Configuring the display managers in the central module by adding
|
||||
an option to select which display manager backend to use.
|
||||
|
||||
Both approaches have problems.
|
||||
|
||||
Making backends independent can quickly become hard to manage. For
|
||||
display managers, there can only be one enabled at a time, but the
|
||||
type system cannot enforce this restriction as there is no relation
|
||||
between each backend's `enable` option. As a result, this restriction
|
||||
has to be done explicitly by adding assertions in each display manager
|
||||
backend module.
|
||||
|
||||
On the other hand, managing the display manager backends in the
|
||||
central module will require changing the central module option every
|
||||
time a new backend is added or removed.
|
||||
|
||||
By using extensible option types, it is possible to create a placeholder
|
||||
option in the central module
|
||||
([Example: Extensible type placeholder in the service module](#ex-option-declaration-eot-service)),
|
||||
and to extend it in each backend module
|
||||
([Example: Extending `services.xserver.displayManager.enable` in the `gdm` module](#ex-option-declaration-eot-backend-gdm),
|
||||
[Example: Extending `services.xserver.displayManager.enable` in the `sddm` module](#ex-option-declaration-eot-backend-sddm)).
|
||||
|
||||
As a result, `displayManager.enable` option values can be added without
|
||||
changing the main service module file and the type system automatically
|
||||
enforces that there can only be a single display manager enabled.
|
||||
|
||||
::: {#ex-option-declaration-eot-service .example}
|
||||
::: {.title}
|
||||
**Example: Extensible type placeholder in the service module**
|
||||
:::
|
||||
```nix
|
||||
services.xserver.displayManager.enable = mkOption {
|
||||
description = "Display manager to use";
|
||||
type = with types; nullOr (enum [ ]);
|
||||
};
|
||||
```
|
||||
:::
|
||||
|
||||
::: {#ex-option-declaration-eot-backend-gdm .example}
|
||||
::: {.title}
|
||||
**Example: Extending `services.xserver.displayManager.enable` in the `gdm` module**
|
||||
:::
|
||||
```nix
|
||||
services.xserver.displayManager.enable = mkOption {
|
||||
type = with types; nullOr (enum [ "gdm" ]);
|
||||
};
|
||||
```
|
||||
:::
|
||||
|
||||
::: {#ex-option-declaration-eot-backend-sddm .example}
|
||||
::: {.title}
|
||||
**Example: Extending `services.xserver.displayManager.enable` in the `sddm` module**
|
||||
:::
|
||||
```nix
|
||||
services.xserver.displayManager.enable = mkOption {
|
||||
type = with types; nullOr (enum [ "sddm" ]);
|
||||
};
|
||||
```
|
||||
:::
|
||||
|
||||
The placeholder declaration is a standard `mkOption` declaration, but it
|
||||
is important that extensible option declarations only use the `type`
|
||||
argument.
|
||||
|
||||
Extensible option types work with any of the composed variants of `enum`
|
||||
such as `with types; nullOr (enum [ "foo" "bar" ])` or `with types;
|
||||
listOf (enum [ "foo" "bar" ])`.
|
||||
91
nixos/doc/manual/development/option-def.section.md
Normal file
91
nixos/doc/manual/development/option-def.section.md
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
# Option Definitions {#sec-option-definitions}
|
||||
|
||||
Option definitions are generally straight-forward bindings of values to
|
||||
option names, like
|
||||
|
||||
```nix
|
||||
config = {
|
||||
services.httpd.enable = true;
|
||||
};
|
||||
```
|
||||
|
||||
However, sometimes you need to wrap an option definition or set of
|
||||
option definitions in a *property* to achieve certain effects:
|
||||
|
||||
## Delaying Conditionals {#sec-option-definitions-delaying-conditionals .unnumbered}
|
||||
|
||||
If a set of option definitions is conditional on the value of another
|
||||
option, you may need to use `mkIf`. Consider, for instance:
|
||||
|
||||
```nix
|
||||
config = if config.services.httpd.enable then {
|
||||
environment.systemPackages = [ ... ];
|
||||
...
|
||||
} else {};
|
||||
```
|
||||
|
||||
This definition will cause Nix to fail with an "infinite recursion"
|
||||
error. Why? Because the value of `config.services.httpd.enable` depends
|
||||
on the value being constructed here. After all, you could also write the
|
||||
clearly circular and contradictory:
|
||||
|
||||
```nix
|
||||
config = if config.services.httpd.enable then {
|
||||
services.httpd.enable = false;
|
||||
} else {
|
||||
services.httpd.enable = true;
|
||||
};
|
||||
```
|
||||
|
||||
The solution is to write:
|
||||
|
||||
```nix
|
||||
config = mkIf config.services.httpd.enable {
|
||||
environment.systemPackages = [ ... ];
|
||||
...
|
||||
};
|
||||
```
|
||||
|
||||
The special function `mkIf` causes the evaluation of the conditional to
|
||||
be "pushed down" into the individual definitions, as if you had written:
|
||||
|
||||
```nix
|
||||
config = {
|
||||
environment.systemPackages = if config.services.httpd.enable then [ ... ] else [];
|
||||
...
|
||||
};
|
||||
```
|
||||
|
||||
## Setting Priorities {#sec-option-definitions-setting-priorities .unnumbered}
|
||||
|
||||
A module can override the definitions of an option in other modules by
|
||||
setting a *priority*. All option definitions that do not have the lowest
|
||||
priority value are discarded. By default, option definitions have
|
||||
priority 1000. You can specify an explicit priority by using
|
||||
`mkOverride`, e.g.
|
||||
|
||||
```nix
|
||||
services.openssh.enable = mkOverride 10 false;
|
||||
```
|
||||
|
||||
This definition causes all other definitions with priorities above 10 to
|
||||
be discarded. The function `mkForce` is equal to `mkOverride 50`.
|
||||
|
||||
## Merging Configurations {#sec-option-definitions-merging .unnumbered}
|
||||
|
||||
In conjunction with `mkIf`, it is sometimes useful for a module to
|
||||
return multiple sets of option definitions, to be merged together as if
|
||||
they were declared in separate modules. This can be done using
|
||||
`mkMerge`:
|
||||
|
||||
```nix
|
||||
config = mkMerge
|
||||
[ # Unconditional stuff.
|
||||
{ environment.systemPackages = [ ... ];
|
||||
}
|
||||
# Conditional stuff.
|
||||
(mkIf config.services.bla.enable {
|
||||
environment.systemPackages = [ ... ];
|
||||
})
|
||||
];
|
||||
```
|
||||
587
nixos/doc/manual/development/option-types.section.md
Normal file
587
nixos/doc/manual/development/option-types.section.md
Normal file
|
|
@ -0,0 +1,587 @@
|
|||
# Options Types {#sec-option-types}
|
||||
|
||||
Option types are a way to put constraints on the values a module option
|
||||
can take. Types are also responsible of how values are merged in case of
|
||||
multiple value definitions.
|
||||
|
||||
## Basic Types {#sec-option-types-basic}
|
||||
|
||||
Basic types are the simplest available types in the module system. Basic
|
||||
types include multiple string types that mainly differ in how definition
|
||||
merging is handled.
|
||||
|
||||
`types.bool`
|
||||
|
||||
: A boolean, its values can be `true` or `false`.
|
||||
|
||||
`types.path`
|
||||
|
||||
: A filesystem path is anything that starts with a slash when
|
||||
coerced to a string. Even if derivations can be considered as
|
||||
paths, the more specific `types.package` should be preferred.
|
||||
|
||||
`types.package`
|
||||
|
||||
: A top-level store path. This can be an attribute set pointing
|
||||
to a store path, like a derivation or a flake input.
|
||||
|
||||
`types.anything`
|
||||
|
||||
: A type that accepts any value and recursively merges attribute sets
|
||||
together. This type is recommended when the option type is unknown.
|
||||
|
||||
::: {#ex-types-anything .example}
|
||||
::: {.title}
|
||||
**Example: `types.anything` Example**
|
||||
:::
|
||||
Two definitions of this type like
|
||||
|
||||
```nix
|
||||
{
|
||||
str = lib.mkDefault "foo";
|
||||
pkg.hello = pkgs.hello;
|
||||
fun.fun = x: x + 1;
|
||||
}
|
||||
```
|
||||
|
||||
```nix
|
||||
{
|
||||
str = lib.mkIf true "bar";
|
||||
pkg.gcc = pkgs.gcc;
|
||||
fun.fun = lib.mkForce (x: x + 2);
|
||||
}
|
||||
```
|
||||
|
||||
will get merged to
|
||||
|
||||
```nix
|
||||
{
|
||||
str = "bar";
|
||||
pkg.gcc = pkgs.gcc;
|
||||
pkg.hello = pkgs.hello;
|
||||
fun.fun = x: x + 2;
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
`types.raw`
|
||||
|
||||
: A type which doesn't do any checking, merging or nested evaluation. It
|
||||
accepts a single arbitrary value that is not recursed into, making it
|
||||
useful for values coming from outside the module system, such as package
|
||||
sets or arbitrary data. Options of this type are still evaluated according
|
||||
to priorities and conditionals, so `mkForce`, `mkIf` and co. still work on
|
||||
the option value itself, but not for any value nested within it. This type
|
||||
should only be used when checking, merging and nested evaluation are not
|
||||
desirable.
|
||||
|
||||
`types.optionType`
|
||||
|
||||
: The type of an option's type. Its merging operation ensures that nested
|
||||
options have the correct file location annotated, and that if possible,
|
||||
multiple option definitions are correctly merged together. The main use
|
||||
case is as the type of the `_module.freeformType` option.
|
||||
|
||||
`types.attrs`
|
||||
|
||||
: A free-form attribute set.
|
||||
|
||||
::: {.warning}
|
||||
This type will be deprecated in the future because it doesn\'t
|
||||
recurse into attribute sets, silently drops earlier attribute
|
||||
definitions, and doesn\'t discharge `lib.mkDefault`, `lib.mkIf`
|
||||
and co. For allowing arbitrary attribute sets, prefer
|
||||
`types.attrsOf types.anything` instead which doesn\'t have these
|
||||
problems.
|
||||
:::
|
||||
|
||||
Integer-related types:
|
||||
|
||||
`types.int`
|
||||
|
||||
: A signed integer.
|
||||
|
||||
`types.ints.{s8, s16, s32}`
|
||||
|
||||
: Signed integers with a fixed length (8, 16 or 32 bits). They go from
|
||||
−2^n/2 to
|
||||
2^n/2−1 respectively (e.g. `−128` to
|
||||
`127` for 8 bits).
|
||||
|
||||
`types.ints.unsigned`
|
||||
|
||||
: An unsigned integer (that is >= 0).
|
||||
|
||||
`types.ints.{u8, u16, u32}`
|
||||
|
||||
: Unsigned integers with a fixed length (8, 16 or 32 bits). They go
|
||||
from 0 to 2^n−1 respectively (e.g. `0`
|
||||
to `255` for 8 bits).
|
||||
|
||||
`types.ints.positive`
|
||||
|
||||
: A positive integer (that is > 0).
|
||||
|
||||
`types.port`
|
||||
|
||||
: A port number. This type is an alias to
|
||||
`types.ints.u16`.
|
||||
|
||||
String-related types:
|
||||
|
||||
`types.str`
|
||||
|
||||
: A string. Multiple definitions cannot be merged.
|
||||
|
||||
`types.lines`
|
||||
|
||||
: A string. Multiple definitions are concatenated with a new line
|
||||
`"\n"`.
|
||||
|
||||
`types.commas`
|
||||
|
||||
: A string. Multiple definitions are concatenated with a comma `","`.
|
||||
|
||||
`types.envVar`
|
||||
|
||||
: A string. Multiple definitions are concatenated with a collon `":"`.
|
||||
|
||||
`types.strMatching`
|
||||
|
||||
: A string matching a specific regular expression. Multiple
|
||||
definitions cannot be merged. The regular expression is processed
|
||||
using `builtins.match`.
|
||||
|
||||
## Value Types {#sec-option-types-value}
|
||||
|
||||
Value types are types that take a value parameter.
|
||||
|
||||
`types.enum` *`l`*
|
||||
|
||||
: One element of the list *`l`*, e.g. `types.enum [ "left" "right" ]`.
|
||||
Multiple definitions cannot be merged.
|
||||
|
||||
`types.separatedString` *`sep`*
|
||||
|
||||
: A string with a custom separator *`sep`*, e.g.
|
||||
`types.separatedString "|"`.
|
||||
|
||||
`types.ints.between` *`lowest highest`*
|
||||
|
||||
: An integer between *`lowest`* and *`highest`* (both inclusive). Useful
|
||||
for creating types like `types.port`.
|
||||
|
||||
`types.submodule` *`o`*
|
||||
|
||||
: A set of sub options *`o`*. *`o`* can be an attribute set, a function
|
||||
returning an attribute set, or a path to a file containing such a
|
||||
value. Submodules are used in composed types to create modular
|
||||
options. This is equivalent to
|
||||
`types.submoduleWith { modules = toList o; shorthandOnlyDefinesConfig = true; }`.
|
||||
Submodules are detailed in [Submodule](#section-option-types-submodule).
|
||||
|
||||
`types.submoduleWith` { *`modules`*, *`specialArgs`* ? {}, *`shorthandOnlyDefinesConfig`* ? false }
|
||||
|
||||
: Like `types.submodule`, but more flexible and with better defaults.
|
||||
It has parameters
|
||||
|
||||
- *`modules`* A list of modules to use by default for this
|
||||
submodule type. This gets combined with all option definitions
|
||||
to build the final list of modules that will be included.
|
||||
|
||||
::: {.note}
|
||||
Only options defined with this argument are included in rendered
|
||||
documentation.
|
||||
:::
|
||||
|
||||
- *`specialArgs`* An attribute set of extra arguments to be passed
|
||||
to the module functions. The option `_module.args` should be
|
||||
used instead for most arguments since it allows overriding.
|
||||
*`specialArgs`* should only be used for arguments that can\'t go
|
||||
through the module fixed-point, because of infinite recursion or
|
||||
other problems. An example is overriding the `lib` argument,
|
||||
because `lib` itself is used to define `_module.args`, which
|
||||
makes using `_module.args` to define it impossible.
|
||||
|
||||
- *`shorthandOnlyDefinesConfig`* Whether definitions of this type
|
||||
should default to the `config` section of a module (see
|
||||
[Example: Structure of NixOS Modules](#ex-module-syntax))
|
||||
if it is an attribute set. Enabling this only has a benefit
|
||||
when the submodule defines an option named `config` or `options`.
|
||||
In such a case it would allow the option to be set with
|
||||
`the-submodule.config = "value"` instead of requiring
|
||||
`the-submodule.config.config = "value"`. This is because
|
||||
only when modules *don\'t* set the `config` or `options`
|
||||
keys, all keys are interpreted as option definitions in the
|
||||
`config` section. Enabling this option implicitly puts all
|
||||
attributes in the `config` section.
|
||||
|
||||
With this option enabled, defining a non-`config` section
|
||||
requires using a function:
|
||||
`the-submodule = { ... }: { options = { ... }; }`.
|
||||
|
||||
## Composed Types {#sec-option-types-composed}
|
||||
|
||||
Composed types are types that take a type as parameter. `listOf
|
||||
int` and `either int str` are examples of composed types.
|
||||
|
||||
`types.listOf` *`t`*
|
||||
|
||||
: A list of *`t`* type, e.g. `types.listOf
|
||||
int`. Multiple definitions are merged with list concatenation.
|
||||
|
||||
`types.attrsOf` *`t`*
|
||||
|
||||
: An attribute set of where all the values are of *`t`* type. Multiple
|
||||
definitions result in the joined attribute set.
|
||||
|
||||
::: {.note}
|
||||
This type is *strict* in its values, which in turn means attributes
|
||||
cannot depend on other attributes. See `
|
||||
types.lazyAttrsOf` for a lazy version.
|
||||
:::
|
||||
|
||||
`types.lazyAttrsOf` *`t`*
|
||||
|
||||
: An attribute set of where all the values are of *`t`* type. Multiple
|
||||
definitions result in the joined attribute set. This is the lazy
|
||||
version of `types.attrsOf
|
||||
`, allowing attributes to depend on each other.
|
||||
|
||||
::: {.warning}
|
||||
This version does not fully support conditional definitions! With an
|
||||
option `foo` of this type and a definition
|
||||
`foo.attr = lib.mkIf false 10`, evaluating `foo ? attr` will return
|
||||
`true` even though it should be false. Accessing the value will then
|
||||
throw an error. For types *`t`* that have an `emptyValue` defined,
|
||||
that value will be returned instead of throwing an error. So if the
|
||||
type of `foo.attr` was `lazyAttrsOf (nullOr int)`, `null` would be
|
||||
returned instead for the same `mkIf false` definition.
|
||||
:::
|
||||
|
||||
`types.nullOr` *`t`*
|
||||
|
||||
: `null` or type *`t`*. Multiple definitions are merged according to
|
||||
type *`t`*.
|
||||
|
||||
`types.uniq` *`t`*
|
||||
|
||||
: Ensures that type *`t`* cannot be merged. It is used to ensure option
|
||||
definitions are declared only once.
|
||||
|
||||
`types.unique` `{ message = m }` *`t`*
|
||||
|
||||
: Ensures that type *`t`* cannot be merged. Prints the message *`m`*, after
|
||||
the line `The option <option path> is defined multiple times.` and before
|
||||
a list of definition locations.
|
||||
|
||||
`types.either` *`t1 t2`*
|
||||
|
||||
: Type *`t1`* or type *`t2`*, e.g. `with types; either int str`.
|
||||
Multiple definitions cannot be merged.
|
||||
|
||||
`types.oneOf` \[ *`t1 t2`* \... \]
|
||||
|
||||
: Type *`t1`* or type *`t2`* and so forth, e.g.
|
||||
`with types; oneOf [ int str bool ]`. Multiple definitions cannot be
|
||||
merged.
|
||||
|
||||
`types.coercedTo` *`from f to`*
|
||||
|
||||
: Type *`to`* or type *`from`* which will be coerced to type *`to`* using
|
||||
function *`f`* which takes an argument of type *`from`* and return a
|
||||
value of type *`to`*. Can be used to preserve backwards compatibility
|
||||
of an option if its type was changed.
|
||||
|
||||
## Submodule {#section-option-types-submodule}
|
||||
|
||||
`submodule` is a very powerful type that defines a set of sub-options
|
||||
that are handled like a separate module.
|
||||
|
||||
It takes a parameter *`o`*, that should be a set, or a function returning
|
||||
a set with an `options` key defining the sub-options. Submodule option
|
||||
definitions are type-checked accordingly to the `options` declarations.
|
||||
Of course, you can nest submodule option definitons for even higher
|
||||
modularity.
|
||||
|
||||
The option set can be defined directly
|
||||
([Example: Directly defined submodule](#ex-submodule-direct)) or as reference
|
||||
([Example: Submodule defined as a reference](#ex-submodule-reference)).
|
||||
|
||||
Note that even if your submodule’s options all have a default value,
|
||||
you will still need to provide a default value (e.g. an empty attribute set)
|
||||
if you want to allow users to leave it undefined.
|
||||
|
||||
::: {#ex-submodule-direct .example}
|
||||
::: {.title}
|
||||
**Example: Directly defined submodule**
|
||||
:::
|
||||
```nix
|
||||
options.mod = mkOption {
|
||||
description = "submodule example";
|
||||
type = with types; submodule {
|
||||
options = {
|
||||
foo = mkOption {
|
||||
type = int;
|
||||
};
|
||||
bar = mkOption {
|
||||
type = str;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
```
|
||||
:::
|
||||
|
||||
::: {#ex-submodule-reference .example}
|
||||
::: {.title}
|
||||
**Example: Submodule defined as a reference**
|
||||
:::
|
||||
```nix
|
||||
let
|
||||
modOptions = {
|
||||
options = {
|
||||
foo = mkOption {
|
||||
type = int;
|
||||
};
|
||||
bar = mkOption {
|
||||
type = int;
|
||||
};
|
||||
};
|
||||
};
|
||||
in
|
||||
options.mod = mkOption {
|
||||
description = "submodule example";
|
||||
type = with types; submodule modOptions;
|
||||
};
|
||||
```
|
||||
:::
|
||||
|
||||
The `submodule` type is especially interesting when used with composed
|
||||
types like `attrsOf` or `listOf`. When composed with `listOf`
|
||||
([Example: Declaration of a list of submodules](#ex-submodule-listof-declaration)), `submodule` allows
|
||||
multiple definitions of the submodule option set
|
||||
([Example: Definition of a list of submodules](#ex-submodule-listof-definition)).
|
||||
|
||||
::: {#ex-submodule-listof-declaration .example}
|
||||
::: {.title}
|
||||
**Example: Declaration of a list of submodules**
|
||||
:::
|
||||
```nix
|
||||
options.mod = mkOption {
|
||||
description = "submodule example";
|
||||
type = with types; listOf (submodule {
|
||||
options = {
|
||||
foo = mkOption {
|
||||
type = int;
|
||||
};
|
||||
bar = mkOption {
|
||||
type = str;
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
```
|
||||
:::
|
||||
|
||||
::: {#ex-submodule-listof-definition .example}
|
||||
::: {.title}
|
||||
**Example: Definition of a list of submodules**
|
||||
:::
|
||||
```nix
|
||||
config.mod = [
|
||||
{ foo = 1; bar = "one"; }
|
||||
{ foo = 2; bar = "two"; }
|
||||
];
|
||||
```
|
||||
:::
|
||||
|
||||
When composed with `attrsOf`
|
||||
([Example: Declaration of attribute sets of submodules](#ex-submodule-attrsof-declaration)), `submodule` allows
|
||||
multiple named definitions of the submodule option set
|
||||
([Example: Definition of attribute sets of submodules](#ex-submodule-attrsof-definition)).
|
||||
|
||||
::: {#ex-submodule-attrsof-declaration .example}
|
||||
::: {.title}
|
||||
**Example: Declaration of attribute sets of submodules**
|
||||
:::
|
||||
```nix
|
||||
options.mod = mkOption {
|
||||
description = "submodule example";
|
||||
type = with types; attrsOf (submodule {
|
||||
options = {
|
||||
foo = mkOption {
|
||||
type = int;
|
||||
};
|
||||
bar = mkOption {
|
||||
type = str;
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
```
|
||||
:::
|
||||
|
||||
::: {#ex-submodule-attrsof-definition .example}
|
||||
::: {.title}
|
||||
**Example: Definition of attribute sets of submodules**
|
||||
:::
|
||||
```nix
|
||||
config.mod.one = { foo = 1; bar = "one"; };
|
||||
config.mod.two = { foo = 2; bar = "two"; };
|
||||
```
|
||||
:::
|
||||
|
||||
## Extending types {#sec-option-types-extending}
|
||||
|
||||
Types are mainly characterized by their `check` and `merge` functions.
|
||||
|
||||
`check`
|
||||
|
||||
: The function to type check the value. Takes a value as parameter and
|
||||
return a boolean. It is possible to extend a type check with the
|
||||
`addCheck` function ([Example: Adding a type check](#ex-extending-type-check-1)),
|
||||
or to fully override the check function
|
||||
([Example: Overriding a type check](#ex-extending-type-check-2)).
|
||||
|
||||
::: {#ex-extending-type-check-1 .example}
|
||||
::: {.title}
|
||||
**Example: Adding a type check**
|
||||
:::
|
||||
```nix
|
||||
byte = mkOption {
|
||||
description = "An integer between 0 and 255.";
|
||||
type = types.addCheck types.int (x: x >= 0 && x <= 255);
|
||||
};
|
||||
```
|
||||
:::
|
||||
|
||||
::: {#ex-extending-type-check-2 .example}
|
||||
::: {.title}
|
||||
**Example: Overriding a type check**
|
||||
:::
|
||||
```nix
|
||||
nixThings = mkOption {
|
||||
description = "words that start with 'nix'";
|
||||
type = types.str // {
|
||||
check = (x: lib.hasPrefix "nix" x)
|
||||
};
|
||||
};
|
||||
```
|
||||
:::
|
||||
|
||||
`merge`
|
||||
|
||||
: Function to merge the options values when multiple values are set.
|
||||
The function takes two parameters, `loc` the option path as a list
|
||||
of strings, and `defs` the list of defined values as a list. It is
|
||||
possible to override a type merge function for custom needs.
|
||||
|
||||
## Custom Types {#sec-option-types-custom}
|
||||
|
||||
Custom types can be created with the `mkOptionType` function. As type
|
||||
creation includes some more complex topics such as submodule handling,
|
||||
it is recommended to get familiar with `types.nix` code before creating
|
||||
a new type.
|
||||
|
||||
The only required parameter is `name`.
|
||||
|
||||
`name`
|
||||
|
||||
: A string representation of the type function name.
|
||||
|
||||
`definition`
|
||||
|
||||
: Description of the type used in documentation. Give information of
|
||||
the type and any of its arguments.
|
||||
|
||||
`check`
|
||||
|
||||
: A function to type check the definition value. Takes the definition
|
||||
value as a parameter and returns a boolean indicating the type check
|
||||
result, `true` for success and `false` for failure.
|
||||
|
||||
`merge`
|
||||
|
||||
: A function to merge multiple definitions values. Takes two
|
||||
parameters:
|
||||
|
||||
*`loc`*
|
||||
|
||||
: The option path as a list of strings, e.g. `["boot" "loader
|
||||
"grub" "enable"]`.
|
||||
|
||||
*`defs`*
|
||||
|
||||
: The list of sets of defined `value` and `file` where the value
|
||||
was defined, e.g. `[ {
|
||||
file = "/foo.nix"; value = 1; } { file = "/bar.nix"; value = 2 }
|
||||
]`. The `merge` function should return the merged value
|
||||
or throw an error in case the values are impossible or not meant
|
||||
to be merged.
|
||||
|
||||
`getSubOptions`
|
||||
|
||||
: For composed types that can take a submodule as type parameter, this
|
||||
function generate sub-options documentation. It takes the current
|
||||
option prefix as a list and return the set of sub-options. Usually
|
||||
defined in a recursive manner by adding a term to the prefix, e.g.
|
||||
`prefix:
|
||||
elemType.getSubOptions (prefix ++
|
||||
["prefix"])` where *`"prefix"`* is the newly added prefix.
|
||||
|
||||
`getSubModules`
|
||||
|
||||
: For composed types that can take a submodule as type parameter, this
|
||||
function should return the type parameters submodules. If the type
|
||||
parameter is called `elemType`, the function should just recursively
|
||||
look into submodules by returning `elemType.getSubModules;`.
|
||||
|
||||
`substSubModules`
|
||||
|
||||
: For composed types that can take a submodule as type parameter, this
|
||||
function can be used to substitute the parameter of a submodule
|
||||
type. It takes a module as parameter and return the type with the
|
||||
submodule options substituted. It is usually defined as a type
|
||||
function call with a recursive call to `substSubModules`, e.g for a
|
||||
type `composedType` that take an `elemtype` type parameter, this
|
||||
function should be defined as `m:
|
||||
composedType (elemType.substSubModules m)`.
|
||||
|
||||
`typeMerge`
|
||||
|
||||
: A function to merge multiple type declarations. Takes the type to
|
||||
merge `functor` as parameter. A `null` return value means that type
|
||||
cannot be merged.
|
||||
|
||||
*`f`*
|
||||
|
||||
: The type to merge `functor`.
|
||||
|
||||
Note: There is a generic `defaultTypeMerge` that work with most of
|
||||
value and composed types.
|
||||
|
||||
`functor`
|
||||
|
||||
: An attribute set representing the type. It is used for type
|
||||
operations and has the following keys:
|
||||
|
||||
`type`
|
||||
|
||||
: The type function.
|
||||
|
||||
`wrapped`
|
||||
|
||||
: Holds the type parameter for composed types.
|
||||
|
||||
`payload`
|
||||
|
||||
: Holds the value parameter for value types. The types that have a
|
||||
`payload` are the `enum`, `separatedString` and `submodule`
|
||||
types.
|
||||
|
||||
`binOp`
|
||||
|
||||
: A binary operation that can merge the payloads of two same
|
||||
types. Defined as a function that take two payloads as
|
||||
parameters and return the payloads merged.
|
||||
64
nixos/doc/manual/development/replace-modules.section.md
Normal file
64
nixos/doc/manual/development/replace-modules.section.md
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
# Replace Modules {#sec-replace-modules}
|
||||
|
||||
Modules that are imported can also be disabled. The option declarations,
|
||||
config implementation and the imports of a disabled module will be
|
||||
ignored, allowing another to take it\'s place. This can be used to
|
||||
import a set of modules from another channel while keeping the rest of
|
||||
the system on a stable release.
|
||||
|
||||
`disabledModules` is a top level attribute like `imports`, `options` and
|
||||
`config`. It contains a list of modules that will be disabled. This can
|
||||
either be the full path to the module or a string with the filename
|
||||
relative to the modules path (eg. \<nixpkgs/nixos/modules> for nixos).
|
||||
|
||||
This example will replace the existing postgresql module with the
|
||||
version defined in the nixos-unstable channel while keeping the rest of
|
||||
the modules and packages from the original nixos channel. This only
|
||||
overrides the module definition, this won\'t use postgresql from
|
||||
nixos-unstable unless explicitly configured to do so.
|
||||
|
||||
```nix
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
disabledModules = [ "services/databases/postgresql.nix" ];
|
||||
|
||||
imports =
|
||||
[ # Use postgresql service from nixos-unstable channel.
|
||||
# sudo nix-channel --add https://nixos.org/channels/nixos-unstable nixos-unstable
|
||||
<nixos-unstable/nixos/modules/services/databases/postgresql.nix>
|
||||
];
|
||||
|
||||
services.postgresql.enable = true;
|
||||
}
|
||||
```
|
||||
|
||||
This example shows how to define a custom module as a replacement for an
|
||||
existing module. Importing this module will disable the original module
|
||||
without having to know it\'s implementation details.
|
||||
|
||||
```nix
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.programs.man;
|
||||
in
|
||||
|
||||
{
|
||||
disabledModules = [ "services/programs/man.nix" ];
|
||||
|
||||
options = {
|
||||
programs.man.enable = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Whether to enable manual pages.";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enabled {
|
||||
warnings = [ "disabled manpages for production deployments." ];
|
||||
};
|
||||
}
|
||||
```
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
# Running Tests interactively {#sec-running-nixos-tests-interactively}
|
||||
|
||||
The test itself can be run interactively. This is particularly useful
|
||||
when developing or debugging a test:
|
||||
|
||||
```ShellSession
|
||||
$ nix-build . -A nixosTests.login.driverInteractive
|
||||
$ ./result/bin/nixos-test-driver
|
||||
[...]
|
||||
>>>
|
||||
```
|
||||
|
||||
You can then take any Python statement, e.g.
|
||||
|
||||
```py
|
||||
>>> start_all()
|
||||
>>> test_script()
|
||||
>>> machine.succeed("touch /tmp/foo")
|
||||
>>> print(machine.succeed("pwd")) # Show stdout of command
|
||||
```
|
||||
|
||||
The function `test_script` executes the entire test script and drops you
|
||||
back into the test driver command line upon its completion. This allows
|
||||
you to inspect the state of the VMs after the test (e.g. to debug the
|
||||
test script).
|
||||
|
||||
You can re-use the VM states coming from a previous run by setting the
|
||||
`--keep-vm-state` flag.
|
||||
|
||||
```ShellSession
|
||||
$ ./result/bin/nixos-test-driver --keep-vm-state
|
||||
```
|
||||
|
||||
The machine state is stored in the `$TMPDIR/vm-state-machinename`
|
||||
directory.
|
||||
31
nixos/doc/manual/development/running-nixos-tests.section.md
Normal file
31
nixos/doc/manual/development/running-nixos-tests.section.md
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
# Running Tests {#sec-running-nixos-tests}
|
||||
|
||||
You can run tests using `nix-build`. For example, to run the test
|
||||
[`login.nix`](https://github.com/NixOS/nixpkgs/blob/master/nixos/tests/login.nix),
|
||||
you just do:
|
||||
|
||||
```ShellSession
|
||||
$ nix-build '<nixpkgs/nixos/tests/login.nix>'
|
||||
```
|
||||
|
||||
or, if you don't want to rely on `NIX_PATH`:
|
||||
|
||||
```ShellSession
|
||||
$ cd /my/nixpkgs/nixos/tests
|
||||
$ nix-build login.nix
|
||||
…
|
||||
running the VM test script
|
||||
machine: QEMU running (pid 8841)
|
||||
…
|
||||
6 out of 6 tests succeeded
|
||||
```
|
||||
|
||||
After building/downloading all required dependencies, this will perform
|
||||
a build that starts a QEMU/KVM virtual machine containing a NixOS
|
||||
system. The virtual machine mounts the Nix store of the host; this makes
|
||||
VM creation very fast, as no disk image needs to be created. Afterwards,
|
||||
you can view a log of the test:
|
||||
|
||||
```ShellSession
|
||||
$ nix-store --read-log result
|
||||
```
|
||||
251
nixos/doc/manual/development/settings-options.section.md
Normal file
251
nixos/doc/manual/development/settings-options.section.md
Normal file
|
|
@ -0,0 +1,251 @@
|
|||
# Options for Program Settings {#sec-settings-options}
|
||||
|
||||
Many programs have configuration files where program-specific settings
|
||||
can be declared. File formats can be separated into two categories:
|
||||
|
||||
- Nix-representable ones: These can trivially be mapped to a subset of
|
||||
Nix syntax. E.g. JSON is an example, since its values like
|
||||
`{"foo":{"bar":10}}` can be mapped directly to Nix:
|
||||
`{ foo = { bar = 10; }; }`. Other examples are INI, YAML and TOML.
|
||||
The following section explains the convention for these settings.
|
||||
|
||||
- Non-nix-representable ones: These can\'t be trivially mapped to a
|
||||
subset of Nix syntax. Most generic programming languages are in this
|
||||
group, e.g. bash, since the statement `if true; then echo hi; fi`
|
||||
doesn\'t have a trivial representation in Nix.
|
||||
|
||||
Currently there are no fixed conventions for these, but it is common
|
||||
to have a `configFile` option for setting the configuration file
|
||||
path directly. The default value of `configFile` can be an
|
||||
auto-generated file, with convenient options for controlling the
|
||||
contents. For example an option of type `attrsOf str` can be used
|
||||
for representing environment variables which generates a section
|
||||
like `export FOO="foo"`. Often it can also be useful to also include
|
||||
an `extraConfig` option of type `lines` to allow arbitrary text
|
||||
after the autogenerated part of the file.
|
||||
|
||||
## Nix-representable Formats (JSON, YAML, TOML, INI, \...) {#sec-settings-nix-representable}
|
||||
|
||||
By convention, formats like this are handled with a generic `settings`
|
||||
option, representing the full program configuration as a Nix value. The
|
||||
type of this option should represent the format. The most common formats
|
||||
have a predefined type and string generator already declared under
|
||||
`pkgs.formats`:
|
||||
|
||||
`pkgs.formats.javaProperties` { *`comment`* ? `"Generated with Nix"` }
|
||||
|
||||
: A function taking an attribute set with values
|
||||
|
||||
`comment`
|
||||
|
||||
: A string to put at the start of the
|
||||
file in a comment. It can have multiple
|
||||
lines.
|
||||
|
||||
It returns the `type`: `attrsOf str` and a function
|
||||
`generate` to build a Java `.properties` file, taking
|
||||
care of the correct escaping, etc.
|
||||
|
||||
`pkgs.formats.json` { }
|
||||
|
||||
: A function taking an empty attribute set (for future extensibility)
|
||||
and returning a set with JSON-specific attributes `type` and
|
||||
`generate` as specified [below](#pkgs-formats-result).
|
||||
|
||||
`pkgs.formats.yaml` { }
|
||||
|
||||
: A function taking an empty attribute set (for future extensibility)
|
||||
and returning a set with YAML-specific attributes `type` and
|
||||
`generate` as specified [below](#pkgs-formats-result).
|
||||
|
||||
`pkgs.formats.ini` { *`listsAsDuplicateKeys`* ? false, *`listToValue`* ? null, \... }
|
||||
|
||||
: A function taking an attribute set with values
|
||||
|
||||
`listsAsDuplicateKeys`
|
||||
|
||||
: A boolean for controlling whether list values can be used to
|
||||
represent duplicate INI keys
|
||||
|
||||
`listToValue`
|
||||
|
||||
: A function for turning a list of values into a single value.
|
||||
|
||||
It returns a set with INI-specific attributes `type` and `generate`
|
||||
as specified [below](#pkgs-formats-result).
|
||||
|
||||
`pkgs.formats.toml` { }
|
||||
|
||||
: A function taking an empty attribute set (for future extensibility)
|
||||
and returning a set with TOML-specific attributes `type` and
|
||||
`generate` as specified [below](#pkgs-formats-result).
|
||||
|
||||
`pkgs.formats.elixirConf { elixir ? pkgs.elixir }`
|
||||
|
||||
: A function taking an attribute set with values
|
||||
|
||||
`elixir`
|
||||
|
||||
: The Elixir package which will be used to format the generated output
|
||||
|
||||
It returns a set with Elixir-Config-specific attributes `type`, `lib`, and
|
||||
`generate` as specified [below](#pkgs-formats-result).
|
||||
|
||||
The `lib` attribute contains functions to be used in settings, for
|
||||
generating special Elixir values:
|
||||
|
||||
`mkRaw elixirCode`
|
||||
|
||||
: Outputs the given string as raw Elixir code
|
||||
|
||||
`mkGetEnv { envVariable, fallback ? null }`
|
||||
|
||||
: Makes the configuration fetch an environment variable at runtime
|
||||
|
||||
`mkAtom atom`
|
||||
|
||||
: Outputs the given string as an Elixir atom, instead of the default
|
||||
Elixir binary string. Note: lowercase atoms still needs to be prefixed
|
||||
with `:`
|
||||
|
||||
`mkTuple array`
|
||||
|
||||
: Outputs the given array as an Elixir tuple, instead of the default
|
||||
Elixir list
|
||||
|
||||
`mkMap attrset`
|
||||
|
||||
: Outputs the given attribute set as an Elixir map, instead of the
|
||||
default Elixir keyword list
|
||||
|
||||
|
||||
::: {#pkgs-formats-result}
|
||||
These functions all return an attribute set with these values:
|
||||
:::
|
||||
|
||||
`type`
|
||||
|
||||
: A module system type representing a value of the format
|
||||
|
||||
`lib`
|
||||
|
||||
: Utility functions for convenience, or special interactions with the format.
|
||||
This attribute is optional. It may contain inside a `types` attribute
|
||||
containing types specific to this format.
|
||||
|
||||
`generate` *`filename jsonValue`*
|
||||
|
||||
: A function that can render a value of the format to a file. Returns
|
||||
a file path.
|
||||
|
||||
::: {.note}
|
||||
This function puts the value contents in the Nix store. So this
|
||||
should be avoided for secrets.
|
||||
:::
|
||||
|
||||
::: {#ex-settings-nix-representable .example}
|
||||
::: {.title}
|
||||
**Example: Module with conventional `settings` option**
|
||||
:::
|
||||
The following shows a module for an example program that uses a JSON
|
||||
configuration file. It demonstrates how above values can be used, along
|
||||
with some other related best practices. See the comments for
|
||||
explanations.
|
||||
|
||||
```nix
|
||||
{ options, config, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.services.foo;
|
||||
# Define the settings format used for this program
|
||||
settingsFormat = pkgs.formats.json {};
|
||||
in {
|
||||
|
||||
options.services.foo = {
|
||||
enable = lib.mkEnableOption "foo service";
|
||||
|
||||
settings = lib.mkOption {
|
||||
# Setting this type allows for correct merging behavior
|
||||
type = settingsFormat.type;
|
||||
default = {};
|
||||
description = ''
|
||||
Configuration for foo, see
|
||||
<link xlink:href="https://example.com/docs/foo"/>
|
||||
for supported settings.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
# We can assign some default settings here to make the service work by just
|
||||
# enabling it. We use `mkDefault` for values that can be changed without
|
||||
# problems
|
||||
services.foo.settings = {
|
||||
# Fails at runtime without any value set
|
||||
log_level = lib.mkDefault "WARN";
|
||||
|
||||
# We assume systemd's `StateDirectory` is used, so we require this value,
|
||||
# therefore no mkDefault
|
||||
data_path = "/var/lib/foo";
|
||||
|
||||
# Since we use this to create a user we need to know the default value at
|
||||
# eval time
|
||||
user = lib.mkDefault "foo";
|
||||
};
|
||||
|
||||
environment.etc."foo.json".source =
|
||||
# The formats generator function takes a filename and the Nix value
|
||||
# representing the format value and produces a filepath with that value
|
||||
# rendered in the format
|
||||
settingsFormat.generate "foo-config.json" cfg.settings;
|
||||
|
||||
# We know that the `user` attribute exists because we set a default value
|
||||
# for it above, allowing us to use it without worries here
|
||||
users.users.${cfg.settings.user} = { isSystemUser = true; };
|
||||
|
||||
# ...
|
||||
};
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### Option declarations for attributes {#sec-settings-attrs-options}
|
||||
|
||||
Some `settings` attributes may deserve some extra care. They may need a
|
||||
different type, default or merging behavior, or they are essential
|
||||
options that should show their documentation in the manual. This can be
|
||||
done using [](#sec-freeform-modules).
|
||||
|
||||
We extend above example using freeform modules to declare an option for
|
||||
the port, which will enforce it to be a valid integer and make it show
|
||||
up in the manual.
|
||||
|
||||
::: {#ex-settings-typed-attrs .example}
|
||||
::: {.title}
|
||||
**Example: Declaring a type-checked `settings` attribute**
|
||||
:::
|
||||
```nix
|
||||
settings = lib.mkOption {
|
||||
type = lib.types.submodule {
|
||||
|
||||
freeformType = settingsFormat.type;
|
||||
|
||||
# Declare an option for the port such that the type is checked and this option
|
||||
# is shown in the manual.
|
||||
options.port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 8080;
|
||||
description = ''
|
||||
Which port this service should listen on.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
default = {};
|
||||
description = ''
|
||||
Configuration for Foo, see
|
||||
<link xlink:href="https://example.com/docs/foo"/>
|
||||
for supported values.
|
||||
'';
|
||||
};
|
||||
```
|
||||
:::
|
||||
77
nixos/doc/manual/development/sources.chapter.md
Normal file
77
nixos/doc/manual/development/sources.chapter.md
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
# Getting the Sources {#sec-getting-sources}
|
||||
|
||||
By default, NixOS's `nixos-rebuild` command uses the NixOS and Nixpkgs
|
||||
sources provided by the `nixos` channel (kept in
|
||||
`/nix/var/nix/profiles/per-user/root/channels/nixos`). To modify NixOS,
|
||||
however, you should check out the latest sources from Git. This is as
|
||||
follows:
|
||||
|
||||
```ShellSession
|
||||
$ git clone https://github.com/NixOS/nixpkgs
|
||||
$ cd nixpkgs
|
||||
$ git remote update origin
|
||||
```
|
||||
|
||||
This will check out the latest Nixpkgs sources to `./nixpkgs` the NixOS
|
||||
sources to `./nixpkgs/nixos`. (The NixOS source tree lives in a
|
||||
subdirectory of the Nixpkgs repository.) The `nixpkgs` repository has
|
||||
branches that correspond to each Nixpkgs/NixOS channel (see
|
||||
[](#sec-upgrading) for more information about channels). Thus, the
|
||||
Git branch `origin/nixos-17.03` will contain the latest built and tested
|
||||
version available in the `nixos-17.03` channel.
|
||||
|
||||
It's often inconvenient to develop directly on the master branch, since
|
||||
if somebody has just committed (say) a change to GCC, then the binary
|
||||
cache may not have caught up yet and you'll have to rebuild everything
|
||||
from source. So you may want to create a local branch based on your
|
||||
current NixOS version:
|
||||
|
||||
```ShellSession
|
||||
$ nixos-version
|
||||
17.09pre104379.6e0b727 (Hummingbird)
|
||||
|
||||
$ git checkout -b local 6e0b727
|
||||
```
|
||||
|
||||
Or, to base your local branch on the latest version available in a NixOS
|
||||
channel:
|
||||
|
||||
```ShellSession
|
||||
$ git remote update origin
|
||||
$ git checkout -b local origin/nixos-17.03
|
||||
```
|
||||
|
||||
(Replace `nixos-17.03` with the name of the channel you want to use.)
|
||||
You can use `git merge` or `git
|
||||
rebase` to keep your local branch in sync with the channel, e.g.
|
||||
|
||||
```ShellSession
|
||||
$ git remote update origin
|
||||
$ git merge origin/nixos-17.03
|
||||
```
|
||||
|
||||
You can use `git cherry-pick` to copy commits from your local branch to
|
||||
the upstream branch.
|
||||
|
||||
If you want to rebuild your system using your (modified) sources, you
|
||||
need to tell `nixos-rebuild` about them using the `-I` flag:
|
||||
|
||||
```ShellSession
|
||||
# nixos-rebuild switch -I nixpkgs=/my/sources/nixpkgs
|
||||
```
|
||||
|
||||
If you want `nix-env` to use the expressions in `/my/sources`, use
|
||||
`nix-env -f
|
||||
/my/sources/nixpkgs`, or change the default by adding a symlink in
|
||||
`~/.nix-defexpr`:
|
||||
|
||||
```ShellSession
|
||||
$ ln -s /my/sources/nixpkgs ~/.nix-defexpr/nixpkgs
|
||||
```
|
||||
|
||||
You may want to delete the symlink `~/.nix-defexpr/channels_root` to
|
||||
prevent root's NixOS channel from clashing with your own tree (this may
|
||||
break the command-not-found utility though). If you want to go back to
|
||||
the default state, you may just remove the `~/.nix-defexpr` directory
|
||||
completely, log out and log in again and it should have been recreated
|
||||
with a link to the root channels.
|
||||
18
nixos/doc/manual/development/testing-installer.chapter.md
Normal file
18
nixos/doc/manual/development/testing-installer.chapter.md
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# Testing the Installer {#ch-testing-installer}
|
||||
|
||||
Building, burning, and booting from an installation CD is rather
|
||||
tedious, so here is a quick way to see if the installer works properly:
|
||||
|
||||
```ShellSession
|
||||
# mount -t tmpfs none /mnt
|
||||
# nixos-generate-config --root /mnt
|
||||
$ nix-build '<nixpkgs/nixos>' -A config.system.build.nixos-install
|
||||
# ./result/bin/nixos-install
|
||||
```
|
||||
|
||||
To start a login shell in the new NixOS installation in `/mnt`:
|
||||
|
||||
```ShellSession
|
||||
$ nix-build '<nixpkgs/nixos>' -A config.system.build.nixos-enter
|
||||
# ./result/bin/nixos-enter
|
||||
```
|
||||
62
nixos/doc/manual/development/unit-handling.section.md
Normal file
62
nixos/doc/manual/development/unit-handling.section.md
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
# Unit handling {#sec-unit-handling}
|
||||
|
||||
To figure out what units need to be started/stopped/restarted/reloaded, the
|
||||
script first checks the current state of the system, similar to what `systemctl
|
||||
list-units` shows. For each of the units, the script goes through the following
|
||||
checks:
|
||||
|
||||
- Is the unit file still in the new system? If not, **stop** the service unless
|
||||
it sets `X-StopOnRemoval` in the `[Unit]` section to `false`.
|
||||
|
||||
- Is it a `.target` unit? If so, **start** it unless it sets
|
||||
`RefuseManualStart` in the `[Unit]` section to `true` or `X-OnlyManualStart`
|
||||
in the `[Unit]` section to `true`. Also **stop** the unit again unless it
|
||||
sets `X-StopOnReconfiguration` to `false`.
|
||||
|
||||
- Are the contents of the unit files different? They are compared by parsing
|
||||
them and comparing their contents. If they are different but only
|
||||
`X-Reload-Triggers` in the `[Unit]` section is changed, **reload** the unit.
|
||||
The NixOS module system allows setting these triggers with the option
|
||||
[systemd.services.\<name\>.reloadTriggers](#opt-systemd.services). There are
|
||||
some additional keys in the `[Unit]` section that are ignored as well. If the
|
||||
unit files differ in any way, the following actions are performed:
|
||||
|
||||
- `.path` and `.slice` units are ignored. There is no need to restart them
|
||||
since changes in their values are applied by systemd when systemd is
|
||||
reloaded.
|
||||
|
||||
- `.mount` units are **reload**ed. These mostly come from the `/etc/fstab`
|
||||
parser.
|
||||
|
||||
- `.socket` units are currently ignored. This is to be fixed at a later
|
||||
point.
|
||||
|
||||
- The rest of the units (mostly `.service` units) are then **reload**ed if
|
||||
`X-ReloadIfChanged` in the `[Service]` section is set to `true` (exposed
|
||||
via [systemd.services.\<name\>.reloadIfChanged](#opt-systemd.services)).
|
||||
A little exception is done for units that were deactivated in the meantime,
|
||||
for example because they require a unit that got stopped before. These
|
||||
are **start**ed instead of reloaded.
|
||||
|
||||
- If the reload flag is not set, some more flags decide if the unit is
|
||||
skipped. These flags are `X-RestartIfChanged` in the `[Service]` section
|
||||
(exposed via
|
||||
[systemd.services.\<name\>.restartIfChanged](#opt-systemd.services)),
|
||||
`RefuseManualStop` in the `[Unit]` section, and `X-OnlyManualStart` in the
|
||||
`[Unit]` section.
|
||||
|
||||
- Further behavior depends on the unit having `X-StopIfChanged` in the
|
||||
`[Service]` section set to `true` (exposed via
|
||||
[systemd.services.\<name\>.stopIfChanged](#opt-systemd.services)). This is
|
||||
set to `true` by default and must be explicitly turned off if not wanted.
|
||||
If the flag is enabled, the unit is **stop**ped and then **start**ed. If
|
||||
not, the unit is **restart**ed. The goal of the flag is to make sure that
|
||||
the new unit never runs in the old environment which is still in place
|
||||
before the activation script is run. This behavior is different when the
|
||||
service is socket-activated, as outlined in the following steps.
|
||||
|
||||
- The last thing that is taken into account is whether the unit is a service
|
||||
and socket-activated. If `X-StopIfChanged` is **not** set, the service
|
||||
is **restart**ed with the others. If it is set, both the service and the
|
||||
socket are **stop**ped and the socket is **start**ed, leaving socket
|
||||
activation to start the service when it's needed.
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
# What happens during a system switch? {#sec-switching-systems}
|
||||
|
||||
Running `nixos-rebuild switch` is one of the more common tasks under NixOS.
|
||||
This chapter explains some of the internals of this command to make it simpler
|
||||
for new module developers to configure their units correctly and to make it
|
||||
easier to understand what is happening and why for curious administrators.
|
||||
|
||||
`nixos-rebuild`, like many deployment solutions, calls `switch-to-configuration`
|
||||
which resides in a NixOS system at `$out/bin/switch-to-configuration`. The
|
||||
script is called with the action that is to be performed like `switch`, `test`,
|
||||
`boot`. There is also the `dry-activate` action which does not really perform
|
||||
the actions but rather prints what it would do if you called it with `test`.
|
||||
This feature can be used to check what service states would be changed if the
|
||||
configuration was switched to.
|
||||
|
||||
If the action is `switch` or `boot`, the bootloader is updated first so the
|
||||
configuration will be the next one to boot. Unless `NIXOS_NO_SYNC` is set to
|
||||
`1`, `/nix/store` is synced to disk.
|
||||
|
||||
If the action is `switch` or `test`, the currently running system is inspected
|
||||
and the actions to switch to the new system are calculated. This process takes
|
||||
two data sources into account: `/etc/fstab` and the current systemd status.
|
||||
Mounts and swaps are read from `/etc/fstab` and the corresponding actions are
|
||||
generated. If a new mount is added, for example, the proper `.mount` unit is
|
||||
marked to be started. The current systemd state is inspected, the difference
|
||||
between the current system and the desired configuration is calculated and
|
||||
actions are generated to get to this state. There are a lot of nuances that can
|
||||
be controlled by the units which are explained here.
|
||||
|
||||
After calculating what should be done, the actions are carried out. The order
|
||||
of actions is always the same:
|
||||
- Stop units (`systemctl stop`)
|
||||
- Run activation script (`$out/activate`)
|
||||
- See if the activation script requested more units to restart
|
||||
- Restart systemd if needed (`systemd daemon-reexec`)
|
||||
- Forget about the failed state of units (`systemctl reset-failed`)
|
||||
- Reload systemd (`systemctl daemon-reload`)
|
||||
- Reload systemd user instances (`systemctl --user daemon-reload`)
|
||||
- Set up tmpfiles (`systemd-tmpfiles --create`)
|
||||
- Reload units (`systemctl reload`)
|
||||
- Restart units (`systemctl restart`)
|
||||
- Start units (`systemctl start`)
|
||||
- Inspect what changed during these actions and print units that failed and
|
||||
that were newly started
|
||||
|
||||
Most of these actions are either self-explaining but some of them have to do
|
||||
with our units or the activation script. For this reason, these topics are
|
||||
explained in the next sections.
|
||||
|
||||
```{=docbook}
|
||||
<xi:include href="unit-handling.section.xml" />
|
||||
<xi:include href="activation-script.section.xml" />
|
||||
```
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
# Writing NixOS Documentation {#sec-writing-documentation}
|
||||
|
||||
As NixOS grows, so too does the need for a catalogue and explanation of
|
||||
its extensive functionality. Collecting pertinent information from
|
||||
disparate sources and presenting it in an accessible style would be a
|
||||
worthy contribution to the project.
|
||||
|
||||
## Building the Manual {#sec-writing-docs-building-the-manual}
|
||||
|
||||
The DocBook sources of the [](#book-nixos-manual) are in the
|
||||
[`nixos/doc/manual`](https://github.com/NixOS/nixpkgs/tree/master/nixos/doc/manual)
|
||||
subdirectory of the Nixpkgs repository.
|
||||
|
||||
You can quickly validate your edits with `make`:
|
||||
|
||||
```ShellSession
|
||||
$ cd /path/to/nixpkgs/nixos/doc/manual
|
||||
$ nix-shell
|
||||
nix-shell$ make
|
||||
```
|
||||
|
||||
Once you are done making modifications to the manual, it\'s important to
|
||||
build it before committing. You can do that as follows:
|
||||
|
||||
```ShellSession
|
||||
nix-build nixos/release.nix -A manual.x86_64-linux
|
||||
```
|
||||
|
||||
When this command successfully finishes, it will tell you where the
|
||||
manual got generated. The HTML will be accessible through the `result`
|
||||
symlink at `./result/share/doc/nixos/index.html`.
|
||||
|
||||
## Editing DocBook XML {#sec-writing-docs-editing-docbook-xml}
|
||||
|
||||
For general information on how to write in DocBook, see [DocBook 5: The
|
||||
Definitive Guide](http://www.docbook.org/tdg5/en/html/docbook.html).
|
||||
|
||||
Emacs nXML Mode is very helpful for editing DocBook XML because it
|
||||
validates the document as you write, and precisely locates errors. To
|
||||
use it, see [](#sec-emacs-docbook-xml).
|
||||
|
||||
[Pandoc](http://pandoc.org) can generate DocBook XML from a multitude of
|
||||
formats, which makes a good starting point. Here is an example of Pandoc
|
||||
invocation to convert GitHub-Flavoured MarkDown to DocBook 5 XML:
|
||||
|
||||
```ShellSession
|
||||
pandoc -f markdown_github -t docbook5 docs.md -o my-section.md
|
||||
```
|
||||
|
||||
Pandoc can also quickly convert a single `section.xml` to HTML, which is
|
||||
helpful when drafting.
|
||||
|
||||
Sometimes writing valid DocBook is simply too difficult. In this case,
|
||||
submit your documentation updates in a [GitHub
|
||||
Issue](https://github.com/NixOS/nixpkgs/issues/new) and someone will
|
||||
handle the conversion to XML for you.
|
||||
|
||||
## Creating a Topic {#sec-writing-docs-creating-a-topic}
|
||||
|
||||
You can use an existing topic as a basis for the new topic or create a
|
||||
topic from scratch.
|
||||
|
||||
Keep the following guidelines in mind when you create and add a topic:
|
||||
|
||||
- The NixOS [`book`](http://www.docbook.org/tdg5/en/html/book.html)
|
||||
element is in `nixos/doc/manual/manual.xml`. It includes several
|
||||
[`parts`](http://www.docbook.org/tdg5/en/html/book.html) which are in
|
||||
subdirectories.
|
||||
|
||||
- Store the topic file in the same directory as the `part` to which it
|
||||
belongs. If your topic is about configuring a NixOS module, then the
|
||||
XML file can be stored alongside the module definition `nix` file.
|
||||
|
||||
- If you include multiple words in the file name, separate the words
|
||||
with a dash. For example: `ipv6-config.xml`.
|
||||
|
||||
- Make sure that the `xml:id` value is unique. You can use abbreviations
|
||||
if the ID is too long. For example: `nixos-config`.
|
||||
|
||||
- Determine whether your topic is a chapter or a section. If you are
|
||||
unsure, open an existing topic file and check whether the main
|
||||
element is chapter or section.
|
||||
|
||||
## Adding a Topic to the Book {#sec-writing-docs-adding-a-topic}
|
||||
|
||||
Open the parent XML file and add an `xi:include` element to the list of
|
||||
chapters with the file name of the topic that you created. If you
|
||||
created a `section`, you add the file to the `chapter` file. If you created
|
||||
a `chapter`, you add the file to the `part` file.
|
||||
|
||||
If the topic is about configuring a NixOS module, it can be
|
||||
automatically included in the manual by using the `meta.doc` attribute.
|
||||
See [](#sec-meta-attributes) for an explanation.
|
||||
208
nixos/doc/manual/development/writing-modules.chapter.md
Normal file
208
nixos/doc/manual/development/writing-modules.chapter.md
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
# Writing NixOS Modules {#sec-writing-modules}
|
||||
|
||||
NixOS has a modular system for declarative configuration. This system
|
||||
combines multiple *modules* to produce the full system configuration.
|
||||
One of the modules that constitute the configuration is
|
||||
`/etc/nixos/configuration.nix`. Most of the others live in the
|
||||
[`nixos/modules`](https://github.com/NixOS/nixpkgs/tree/master/nixos/modules)
|
||||
subdirectory of the Nixpkgs tree.
|
||||
|
||||
Each NixOS module is a file that handles one logical aspect of the
|
||||
configuration, such as a specific kind of hardware, a service, or
|
||||
network settings. A module configuration does not have to handle
|
||||
everything from scratch; it can use the functionality provided by other
|
||||
modules for its implementation. Thus a module can *declare* options that
|
||||
can be used by other modules, and conversely can *define* options
|
||||
provided by other modules in its own implementation. For example, the
|
||||
module
|
||||
[`pam.nix`](https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/security/pam.nix)
|
||||
declares the option `security.pam.services` that allows other modules (e.g.
|
||||
[`sshd.nix`](https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/networking/ssh/sshd.nix))
|
||||
to define PAM services; and it defines the option `environment.etc` (declared by
|
||||
[`etc.nix`](https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/system/etc/etc.nix))
|
||||
to cause files to be created in `/etc/pam.d`.
|
||||
|
||||
In [](#sec-configuration-syntax), we saw the following structure of
|
||||
NixOS modules:
|
||||
|
||||
```nix
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
{ option definitions
|
||||
}
|
||||
```
|
||||
|
||||
This is actually an *abbreviated* form of module that only defines
|
||||
options, but does not declare any. The structure of full NixOS modules
|
||||
is shown in [Example: Structure of NixOS Modules](#ex-module-syntax).
|
||||
|
||||
::: {#ex-module-syntax .example}
|
||||
::: {.title}
|
||||
**Example: Structure of NixOS Modules**
|
||||
:::
|
||||
```nix
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
{
|
||||
imports =
|
||||
[ paths of other modules
|
||||
];
|
||||
|
||||
options = {
|
||||
option declarations
|
||||
};
|
||||
|
||||
config = {
|
||||
option definitions
|
||||
};
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
The meaning of each part is as follows.
|
||||
|
||||
- The first line makes the current Nix expression a function. The variable
|
||||
`pkgs` contains Nixpkgs (by default, it takes the `nixpkgs` entry of
|
||||
`NIX_PATH`, see the [Nix manual](https://nixos.org/manual/nix/stable/#sec-common-env)
|
||||
for further details), while `config` contains the full system
|
||||
configuration. This line can be omitted if there is no reference to
|
||||
`pkgs` and `config` inside the module.
|
||||
|
||||
- This `imports` list enumerates the paths to other NixOS modules that
|
||||
should be included in the evaluation of the system configuration. A
|
||||
default set of modules is defined in the file `modules/module-list.nix`.
|
||||
These don\'t need to be added in the import list.
|
||||
|
||||
- The attribute `options` is a nested set of *option declarations*
|
||||
(described below).
|
||||
|
||||
- The attribute `config` is a nested set of *option definitions* (also
|
||||
described below).
|
||||
|
||||
[Example: NixOS Module for the "locate" Service](#locate-example)
|
||||
shows a module that handles the regular update of the "locate" database,
|
||||
an index of all files in the file system. This module declares two
|
||||
options that can be defined by other modules (typically the user's
|
||||
`configuration.nix`): `services.locate.enable` (whether the database should
|
||||
be updated) and `services.locate.interval` (when the update should be done).
|
||||
It implements its functionality by defining two options declared by other
|
||||
modules: `systemd.services` (the set of all systemd services) and
|
||||
`systemd.timers` (the list of commands to be executed periodically by
|
||||
`systemd`).
|
||||
|
||||
Care must be taken when writing systemd services using `Exec*` directives. By
|
||||
default systemd performs substitution on `%<char>` specifiers in these
|
||||
directives, expands environment variables from `$FOO` and `${FOO}`, splits
|
||||
arguments on whitespace, and splits commands on `;`. All of these must be escaped
|
||||
to avoid unexpected substitution or splitting when interpolating into an `Exec*`
|
||||
directive, e.g. when using an `extraArgs` option to pass additional arguments to
|
||||
the service. The functions `utils.escapeSystemdExecArg` and
|
||||
`utils.escapeSystemdExecArgs` are provided for this, see [Example: Escaping in
|
||||
Exec directives](#exec-escaping-example) for an example. When using these
|
||||
functions system environment substitution should *not* be disabled explicitly.
|
||||
|
||||
::: {#locate-example .example}
|
||||
::: {.title}
|
||||
**Example: NixOS Module for the "locate" Service**
|
||||
:::
|
||||
```nix
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.locate;
|
||||
in {
|
||||
options.services.locate = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
If enabled, NixOS will periodically update the database of
|
||||
files used by the locate command.
|
||||
'';
|
||||
};
|
||||
|
||||
interval = mkOption {
|
||||
type = types.str;
|
||||
default = "02:15";
|
||||
example = "hourly";
|
||||
description = ''
|
||||
Update the locate database at this interval. Updates by
|
||||
default at 2:15 AM every day.
|
||||
|
||||
The format is described in
|
||||
systemd.time(7).
|
||||
'';
|
||||
};
|
||||
|
||||
# Other options omitted for documentation
|
||||
};
|
||||
|
||||
config = {
|
||||
systemd.services.update-locatedb =
|
||||
{ description = "Update Locate Database";
|
||||
path = [ pkgs.su ];
|
||||
script =
|
||||
''
|
||||
mkdir -m 0755 -p $(dirname ${toString cfg.output})
|
||||
exec updatedb \
|
||||
--localuser=${cfg.localuser} \
|
||||
${optionalString (!cfg.includeStore) "--prunepaths='/nix/store'"} \
|
||||
--output=${toString cfg.output} ${concatStringsSep " " cfg.extraFlags}
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.timers.update-locatedb = mkIf cfg.enable
|
||||
{ description = "Update timer for locate database";
|
||||
partOf = [ "update-locatedb.service" ];
|
||||
wantedBy = [ "timers.target" ];
|
||||
timerConfig.OnCalendar = cfg.interval;
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
::: {#exec-escaping-example .example}
|
||||
::: {.title}
|
||||
**Example: Escaping in Exec directives**
|
||||
:::
|
||||
```nix
|
||||
{ config, lib, pkgs, utils, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.echo;
|
||||
echoAll = pkgs.writeScript "echo-all" ''
|
||||
#! ${pkgs.runtimeShell}
|
||||
for s in "$@"; do
|
||||
printf '%s\n' "$s"
|
||||
done
|
||||
'';
|
||||
args = [ "a%Nything" "lang=\${LANG}" ";" "/bin/sh -c date" ];
|
||||
in {
|
||||
systemd.services.echo =
|
||||
{ description = "Echo to the journal";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig.Type = "oneshot";
|
||||
serviceConfig.ExecStart = ''
|
||||
${echoAll} ${utils.escapeSystemdExecArgs args}
|
||||
'';
|
||||
};
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
```{=docbook}
|
||||
<xi:include href="option-declarations.section.xml" />
|
||||
<xi:include href="option-types.section.xml" />
|
||||
<xi:include href="option-def.section.xml" />
|
||||
<xi:include href="assertions.section.xml" />
|
||||
<xi:include href="meta-attributes.section.xml" />
|
||||
<xi:include href="importing-modules.section.xml" />
|
||||
<xi:include href="replace-modules.section.xml" />
|
||||
<xi:include href="freeform-modules.section.xml" />
|
||||
<xi:include href="settings-options.section.xml" />
|
||||
```
|
||||
417
nixos/doc/manual/development/writing-nixos-tests.section.md
Normal file
417
nixos/doc/manual/development/writing-nixos-tests.section.md
Normal file
|
|
@ -0,0 +1,417 @@
|
|||
# Writing Tests {#sec-writing-nixos-tests}
|
||||
|
||||
A NixOS test is a Nix expression that has the following structure:
|
||||
|
||||
```nix
|
||||
import ./make-test-python.nix {
|
||||
|
||||
# One or more machines:
|
||||
nodes =
|
||||
{ machine =
|
||||
{ config, pkgs, ... }: { … };
|
||||
machine2 =
|
||||
{ config, pkgs, ... }: { … };
|
||||
…
|
||||
};
|
||||
|
||||
testScript =
|
||||
''
|
||||
Python code…
|
||||
'';
|
||||
}
|
||||
```
|
||||
|
||||
The attribute `testScript` is a bit of Python code that executes the
|
||||
test (described below). During the test, it will start one or more
|
||||
virtual machines, the configuration of which is described by
|
||||
the attribute `nodes`.
|
||||
|
||||
An example of a single-node test is
|
||||
[`login.nix`](https://github.com/NixOS/nixpkgs/blob/master/nixos/tests/login.nix).
|
||||
It only needs a single machine to test whether users can log in
|
||||
on the virtual console, whether device ownership is correctly maintained
|
||||
when switching between consoles, and so on. An interesting multi-node test is
|
||||
[`nfs/simple.nix`](https://github.com/NixOS/nixpkgs/blob/master/nixos/tests/nfs/simple.nix).
|
||||
It uses two client nodes to test correct locking across server crashes.
|
||||
|
||||
There are a few special NixOS configuration options for test VMs:
|
||||
|
||||
`virtualisation.memorySize`
|
||||
|
||||
: The memory of the VM in megabytes.
|
||||
|
||||
`virtualisation.vlans`
|
||||
|
||||
: The virtual networks to which the VM is connected. See
|
||||
[`nat.nix`](https://github.com/NixOS/nixpkgs/blob/master/nixos/tests/nat.nix)
|
||||
for an example.
|
||||
|
||||
`virtualisation.writableStore`
|
||||
|
||||
: By default, the Nix store in the VM is not writable. If you enable
|
||||
this option, a writable union file system is mounted on top of the
|
||||
Nix store to make it appear writable. This is necessary for tests
|
||||
that run Nix operations that modify the store.
|
||||
|
||||
For more options, see the module
|
||||
[`qemu-vm.nix`](https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/virtualisation/qemu-vm.nix).
|
||||
|
||||
The test script is a sequence of Python statements that perform various
|
||||
actions, such as starting VMs, executing commands in the VMs, and so on.
|
||||
Each virtual machine is represented as an object stored in the variable
|
||||
`name` if this is also the identifier of the machine in the declarative
|
||||
config. If you specified a node `nodes.machine`, the following example starts the
|
||||
machine, waits until it has finished booting, then executes a command
|
||||
and checks that the output is more-or-less correct:
|
||||
|
||||
```py
|
||||
machine.start()
|
||||
machine.wait_for_unit("default.target")
|
||||
if not "Linux" in machine.succeed("uname"):
|
||||
raise Exception("Wrong OS")
|
||||
```
|
||||
|
||||
The first line is technically unnecessary; machines are implicitly started
|
||||
when you first execute an action on them (such as `wait_for_unit` or
|
||||
`succeed`). If you have multiple machines, you can speed up the test by
|
||||
starting them in parallel:
|
||||
|
||||
```py
|
||||
start_all()
|
||||
```
|
||||
|
||||
## Machine objects {#ssec-machine-objects}
|
||||
|
||||
The following methods are available on machine objects:
|
||||
|
||||
`start`
|
||||
|
||||
: Start the virtual machine. This method is asynchronous --- it does
|
||||
not wait for the machine to finish booting.
|
||||
|
||||
`shutdown`
|
||||
|
||||
: Shut down the machine, waiting for the VM to exit.
|
||||
|
||||
`crash`
|
||||
|
||||
: Simulate a sudden power failure, by telling the VM to exit
|
||||
immediately.
|
||||
|
||||
`block`
|
||||
|
||||
: Simulate unplugging the Ethernet cable that connects the machine to
|
||||
the other machines.
|
||||
|
||||
`unblock`
|
||||
|
||||
: Undo the effect of `block`.
|
||||
|
||||
`screenshot`
|
||||
|
||||
: Take a picture of the display of the virtual machine, in PNG format.
|
||||
The screenshot is linked from the HTML log.
|
||||
|
||||
`get_screen_text_variants`
|
||||
|
||||
: Return a list of different interpretations of what is currently
|
||||
visible on the machine\'s screen using optical character
|
||||
recognition. The number and order of the interpretations is not
|
||||
specified and is subject to change, but if no exception is raised at
|
||||
least one will be returned.
|
||||
|
||||
::: {.note}
|
||||
This requires passing `enableOCR` to the test attribute set.
|
||||
:::
|
||||
|
||||
`get_screen_text`
|
||||
|
||||
: Return a textual representation of what is currently visible on the
|
||||
machine\'s screen using optical character recognition.
|
||||
|
||||
::: {.note}
|
||||
This requires passing `enableOCR` to the test attribute set.
|
||||
:::
|
||||
|
||||
`send_monitor_command`
|
||||
|
||||
: Send a command to the QEMU monitor. This is rarely used, but allows
|
||||
doing stuff such as attaching virtual USB disks to a running
|
||||
machine.
|
||||
|
||||
`send_key`
|
||||
|
||||
: Simulate pressing keys on the virtual keyboard, e.g.,
|
||||
`send_key("ctrl-alt-delete")`.
|
||||
|
||||
`send_chars`
|
||||
|
||||
: Simulate typing a sequence of characters on the virtual keyboard,
|
||||
e.g., `send_chars("foobar\n")` will type the string `foobar`
|
||||
followed by the Enter key.
|
||||
|
||||
`send_console`
|
||||
|
||||
: Send keys to the kernel console. This allows interaction with the systemd
|
||||
emergency mode, for example. Takes a string that is sent, e.g.,
|
||||
`send_console("\n\nsystemctl default\n")`.
|
||||
|
||||
`execute`
|
||||
|
||||
: Execute a shell command, returning a list `(status, stdout)`.
|
||||
|
||||
Commands are run with `set -euo pipefail` set:
|
||||
|
||||
- If several commands are separated by `;` and one fails, the
|
||||
command as a whole will fail.
|
||||
|
||||
- For pipelines, the last non-zero exit status will be returned
|
||||
(if there is one; otherwise zero will be returned).
|
||||
|
||||
- Dereferencing unset variables fails the command.
|
||||
|
||||
- It will wait for stdout to be closed.
|
||||
|
||||
If the command detaches, it must close stdout, as `execute` will wait
|
||||
for this to consume all output reliably. This can be achieved by
|
||||
redirecting stdout to stderr `>&2`, to `/dev/console`, `/dev/null` or
|
||||
a file. Examples of detaching commands are `sleep 365d &`, where the
|
||||
shell forks a new process that can write to stdout and `xclip -i`, where
|
||||
the `xclip` command itself forks without closing stdout.
|
||||
|
||||
Takes an optional parameter `check_return` that defaults to `True`.
|
||||
Setting this parameter to `False` will not check for the return code
|
||||
and return -1 instead. This can be used for commands that shut down
|
||||
the VM and would therefore break the pipe that would be used for
|
||||
retrieving the return code.
|
||||
|
||||
A timeout for the command can be specified (in seconds) using the optional
|
||||
`timeout` parameter, e.g., `execute(cmd, timeout=10)` or
|
||||
`execute(cmd, timeout=None)`. The default is 900 seconds.
|
||||
|
||||
`succeed`
|
||||
|
||||
: Execute a shell command, raising an exception if the exit status is
|
||||
not zero, otherwise returning the standard output. Similar to `execute`,
|
||||
except that the timeout is `None` by default. See `execute` for details on
|
||||
command execution.
|
||||
|
||||
`fail`
|
||||
|
||||
: Like `succeed`, but raising an exception if the command returns a zero
|
||||
status.
|
||||
|
||||
`wait_until_succeeds`
|
||||
|
||||
: Repeat a shell command with 1-second intervals until it succeeds.
|
||||
Has a default timeout of 900 seconds which can be modified, e.g.
|
||||
`wait_until_succeeds(cmd, timeout=10)`. See `execute` for details on
|
||||
command execution.
|
||||
|
||||
`wait_until_fails`
|
||||
|
||||
: Like `wait_until_succeeds`, but repeating the command until it fails.
|
||||
|
||||
`wait_for_unit`
|
||||
|
||||
: Wait until the specified systemd unit has reached the "active"
|
||||
state.
|
||||
|
||||
`wait_for_file`
|
||||
|
||||
: Wait until the specified file exists.
|
||||
|
||||
`wait_for_open_port`
|
||||
|
||||
: Wait until a process is listening on the given TCP port (on
|
||||
`localhost`, at least).
|
||||
|
||||
`wait_for_closed_port`
|
||||
|
||||
: Wait until nobody is listening on the given TCP port.
|
||||
|
||||
`wait_for_x`
|
||||
|
||||
: Wait until the X11 server is accepting connections.
|
||||
|
||||
`wait_for_text`
|
||||
|
||||
: Wait until the supplied regular expressions matches the textual
|
||||
contents of the screen by using optical character recognition (see
|
||||
`get_screen_text` and `get_screen_text_variants`).
|
||||
|
||||
::: {.note}
|
||||
This requires passing `enableOCR` to the test attribute set.
|
||||
:::
|
||||
|
||||
`wait_for_console_text`
|
||||
|
||||
: Wait until the supplied regular expressions match a line of the
|
||||
serial console output. This method is useful when OCR is not
|
||||
possibile or accurate enough.
|
||||
|
||||
`wait_for_window`
|
||||
|
||||
: Wait until an X11 window has appeared whose name matches the given
|
||||
regular expression, e.g., `wait_for_window("Terminal")`.
|
||||
|
||||
`copy_from_host`
|
||||
|
||||
: Copies a file from host to machine, e.g.,
|
||||
`copy_from_host("myfile", "/etc/my/important/file")`.
|
||||
|
||||
The first argument is the file on the host. The file needs to be
|
||||
accessible while building the nix derivation. The second argument is
|
||||
the location of the file on the machine.
|
||||
|
||||
`systemctl`
|
||||
|
||||
: Runs `systemctl` commands with optional support for
|
||||
`systemctl --user`
|
||||
|
||||
```py
|
||||
machine.systemctl("list-jobs --no-pager") # runs `systemctl list-jobs --no-pager`
|
||||
machine.systemctl("list-jobs --no-pager", "any-user") # spawns a shell for `any-user` and runs `systemctl --user list-jobs --no-pager`
|
||||
```
|
||||
|
||||
`shell_interact`
|
||||
|
||||
: Allows you to directly interact with the guest shell. This should
|
||||
only be used during test development, not in production tests.
|
||||
Killing the interactive session with `Ctrl-d` or `Ctrl-c` also ends
|
||||
the guest session.
|
||||
|
||||
`console_interact`
|
||||
|
||||
: Allows you to directly interact with QEMU's stdin. This should
|
||||
only be used during test development, not in production tests.
|
||||
Output from QEMU is only read line-wise. `Ctrl-c` kills QEMU and
|
||||
`Ctrl-d` closes console and returns to the test runner.
|
||||
|
||||
To test user units declared by `systemd.user.services` the optional
|
||||
`user` argument can be used:
|
||||
|
||||
```py
|
||||
machine.start()
|
||||
machine.wait_for_x()
|
||||
machine.wait_for_unit("xautolock.service", "x-session-user")
|
||||
```
|
||||
|
||||
This applies to `systemctl`, `get_unit_info`, `wait_for_unit`,
|
||||
`start_job` and `stop_job`.
|
||||
|
||||
For faster dev cycles it\'s also possible to disable the code-linters
|
||||
(this shouldn\'t be commited though):
|
||||
|
||||
```nix
|
||||
import ./make-test-python.nix {
|
||||
skipLint = true;
|
||||
nodes.machine =
|
||||
{ config, pkgs, ... }:
|
||||
{ configuration…
|
||||
};
|
||||
|
||||
testScript =
|
||||
''
|
||||
Python code…
|
||||
'';
|
||||
}
|
||||
```
|
||||
|
||||
This will produce a Nix warning at evaluation time. To fully disable the
|
||||
linter, wrap the test script in comment directives to disable the Black
|
||||
linter directly (again, don\'t commit this within the Nixpkgs
|
||||
repository):
|
||||
|
||||
```nix
|
||||
testScript =
|
||||
''
|
||||
# fmt: off
|
||||
Python code…
|
||||
# fmt: on
|
||||
'';
|
||||
```
|
||||
|
||||
Similarly, the type checking of test scripts can be disabled in the following
|
||||
way:
|
||||
|
||||
```nix
|
||||
import ./make-test-python.nix {
|
||||
skipTypeCheck = true;
|
||||
nodes.machine =
|
||||
{ config, pkgs, ... }:
|
||||
{ configuration…
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Failing tests early {#ssec-failing-tests-early}
|
||||
|
||||
To fail tests early when certain invariables are no longer met (instead of waiting for the build to time out), the decorator `polling_condition` is provided. For example, if we are testing a program `foo` that should not quit after being started, we might write the following:
|
||||
|
||||
```py
|
||||
@polling_condition
|
||||
def foo_running():
|
||||
machine.succeed("pgrep -x foo")
|
||||
|
||||
|
||||
machine.succeed("foo --start")
|
||||
machine.wait_until_succeeds("pgrep -x foo")
|
||||
|
||||
with foo_running:
|
||||
... # Put `foo` through its paces
|
||||
```
|
||||
|
||||
|
||||
`polling_condition` takes the following (optional) arguments:
|
||||
|
||||
`seconds_interval`
|
||||
|
||||
:
|
||||
specifies how often the condition should be polled:
|
||||
|
||||
```py
|
||||
@polling_condition(seconds_interval=10)
|
||||
def foo_running():
|
||||
machine.succeed("pgrep -x foo")
|
||||
```
|
||||
|
||||
`description`
|
||||
|
||||
:
|
||||
is used in the log when the condition is checked. If this is not provided, the description is pulled from the docstring of the function. These two are therefore equivalent:
|
||||
|
||||
```py
|
||||
@polling_condition
|
||||
def foo_running():
|
||||
"check that foo is running"
|
||||
machine.succeed("pgrep -x foo")
|
||||
```
|
||||
|
||||
```py
|
||||
@polling_condition(description="check that foo is running")
|
||||
def foo_running():
|
||||
machine.succeed("pgrep -x foo")
|
||||
```
|
||||
|
||||
## Adding Python packages to the test script {#ssec-python-packages-in-test-script}
|
||||
|
||||
When additional Python libraries are required in the test script, they can be
|
||||
added using the parameter `extraPythonPackages`. For example, you could add
|
||||
`numpy` like this:
|
||||
|
||||
```nix
|
||||
import ./make-test-python.nix
|
||||
{
|
||||
extraPythonPackages = p: [ p.numpy ];
|
||||
|
||||
nodes = { };
|
||||
|
||||
testScript = ''
|
||||
import numpy as np
|
||||
assert str(np.zeros(4) == "array([0., 0., 0., 0.])")
|
||||
'';
|
||||
}
|
||||
```
|
||||
|
||||
In that case, `numpy` is chosen from the generic `python3Packages`.
|
||||
5
nixos/doc/manual/from_md/README.md
Normal file
5
nixos/doc/manual/from_md/README.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
This directory is temporarily needed while we transition the manual to CommonMark. It stores the output of the ../md-to-db.sh script that converts CommonMark files back to DocBook.
|
||||
|
||||
We are choosing to convert the Markdown to DocBook at authoring time instead of manual building time, because we do not want the pandoc toolchain to become part of the NixOS closure.
|
||||
|
||||
Do not edit the DocBook files inside this directory or its subdirectories. Instead, edit the corresponding .md file in the normal manual directories, and run ../md-to-db.sh to update the file here.
|
||||
|
|
@ -0,0 +1,144 @@
|
|||
<section xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="sec-boot-problems">
|
||||
<title>Boot Problems</title>
|
||||
<para>
|
||||
If NixOS fails to boot, there are a number of kernel command line
|
||||
parameters that may help you to identify or fix the issue. You can
|
||||
add these parameters in the GRUB boot menu by pressing “e” to modify
|
||||
the selected boot entry and editing the line starting with
|
||||
<literal>linux</literal>. The following are some useful kernel
|
||||
command line parameters that are recognised by the NixOS boot
|
||||
scripts or by systemd:
|
||||
</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>boot.shell_on_fail</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Allows the user to start a root shell if something goes wrong
|
||||
in stage 1 of the boot process (the initial ramdisk). This is
|
||||
disabled by default because there is no authentication for the
|
||||
root shell.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>boot.debug1</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Start an interactive shell in stage 1 before anything useful
|
||||
has been done. That is, no modules have been loaded and no
|
||||
file systems have been mounted, except for
|
||||
<literal>/proc</literal> and <literal>/sys</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>boot.debug1devices</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Like <literal>boot.debug1</literal>, but runs stage1 until
|
||||
kernel modules are loaded and device nodes are created. This
|
||||
may help with e.g. making the keyboard work.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>boot.debug1mounts</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Like <literal>boot.debug1</literal> or
|
||||
<literal>boot.debug1devices</literal>, but runs stage1 until
|
||||
all filesystems that are mounted during initrd are mounted
|
||||
(see
|
||||
<link linkend="opt-fileSystems._name_.neededForBoot">neededForBoot</link>).
|
||||
As a motivating example, this could be useful if you’ve
|
||||
forgotten to set
|
||||
<link linkend="opt-fileSystems._name_.neededForBoot">neededForBoot</link>
|
||||
on a file system.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>boot.trace</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Print every shell command executed by the stage 1 and 2 boot
|
||||
scripts.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>single</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Boot into rescue mode (a.k.a. single user mode). This will
|
||||
cause systemd to start nothing but the unit
|
||||
<literal>rescue.target</literal>, which runs
|
||||
<literal>sulogin</literal> to prompt for the root password and
|
||||
start a root login shell. Exiting the shell causes the system
|
||||
to continue with the normal boot process.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>systemd.log_level=debug</literal>
|
||||
<literal>systemd.log_target=console</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Make systemd very verbose and send log messages to the console
|
||||
instead of the journal. For more parameters recognised by
|
||||
systemd, see systemd(1).
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<para>
|
||||
In addition, these arguments are recognised by the live image only:
|
||||
</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>live.nixos.passwd=password</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Set the password for the <literal>nixos</literal> live user.
|
||||
This can be used for SSH access if there are issues using the
|
||||
terminal.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<para>
|
||||
Notice that for <literal>boot.shell_on_fail</literal>,
|
||||
<literal>boot.debug1</literal>,
|
||||
<literal>boot.debug1devices</literal>, and
|
||||
<literal>boot.debug1mounts</literal>, if you did
|
||||
<emphasis role="strong">not</emphasis> select <quote>start the new
|
||||
shell as pid 1</quote>, and you <literal>exit</literal> from the new
|
||||
shell, boot will proceed normally from the point where it failed, as
|
||||
if you’d chosen <quote>ignore the error and continue</quote>.
|
||||
</para>
|
||||
<para>
|
||||
If no login prompts or X11 login screens appear (e.g. due to hanging
|
||||
dependencies), you can press Alt+ArrowUp. If you’re lucky, this will
|
||||
start rescue mode (described above). (Also note that since most
|
||||
units have a 90-second timeout before systemd gives up on them, the
|
||||
<literal>agetty</literal> login prompts should appear eventually
|
||||
unless something is very wrong.)
|
||||
</para>
|
||||
</section>
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="sec-nix-gc">
|
||||
<title>Cleaning the Nix Store</title>
|
||||
<para>
|
||||
Nix has a purely functional model, meaning that packages are never
|
||||
upgraded in place. Instead new versions of packages end up in a
|
||||
different location in the Nix store (<literal>/nix/store</literal>).
|
||||
You should periodically run Nix’s <emphasis>garbage
|
||||
collector</emphasis> to remove old, unreferenced packages. This is
|
||||
easy:
|
||||
</para>
|
||||
<programlisting>
|
||||
$ nix-collect-garbage
|
||||
</programlisting>
|
||||
<para>
|
||||
Alternatively, you can use a systemd unit that does the same in the
|
||||
background:
|
||||
</para>
|
||||
<programlisting>
|
||||
# systemctl start nix-gc.service
|
||||
</programlisting>
|
||||
<para>
|
||||
You can tell NixOS in <literal>configuration.nix</literal> to run
|
||||
this unit automatically at certain points in time, for instance,
|
||||
every night at 03:15:
|
||||
</para>
|
||||
<programlisting language="bash">
|
||||
nix.gc.automatic = true;
|
||||
nix.gc.dates = "03:15";
|
||||
</programlisting>
|
||||
<para>
|
||||
The commands above do not remove garbage collector roots, such as
|
||||
old system configurations. Thus they do not remove the ability to
|
||||
roll back to previous configurations. The following command deletes
|
||||
old roots, removing the ability to roll back to them:
|
||||
</para>
|
||||
<programlisting>
|
||||
$ nix-collect-garbage -d
|
||||
</programlisting>
|
||||
<para>
|
||||
You can also do this for specific profiles, e.g.
|
||||
</para>
|
||||
<programlisting>
|
||||
$ nix-env -p /nix/var/nix/profiles/per-user/eelco/profile --delete-generations old
|
||||
</programlisting>
|
||||
<para>
|
||||
Note that NixOS system configurations are stored in the profile
|
||||
<literal>/nix/var/nix/profiles/system</literal>.
|
||||
</para>
|
||||
<para>
|
||||
Another way to reclaim disk space (often as much as 40% of the size
|
||||
of the Nix store) is to run Nix’s store optimiser, which seeks out
|
||||
identical files in the store and replaces them with hard links to a
|
||||
single copy.
|
||||
</para>
|
||||
<programlisting>
|
||||
$ nix-store --optimise
|
||||
</programlisting>
|
||||
<para>
|
||||
Since this command needs to read the entire Nix store, it can take
|
||||
quite a while to finish.
|
||||
</para>
|
||||
<section xml:id="sect-nixos-gc-boot-entries">
|
||||
<title>NixOS Boot Entries</title>
|
||||
<para>
|
||||
If your <literal>/boot</literal> partition runs out of space,
|
||||
after clearing old profiles you must rebuild your system with
|
||||
<literal>nixos-rebuild boot</literal> or
|
||||
<literal>nixos-rebuild switch</literal> to update the
|
||||
<literal>/boot</literal> partition and clear space.
|
||||
</para>
|
||||
</section>
|
||||
</chapter>
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
<section xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="sec-container-networking">
|
||||
<title>Container Networking</title>
|
||||
<para>
|
||||
When you create a container using
|
||||
<literal>nixos-container create</literal>, it gets it own private
|
||||
IPv4 address in the range <literal>10.233.0.0/16</literal>. You can
|
||||
get the container’s IPv4 address as follows:
|
||||
</para>
|
||||
<programlisting>
|
||||
# nixos-container show-ip foo
|
||||
10.233.4.2
|
||||
|
||||
$ ping -c1 10.233.4.2
|
||||
64 bytes from 10.233.4.2: icmp_seq=1 ttl=64 time=0.106 ms
|
||||
</programlisting>
|
||||
<para>
|
||||
Networking is implemented using a pair of virtual Ethernet devices.
|
||||
The network interface in the container is called
|
||||
<literal>eth0</literal>, while the matching interface in the host is
|
||||
called <literal>ve-container-name</literal> (e.g.,
|
||||
<literal>ve-foo</literal>). The container has its own network
|
||||
namespace and the <literal>CAP_NET_ADMIN</literal> capability, so it
|
||||
can perform arbitrary network configuration such as setting up
|
||||
firewall rules, without affecting or having access to the host’s
|
||||
network.
|
||||
</para>
|
||||
<para>
|
||||
By default, containers cannot talk to the outside network. If you
|
||||
want that, you should set up Network Address Translation (NAT) rules
|
||||
on the host to rewrite container traffic to use your external IP
|
||||
address. This can be accomplished using the following configuration
|
||||
on the host:
|
||||
</para>
|
||||
<programlisting language="bash">
|
||||
networking.nat.enable = true;
|
||||
networking.nat.internalInterfaces = ["ve-+"];
|
||||
networking.nat.externalInterface = "eth0";
|
||||
</programlisting>
|
||||
<para>
|
||||
where <literal>eth0</literal> should be replaced with the desired
|
||||
external interface. Note that <literal>ve-+</literal> is a wildcard
|
||||
that matches all container interfaces.
|
||||
</para>
|
||||
<para>
|
||||
If you are using Network Manager, you need to explicitly prevent it
|
||||
from managing container interfaces:
|
||||
</para>
|
||||
<programlisting language="bash">
|
||||
networking.networkmanager.unmanaged = [ "interface-name:ve-*" ];
|
||||
</programlisting>
|
||||
<para>
|
||||
You may need to restart your system for the changes to take effect.
|
||||
</para>
|
||||
</section>
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xi="http://www.w3.org/2001/XInclude" xml:id="ch-containers">
|
||||
<title>Container Management</title>
|
||||
<para>
|
||||
NixOS allows you to easily run other NixOS instances as
|
||||
<emphasis>containers</emphasis>. Containers are a light-weight
|
||||
approach to virtualisation that runs software in the container at
|
||||
the same speed as in the host system. NixOS containers share the Nix
|
||||
store of the host, making container creation very efficient.
|
||||
</para>
|
||||
<warning>
|
||||
<para>
|
||||
Currently, NixOS containers are not perfectly isolated from the
|
||||
host system. This means that a user with root access to the
|
||||
container can do things that affect the host. So you should not
|
||||
give container root access to untrusted users.
|
||||
</para>
|
||||
</warning>
|
||||
<para>
|
||||
NixOS containers can be created in two ways: imperatively, using the
|
||||
command <literal>nixos-container</literal>, and declaratively, by
|
||||
specifying them in your <literal>configuration.nix</literal>. The
|
||||
declarative approach implies that containers get upgraded along with
|
||||
your host system when you run <literal>nixos-rebuild</literal>,
|
||||
which is often not what you want. By contrast, in the imperative
|
||||
approach, containers are configured and updated independently from
|
||||
the host system.
|
||||
</para>
|
||||
<xi:include href="imperative-containers.section.xml" />
|
||||
<xi:include href="declarative-containers.section.xml" />
|
||||
<xi:include href="container-networking.section.xml" />
|
||||
</chapter>
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="sec-cgroups">
|
||||
<title>Control Groups</title>
|
||||
<para>
|
||||
To keep track of the processes in a running system, systemd uses
|
||||
<emphasis>control groups</emphasis> (cgroups). A control group is a
|
||||
set of processes used to allocate resources such as CPU, memory or
|
||||
I/O bandwidth. There can be multiple control group hierarchies,
|
||||
allowing each kind of resource to be managed independently.
|
||||
</para>
|
||||
<para>
|
||||
The command <literal>systemd-cgls</literal> lists all control groups
|
||||
in the <literal>systemd</literal> hierarchy, which is what systemd
|
||||
uses to keep track of the processes belonging to each service or
|
||||
user session:
|
||||
</para>
|
||||
<programlisting>
|
||||
$ systemd-cgls
|
||||
├─user
|
||||
│ └─eelco
|
||||
│ └─c1
|
||||
│ ├─ 2567 -:0
|
||||
│ ├─ 2682 kdeinit4: kdeinit4 Running...
|
||||
│ ├─ ...
|
||||
│ └─10851 sh -c less -R
|
||||
└─system
|
||||
├─httpd.service
|
||||
│ ├─2444 httpd -f /nix/store/3pyacby5cpr55a03qwbnndizpciwq161-httpd.conf -DNO_DETACH
|
||||
│ └─...
|
||||
├─dhcpcd.service
|
||||
│ └─2376 dhcpcd --config /nix/store/f8dif8dsi2yaa70n03xir8r653776ka6-dhcpcd.conf
|
||||
└─ ...
|
||||
</programlisting>
|
||||
<para>
|
||||
Similarly, <literal>systemd-cgls cpu</literal> shows the cgroups in
|
||||
the CPU hierarchy, which allows per-cgroup CPU scheduling
|
||||
priorities. By default, every systemd service gets its own CPU
|
||||
cgroup, while all user sessions are in the top-level CPU cgroup.
|
||||
This ensures, for instance, that a thousand run-away processes in
|
||||
the <literal>httpd.service</literal> cgroup cannot starve the CPU
|
||||
for one process in the <literal>postgresql.service</literal> cgroup.
|
||||
(By contrast, it they were in the same cgroup, then the PostgreSQL
|
||||
process would get 1/1001 of the cgroup’s CPU time.) You can limit a
|
||||
service’s CPU share in <literal>configuration.nix</literal>:
|
||||
</para>
|
||||
<programlisting language="bash">
|
||||
systemd.services.httpd.serviceConfig.CPUShares = 512;
|
||||
</programlisting>
|
||||
<para>
|
||||
By default, every cgroup has 1024 CPU shares, so this will halve the
|
||||
CPU allocation of the <literal>httpd.service</literal> cgroup.
|
||||
</para>
|
||||
<para>
|
||||
There also is a <literal>memory</literal> hierarchy that controls
|
||||
memory allocation limits; by default, all processes are in the
|
||||
top-level cgroup, so any service or session can exhaust all
|
||||
available memory. Per-cgroup memory limits can be specified in
|
||||
<literal>configuration.nix</literal>; for instance, to limit
|
||||
<literal>httpd.service</literal> to 512 MiB of RAM (excluding swap):
|
||||
</para>
|
||||
<programlisting language="bash">
|
||||
systemd.services.httpd.serviceConfig.MemoryLimit = "512M";
|
||||
</programlisting>
|
||||
<para>
|
||||
The command <literal>systemd-cgtop</literal> shows a continuously
|
||||
updated list of all cgroups with their CPU and memory usage.
|
||||
</para>
|
||||
</chapter>
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
<section xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="sec-declarative-containers">
|
||||
<title>Declarative Container Specification</title>
|
||||
<para>
|
||||
You can also specify containers and their configuration in the
|
||||
host’s <literal>configuration.nix</literal>. For example, the
|
||||
following specifies that there shall be a container named
|
||||
<literal>database</literal> running PostgreSQL:
|
||||
</para>
|
||||
<programlisting language="bash">
|
||||
containers.database =
|
||||
{ config =
|
||||
{ config, pkgs, ... }:
|
||||
{ services.postgresql.enable = true;
|
||||
services.postgresql.package = pkgs.postgresql_10;
|
||||
};
|
||||
};
|
||||
</programlisting>
|
||||
<para>
|
||||
If you run <literal>nixos-rebuild switch</literal>, the container
|
||||
will be built. If the container was already running, it will be
|
||||
updated in place, without rebooting. The container can be configured
|
||||
to start automatically by setting
|
||||
<literal>containers.database.autoStart = true</literal> in its
|
||||
configuration.
|
||||
</para>
|
||||
<para>
|
||||
By default, declarative containers share the network namespace of
|
||||
the host, meaning that they can listen on (privileged) ports.
|
||||
However, they cannot change the network configuration. You can give
|
||||
a container its own network as follows:
|
||||
</para>
|
||||
<programlisting language="bash">
|
||||
containers.database = {
|
||||
privateNetwork = true;
|
||||
hostAddress = "192.168.100.10";
|
||||
localAddress = "192.168.100.11";
|
||||
};
|
||||
</programlisting>
|
||||
<para>
|
||||
This gives the container a private virtual Ethernet interface with
|
||||
IP address <literal>192.168.100.11</literal>, which is hooked up to
|
||||
a virtual Ethernet interface on the host with IP address
|
||||
<literal>192.168.100.10</literal>. (See the next section for details
|
||||
on container networking.)
|
||||
</para>
|
||||
<para>
|
||||
To disable the container, just remove it from
|
||||
<literal>configuration.nix</literal> and run
|
||||
<literal>nixos-rebuild switch</literal>. Note that this will not
|
||||
delete the root directory of the container in
|
||||
<literal>/var/lib/nixos-containers</literal>. Containers can be
|
||||
destroyed using the imperative method:
|
||||
<literal>nixos-container destroy foo</literal>.
|
||||
</para>
|
||||
<para>
|
||||
Declarative containers can be started and stopped using the
|
||||
corresponding systemd service, e.g.
|
||||
<literal>systemctl start container@database</literal>.
|
||||
</para>
|
||||
</section>
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
<section xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="sec-imperative-containers">
|
||||
<title>Imperative Container Management</title>
|
||||
<para>
|
||||
We’ll cover imperative container management using
|
||||
<literal>nixos-container</literal> first. Be aware that container
|
||||
management is currently only possible as <literal>root</literal>.
|
||||
</para>
|
||||
<para>
|
||||
You create a container with identifier <literal>foo</literal> as
|
||||
follows:
|
||||
</para>
|
||||
<programlisting>
|
||||
# nixos-container create foo
|
||||
</programlisting>
|
||||
<para>
|
||||
This creates the container’s root directory in
|
||||
<literal>/var/lib/nixos-containers/foo</literal> and a small
|
||||
configuration file in
|
||||
<literal>/etc/nixos-containers/foo.conf</literal>. It also builds
|
||||
the container’s initial system configuration and stores it in
|
||||
<literal>/nix/var/nix/profiles/per-container/foo/system</literal>.
|
||||
You can modify the initial configuration of the container on the
|
||||
command line. For instance, to create a container that has
|
||||
<literal>sshd</literal> running, with the given public key for
|
||||
<literal>root</literal>:
|
||||
</para>
|
||||
<programlisting>
|
||||
# nixos-container create foo --config '
|
||||
services.openssh.enable = true;
|
||||
users.users.root.openssh.authorizedKeys.keys = ["ssh-dss AAAAB3N…"];
|
||||
'
|
||||
</programlisting>
|
||||
<para>
|
||||
By default the next free address in the
|
||||
<literal>10.233.0.0/16</literal> subnet will be chosen as container
|
||||
IP. This behavior can be altered by setting
|
||||
<literal>--host-address</literal> and
|
||||
<literal>--local-address</literal>:
|
||||
</para>
|
||||
<programlisting>
|
||||
# nixos-container create test --config-file test-container.nix \
|
||||
--local-address 10.235.1.2 --host-address 10.235.1.1
|
||||
</programlisting>
|
||||
<para>
|
||||
Creating a container does not start it. To start the container, run:
|
||||
</para>
|
||||
<programlisting>
|
||||
# nixos-container start foo
|
||||
</programlisting>
|
||||
<para>
|
||||
This command will return as soon as the container has booted and has
|
||||
reached <literal>multi-user.target</literal>. On the host, the
|
||||
container runs within a systemd unit called
|
||||
<literal>container@container-name.service</literal>. Thus, if
|
||||
something went wrong, you can get status info using
|
||||
<literal>systemctl</literal>:
|
||||
</para>
|
||||
<programlisting>
|
||||
# systemctl status container@foo
|
||||
</programlisting>
|
||||
<para>
|
||||
If the container has started successfully, you can log in as root
|
||||
using the <literal>root-login</literal> operation:
|
||||
</para>
|
||||
<programlisting>
|
||||
# nixos-container root-login foo
|
||||
[root@foo:~]#
|
||||
</programlisting>
|
||||
<para>
|
||||
Note that only root on the host can do this (since there is no
|
||||
authentication). You can also get a regular login prompt using the
|
||||
<literal>login</literal> operation, which is available to all users
|
||||
on the host:
|
||||
</para>
|
||||
<programlisting>
|
||||
# nixos-container login foo
|
||||
foo login: alice
|
||||
Password: ***
|
||||
</programlisting>
|
||||
<para>
|
||||
With <literal>nixos-container run</literal>, you can execute
|
||||
arbitrary commands in the container:
|
||||
</para>
|
||||
<programlisting>
|
||||
# nixos-container run foo -- uname -a
|
||||
Linux foo 3.4.82 #1-NixOS SMP Thu Mar 20 14:44:05 UTC 2014 x86_64 GNU/Linux
|
||||
</programlisting>
|
||||
<para>
|
||||
There are several ways to change the configuration of the container.
|
||||
First, on the host, you can edit
|
||||
<literal>/var/lib/container/name/etc/nixos/configuration.nix</literal>,
|
||||
and run
|
||||
</para>
|
||||
<programlisting>
|
||||
# nixos-container update foo
|
||||
</programlisting>
|
||||
<para>
|
||||
This will build and activate the new configuration. You can also
|
||||
specify a new configuration on the command line:
|
||||
</para>
|
||||
<programlisting>
|
||||
# nixos-container update foo --config '
|
||||
services.httpd.enable = true;
|
||||
services.httpd.adminAddr = "foo@example.org";
|
||||
networking.firewall.allowedTCPPorts = [ 80 ];
|
||||
'
|
||||
|
||||
# curl http://$(nixos-container show-ip foo)/
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">…
|
||||
</programlisting>
|
||||
<para>
|
||||
However, note that this will overwrite the container’s
|
||||
<literal>/etc/nixos/configuration.nix</literal>.
|
||||
</para>
|
||||
<para>
|
||||
Alternatively, you can change the configuration from within the
|
||||
container itself by running <literal>nixos-rebuild switch</literal>
|
||||
inside the container. Note that the container by default does not
|
||||
have a copy of the NixOS channel, so you should run
|
||||
<literal>nix-channel --update</literal> first.
|
||||
</para>
|
||||
<para>
|
||||
Containers can be stopped and started using
|
||||
<literal>nixos-container stop</literal> and
|
||||
<literal>nixos-container start</literal>, respectively, or by using
|
||||
<literal>systemctl</literal> on the container’s service unit. To
|
||||
destroy a container, including its file system, do
|
||||
</para>
|
||||
<programlisting>
|
||||
# nixos-container destroy foo
|
||||
</programlisting>
|
||||
</section>
|
||||
45
nixos/doc/manual/from_md/administration/logging.chapter.xml
Normal file
45
nixos/doc/manual/from_md/administration/logging.chapter.xml
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="sec-logging">
|
||||
<title>Logging</title>
|
||||
<para>
|
||||
System-wide logging is provided by systemd’s
|
||||
<emphasis>journal</emphasis>, which subsumes traditional logging
|
||||
daemons such as syslogd and klogd. Log entries are kept in binary
|
||||
files in <literal>/var/log/journal/</literal>. The command
|
||||
<literal>journalctl</literal> allows you to see the contents of the
|
||||
journal. For example,
|
||||
</para>
|
||||
<programlisting>
|
||||
$ journalctl -b
|
||||
</programlisting>
|
||||
<para>
|
||||
shows all journal entries since the last reboot. (The output of
|
||||
<literal>journalctl</literal> is piped into <literal>less</literal>
|
||||
by default.) You can use various options and match operators to
|
||||
restrict output to messages of interest. For instance, to get all
|
||||
messages from PostgreSQL:
|
||||
</para>
|
||||
<programlisting>
|
||||
$ journalctl -u postgresql.service
|
||||
-- Logs begin at Mon, 2013-01-07 13:28:01 CET, end at Tue, 2013-01-08 01:09:57 CET. --
|
||||
...
|
||||
Jan 07 15:44:14 hagbard postgres[2681]: [2-1] LOG: database system is shut down
|
||||
-- Reboot --
|
||||
Jan 07 15:45:10 hagbard postgres[2532]: [1-1] LOG: database system was shut down at 2013-01-07 15:44:14 CET
|
||||
Jan 07 15:45:13 hagbard postgres[2500]: [1-1] LOG: database system is ready to accept connections
|
||||
</programlisting>
|
||||
<para>
|
||||
Or to get all messages since the last reboot that have at least a
|
||||
<quote>critical</quote> severity level:
|
||||
</para>
|
||||
<programlisting>
|
||||
$ journalctl -b -p crit
|
||||
Dec 17 21:08:06 mandark sudo[3673]: pam_unix(sudo:auth): auth could not identify password for [alice]
|
||||
Dec 29 01:30:22 mandark kernel[6131]: [1053513.909444] CPU6: Core temperature above threshold, cpu clock throttled (total events = 1)
|
||||
</programlisting>
|
||||
<para>
|
||||
The system journal is readable by root and by users in the
|
||||
<literal>wheel</literal> and <literal>systemd-journal</literal>
|
||||
groups. All users have a private journal that can be read using
|
||||
<literal>journalctl</literal>.
|
||||
</para>
|
||||
</chapter>
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue