mirror of
https://github.com/ilyakooo0/nixpkgs.git
synced 2024-12-28 14:22:50 +03:00
Merge remote-tracking branch 'origin/systemd'
This commit is contained in:
commit
1aaa726e75
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*~
|
||||
.version-suffix
|
173
doc/manual/configuration.xml
Normal file
173
doc/manual/configuration.xml
Normal file
@ -0,0 +1,173 @@
|
||||
<chapter xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xml:id="ch-configuration">
|
||||
|
||||
<title>Configuring NixOS</title>
|
||||
|
||||
<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 that file only take
|
||||
effect after you run <command>nixos-rebuild</command>.</para>
|
||||
|
||||
|
||||
<!--===============================================================-->
|
||||
|
||||
<section><title>Networking</title>
|
||||
|
||||
<section><title>Secure shell access</title>
|
||||
|
||||
<para>Secure shell (SSH) access to your machine can be enabled by
|
||||
setting:
|
||||
|
||||
<programlisting>
|
||||
services.openssh.enable = true;
|
||||
</programlisting>
|
||||
|
||||
By default, root logins using a password are disallowed. They can be
|
||||
disabled entirely by setting
|
||||
<literal>services.openssh.permitRootLogin</literal> to
|
||||
<literal>"no"</literal>.</para>
|
||||
|
||||
<para>You can declaratively specify authorised RSA/DSA public keys for
|
||||
a user as follows:
|
||||
|
||||
<!-- FIXME: this might not work if the user is unmanaged. -->
|
||||
<programlisting>
|
||||
users.extraUsers.alice.openssh.authorizedKeys.keys =
|
||||
[ "ssh-dss AAAAB3NzaC1kc3MAAACBAPIkGWVEt4..." ];
|
||||
</programlisting>
|
||||
|
||||
</para>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
<section><title>IPv4 configuration</title>
|
||||
|
||||
<para>By default, NixOS uses DHCP (specifically,
|
||||
(<command>dhcpcd</command>)) to automatically configure network
|
||||
interfaces. However, you can configure an interface manually as
|
||||
follows:
|
||||
|
||||
<programlisting>
|
||||
networking.interfaces.eth0 = { ipAddress = "192.168.1.2"; prefixLength = 24; };
|
||||
</programlisting>
|
||||
|
||||
(The network prefix can also be specified using the option
|
||||
<literal>subnetMask</literal>,
|
||||
e.g. <literal>"255.255.255.0"</literal>, but this is deprecated.)
|
||||
Typically you’ll also want to set a default gateway and set of name
|
||||
servers:
|
||||
|
||||
<programlisting>
|
||||
networking.defaultGateway = "192.168.1.1";
|
||||
networking.nameservers = [ "8.8.8.8" ];
|
||||
</programlisting>
|
||||
|
||||
</para>
|
||||
|
||||
<note><para>Statically configured interfaces are set up by the systemd
|
||||
service
|
||||
<replaceable>interface-name</replaceable><literal>-cfg.service</literal>.
|
||||
The default gateway and name server configuration is performed by
|
||||
<literal>network-setup.service</literal>.</para></note>
|
||||
|
||||
<para>The host name is set using <option>networking.hostName</option>:
|
||||
|
||||
<programlisting>
|
||||
networking.hostName = "cartman";
|
||||
</programlisting>
|
||||
|
||||
The default host name is <literal>nixos</literal>. Set it to the
|
||||
empty string (<literal>""</literal>) to allow the DHCP server to
|
||||
provide the host name.</para>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
<section><title>IPv6 configuration</title>
|
||||
|
||||
<para>IPv6 is enabled by default. Stateless address autoconfiguration
|
||||
is used to automatically assign IPv6 addresses to all interfaces. You
|
||||
can disable IPv6 support globally by setting:
|
||||
|
||||
<programlisting>
|
||||
networking.enableIPv6 = false;
|
||||
</programlisting>
|
||||
|
||||
</para>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
<section><title>Firewall</title>
|
||||
|
||||
<para>NixOS has a simple stateful firewall that blocks incoming
|
||||
connections and other unexpected packets. The firewall applies to
|
||||
both IPv4 and IPv6 traffic. It can be enabled as follows:
|
||||
|
||||
<programlisting>
|
||||
networking.firewall.enable = true;
|
||||
</programlisting>
|
||||
|
||||
You can open specific TCP ports to the outside world:
|
||||
|
||||
<programlisting>
|
||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||
</programlisting>
|
||||
|
||||
Note that TCP port 22 (ssh) is opened automatically if the SSH daemon
|
||||
is enabled (<option>services.openssh.enable = true</option>). UDP
|
||||
ports can be opened through
|
||||
<option>networking.firewall.allowedUDPPorts</option>. Also of
|
||||
interest is
|
||||
|
||||
<programlisting>
|
||||
networking.firewall.allowPing = true;
|
||||
</programlisting>
|
||||
|
||||
to allow the machine to respond to ping requests. (ICMPv6 pings are
|
||||
always allowed.)</para>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
<section><title>Wireless networks</title>
|
||||
|
||||
<para>TODO</para>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
<section><title>Ad-hoc configuration</title>
|
||||
|
||||
<para>You can use <option>networking.localCommands</option> to specify
|
||||
shell commands to be run at the end of
|
||||
<literal>network-setup.service</literal>. This is useful for doing
|
||||
network configuration not covered by the existing NixOS modules. For
|
||||
instance, to statically configure an IPv6 address:
|
||||
|
||||
<programlisting>
|
||||
networking.localCommands =
|
||||
''
|
||||
ip -6 addr add 2001:610:685:1::1/64 dev eth0
|
||||
'';
|
||||
</programlisting>
|
||||
|
||||
</para>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
<!-- TODO: OpenVPN, NAT -->
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
<!-- TODO: declarative package installation; X11; user management;
|
||||
Apache; libvirtd virtualisation -->
|
||||
|
||||
|
||||
</chapter>
|
@ -59,7 +59,7 @@ in rec {
|
||||
|
||||
mkdir -p $dst/images/callouts
|
||||
cp ${pkgs.docbook5_xsl}/xml/xsl/docbook/images/callouts/*.gif $dst/images/callouts/
|
||||
|
||||
|
||||
cp ${./style.css} $dst/style.css
|
||||
|
||||
ensureDir $out/nix-support
|
||||
|
@ -1,7 +1,7 @@
|
||||
<chapter xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
|
||||
<title>Installation</title>
|
||||
<title>Installing NixOS</title>
|
||||
|
||||
|
||||
<!--===============================================================-->
|
||||
@ -58,7 +58,7 @@ Wiki</link>.</para>
|
||||
|
||||
<listitem><para>For partitioning:
|
||||
<command>fdisk</command>.</para></listitem>
|
||||
|
||||
|
||||
<listitem><para>For initialising Ext4 partitions:
|
||||
<command>mkfs.ext4</command>. It is recommended that you assign a
|
||||
unique symbolic label to the file system using the option
|
||||
@ -70,13 +70,13 @@ Wiki</link>.</para>
|
||||
<command>mkswap</command>. Again it’s recommended to assign a
|
||||
label to the swap partition: <option>-L
|
||||
<replaceable>label</replaceable></option>.</para></listitem>
|
||||
|
||||
|
||||
<listitem><para>For creating LVM volumes, the LVM commands, e.g.,
|
||||
|
||||
<screen>
|
||||
$ pvcreate /dev/sda1 /dev/sdb1
|
||||
$ vgcreate MyVolGroup /dev/sda1 /dev/sdb1
|
||||
$ lvcreate --size 2G --name bigdisk MyVolGroup
|
||||
$ lvcreate --size 2G --name bigdisk MyVolGroup
|
||||
$ lvcreate --size 1G --name smalldisk MyVolGroup</screen>
|
||||
|
||||
</para></listitem>
|
||||
@ -87,7 +87,7 @@ $ lvcreate --size 1G --name smalldisk MyVolGroup</screen>
|
||||
</itemizedlist>
|
||||
|
||||
</para></listitem>
|
||||
|
||||
|
||||
<listitem><para>Mount the target file system on which NixOS should
|
||||
be installed on <filename>/mnt</filename>.</para></listitem>
|
||||
|
||||
@ -138,7 +138,7 @@ $ nixos-option --install</screen>
|
||||
xlink:href="https://nixos.org/repos/nix/configurations/trunk/"/>.</para>
|
||||
|
||||
</listitem>
|
||||
|
||||
|
||||
<listitem><para>If your machine has a limited amount of memory, you
|
||||
may want to activate swap devices now (<command>swapon
|
||||
<replaceable>device</replaceable></command>). The installer (or
|
||||
@ -230,15 +230,11 @@ $ reboot</screen>
|
||||
{
|
||||
boot.loader.grub.device = "/dev/sda";
|
||||
|
||||
fileSystems =
|
||||
[ { mountPoint = "/";
|
||||
device = "/dev/disk/by-label/nixos";
|
||||
}
|
||||
];
|
||||
fileSystems."/".device = "/dev/disk/by-label/nixos";
|
||||
|
||||
swapDevices =
|
||||
[ { device = "/dev/disk/by-label/swap"; } ];
|
||||
|
||||
|
||||
services.sshd.enable = true;
|
||||
}</screen>
|
||||
</example>
|
||||
@ -264,7 +260,7 @@ to build the new configuration, make it the default configuration for
|
||||
booting, and try to realise the configuration in the running system
|
||||
(e.g., by restarting system services).</para>
|
||||
|
||||
<para>You can also do
|
||||
<para>You can also do
|
||||
|
||||
<screen>
|
||||
$ nixos-rebuild test</screen>
|
||||
@ -274,7 +270,7 @@ without making it the boot default. So if (say) the configuration
|
||||
locks up your machine, you can just reboot to get back to a working
|
||||
configuration.</para>
|
||||
|
||||
<para>There is also
|
||||
<para>There is also
|
||||
|
||||
<screen>
|
||||
$ nixos-rebuild boot</screen>
|
||||
@ -283,7 +279,7 @@ to build the configuration and make it the boot default, but not
|
||||
switch to it now (so it will only take effect after the next
|
||||
reboot).</para>
|
||||
|
||||
<para>Finally, you can do
|
||||
<para>Finally, you can do
|
||||
|
||||
<screen>
|
||||
$ nixos-rebuild build</screen>
|
||||
@ -333,7 +329,7 @@ You can then upgrade NixOS to the latest version in the channel by
|
||||
running
|
||||
|
||||
<screen>
|
||||
$ nix-channel --update
|
||||
$ nix-channel --update nixos
|
||||
</screen>
|
||||
|
||||
and running the <command>nixos-rebuild</command> command as described
|
||||
|
@ -24,16 +24,16 @@
|
||||
<year>2007-2012</year>
|
||||
<holder>Eelco Dolstra</holder>
|
||||
</copyright>
|
||||
|
||||
|
||||
</info>
|
||||
|
||||
|
||||
|
||||
<preface>
|
||||
<title>Preface</title>
|
||||
|
||||
<para>This manual describes NixOS, a Linux distribution based on
|
||||
the purely functional package management system Nix.</para>
|
||||
|
||||
|
||||
<para>NixOS is rather bleeding edge, and this manual is
|
||||
correspondingly sketchy and quite possibly out of date. It gives
|
||||
basic information on how to get NixOS up and running, but since
|
||||
@ -45,11 +45,13 @@
|
||||
mailing list or on <link
|
||||
xlink:href="irc://irc.freenode.net/#nixos">the
|
||||
<literal>#nixos</literal> channel on Freenode.</link>.</para>
|
||||
|
||||
|
||||
</preface>
|
||||
|
||||
|
||||
|
||||
<xi:include href="installation.xml" />
|
||||
<xi:include href="configuration.xml" />
|
||||
<xi:include href="running.xml" />
|
||||
<!-- <xi:include href="userconfiguration.xml" /> -->
|
||||
<xi:include href="troubleshooting.xml" />
|
||||
<xi:include href="development.xml" />
|
||||
|
288
doc/manual/running.xml
Normal file
288
doc/manual/running.xml
Normal file
@ -0,0 +1,288 @@
|
||||
<chapter xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xml:id="ch-running">
|
||||
|
||||
<title>Running NixOS</title>
|
||||
|
||||
<para>This chapter describes various aspects of managing a running
|
||||
NixOS system, such as how to use the <command>systemd</command>
|
||||
service manager.</para>
|
||||
|
||||
|
||||
<!--===============================================================-->
|
||||
|
||||
<section><title>Service management</title>
|
||||
|
||||
<para>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 succesfully
|
||||
started before the first unit can be started. When the system boots,
|
||||
it starts a unit named <literal>default.target</literal>; the
|
||||
dependencies of this unit cause all system services to be started,
|
||||
filesystems to be mounted, swap files to be activated, and so
|
||||
on.</para>
|
||||
|
||||
<para>The command <command>systemctl</command> is the main way to
|
||||
interact with <command>systemd</command>. Without any arguments, it
|
||||
shows the status of active units:
|
||||
|
||||
<screen>
|
||||
$ 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
|
||||
<replaceable>...</replaceable>
|
||||
</screen>
|
||||
|
||||
</para>
|
||||
|
||||
<para>You can ask for detailed status information about a unit, for
|
||||
instance, the PostgreSQL database service:
|
||||
|
||||
<screen>
|
||||
$ 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.
|
||||
</screen>
|
||||
|
||||
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.
|
||||
|
||||
</para>
|
||||
|
||||
<para>Units can be stopped, started or restarted:
|
||||
|
||||
<screen>
|
||||
$ systemctl stop postgresql.service
|
||||
$ systemctl start postgresql.service
|
||||
$ systemctl restart postgresql.service
|
||||
</screen>
|
||||
|
||||
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).</para>
|
||||
|
||||
<!-- - cgroups: each service and user session is a cgroup
|
||||
|
||||
- cgroup resource management -->
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
<!--===============================================================-->
|
||||
|
||||
<section><title>Rebooting and shutting down</title>
|
||||
|
||||
<para>The system can be shut down (and automatically powered off) by
|
||||
doing:
|
||||
|
||||
<screen>
|
||||
$ shutdown
|
||||
</screen>
|
||||
|
||||
This is equivalent to running <command>systemctl poweroff</command>.
|
||||
Likewise, <command>reboot</command> (a.k.a. <command>systemctl
|
||||
reboot</command>) will reboot the system.</para>
|
||||
|
||||
<para>The machine can be suspended to RAM (if supported) using
|
||||
<command>systemctl suspend</command>, and suspended to disk using
|
||||
<command>systemctl hibernate</command>.</para>
|
||||
|
||||
<para>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.</para>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
<!--===============================================================-->
|
||||
|
||||
<section><title>User sessions</title>
|
||||
|
||||
<para>Systemd keeps track of all users who are logged into the system
|
||||
(e.g. on a virtual console or remotely via SSH). The command
|
||||
<command>loginctl</command> allows quering and manipulating user
|
||||
sessions. For instance, to list all user sessions:
|
||||
|
||||
<screen>
|
||||
$ loginctl
|
||||
SESSION UID USER SEAT
|
||||
c1 500 eelco seat0
|
||||
c3 0 root seat0
|
||||
c4 500 alice
|
||||
</screen>
|
||||
|
||||
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:
|
||||
|
||||
<screen>
|
||||
$ 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
|
||||
</screen>
|
||||
|
||||
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:
|
||||
|
||||
<screen>
|
||||
$ loginctl terminate-session c3
|
||||
</screen>
|
||||
|
||||
</para>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
<!--===============================================================-->
|
||||
|
||||
<section><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 <command>systemd-cgls</command> 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:
|
||||
|
||||
<screen>
|
||||
$ systemd-cgls
|
||||
├─user
|
||||
│ └─eelco
|
||||
│ └─c1
|
||||
│ ├─ 2567 -:0
|
||||
│ ├─ 2682 kdeinit4: kdeinit4 Running...
|
||||
│ ├─ <replaceable>...</replaceable>
|
||||
│ └─10851 sh -c less -R
|
||||
└─system
|
||||
├─httpd.service
|
||||
│ ├─2444 httpd -f /nix/store/3pyacby5cpr55a03qwbnndizpciwq161-httpd.conf -DNO_DETACH
|
||||
│ └─<replaceable>...</replaceable>
|
||||
├─dhcpcd.service
|
||||
│ └─2376 dhcpcd --config /nix/store/f8dif8dsi2yaa70n03xir8r653776ka6-dhcpcd.conf
|
||||
└─ <replaceable>...</replaceable>
|
||||
</screen>
|
||||
|
||||
Similarly, <command>systemd-cgls cpu</command> 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 <filename>configuration.nix</filename>:
|
||||
|
||||
<programlisting>
|
||||
systemd.services.httpd.serviceConfig.CPUShares = 512;
|
||||
</programlisting>
|
||||
|
||||
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
|
||||
<filename>configuration.nix</filename>; for instance, to limit
|
||||
<literal>httpd.service</literal> to 512 MiB of RAM (excluding swap)
|
||||
and 640 MiB of RAM (including swap):
|
||||
|
||||
<programlisting>
|
||||
systemd.services.httpd.serviceConfig.MemoryLimit = "512M";
|
||||
systemd.services.httpd.serviceConfig.ControlGroupAttribute = [ "memory.memsw.limit_in_bytes 640M" ];
|
||||
</programlisting>
|
||||
|
||||
</para>
|
||||
|
||||
<para>The command <command>systemd-cgtop</command> shows a
|
||||
continuously updated list of all cgroups with their CPU and memory
|
||||
usage.</para>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
<!--===============================================================-->
|
||||
|
||||
<section><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 <filename>/var/log/journal/</filename>. The command
|
||||
<literal>journalctl</literal> allows you to see the contents of the
|
||||
journal. For example,
|
||||
|
||||
<screen>
|
||||
$ journalctl -b
|
||||
</screen>
|
||||
|
||||
shows all journal entries since the last reboot. (The output of
|
||||
<command>journalctl</command> is piped into <command>less</command> 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:
|
||||
|
||||
<screen>
|
||||
$ journalctl _SYSTEMD_UNIT=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
|
||||
</screen>
|
||||
|
||||
Or to get all messages since the last reboot that have at least a
|
||||
“critical” severity level:
|
||||
|
||||
<screen>
|
||||
$ 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)
|
||||
</screen>
|
||||
|
||||
</para>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
</chapter>
|
@ -4,60 +4,81 @@
|
||||
<title>Troubleshooting</title>
|
||||
|
||||
|
||||
<section>
|
||||
|
||||
<title>Debugging the boot process</title>
|
||||
<section><title>Boot problems</title>
|
||||
|
||||
<para>To get a Stage 1 shell (i.e., a shell in the initial ramdisk),
|
||||
add <literal>debug1</literal> to the kernel command line. The shell
|
||||
gets started before anything useful has been done. That is, no
|
||||
modules have been loaded and no file systems have been mounted, except
|
||||
for <filename>/proc</filename> and <filename>/sys</filename>.</para>
|
||||
<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>To get a Stage 2 shell (i.e., a shell in the actual root file
|
||||
system), add <literal>debug2</literal> to the kernel command
|
||||
line. This shell is started right after stage 1 calls the stage 2
|
||||
<literal>init</literal> script, so the root file system is there but
|
||||
no services have been started.</para>
|
||||
<variablelist>
|
||||
|
||||
</section>
|
||||
<varlistentry><term><literal>boot.shell_on_fail</literal></term>
|
||||
<listitem><para>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
|
||||
<filename>/proc</filename> and
|
||||
<filename>/sys</filename>.</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>
|
||||
|
||||
<section>
|
||||
|
||||
<title>Safe mode</title>
|
||||
<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
|
||||
<command>sulogin</command> 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>
|
||||
|
||||
<para>If the hardware autodetection (in
|
||||
<filename>upstart-jobs/hardware-scan</filename>) causes problems, add
|
||||
<literal>safemode</literal> to the kernel command line. This will
|
||||
disable auto-loading of modules for your PCI devices. However, you
|
||||
will probably need to explicitly add modules to
|
||||
<option>boot.kernelModules</option> to get network support etc.</para>
|
||||
<varlistentry><term><literal>systemd.log_level=debug systemd.log_target=console</literal></term>
|
||||
<listitem><para>Make systemd very verbose and send log messages to
|
||||
the console instead of the journal.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
For more parameters recognised by systemd, see
|
||||
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>.</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 <command>agetty</command> login prompts should appear eventually
|
||||
unless something is very wrong.)</para>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
<section>
|
||||
|
||||
|
||||
<title>Maintenance mode</title>
|
||||
|
||||
<para>You can go to maintenance mode by doing
|
||||
<para>You can enter rescue mode by running:
|
||||
|
||||
<screen>
|
||||
$ shutdown now</screen>
|
||||
$ systemctl rescue</screen>
|
||||
|
||||
This will eventually give you a single-user root shell.
|
||||
|
||||
To get out of maintenance mode, do
|
||||
|
||||
<screen>
|
||||
$ initctl emit startup</screen>
|
||||
|
||||
</para>
|
||||
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.</para>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
</chapter>
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
let pkgs = import <nixpkgs> { config = {}; inherit system; }; in
|
||||
|
||||
with pkgs;
|
||||
with pkgs.lib;
|
||||
with import ../lib/qemu-flags.nix;
|
||||
|
||||
rec {
|
||||
@ -15,7 +15,7 @@ rec {
|
||||
# hostname and `configX' is a NixOS system configuration. Each
|
||||
# machine is given an arbitrary IP address in the virtual network.
|
||||
buildVirtualNetwork =
|
||||
nodes: let nodesOut = lib.mapAttrs (n: buildVM nodesOut) (assignIPAddresses nodes); in nodesOut;
|
||||
nodes: let nodesOut = mapAttrs (n: buildVM nodesOut) (assignIPAddresses nodes); in nodesOut;
|
||||
|
||||
|
||||
buildVM =
|
||||
@ -27,7 +27,7 @@ rec {
|
||||
[ ../modules/virtualisation/qemu-vm.nix
|
||||
../modules/testing/test-instrumentation.nix # !!! should only get added for automated test runs
|
||||
{ key = "no-manual"; services.nixosManual.enable = false; }
|
||||
] ++ lib.optional minimal ../modules/testing/minimal-kernel.nix;
|
||||
] ++ optional minimal ../modules/testing/minimal-kernel.nix;
|
||||
extraArgs = { inherit nodes; };
|
||||
};
|
||||
|
||||
@ -39,51 +39,49 @@ rec {
|
||||
|
||||
let
|
||||
|
||||
machines = lib.attrNames nodes;
|
||||
machines = attrNames nodes;
|
||||
|
||||
machinesNumbered = lib.zipTwoLists machines (lib.range 1 254);
|
||||
machinesNumbered = zipTwoLists machines (range 1 254);
|
||||
|
||||
nodes_ = lib.flip map machinesNumbered (m: lib.nameValuePair m.first
|
||||
nodes_ = flip map machinesNumbered (m: nameValuePair m.first
|
||||
[ ( { config, pkgs, nodes, ... }:
|
||||
let
|
||||
interfacesNumbered = lib.zipTwoLists config.virtualisation.vlans (lib.range 1 255);
|
||||
interfaces =
|
||||
lib.flip map interfacesNumbered ({ first, second }:
|
||||
{ name = "eth${toString second}";
|
||||
ipAddress = "192.168.${toString first}.${toString m.second}";
|
||||
interfacesNumbered = zipTwoLists config.virtualisation.vlans (range 1 255);
|
||||
interfaces = flip map interfacesNumbered ({ first, second }:
|
||||
nameValuePair "eth${toString second}"
|
||||
{ ipAddress = "192.168.${toString first}.${toString m.second}";
|
||||
subnetMask = "255.255.255.0";
|
||||
}
|
||||
);
|
||||
});
|
||||
in
|
||||
{ key = "ip-address";
|
||||
config =
|
||||
{ networking.hostName = m.first;
|
||||
|
||||
networking.interfaces = interfaces;
|
||||
networking.interfaces = listToAttrs interfaces;
|
||||
|
||||
networking.primaryIPAddress =
|
||||
lib.optionalString (interfaces != []) (lib.head interfaces).ipAddress;
|
||||
optionalString (interfaces != []) (head interfaces).value.ipAddress;
|
||||
|
||||
# Put the IP addresses of all VMs in this machine's
|
||||
# /etc/hosts file. If a machine has multiple
|
||||
# interfaces, use the IP address corresponding to
|
||||
# the first interface (i.e. the first network in its
|
||||
# virtualisation.vlans option).
|
||||
networking.extraHosts = lib.flip lib.concatMapStrings machines
|
||||
(m: let config = (lib.getAttr m nodes).config; in
|
||||
lib.optionalString (config.networking.primaryIPAddress != "")
|
||||
networking.extraHosts = flip concatMapStrings machines
|
||||
(m: let config = (getAttr m nodes).config; in
|
||||
optionalString (config.networking.primaryIPAddress != "")
|
||||
("${config.networking.primaryIPAddress} " +
|
||||
"${config.networking.hostName}\n"));
|
||||
|
||||
virtualisation.qemu.options =
|
||||
lib.flip map interfacesNumbered
|
||||
flip map interfacesNumbered
|
||||
({ first, second }: qemuNICFlags second first m.second);
|
||||
};
|
||||
}
|
||||
)
|
||||
(lib.getAttr m.first nodes)
|
||||
(getAttr m.first nodes)
|
||||
] );
|
||||
|
||||
in lib.listToAttrs nodes_;
|
||||
in listToAttrs nodes_;
|
||||
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ rec {
|
||||
inherit pkgs modules baseModules;
|
||||
modulesPath = ../modules;
|
||||
pkgs_i686 = import <nixpkgs> { system = "i686-linux"; };
|
||||
utils = {}; # forward compatibility
|
||||
utils = import ./utils.nix pkgs;
|
||||
};
|
||||
|
||||
# Import Nixpkgs, allowing the NixOS option nixpkgs.config to
|
||||
|
@ -58,6 +58,7 @@ sub new {
|
||||
stateDir => "$tmpDir/vm-state-$name",
|
||||
monitor => undef,
|
||||
log => $args->{log},
|
||||
redirectSerial => $args->{redirectSerial} // 1,
|
||||
};
|
||||
|
||||
mkdir $self->{stateDir}, 0700;
|
||||
@ -125,10 +126,12 @@ sub start {
|
||||
close $serialP;
|
||||
close $monitorS;
|
||||
close $shellS;
|
||||
open NUL, "</dev/null" or die;
|
||||
dup2(fileno(NUL), fileno(STDIN));
|
||||
dup2(fileno($serialC), fileno(STDOUT));
|
||||
dup2(fileno($serialC), fileno(STDERR));
|
||||
if ($self->{redirectSerial}) {
|
||||
open NUL, "</dev/null" or die;
|
||||
dup2(fileno(NUL), fileno(STDIN));
|
||||
dup2(fileno($serialC), fileno(STDOUT));
|
||||
dup2(fileno($serialC), fileno(STDERR));
|
||||
}
|
||||
$ENV{TMPDIR} = $self->{stateDir};
|
||||
$ENV{SHARED_DIR} = $sharedDir;
|
||||
$ENV{USE_TMPDIR} = 1;
|
||||
@ -349,18 +352,39 @@ sub mustFail {
|
||||
}
|
||||
|
||||
|
||||
# Wait for an Upstart job to reach the "running" state.
|
||||
sub waitForJob {
|
||||
my ($self, $jobName) = @_;
|
||||
$self->nest("waiting for job ‘$jobName’", sub {
|
||||
sub getUnitInfo {
|
||||
my ($self, $unit) = @_;
|
||||
my ($status, $lines) = $self->execute("systemctl --no-pager show '$unit'");
|
||||
return undef if $status != 0;
|
||||
my $info = {};
|
||||
foreach my $line (split '\n', $lines) {
|
||||
$line =~ /^([^=]+)=(.*)$/ or next;
|
||||
$info->{$1} = $2;
|
||||
}
|
||||
return $info;
|
||||
}
|
||||
|
||||
|
||||
# Wait for a systemd unit to reach the "active" state.
|
||||
sub waitForUnit {
|
||||
my ($self, $unit) = @_;
|
||||
$self->nest("waiting for unit ‘$unit’", sub {
|
||||
retry sub {
|
||||
my ($status, $out) = $self->execute("initctl status $jobName");
|
||||
return 1 if $out =~ /start\/running/;
|
||||
my $info = $self->getUnitInfo($unit);
|
||||
my $state = $info->{ActiveState};
|
||||
die "unit ‘$unit’ reached state ‘$state’\n" if $state eq "failed";
|
||||
return 1 if $state eq "active";
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
sub waitForJob {
|
||||
my ($self, $jobName) = @_;
|
||||
return $self->waitForUnit($jobName);
|
||||
}
|
||||
|
||||
|
||||
# Wait until the specified file exists.
|
||||
sub waitForFile {
|
||||
my ($self, $fileName) = @_;
|
||||
@ -374,16 +398,13 @@ sub waitForFile {
|
||||
|
||||
sub startJob {
|
||||
my ($self, $jobName) = @_;
|
||||
$self->execute("initctl start $jobName");
|
||||
my ($status, $out) = $self->execute("initctl status $jobName");
|
||||
die "failed to start $jobName" unless $out =~ /start\/running/;
|
||||
$self->execute("systemctl stop $jobName");
|
||||
# FIXME: check result
|
||||
}
|
||||
|
||||
sub stopJob {
|
||||
my ($self, $jobName) = @_;
|
||||
$self->execute("initctl stop $jobName");
|
||||
my ($status, $out) = $self->execute("initctl status $jobName");
|
||||
die "failed to stop $jobName" unless $out =~ /stop\/waiting/;
|
||||
$self->execute("systemctl stop $jobName");
|
||||
}
|
||||
|
||||
|
||||
@ -413,7 +434,7 @@ sub shutdown {
|
||||
my ($self) = @_;
|
||||
return unless $self->{booted};
|
||||
|
||||
$self->execute("poweroff");
|
||||
print { $self->{socket} } ("poweroff\n");
|
||||
|
||||
$self->waitForShutdown;
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ my $context = "";
|
||||
|
||||
sub createMachine {
|
||||
my ($args) = @_;
|
||||
my $vm = Machine->new({%{$args}, log => $log});
|
||||
my $vm = Machine->new({%{$args}, log => $log, redirectSerial => ($ENV{USE_SERIAL} // "0") ne "1"});
|
||||
$vms{$vm->name} = $vm;
|
||||
return $vm;
|
||||
}
|
||||
|
@ -158,7 +158,8 @@ rec {
|
||||
wrapProgram $out/bin/nixos-run-vms \
|
||||
--add-flags "$vms" \
|
||||
--set tests '"startAll; joinAll;"' \
|
||||
--set VLANS '"${toString vlans}"'
|
||||
--set VLANS '"${toString vlans}"' \
|
||||
${lib.optionalString (builtins.length vms == 1) "--set USE_SERIAL 1"}
|
||||
''; # "
|
||||
|
||||
test = runTests driver;
|
||||
|
10
lib/utils.nix
Normal file
10
lib/utils.nix
Normal file
@ -0,0 +1,10 @@
|
||||
pkgs: with pkgs.lib;
|
||||
|
||||
rec {
|
||||
|
||||
# Escape a path according to the systemd rules, e.g. /dev/xyzzy
|
||||
# becomes dev-xyzzy. FIXME: slow.
|
||||
escapeSystemdPath = s:
|
||||
replaceChars ["/" "-" " "] ["-" "\\x2d" "\\x20"] (substring 1 (stringLength s) s);
|
||||
|
||||
}
|
@ -32,10 +32,16 @@ f.write('''{{
|
||||
'''.format(args.region, key_name, ebs_size))
|
||||
f.close()
|
||||
|
||||
depl = deployment.Deployment("./ebs-creator.json", create=True, nix_exprs=["./ebs-creator.nix", "./ebs-creator-config.nix"])
|
||||
depl.load_state()
|
||||
if not args.keep: depl.destroy_vms()
|
||||
depl.deploy()
|
||||
db = deployment.open_database("./ebs-creator.charon")
|
||||
try:
|
||||
depl = deployment.open_deployment(db, "ebs-creator")
|
||||
except Exception:
|
||||
depl = deployment.create_deployment(db)
|
||||
depl.name = "ebs-creator"
|
||||
depl.auto_response = "y"
|
||||
depl.nix_exprs = ["./ebs-creator.nix", "./ebs-creator-config.nix"]
|
||||
if not args.keep: depl.destroy_resources()
|
||||
depl.deploy(allow_reboot=True)
|
||||
|
||||
m = depl.machines['machine']
|
||||
|
||||
@ -52,15 +58,23 @@ m.run_command("mkdir -p /mnt")
|
||||
m.run_command("mount {0} /mnt".format(device))
|
||||
m.run_command("touch /mnt/.ebs")
|
||||
m.run_command("mkdir -p /mnt/etc/nixos")
|
||||
m.run_command("nix-channel --add http://nixos.org/channels/nixos-unstable")
|
||||
m.run_command("nix-channel --update")
|
||||
# Kind of hacky until the nixos channel is updated to systemd
|
||||
#m.run_command("nix-channel --add http://nixos.org/channels/nixos-unstable")
|
||||
#m.run_command("nix-channel --update")
|
||||
m.run_command("mkdir unpack")
|
||||
m.run_command("cd unpack; (curl -L http://hydra.nixos.org/job/nixos/systemd/channel/latest/download | bzcat | tar xv)")
|
||||
m.run_command("mkdir nixos")
|
||||
m.run_command("mv unpack/*/* nixos")
|
||||
m.run_command("mv nixos unpack/*")
|
||||
m.run_command("nix-env -p /nix/var/nix/profiles/per-user/root/channels -i $(nix-store --add unpack/*)")
|
||||
m.run_command("rm -fR unpack")
|
||||
m.run_command("nixos-rebuild switch")
|
||||
version = m.run_command("nixos-version", capture_stdout=True).replace('"', '').rstrip()
|
||||
print >> sys.stderr, "NixOS version is {0}".format(version)
|
||||
m.run_command("cp -f $(nix-instantiate --find-file nixos/modules/virtualisation/amazon-config.nix) /mnt/etc/nixos/configuration.nix")
|
||||
m.run_command("nixos-install")
|
||||
if args.hvm:
|
||||
m.run_command('cp /nix/store/*-grub-0.97*/lib/grub/i386-pc/* /mnt/boot/grub')
|
||||
m.run_command('cp /mnt/nix/store/*-grub-0.97*/lib/grub/i386-pc/* /mnt/boot/grub')
|
||||
m.run_command('sed -i "s|hd0|hd0,0|" /mnt/boot/grub/menu.lst')
|
||||
m.run_command('echo "(hd1) /dev/xvdg" > device.map')
|
||||
m.run_command('echo -e "root (hd1,0)\nsetup (hd1)" | grub --device-map=device.map --batch')
|
||||
@ -84,12 +98,12 @@ def check():
|
||||
return status == '100%'
|
||||
|
||||
m.connect()
|
||||
volume = m._conn.get_all_volumes([], filters={'attachment.instance-id': m._instance_id, 'attachment.device': "/dev/sdg"})[0]
|
||||
volume = m._conn.get_all_volumes([], filters={'attachment.instance-id': m.resource_id, 'attachment.device': "/dev/sdg"})[0]
|
||||
if args.hvm:
|
||||
instance = m._conn.run_instances( image_id="ami-6a9e4503"
|
||||
, instance_type=instance_type
|
||||
, key_name=key_name
|
||||
, placement=m._zone
|
||||
, placement=m.zone
|
||||
, security_groups=["eelco-test"]).instances[0]
|
||||
charon.util.check_wait(lambda: instance.update() == 'running', max_tries=120)
|
||||
instance.stop()
|
||||
@ -117,7 +131,7 @@ else:
|
||||
|
||||
m._conn.create_tags([snapshot.id], {'Name': ami_name})
|
||||
|
||||
if not args.keep: depl.destroy_vms()
|
||||
if not args.keep: depl.destroy_resources()
|
||||
|
||||
# Register the image.
|
||||
aki = m._conn.get_all_images(filters={'manifest-location': '*pv-grub-hd0_1.03-x86_64*'})[0]
|
||||
@ -163,11 +177,15 @@ f.write(
|
||||
'''.format(args.region, ami_id, instance_type, key_name))
|
||||
f.close()
|
||||
|
||||
test_depl = deployment.Deployment("./ebs-test.json", create=True, nix_exprs=["./ebs-test.nix"])
|
||||
test_depl.load_state()
|
||||
test_depl = deployment.create_deployment(db)
|
||||
test_depl.auto_response = "y"
|
||||
test_depl.name = "ebs-creator-test"
|
||||
test_depl.nix_exprs = [ "./ebs-test.nix" ]
|
||||
test_depl.deploy(create_only=True)
|
||||
test_depl.machines['machine'].run_command("nixos-version")
|
||||
if not args.keep: test_depl.destroy_vms()
|
||||
if not args.keep:
|
||||
test_depl.destroy_resources()
|
||||
test_depl.delete()
|
||||
|
||||
# Log the AMI ID.
|
||||
f = open("{0}.ebs.ami-id".format(args.region), "w")
|
||||
|
@ -1,6 +1,7 @@
|
||||
#! /bin/sh -e
|
||||
|
||||
revision=$(svnversion "$NIXOS")
|
||||
nixos=$(nix-instantiate --find-file nixos)
|
||||
revision=$(cd $nixos; git rev-parse --short HEAD)
|
||||
echo "NixOS revision is $revision"
|
||||
|
||||
buildAndUploadFor() {
|
||||
@ -8,7 +9,7 @@ buildAndUploadFor() {
|
||||
arch="$2"
|
||||
|
||||
echo "building $system image..."
|
||||
NIXOS_CONFIG=$NIXOS/modules/virtualisation/amazon-config.nix nix-build "$NIXOS" \
|
||||
NIXOS_CONFIG=$nixos/modules/virtualisation/amazon-config.nix nix-build "$nixos" \
|
||||
-A config.system.build.amazonImage --argstr system "$system" -o ec2-ami
|
||||
|
||||
ec2-bundle-image -i ./ec2-ami/nixos.img --user "$AWS_ACCOUNT" --arch "$arch" \
|
||||
|
@ -1,8 +1,10 @@
|
||||
{pkgs, config, ...}:
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
with pkgs.lib;
|
||||
|
||||
###### interface
|
||||
|
||||
let
|
||||
inherit (pkgs.lib) mkOption mkIf;
|
||||
|
||||
options = {
|
||||
i18n = {
|
||||
@ -45,16 +47,15 @@ let
|
||||
The keyboard mapping table for the virtual consoles.
|
||||
";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
in
|
||||
|
||||
###### implementation
|
||||
|
||||
let
|
||||
|
||||
glibcLocales = pkgs.glibcLocales.override {
|
||||
allLocales = pkgs.lib.any (x: x == "all") config.i18n.supportedLocales;
|
||||
allLocales = any (x: x == "all") config.i18n.supportedLocales;
|
||||
locales = config.i18n.supportedLocales;
|
||||
};
|
||||
|
||||
@ -63,10 +64,19 @@ in
|
||||
{
|
||||
require = options;
|
||||
|
||||
environment.systemPackages = [glibcLocales];
|
||||
environment.systemPackages = [ glibcLocales ];
|
||||
|
||||
environment.shellInit =
|
||||
''
|
||||
export LANG=${config.i18n.defaultLocale}
|
||||
'';
|
||||
|
||||
# ‘/etc/locale.conf’ is used by systemd.
|
||||
environment.etc = singleton
|
||||
{ target = "locale.conf";
|
||||
source = pkgs.writeText "locale.conf"
|
||||
''
|
||||
LANG=${config.i18n.defaultLocale}
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
@ -3,7 +3,9 @@
|
||||
{config, pkgs, ...}:
|
||||
|
||||
with pkgs.lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.networking;
|
||||
|
||||
options = {
|
||||
@ -55,7 +57,9 @@ in
|
||||
source = pkgs.writeText "hosts"
|
||||
''
|
||||
127.0.0.1 localhost
|
||||
::1 localhost
|
||||
${optionalString cfg.enableIPv6 ''
|
||||
::1 localhost
|
||||
''}
|
||||
${cfg.extraHosts}
|
||||
'';
|
||||
target = "hosts";
|
||||
@ -71,7 +75,7 @@ in
|
||||
'' + optionalString config.services.nscd.enable ''
|
||||
# Invalidate the nscd cache whenever resolv.conf is
|
||||
# regenerated.
|
||||
libc_restart='${pkgs.upstart}/sbin/start invalidate-nscd'
|
||||
libc_restart='${pkgs.systemd}/bin/systemctl reload --no-block nscd.service'
|
||||
'' + optionalString cfg.dnsSingleRequest ''
|
||||
# only send one DNS request at a time
|
||||
resolv_conf_options='single-request'
|
||||
@ -82,4 +86,10 @@ in
|
||||
target = "resolvconf.conf";
|
||||
}
|
||||
];
|
||||
|
||||
systemd.units."ip-up.target".text =
|
||||
''
|
||||
[Unit]
|
||||
Description=Services Requiring IP Connectivity
|
||||
'';
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
example = true;
|
||||
description = ''
|
||||
Switch off the options in the default configuration that require X libraries.
|
||||
Currently this includes: ssh X11 forwarding, dbus, hal, fonts.enableCoreFonts,
|
||||
Currently this includes: ssh X11 forwarding, dbus, fonts.enableCoreFonts,
|
||||
fonts.enableFontConfig
|
||||
'';
|
||||
};
|
||||
@ -16,7 +16,6 @@
|
||||
programs.ssh.setXAuthLocation = false;
|
||||
services = {
|
||||
dbus.enable = false;
|
||||
hal.enable = false;
|
||||
};
|
||||
fonts = {
|
||||
enableCoreFonts = false;
|
||||
|
@ -6,21 +6,6 @@ let
|
||||
|
||||
cfg = config.powerManagement;
|
||||
|
||||
sleepHook = pkgs.writeScript "sleep-hook.sh"
|
||||
''
|
||||
#! ${pkgs.stdenv.shell}
|
||||
action="$1"
|
||||
case "$action" in
|
||||
hibernate|suspend)
|
||||
${cfg.powerDownCommands}
|
||||
;;
|
||||
thaw|resume)
|
||||
${cfg.resumeCommands}
|
||||
${cfg.powerUpCommands}
|
||||
;;
|
||||
esac
|
||||
'';
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
@ -32,7 +17,7 @@ in
|
||||
powerManagement = {
|
||||
|
||||
enable = mkOption {
|
||||
default = false;
|
||||
default = true;
|
||||
description =
|
||||
''
|
||||
Whether to enable power management. This includes support
|
||||
@ -79,13 +64,6 @@ in
|
||||
# Enable the ACPI daemon. Not sure whether this is essential.
|
||||
services.acpid.enable = true;
|
||||
|
||||
environment.systemPackages = [ pkgs.pmutils ];
|
||||
|
||||
environment.etc = singleton
|
||||
{ source = sleepHook;
|
||||
target = "pm/sleep.d/00sleep-hook";
|
||||
};
|
||||
|
||||
boot.kernelModules =
|
||||
[ "acpi_cpufreq" "powernow-k8" "cpufreq_performance" "cpufreq_powersave" "cpufreq_ondemand"
|
||||
"cpufreq_conservative"
|
||||
@ -93,7 +71,46 @@ in
|
||||
|
||||
powerManagement.cpuFreqGovernor = mkDefault "ondemand";
|
||||
powerManagement.scsiLinkPolicy = mkDefault "min_power";
|
||||
|
||||
|
||||
# Service executed before suspending/hibernating.
|
||||
systemd.services."pre-sleep" =
|
||||
{ description = "Pre-Sleep Actions";
|
||||
wantedBy = [ "sleep.target" ];
|
||||
before = [ "sleep.target" ];
|
||||
script =
|
||||
''
|
||||
${cfg.powerDownCommands}
|
||||
'';
|
||||
serviceConfig.Type = "oneshot";
|
||||
};
|
||||
|
||||
# Service executed before suspending/hibernating. There doesn't
|
||||
# seem to be a good way to hook in a service to be executed after
|
||||
# both suspend *and* hibernate, so have a separate one for each.
|
||||
systemd.services."post-suspend" =
|
||||
{ description = "Post-Suspend Actions";
|
||||
wantedBy = [ "suspend.target" ];
|
||||
after = [ "systemd-suspend.service" ];
|
||||
script =
|
||||
''
|
||||
${cfg.resumeCommands}
|
||||
${cfg.powerUpCommands}
|
||||
'';
|
||||
serviceConfig.Type = "oneshot";
|
||||
};
|
||||
|
||||
systemd.services."post-hibernate" =
|
||||
{ description = "Post-Hibernate Actions";
|
||||
wantedBy = [ "hibernate.target" ];
|
||||
after = [ "systemd-hibernate.service" ];
|
||||
script =
|
||||
''
|
||||
${cfg.resumeCommands}
|
||||
${cfg.powerUpCommands}
|
||||
'';
|
||||
serviceConfig.Type = "oneshot";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
{ config, pkgs, ... }:
|
||||
{ config, pkgs, utils, ... }:
|
||||
|
||||
with pkgs.lib;
|
||||
with utils;
|
||||
|
||||
{
|
||||
|
||||
@ -74,9 +75,39 @@ with pkgs.lib;
|
||||
};
|
||||
|
||||
config = mkIf ((length config.swapDevices) != 0) {
|
||||
|
||||
system.requiredKernelConfig = with config.lib.kernelConfig; [
|
||||
(isYes "SWAP")
|
||||
];
|
||||
|
||||
# Create missing swapfiles.
|
||||
# FIXME: support changing the size of existing swapfiles.
|
||||
systemd.services =
|
||||
let
|
||||
|
||||
createSwapDevice = sw:
|
||||
assert sw.device != "";
|
||||
let device' = escapeSystemdPath sw.device; in
|
||||
nameValuePair "mkswap-${escapeSystemdPath sw.device}"
|
||||
{ description = "Initialisation of Swapfile ${sw.device}";
|
||||
wantedBy = [ "${device'}.swap" ];
|
||||
before = [ "${device'}.swap" ];
|
||||
path = [ pkgs.utillinux ];
|
||||
script =
|
||||
''
|
||||
if [ ! -e "${sw.device}" ]; then
|
||||
fallocate -l ${toString sw.size}M "${sw.device}" ||
|
||||
dd if=/dev/zero of="${sw.device}" bs=1M count=${toString sw.size}
|
||||
mkswap ${sw.device}
|
||||
fi
|
||||
'';
|
||||
unitConfig.RequiresMountsFor = [ "${dirOf sw.device}" ];
|
||||
unitConfig.DefaultDependencies = false; # needed to prevent a cycle
|
||||
serviceConfig.Type = "oneshot";
|
||||
};
|
||||
|
||||
in listToAttrs (map createSwapDevice (filter (sw: sw.size != null) config.swapDevices));
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -16,9 +16,7 @@ let
|
||||
'';
|
||||
|
||||
requiredPackages =
|
||||
[ config.system.sbin.modprobe # must take precedence over module_init_tools
|
||||
config.system.build.upstart
|
||||
config.environment.nix
|
||||
[ config.environment.nix
|
||||
pkgs.acl
|
||||
pkgs.attr
|
||||
pkgs.bashInteractive # bash with ncurses support
|
||||
@ -39,7 +37,6 @@ let
|
||||
pkgs.less
|
||||
pkgs.libcap
|
||||
pkgs.man
|
||||
pkgs.module_init_tools
|
||||
pkgs.nano
|
||||
pkgs.ncurses
|
||||
pkgs.netcat
|
||||
@ -50,12 +47,10 @@ let
|
||||
pkgs.procps
|
||||
pkgs.rsync
|
||||
pkgs.strace
|
||||
pkgs.sysklogd
|
||||
pkgs.sysvtools
|
||||
pkgs.time
|
||||
pkgs.udev
|
||||
pkgs.usbutils
|
||||
pkgs.utillinuxCurses
|
||||
pkgs.utillinux
|
||||
extraManpages
|
||||
];
|
||||
|
||||
|
@ -8,74 +8,74 @@ let
|
||||
users = config.users;
|
||||
|
||||
userOpts = { name, config, ... }: {
|
||||
|
||||
|
||||
options = {
|
||||
|
||||
|
||||
name = mkOption {
|
||||
type = with types; uniq string;
|
||||
description = "The name of the user account. If undefined, the name of the attribute set will be used.";
|
||||
};
|
||||
|
||||
|
||||
description = mkOption {
|
||||
type = with types; uniq string;
|
||||
default = "";
|
||||
description = "A short description of the user account.";
|
||||
};
|
||||
|
||||
|
||||
uid = mkOption {
|
||||
type = with types; uniq (nullOr int);
|
||||
default = null;
|
||||
description = "The account UID. If undefined, NixOS will select a free UID.";
|
||||
};
|
||||
|
||||
|
||||
group = mkOption {
|
||||
type = with types; uniq string;
|
||||
default = "nogroup";
|
||||
description = "The user's primary group.";
|
||||
};
|
||||
|
||||
|
||||
extraGroups = mkOption {
|
||||
type = types.listOf types.string;
|
||||
default = [];
|
||||
description = "The user's auxiliary groups.";
|
||||
};
|
||||
|
||||
|
||||
home = mkOption {
|
||||
type = with types; uniq string;
|
||||
default = "/var/empty";
|
||||
description = "The user's home directory.";
|
||||
};
|
||||
|
||||
|
||||
shell = mkOption {
|
||||
type = with types; uniq string;
|
||||
default = "/run/current-system/sw/sbin/nologin";
|
||||
description = "The path to the user's shell.";
|
||||
};
|
||||
|
||||
|
||||
createHome = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "If true, the home directory will be created automatically.";
|
||||
};
|
||||
|
||||
|
||||
useDefaultShell = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "If true, the user's shell will be set to <literal>users.defaultUserShell</literal>.";
|
||||
};
|
||||
|
||||
|
||||
password = mkOption {
|
||||
type = with types; uniq (nullOr string);
|
||||
default = null;
|
||||
description = "The user's password. If undefined, no password is set for the user. Warning: do not set confidential information here because this data would be readable by all. This option should only be used for public account such as guest.";
|
||||
};
|
||||
|
||||
|
||||
isSystemUser = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Indicates if the user is a system user or not.";
|
||||
};
|
||||
|
||||
|
||||
createUser = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
@ -85,7 +85,13 @@ let
|
||||
then not modify any of the basic properties for the user account.
|
||||
";
|
||||
};
|
||||
|
||||
|
||||
isAlias = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "If true, the UID of this user is not required to be unique and can thus alias another user.";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
config = {
|
||||
@ -93,41 +99,41 @@ let
|
||||
uid = mkDefault (attrByPath [name] null ids.uids);
|
||||
shell = mkIf config.useDefaultShell (mkDefault users.defaultUserShell);
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
|
||||
groupOpts = { name, config, ... }: {
|
||||
|
||||
|
||||
options = {
|
||||
|
||||
|
||||
name = mkOption {
|
||||
type = with types; uniq string;
|
||||
description = "The name of the group. If undefined, the name of the attribute set will be used.";
|
||||
};
|
||||
|
||||
|
||||
gid = mkOption {
|
||||
type = with types; uniq (nullOr int);
|
||||
default = null;
|
||||
description = "The GID of the group. If undefined, NixOS will select a free GID.";
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
|
||||
config = {
|
||||
name = mkDefault name;
|
||||
gid = mkDefault (attrByPath [name] null ids.gids);
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
|
||||
# Note: the 'X' in front of the password is to distinguish between
|
||||
# having an empty password, and not having a password.
|
||||
serializedUser = userName: let u = getAttr userName config.users.extraUsers; in "${u.name}\n${u.description}\n${if u.uid != null then toString u.uid else ""}\n${u.group}\n${toString (concatStringsSep "," u.extraGroups)}\n${u.home}\n${u.shell}\n${toString u.createHome}\n${if u.password != null then "X" + u.password else ""}\n${toString u.isSystemUser}\n${if u.createUser then "yes" else "no"}\n";
|
||||
serializedUser = u: "${u.name}\n${u.description}\n${if u.uid != null then toString u.uid else ""}\n${u.group}\n${toString (concatStringsSep "," u.extraGroups)}\n${u.home}\n${u.shell}\n${toString u.createHome}\n${if u.password != null then "X" + u.password else ""}\n${toString u.isSystemUser}\n${toString u.createUser}\n${toString u.isAlias}\n";
|
||||
|
||||
# keep this extra file so that cat can be used to pass special chars such as "`" which is used in the avahi daemon
|
||||
usersFile = pkgs.writeText "users" (
|
||||
concatMapStrings serializedUser (attrNames config.users.extraUsers)
|
||||
);
|
||||
let
|
||||
p = partition (u: u.isAlias) (attrValues config.users.extraUsers);
|
||||
in concatStrings (map serializedUser p.wrong ++ map serializedUser p.right));
|
||||
|
||||
in
|
||||
|
||||
@ -208,6 +214,7 @@ in
|
||||
users = { };
|
||||
nixbld = { };
|
||||
utmp = { };
|
||||
adm = { }; # expected by journald
|
||||
};
|
||||
|
||||
system.activationScripts.rootPasswd = stringAfter [ "etc" ]
|
||||
@ -242,8 +249,9 @@ in
|
||||
read password
|
||||
read isSystemUser
|
||||
read createUser
|
||||
read isAlias
|
||||
|
||||
if ! test "$createUser" = "yes"; then
|
||||
if [ -z "$createUser" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
@ -256,6 +264,7 @@ in
|
||||
--home "$home" \
|
||||
--shell "$shell" \
|
||||
''${createHome:+--create-home} \
|
||||
''${isAlias:+--non-unique} \
|
||||
"$name"
|
||||
if test "''${password:0:1}" = 'X'; then
|
||||
(echo "''${password:1}"; echo "''${password:1}") | ${pkgs.shadow}/bin/passwd "$name"
|
||||
|
@ -87,7 +87,7 @@ let
|
||||
# The Grub image.
|
||||
grubImage = pkgs.runCommand "grub_eltorito" {}
|
||||
''
|
||||
${pkgs.grub2}/bin/grub-mkimage -O i386-pc -o tmp biosdisk iso9660 help linux linux16 chain vbe png jpeg echo test normal
|
||||
${pkgs.grub2}/bin/grub-mkimage -O i386-pc -o tmp biosdisk iso9660 help linux linux16 chain png jpeg echo gfxmenu reboot
|
||||
cat ${pkgs.grub2}/lib/grub/*/cdboot.img tmp > $out
|
||||
''; # */
|
||||
|
||||
@ -184,27 +184,15 @@ in
|
||||
# Note that /dev/root is a symlink to the actual root device
|
||||
# specified on the kernel command line, created in the stage 1 init
|
||||
# script.
|
||||
fileSystems =
|
||||
[ { mountPoint = "/";
|
||||
device = "/dev/root";
|
||||
}
|
||||
{ mountPoint = "/nix/store";
|
||||
fsType = "squashfs";
|
||||
device = "/nix-store.squashfs";
|
||||
options = "loop";
|
||||
neededForBoot = true;
|
||||
}
|
||||
];
|
||||
fileSystems."/".device = "/dev/root";
|
||||
|
||||
# We need squashfs in the initrd to mount the compressed Nix store,
|
||||
# and aufs to make the root filesystem appear writable.
|
||||
boot.extraModulePackages =
|
||||
if config.boot.kernelPackages.aufs == null then
|
||||
abort "This kernel doesn't have aufs enabled"
|
||||
else
|
||||
[ config.boot.kernelPackages.aufs ];
|
||||
fileSystems."/nix/store" =
|
||||
{ fsType = "squashfs";
|
||||
device = "/nix-store.squashfs";
|
||||
options = "loop";
|
||||
};
|
||||
|
||||
boot.initrd.availableKernelModules = [ "aufs" "squashfs" "iso9660" ];
|
||||
boot.initrd.availableKernelModules = [ "squashfs" "iso9660" ];
|
||||
|
||||
boot.initrd.kernelModules = [ "loop" ];
|
||||
|
||||
@ -214,16 +202,20 @@ in
|
||||
# /nix/store (the squashfs image) to make this a live CD.
|
||||
boot.initrd.postMountCommands =
|
||||
''
|
||||
mkdir /mnt-root-tmpfs
|
||||
mount -t tmpfs -o "mode=755" none /mnt-root-tmpfs
|
||||
mkdir -p /unionfs-chroot/ro-root
|
||||
mount --rbind $targetRoot /unionfs-chroot/ro-root
|
||||
|
||||
mkdir /unionfs-chroot/rw-root
|
||||
mount -t tmpfs -o "mode=755" none /unionfs-chroot/rw-root
|
||||
mkdir /mnt-root-union
|
||||
mount -t aufs -o dirs=/mnt-root-tmpfs=rw:$targetRoot=ro none /mnt-root-union
|
||||
unionfs -o allow_other,cow,chroot=/unionfs-chroot /rw-root=RW:/ro-root=RO /mnt-root-union
|
||||
oldTargetRoot=$targetRoot
|
||||
targetRoot=/mnt-root-union
|
||||
|
||||
mkdir /mnt-store-tmpfs
|
||||
mount -t tmpfs -o "mode=755" none /mnt-store-tmpfs
|
||||
mkdir -p $targetRoot/nix/store
|
||||
mount -t aufs -o dirs=/mnt-store-tmpfs=rw:/mnt-root/nix/store=ro none /mnt-root-union/nix/store
|
||||
mkdir /unionfs-chroot/rw-store
|
||||
mount -t tmpfs -o "mode=755" none /unionfs-chroot/rw-store
|
||||
mkdir -p $oldTargetRoot/nix/store
|
||||
unionfs -o allow_other,cow,nonempty,chroot=/unionfs-chroot /rw-store=RW:/ro-root/nix/store=RO /mnt-root-union/nix/store
|
||||
'';
|
||||
|
||||
# Closures to be copied to the Nix store on the CD, namely the init
|
||||
@ -315,7 +307,7 @@ in
|
||||
'';
|
||||
|
||||
# Add vfat support to the initrd to enable people to copy the
|
||||
# contents of the CD to a bootable USB stick.
|
||||
boot.initrd.supportedFilesystems = [ "vfat" ];
|
||||
# contents of the CD to a bootable USB stick. Need unionfs-fuse for union mounts
|
||||
boot.initrd.supportedFilesystems = [ "vfat" "unionfs-fuse" ];
|
||||
|
||||
}
|
||||
|
29
modules/installer/tools/get-version-suffix
Normal file
29
modules/installer/tools/get-version-suffix
Normal file
@ -0,0 +1,29 @@
|
||||
getVersion() {
|
||||
local dir="$1"
|
||||
rev=
|
||||
if [ -e "$dir/.git" ]; then
|
||||
if [ -z "$(type -P git)" ]; then
|
||||
echo "warning: Git not found; cannot figure out revision of $dir" >&2
|
||||
return
|
||||
fi
|
||||
cd "$dir"
|
||||
rev=$(git rev-parse --short HEAD)
|
||||
if git describe --always --dirty | grep -q dirty; then
|
||||
rev+=M
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
if nixos=$(nix-instantiate --find-file nixos "$@"); then
|
||||
getVersion $nixos
|
||||
if [ -n "$rev" ]; then
|
||||
suffix="pre-$rev"
|
||||
if nixpkgs=$(nix-instantiate --find-file nixpkgs "$@"); then
|
||||
getVersion $nixpkgs
|
||||
if [ -n "$rev" ]; then
|
||||
suffix+="-$rev"
|
||||
fi
|
||||
fi
|
||||
echo $suffix
|
||||
fi
|
||||
fi
|
@ -16,7 +16,7 @@ if test -z "$mountPoint"; then
|
||||
fi
|
||||
|
||||
if test -z "$NIXOS_CONFIG"; then
|
||||
NIXOS_CONFIG=/mnt/etc/nixos/configuration.nix
|
||||
NIXOS_CONFIG=/etc/nixos/configuration.nix
|
||||
fi
|
||||
|
||||
if ! test -e "$mountPoint"; then
|
||||
@ -28,32 +28,41 @@ if ! grep -F -q " $mountPoint " /proc/mounts; then
|
||||
echo "$mountPoint doesn't appear to be a mount point"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! test -e "$NIXOS_CONFIG"; then
|
||||
|
||||
if ! test -e "$mountPoint/$NIXOS_CONFIG"; then
|
||||
echo "configuration file $NIXOS_CONFIG doesn't exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
# Mount some stuff in the target root directory. We bind-mount /etc
|
||||
# into the chroot because we need networking and the nixbld user
|
||||
# accounts in /etc/passwd. But we do need the target's /etc/nixos.
|
||||
mkdir -m 0755 -p $mountPoint/dev $mountPoint/proc $mountPoint/sys $mountPoint/mnt $mountPoint/etc
|
||||
mount --rbind /dev $mountPoint/dev
|
||||
mount --rbind /proc $mountPoint/proc
|
||||
mount --rbind /sys $mountPoint/sys
|
||||
mount --rbind / $mountPoint/mnt
|
||||
mkdir -m 0755 -p $mountPoint/dev $mountPoint/proc $mountPoint/sys $mountPoint/mnt $mountPoint/mnt2 $mountPoint/etc /etc/nixos
|
||||
mount --make-private / # systemd makes / shared, which is annoying
|
||||
mount --bind / $mountPoint/mnt
|
||||
mount --bind /nix/store $mountPoint/mnt/nix/store
|
||||
mount --bind /dev $mountPoint/dev
|
||||
mount --bind /dev/shm $mountPoint/dev/shm
|
||||
mount --bind /proc $mountPoint/proc
|
||||
mount --bind /sys $mountPoint/sys
|
||||
mount --bind $mountPoint/etc/nixos $mountPoint/mnt2
|
||||
mount --bind /etc $mountPoint/etc
|
||||
mount --bind $mountPoint/mnt/$mountPoint/etc/nixos $mountPoint/etc/nixos
|
||||
mount --bind $mountPoint/mnt2 $mountPoint/etc/nixos
|
||||
|
||||
cleanup() {
|
||||
set +e
|
||||
umount -l $mountPoint/mnt
|
||||
umount -l $mountPoint/dev
|
||||
umount -l $mountPoint/proc
|
||||
umount -l $mountPoint/sys
|
||||
mountpoint -q $mountPoint/etc && umount -l $mountPoint/etc
|
||||
mountpoint -q $mountPoint/etc/nixos && umount $mountPoint/etc/nixos
|
||||
mountpoint -q $mountPoint/etc && umount $mountPoint/etc
|
||||
umount $mountPoint/mnt2
|
||||
umount $mountPoint/sys
|
||||
umount $mountPoint/proc
|
||||
umount $mountPoint/dev/shm
|
||||
umount $mountPoint/dev
|
||||
umount $mountPoint/mnt/nix/store
|
||||
umount $mountPoint/mnt
|
||||
rmdir $mountPoint/mnt $mountPoint/mnt2
|
||||
}
|
||||
|
||||
trap "cleanup" EXIT
|
||||
@ -144,7 +153,7 @@ srcs=$(nix-env -p /nix/var/nix/profiles/per-user/root/channels -q nixos --no-nam
|
||||
# Build the specified Nix expression in the target store and install
|
||||
# it into the system configuration profile.
|
||||
echo "building the system configuration..."
|
||||
NIX_PATH="/mnt$srcs/nixos:nixos-config=/mnt$NIXOS_CONFIG" NIXOS_CONFIG= \
|
||||
NIX_PATH="/mnt$srcs/nixos:nixos-config=$NIXOS_CONFIG" NIXOS_CONFIG= \
|
||||
chroot $mountPoint @nix@/bin/nix-env \
|
||||
-p /nix/var/nix/profiles/system -f '<nixos>' --set -A system --show-trace
|
||||
|
||||
|
@ -239,17 +239,14 @@ if $generate; then
|
||||
# Add filesystem entries for each partition that you want to see
|
||||
# mounted at boot time. This should include at least the root
|
||||
# filesystem.
|
||||
fileSystems =
|
||||
[ # { mountPoint = "/";
|
||||
# device = "/dev/disk/by-label/nixos";
|
||||
# }
|
||||
|
||||
# { mountPoint = "/data"; # where you want to mount the device
|
||||
# device = "/dev/sdb"; # the device
|
||||
# fsType = "ext3"; # the type of the partition
|
||||
# options = "data=journal";
|
||||
# }
|
||||
];
|
||||
# fileSystems."/".device = "/dev/disk/by-label/nixos";
|
||||
|
||||
# fileSystems."/data" = # where you want to mount the device
|
||||
# { device = "/dev/sdb"; # the device
|
||||
# fsType = "ext3"; # the type of the partition
|
||||
# options = "data=journal";
|
||||
# };
|
||||
|
||||
# List swap partitions activated at boot time.
|
||||
swapDevices =
|
||||
|
@ -44,13 +44,13 @@ EOF
|
||||
|
||||
|
||||
# Parse the command line.
|
||||
extraBuildFlags=
|
||||
extraBuildFlags=()
|
||||
action=
|
||||
buildNix=1
|
||||
rollback=
|
||||
upgrade=
|
||||
|
||||
while test "$#" -gt 0; do
|
||||
while [ "$#" -gt 0 ]; do
|
||||
i="$1"; shift 1
|
||||
case "$i" in
|
||||
--help)
|
||||
@ -72,20 +72,20 @@ while test "$#" -gt 0; do
|
||||
upgrade=1
|
||||
;;
|
||||
--show-trace|--no-build-hook|--keep-failed|-K|--keep-going|-k|--verbose|-v|--fallback)
|
||||
extraBuildFlags="$extraBuildFlags $i"
|
||||
extraBuildFlags+=("$i")
|
||||
;;
|
||||
--max-jobs|-j|--cores|-I)
|
||||
j="$1"; shift 1
|
||||
extraBuildFlags="$extraBuildFlags $i $j"
|
||||
extraBuildFlags+=("$i" "$j")
|
||||
;;
|
||||
--option)
|
||||
j="$1"; shift 1
|
||||
k="$1"; shift 1
|
||||
extraBuildFlags="$extraBuildFlags $i $j $k"
|
||||
extraBuildFlags+=("$i" "$j" "$k")
|
||||
;;
|
||||
--fast)
|
||||
buildNix=
|
||||
extraBuildFlags="$extraBuildFlags --show-trace"
|
||||
extraBuildFlags+=(--show-trace)
|
||||
;;
|
||||
*)
|
||||
echo "$0: unknown option \`$i'"
|
||||
@ -94,13 +94,9 @@ while test "$#" -gt 0; do
|
||||
esac
|
||||
done
|
||||
|
||||
if test -z "$action"; then showSyntax; fi
|
||||
if [ -z "$action" ]; then showSyntax; fi
|
||||
|
||||
if test "$action" = dry-run; then
|
||||
extraBuildFlags="$extraBuildFlags --dry-run"
|
||||
fi
|
||||
|
||||
if test -n "$rollback"; then
|
||||
if [ -n "$rollback" ]; then
|
||||
buildNix=
|
||||
fi
|
||||
|
||||
@ -115,7 +111,7 @@ trap 'rm -rf "$tmpDir"' EXIT
|
||||
# This matters if the new Nix in Nixpkgs has a schema change. It
|
||||
# would upgrade the schema, which should only happen once we actually
|
||||
# switch to the new configuration.
|
||||
if initctl status nix-daemon 2>&1 | grep -q 'running'; then
|
||||
if systemctl show nix-daemon.socket nix-daemon.service | grep -q ActiveState=active; then
|
||||
export NIX_REMOTE=${NIX_REMOTE:-daemon}
|
||||
fi
|
||||
|
||||
@ -129,42 +125,57 @@ fi
|
||||
# First build Nix, since NixOS may require a newer version than the
|
||||
# current one. Of course, the same goes for Nixpkgs, but Nixpkgs is
|
||||
# more conservative.
|
||||
if [ -n "$buildNix" ]; then
|
||||
if [ "$action" != dry-run -a -n "$buildNix" ]; then
|
||||
echo "building Nix..." >&2
|
||||
if ! nix-build '<nixos>' -A config.environment.nix -o $tmpDir/nix $extraBuildFlags > /dev/null; then
|
||||
if ! nix-build '<nixos>' -A nixFallback -o $tmpDir/nix $extraBuildFlags > /dev/null; then
|
||||
nix-build '<nixpkgs>' -A nixUnstable -o $tmpDir/nix $extraBuildFlags > /dev/null
|
||||
if ! nix-build '<nixos>' -A config.environment.nix -o $tmpDir/nix "${extraBuildFlags[@]}" > /dev/null; then
|
||||
if ! nix-build '<nixos>' -A nixFallback -o $tmpDir/nix "${extraBuildFlags[@]}" > /dev/null; then
|
||||
nix-build '<nixpkgs>' -A nixUnstable -o $tmpDir/nix "${extraBuildFlags[@]}" > /dev/null
|
||||
fi
|
||||
fi
|
||||
PATH=$tmpDir/nix/bin:$PATH
|
||||
fi
|
||||
|
||||
|
||||
# Update the version suffix if we're building from Git (so that
|
||||
# nixos-version shows something useful).
|
||||
if nixos=$(nix-instantiate --find-file nixos "${extraBuildFlags[@]}"); then
|
||||
suffix=$($SHELL $nixos/modules/installer/tools/get-version-suffix "${extraBuildFlags[@]}")
|
||||
if [ -n "$suffix" ]; then
|
||||
echo -n "$suffix" > "$nixos/.version-suffix"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
if [ "$action" = dry-run ]; then
|
||||
extraBuildFlags+=(--dry-run)
|
||||
fi
|
||||
|
||||
|
||||
# Either upgrade the configuration in the system profile (for "switch"
|
||||
# or "boot"), or just build it and create a symlink "result" in the
|
||||
# current directory (for "build" and "test").
|
||||
if test -z "$rollback"; then
|
||||
if [ -z "$rollback" ]; then
|
||||
echo "building the system configuration..." >&2
|
||||
if test "$action" = switch -o "$action" = boot; then
|
||||
nix-env $extraBuildFlags -p /nix/var/nix/profiles/system -f '<nixos>' --set -A system
|
||||
if [ "$action" = switch -o "$action" = boot ]; then
|
||||
nix-env "${extraBuildFlags[@]}" -p /nix/var/nix/profiles/system -f '<nixos>' --set -A system
|
||||
pathToConfig=/nix/var/nix/profiles/system
|
||||
elif test "$action" = test -o "$action" = build -o "$action" = dry-run; then
|
||||
nix-build '<nixos>' -A system -K -k $extraBuildFlags > /dev/null
|
||||
elif [ "$action" = test -o "$action" = build -o "$action" = dry-run ]; then
|
||||
nix-build '<nixos>' -A system -K -k "${extraBuildFlags[@]}" > /dev/null
|
||||
pathToConfig=./result
|
||||
elif [ "$action" = build-vm ]; then
|
||||
nix-build '<nixos>' -A vm -K -k $extraBuildFlags > /dev/null
|
||||
nix-build '<nixos>' -A vm -K -k "${extraBuildFlags[@]}" > /dev/null
|
||||
pathToConfig=./result
|
||||
elif [ "$action" = build-vm-with-bootloader ]; then
|
||||
nix-build '<nixos>' -A vmWithBootLoader -K -k $extraBuildFlags > /dev/null
|
||||
nix-build '<nixos>' -A vmWithBootLoader -K -k "${extraBuildFlags[@]}" > /dev/null
|
||||
pathToConfig=./result
|
||||
else
|
||||
showSyntax
|
||||
fi
|
||||
else # test -n "$rollback"
|
||||
if test "$action" = switch -o "$action" = boot; then
|
||||
else # [ -n "$rollback" ]
|
||||
if [ "$action" = switch -o "$action" = boot ]; then
|
||||
nix-env --rollback -p /nix/var/nix/profiles/system
|
||||
pathToConfig=/nix/var/nix/profiles/system
|
||||
elif test "$action" = test -o "$action" = build; then
|
||||
elif [ "$action" = test -o "$action" = build ]; then
|
||||
systemNumber=$(
|
||||
nix-env -p /nix/var/nix/profiles/system --list-generations |
|
||||
sed -n '/current/ {g; p;}; s/ *\([0-9]*\).*/\1/; h'
|
||||
@ -179,7 +190,7 @@ fi
|
||||
|
||||
# If we're not just building, then make the new configuration the boot
|
||||
# default and/or activate it now.
|
||||
if test "$action" = switch -o "$action" = boot -o "$action" = test; then
|
||||
if [ "$action" = switch -o "$action" = boot -o "$action" = test ]; then
|
||||
# Just in case the new configuration hangs the system, do a sync now.
|
||||
sync
|
||||
|
||||
@ -187,7 +198,7 @@ if test "$action" = switch -o "$action" = boot -o "$action" = test; then
|
||||
fi
|
||||
|
||||
|
||||
if test "$action" = build-vm; then
|
||||
if [ "$action" = build-vm ]; then
|
||||
cat >&2 <<EOF
|
||||
|
||||
Done. The virtual machine can be started by running $(echo $pathToConfig/bin/run-*-vm).
|
||||
|
@ -70,4 +70,18 @@ in
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
config = {
|
||||
|
||||
# FIXME
|
||||
nixpkgs.config.packageOverrides = pkgs: {
|
||||
#udev = pkgs.systemd;
|
||||
slim = pkgs.slim.override (args: if args ? consolekit then { consolekit = null; } else { });
|
||||
lvm2 = pkgs.lvm2.override { udev = pkgs.systemd; };
|
||||
upower = pkgs.upower.override { useSystemd = true; };
|
||||
polkit = pkgs.polkit.override { useSystemd = true; };
|
||||
consolekit = null;
|
||||
};
|
||||
|
||||
};
|
||||
}
|
||||
|
@ -5,18 +5,27 @@ with pkgs.lib;
|
||||
{
|
||||
|
||||
options = {
|
||||
|
||||
|
||||
system.nixosVersion = mkOption {
|
||||
default =
|
||||
builtins.readFile ../../.version
|
||||
+ (if builtins.pathExists ../../.version-suffix then builtins.readFile ../../.version-suffix else "pre-git");
|
||||
type = types.uniq types.string;
|
||||
description = "NixOS version.";
|
||||
};
|
||||
|
||||
system.nixosVersionSuffix = mkOption {
|
||||
type = types.uniq types.string;
|
||||
description = "NixOS version suffix.";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
config = {
|
||||
|
||||
system.nixosVersion =
|
||||
mkDefault (builtins.readFile ../../.version + config.system.nixosVersionSuffix);
|
||||
|
||||
system.nixosVersionSuffix =
|
||||
mkDefault (if builtins.pathExists ../../.version-suffix then builtins.readFile ../../.version-suffix else "pre-git");
|
||||
|
||||
# Generate /etc/os-release. See
|
||||
# http://0pointer.de/public/systemd-man/os-release.html for the
|
||||
# format.
|
||||
@ -32,7 +41,7 @@ with pkgs.lib;
|
||||
'';
|
||||
target = "os-release";
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -46,11 +46,10 @@
|
||||
./rename.nix
|
||||
./security/apparmor.nix
|
||||
./security/ca.nix
|
||||
./security/consolekit.nix
|
||||
./security/pam.nix
|
||||
./security/pam_usb.nix
|
||||
./security/policykit.nix
|
||||
./security/polkit.nix
|
||||
./security/rngd.nix
|
||||
./security/rtkit.nix
|
||||
./security/setuid-wrappers.nix
|
||||
./security/sudo.nix
|
||||
@ -73,7 +72,6 @@
|
||||
./services/games/ghost-one.nix
|
||||
./services/hardware/acpid.nix
|
||||
./services/hardware/bluetooth.nix
|
||||
./services/hardware/hal.nix
|
||||
./services/hardware/nvidia-optimus.nix
|
||||
./services/hardware/pcscd.nix
|
||||
./services/hardware/pommed.nix
|
||||
@ -102,6 +100,7 @@
|
||||
./services/misc/rogue.nix
|
||||
./services/misc/svnserve.nix
|
||||
./services/misc/synergy.nix
|
||||
./services/monitoring/dd-agent.nix
|
||||
./services/monitoring/monit.nix
|
||||
./services/monitoring/nagios/default.nix
|
||||
./services/monitoring/smartd.nix
|
||||
@ -166,13 +165,12 @@
|
||||
./services/security/tor.nix
|
||||
./services/security/torify.nix
|
||||
./services/security/torsocks.nix
|
||||
./services/system/cgroups.nix
|
||||
./services/system/dbus.nix
|
||||
./services/system/kerberos.nix
|
||||
./services/system/nscd.nix
|
||||
./services/system/uptimed.nix
|
||||
./services/ttys/gpm.nix
|
||||
./services/ttys/mingetty.nix
|
||||
./services/ttys/agetty.nix
|
||||
./services/web-servers/apache-httpd/default.nix
|
||||
./services/web-servers/jboss/default.nix
|
||||
./services/web-servers/tomcat.nix
|
||||
@ -206,12 +204,11 @@
|
||||
./system/boot/loader/init-script/init-script.nix
|
||||
./system/boot/luksroot.nix
|
||||
./system/boot/modprobe.nix
|
||||
./system/boot/shutdown.nix
|
||||
./system/boot/stage-1.nix
|
||||
./system/boot/stage-2.nix
|
||||
./system/boot/systemd.nix
|
||||
./system/etc/etc.nix
|
||||
./system/upstart-events/control-alt-delete.nix
|
||||
./system/upstart-events/runlevel.nix
|
||||
./system/upstart-events/shutdown.nix
|
||||
./system/upstart/upstart.nix
|
||||
./tasks/cpu-freq.nix
|
||||
./tasks/filesystems.nix
|
||||
@ -219,6 +216,7 @@
|
||||
./tasks/filesystems/ext.nix
|
||||
./tasks/filesystems/nfs.nix
|
||||
./tasks/filesystems/reiserfs.nix
|
||||
./tasks/filesystems/unionfs-fuse.nix
|
||||
./tasks/filesystems/vfat.nix
|
||||
./tasks/filesystems/xfs.nix
|
||||
./tasks/kbd.nix
|
||||
|
@ -10,19 +10,11 @@ with pkgs.lib;
|
||||
boot.vesa = false;
|
||||
boot.initrd.enableSplashScreen = false;
|
||||
services.ttyBackgrounds.enable = false;
|
||||
services.mingetty.ttys = [ ];
|
||||
|
||||
# Don't start a tty on the serial consoles.
|
||||
systemd.services."serial-getty@ttyS0".enable = false;
|
||||
systemd.services."serial-getty@hvc0".enable = false;
|
||||
|
||||
# Since we can't manually respond to a panic, just reboot.
|
||||
boot.kernelParams = [ "panic=1" "stage1panic=1" ];
|
||||
|
||||
# Since we don't have an (interactive) console, disable the
|
||||
# emergency shell (started if mountall fails).
|
||||
jobs."mount-failed".script = mkOverride 50
|
||||
''
|
||||
${pkgs.utillinux}/bin/logger -p user.emerg -t mountall "filesystem ‘$DEVICE’ could not be mounted on ‘$MOUNTPOINT’"
|
||||
'';
|
||||
|
||||
# Likewise, redirect mountall output from the console to the default
|
||||
# Upstart job log file.
|
||||
jobs."mountall".console = mkOverride 50 "";
|
||||
boot.kernelParams = [ "panic=1" "boot.panic_on_fail" ];
|
||||
}
|
||||
|
@ -31,20 +31,48 @@ let
|
||||
|
||||
options = {
|
||||
|
||||
environment.promptInit = mkOption {
|
||||
default = ''
|
||||
# Provide a nice prompt.
|
||||
PROMPT_COLOR="1;31m"
|
||||
let $UID && PROMPT_COLOR="1;32m"
|
||||
PS1="\n\[\033[$PROMPT_COLOR\][\u@\h:\w]\\$\[\033[0m\] "
|
||||
if test "$TERM" = "xterm"; then
|
||||
PS1="\[\033]2;\h:\u:\w\007\]$PS1"
|
||||
fi
|
||||
'';
|
||||
description = "
|
||||
Script used to initialized shell prompt.
|
||||
";
|
||||
type = with pkgs.lib.types; string;
|
||||
};
|
||||
|
||||
environment.shellInit = mkOption {
|
||||
default = "";
|
||||
example = ''export PATH=/godi/bin/:$PATH'';
|
||||
description = "
|
||||
Script used to initialized user shell environments.
|
||||
";
|
||||
type = with pkgs.lib.types; string;
|
||||
};
|
||||
default = "";
|
||||
example = ''export PATH=/godi/bin/:$PATH'';
|
||||
description = "
|
||||
Script used to initialized user shell environments.
|
||||
";
|
||||
type = with pkgs.lib.types; string;
|
||||
};
|
||||
|
||||
environment.enableBashCompletion = mkOption {
|
||||
default = false;
|
||||
description = "Enable bash-completion for all interactive shells.";
|
||||
type = with pkgs.lib.types; bool;
|
||||
};
|
||||
default = false;
|
||||
description = "Enable bash-completion for all interactive shells.";
|
||||
type = with pkgs.lib.types; bool;
|
||||
};
|
||||
|
||||
environment.binsh = mkOption {
|
||||
default = "${config.system.build.binsh}/bin/sh";
|
||||
example = "\${pkgs.dash}/bin/dash";
|
||||
type = with pkgs.lib.types; path;
|
||||
description = ''
|
||||
Select the shell executable that is linked system-wide to
|
||||
<literal>/bin/sh</literal>. Please note that NixOS assumes all
|
||||
over the place that shell to be Bash, so override the default
|
||||
setting only if you know exactly what you're doing.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
@ -68,6 +96,7 @@ in
|
||||
# configured properly.
|
||||
source = pkgs.substituteAll {
|
||||
src = ./bashrc.sh;
|
||||
inherit (config.environment) promptInit;
|
||||
inherit initBashCompletion shellAliases;
|
||||
};
|
||||
target = "bashrc";
|
||||
@ -79,12 +108,12 @@ in
|
||||
}
|
||||
];
|
||||
|
||||
environment.shellAliases = {
|
||||
ls = "ls --color=tty";
|
||||
ll = "ls -l";
|
||||
l = "ls -alh";
|
||||
which = "type -P";
|
||||
};
|
||||
environment.shellAliases =
|
||||
{ ls = "ls --color=tty";
|
||||
ll = "ls -l";
|
||||
l = "ls -alh";
|
||||
which = "type -P";
|
||||
};
|
||||
|
||||
system.build.binsh = pkgs.bashInteractive;
|
||||
|
||||
@ -93,7 +122,7 @@ in
|
||||
# Create the required /bin/sh symlink; otherwise lots of things
|
||||
# (notably the system() function) won't work.
|
||||
mkdir -m 0755 -p /bin
|
||||
ln -sfn ${config.system.build.binsh}/bin/sh /bin/.sh.tmp
|
||||
ln -sfn "${config.environment.binsh}" /bin/.sh.tmp
|
||||
mv /bin/.sh.tmp /bin/sh # atomically replace /bin/sh
|
||||
'';
|
||||
|
||||
|
@ -19,14 +19,6 @@ if [ -z "$PS1" ]; then return; fi
|
||||
# Check the window size after every command.
|
||||
shopt -s checkwinsize
|
||||
|
||||
# Provide a nice prompt.
|
||||
PROMPT_COLOR="1;31m"
|
||||
let $UID && PROMPT_COLOR="1;32m"
|
||||
PS1="\n\[\033[$PROMPT_COLOR\][\u@\h:\w]\\$\[\033[0m\] "
|
||||
if test "$TERM" = "xterm"; then
|
||||
PS1="\[\033]2;\h:\u:\w\007\]$PS1"
|
||||
fi
|
||||
|
||||
@promptInit@
|
||||
@initBashCompletion@
|
||||
|
||||
@shellAliases@
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Configuration for the pwdutils suite of tools: passwd, useradd, etc.
|
||||
|
||||
{config, pkgs, ...}:
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
let
|
||||
|
||||
@ -27,6 +27,7 @@ let
|
||||
# Uncomment this to allow non-root users to change their account
|
||||
#information. This should be made configurable.
|
||||
#CHFN_RESTRICT frwh
|
||||
|
||||
'';
|
||||
|
||||
in
|
||||
@ -90,7 +91,7 @@ in
|
||||
{ name = "groupmod"; rootOK = true; }
|
||||
{ name = "groupmems"; rootOK = true; }
|
||||
{ name = "groupdel"; rootOK = true; }
|
||||
{ name = "login"; ownDevices = true; allowNullPassword = true; }
|
||||
{ name = "login"; startSession = true; allowNullPassword = true; showMotd = true; }
|
||||
];
|
||||
|
||||
security.setuidPrograms = [ "passwd" "chfn" "su" "newgrp" ];
|
||||
|
@ -38,7 +38,7 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
assertions = [{ assertion = if cfg.forwardX11 then cfg.setXAuthLocation else true;
|
||||
assertions = [{ assertion = if cfg.forwardX11 then cfg.setXAuthLocation else true;
|
||||
message = "cannot enable X11 forwarding without setting xauth location";}];
|
||||
|
||||
config = {
|
||||
@ -46,14 +46,11 @@ in
|
||||
[ { # SSH configuration. Slight duplication of the sshd_config
|
||||
# generation in the sshd service.
|
||||
source = pkgs.writeText "ssh_config" ''
|
||||
AddressFamily ${if config.networking.enableIPv6 then "any" else "inet"}
|
||||
${optionalString cfg.setXAuthLocation ''
|
||||
XAuthLocation ${pkgs.xorg.xauth}/bin/xauth
|
||||
''}
|
||||
${if cfg.forwardX11 then ''
|
||||
ForwardX11 yes
|
||||
'' else ''
|
||||
ForwardX11 no
|
||||
''}
|
||||
ForwardX11 ${if cfg.forwardX11 then "yes" else "no"}
|
||||
'';
|
||||
target = "ssh/ssh_config";
|
||||
}
|
||||
|
@ -10,26 +10,32 @@ let virtualbox = config.boot.kernelPackages.virtualbox; in
|
||||
environment.systemPackages = [ virtualbox ];
|
||||
|
||||
users.extraGroups = singleton { name = "vboxusers"; };
|
||||
|
||||
|
||||
services.udev.extraRules =
|
||||
''
|
||||
KERNEL=="vboxdrv", OWNER="root", GROUP="vboxusers", MODE="0660"
|
||||
KERNEL=="vboxnetctl", OWNER="root", GROUP="root", MODE="0600"
|
||||
KERNEL=="vboxdrv", OWNER="root", GROUP="vboxusers", MODE="0660", TAG+="systemd"
|
||||
KERNEL=="vboxnetctl", OWNER="root", GROUP="root", MODE="0600", TAG+="systemd"
|
||||
'';
|
||||
|
||||
# Since we lack the right setuid binaries, set up a host-only network by default.
|
||||
|
||||
jobs."create-vboxnet0" =
|
||||
{ task = true;
|
||||
|
||||
jobs."vboxnet0" =
|
||||
{ description = "VirtualBox vboxnet0 Interface";
|
||||
requires = [ "dev-vboxnetctl.device" ];
|
||||
after = [ "dev-vboxnetctl.device" ];
|
||||
wantedBy = [ "network.target" "sys-subsystem-net-devices-vboxnet0.device" ];
|
||||
path = [ virtualbox ];
|
||||
startOn = "starting network-interfaces";
|
||||
script =
|
||||
preStart =
|
||||
''
|
||||
if ! [ -e /sys/class/net/vboxnet0 ]; then
|
||||
VBoxManage hostonlyif create
|
||||
fi
|
||||
'';
|
||||
postStop =
|
||||
''
|
||||
VBoxManage hostonlyif remove vboxnet0
|
||||
'';
|
||||
};
|
||||
|
||||
networking.interfaces = [ { name = "vboxnet0"; ipAddress = "192.168.56.1"; subnetMask = "255.255.255.0"; } ];
|
||||
networking.interfaces.vboxnet0 = { ipAddress = "192.168.56.1"; prefixLength = 24; };
|
||||
}
|
||||
|
@ -71,6 +71,11 @@ in zipModules ([]
|
||||
++ rename obsolete "networking.enableWLAN" "networking.wireless.enable"
|
||||
++ rename obsolete "networking.enableRT73Firmware" "networking.enableRalinkFirmware"
|
||||
|
||||
# FIXME: Remove these eventually.
|
||||
++ rename obsolete "boot.systemd.sockets" "systemd.sockets"
|
||||
++ rename obsolete "boot.systemd.targets" "systemd.targets"
|
||||
++ rename obsolete "boot.systemd.services" "systemd.services"
|
||||
|
||||
# Old Grub-related options.
|
||||
++ rename obsolete "boot.copyKernels" "boot.loader.grub.copyKernels"
|
||||
++ rename obsolete "boot.extraGrubEntries" "boot.loader.grub.extraEntries"
|
||||
|
@ -21,7 +21,6 @@ with pkgs.lib;
|
||||
''
|
||||
export OPENSSL_X509_CERT_FILE=/etc/ssl/certs/ca-bundle.crt
|
||||
|
||||
# !!! Remove the following as soon as OpenSSL 1.0.0e is the default.
|
||||
export CURL_CA_BUNDLE=/etc/ssl/certs/ca-bundle.crt
|
||||
export GIT_SSL_CAINFO=/etc/ssl/certs/ca-bundle.crt
|
||||
'';
|
||||
|
@ -1,60 +0,0 @@
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
with pkgs.lib;
|
||||
|
||||
let
|
||||
|
||||
# `pam_console' maintains the set of locally logged in users in
|
||||
# /var/run/console. This is obsolete, but D-Bus still uses it for
|
||||
# its `at_console' feature. So maintain it using a ConsoleKit
|
||||
# session script. Borrowed from
|
||||
# http://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/sys-auth/consolekit/files/pam-foreground-compat.ck
|
||||
updateVarRunConsole = pkgs.writeTextFile {
|
||||
name = "var-run-console.ck";
|
||||
destination = "/etc/ConsoleKit/run-session.d/var-run-console.ck";
|
||||
executable = true;
|
||||
|
||||
text =
|
||||
''
|
||||
#! ${pkgs.stdenv.shell} -e
|
||||
PATH=${pkgs.coreutils}/bin:${pkgs.gnused}/bin:${pkgs.glibc}/bin
|
||||
TAGDIR=/var/run/console
|
||||
|
||||
[ -n "$CK_SESSION_USER_UID" ] || exit 1
|
||||
|
||||
TAGFILE="$TAGDIR/`getent passwd $CK_SESSION_USER_UID | cut -f 1 -d:`"
|
||||
|
||||
if [ "$1" = "session_added" ]; then
|
||||
mkdir -p "$TAGDIR"
|
||||
echo "$CK_SESSION_ID" >> "$TAGFILE"
|
||||
fi
|
||||
|
||||
if [ "$1" = "session_removed" ] && [ -e "$TAGFILE" ]; then
|
||||
sed -i "\%^$CK_SESSION_ID\$%d" "$TAGFILE"
|
||||
[ -s "$TAGFILE" ] || rm -f "$TAGFILE"
|
||||
fi
|
||||
'';
|
||||
};
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
|
||||
config = {
|
||||
|
||||
environment.systemPackages = [ pkgs.consolekit ];
|
||||
|
||||
services.dbus.packages = [ pkgs.consolekit ];
|
||||
|
||||
environment.etc = singleton
|
||||
{ source = (pkgs.buildEnv {
|
||||
name = "consolekit-config";
|
||||
pathsToLink = [ "/etc/ConsoleKit" ];
|
||||
paths = [ pkgs.consolekit pkgs.udev updateVarRunConsole ];
|
||||
}) + "/etc/ConsoleKit";
|
||||
target = "ConsoleKit";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -31,6 +31,8 @@ let
|
||||
concatStringsSep " " [ domain type item value ])
|
||||
limits));
|
||||
|
||||
motd = pkgs.writeText "motd" config.users.motd;
|
||||
|
||||
makePAMService =
|
||||
{ name
|
||||
, # If set, root doesn't need to authenticate (e.g. for the "chsh"
|
||||
@ -43,9 +45,10 @@ let
|
||||
# against the keys in the calling user's ~/.ssh/authorized_keys.
|
||||
# This is useful for "sudo" on password-less remote systems.
|
||||
sshAgentAuth ? false
|
||||
, # If set, use ConsoleKit's PAM connector module to claim
|
||||
# ownership of audio devices etc.
|
||||
ownDevices ? false
|
||||
, # If set, the service will register a new session with systemd's
|
||||
# login manager. If the service is running locally, this will
|
||||
# give the user ownership of audio devices etc.
|
||||
startSession ? false
|
||||
, # Whether to forward XAuth keys between users. Mostly useful
|
||||
# for "su".
|
||||
forwardXAuth ? false
|
||||
@ -59,6 +62,8 @@ let
|
||||
allowNullPassword ? false
|
||||
, # The limits, as per limits.conf(5).
|
||||
limits ? config.security.pam.loginLimits
|
||||
, # Whether to show the message of the day.
|
||||
showMotd ? false
|
||||
}:
|
||||
|
||||
{ source = pkgs.writeText "${name}.pam"
|
||||
@ -77,7 +82,7 @@ let
|
||||
${optionalString rootOK
|
||||
"auth sufficient pam_rootok.so"}
|
||||
${optionalString (config.security.pam.enableSSHAgentAuth && sshAgentAuth)
|
||||
"auth sufficient ${pkgs.pam_ssh_agent_auth}/libexec/pam_ssh_agent_auth.so file=~/.ssh/authorized_keys"}
|
||||
"auth sufficient ${pkgs.pam_ssh_agent_auth}/libexec/pam_ssh_agent_auth.so file=~/.ssh/authorized_keys:~/.ssh/authorized_keys2:/etc/ssh/authorized_keys.d/%u"}
|
||||
${optionalString usbAuth
|
||||
"auth sufficient ${pkgs.pam_usb}/lib/security/pam_usb.so"}
|
||||
auth sufficient pam_unix.so ${optionalString allowNullPassword "nullok"} likeauth
|
||||
@ -105,12 +110,14 @@ let
|
||||
"session optional ${pam_ldap}/lib/security/pam_ldap.so"}
|
||||
${optionalString config.krb5.enable
|
||||
"session optional ${pam_krb5}/lib/security/pam_krb5.so"}
|
||||
${optionalString ownDevices
|
||||
"session optional ${pkgs.consolekit}/lib/security/pam_ck_connector.so"}
|
||||
${optionalString startSession
|
||||
"session optional ${pkgs.systemd}/lib/security/pam_systemd.so"}
|
||||
${optionalString forwardXAuth
|
||||
"session optional pam_xauth.so xauthpath=${pkgs.xorg.xauth}/bin/xauth systemuser=99"}
|
||||
${optionalString (limits != [])
|
||||
"session required ${pkgs.pam}/lib/security/pam_limits.so conf=${makeLimitsConf limits}"}
|
||||
${optionalString (showMotd && config.users.motd != null)
|
||||
"session optional ${pkgs.pam}/lib/security/pam_motd.so motd=${motd}"}
|
||||
'';
|
||||
target = "pam.d/${name}";
|
||||
};
|
||||
@ -152,7 +159,7 @@ in
|
||||
default = [];
|
||||
example = [
|
||||
{ name = "chsh"; rootOK = true; }
|
||||
{ name = "login"; ownDevices = true; allowNullPassword = true;
|
||||
{ name = "login"; startSession = true; allowNullPassword = true;
|
||||
limits = [
|
||||
{ domain = "ftp";
|
||||
type = "hard";
|
||||
@ -173,13 +180,13 @@ in
|
||||
the name of the service. The attribute
|
||||
<varname>rootOK</varname> specifies whether the root user is
|
||||
allowed to use this service without authentication. The
|
||||
attribute <varname>ownDevices</varname> specifies whether
|
||||
ConsoleKit's PAM connector module should be used to give the
|
||||
user ownership of devices such as audio and CD-ROM drives.
|
||||
The attribute <varname>forwardXAuth</varname> specifies
|
||||
whether X authentication keys should be passed from the
|
||||
calling user to the target user (e.g. for
|
||||
<command>su</command>).
|
||||
attribute <varname>startSession</varname> specifies whether
|
||||
systemd's PAM connector module should be used to start a new
|
||||
session; for local sessions, this will give the user
|
||||
ownership of devices such as audio and CD-ROM drives. The
|
||||
attribute <varname>forwardXAuth</varname> specifies whether
|
||||
X authentication keys should be passed from the calling user
|
||||
to the target user (e.g. for <command>su</command>).
|
||||
|
||||
The attribute <varname>limits</varname> defines resource limits
|
||||
that should apply to users or groups for the service. Each item in
|
||||
@ -202,6 +209,13 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
users.motd = mkOption {
|
||||
default = null;
|
||||
example = "Today is Sweetmorn, the 4th day of The Aftermath in the YOLD 3178.";
|
||||
type = types.nullOr types.string;
|
||||
description = "Message of the day shown to users when they log in.";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -238,7 +252,6 @@ in
|
||||
{ name = "lshd"; }
|
||||
{ name = "samba"; }
|
||||
{ name = "screen"; }
|
||||
{ name = "sshd"; }
|
||||
{ name = "vlock"; }
|
||||
{ name = "xlock"; }
|
||||
{ name = "xscreensaver"; }
|
||||
|
@ -1,80 +0,0 @@
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
with pkgs.lib;
|
||||
|
||||
let
|
||||
|
||||
conf = pkgs.writeText "PolicyKit.conf"
|
||||
''
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!DOCTYPE pkconfig PUBLIC "-//freedesktop//DTD PolicyKit Configuration 1.0//EN"
|
||||
"http://hal.freedesktop.org/releases/PolicyKit/1.0/config.dtd">
|
||||
|
||||
<config version="0.1">
|
||||
</config>
|
||||
'';
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
|
||||
options = {
|
||||
|
||||
security.policykit.enable = mkOption {
|
||||
default = false;
|
||||
description = "Enable PolicyKit (obsolete).";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
config = mkIf config.security.policykit.enable {
|
||||
|
||||
environment.systemPackages = [ pkgs.policykit ];
|
||||
|
||||
services.dbus.packages = [ pkgs.policykit ];
|
||||
|
||||
security.pam.services = [ { name = "polkit"; } ];
|
||||
|
||||
users.extraUsers = singleton
|
||||
{ name = "polkituser";
|
||||
uid = config.ids.uids.polkituser;
|
||||
description = "PolicyKit user";
|
||||
};
|
||||
|
||||
users.extraGroups = singleton
|
||||
{ name = "polkituser";
|
||||
gid = config.ids.gids.polkituser;
|
||||
};
|
||||
|
||||
environment.etc =
|
||||
[ { source = conf;
|
||||
target = "PolicyKit/PolicyKit.conf";
|
||||
}
|
||||
{ source = (pkgs.buildEnv {
|
||||
name = "PolicyKit-policies";
|
||||
pathsToLink = [ "/share/PolicyKit/policy" ];
|
||||
paths = [ pkgs.policykit pkgs.consolekit pkgs.hal ];
|
||||
}) + "/share/PolicyKit/policy";
|
||||
target = "PolicyKit/policy";
|
||||
}
|
||||
];
|
||||
|
||||
system.activationScripts.policyKit = stringAfter [ "users" ]
|
||||
''
|
||||
mkdir -m 0770 -p /var/run/PolicyKit
|
||||
chown root:polkituser /var/run/PolicyKit
|
||||
|
||||
mkdir -m 0770 -p /var/lib/PolicyKit
|
||||
chown root:polkituser /var/lib/PolicyKit
|
||||
|
||||
mkdir -p /var/lib/misc
|
||||
touch /var/lib/misc/PolicyKit.reload
|
||||
chmod 0664 /var/lib/misc/PolicyKit.reload
|
||||
chown polkituser:polkituser /var/lib/misc/PolicyKit.reload
|
||||
'';
|
||||
|
||||
};
|
||||
|
||||
}
|
37
modules/security/rngd.nix
Normal file
37
modules/security/rngd.nix
Normal file
@ -0,0 +1,37 @@
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
with pkgs.lib;
|
||||
|
||||
{
|
||||
options = {
|
||||
security.rngd.enable = mkOption {
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to enable the rng daemon, which adds entropy from
|
||||
hardware sources of randomness to the kernel entropy pool when
|
||||
available.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf config.security.rngd.enable {
|
||||
services.udev.extraRules = ''
|
||||
KERNEL=="random", TAG+="systemd"
|
||||
SUBSYSTEM=="cpu", ENV{MODALIAS}=="x86cpu:*feature:*009E*", TAG+="systemd", ENV{SYSTEMD_WANTS}+="rngd.service"
|
||||
KERNEL=="hw_random", TAG+="systemd", ENV{SYSTEMD_WANTS}+="rngd.service"
|
||||
KERNEL=="tmp0", TAG+="systemd", ENV{SYSTEMD_WANTS}+="rngd.service"
|
||||
'';
|
||||
|
||||
systemd.services.rngd = {
|
||||
bindsTo = [ "dev-random.device" ];
|
||||
|
||||
after = [ "dev-random.device" ];
|
||||
|
||||
description = "Hardware RNG Entropy Gatherer Daemon";
|
||||
|
||||
serviceConfig.ExecStart = "${pkgs.rng_tools}/sbin/rngd -f";
|
||||
|
||||
restartTriggers = [ pkgs.rng_tools ];
|
||||
};
|
||||
};
|
||||
}
|
@ -37,25 +37,6 @@ in
|
||||
security.sudo.configFile = mkOption {
|
||||
# Note: if syntax errors are detected in this file, the NixOS
|
||||
# configuration will fail to build.
|
||||
default =
|
||||
''
|
||||
# Don't edit this file. Set the NixOS option ‘security.sudo.configFile’ instead.
|
||||
|
||||
# Environment variables to keep for root and %wheel.
|
||||
Defaults:root,%wheel env_keep+=LOCALE_ARCHIVE
|
||||
Defaults:root,%wheel env_keep+=NIX_CONF_DIR
|
||||
Defaults:root,%wheel env_keep+=NIX_PATH
|
||||
Defaults:root,%wheel env_keep+=TERMINFO_DIRS
|
||||
|
||||
# Keep SSH_AUTH_SOCK so that pam_ssh_agent_auth.so can do its magic.
|
||||
Defaults env_keep+=SSH_AUTH_SOCK
|
||||
|
||||
# "root" is allowed to do anything.
|
||||
root ALL=(ALL) SETENV: ALL
|
||||
|
||||
# Users in the "wheel" group can do anything.
|
||||
%wheel ALL=(ALL) ${if cfg.wheelNeedsPassword then "" else "NOPASSWD: ALL, "}SETENV: ALL
|
||||
'';
|
||||
description =
|
||||
''
|
||||
This string contains the contents of the
|
||||
@ -69,6 +50,26 @@ in
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
security.sudo.configFile =
|
||||
''
|
||||
# Don't edit this file. Set the NixOS option ‘security.sudo.configFile’ instead.
|
||||
|
||||
# Environment variables to keep for root and %wheel.
|
||||
Defaults:root,%wheel env_keep+=LOCALE_ARCHIVE
|
||||
Defaults:root,%wheel env_keep+=NIX_CONF_DIR
|
||||
Defaults:root,%wheel env_keep+=NIX_PATH
|
||||
Defaults:root,%wheel env_keep+=TERMINFO_DIRS
|
||||
|
||||
# Keep SSH_AUTH_SOCK so that pam_ssh_agent_auth.so can do its magic.
|
||||
Defaults env_keep+=SSH_AUTH_SOCK
|
||||
|
||||
# "root" is allowed to do anything.
|
||||
root ALL=(ALL) SETENV: ALL
|
||||
|
||||
# Users in the "wheel" group can do anything.
|
||||
%wheel ALL=(ALL) ${if cfg.wheelNeedsPassword then "" else "NOPASSWD: ALL, "}SETENV: ALL
|
||||
'';
|
||||
|
||||
security.setuidPrograms = [ "sudo" ];
|
||||
|
||||
environment.systemPackages = [ sudo ];
|
||||
|
@ -29,9 +29,9 @@ in
|
||||
|
||||
enableOSSEmulation = mkOption {
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to enable ALSA OSS emulation (with certain cards sound mixing may not work!).
|
||||
'';
|
||||
description = ''
|
||||
Whether to enable ALSA OSS emulation (with certain cards sound mixing may not work!).
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
@ -45,25 +45,18 @@ in
|
||||
|
||||
environment.systemPackages = [ alsaUtils ];
|
||||
|
||||
# ALSA provides a udev rule for restoring volume settings.
|
||||
services.udev.packages = [ alsaUtils ];
|
||||
|
||||
boot.kernelModules = optional config.sound.enableOSSEmulation "snd_pcm_oss";
|
||||
|
||||
jobs.alsa =
|
||||
{ startOn = "stopped udevtrigger";
|
||||
|
||||
preStart =
|
||||
''
|
||||
mkdir -m 0755 -p $(dirname ${soundState})
|
||||
|
||||
# Try to restore the sound state.
|
||||
${alsaUtils}/sbin/alsactl --ignore init || true
|
||||
${alsaUtils}/sbin/alsactl --ignore -f ${soundState} restore || true
|
||||
'';
|
||||
|
||||
postStop =
|
||||
''
|
||||
# Save the sound state.
|
||||
${alsaUtils}/sbin/alsactl --ignore -f ${soundState} store
|
||||
'';
|
||||
systemd.services."alsa-store" =
|
||||
{ description = "Store Sound Card State";
|
||||
wantedBy = [ "shutdown.target" ];
|
||||
before = [ "shutdown.target" ];
|
||||
unitConfig.DefaultDependencies = "no";
|
||||
serviceConfig.Type = "oneshot";
|
||||
serviceConfig.ExecStart = "${alsaUtils}/sbin/alsactl store --ignore";
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -97,17 +97,16 @@ in
|
||||
|
||||
users.extraUsers = singleton
|
||||
{ name = cfg.user;
|
||||
shell = "/bin/sh";
|
||||
description = "MongoDB server user";
|
||||
};
|
||||
|
||||
environment.systemPackages = [mongodb];
|
||||
environment.systemPackages = [ mongodb ];
|
||||
|
||||
jobs.mongodb =
|
||||
systemd.services.mongodb =
|
||||
{ description = "MongoDB server";
|
||||
daemonType = "daemon";
|
||||
|
||||
startOn = "filesystem";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
|
||||
preStart =
|
||||
''
|
||||
@ -117,11 +116,10 @@ in
|
||||
fi
|
||||
'';
|
||||
|
||||
path = [mongodb];
|
||||
exec = "mongod --config ${mongoCnf} --fork";
|
||||
setuid = cfg.user;
|
||||
|
||||
extraConfig = "kill timeout 10";
|
||||
serviceConfig = {
|
||||
ExecStart = "${mongodb}/bin/mongod --quiet --config ${mongoCnf}";
|
||||
User = cfg.user;
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -91,6 +91,7 @@ in
|
||||
description = "A file containing SQL statements to be executed on the first startup. Can be used for granting certain permissions on the database";
|
||||
};
|
||||
|
||||
# FIXME: remove this option; it's a really bad idea.
|
||||
rootPassword = mkOption {
|
||||
default = null;
|
||||
description = "Path to a file containing the root password, modified on the first startup. Not specifying a root password will leave the root password empty.";
|
||||
@ -140,10 +141,12 @@ in
|
||||
|
||||
environment.systemPackages = [mysql];
|
||||
|
||||
jobs.mysql =
|
||||
{ description = "MySQL server";
|
||||
systemd.services.mysql =
|
||||
{ description = "MySQL Server";
|
||||
|
||||
startOn = "filesystem";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
unitConfig.RequiresMountsFor = "${cfg.dataDir}";
|
||||
|
||||
preStart =
|
||||
''
|
||||
@ -156,9 +159,12 @@ in
|
||||
|
||||
mkdir -m 0700 -p ${cfg.pidDir}
|
||||
chown -R ${cfg.user} ${cfg.pidDir}
|
||||
|
||||
${mysql}/libexec/mysqld --defaults-extra-file=${myCnf} ${mysqldOptions} &
|
||||
'';
|
||||
|
||||
serviceConfig.ExecStart = "${mysql}/libexec/mysqld --defaults-extra-file=${myCnf} ${mysqldOptions}";
|
||||
|
||||
postStart =
|
||||
''
|
||||
# Wait until the MySQL server is available for use
|
||||
count=0
|
||||
while [ ! -e /tmp/mysql.sock ]
|
||||
@ -183,7 +189,7 @@ in
|
||||
echo "Creating initial database: ${database.name}"
|
||||
( echo "create database ${database.name};"
|
||||
echo "use ${database.name};"
|
||||
|
||||
|
||||
if [ -f "${database.schema}" ]
|
||||
then
|
||||
cat ${database.schema}
|
||||
@ -204,7 +210,7 @@ in
|
||||
${optionalString (cfg.rootPassword != null)
|
||||
''
|
||||
# Change root password
|
||||
|
||||
|
||||
( echo "use mysql;"
|
||||
echo "update user set Password=password('$(cat ${cfg.rootPassword})') where User='root';"
|
||||
echo "flush privileges;"
|
||||
@ -213,14 +219,10 @@ in
|
||||
|
||||
rm /tmp/mysql_init
|
||||
fi
|
||||
'';
|
||||
''; # */
|
||||
|
||||
postStop = "${mysql}/bin/mysqladmin ${optionalString (cfg.rootPassword != null) "--user=root --password=\"$(cat ${cfg.rootPassword})\""} shutdown";
|
||||
|
||||
# !!! Need a postStart script to wait until mysqld is ready to
|
||||
# accept connections.
|
||||
|
||||
extraConfig = "kill timeout 60";
|
||||
serviceConfig.ExecStop =
|
||||
"${mysql}/bin/mysqladmin ${optionalString (cfg.rootPassword != null) "--user=root --password=\"$(cat ${cfg.rootPassword})\""} shutdown";
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -84,6 +84,7 @@ in
|
||||
description = "A file containing SQL statements to be executed on the first startup. Can be used for granting certain permissions on the database";
|
||||
};
|
||||
|
||||
# FIXME: remove this option; it's a really bad idea.
|
||||
rootPassword = mkOption {
|
||||
default = null;
|
||||
description = "Path to a file containing the root password, modified on the first startup. Not specifying a root password will leave the root password empty.";
|
||||
@ -133,10 +134,12 @@ in
|
||||
|
||||
environment.systemPackages = [mysql];
|
||||
|
||||
jobs.mysql =
|
||||
{ description = "MySQL server";
|
||||
systemd.services.mysql =
|
||||
{ description = "MySQL Server";
|
||||
|
||||
startOn = "filesystem";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
unitConfig.RequiresMountsFor = "${cfg.dataDir}";
|
||||
|
||||
preStart =
|
||||
''
|
||||
@ -149,9 +152,12 @@ in
|
||||
|
||||
mkdir -m 0700 -p ${cfg.pidDir}
|
||||
chown -R ${cfg.user} ${cfg.pidDir}
|
||||
|
||||
${mysql}/bin/mysqld --defaults-extra-file=${myCnf} ${mysqldOptions} &
|
||||
'';
|
||||
|
||||
serviceConfig.ExecStart = "${mysql}/bin/mysqld --defaults-extra-file=${myCnf} ${mysqldOptions}";
|
||||
|
||||
postStart =
|
||||
''
|
||||
# Wait until the MySQL server is available for use
|
||||
count=0
|
||||
while [ ! -e /tmp/mysql.sock ]
|
||||
@ -176,7 +182,7 @@ in
|
||||
echo "Creating initial database: ${database.name}"
|
||||
( echo "create database ${database.name};"
|
||||
echo "use ${database.name};"
|
||||
|
||||
|
||||
if [ -f "${database.schema}" ]
|
||||
then
|
||||
cat ${database.schema}
|
||||
@ -207,7 +213,7 @@ in
|
||||
${optionalString (cfg.rootPassword != null)
|
||||
''
|
||||
# Change root password
|
||||
|
||||
|
||||
( echo "use mysql;"
|
||||
echo "update user set Password=password('$(cat ${cfg.rootPassword})') where User='root';"
|
||||
echo "flush privileges;"
|
||||
@ -216,14 +222,10 @@ in
|
||||
|
||||
rm /tmp/mysql_init
|
||||
fi
|
||||
'';
|
||||
''; # */
|
||||
|
||||
postStop = "${mysql}/bin/mysqladmin ${optionalString (cfg.rootPassword != null) "--user=root --password=\"$(cat ${cfg.rootPassword})\""} shutdown";
|
||||
|
||||
# !!! Need a postStart script to wait until mysqld is ready to
|
||||
# accept connections.
|
||||
|
||||
extraConfig = "kill timeout 60";
|
||||
serviceConfig.ExecStop =
|
||||
"${mysql}/bin/mysqladmin ${optionalString (cfg.rootPassword != null) "--user=root --password=\"$(cat ${cfg.rootPassword})\""} shutdown";
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -22,8 +22,6 @@ let
|
||||
|
||||
postgresql = postgresqlAndPlugins cfg.package;
|
||||
|
||||
run = "su -s ${pkgs.stdenv.shell} postgres";
|
||||
|
||||
flags = optional cfg.enableTCPIP "-i";
|
||||
|
||||
# The main PostgreSQL configuration file.
|
||||
@ -36,7 +34,7 @@ let
|
||||
'';
|
||||
|
||||
pre84 = versionOlder (builtins.parseDrvName postgresql.name).version "8.4";
|
||||
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
@ -146,7 +144,7 @@ in
|
||||
host all all 127.0.0.1/32 md5
|
||||
host all all ::1/128 md5
|
||||
'';
|
||||
|
||||
|
||||
users.extraUsers = singleton
|
||||
{ name = "postgres";
|
||||
description = "PostgreSQL server user";
|
||||
@ -157,10 +155,11 @@ in
|
||||
|
||||
environment.systemPackages = [postgresql];
|
||||
|
||||
jobs.postgresql =
|
||||
{ description = "PostgreSQL server";
|
||||
systemd.services.postgresql =
|
||||
{ description = "PostgreSQL Server";
|
||||
|
||||
startOn = "started network-interfaces and filesystem";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
|
||||
environment =
|
||||
{ TZ = config.time.timeZone;
|
||||
@ -175,34 +174,38 @@ in
|
||||
if ! test -e ${cfg.dataDir}; then
|
||||
mkdir -m 0700 -p ${cfg.dataDir}
|
||||
chown -R postgres ${cfg.dataDir}
|
||||
${run} -c 'initdb -U root'
|
||||
su -s ${pkgs.stdenv.shell} postgres -c 'initdb -U root'
|
||||
rm -f ${cfg.dataDir}/*.conf
|
||||
fi
|
||||
|
||||
ln -sfn ${configFile} ${cfg.dataDir}/postgresql.conf
|
||||
''; # */
|
||||
|
||||
exec = "${run} -c 'postgres ${toString flags}'";
|
||||
serviceConfig =
|
||||
{ ExecStart = "@${postgresql}/bin/postgres postgres ${toString flags}";
|
||||
User = "postgres";
|
||||
Group = "postgres";
|
||||
PermissionsStartOnly = true;
|
||||
|
||||
# Shut down Postgres using SIGINT ("Fast Shutdown mode"). See
|
||||
# http://www.postgresql.org/docs/current/static/server-shutdown.html
|
||||
KillSignal = "SIGINT";
|
||||
|
||||
# Give Postgres a decent amount of time to clean up after
|
||||
# receiving systemd's SIGINT.
|
||||
TimeoutSec = 60;
|
||||
};
|
||||
|
||||
# Wait for PostgreSQL to be ready to accept connections.
|
||||
postStart =
|
||||
''
|
||||
while ! psql postgres -c ""; do
|
||||
stop_check
|
||||
sleep 1
|
||||
while ! psql postgres -c "" 2> /dev/null; do
|
||||
if ! kill -0 "$MAINPID"; then exit 1; fi
|
||||
sleep 0.1
|
||||
done
|
||||
'';
|
||||
|
||||
extraConfig =
|
||||
''
|
||||
# Shut down Postgres using SIGINT ("Fast Shutdown mode"). See
|
||||
# http://www.postgresql.org/docs/current/static/server-shutdown.html
|
||||
kill signal INT
|
||||
|
||||
# Give Postgres a decent amount of time to clean up after
|
||||
# receiving Upstart's SIGINT.
|
||||
kill timeout 60
|
||||
'';
|
||||
unitConfig.RequiresMountsFor = "${cfg.dataDir}";
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -95,15 +95,18 @@ in
|
||||
config = mkIf config.services.acpid.enable {
|
||||
|
||||
jobs.acpid =
|
||||
{ description = "ACPI daemon";
|
||||
{ description = "ACPI Daemon";
|
||||
|
||||
startOn = "stopped udevtrigger and started syslogd";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "systemd-udev-settle.service" ];
|
||||
|
||||
path = [ pkgs.acpid ];
|
||||
|
||||
daemonType = "fork";
|
||||
|
||||
exec = "acpid --confdir ${acpiConfDir}";
|
||||
|
||||
unitConfig.ConditionPathExists = [ "/proc/acpi" ];
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -1,117 +0,0 @@
|
||||
# HAL daemon.
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
with pkgs.lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.hal;
|
||||
|
||||
inherit (pkgs) hal;
|
||||
|
||||
fdi = pkgs.buildEnv {
|
||||
name = "hal-fdi";
|
||||
pathsToLink = [ "/share/hal/fdi" ];
|
||||
paths = cfg.packages;
|
||||
};
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
|
||||
###### interface
|
||||
|
||||
options = {
|
||||
|
||||
services.hal = {
|
||||
|
||||
enable = mkOption {
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to start the HAL daemon.
|
||||
'';
|
||||
};
|
||||
|
||||
packages = mkOption {
|
||||
default = [];
|
||||
description = ''
|
||||
Packages containing additional HAL configuration data.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
environment.systemPackages = [ hal ];
|
||||
|
||||
services.hal.packages = [ hal pkgs.hal_info ];
|
||||
|
||||
security.policykit.enable = true;
|
||||
|
||||
users.extraUsers = singleton
|
||||
{ name = "haldaemon";
|
||||
uid = config.ids.uids.haldaemon;
|
||||
description = "HAL daemon user";
|
||||
};
|
||||
|
||||
users.extraGroups = singleton
|
||||
{ name = "haldaemon";
|
||||
gid = config.ids.gids.haldaemon;
|
||||
};
|
||||
|
||||
jobs.hal =
|
||||
{ description = "HAL daemon";
|
||||
|
||||
startOn = "started dbus" + optionalString config.services.acpid.enable " and started acpid";
|
||||
|
||||
environment =
|
||||
{ # !!! HACK? These environment variables manipulated inside
|
||||
# 'src'/hald/mmap_cache.c are used for testing the daemon.
|
||||
HAL_FDI_SOURCE_PREPROBE = "${fdi}/share/hal/fdi/preprobe";
|
||||
HAL_FDI_SOURCE_INFORMATION = "${fdi}/share/hal/fdi/information";
|
||||
HAL_FDI_SOURCE_POLICY = "${fdi}/share/hal/fdi/policy";
|
||||
|
||||
# Stuff needed by the shell scripts run by HAL (in particular pm-utils).
|
||||
HALD_RUNNER_PATH = concatStringsSep ":"
|
||||
[ "${pkgs.coreutils}/bin"
|
||||
"${pkgs.gnugrep}/bin"
|
||||
"${pkgs.dbus_tools}/bin"
|
||||
"${pkgs.procps}/bin"
|
||||
"${pkgs.procps}/sbin"
|
||||
"${config.system.sbin.modprobe}/sbin"
|
||||
"${pkgs.module_init_tools}/bin"
|
||||
"${pkgs.module_init_tools}/sbin"
|
||||
"${pkgs.kbd}/bin"
|
||||
];
|
||||
};
|
||||
|
||||
preStart =
|
||||
''
|
||||
mkdir -m 0755 -p /var/cache/hald
|
||||
mkdir -m 0755 -p /var/run/hald
|
||||
|
||||
rm -f /var/cache/hald/fdi-cache
|
||||
'';
|
||||
|
||||
daemonType = "fork";
|
||||
|
||||
# The `PATH=' works around a bug in HAL: it concatenates
|
||||
# its libexec directory to $PATH, but using a 512-byte
|
||||
# buffer. So if $PATH is too long it fails.
|
||||
script = "PATH= exec ${hal}/sbin/hald --use-syslog";
|
||||
};
|
||||
|
||||
services.udev.packages = [hal];
|
||||
|
||||
services.dbus.enable = true;
|
||||
services.dbus.packages = [hal];
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -4,7 +4,9 @@ with pkgs.lib;
|
||||
|
||||
let
|
||||
|
||||
inherit (pkgs) stdenv writeText udev procps;
|
||||
inherit (pkgs) stdenv writeText procps;
|
||||
|
||||
udev = config.systemd.package;
|
||||
|
||||
cfg = config.services.udev;
|
||||
|
||||
@ -24,20 +26,16 @@ let
|
||||
udevRules = stdenv.mkDerivation {
|
||||
name = "udev-rules";
|
||||
buildCommand = ''
|
||||
ensureDir $out
|
||||
mkdir -p $out
|
||||
shopt -s nullglob
|
||||
|
||||
# Set a reasonable $PATH for programs called by udev rules.
|
||||
echo 'ENV{PATH}="${udevPath}/bin:${udevPath}/sbin"' > $out/00-path.rules
|
||||
|
||||
# Set the firmware search path so that the firmware.sh helper
|
||||
# called by 50-firmware.rules works properly.
|
||||
echo 'ENV{FIRMWARE_DIRS}="/root/test-firmware ${toString config.hardware.firmware}"' >> $out/00-path.rules
|
||||
|
||||
# Add the udev rules from other packages.
|
||||
for i in ${toString cfg.packages}; do
|
||||
echo "Adding rules for package $i"
|
||||
for j in $i/*/udev/rules.d/*; do
|
||||
for j in $i/{etc,lib}/udev/rules.d/*; do
|
||||
echo "Copying $j to $out/$(basename $j)"
|
||||
echo "# Copied from $j" > $out/$(basename $j)
|
||||
cat $j >> $out/$(basename $j)
|
||||
@ -53,12 +51,7 @@ let
|
||||
--replace \"/bin/mount \"${pkgs.utillinux}/bin/mount
|
||||
done
|
||||
|
||||
# If auto-configuration is disabled, then remove
|
||||
# udev's 80-drivers.rules file, which contains rules for
|
||||
# automatically calling modprobe.
|
||||
${if !config.boot.hardwareScan then "rm $out/80-drivers.rules" else ""}
|
||||
|
||||
echo -n "Checking that all programs called by relative paths in udev rules exist in ${udev}/lib/udev ... "
|
||||
echo -n "Checking that all programs called by relative paths in udev rules exist in ${udev}/lib/udev... "
|
||||
import_progs=$(grep 'IMPORT{program}="[^/$]' $out/* |
|
||||
sed -e 's/.*IMPORT{program}="\([^ "]*\)[ "].*/\1/' | uniq)
|
||||
run_progs=$(grep -v '^[[:space:]]*#' $out/* | grep 'RUN+="[^/$]' |
|
||||
@ -72,7 +65,7 @@ let
|
||||
done
|
||||
echo "OK"
|
||||
|
||||
echo -n "Checking that all programs call by absolute paths in udev rules exist ... "
|
||||
echo -n "Checking that all programs called by absolute paths in udev rules exist... "
|
||||
import_progs=$(grep 'IMPORT{program}="\/' $out/* |
|
||||
sed -e 's/.*IMPORT{program}="\([^ "]*\)[ "].*/\1/' | uniq)
|
||||
run_progs=$(grep -v '^[[:space:]]*#' $out/* | grep 'RUN+="/' |
|
||||
@ -90,24 +83,9 @@ let
|
||||
for i in ${toString cfg.packages}; do
|
||||
grep -l '\(RUN+\|IMPORT{program}\)="\(/usr\)\?/s\?bin' $i/*/udev/rules.d/* || true
|
||||
done
|
||||
|
||||
# Use the persistent device rules (naming for CD/DVD and
|
||||
# network devices) stored in
|
||||
# /var/lib/udev/rules.d/70-persistent-{cd,net}.rules. These are
|
||||
# modified by the write_{cd,net}_rules helpers called from
|
||||
# 75-cd-aliases-generator.rules and
|
||||
# 75-persistent-net-generator.rules.
|
||||
ln -sv /var/lib/udev/rules.d/70-persistent-cd.rules $out/
|
||||
ln -sv /var/lib/udev/rules.d/70-persistent-net.rules $out/
|
||||
''; # */
|
||||
};
|
||||
|
||||
# The udev configuration file.
|
||||
conf = writeText "udev.conf" ''
|
||||
udev_rules="${udevRules}"
|
||||
#udev_log="debug"
|
||||
'';
|
||||
|
||||
# Udev has a 512-character limit for ENV{PATH}, so create a symlink
|
||||
# tree to work around this.
|
||||
udevPath = pkgs.buildEnv {
|
||||
@ -207,61 +185,15 @@ in
|
||||
|
||||
services.udev.extraRules = nixosRules;
|
||||
|
||||
services.udev.packages = [ pkgs.udev extraUdevRules ];
|
||||
services.udev.packages = [ extraUdevRules ];
|
||||
|
||||
services.udev.path = [ pkgs.coreutils pkgs.gnused pkgs.gnugrep pkgs.utillinux pkgs.udev ];
|
||||
services.udev.path = [ pkgs.coreutils pkgs.gnused pkgs.gnugrep pkgs.utillinux udev ];
|
||||
|
||||
jobs.udev =
|
||||
{ startOn = "startup";
|
||||
|
||||
environment = { UDEV_CONFIG_FILE = conf; };
|
||||
|
||||
path = [ udev ];
|
||||
|
||||
preStart =
|
||||
''
|
||||
echo "" > /proc/sys/kernel/hotplug || true
|
||||
|
||||
mkdir -p /var/lib/udev/rules.d
|
||||
touch /var/lib/udev/rules.d/70-persistent-cd.rules /var/lib/udev/rules.d/70-persistent-net.rules
|
||||
|
||||
mkdir -p /dev/.udev # !!! bug in udev?
|
||||
'';
|
||||
|
||||
daemonType = "fork";
|
||||
|
||||
exec = "udevd --daemon";
|
||||
|
||||
postStart =
|
||||
''
|
||||
# Do the loading of additional stage 2 kernel modules.
|
||||
# This needs to be done while udevd is running, because
|
||||
# the modules may call upon udev's firmware loading rule.
|
||||
for i in ${toString config.boot.kernelModules}; do
|
||||
echo "loading kernel module ‘$i’..."
|
||||
${config.system.sbin.modprobe}/sbin/modprobe $i || true
|
||||
done
|
||||
'';
|
||||
};
|
||||
|
||||
jobs.udevtrigger =
|
||||
{ startOn = "started udev";
|
||||
|
||||
task = true;
|
||||
|
||||
path = [ udev ];
|
||||
|
||||
script =
|
||||
''
|
||||
# Let udev create device nodes for all modules that have already
|
||||
# been loaded into the kernel (or for which support is built into
|
||||
# the kernel).
|
||||
udevadm trigger --action=add
|
||||
udevadm settle || true # wait for udev to finish
|
||||
|
||||
initctl emit -n new-devices
|
||||
'';
|
||||
};
|
||||
environment.etc =
|
||||
[ { source = udevRules;
|
||||
target = "udev/rules.d";
|
||||
}
|
||||
];
|
||||
|
||||
system.requiredKernelConfig = with config.lib.kernelConfig; [
|
||||
(isEnabled "UNIX")
|
||||
|
@ -35,11 +35,30 @@ with pkgs.lib;
|
||||
|
||||
services.udev.packages = [ pkgs.upower ];
|
||||
|
||||
systemd.services.upower =
|
||||
{ description = "Power Management Daemon";
|
||||
path = [ pkgs.glib ]; # needed for gdbus
|
||||
serviceConfig =
|
||||
{ Type = "dbus";
|
||||
BusName = "org.freedesktop.UPower";
|
||||
ExecStart = "@${pkgs.upower}/libexec/upowerd upowerd";
|
||||
};
|
||||
};
|
||||
|
||||
system.activationScripts.upower =
|
||||
''
|
||||
mkdir -m 0755 -p /var/lib/upower
|
||||
'';
|
||||
|
||||
# The upower daemon seems to get stuck after doing a suspend
|
||||
# (i.e. subsequent suspend requests will say "Sleep has already
|
||||
# been requested and is pending"). So as a workaround, restart
|
||||
# the daemon.
|
||||
powerManagement.resumeCommands =
|
||||
''
|
||||
${config.systemd.package}/bin/systemctl try-restart upower
|
||||
'';
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1,19 +1,42 @@
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
###### implementation
|
||||
with pkgs.lib;
|
||||
|
||||
{
|
||||
###### interface
|
||||
|
||||
jobs.klogd =
|
||||
{ description = "Kernel log daemon";
|
||||
options = {
|
||||
|
||||
startOn = "started syslogd";
|
||||
|
||||
path = [ pkgs.sysklogd ];
|
||||
|
||||
exec =
|
||||
"klogd -c 1 -2 -n " +
|
||||
"-k $(dirname $(readlink -f /run/booted-system/kernel))/System.map";
|
||||
services.klogd.enable = mkOption {
|
||||
type = types.bool;
|
||||
default = versionOlder (getVersion config.boot.kernelPackages.kernel) "3.5";
|
||||
description = ''
|
||||
Whether to enable klogd, the kernel log message processing
|
||||
daemon. Since systemd handles logging of kernel messages on
|
||||
Linux 3.5 and later, this is only useful if you're running an
|
||||
older kernel.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf config.services.klogd.enable {
|
||||
|
||||
jobs.klogd =
|
||||
{ description = "Kernel Log Daemon";
|
||||
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
path = [ pkgs.sysklogd ];
|
||||
|
||||
exec =
|
||||
"klogd -c 1 -2 -n " +
|
||||
"-k $(dirname $(readlink -f /run/booted-system/kernel))/System.map";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -136,12 +136,11 @@ in
|
||||
mkNameValuePairs = mergeConfigs;
|
||||
};
|
||||
} ( mkIf cfg.enable {
|
||||
# Always log to stdout
|
||||
services.logstash.outputConfig = { stdout = {}; };
|
||||
|
||||
jobs.logstash = with pkgs; {
|
||||
systemd.services.logstash = with pkgs; {
|
||||
description = "Logstash daemon";
|
||||
startOn = "started networking and filesystem";
|
||||
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
environment.TZ = config.time.timeZone;
|
||||
|
||||
path = [ jre ];
|
||||
|
||||
@ -157,7 +156,7 @@ in
|
||||
output {
|
||||
${exprToConfig cfg.outputConfig}
|
||||
}
|
||||
''}";
|
||||
''} &> /var/log/logstash.log";
|
||||
};
|
||||
})];
|
||||
}
|
||||
|
@ -36,6 +36,15 @@ in
|
||||
|
||||
services.syslogd = {
|
||||
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to enable syslogd. Note that systemd also logs
|
||||
syslog messages, so you normally don't need to run syslogd.
|
||||
'';
|
||||
};
|
||||
|
||||
tty = mkOption {
|
||||
type = types.uniq types.string;
|
||||
default = "tty10";
|
||||
@ -89,22 +98,27 @@ in
|
||||
|
||||
###### implementation
|
||||
|
||||
config = {
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
environment.systemPackages = [ pkgs.sysklogd ];
|
||||
|
||||
services.syslogd.extraParams = optional cfg.enableNetworkInput "-r";
|
||||
|
||||
jobs.syslogd =
|
||||
{ description = "Syslog daemon";
|
||||
# FIXME: restarting syslog seems to break journal logging.
|
||||
systemd.services.syslog =
|
||||
{ description = "Syslog Daemon";
|
||||
|
||||
startOn = "started udev";
|
||||
requires = [ "syslog.socket" ];
|
||||
|
||||
environment = { TZ = config.time.timeZone; };
|
||||
wantedBy = [ "multi-user.target" "syslog.target" ];
|
||||
|
||||
daemonType = "fork";
|
||||
environment.TZ = config.time.timeZone;
|
||||
|
||||
path = [ pkgs.sysklogd ];
|
||||
|
||||
exec = "syslogd ${toString cfg.extraParams} -f ${syslogConf}";
|
||||
serviceConfig =
|
||||
{ ExecStart = "${pkgs.sysklogd}/sbin/syslogd ${toString cfg.extraParams} -f ${syslogConf} -n";
|
||||
# Prevent syslogd output looping back through journald.
|
||||
StandardOutput = "null";
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -364,22 +364,13 @@ in
|
||||
# accurate way is unlikely to be better.
|
||||
{ description = "Postfix mail server";
|
||||
|
||||
startOn = "started networking and filesystem";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
|
||||
daemonType = "none";
|
||||
|
||||
respawn = true;
|
||||
daemonType = "fork";
|
||||
|
||||
environment.TZ = config.time.timeZone;
|
||||
|
||||
script = ''
|
||||
while ${pkgs.procps}/bin/ps `${pkgs.coreutils}/bin/cat /var/postfix/queue/pid/master.pid` |
|
||||
grep -q postfix
|
||||
do
|
||||
${pkgs.coreutils}/bin/sleep 1m
|
||||
done
|
||||
'';
|
||||
|
||||
preStart =
|
||||
''
|
||||
if ! [ -d /var/spool/postfix ]; then
|
||||
@ -402,11 +393,11 @@ in
|
||||
${pkgs.postfix}/sbin/postalias -c /var/postfix/conf /var/postfix/conf/aliases
|
||||
${pkgs.postfix}/sbin/postmap -c /var/postfix/conf /var/postfix/conf/virtual
|
||||
|
||||
exec ${pkgs.postfix}/sbin/postfix -c /var/postfix/conf start
|
||||
${pkgs.postfix}/sbin/postfix -c /var/postfix/conf start
|
||||
'';
|
||||
|
||||
preStop = ''
|
||||
exec ${pkgs.postfix}/sbin/postfix -c /var/postfix/conf stop
|
||||
${pkgs.postfix}/sbin/postfix -c /var/postfix/conf stop
|
||||
'';
|
||||
|
||||
};
|
||||
|
@ -4,6 +4,8 @@ with pkgs.lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.nix;
|
||||
|
||||
inherit (config.environment) nix;
|
||||
|
||||
makeNixBuildUser = nr:
|
||||
@ -74,9 +76,7 @@ in
|
||||
gc-keep-outputs = true
|
||||
gc-keep-derivations = true
|
||||
";
|
||||
description = "
|
||||
This option allows to append lines to nix.conf.
|
||||
";
|
||||
description = "Additional text appended to <filename>nix.conf</filename>.";
|
||||
};
|
||||
|
||||
distributedBuilds = mkOption {
|
||||
@ -169,11 +169,9 @@ in
|
||||
# actually a shell script.
|
||||
envVars = mkOption {
|
||||
internal = true;
|
||||
default = "";
|
||||
type = types.string;
|
||||
description = "
|
||||
Environment variables used by Nix.
|
||||
";
|
||||
default = {};
|
||||
type = types.attrs;
|
||||
description = "Environment variables used by Nix.";
|
||||
};
|
||||
|
||||
nrBuildUsers = mkOption {
|
||||
@ -186,6 +184,16 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
readOnlyStore = mkOption {
|
||||
default = false;
|
||||
description = ''
|
||||
If set, NixOS will enforce the immutability of the Nix store
|
||||
by making <filename>/nix/store</filename> a read-only bind
|
||||
mount. Nix will automatically make the store writable when
|
||||
needed.
|
||||
'';
|
||||
};
|
||||
|
||||
binaryCaches = mkOption {
|
||||
default = [ http://nixos.org/binary-cache ];
|
||||
type = types.list types.string;
|
||||
@ -231,16 +239,16 @@ in
|
||||
# /bin/sh won't work.
|
||||
binshDeps = pkgs.writeReferencesToFile config.system.build.binsh;
|
||||
in
|
||||
pkgs.runCommand "nix.conf" {extraOptions = config.nix.extraOptions; } ''
|
||||
pkgs.runCommand "nix.conf" {extraOptions = cfg.extraOptions; } ''
|
||||
extraPaths=$(for i in $(cat ${binshDeps}); do if test -d $i; then echo $i; fi; done)
|
||||
cat > $out <<END
|
||||
# WARNING: this file is generated.
|
||||
build-users-group = nixbld
|
||||
build-max-jobs = ${toString (config.nix.maxJobs)}
|
||||
build-use-chroot = ${if config.nix.useChroot then "true" else "false"}
|
||||
build-chroot-dirs = ${toString config.nix.chrootDirs} $(echo $extraPaths)
|
||||
binary-caches = ${toString config.nix.binaryCaches}
|
||||
trusted-binary-caches = ${toString config.nix.trustedBinaryCaches}
|
||||
build-max-jobs = ${toString (cfg.maxJobs)}
|
||||
build-use-chroot = ${if cfg.useChroot then "true" else "false"}
|
||||
build-chroot-dirs = ${toString cfg.chrootDirs} $(echo $extraPaths)
|
||||
binary-caches = ${toString cfg.binaryCaches}
|
||||
trusted-binary-caches = ${toString cfg.trustedBinaryCaches}
|
||||
$extraOptions
|
||||
END
|
||||
'';
|
||||
@ -248,7 +256,7 @@ in
|
||||
}
|
||||
]
|
||||
|
||||
++ optional (config.nix.distributedBuilds && !config.nix.manualNixMachines)
|
||||
++ optional (cfg.distributedBuilds && !cfg.manualNixMachines)
|
||||
{ # List of machines for distributed Nix builds in the format expected
|
||||
# by build-remote.pl.
|
||||
source = pkgs.writeText "nix.machines"
|
||||
@ -258,37 +266,61 @@ in
|
||||
+ " ${machine.sshKey} ${toString machine.maxJobs} "
|
||||
+ (if machine ? speedFactor then toString machine.speedFactor else "1" )
|
||||
+ "\n"
|
||||
) config.nix.buildMachines));
|
||||
) cfg.buildMachines));
|
||||
target = "nix.machines";
|
||||
};
|
||||
|
||||
jobs.nixDaemon =
|
||||
{ name = "nix-daemon";
|
||||
systemd.sockets."nix-daemon" =
|
||||
{ description = "Nix Daemon Socket";
|
||||
wantedBy = [ "sockets.target" ];
|
||||
before = [ "multi-user.target" ];
|
||||
socketConfig.ListenStream = "/nix/var/nix/daemon-socket/socket";
|
||||
};
|
||||
|
||||
startOn = "startup";
|
||||
systemd.services."nix-daemon" =
|
||||
{ description = "Nix Daemon";
|
||||
|
||||
path = [ nix pkgs.openssl pkgs.utillinux ]
|
||||
++ optionals config.nix.distributedBuilds [ pkgs.openssh pkgs.gzip ];
|
||||
++ optionals cfg.distributedBuilds [ pkgs.openssh pkgs.gzip ];
|
||||
|
||||
script =
|
||||
''
|
||||
${config.nix.envVars}
|
||||
exec \
|
||||
nice -n ${builtins.toString config.nix.daemonNiceLevel} \
|
||||
ionice -n ${builtins.toString config.nix.daemonIONiceLevel} \
|
||||
nix-worker --daemon > /dev/null 2>&1
|
||||
'';
|
||||
environment = cfg.envVars;
|
||||
|
||||
extraConfig =
|
||||
''
|
||||
limit nofile 4096 4096
|
||||
'';
|
||||
serviceConfig =
|
||||
{ ExecStart = "@${nix}/bin/nix-daemon nix-daemon";
|
||||
KillMode = "process";
|
||||
Nice = cfg.daemonNiceLevel;
|
||||
IOSchedulingPriority = cfg.daemonIONiceLevel;
|
||||
LimitNOFILE = 4096;
|
||||
};
|
||||
};
|
||||
|
||||
nix.envVars =
|
||||
{ NIX_CONF_DIR = "/etc/nix";
|
||||
|
||||
# Enable the copy-from-other-stores substituter, which allows builds
|
||||
# to be sped up by copying build results from remote Nix stores. To
|
||||
# do this, mount the remote file system on a subdirectory of
|
||||
# /var/run/nix/remote-stores.
|
||||
NIX_OTHER_STORES = "/var/run/nix/remote-stores/*/nix";
|
||||
}
|
||||
|
||||
// optionalAttrs cfg.distributedBuilds {
|
||||
NIX_BUILD_HOOK = "${config.environment.nix}/libexec/nix/build-remote.pl";
|
||||
NIX_REMOTE_SYSTEMS = "/etc/nix.machines";
|
||||
NIX_CURRENT_LOAD = "/var/run/nix/current-load";
|
||||
}
|
||||
|
||||
# !!! These should not be defined here, but in some general proxy configuration module!
|
||||
// optionalAttrs (cfg.proxy != "") {
|
||||
http_proxy = cfg.proxy;
|
||||
https_proxy = cfg.proxy;
|
||||
ftp_proxy = cfg.proxy;
|
||||
};
|
||||
|
||||
environment.shellInit =
|
||||
''
|
||||
# Set up the environment variables for running Nix.
|
||||
${config.nix.envVars}
|
||||
${concatMapStrings (n: "export ${n}=\"${getAttr n cfg.envVars}\"\n") (attrNames cfg.envVars)}
|
||||
|
||||
# Set up secure multi-user builds: non-root users build through the
|
||||
# Nix daemon.
|
||||
@ -299,36 +331,10 @@ in
|
||||
fi
|
||||
'';
|
||||
|
||||
nix.envVars =
|
||||
''
|
||||
export NIX_CONF_DIR=/etc/nix
|
||||
|
||||
# Enable the copy-from-other-stores substituter, which allows builds
|
||||
# to be sped up by copying build results from remote Nix stores. To
|
||||
# do this, mount the remote file system on a subdirectory of
|
||||
# /var/run/nix/remote-stores.
|
||||
export NIX_OTHER_STORES=/var/run/nix/remote-stores/*/nix
|
||||
'' # */
|
||||
+ optionalString config.nix.distributedBuilds ''
|
||||
export NIX_BUILD_HOOK=${config.environment.nix}/libexec/nix/build-remote.pl
|
||||
export NIX_REMOTE_SYSTEMS=/etc/nix.machines
|
||||
export NIX_CURRENT_LOAD=/var/run/nix/current-load
|
||||
''
|
||||
# !!! These should not be defined here, but in some general proxy configuration module!
|
||||
+ optionalString (config.nix.proxy != "") ''
|
||||
export http_proxy=${config.nix.proxy}
|
||||
export https_proxy=${config.nix.proxy}
|
||||
export ftp_proxy=${config.nix.proxy}
|
||||
'';
|
||||
|
||||
users.extraUsers = map makeNixBuildUser (range 1 config.nix.nrBuildUsers);
|
||||
users.extraUsers = map makeNixBuildUser (range 1 cfg.nrBuildUsers);
|
||||
|
||||
system.activationScripts.nix = stringAfter [ "etc" "users" ]
|
||||
''
|
||||
# Set up Nix.
|
||||
chown root:nixbld /nix/store
|
||||
chmod 1775 /nix/store
|
||||
|
||||
# Nix initialisation.
|
||||
mkdir -m 0755 -p \
|
||||
/nix/var/nix/gcroots \
|
||||
@ -340,9 +346,10 @@ in
|
||||
/nix/var/log/nix/drvs \
|
||||
/nix/var/nix/channel-cache \
|
||||
/nix/var/nix/chroots
|
||||
mkdir -m 1777 -p /nix/var/nix/gcroots/per-user
|
||||
mkdir -m 1777 -p /nix/var/nix/profiles/per-user
|
||||
mkdir -m 1777 -p /nix/var/nix/gcroots/tmp
|
||||
mkdir -m 1777 -p \
|
||||
/nix/var/nix/gcroots/per-user \
|
||||
/nix/var/nix/profiles/per-user \
|
||||
/nix/var/nix/gcroots/tmp
|
||||
|
||||
ln -sf /nix/var/nix/profiles /nix/var/nix/gcroots/
|
||||
ln -sf /nix/var/nix/manifests /nix/var/nix/gcroots/
|
||||
|
@ -3,7 +3,6 @@
|
||||
with pkgs.lib;
|
||||
|
||||
let
|
||||
nix = config.environment.nix;
|
||||
cfg = config.nix.gc;
|
||||
in
|
||||
|
||||
@ -16,7 +15,7 @@ in
|
||||
|
||||
automatic = mkOption {
|
||||
default = false;
|
||||
example = true;
|
||||
type = types.bool;
|
||||
description = "
|
||||
Automatically run the garbage collector at specified dates.
|
||||
";
|
||||
@ -24,6 +23,7 @@ in
|
||||
|
||||
dates = mkOption {
|
||||
default = "15 03 * * *";
|
||||
type = types.string;
|
||||
description = "
|
||||
Run the garbage collector at specified dates to avoid full
|
||||
hard-drives.
|
||||
@ -33,6 +33,7 @@ in
|
||||
options = mkOption {
|
||||
default = "";
|
||||
example = "--max-freed $((64 * 1024**3))";
|
||||
type = types.string;
|
||||
description = "
|
||||
Options given to <filename>nix-collect-garbage</filename> when the
|
||||
garbage collector is run automatically.
|
||||
@ -45,10 +46,17 @@ in
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf cfg.automatic {
|
||||
services.cron.systemCronJobs = [
|
||||
"${cfg.dates} root ${nix}/bin/nix-collect-garbage ${cfg.options} > /var/log/gc.log 2>&1"
|
||||
];
|
||||
config = {
|
||||
|
||||
services.cron.systemCronJobs = mkIf cfg.automatic (singleton
|
||||
"${cfg.dates} root ${config.systemd.package}/bin/systemctl start nix-gc.service");
|
||||
|
||||
systemd.services."nix-gc" =
|
||||
{ description = "Nix Garbage Collector";
|
||||
path = [ config.environment.nix ];
|
||||
script = "exec nix-collect-garbage ${cfg.options}";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -16,6 +16,17 @@ let
|
||||
inherit pkgs options;
|
||||
};
|
||||
|
||||
entry = "${manual.manual}/share/doc/nixos/manual.html";
|
||||
|
||||
help = pkgs.writeScriptBin "nixos-help"
|
||||
''
|
||||
#! ${pkgs.stdenv.shell} -e
|
||||
if ! ''${BROWSER:-w3m} ${entry}; then
|
||||
echo "$0: unable to start a web browser; please set \$BROWSER or install ‘w3m’"
|
||||
exit 1
|
||||
fi
|
||||
'';
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
@ -69,23 +80,23 @@ in
|
||||
|
||||
system.build.manual = manual;
|
||||
|
||||
environment.systemPackages = [ manual.manpages ];
|
||||
environment.systemPackages = [ manual.manpages help ];
|
||||
|
||||
boot.extraTTYs = mkIf cfg.showManual ["tty${cfg.ttyNumber}"];
|
||||
|
||||
jobs = mkIf cfg.showManual
|
||||
{ nixosManual =
|
||||
{ name = "nixos-manual";
|
||||
|
||||
description = "NixOS manual";
|
||||
|
||||
startOn = "started udev";
|
||||
|
||||
exec =
|
||||
''
|
||||
${cfg.browser} ${manual.manual}/share/doc/nixos/manual.html \
|
||||
< /dev/tty${toString cfg.ttyNumber} > /dev/tty${toString cfg.ttyNumber} 2>&1
|
||||
'';
|
||||
systemd.services = optionalAttrs cfg.showManual
|
||||
{ "nixos-manual" =
|
||||
{ description = "NixOS Manual";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig =
|
||||
{ ExecStart = "${cfg.browser} ${entry}";
|
||||
StandardInput = "tty";
|
||||
StandardOutput = "tty";
|
||||
TTYPath = "/dev/tty${cfg.ttyNumber}";
|
||||
TTYReset = true;
|
||||
TTYVTDisallocate = true;
|
||||
Restart = "always";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -40,14 +40,18 @@ in
|
||||
|
||||
boot.extraTTYs = [ cfg.tty ];
|
||||
|
||||
jobs.rogue =
|
||||
systemd.services.rogue =
|
||||
{ description = "Rogue dungeon crawling game";
|
||||
|
||||
startOn = "started udev";
|
||||
|
||||
extraConfig = "chdir /root";
|
||||
|
||||
exec = "${pkgs.rogue}/bin/rogue < /dev/${cfg.tty} > /dev/${cfg.tty} 2>&1";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig =
|
||||
{ ExecStart = "${pkgs.rogue}/bin/rogue";
|
||||
StandardInput = "tty";
|
||||
StandardOutput = "tty";
|
||||
TTYPath = "/dev/${cfg.tty}";
|
||||
TTYReset = true;
|
||||
TTYVTDisallocate = true;
|
||||
Restart = "always";
|
||||
};
|
||||
};
|
||||
|
||||
services.ttyBackgrounds.specificThemes = singleton
|
||||
|
58
modules/services/monitoring/dd-agent.nix
Normal file
58
modules/services/monitoring/dd-agent.nix
Normal file
@ -0,0 +1,58 @@
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
with pkgs.lib;
|
||||
|
||||
let
|
||||
cfg = config.services.dd-agent;
|
||||
|
||||
datadog-conf = pkgs.runCommand "datadog.conf" {} ''
|
||||
sed -e 's|^api_key:|api_key: ${cfg.api_key}|' ${optionalString (cfg.hostname != null)
|
||||
"-e 's|^#hostname: mymachine.mydomain|hostname: ${cfg.hostname}|'"
|
||||
} ${pkgs.dd-agent}/etc/dd-agent/datadog.conf.example > $out
|
||||
'';
|
||||
in {
|
||||
options.services.dd-agent = {
|
||||
enable = mkOption {
|
||||
description = "Whether to enable the dd-agent montioring service";
|
||||
|
||||
default = false;
|
||||
|
||||
type = types.bool;
|
||||
};
|
||||
|
||||
# !!! This gets stored in the store (world-readable), wish we had https://github.com/NixOS/nix/issues/8
|
||||
api_key = mkOption {
|
||||
description = "The Datadog API key to associate the agent with your account";
|
||||
|
||||
example = "ae0aa6a8f08efa988ba0a17578f009ab";
|
||||
|
||||
type = types.uniq types.string;
|
||||
};
|
||||
|
||||
hostname = mkOption {
|
||||
description = "The hostname to show in the Datadog dashboard (optional)";
|
||||
|
||||
default = null;
|
||||
|
||||
example = "mymachine.mydomain";
|
||||
|
||||
type = types.uniq (types.nullOr types.string);
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
environment.etc = [ { source = datadog-conf; target = "dd-agent/datadog.conf"; } ];
|
||||
|
||||
systemd.services.dd-agent = {
|
||||
description = "Datadog agent monitor";
|
||||
|
||||
path = [ pkgs.sysstat pkgs.procps ];
|
||||
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
serviceConfig.ExecStart = "${pkgs.dd-agent}/bin/dd-agent foreground";
|
||||
|
||||
restartTriggers = [ pkgs.dd-agent ];
|
||||
};
|
||||
};
|
||||
}
|
@ -159,12 +159,7 @@ in
|
||||
environment.systemPackages = [ pkgs.nagios ];
|
||||
|
||||
jobs.nagios =
|
||||
{ # Run `nagios -v' to check the validity of the configuration file so
|
||||
# that a nixos-rebuild fails *before* we kill the running Nagios
|
||||
# daemon.
|
||||
buildHook = "${pkgs.nagios}/bin/nagios -v ${nagiosCfgFile}";
|
||||
|
||||
description = "Nagios monitoring daemon";
|
||||
{ description = "Nagios monitoring daemon";
|
||||
|
||||
startOn = "started network-interfaces";
|
||||
stopOn = "stopping network-interfaces";
|
||||
|
@ -57,7 +57,7 @@ in
|
||||
description = ''
|
||||
Additional options for each device that is monitored. The example
|
||||
turns on SMART Automatic Offline Testing on startup, and schedules short
|
||||
self-tests daily, and long self-tests weekly.
|
||||
self-tests daily, and long self-tests weekly.
|
||||
'';
|
||||
};
|
||||
|
||||
@ -81,17 +81,15 @@ in
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
jobs.smartd = {
|
||||
description = "S.M.A.R.T. Daemon";
|
||||
systemd.services.smartd = {
|
||||
description = "S.M.A.R.T. Daemon";
|
||||
|
||||
environment.TZ = config.time.timeZone;
|
||||
environment.TZ = config.time.timeZone;
|
||||
|
||||
startOn = "started syslogd";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
path = [ pkgs.smartmontools ];
|
||||
|
||||
exec = "smartd --no-fork --pidfile=/var/run/smartd.pid ${smartdFlags}";
|
||||
};
|
||||
serviceConfig.ExecStart = "${pkgs.smartmontools}/sbin/smartd --no-fork ${smartdFlags}";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
@ -73,15 +73,12 @@ in
|
||||
description = "Zabbix daemon user";
|
||||
};
|
||||
|
||||
jobs.zabbix_agent =
|
||||
{ name = "zabbix-agent";
|
||||
systemd.services."zabbix-agent" =
|
||||
{ description = "Zabbix Agent";
|
||||
|
||||
description = "Zabbix agent daemon";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
startOn = "ip-up";
|
||||
stopOn = "stopping network-interfaces";
|
||||
|
||||
path = [ pkgs.zabbix.agent ];
|
||||
path = [ pkgs.nettools ];
|
||||
|
||||
preStart =
|
||||
''
|
||||
@ -89,30 +86,11 @@ in
|
||||
chown zabbix ${stateDir} ${logDir}
|
||||
'';
|
||||
|
||||
# Zabbix doesn't have an option not to daemonize, and doesn't
|
||||
# daemonize in a way that allows Upstart to track it. So to
|
||||
# make sure that we notice when it goes down, we start Zabbix
|
||||
# with an open connection to a fifo, with a `cat' on the other
|
||||
# side. If Zabbix dies, then `cat' will exit as well, so we
|
||||
# just monitor `cat'.
|
||||
script =
|
||||
''
|
||||
export PATH=${pkgs.nettools}/bin:$PATH
|
||||
rm -f ${stateDir}/dummy2
|
||||
mkfifo ${stateDir}/dummy2
|
||||
cat ${stateDir}/dummy2 &
|
||||
pid=$!
|
||||
zabbix_agentd --config ${configFile} 100>${stateDir}/dummy2
|
||||
wait "$pid"
|
||||
'';
|
||||
|
||||
postStop =
|
||||
''
|
||||
pid=$(cat ${pidFile} 2> /dev/null || true)
|
||||
(test -n "$pid" && kill "$pid") || true
|
||||
# Wait until they're really gone.
|
||||
while ${pkgs.procps}/bin/pgrep -u zabbix zabbix_agentd > /dev/null; do sleep 1; done
|
||||
'';
|
||||
serviceConfig.ExecStart = "@${pkgs.zabbix.agent}/sbin/zabbix_agentd zabbix_agentd --config ${configFile}";
|
||||
serviceConfig.Type = "forking";
|
||||
serviceConfig.RemainAfterExit = true;
|
||||
serviceConfig.Restart = "always";
|
||||
serviceConfig.RestartSec = 2;
|
||||
};
|
||||
|
||||
environment.systemPackages = [ pkgs.zabbix.agent ];
|
||||
|
@ -73,12 +73,11 @@ in
|
||||
description = "Zabbix daemon user";
|
||||
};
|
||||
|
||||
jobs.zabbix_server =
|
||||
{ name = "zabbix-server";
|
||||
systemd.services."zabbix-server" =
|
||||
{ description = "Zabbix Server";
|
||||
|
||||
description = "Zabbix server daemon";
|
||||
|
||||
startOn = "filesystem";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = optional (cfg.dbServer == "localhost") "postgresql.service";
|
||||
|
||||
preStart =
|
||||
''
|
||||
@ -95,31 +94,12 @@ in
|
||||
fi
|
||||
'';
|
||||
|
||||
path = [ pkgs.nettools pkgs.zabbix.server ];
|
||||
path = [ pkgs.nettools ];
|
||||
|
||||
# Zabbix doesn't have an option not to daemonize, and doesn't
|
||||
# daemonize in a way that allows Upstart to track it. So to
|
||||
# make sure that we notice when it goes down, we start Zabbix
|
||||
# with an open connection to a fifo, with a `cat' on the other
|
||||
# side. If Zabbix dies, then `cat' will exit as well, so we
|
||||
# just monitor `cat'.
|
||||
script =
|
||||
''
|
||||
rm -f ${stateDir}/dummy
|
||||
mkfifo ${stateDir}/dummy
|
||||
cat ${stateDir}/dummy &
|
||||
pid=$!
|
||||
zabbix_server --config ${configFile} 100>${stateDir}/dummy
|
||||
wait "$pid"
|
||||
'';
|
||||
|
||||
postStop =
|
||||
''
|
||||
pid=$(cat ${pidFile} 2> /dev/null || true)
|
||||
(test -n "$pid" && kill "$pid") || true
|
||||
# Wait until they're really gone.
|
||||
while ${pkgs.procps}/bin/pkill -u zabbix zabbix_server; do true; done
|
||||
'';
|
||||
serviceConfig.ExecStart = "@${pkgs.zabbix.server}/sbin/zabbix_server zabbix_server --config ${configFile}";
|
||||
serviceConfig.Type = "forking";
|
||||
serviceConfig.Restart = "always";
|
||||
serviceConfig.RestartSec = 2;
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -80,44 +80,44 @@ in
|
||||
|
||||
boot.kernelModules = [ "nfsd" ];
|
||||
|
||||
jobs.nfsd =
|
||||
{ description = "Kernel NFS server";
|
||||
systemd.services.nfsd =
|
||||
{ description = "NFS Server";
|
||||
|
||||
startOn = "started networking";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
requires = [ "rpcbind.service" "mountd.service" ];
|
||||
after = [ "rpcbind.service" "mountd.service" "statd.service" ];
|
||||
|
||||
path = [ pkgs.nfsUtils ];
|
||||
|
||||
preStart =
|
||||
script =
|
||||
''
|
||||
ensure rpcbind
|
||||
ensure mountd
|
||||
|
||||
# Create a state directory required by NFSv4.
|
||||
mkdir -p /var/lib/nfs/v4recovery
|
||||
|
||||
rpc.nfsd \
|
||||
${if cfg.hostName != null then "-H ${cfg.hostName}" else ""} \
|
||||
${builtins.toString cfg.nproc}
|
||||
|
||||
sm-notify -d
|
||||
'';
|
||||
|
||||
postStop = "rpc.nfsd 0";
|
||||
|
||||
postStart =
|
||||
''
|
||||
ensure statd
|
||||
ensure idmapd
|
||||
'';
|
||||
serviceConfig.Type = "oneshot";
|
||||
serviceConfig.RemainAfterExit = true;
|
||||
};
|
||||
|
||||
jobs.mountd =
|
||||
{ description = "Kernel NFS server - mount daemon";
|
||||
systemd.services.mountd =
|
||||
{ description = "NFSv3 Mount Daemon";
|
||||
|
||||
requires = [ "rpcbind.service" ];
|
||||
after = [ "rpcbind.service" ];
|
||||
|
||||
path = [ pkgs.nfsUtils pkgs.sysvtools pkgs.utillinux ];
|
||||
|
||||
preStart =
|
||||
''
|
||||
ensure rpcbind
|
||||
|
||||
mkdir -p /var/lib/nfs
|
||||
touch /var/lib/nfs/rmtab
|
||||
|
||||
@ -133,14 +133,14 @@ in
|
||||
''
|
||||
}
|
||||
|
||||
# exports file is ${exports}
|
||||
# keep this comment so that this job is restarted whenever exports changes!
|
||||
exportfs -ra
|
||||
'';
|
||||
|
||||
daemonType = "fork";
|
||||
restartTriggers = [ exports ];
|
||||
|
||||
exec = "rpc.mountd -f /etc/exports";
|
||||
serviceConfig.Type = "forking";
|
||||
serviceConfig.ExecStart = "@${pkgs.nfsUtils}/sbin/rpc.mountd rpc.mountd -f /etc/exports";
|
||||
serviceConfig.Restart = "always";
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -26,18 +26,14 @@ let
|
||||
mkdir -p /var/samba/locks /var/samba/cores/nmbd /var/samba/cores/smbd /var/samba/cores/winbindd
|
||||
fi
|
||||
|
||||
passwdFile="$(sed -n 's/^.*smb[ ]\+passwd[ ]\+file[ ]\+=[ ]\+\(.*\)/\1/p' ${configFile})"
|
||||
passwdFile="$(${pkgs.gnused}/bin/sed -n 's/^.*smb[ ]\+passwd[ ]\+file[ ]\+=[ ]\+\(.*\)/\1/p' ${configFile})"
|
||||
if [ -n "$passwdFile" ]; then
|
||||
echo 'INFO: creating directory containing passwd file'
|
||||
echo 'INFO: [samba] creating directory containing passwd file'
|
||||
mkdir -p "$(dirname "$passwdFile")"
|
||||
fi
|
||||
|
||||
mkdir -p ${logDir}
|
||||
mkdir -p ${privateDir}
|
||||
|
||||
# The following line is to trigger a restart of the daemons when
|
||||
# the configuration changes:
|
||||
# ${configFile}
|
||||
'';
|
||||
|
||||
configFile = pkgs.writeText "smb.conf"
|
||||
@ -60,12 +56,11 @@ let
|
||||
# This may include nss_ldap, needed for samba if it has to use ldap.
|
||||
nssModulesPath = config.system.nssModules.path;
|
||||
|
||||
daemonJob = appName: args:
|
||||
{ name = "samba-${appName}";
|
||||
description = "Samba Service daemon ${appName}";
|
||||
daemonService = appName: args:
|
||||
{ description = "Samba Service daemon ${appName}";
|
||||
|
||||
startOn = "started samba";
|
||||
stopOn = "stopping samba";
|
||||
wantedBy = [ "samba.target" ];
|
||||
partOf = [ "samba.target" ];
|
||||
|
||||
environment = {
|
||||
LD_LIBRARY_PATH = nssModulesPath;
|
||||
@ -73,9 +68,12 @@ let
|
||||
LOCALE_ARCHIVE = "/run/current-system/sw/lib/locale/locale-archive";
|
||||
};
|
||||
|
||||
daemonType = "fork";
|
||||
serviceConfig = {
|
||||
ExecStart = "${samba}/sbin/${appName} ${args}";
|
||||
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
|
||||
};
|
||||
|
||||
exec = "${samba}/sbin/${appName} ${args}";
|
||||
restartTriggers = [ configFile ];
|
||||
};
|
||||
|
||||
in
|
||||
@ -202,22 +200,26 @@ in
|
||||
};
|
||||
|
||||
|
||||
# Dummy job to start the real Samba daemons (nmbd, smbd, winbindd).
|
||||
jobs.sambaControl =
|
||||
{ name = "samba";
|
||||
systemd = {
|
||||
targets.samba = {
|
||||
description = "Samba server";
|
||||
|
||||
startOn = "started network-interfaces";
|
||||
stopOn = "stopping network-interfaces";
|
||||
|
||||
preStart = setupScript;
|
||||
requires = [ "samba-setup.service" ];
|
||||
after = [ "samba-setup.service" "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
};
|
||||
|
||||
jobs.nmbd = daemonJob "nmbd" "-D";
|
||||
services = {
|
||||
"samba-nmbd" = daemonService "nmbd" "-F";
|
||||
"samba-smbd" = daemonService "smbd" "-F";
|
||||
"samba-winbindd" = daemonService "winbindd" "-F";
|
||||
"samba-setup" = {
|
||||
description = "Samba setup task";
|
||||
script = setupScript;
|
||||
unitConfig.RequiresMountsFor = "/home/smbd /var/samba /var/log/samba";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
jobs.smbd = daemonJob "smbd" "-D";
|
||||
|
||||
jobs.winbindd = daemonJob "winbindd" "-D";
|
||||
})
|
||||
];
|
||||
|
||||
|
@ -9,7 +9,7 @@ let
|
||||
# Don't start dhclient on explicitly configured interfaces or on
|
||||
# interfaces that are part of a bridge.
|
||||
ignoredInterfaces =
|
||||
map (i: i.name) (filter (i: i ? ipAddress && i.ipAddress != "" ) config.networking.interfaces)
|
||||
map (i: i.name) (filter (i: i.ipAddress != null) (attrValues config.networking.interfaces))
|
||||
++ concatLists (attrValues (mapAttrs (n: v: v.interfaces) config.networking.bridges))
|
||||
++ config.networking.dhcpcd.denyInterfaces;
|
||||
|
||||
@ -52,20 +52,19 @@ let
|
||||
''}
|
||||
|
||||
if [ "$reason" = BOUND -o "$reason" = REBOOT ]; then
|
||||
# Restart ntpd. (The "ip-up" event below will trigger the
|
||||
# restart.) We need to restart it to make sure that it will
|
||||
# actually do something: if ntpd cannot resolve the server
|
||||
# hostnames in its config file, then it will never do
|
||||
# Restart ntpd. We need to restart it to make sure that it
|
||||
# will actually do something: if ntpd cannot resolve the
|
||||
# server hostnames in its config file, then it will never do
|
||||
# anything ever again ("couldn't resolve ..., giving up on
|
||||
# it"), so we silently lose time synchronisation.
|
||||
${config.system.build.upstart}/sbin/initctl stop ntpd
|
||||
${config.systemd.package}/bin/systemctl try-restart ntpd.service
|
||||
|
||||
${config.system.build.upstart}/sbin/initctl emit -n ip-up $params
|
||||
${config.systemd.package}/bin/systemctl start ip-up.target
|
||||
fi
|
||||
|
||||
if [ "$reason" = EXPIRE -o "$reason" = RELEASE -o "$reason" = NOCARRIER ] ; then
|
||||
${config.system.build.upstart}/sbin/initctl emit -n ip-down $params
|
||||
fi
|
||||
#if [ "$reason" = EXPIRE -o "$reason" = RELEASE -o "$reason" = NOCARRIER ] ; then
|
||||
# ${config.systemd.package}/bin/systemctl start ip-down.target
|
||||
#fi
|
||||
'';
|
||||
|
||||
in
|
||||
@ -93,12 +92,27 @@ in
|
||||
|
||||
config = mkIf config.networking.useDHCP {
|
||||
|
||||
jobs.dhcpcd =
|
||||
{ startOn = "started network-interfaces";
|
||||
systemd.services.dhcpcd =
|
||||
{ description = "DHCP Client";
|
||||
|
||||
wantedBy = [ "network.target" ];
|
||||
after = [ "systemd-udev-settle.service" ];
|
||||
|
||||
# Stopping dhcpcd during a reconfiguration is undesirable
|
||||
# because it brings down the network interfaces configured by
|
||||
# dhcpcd. So do a "systemctl restart" instead.
|
||||
stopIfChanged = false;
|
||||
|
||||
path = [ dhcpcd pkgs.nettools pkgs.openresolv ];
|
||||
|
||||
exec = "dhcpcd --config ${dhcpcdConf} --nobackground";
|
||||
serviceConfig =
|
||||
{ Type = "forking";
|
||||
PIDFile = "/run/dhcpcd.pid";
|
||||
ExecStart = "@${dhcpcd}/sbin/dhcpcd dhcpcd --config ${dhcpcdConf}";
|
||||
ExecReload = "${dhcpcd}/sbin/dhcpcd --rebind";
|
||||
StandardError = "null";
|
||||
Restart = "always";
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = [ dhcpcd ];
|
||||
@ -112,8 +126,7 @@ in
|
||||
powerManagement.resumeCommands =
|
||||
''
|
||||
# Tell dhcpcd to rebind its interfaces if it's running.
|
||||
status="$(${config.system.build.upstart}/sbin/status dhcpcd)"
|
||||
[[ "$status" =~ start/running ]] && ${dhcpcd}/sbin/dhcpcd --rebind
|
||||
${config.systemd.package}/bin/systemctl reload dhcpcd.service
|
||||
'';
|
||||
|
||||
};
|
||||
|
@ -236,14 +236,15 @@ in
|
||||
];
|
||||
|
||||
jobs.firewall =
|
||||
{ startOn = "started network-interfaces";
|
||||
{ description = "Firewall";
|
||||
|
||||
startOn = "started network-interfaces";
|
||||
|
||||
path = [ pkgs.iptables ];
|
||||
|
||||
preStart =
|
||||
''
|
||||
${helpers}
|
||||
set -x
|
||||
|
||||
# Flush the old firewall rules. !!! Ideally, updating the
|
||||
# firewall would be atomic. Apparently that's possible
|
||||
|
@ -56,22 +56,31 @@ in
|
||||
config = mkIf cfg.enable {
|
||||
boot.kernelModules = [ "tun" ];
|
||||
|
||||
# environment.systemPackages = [pkgs.gogoclient];
|
||||
|
||||
networking.enableIPv6 = true;
|
||||
|
||||
jobs.gogoclient = {
|
||||
name = "gogoclient";
|
||||
systemd.services.gogoclient = {
|
||||
description = "ipv6 tunnel";
|
||||
startOn = optionalString cfg.autorun "starting networking";
|
||||
stopOn = "stopping network-interfaces";
|
||||
preStart = ''
|
||||
mkdir -p /var/lib/gogoc
|
||||
chmod 700 /var/lib/gogoc
|
||||
cat ${pkgs.gogoclient}/share/${pkgs.gogoclient.name}/gogoc.conf.sample | ${pkgs.gnused}/bin/sed -e "s|^userid=|&${cfg.username}|;s|^passwd=|&${if cfg.password == "" then "" else "$(cat ${cfg.password})"}|;s|^server=.*|server=${cfg.server}|;s|^auth_method=.*|auth_method=${if cfg.password == "" then "anonymous" else "any"}|;s|^#log_file=|log_file=1|" > /var/lib/gogoc/gogoc.conf
|
||||
|
||||
after = [ "network.target" ];
|
||||
requires = [ "network.target" ];
|
||||
|
||||
unitConfig.RequiresMountsFor = "/var/lib/gogoc";
|
||||
|
||||
script = let authMethod = if cfg.password == "" then "anonymous" else "any"; in ''
|
||||
mkdir -p -m 700 /var/lib/gogoc
|
||||
cat ${pkgs.gogoclient}/share/${pkgs.gogoclient.name}/gogoc.conf.sample | \
|
||||
${pkgs.gnused}/bin/sed \
|
||||
-e "s|^userid=|&${cfg.username}|" \
|
||||
-e "s|^passwd=|&${optionalString (cfg.password != "") "$(cat ${cfg.password})"}|" \
|
||||
-e "s|^server=.*|server=${cfg.server}|" \
|
||||
-e "s|^auth_method=.*|auth_method=${authMethod}|" \
|
||||
-e "s|^#log_file=|log_file=1|" > /var/lib/gogoc/gogoc.conf
|
||||
cd /var/lib/gogoc
|
||||
exec ${pkgs.gogoclient}/bin/gogoc -y -f /var/lib/gogoc/gogoc.conf
|
||||
'';
|
||||
script = "cd /var/lib/gogoc; exec gogoc -y -f ./gogoc.conf";
|
||||
path = [pkgs.gogoclient];
|
||||
} // optionalAttrs cfg.autorun {
|
||||
wantedBy = [ "ip-up.target" ];
|
||||
partOf = [ "ip-up.target" ];
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -1,13 +1,14 @@
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
with pkgs.lib;
|
||||
with pkgs;
|
||||
|
||||
let
|
||||
cfg = config.networking.networkmanager;
|
||||
|
||||
stateDirs = "/var/lib/NetworkManager /var/lib/dhclient";
|
||||
|
||||
configFile = pkgs.writeText "NetworkManager.conf" ''
|
||||
configFile = writeText "NetworkManager.conf" ''
|
||||
[main]
|
||||
plugins=keyfile
|
||||
|
||||
@ -36,10 +37,10 @@ let
|
||||
ResultActive=yes
|
||||
'';
|
||||
|
||||
ipUpScript = pkgs.writeScript "01nixos-ip-up" ''
|
||||
ipUpScript = writeScript "01nixos-ip-up" ''
|
||||
#!/bin/sh
|
||||
if test "$2" = "up"; then
|
||||
${pkgs.upstart}/sbin/initctl emit ip-up "IFACE=$1"
|
||||
${config.systemd.package}/bin/systemctl start ip-up.target
|
||||
fi
|
||||
'';
|
||||
|
||||
@ -67,7 +68,7 @@ in {
|
||||
Extra packages that provide NetworkManager plugins.
|
||||
'';
|
||||
merge = mergeListOption;
|
||||
apply = list: [ pkgs.networkmanager pkgs.modemmanager ] ++ list;
|
||||
apply = list: [ networkmanager modemmanager wpa_supplicant ] ++ list;
|
||||
};
|
||||
};
|
||||
|
||||
@ -76,10 +77,14 @@ in {
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
environment.etc = singleton {
|
||||
source = ipUpScript;
|
||||
target = "NetworkManager/dispatcher.d/01nixos-ip-up";
|
||||
};
|
||||
environment.etc = [
|
||||
{ source = ipUpScript;
|
||||
target = "NetworkManager/dispatcher.d/01nixos-ip-up";
|
||||
}
|
||||
{ source = configFile;
|
||||
target = "NetworkManager/NetworkManager.conf";
|
||||
}
|
||||
];
|
||||
|
||||
environment.systemPackages = cfg.packages;
|
||||
|
||||
@ -88,24 +93,31 @@ in {
|
||||
gid = config.ids.gids.networkmanager;
|
||||
};
|
||||
|
||||
jobs.networkmanager = {
|
||||
startOn = "started network-interfaces";
|
||||
stopOn = "stopping network-interfaces";
|
||||
systemd.packages = cfg.packages;
|
||||
|
||||
path = [ pkgs.networkmanager ];
|
||||
|
||||
preStart = ''
|
||||
mkdir -m 755 -p /etc/NetworkManager
|
||||
# Create an initialisation service that both starts
|
||||
# NetworkManager when network.target is reached,
|
||||
# and sets up necessary directories for NM.
|
||||
systemd.services."networkmanager-init" = {
|
||||
description = "NetworkManager initialisation";
|
||||
wantedBy = [ "network.target" ];
|
||||
partOf = [ "NetworkManager.service" ];
|
||||
wants = [ "NetworkManager.service" ];
|
||||
before = [ "NetworkManager.service" ];
|
||||
script = ''
|
||||
mkdir -m 700 -p /etc/NetworkManager/system-connections
|
||||
mkdir -m 755 -p ${stateDirs}
|
||||
'';
|
||||
|
||||
exec = "NetworkManager --config=${configFile} --no-daemon";
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
};
|
||||
};
|
||||
|
||||
networking.useDHCP = false;
|
||||
|
||||
networking.wireless.enable = true;
|
||||
# Turn off NixOS' network management
|
||||
networking = {
|
||||
useDHCP = false;
|
||||
wireless.enable = false;
|
||||
};
|
||||
|
||||
security.polkit.permissions = polkitConf;
|
||||
|
||||
|
@ -66,9 +66,10 @@ in
|
||||
};
|
||||
|
||||
jobs.ntpd =
|
||||
{ description = "NTP daemon";
|
||||
{ description = "NTP Daemon";
|
||||
|
||||
startOn = "ip-up";
|
||||
wantedBy = [ "ip-up.target" ];
|
||||
partOf = [ "ip-up.target" ];
|
||||
|
||||
path = [ ntp ];
|
||||
|
||||
|
@ -11,8 +11,8 @@ let
|
||||
makeOpenVPNJob = cfg: name:
|
||||
let
|
||||
|
||||
path = (getAttr "openvpn-${name}" config.jobs).path;
|
||||
|
||||
path = (getAttr "openvpn-${name}" config.systemd.services).path;
|
||||
|
||||
upScript = ''
|
||||
#! /bin/sh
|
||||
exec > /var/log/openvpn-${name}-up 2>&1
|
||||
@ -28,17 +28,17 @@ let
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
${cfg.up}
|
||||
'';
|
||||
|
||||
|
||||
downScript = ''
|
||||
#! /bin/sh
|
||||
exec > /var/log/openvpn-${name}-down 2>&1
|
||||
export PATH=${path}
|
||||
${cfg.down}
|
||||
'';
|
||||
|
||||
|
||||
configFile = pkgs.writeText "openvpn-config-${name}"
|
||||
''
|
||||
${optionalString (cfg.up != "" || cfg.down != "") "script-security 2"}
|
||||
@ -46,7 +46,7 @@ let
|
||||
${optionalString (cfg.up != "") "up ${pkgs.writeScript "openvpn-${name}-up" upScript}"}
|
||||
${optionalString (cfg.down != "") "down ${pkgs.writeScript "openvpn-${name}-down" downScript}"}
|
||||
'';
|
||||
|
||||
|
||||
in {
|
||||
description = "OpenVPN instance ‘${name}’";
|
||||
|
||||
@ -76,7 +76,7 @@ in
|
||||
default = {};
|
||||
|
||||
example = {
|
||||
|
||||
|
||||
server = {
|
||||
config = ''
|
||||
# Simplest server configuration: http://openvpn.net/index.php/documentation/miscellaneous/static-key-mini-howto.html.
|
||||
@ -88,7 +88,7 @@ in
|
||||
up = "ip route add ...";
|
||||
down = "ip route del ...";
|
||||
};
|
||||
|
||||
|
||||
client = {
|
||||
config = ''
|
||||
client
|
||||
@ -103,7 +103,7 @@ in
|
||||
up = "echo nameserver $nameserver | ${pkgs.openresolv}/sbin/resolvconf -m 0 -a $dev";
|
||||
down = "${pkgs.openresolv}/sbin/resolvconf -d $dev";
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
|
||||
description = ''
|
||||
@ -116,7 +116,7 @@ in
|
||||
'';
|
||||
|
||||
type = types.attrsOf types.optionSet;
|
||||
|
||||
|
||||
options = {
|
||||
|
||||
config = mkOption {
|
||||
@ -158,9 +158,9 @@ in
|
||||
jobs = listToAttrs (mapAttrsFlatten (name: value: nameValuePair "openvpn-${name}" (makeOpenVPNJob value name)) cfg.servers);
|
||||
|
||||
environment.systemPackages = [ openvpn ];
|
||||
|
||||
|
||||
boot.kernelModules = [ "tun" ];
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -29,6 +29,8 @@ let
|
||||
'';
|
||||
};
|
||||
|
||||
check = mkAssert (!(config.services.rpcbind.enable && config.services.portmap.enable))
|
||||
"Portmap and rpcbind cannot both be enabled.";
|
||||
|
||||
in
|
||||
|
||||
@ -57,24 +59,26 @@ in
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf config.services.rpcbind.enable {
|
||||
config = mkIf config.services.rpcbind.enable (check {
|
||||
|
||||
environment.etc = [netconfigFile];
|
||||
environment.systemPackages = [ pkgs.rpcbind ];
|
||||
|
||||
jobs.rpcbind =
|
||||
{ description = "ONC RPC rpcbind";
|
||||
environment.etc = [ netconfigFile ];
|
||||
|
||||
startOn = "started network-interfaces";
|
||||
stopOn = "";
|
||||
systemd.services.rpcbind =
|
||||
{ description = "ONC RPC Directory Service";
|
||||
|
||||
daemonType = "fork";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
exec =
|
||||
''
|
||||
${pkgs.rpcbind}/bin/rpcbind
|
||||
'';
|
||||
requires = [ "basic.target" ];
|
||||
after = [ "basic.target" ];
|
||||
|
||||
unitConfig.DefaultDependencies = false; # don't stop during shutdown
|
||||
|
||||
serviceConfig.Type = "forking";
|
||||
serviceConfig.ExecStart = "@${pkgs.rpcbind}/bin/rpcbind rpcbind";
|
||||
};
|
||||
|
||||
};
|
||||
});
|
||||
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ let
|
||||
);
|
||||
|
||||
userOptions = {
|
||||
|
||||
openssh.authorizedKeys = {
|
||||
keys = mkOption {
|
||||
type = types.listOf types.string;
|
||||
@ -63,6 +64,7 @@ let
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
authKeysFiles = let
|
||||
@ -114,14 +116,13 @@ in
|
||||
};
|
||||
|
||||
permitRootLogin = mkOption {
|
||||
default = "yes";
|
||||
default = "without-password";
|
||||
check = permitRootLoginCheck;
|
||||
description = ''
|
||||
Whether the root user can login using ssh. Valid values are
|
||||
<literal>yes</literal>, <literal>without-password</literal>,
|
||||
<literal>forced-commands-only</literal> or
|
||||
<literal>no</literal>.
|
||||
If without-password doesn't work try <literal>yes</literal>.
|
||||
'';
|
||||
};
|
||||
|
||||
@ -261,20 +262,18 @@ in
|
||||
}
|
||||
];
|
||||
|
||||
jobs.sshd = {
|
||||
systemd.services.sshd =
|
||||
{ description = "SSH Daemon";
|
||||
|
||||
description = "OpenSSH server";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
startOn = "started network-interfaces";
|
||||
|
||||
environment = {
|
||||
LD_LIBRARY_PATH = nssModulesPath;
|
||||
# Duplicated from bashrc. OpenSSH needs a patch for this.
|
||||
LOCALE_ARCHIVE = "/run/current-system/sw/lib/locale/locale-archive";
|
||||
};
|
||||
stopIfChanged = false;
|
||||
|
||||
path = [ pkgs.openssh ];
|
||||
|
||||
environment.LD_LIBRARY_PATH = nssModulesPath;
|
||||
environment.LOCALE_ARCHIVE = "/run/current-system/sw/lib/locale/locale-archive";
|
||||
|
||||
preStart =
|
||||
''
|
||||
mkdir -m 0755 -p /etc/ssh
|
||||
@ -284,22 +283,28 @@ in
|
||||
fi
|
||||
'';
|
||||
|
||||
daemonType = "fork";
|
||||
|
||||
exec =
|
||||
''
|
||||
${pkgs.openssh}/sbin/sshd -h ${cfg.hostKeyPath} \
|
||||
-f ${pkgs.writeText "sshd_config" cfg.extraConfig}
|
||||
'';
|
||||
serviceConfig =
|
||||
{ ExecStart =
|
||||
"${pkgs.openssh}/sbin/sshd -h ${cfg.hostKeyPath} " +
|
||||
"-f ${pkgs.writeText "sshd_config" cfg.extraConfig}";
|
||||
Restart = "always";
|
||||
Type = "forking";
|
||||
KillMode = "process";
|
||||
PIDFile = "/run/sshd.pid";
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = cfg.ports;
|
||||
|
||||
security.pam.services = optional cfg.usePAM { name = "sshd"; startSession = true; showMotd = true; };
|
||||
|
||||
services.openssh.authorizedKeysFiles =
|
||||
[ ".ssh/authorized_keys" ".ssh/authorized_keys2" "/etc/ssh/authorized_keys.d/%u" ];
|
||||
|
||||
services.openssh.extraConfig =
|
||||
''
|
||||
PidFile /run/sshd.pid
|
||||
|
||||
Protocol 2
|
||||
|
||||
UsePAM ${if cfg.usePAM then "yes" else "no"}
|
||||
@ -328,11 +333,14 @@ in
|
||||
PasswordAuthentication ${if cfg.passwordAuthentication then "yes" else "no"}
|
||||
ChallengeResponseAuthentication ${if cfg.challengeResponseAuthentication then "yes" else "no"}
|
||||
|
||||
PrintMotd no # handled by pam_motd
|
||||
|
||||
AuthorizedKeysFile ${toString cfg.authorizedKeysFiles}
|
||||
'';
|
||||
|
||||
assertions = [{ assertion = if cfg.forwardX11 then cfgc.setXAuthLocation else true;
|
||||
message = "cannot enable X11 forwarding without setting xauth location";}];
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -45,15 +45,15 @@ in
|
||||
description = ''
|
||||
The interfaces <command>wpa_supplicant</command> will use. If empty, it will
|
||||
automatically use all wireless interfaces. (Note that auto-detection is currently
|
||||
broken on Linux 3.4.x kernels. See http://github.com/NixOS/nixos/issues/10 for
|
||||
further details.)
|
||||
broken on Linux 3.4.x kernels. See http://github.com/NixOS/nixos/issues/10 for
|
||||
further details.)
|
||||
'';
|
||||
};
|
||||
|
||||
driver = mkOption {
|
||||
default = "";
|
||||
example = "nl80211";
|
||||
description = "force a specific wpa_supplicant driver";
|
||||
description = "Force a specific wpa_supplicant driver.";
|
||||
};
|
||||
|
||||
userControlled = {
|
||||
@ -66,7 +66,7 @@ in
|
||||
When you want to use this, make sure ${configFile} doesn't exist.
|
||||
It will be created for you.
|
||||
|
||||
Currently it is also necesarry to explicitly specify networking.wireless.interfaces
|
||||
Currently it is also necessary to explicitly specify networking.wireless.interfaces.
|
||||
'';
|
||||
};
|
||||
|
||||
@ -74,7 +74,7 @@ in
|
||||
default = "wheel";
|
||||
example = "network";
|
||||
type = types.string;
|
||||
description = "members of this group can control wpa_supplicant";
|
||||
description = "Members of this group can control wpa_supplicant.";
|
||||
};
|
||||
};
|
||||
};
|
||||
@ -90,8 +90,10 @@ in
|
||||
services.dbus.packages = [ pkgs.wpa_supplicant ];
|
||||
|
||||
jobs.wpa_supplicant =
|
||||
{ startOn = "started network-interfaces";
|
||||
stopOn = "stopping network-interfaces";
|
||||
{ description = "WPA Supplicant";
|
||||
|
||||
wantedBy = [ "network.target" ];
|
||||
after = [ "systemd-udev-settle.service" ];
|
||||
|
||||
path = [ pkgs.wpa_supplicant ];
|
||||
|
||||
@ -122,7 +124,7 @@ in
|
||||
|
||||
powerManagement.resumeCommands =
|
||||
''
|
||||
${config.system.build.upstart}/sbin/restart wpa_supplicant
|
||||
${config.systemd.package}/bin/systemctl try-restart wpa_supplicant
|
||||
'';
|
||||
|
||||
assertions = [{ assertion = !cfg.userControlled.enable || cfg.interfaces != [];
|
||||
|
@ -118,7 +118,7 @@ in
|
||||
boot.blacklistedKernelModules = [ "usblp" ];
|
||||
|
||||
jobs.cupsd =
|
||||
{ description = "CUPS printing daemon";
|
||||
{ description = "CUPS Printing Daemon";
|
||||
|
||||
startOn = "started network-interfaces";
|
||||
stopOn = "stopping network-interfaces";
|
||||
|
@ -64,7 +64,7 @@ in
|
||||
};
|
||||
|
||||
jobs.atd =
|
||||
{ description = "at daemon (atd)";
|
||||
{ description = "Job Execution Daemon (atd)";
|
||||
|
||||
startOn = "stopped udevtrigger";
|
||||
|
||||
|
@ -86,7 +86,7 @@ in
|
||||
environment.systemPackages = [ cronNixosPkg ];
|
||||
|
||||
jobs.cron =
|
||||
{ description = "Cron daemon";
|
||||
{ description = "Cron Daemon";
|
||||
|
||||
startOn = "startup";
|
||||
|
||||
|
@ -1,146 +0,0 @@
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
with pkgs.lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.cgroups;
|
||||
|
||||
cgconfigConf = pkgs.writeText "cgconfig.conf" cfg.groups;
|
||||
|
||||
cgrulesConf = pkgs.writeText "cgrules.conf" cfg.rules;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
|
||||
###### interface
|
||||
|
||||
options = {
|
||||
|
||||
services.cgroups.enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to enable support for control groups, a Linux kernel
|
||||
feature for resource management. It allows you to assign
|
||||
processes to groups that share certain resource limits (e.g.,
|
||||
CPU or memory). The <command>cgrulesengd</command> daemon
|
||||
automatically assigns processes to the right cgroup depending
|
||||
on the rules defined in
|
||||
<option>services.cgroups.rules</option>.
|
||||
'';
|
||||
};
|
||||
|
||||
services.cgroups.groups = mkOption {
|
||||
type = types.string;
|
||||
default =
|
||||
''
|
||||
mount {
|
||||
cpu = /sys/fs/cgroup/cpu;
|
||||
}
|
||||
'';
|
||||
example =
|
||||
''
|
||||
mount {
|
||||
cpu = /sys/fs/cgroup/cpu;
|
||||
cpuacct = /sys/fs/cgroup/cpuacct;
|
||||
}
|
||||
|
||||
# Create a "www" cgroup with a lower share of the CPU (the
|
||||
# default is 1024).
|
||||
group www {
|
||||
cpu {
|
||||
cpu.shares = "500";
|
||||
}
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
The contents of the <filename>cgconfig.conf</filename>
|
||||
configuration file, which defines the cgroups.
|
||||
'';
|
||||
};
|
||||
|
||||
services.cgroups.rules = mkOption {
|
||||
type = types.string;
|
||||
default = "";
|
||||
example =
|
||||
''
|
||||
# All processes executed by the "wwwrun" uid should be
|
||||
# assigned to the "www" CPU cgroup.
|
||||
wwwrun cpu www
|
||||
'';
|
||||
description = ''
|
||||
The contents of the <filename>cgrules.conf</filename>
|
||||
configuration file, which determines to which cgroups
|
||||
processes should be assigned by the
|
||||
<command>cgrulesengd</command> daemon.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
environment.systemPackages = [ pkgs.libcgroup ];
|
||||
|
||||
environment.etc =
|
||||
[ { source = cgconfigConf;
|
||||
target = "cgconfig.conf";
|
||||
}
|
||||
{ source = cgrulesConf;
|
||||
target = "cgrules.conf";
|
||||
}
|
||||
];
|
||||
|
||||
# The daemon requires the userspace<->kernelspace netlink
|
||||
# connector.
|
||||
boot.kernelModules = [ "cn" ];
|
||||
|
||||
jobs.cgroups =
|
||||
{ startOn = "startup";
|
||||
|
||||
description = "Control groups daemon";
|
||||
|
||||
path = [ pkgs.libcgroup pkgs.procps pkgs.utillinux ];
|
||||
|
||||
preStart =
|
||||
''
|
||||
if [ -d /sys/fs/cgroup ]; then
|
||||
if ! mountpoint -q /sys/fs/cgroup; then
|
||||
mount -t tmpfs -o mode=755 /dev/cgroup /sys/fs/cgroup
|
||||
fi
|
||||
fi
|
||||
|
||||
cgclear || true
|
||||
|
||||
# Mount the cgroup hierarchies. Note: we refer to the
|
||||
# store path of cgconfig.conf here to ensure that the job
|
||||
# gets reloaded if the configuration changes.
|
||||
cgconfigparser -l ${cgconfigConf}
|
||||
|
||||
# Move existing processes to the right cgroup.
|
||||
cgclassify --cancel-sticky $(ps --no-headers -eL o tid) || true
|
||||
|
||||
# Force a restart if the rules change:
|
||||
# ${cgrulesConf}
|
||||
'';
|
||||
|
||||
# Run the daemon that moves new processes to the right cgroup.
|
||||
exec = "cgrulesengd";
|
||||
|
||||
daemonType = "fork";
|
||||
|
||||
postStop =
|
||||
''
|
||||
cgclear
|
||||
'';
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -116,6 +116,33 @@ in
|
||||
gid = config.ids.gids.messagebus;
|
||||
};
|
||||
|
||||
# FIXME: these are copied verbatim from the dbus source tree. We
|
||||
# should install and use the originals.
|
||||
systemd.units."dbus.socket".text =
|
||||
''
|
||||
[Unit]
|
||||
Description=D-Bus System Message Bus Socket
|
||||
|
||||
[Socket]
|
||||
ListenStream=/var/run/dbus/system_bus_socket
|
||||
'';
|
||||
|
||||
systemd.units."dbus.service".text =
|
||||
''
|
||||
[Unit]
|
||||
Description=D-Bus System Message Bus
|
||||
Requires=dbus.socket
|
||||
After=syslog.target
|
||||
|
||||
[Service]
|
||||
ExecStartPre=${pkgs.dbus_tools}/bin/dbus-uuidgen --ensure
|
||||
ExecStartPre=-${pkgs.coreutils}/bin/rm -f /var/run/dbus/pid
|
||||
ExecStart=${pkgs.dbus_daemon}/bin/dbus-daemon --system --address=systemd: --nofork --systemd-activation
|
||||
ExecReload=${pkgs.dbus_tools}/bin/dbus-send --print-reply --system --type=method_call --dest=org.freedesktop.DBus / org.freedesktop.DBus.ReloadConfig
|
||||
OOMScoreAdjust=-900
|
||||
'';
|
||||
|
||||
/*
|
||||
jobs.dbus =
|
||||
{ startOn = "started udev and started syslogd";
|
||||
|
||||
@ -138,15 +165,6 @@ in
|
||||
|
||||
exec = "dbus-daemon --system";
|
||||
|
||||
/*
|
||||
postStart =
|
||||
''
|
||||
# Signal Upstart to connect to the system bus. This
|
||||
# allows ‘initctl’ to work for non-root users.
|
||||
kill -USR1 1
|
||||
'';
|
||||
*/
|
||||
|
||||
postStop =
|
||||
''
|
||||
# !!! Hack: doesn't belong here.
|
||||
@ -157,6 +175,7 @@ in
|
||||
fi
|
||||
'';
|
||||
};
|
||||
*/
|
||||
|
||||
security.setuidOwners = singleton
|
||||
{ program = "dbus-daemon-launch-helper";
|
||||
|
@ -20,15 +20,14 @@ in
|
||||
|
||||
enable = mkOption {
|
||||
default = true;
|
||||
description = "
|
||||
Whether to enable the Name Service Cache Daemon.
|
||||
";
|
||||
description = "Whether to enable the Name Service Cache Daemon.";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf config.services.nscd.enable {
|
||||
@ -39,37 +38,31 @@ in
|
||||
description = "Name service cache daemon user";
|
||||
};
|
||||
|
||||
jobs.nscd =
|
||||
systemd.services.nscd =
|
||||
{ description = "Name Service Cache Daemon";
|
||||
|
||||
startOn = "startup";
|
||||
wantedBy = [ "nss-lookup.target" "nss-user-lookup.target" ];
|
||||
|
||||
environment = { LD_LIBRARY_PATH = nssModulesPath; };
|
||||
|
||||
preStart =
|
||||
''
|
||||
mkdir -m 0755 -p /var/run/nscd
|
||||
mkdir -m 0755 -p /run/nscd
|
||||
rm -f /run/nscd/nscd.pid
|
||||
mkdir -m 0755 -p /var/db/nscd
|
||||
'';
|
||||
|
||||
path = [ pkgs.glibc ];
|
||||
|
||||
exec = "nscd -f ${./nscd.conf} -d 2> /dev/null";
|
||||
};
|
||||
|
||||
# Flush nscd's ‘hosts’ database when the network comes up or the
|
||||
# system configuration changes to get rid of any negative entries.
|
||||
jobs.invalidate_nscd =
|
||||
{ name = "invalidate-nscd";
|
||||
description = "Invalidate NSCD cache";
|
||||
startOn = "ip-up or config-changed";
|
||||
task = true;
|
||||
path = [ pkgs.glibc ];
|
||||
script = ''
|
||||
nscd --invalidate=passwd
|
||||
nscd --invalidate=group
|
||||
nscd --invalidate=hosts
|
||||
'';
|
||||
serviceConfig =
|
||||
{ ExecStart = "@${pkgs.glibc}/sbin/nscd nscd -f ${./nscd.conf}";
|
||||
Type = "forking";
|
||||
PIDFile = "/run/nscd/nscd.pid";
|
||||
Restart = "always";
|
||||
ExecReload =
|
||||
[ "${pkgs.glibc}/sbin/nscd --invalidate passwd"
|
||||
"${pkgs.glibc}/sbin/nscd --invalidate group"
|
||||
"${pkgs.glibc}/sbin/nscd --invalidate hosts"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
127
modules/services/ttys/agetty.nix
Normal file
127
modules/services/ttys/agetty.nix
Normal file
@ -0,0 +1,127 @@
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
with pkgs.lib;
|
||||
|
||||
{
|
||||
|
||||
###### interface
|
||||
|
||||
options = {
|
||||
|
||||
services.mingetty = {
|
||||
|
||||
greetingLine = mkOption {
|
||||
default = ''<<< Welcome to NixOS ${config.system.nixosVersion} (\m) - \l >>>'';
|
||||
description = ''
|
||||
Welcome line printed by mingetty.
|
||||
'';
|
||||
};
|
||||
|
||||
helpLine = mkOption {
|
||||
default = "";
|
||||
description = ''
|
||||
Help line printed by mingetty below the welcome line.
|
||||
Used by the installation CD to give some hints on
|
||||
how to proceed.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
###### implementation
|
||||
|
||||
config = {
|
||||
|
||||
# FIXME: these are mostly copy/pasted from the systemd sources,
|
||||
# which some small modifications, which is annoying.
|
||||
|
||||
# Generate a separate job for each tty.
|
||||
systemd.units."getty@.service".text =
|
||||
''
|
||||
[Unit]
|
||||
Description=Getty on %I
|
||||
Documentation=man:agetty(8)
|
||||
After=systemd-user-sessions.service plymouth-quit-wait.service
|
||||
|
||||
# If additional gettys are spawned during boot then we should make
|
||||
# sure that this is synchronized before getty.target, even though
|
||||
# getty.target didn't actually pull it in.
|
||||
Before=getty.target
|
||||
IgnoreOnIsolate=yes
|
||||
|
||||
ConditionPathExists=/dev/tty0
|
||||
|
||||
[Service]
|
||||
Environment=TERM=linux
|
||||
Environment=LOCALE_ARCHIVE=/run/current-system/sw/lib/locale/locale-archive
|
||||
ExecStart=@${pkgs.utillinux}/sbin/agetty agetty --noclear --login-program ${pkgs.shadow}/bin/login %I 38400
|
||||
Type=idle
|
||||
Restart=always
|
||||
RestartSec=0
|
||||
UtmpIdentifier=%I
|
||||
TTYPath=/dev/%I
|
||||
TTYReset=yes
|
||||
TTYVHangup=yes
|
||||
TTYVTDisallocate=yes # set to no to prevent clearing the screen
|
||||
KillMode=process
|
||||
IgnoreSIGPIPE=no
|
||||
|
||||
# Some login implementations ignore SIGTERM, so we send SIGHUP
|
||||
# instead, to ensure that login terminates cleanly.
|
||||
KillSignal=SIGHUP
|
||||
|
||||
X-RestartIfChanged=false
|
||||
'';
|
||||
|
||||
systemd.units."serial-getty@.service".text =
|
||||
''
|
||||
[Unit]
|
||||
Description=Serial Getty on %I
|
||||
Documentation=man:agetty(8) man:systemd-getty-generator(8)
|
||||
BindsTo=dev-%i.device
|
||||
After=dev-%i.device systemd-user-sessions.service plymouth-quit-wait.service
|
||||
|
||||
# If additional gettys are spawned during boot then we should make
|
||||
# sure that this is synchronized before getty.target, even though
|
||||
# getty.target didn't actually pull it in.
|
||||
Before=getty.target
|
||||
IgnoreOnIsolate=yes
|
||||
|
||||
[Service]
|
||||
Environment=TERM=linux
|
||||
Environment=LOCALE_ARCHIVE=/run/current-system/sw/lib/locale/locale-archive
|
||||
ExecStart=@${pkgs.utillinux}/sbin/agetty agetty --login-program ${pkgs.shadow}/bin/login %I 115200,38400,9600
|
||||
Type=idle
|
||||
Restart=always
|
||||
RestartSec=0
|
||||
UtmpIdentifier=%I
|
||||
TTYPath=/dev/%I
|
||||
TTYReset=yes
|
||||
TTYVHangup=yes
|
||||
KillMode=process
|
||||
IgnoreSIGPIPE=no
|
||||
|
||||
# Some login implementations ignore SIGTERM, so we send SIGHUP
|
||||
# instead, to ensure that login terminates cleanly.
|
||||
KillSignal=SIGHUP
|
||||
|
||||
X-RestartIfChanged=false
|
||||
'';
|
||||
|
||||
environment.etc = singleton
|
||||
{ # Friendly greeting on the virtual consoles.
|
||||
source = pkgs.writeText "issue" ''
|
||||
|
||||
[1;32m${config.services.mingetty.greetingLine}[0m
|
||||
${config.services.mingetty.helpLine}
|
||||
|
||||
'';
|
||||
target = "issue";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -1,90 +0,0 @@
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
with pkgs.lib;
|
||||
|
||||
{
|
||||
|
||||
###### interface
|
||||
|
||||
options = {
|
||||
|
||||
services.mingetty = {
|
||||
|
||||
ttys = mkOption {
|
||||
default =
|
||||
if pkgs.stdenv.isArm
|
||||
then [ "ttyS0" ] # presumably an embedded platform such as a plug
|
||||
else [ "tty1" "tty2" "tty3" "tty4" "tty5" "tty6" ];
|
||||
description = ''
|
||||
The list of tty devices on which to start a login prompt.
|
||||
'';
|
||||
};
|
||||
|
||||
waitOnMounts = mkOption {
|
||||
default = false;
|
||||
description = ''
|
||||
Whether the login prompts on the virtual consoles will be
|
||||
started before or after all file systems have been mounted. By
|
||||
default we don't wait, but if for example your /home is on a
|
||||
separate partition, you may want to turn this on.
|
||||
'';
|
||||
};
|
||||
|
||||
greetingLine = mkOption {
|
||||
default = ''<<< Welcome to NixOS ${config.system.nixosVersion} (\m) - \l >>>'';
|
||||
description = ''
|
||||
Welcome line printed by mingetty.
|
||||
'';
|
||||
};
|
||||
|
||||
helpLine = mkOption {
|
||||
default = "";
|
||||
description = ''
|
||||
Help line printed by mingetty below the welcome line.
|
||||
Used by the installation CD to give some hints on
|
||||
how to proceed.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
###### implementation
|
||||
|
||||
config = {
|
||||
|
||||
# Generate a separate job for each tty.
|
||||
jobs = listToAttrs (map (tty: nameValuePair tty {
|
||||
|
||||
startOn =
|
||||
# On tty1 we should always wait for mountall, since it may
|
||||
# start an emergency-shell job.
|
||||
if config.services.mingetty.waitOnMounts || tty == "tty1"
|
||||
then "stopped udevtrigger and filesystem"
|
||||
else "stopped udevtrigger"; # !!! should start as soon as the tty device is created
|
||||
|
||||
path = [ pkgs.mingetty ];
|
||||
|
||||
exec = "mingetty --loginprog=${pkgs.shadow}/bin/login --noclear ${tty}";
|
||||
|
||||
restartIfChanged = false;
|
||||
|
||||
environment.LOCALE_ARCHIVE = "/run/current-system/sw/lib/locale/locale-archive";
|
||||
|
||||
}) config.services.mingetty.ttys);
|
||||
|
||||
environment.etc = singleton
|
||||
{ # Friendly greeting on the virtual consoles.
|
||||
source = pkgs.writeText "issue" ''
|
||||
|
||||
[1;32m${config.services.mingetty.greetingLine}[0m
|
||||
${config.services.mingetty.helpLine}
|
||||
|
||||
'';
|
||||
target = "issue";
|
||||
};
|
||||
};
|
||||
|
||||
}
|
@ -601,26 +601,12 @@ in
|
||||
date.timezone = "${config.time.timeZone}"
|
||||
'';
|
||||
|
||||
jobs.httpd =
|
||||
{ # Statically verify the syntactic correctness of the generated
|
||||
# httpd.conf. !!! this is impure! It doesn't just check for
|
||||
# syntax, but also whether the Apache user/group exist,
|
||||
# whether SSL keys exist, etc.
|
||||
buildHook =
|
||||
''
|
||||
echo
|
||||
echo '=== Checking the generated Apache configuration file ==='
|
||||
${httpd}/bin/httpd -f ${httpdConf} -t || true
|
||||
'';
|
||||
systemd.services.httpd =
|
||||
{ description = "Apache HTTPD";
|
||||
|
||||
description = "Apache HTTPD";
|
||||
|
||||
startOn = "started networking and filesystem"
|
||||
# Hacky. Some subservices depend on Postgres
|
||||
# (e.g. Mediawiki), but they don't have a way to declare
|
||||
# that dependency. So just start httpd after postgresql if
|
||||
# the latter is enabled.
|
||||
+ optionalString config.services.postgresql.enable " and started postgresql";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
requires = [ "keys.target" ];
|
||||
after = [ "network.target" "fs.target" "postgresql.service" "keys.target" ];
|
||||
|
||||
path =
|
||||
[ httpd pkgs.coreutils pkgs.gnugrep ]
|
||||
@ -632,9 +618,7 @@ in
|
||||
|
||||
environment =
|
||||
{ PHPRC = if enablePHP then phpIni else "";
|
||||
|
||||
TZ = config.time.timeZone;
|
||||
|
||||
} // (listToAttrs (concatMap (svc: svc.globalEnvVars) allSubservices));
|
||||
|
||||
preStart =
|
||||
@ -668,12 +652,9 @@ in
|
||||
done
|
||||
'';
|
||||
|
||||
exec = "httpd -f ${httpdConf} -DNO_DETACH";
|
||||
|
||||
preStop =
|
||||
''
|
||||
${httpd}/bin/httpd -f ${httpdConf} -k graceful-stop
|
||||
'';
|
||||
serviceConfig.ExecStart = "@${httpd}/bin/httpd httpd -f ${httpdConf} -DNO_DETACH";
|
||||
serviceConfig.ExecStop = "${httpd}/bin/httpd -f ${httpdConf} -k graceful-stop";
|
||||
serviceConfig.Restart = "always";
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -158,7 +158,7 @@ in
|
||||
services.udisks.enable = true;
|
||||
services.upower = mkIf config.powerManagement.enable { enable = true; };
|
||||
|
||||
security.pam.services = [ { name = "kde"; allowNullPassword = true; } ];
|
||||
security.pam.services = [ { name = "kde"; allowNullPassword = true; startSession = true; } ];
|
||||
|
||||
};
|
||||
|
||||
|
@ -41,16 +41,11 @@ in
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
services.xserver.displayManager.slim.enable = false;
|
||||
|
||||
services.xserver.displayManager.job =
|
||||
{ execCmd =
|
||||
''
|
||||
exec ${pkgs.xorg.xinit}/bin/xinit \
|
||||
${pkgs.su}/bin/su -c ${dmcfg.session.script} ${cfg.user} \
|
||||
-- ${dmcfg.xserverBin} ${dmcfg.xserverArgs}
|
||||
'';
|
||||
};
|
||||
services.xserver.displayManager.slim = {
|
||||
enable = true;
|
||||
autoLogin = true;
|
||||
defaultUser = cfg.user;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
@ -21,6 +21,7 @@ let
|
||||
''
|
||||
#! /bin/sh
|
||||
|
||||
. /etc/profile
|
||||
cd "$HOME"
|
||||
|
||||
# The first argument of this script is the session type.
|
||||
@ -31,6 +32,13 @@ let
|
||||
exec > ~/.xsession-errors 2>&1
|
||||
''}
|
||||
|
||||
# Stop systemd from handling the power button and lid switch,
|
||||
# since presumably the desktop environment will handle these.
|
||||
if [ -z "$_INHIBITION_LOCK_TAKEN" ]; then
|
||||
export _INHIBITION_LOCK_TAKEN=1
|
||||
exec ${config.systemd.package}/bin/systemd-inhibit --what=handle-lid-switch:handle-power-key "$0" "$sessionType"
|
||||
fi
|
||||
|
||||
${optionalString cfg.startOpenSSHAgent ''
|
||||
if test -z "$SSH_AUTH_SOCK"; then
|
||||
# Restart this script as a child of the SSH agent. (It is
|
||||
@ -53,12 +61,6 @@ let
|
||||
fi
|
||||
''}
|
||||
|
||||
# Start a ConsoleKit session so that we get ownership of various
|
||||
# devices.
|
||||
if test -z "$XDG_SESSION_COOKIE"; then
|
||||
exec ${pkgs.consolekit}/bin/ck-launch-session "$0" "$sessionType"
|
||||
fi
|
||||
|
||||
# Handle being called by kdm.
|
||||
if test "''${1:0:1}" = /; then eval exec "$1"; fi
|
||||
|
||||
|
@ -12,8 +12,8 @@ let
|
||||
defaultConfig =
|
||||
''
|
||||
[Shutdown]
|
||||
HaltCmd=${config.system.build.upstart}/sbin/halt
|
||||
RebootCmd=${config.system.build.upstart}/sbin/reboot
|
||||
HaltCmd=${config.systemd.package}/sbin/shutdown -h now
|
||||
RebootCmd=${config.systemd.package}/sbin/shutdown -r now
|
||||
${optionalString (config.system.boot.loader.id == "grub") ''
|
||||
BootManager=${if config.boot.loader.grub.version == 2 then "Grub2" else "Grub"}
|
||||
''}
|
||||
@ -111,7 +111,7 @@ in
|
||||
logsXsession = true;
|
||||
};
|
||||
|
||||
security.pam.services = [ { name = "kde"; allowNullPassword = true; } ];
|
||||
security.pam.services = [ { name = "kde"; allowNullPassword = true; startSession = true; } ];
|
||||
|
||||
users.extraUsers = singleton
|
||||
{ name = "kdm";
|
||||
|
@ -14,10 +14,9 @@ let
|
||||
xserver_arguments ${dmcfg.xserverArgs}
|
||||
sessions ${pkgs.lib.concatStringsSep "," (dmcfg.session.names ++ ["custom"])}
|
||||
login_cmd exec ${pkgs.stdenv.shell} ${dmcfg.session.script} "%session"
|
||||
halt_cmd ${config.system.build.upstart}/sbin/shutdown -h now
|
||||
reboot_cmd ${config.system.build.upstart}/sbin/shutdown -r now
|
||||
halt_cmd ${config.systemd.package}/sbin/shutdown -h now
|
||||
reboot_cmd ${config.systemd.package}/sbin/shutdown -r now
|
||||
${optionalString (cfg.defaultUser != "") ("default_user " + cfg.defaultUser)}
|
||||
${optionalString cfg.hideCursor "hidecursor true"}
|
||||
${optionalString cfg.autoLogin "auto_login yes"}
|
||||
'';
|
||||
|
||||
@ -76,14 +75,6 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
hideCursor = mkOption {
|
||||
default = false;
|
||||
example = true;
|
||||
description = ''
|
||||
Hide the mouse cursor on the login screen.
|
||||
'';
|
||||
};
|
||||
|
||||
autoLogin = mkOption {
|
||||
default = false;
|
||||
example = true;
|
||||
@ -115,7 +106,7 @@ in
|
||||
|
||||
# Allow null passwords so that the user can login as root on the
|
||||
# installation CD.
|
||||
security.pam.services = [ { name = "slim"; allowNullPassword = true; } ];
|
||||
security.pam.services = [ { name = "slim"; allowNullPassword = true; startSession = true; } ];
|
||||
|
||||
};
|
||||
|
||||
|
@ -434,15 +434,14 @@ in
|
||||
environment.pathsToLink =
|
||||
[ "/etc/xdg" "/share/xdg" "/share/applications" "/share/icons" "/share/pixmaps" ];
|
||||
|
||||
jobs."xserver-start-check" =
|
||||
{ startOn = if cfg.autorun then "filesystem and stopped udevtrigger" else "";
|
||||
stopOn = "";
|
||||
task = true;
|
||||
script = "grep -qv noX11 /proc/cmdline && start xserver || true";
|
||||
};
|
||||
systemd.defaultUnit = mkIf cfg.autorun "graphical.target";
|
||||
|
||||
jobs.xserver =
|
||||
{ restartIfChanged = false;
|
||||
systemd.services."display-manager" =
|
||||
{ description = "X11 Server";
|
||||
|
||||
after = [ "systemd-udev-settle.service" "local-fs.target" ];
|
||||
|
||||
restartIfChanged = false;
|
||||
|
||||
environment =
|
||||
{ FONTCONFIG_FILE = "/etc/fonts/fonts.conf"; # !!! cleanup
|
||||
|
@ -116,9 +116,8 @@ in
|
||||
# jobs. Used to determine which jobs need to be restarted
|
||||
# when switching to a new configuration.
|
||||
mkdir -m 0700 -p /var/run/upstart-jobs
|
||||
|
||||
|
||||
mkdir -m 0755 -p /var/log
|
||||
mkdir -m 0755 -p /var/log/upstart
|
||||
|
||||
touch /var/log/wtmp # must exist
|
||||
chmod 644 /var/log/wtmp
|
||||
@ -146,9 +145,9 @@ in
|
||||
|
||||
system.activationScripts.tmpfs =
|
||||
''
|
||||
${pkgs.utillinux}/bin/mount -o "remount,size=${config.boot.devSize}" /dev
|
||||
${pkgs.utillinux}/bin/mount -o "remount,size=${config.boot.devShmSize}" /dev/shm
|
||||
${pkgs.utillinux}/bin/mount -o "remount,size=${config.boot.runSize}" /run
|
||||
${pkgs.utillinux}/bin/mount -o "remount,size=${config.boot.devSize}" none /dev
|
||||
${pkgs.utillinux}/bin/mount -o "remount,size=${config.boot.devShmSize}" none /dev/shm
|
||||
${pkgs.utillinux}/bin/mount -o "remount,size=${config.boot.runSize}" none /run
|
||||
'';
|
||||
|
||||
};
|
||||
|
345
modules/system/activation/switch-to-configuration.pl
Normal file
345
modules/system/activation/switch-to-configuration.pl
Normal file
@ -0,0 +1,345 @@
|
||||
#! @perl@
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use File::Basename;
|
||||
use File::Slurp;
|
||||
use Cwd 'abs_path';
|
||||
|
||||
my $startListFile = "/run/systemd/start-list";
|
||||
my $restartListFile = "/run/systemd/restart-list";
|
||||
my $reloadListFile = "/run/systemd/reload-list";
|
||||
|
||||
my $action = shift @ARGV;
|
||||
|
||||
if (!defined $action || ($action ne "switch" && $action ne "boot" && $action ne "test")) {
|
||||
print STDERR <<EOF;
|
||||
Usage: $0 [switch|boot|test]
|
||||
|
||||
switch: make the configuration the boot default and activate now
|
||||
boot: make the configuration the boot default
|
||||
test: activate the configuration, but don\'t make it the boot default
|
||||
EOF
|
||||
exit 1;
|
||||
}
|
||||
|
||||
die "This is not a NixOS installation (/etc/NIXOS is missing)!\n" unless -f "/etc/NIXOS";
|
||||
|
||||
# Install or update the bootloader.
|
||||
if ($action eq "switch" || $action eq "boot") {
|
||||
system("@installBootLoader@ @out@") == 0 or exit 1;
|
||||
exit 0 if $action eq "boot";
|
||||
}
|
||||
|
||||
# Check if we can activate the new configuration.
|
||||
my $oldVersion = read_file("/run/current-system/init-interface-version", err_mode => 'quiet') // "";
|
||||
my $newVersion = read_file("@out@/init-interface-version");
|
||||
|
||||
if ($newVersion ne $oldVersion) {
|
||||
print STDERR <<EOF;
|
||||
Warning: the new NixOS configuration has an ‘init’ that is
|
||||
incompatible with the current configuration. The new configuration
|
||||
won\'t take effect until you reboot the system.
|
||||
EOF
|
||||
exit 100;
|
||||
}
|
||||
|
||||
# Ignore SIGHUP so that we're not killed if we're running on (say)
|
||||
# virtual console 1 and we restart the "tty1" unit.
|
||||
$SIG{PIPE} = "IGNORE";
|
||||
|
||||
sub getActiveUnits {
|
||||
# FIXME: use D-Bus or whatever to query this, since parsing the
|
||||
# output of list-units is likely to break.
|
||||
my $lines = `@systemd@/bin/systemctl list-units --full`;
|
||||
my $res = {};
|
||||
foreach my $line (split '\n', $lines) {
|
||||
chomp $line;
|
||||
last if $line eq "";
|
||||
$line =~ /^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s/ or next;
|
||||
next if $1 eq "UNIT";
|
||||
$res->{$1} = { load => $2, state => $3, substate => $4 };
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
sub parseFstab {
|
||||
my ($filename) = @_;
|
||||
my ($fss, $swaps);
|
||||
foreach my $line (read_file($filename, err_mode => 'quiet')) {
|
||||
chomp $line;
|
||||
$line =~ s/#.*//;
|
||||
next if $line =~ /^\s*$/;
|
||||
my @xs = split / /, $line;
|
||||
if ($xs[2] eq "swap") {
|
||||
$swaps->{$xs[0]} = { options => $xs[3] // "" };
|
||||
} else {
|
||||
$fss->{$xs[1]} = { device => $xs[0], fsType => $xs[2], options => $xs[3] // "" };
|
||||
}
|
||||
}
|
||||
return ($fss, $swaps);
|
||||
}
|
||||
|
||||
sub parseUnit {
|
||||
my ($filename) = @_;
|
||||
my $info = {};
|
||||
foreach my $line (read_file($filename)) {
|
||||
# FIXME: not quite correct.
|
||||
$line =~ /^([^=]+)=(.*)$/ or next;
|
||||
$info->{$1} = $2;
|
||||
}
|
||||
return $info;
|
||||
}
|
||||
|
||||
sub boolIsTrue {
|
||||
my ($s) = @_;
|
||||
return $s eq "yes" || $s eq "true";
|
||||
}
|
||||
|
||||
# Stop all services that no longer exist or have changed in the new
|
||||
# configuration.
|
||||
my (@unitsToStop, @unitsToSkip);
|
||||
my $activePrev = getActiveUnits;
|
||||
while (my ($unit, $state) = each %{$activePrev}) {
|
||||
my $baseUnit = $unit;
|
||||
|
||||
# Recognise template instances.
|
||||
$baseUnit = "$1\@.$2" if $unit =~ /^(.*)@[^\.]*\.(.*)$/;
|
||||
my $prevUnitFile = "/etc/systemd/system/$baseUnit";
|
||||
my $newUnitFile = "@out@/etc/systemd/system/$baseUnit";
|
||||
|
||||
my $baseName = $baseUnit;
|
||||
$baseName =~ s/\.[a-z]*$//;
|
||||
|
||||
if (-e $prevUnitFile && ($state->{state} eq "active" || $state->{state} eq "activating")) {
|
||||
if (! -e $newUnitFile) {
|
||||
push @unitsToStop, $unit;
|
||||
}
|
||||
|
||||
elsif ($unit =~ /\.target$/) {
|
||||
my $unitInfo = parseUnit($newUnitFile);
|
||||
|
||||
# Cause all active target units to be restarted below.
|
||||
# This should start most changed units we stop here as
|
||||
# well as any new dependencies (including new mounts and
|
||||
# swap devices). FIXME: the suspend target is sometimes
|
||||
# active after the system has resumed, which probably
|
||||
# should not be the case. Just ignore it.
|
||||
if ($unit ne "suspend.target" && $unit ne "hibernate.target") {
|
||||
unless (boolIsTrue($unitInfo->{'RefuseManualStart'} // "no")) {
|
||||
write_file($startListFile, { append => 1 }, "$unit\n");
|
||||
}
|
||||
}
|
||||
|
||||
# Stop targets that have X-StopOnReconfiguration set.
|
||||
# This is necessary to respect dependency orderings
|
||||
# involving targets: if unit X starts after target Y and
|
||||
# target Y starts after unit Z, then if X and Z have both
|
||||
# changed, then X should be restarted after Z. However,
|
||||
# if target Y is in the "active" state, X and Z will be
|
||||
# restarted at the same time because X's dependency on Y
|
||||
# is already satisfied. Thus, we need to stop Y first.
|
||||
# Stopping a target generally has no effect on other units
|
||||
# (unless there is a PartOf dependency), so this is just a
|
||||
# bookkeeping thing to get systemd to do the right thing.
|
||||
if (boolIsTrue($unitInfo->{'X-StopOnReconfiguration'} // "no")) {
|
||||
push @unitsToStop, $unit;
|
||||
}
|
||||
}
|
||||
|
||||
elsif (abs_path($prevUnitFile) ne abs_path($newUnitFile)) {
|
||||
if ($unit eq "sysinit.target" || $unit eq "basic.target" || $unit eq "multi-user.target" || $unit eq "graphical.target") {
|
||||
# Do nothing. These cannot be restarted directly.
|
||||
} elsif ($unit =~ /\.mount$/) {
|
||||
# Reload the changed mount unit to force a remount.
|
||||
write_file($reloadListFile, { append => 1 }, "$unit\n");
|
||||
} elsif ($unit =~ /\.socket$/ || $unit =~ /\.path$/) {
|
||||
# FIXME: do something?
|
||||
} else {
|
||||
my $unitInfo = parseUnit($newUnitFile);
|
||||
if (!boolIsTrue($unitInfo->{'X-RestartIfChanged'} // "yes")) {
|
||||
push @unitsToSkip, $unit;
|
||||
} else {
|
||||
# If this unit is socket-activated, then stop the
|
||||
# socket unit(s) as well, and restart the
|
||||
# socket(s) instead of the service.
|
||||
my $socketActivated = 0;
|
||||
if ($unit =~ /\.service$/) {
|
||||
my @sockets = split / /, ($unitInfo->{Sockets} // "");
|
||||
if (scalar @sockets == 0) {
|
||||
@sockets = ("$baseName.socket");
|
||||
}
|
||||
foreach my $socket (@sockets) {
|
||||
if (defined $activePrev->{$socket}) {
|
||||
push @unitsToStop, $socket;
|
||||
write_file($startListFile, { append => 1 }, "$socket\n");
|
||||
$socketActivated = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!boolIsTrue($unitInfo->{'X-StopIfChanged'} // "yes")) {
|
||||
|
||||
# This unit should be restarted instead of
|
||||
# stopped and started.
|
||||
write_file($restartListFile, { append => 1 }, "$unit\n");
|
||||
|
||||
} else {
|
||||
|
||||
# If the unit is not socket-activated, record
|
||||
# that this unit needs to be started below.
|
||||
# We write this to a file to ensure that the
|
||||
# service gets restarted if we're interrupted.
|
||||
if (!$socketActivated) {
|
||||
write_file($startListFile, { append => 1 }, "$unit\n");
|
||||
}
|
||||
|
||||
push @unitsToStop, $unit;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub pathToUnitName {
|
||||
my ($path) = @_;
|
||||
die unless substr($path, 0, 1) eq "/";
|
||||
return "-" if $path eq "/";
|
||||
$path = substr($path, 1);
|
||||
$path =~ s/\//-/g;
|
||||
# FIXME: handle - and unprintable characters.
|
||||
return $path;
|
||||
}
|
||||
|
||||
sub unique {
|
||||
my %seen;
|
||||
my @res;
|
||||
foreach my $name (@_) {
|
||||
next if $seen{$name};
|
||||
$seen{$name} = 1;
|
||||
push @res, $name;
|
||||
}
|
||||
return @res;
|
||||
}
|
||||
|
||||
# Compare the previous and new fstab to figure out which filesystems
|
||||
# need a remount or need to be unmounted. New filesystems are mounted
|
||||
# automatically by starting local-fs.target. FIXME: might be nicer if
|
||||
# we generated units for all mounts; then we could unify this with the
|
||||
# unit checking code above.
|
||||
my ($prevFss, $prevSwaps) = parseFstab "/etc/fstab";
|
||||
my ($newFss, $newSwaps) = parseFstab "@out@/etc/fstab";
|
||||
foreach my $mountPoint (keys %$prevFss) {
|
||||
my $prev = $prevFss->{$mountPoint};
|
||||
my $new = $newFss->{$mountPoint};
|
||||
my $unit = pathToUnitName($mountPoint) . ".mount";
|
||||
if (!defined $new) {
|
||||
# Filesystem entry disappeared, so unmount it.
|
||||
push @unitsToStop, $unit;
|
||||
} elsif ($prev->{fsType} ne $new->{fsType} || $prev->{device} ne $new->{device}) {
|
||||
# Filesystem type or device changed, so unmount and mount it.
|
||||
write_file($startListFile, { append => 1 }, "$unit\n");
|
||||
push @unitsToStop, $unit;
|
||||
} elsif ($prev->{options} ne $new->{options}) {
|
||||
# Mount options changes, so remount it.
|
||||
write_file($reloadListFile, { append => 1 }, "$unit\n");
|
||||
}
|
||||
}
|
||||
|
||||
# Also handles swap devices.
|
||||
foreach my $device (keys %$prevSwaps) {
|
||||
my $prev = $prevSwaps->{$device};
|
||||
my $new = $newSwaps->{$device};
|
||||
if (!defined $new) {
|
||||
# Swap entry disappeared, so turn it off. Can't use
|
||||
# "systemctl stop" here because systemd has lots of alias
|
||||
# units that prevent a stop from actually calling
|
||||
# "swapoff".
|
||||
print STDERR "stopping swap device: $device\n";
|
||||
system("@utillinux@/sbin/swapoff", $device);
|
||||
}
|
||||
# FIXME: update swap options (i.e. its priority).
|
||||
}
|
||||
|
||||
if (scalar @unitsToStop > 0) {
|
||||
@unitsToStop = unique(@unitsToStop);
|
||||
print STDERR "stopping the following units: ", join(", ", sort(@unitsToStop)), "\n";
|
||||
system("@systemd@/bin/systemctl", "stop", "--", @unitsToStop); # FIXME: ignore errors?
|
||||
}
|
||||
|
||||
print STDERR "NOT restarting the following units: ", join(", ", sort(@unitsToSkip)), "\n"
|
||||
if scalar @unitsToSkip > 0;
|
||||
|
||||
# Activate the new configuration (i.e., update /etc, make accounts,
|
||||
# and so on).
|
||||
my $res = 0;
|
||||
print STDERR "activating the configuration...\n";
|
||||
system("@out@/activate", "@out@") == 0 or $res = 2;
|
||||
|
||||
# Restart systemd if necessary.
|
||||
if (abs_path("/proc/1/exe") ne abs_path("@systemd@/lib/systemd/systemd")) {
|
||||
print STDERR "restarting systemd...\n";
|
||||
system("@systemd@/bin/systemctl", "daemon-reexec") == 0 or $res = 2;
|
||||
}
|
||||
|
||||
# Forget about previously failed services.
|
||||
system("@systemd@/bin/systemctl", "reset-failed");
|
||||
|
||||
# Make systemd reload its units.
|
||||
system("@systemd@/bin/systemctl", "daemon-reload") == 0 or $res = 3;
|
||||
|
||||
# Restart changed services (those that have to be restarted rather
|
||||
# than stopped and started).
|
||||
my @restart = unique(split('\n', read_file($restartListFile, err_mode => 'quiet') // ""));
|
||||
if (scalar @restart > 0) {
|
||||
print STDERR "restarting the following units: ", join(", ", sort(@restart)), "\n";
|
||||
system("@systemd@/bin/systemctl", "restart", "--", @restart) == 0 or $res = 4;
|
||||
unlink($restartListFile);
|
||||
}
|
||||
|
||||
# Start all active targets, as well as changed units we stopped above.
|
||||
# The latter is necessary because some may not be dependencies of the
|
||||
# targets (i.e., they were manually started). FIXME: detect units
|
||||
# that are symlinks to other units. We shouldn't start both at the
|
||||
# same time because we'll get a "Failed to add path to set" error from
|
||||
# systemd.
|
||||
my @start = unique("default.target", split('\n', read_file($startListFile, err_mode => 'quiet') // ""));
|
||||
print STDERR "starting the following units: ", join(", ", sort(@start)), "\n";
|
||||
system("@systemd@/bin/systemctl", "start", "--", @start) == 0 or $res = 4;
|
||||
unlink($startListFile);
|
||||
|
||||
# Reload units that need it. This includes remounting changed mount
|
||||
# units.
|
||||
my @reload = unique(split '\n', read_file($reloadListFile, err_mode => 'quiet') // "");
|
||||
if (scalar @reload > 0) {
|
||||
print STDERR "reloading the following units: ", join(", ", sort(@reload)), "\n";
|
||||
system("@systemd@/bin/systemctl", "reload", "--", @reload) == 0 or $res = 4;
|
||||
unlink($reloadListFile);
|
||||
}
|
||||
|
||||
# Signal dbus to reload its configuration.
|
||||
system("@systemd@/bin/systemctl", "reload", "dbus.service");
|
||||
|
||||
# Print failed and new units.
|
||||
my (@failed, @new, @restarting);
|
||||
my $activeNew = getActiveUnits;
|
||||
while (my ($unit, $state) = each %{$activeNew}) {
|
||||
push @failed, $unit if $state->{state} eq "failed" || $state->{substate} eq "auto-restart";
|
||||
push @new, $unit if $state->{state} ne "failed" && !defined $activePrev->{$unit};
|
||||
}
|
||||
|
||||
print STDERR "the following new units were started: ", join(", ", sort(@new)), "\n"
|
||||
if scalar @new > 0;
|
||||
|
||||
if (scalar @failed > 0) {
|
||||
print STDERR "warning: the following units failed: ", join(", ", sort(@failed)), "\n";
|
||||
foreach my $unit (@failed) {
|
||||
print STDERR "\n";
|
||||
system("COLUMNS=1000 @systemd@/bin/systemctl status --no-pager '$unit' >&2");
|
||||
}
|
||||
$res = 4;
|
||||
}
|
||||
|
||||
exit $res;
|
@ -1,135 +0,0 @@
|
||||
#! @shell@
|
||||
|
||||
set -e
|
||||
export PATH=/empty
|
||||
for i in @path@; do PATH=$PATH:$i/bin:$i/sbin; done
|
||||
action="$1"
|
||||
|
||||
if ! test -e /etc/NIXOS; then
|
||||
echo "This is not a NixOS installation (/etc/NIXOS) is missing!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -z "$action"; then
|
||||
cat <<EOF
|
||||
Usage: $0 [switch|boot|test]
|
||||
|
||||
switch: make the configuration the boot default and activate now
|
||||
boot: make the configuration the boot default
|
||||
test: activate the configuration, but don't make it the boot default
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Install or update the bootloader.
|
||||
if [ "$action" = "switch" -o "$action" = "boot" ]; then
|
||||
@installBootLoader@ @out@
|
||||
fi
|
||||
|
||||
# Activate the new configuration.
|
||||
if [ "$action" != switch -a "$action" != test ]; then exit 0; fi
|
||||
|
||||
oldVersion=$(cat /run/current-system/upstart-interface-version 2> /dev/null || echo 0)
|
||||
newVersion=$(cat @out@/upstart-interface-version 2> /dev/null || echo 0)
|
||||
|
||||
if test "$oldVersion" -ne "$newVersion"; then
|
||||
cat <<EOF
|
||||
Warning: the new NixOS configuration has an Upstart version that is
|
||||
incompatible with the current version. The new configuration won't
|
||||
take effect until you reboot the system.
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Ignore SIGHUP so that we're not killed if we're running on (say)
|
||||
# virtual console 1 and we restart the "tty1" job.
|
||||
trap "" SIGHUP
|
||||
|
||||
jobsDir=$(readlink -f @out@/etc/init)
|
||||
|
||||
# Stop all currently running jobs that are not in the new Upstart
|
||||
# configuration. (Here "running" means all jobs that are not in the
|
||||
# stop/waiting state.)
|
||||
for job in $(initctl list | sed -e '/ stop\/waiting/ d; /^[^a-z]/ d; s/^\([^ ]\+\).*/\1/' | sort); do
|
||||
if ! [ -e "$jobsDir/$job.conf" ] ; then
|
||||
echo "stopping obsolete job ‘$job’..."
|
||||
stop --quiet "$job" || true
|
||||
fi
|
||||
done
|
||||
|
||||
# Activate the new configuration (i.e., update /etc, make accounts,
|
||||
# and so on).
|
||||
echo "activating the configuration..."
|
||||
@out@/activate @out@
|
||||
|
||||
# Make Upstart reload its jobs.
|
||||
initctl reload-configuration
|
||||
|
||||
# Allow Upstart jobs to react intelligently to a config change.
|
||||
initctl emit config-changed
|
||||
|
||||
declare -A tasks=(@tasks@)
|
||||
declare -A noRestartIfChanged=(@noRestartIfChanged@)
|
||||
|
||||
start_() {
|
||||
local job="$1"
|
||||
if start --quiet "$job"; then
|
||||
# Handle services that cancel themselves.
|
||||
if ! [ -n "${tasks[$job]}" ]; then
|
||||
local status=$(status "$job")
|
||||
[[ "$status" =~ start/running ]] || echo "job ‘$job’ failed to start!"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
log() {
|
||||
echo "$@" >&2 || true
|
||||
}
|
||||
|
||||
# Restart all running jobs that have changed. (Here "running" means
|
||||
# all jobs that don't have a "stop" goal.) We use the symlinks in
|
||||
# /var/run/upstart-jobs (created by each job's pre-start script) to
|
||||
# determine if a job has changed.
|
||||
for job in @jobs@; do
|
||||
status=$(status "$job")
|
||||
if ! [[ "$status" =~ start/ ]]; then continue; fi
|
||||
if [ "$(readlink -f "$jobsDir/$job.conf")" = "$(readlink -f "/var/run/upstart-jobs/$job")" ]; then continue; fi
|
||||
if [ -n "${noRestartIfChanged[$job]}" ]; then
|
||||
log "not restarting changed service ‘$job’"
|
||||
continue
|
||||
fi
|
||||
log "restarting changed service ‘$job’..."
|
||||
# Note: can't use "restart" here, since that only restarts the
|
||||
# job's main process.
|
||||
stop --quiet "$job" || true
|
||||
start_ "$job" || true
|
||||
done
|
||||
|
||||
# Start all jobs that are not running but should be. The "should be"
|
||||
# criterion is tricky: the intended semantics is that we end up with
|
||||
# the same jobs as after a reboot. If it's a task, start it if it
|
||||
# differs from the previous instance of the same task; if it wasn't
|
||||
# previously run, don't run it. If it's a service, only start it if
|
||||
# it has a "start on" condition.
|
||||
for job in @jobs@; do
|
||||
status=$(status "$job")
|
||||
if ! [[ "$status" =~ stop/ ]]; then continue; fi
|
||||
|
||||
if [ -n "${tasks[$job]}" ]; then
|
||||
if [ ! -e "/var/run/upstart-jobs/$job" -o \
|
||||
"$(readlink -f "$jobsDir/$job.conf")" = "$(readlink -f "/var/run/upstart-jobs/$job")" ];
|
||||
then continue; fi
|
||||
if [ -n "${noRestartIfChanged[$job]}" ]; then continue; fi
|
||||
log "starting task ‘$job’..."
|
||||
start --quiet "$job" || true
|
||||
else
|
||||
if ! grep -q "^start on" "$jobsDir/$job.conf"; then continue; fi
|
||||
log "starting service ‘$job’..."
|
||||
start_ "$job" || true
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
# Signal dbus to reload its configuration.
|
||||
dbusPid=$(initctl status dbus 2> /dev/null | sed -e 's/.*process \([0-9]\+\)/\1/;t;d')
|
||||
[ -n "$dbusPid" ] && kill -HUP "$dbusPid"
|
@ -115,12 +115,12 @@ let
|
||||
|
||||
ln -s ${config.system.build.etc}/etc $out/etc
|
||||
ln -s ${config.system.path} $out/sw
|
||||
ln -s ${config.system.build.upstart} $out/upstart
|
||||
ln -s "$systemd" $out/systemd
|
||||
ln -s ${config.hardware.firmware} $out/firmware
|
||||
|
||||
echo -n "$kernelParams" > $out/kernel-params
|
||||
echo -n "$configurationName" > $out/configuration-name
|
||||
echo -n "${toString config.system.build.upstart.interfaceVersion}" > $out/upstart-interface-version
|
||||
echo -n "systemd ${toString config.systemd.package.interfaceVersion}" > $out/init-interface-version
|
||||
echo -n "$nixosVersion" > $out/nixos-version
|
||||
|
||||
mkdir $out/fine-tune
|
||||
@ -131,7 +131,7 @@ let
|
||||
done
|
||||
|
||||
mkdir $out/bin
|
||||
substituteAll ${./switch-to-configuration.sh} $out/bin/switch-to-configuration
|
||||
substituteAll ${./switch-to-configuration.pl} $out/bin/switch-to-configuration
|
||||
chmod +x $out/bin/switch-to-configuration
|
||||
|
||||
${config.system.extraSystemBuilderCmds}
|
||||
@ -147,6 +147,10 @@ let
|
||||
name = "nixos-${config.system.nixosVersion}";
|
||||
preferLocalBuild = true;
|
||||
buildCommand = systemBuilder;
|
||||
|
||||
inherit (pkgs) utillinux;
|
||||
systemd = config.systemd.package;
|
||||
|
||||
inherit children;
|
||||
kernelParams =
|
||||
config.boot.kernelParams ++ config.boot.extraKernelParams;
|
||||
@ -165,17 +169,10 @@ let
|
||||
# to the activation script.
|
||||
noRestartIfChanged = attrValues (mapAttrs (n: v: if v.restartIfChanged then [] else ["[${v.name}]=1"]) config.jobs);
|
||||
|
||||
# Most of these are needed by grub-install.
|
||||
path =
|
||||
[ pkgs.coreutils
|
||||
pkgs.gnused
|
||||
pkgs.gnugrep
|
||||
pkgs.findutils
|
||||
pkgs.diffutils
|
||||
config.system.build.upstart # for initctl
|
||||
];
|
||||
|
||||
configurationName = config.boot.loader.grub.configurationName;
|
||||
|
||||
# Needed by switch-to-configuration.
|
||||
perl = "${pkgs.perl}/bin/perl -I${pkgs.perlPackages.FileSlurp}/lib/perl5/site_perl";
|
||||
};
|
||||
|
||||
|
||||
|
@ -2,7 +2,16 @@
|
||||
|
||||
with pkgs.lib;
|
||||
|
||||
let kernel = config.boot.kernelPackages.kernel; in
|
||||
let
|
||||
|
||||
kernel = config.boot.kernelPackages.kernel;
|
||||
|
||||
kernelModulesConf = pkgs.writeText "nixos.conf"
|
||||
''
|
||||
${concatStringsSep "\n" config.boot.kernelModules}
|
||||
'';
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
|
||||
@ -41,7 +50,7 @@ let kernel = config.boot.kernelPackages.kernel; in
|
||||
|
||||
boot.extraKernelParams = mkOption {
|
||||
default = [ ];
|
||||
example = [ "debugtrace" ];
|
||||
example = [ "boot.trace" ];
|
||||
description = "Additional user-defined kernel parameters.";
|
||||
};
|
||||
|
||||
@ -55,7 +64,7 @@ let kernel = config.boot.kernelPackages.kernel; in
|
||||
|
||||
boot.extraModulePackages = mkOption {
|
||||
default = [];
|
||||
# !!! example = [pkgs.aufs pkgs.nvidia_x11];
|
||||
# !!! example = [pkgs.nvidia_x11];
|
||||
description = "A list of additional packages supplying kernel modules.";
|
||||
};
|
||||
|
||||
@ -191,6 +200,40 @@ let kernel = config.boot.kernelPackages.kernel; in
|
||||
# The Linux kernel >= 2.6.27 provides firmware.
|
||||
hardware.firmware = [ "${kernel}/lib/firmware" ];
|
||||
|
||||
# Create /etc/modules-load.d/nixos.conf, which is read by
|
||||
# systemd-modules-load.service to load required kernel modules.
|
||||
# FIXME: ensure that systemd-modules-load.service is restarted if
|
||||
# this file changes.
|
||||
environment.etc = singleton
|
||||
{ target = "modules-load.d/nixos.conf";
|
||||
source = kernelModulesConf;
|
||||
};
|
||||
|
||||
# Sigh. This overrides systemd's systemd-modules-load.service
|
||||
# just so we can set a restart trigger. Also make
|
||||
# multi-user.target pull it in so that it gets started if it
|
||||
# failed earlier.
|
||||
systemd.services."systemd-modules-load" =
|
||||
{ description = "Load Kernel Modules";
|
||||
wantedBy = [ "sysinit.target" "multi-user.target" ];
|
||||
before = [ "sysinit.target" "shutdown.target" ];
|
||||
unitConfig =
|
||||
{ DefaultDependencies = "no";
|
||||
Conflicts = "shutdown.target";
|
||||
};
|
||||
serviceConfig =
|
||||
{ Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
ExecStart = "${config.systemd.package}/lib/systemd/systemd-modules-load";
|
||||
# Ignore failed module loads. Typically some of the
|
||||
# modules in ‘boot.kernelModules’ are "nice to have but
|
||||
# not required" (e.g. acpi-cpufreq), so we don't want to
|
||||
# barf on those.
|
||||
SuccessExitStatus = "0 1";
|
||||
};
|
||||
restartTriggers = [ kernelModulesConf ];
|
||||
};
|
||||
|
||||
lib.kernelConfig = {
|
||||
isYes = option: {
|
||||
assertion = config: config.isYes option;
|
||||
@ -240,4 +283,5 @@ let kernel = config.boot.kernelPackages.kernel; in
|
||||
) config.system.requiredKernelConfig;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ let
|
||||
version extraConfig extraPerEntryConfig extraEntries
|
||||
extraEntriesBeforeNixOS extraPrepareConfig configurationLimit copyKernels timeout
|
||||
default devices;
|
||||
path = makeSearchPath "bin" [ pkgs.coreutils pkgs.gnused pkgs.gnugrep pkgs.findutils pkgs.diffutils ];
|
||||
});
|
||||
|
||||
in
|
||||
|
@ -39,6 +39,7 @@ my $configurationLimit = int(get("configurationLimit"));
|
||||
my $copyKernels = get("copyKernels") eq "true";
|
||||
my $timeout = int(get("timeout"));
|
||||
my $defaultEntry = int(get("default"));
|
||||
$ENV{'PATH'} = get("path");
|
||||
|
||||
die "unsupported GRUB version\n" if $grubVersion != 1 && $grubVersion != 2;
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
with pkgs.lib;
|
||||
let
|
||||
isEnabled = config.boot.loader.grub.memtest86;
|
||||
memtest86 = pkgs.memtest86;
|
||||
memtest86 = pkgs.memtest86plus;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user