Merge staging-next into staging

This commit is contained in:
Frederik Rietdijk 2019-08-28 08:26:42 +02:00
commit 5061fe0c2c
1209 changed files with 36685 additions and 18393 deletions

View file

@ -185,10 +185,9 @@ with import <nixpkgs> {};
androidenv.emulateApp {
name = "emulate-MyAndroidApp";
platformVersion = "24";
abiVersion = "armeabi-v7a"; # mips, x86 or x86_64
systemImageType = "default";
useGoogleAPIs = false;
platformVersion = "28";
abiVersion = "x86_64"; # armeabi-v7a, mips, x86
systemImageType = "google_apis_playstore";
}
```
@ -201,7 +200,7 @@ with import <nixpkgs> {};
androidenv.emulateApp {
name = "emulate-MyAndroidApp";
platformVersion = "24";
abiVersion = "armeabi-v7a"; # mips, x86 or x86_64
abiVersion = "armeabi-v7a"; # mips, x86, x86_64
systemImageType = "default";
useGoogleAPIs = false;
app = ./MyApp.apk;

View file

@ -75,7 +75,8 @@ foo = import ../path/to/foo.nix {
It adds the contents of the <envar>PERL5LIB</envar> environment variable
to <literal>#! .../bin/perl</literal> line of Perl scripts as
<literal>-I<replaceable>dir</replaceable></literal> flags. This ensures
that a script can find its dependencies.
that a script can find its dependencies. (This can cause this shebang line
to become too long for Darwin to handle; see the note below.)
</para>
</listitem>
<listitem>
@ -137,6 +138,36 @@ ClassC3Componentised = buildPerlPackage rec {
</programlisting>
</para>
<para>
On Darwin, if a script has too many
<literal>-I<replaceable>dir</replaceable></literal> flags in its first line
(its “shebang line”), it will not run. This can be worked around by calling
the <literal>shortenPerlShebang</literal> function from the
<literal>postInstall</literal> phase:
<programlisting>
{ stdenv, buildPerlPackage, fetchurl, shortenPerlShebang }:
ImageExifTool = buildPerlPackage {
pname = "Image-ExifTool";
version = "11.50";
src = fetchurl {
url = "https://www.sno.phy.queensu.ca/~phil/exiftool/Image-ExifTool-11.50.tar.gz";
sha256 = "0d8v48y94z8maxkmw1rv7v9m0jg2dc8xbp581njb6yhr7abwqdv3";
};
buildInputs = stdenv.lib.optional stdenv.isDarwin shortenPerlShebang;
postInstall = stdenv.lib.optional stdenv.isDarwin ''
shortenPerlShebang $out/bin/exiftool
'';
};
</programlisting>
This will remove the <literal>-I</literal> flags from the shebang line,
rewrite them in the <literal>use lib</literal> form, and put them on the next
line instead. This function can be given any number of Perl scripts as
arguments; it will modify them in-place.
</para>
<section xml:id="ssec-generation-from-CPAN">
<title>Generation from CPAN</title>

View file

@ -71,7 +71,7 @@ let
zipAttrsWithNames zipAttrsWith zipAttrs recursiveUpdateUntil
recursiveUpdate matchAttrs overrideExisting getOutput getBin
getLib getDev chooseDevOutputs zipWithNames zip;
inherit (lists) singleton foldr fold foldl foldl' imap0 imap1
inherit (lists) singleton forEach foldr fold foldl foldl' imap0 imap1
concatMap flatten remove findSingle findFirst any all count
optional optionals toList range partition zipListsWith zipLists
reverseList listDfs toposort sort naturalSort compareLists take

View file

@ -21,6 +21,19 @@ rec {
*/
singleton = x: [x];
/* Apply the function to each element in the list. Same as `map`, but arguments
flipped.
Type: forEach :: [a] -> (a -> b) -> [b]
Example:
forEach [ 1 2 ] (x:
toString x
)
=> [ "1" "2" ]
*/
forEach = xs: f: map f xs;
/* right fold a binary function `op` between successive elements of
`list` with `nul' as the starting value, i.e.,
`foldr op nul [x_1 x_2 ... x_n] == op x_1 (op x_2 ... (op x_n nul))`.

View file

@ -36,7 +36,7 @@ rec {
example ? null,
# String describing the option.
description ? null,
# Related packages used in the manual (see `genRelatedPackages` in ../nixos/doc/manual/default.nix).
# Related packages used in the manual (see `genRelatedPackages` in ../nixos/lib/make-options-doc/default.nix).
relatedPackages ? null,
# Option type, providing type-checking and value merging.
type ? null,

View file

@ -40,6 +40,12 @@
See `./scripts/check-maintainer-github-handles.sh` for an example on how to work with this data.
*/
{
"00-matt" = {
name = "Matt Smith";
email = "matt@offtopica.uk";
github = "00-matt";
githubId = 48835712;
};
"0x4A6F" = {
email = "0x4A6F@shackspace.de";
name = "Joachim Ernst";
@ -296,6 +302,11 @@
githubId = 17208985;
name = "Alex Rice";
};
alexbakker = {
email = "ab@alexbakker.me";
github = "alexbakker";
name = "Alexander Bakker";
};
alexchapman = {
email = "alex@farfromthere.net";
github = "AJChapman";
@ -324,6 +335,12 @@
githubId = 2822871;
name = "Alistair Bill";
};
alkeryn = {
email = "plbraundev@gmail.com";
github = "Alkeryn";
githubId = 11599075;
name = "Pierre-Louis Braun";
};
all = {
email = "nix-commits@lists.science.uu.nl";
name = "Nix Committers";
@ -571,6 +588,12 @@
githubId = 816777;
name = "Ashley Gillman";
};
ashkitten = {
email = "ashlea@protonmail.com";
github = "ashkitten";
githubId = 9281956;
name = "ash lea";
};
aske = {
email = "aske@fmap.me";
github = "aske";
@ -1701,6 +1724,16 @@
fingerprint = "389A 78CB CD88 5E0C 4701 DEB9 FD42 C7D0 D414 94C8";
}];
};
dump_stack = {
email = "root@dumpstack.io";
github = "jollheef";
githubId = 1749762;
name = "Mikhail Klementev";
keys = [{
longkeyid = "rsa4096/0x1525585D1B43C62A";
fingerprint = "5DD7 C6F6 0630 F08E DAE7 4711 1525 585D 1B43 C62A";
}];
};
dxf = {
email = "dingxiangfei2009@gmail.com";
github = "dingxiangfei2009";
@ -2738,6 +2771,11 @@
githubId = 26877687;
name = "Yurii Izorkin";
};
jasoncarr = {
email = "jcarr250@gmail.com";
github = "jasoncarr0";
name = "Jason Carr";
};
j-keck = {
email = "jhyphenkeck@gmail.com";
github = "j-keck";
@ -2825,6 +2863,15 @@
githubId = 1383440;
name = "Jason Gilliland";
};
jdanek = {
email = "jdanek@redhat.com";
github = "jdanekrh";
keys = [{
longkeyid = "ed25519/0x69275CADF15D872E";
fingerprint = "D4A6 F051 AD58 2E7C BCED 5439 6927 5CAD F15D 872E";
}];
name = "Jiri Daněk";
};
jdehaas = {
email = "qqlq@nullptr.club";
github = "jeroendehaas";
@ -3218,6 +3265,11 @@
githubId = 6282557;
name = "Kiloreux Emperex";
};
kim0 = {
email = "email.ahmedkamal@googlemail.com";
github = "kim0";
name = "Ahmed Kamal";
};
kimburgess = {
email = "kim@acaprojects.com";
github = "kimburgess";
@ -3236,6 +3288,11 @@
githubId = 451835;
name = "Kirill Elagin";
};
kirikaza = {
email = "k@kirikaza.ru";
github = "kirikaza";
name = "Kirill Kazakov";
};
kisonecat = {
email = "kisonecat@gmail.com";
github = "kisonecat";
@ -3353,6 +3410,11 @@
githubId = 10544;
name = "Giuluo Eulisse";
};
ktor = {
email = "kruszewsky@gmail.com";
github = "ktor";
name = "Pawel Kruszewski";
};
ktosiek = {
email = "tomasz.kontusz@gmail.com";
github = "ktosiek";
@ -3482,6 +3544,11 @@
githubId = 307589;
name = "Nathaniel Baxter";
};
lightbulbjim = {
email = "chris@killred.net";
github = "lightbulbjim";
name = "Chris Rendle-Short";
};
lightdiscord = {
email = "root@arnaud.sh";
github = "lightdiscord";
@ -5897,6 +5964,12 @@
githubId = 231788;
name = "Stephen Weinberg";
};
sterfield = {
email = "sterfield@gmail.com";
github = "sterfield";
githubId = 5747061;
name = "Guillaume Loetscher";
};
sternenseemann = {
email = "post@lukasepple.de";
github = "sternenseemann";
@ -6495,6 +6568,12 @@
githubId = 1525767;
name = "Vaibhav Sagar";
};
valebes = {
email = "valebes@gmail.com";
github = "valebes";
githubid = 10956211;
name = "Valerio Besozzi";
};
valeriangalliat = {
email = "val@codejam.info";
github = "valeriangalliat";

View file

@ -1,4 +1,5 @@
# nix name, luarocks name, server, version,luaversion,maintainers
alt-getopt,,,,,arobyn
ansicolors,,,,,
argparse,,,,,
basexx,,,,,
@ -56,6 +57,7 @@ luv,,,,,
markdown,,,,,
mediator_lua,,,,,
mpack,,,,,
moonscript,,,,,arobyn
nvim-client,,,,,
penlight,,,,,
rapidjson,,,,,

1 # nix name luarocks name server version luaversion maintainers
2 alt-getopt arobyn
3 ansicolors
4 argparse
5 basexx
57 markdown
58 mediator_lua
59 mpack
60 moonscript arobyn
61 nvim-client
62 penlight
63 rapidjson

View file

@ -220,6 +220,30 @@
</itemizedlist>
</section>
</section>
<section xml:id="release-managers">
<title>Release Management Team</title>
<para>
For each release there are two release managers. After each release the
release manager having managed two releases steps down and the release
management team of the last release appoints a new release manager.
</para>
<para>
This makes sure a release management team always consists of one release
manager who already has managed one release and one release manager being
introduced to their role, making it easier to pass on knowledge and
experience.
</para>
<para>
A release manager's role and responsibilities are:
</para>
<itemizedlist>
<listitem><para>manage the release process</para></listitem>
<listitem><para>start discussions about features and changes for a given release</para></listitem>
<listitem><para>create a roadmap</para></listitem>
<listitem><para>release in cooperation with Eelco Dolstra</para></listitem>
<listitem><para>decide which bug fixes, features, etc... get backported after a release</para></listitem>
</itemizedlist>
</section>
<section xml:id="release-schedule">
<title>Release schedule</title>

View file

@ -237,6 +237,12 @@
</para>
</listitem>
<listitem>
<para>
The <literal>shibboleth-sp</literal> package has been updated to version 3.
It is largely backward compatible, for further information refer to the
<link xlink:href="https://wiki.shibboleth.net/confluence/display/SP3/ReleaseNotes">release notes</link>
and <link xlink:href="https://wiki.shibboleth.net/confluence/display/SP3/UpgradingFromV2">upgrade guide</link>.
</para>
<para>
Nodejs 8 is scheduled EOL under the lifetime of 19.09 and has been dropped.
</para>
@ -263,6 +269,28 @@
<literal>false</literal>.
</para>
</listitem>
<listitem>
<para>
The <option>services.systemhealth</option> module has been removed from nixpkgs due to lack of maintainer.
</para>
</listitem>
<listitem>
<para>
The <option>services.mantisbt</option> module has been removed from nixpkgs due to lack of maintainer.
</para>
</listitem>
<listitem>
<para>
Squid 3 has been removed and the <option>squid</option> derivation now refers to Squid 4.
</para>
</listitem>
<listitem>
<para>
The <option>services.pdns-recursor.extraConfig</option> option has been replaced by
<option>services.pdns-recursor.settings</option>. The new option allows setting extra
configuration while being better type-checked and mergeable.
</para>
</listitem>
</itemizedlist>
</section>
@ -424,6 +452,81 @@
installer after creating <literal>/var/lib/nextcloud</literal>.
</para>
</listitem>
<listitem>
<para>
There exists now <literal>lib.forEach</literal>, which is like <literal>map</literal>, but with
arguments flipped. When mapping function body spans many lines (or has nested
<literal>map</literal>s), it is often hard to follow which list is modified.
</para>
<para>
Previous solution to this problem was either to use <literal>lib.flip map</literal>
idiom or extract that anonymous mapping function to a named one. Both can still be used
but <literal>lib.forEach</literal> is preferred over <literal>lib.flip map</literal>.
</para>
<para>
The <literal>/etc/sysctl.d/nixos.conf</literal> file containing all the options set via
<link linkend="opt-boot.kernel.sysctl">boot.kernel.sysctl</link> was moved to
<literal>/etc/sysctl.d/60-nixos.conf</literal>, as
<citerefentry><refentrytitle>sysctl.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>
recommends prefixing all filenames in <literal>/etc/sysctl.d</literal> with a
two-digit number and a dash to simplify the ordering of the files.
</para>
</listitem>
<listitem>
<para>
We now install the sysctl snippets shipped with systemd.
<itemizedlist>
<para>This enables:</para>
<listitem>
<para>Loose reverse path filtering</para>
</listitem>
<listitem>
<para>Source route filtering</para>
</listitem>
<listitem>
<para>
<literal>fq_codel</literal> as a packet scheduler (this helps to fight bufferbloat)
</para>
</listitem>
</itemizedlist>
This also configures the kernel to pass coredumps to <literal>systemd-coredump</literal>.
These sysctl snippets can be found in <literal>/etc/sysctl.d/50-*.conf</literal>,
and overridden via <link linkend="opt-boot.kernel.sysctl">boot.kernel.sysctl</link>
(which will place the parameters in <literal>/etc/sysctl.d/60-nixos.conf</literal>).
</para>
</listitem>
<listitem>
<para>
Coredumps are now acquired by <literal>systemd-coredump</literal> by default.
<literal>systemd-coredump</literal> behaviour can still be modified via
<option>systemd.coredump.extraConfig</option>.
To stick to the old behaviour (having the kernel dump to a file called <literal>core</literal>
in the working directory), without piping it through <literal>systemd-coredump</literal>, set
<option>boot.kernel.sysctl."kernel.core_pattern"</option> to <literal>"core"</literal>.
</para>
</listitem>
<listitem>
<para>
<literal>systemd.packages</literal> option now also supports generators and
shutdown scripts. Old <literal>systemd.generator-packages</literal> option has
been removed.
</para>
</listitem>
<listitem>
<para>
The <literal>rmilter</literal> package was removed with associated module and options due deprecation by upstream developer.
Use <literal>rspamd</literal> in proxy mode instead.
</para>
</listitem>
<listitem>
<para>
systemd cgroup accounting via the
<link linkend="opt-systemd.enableCgroupAccounting">systemd.enableCgroupAccounting</link>
option is now enabled by default. It now also enables the more recent Block IO and IP accounting
features.
</para>
</listitem>
</itemizedlist>
</section>
</section>

View file

@ -54,11 +54,11 @@ rec {
machinesNumbered = zipLists machines (range 1 254);
nodes_ = flip map machinesNumbered (m: nameValuePair m.fst
nodes_ = forEach machinesNumbered (m: nameValuePair m.fst
[ ( { config, nodes, ... }:
let
interfacesNumbered = zipLists config.virtualisation.vlans (range 1 255);
interfaces = flip map interfacesNumbered ({ fst, snd }:
interfaces = forEach interfacesNumbered ({ fst, snd }:
nameValuePair "eth${toString snd}" { ipv4.addresses =
[ { address = "192.168.${toString fst}.${toString m.snd}";
prefixLength = 24;
@ -88,7 +88,7 @@ rec {
"${config.networking.hostName}\n"));
virtualisation.qemu.options =
flip map interfacesNumbered
forEach interfacesNumbered
({ fst, snd }: qemuNICFlags snd fst m.snd);
};
}

View file

@ -102,7 +102,7 @@ let
# builtins multiply by 4 the memory usage and the time used to compute
# each options.
tryCollectOptions = moduleResult:
flip map (excludeOptions (collect isOption moduleResult)) (opt:
forEach (excludeOptions (collect isOption moduleResult)) (opt:
{ name = showOption opt.loc; } // builtins.tryEval (strict opt.value));
in
keepNames (

View file

@ -52,85 +52,11 @@ let
</fontconfig>
'';
# local configuration file
localConf = pkgs.writeText "fc-local.conf" cfg.localConf;
# The configuration to be included in /etc/font/
penultimateConf = pkgs.runCommand "font-penultimate-conf" {
preferLocalBuild = true;
} ''
support_folder=$out/etc/fonts/conf.d
latest_folder=$out/etc/fonts/${latestVersion}/conf.d
mkdir -p $support_folder
mkdir -p $latest_folder
ln -s ${supportFontsConf} $support_folder/../fonts.conf
ln -s ${latestPkg.out}/etc/fonts/fonts.conf \
$latest_folder/../fonts.conf
# fontconfig-penultimate various configuration files
ln -s ${pkgs.fontconfig-penultimate}/etc/fonts/conf.d/*.conf \
$support_folder
ln -s ${pkgs.fontconfig-penultimate}/etc/fonts/conf.d/*.conf \
$latest_folder
ln -s ${cacheConfSupport} $support_folder/00-nixos-cache.conf
ln -s ${cacheConfLatest} $latest_folder/00-nixos-cache.conf
rm $support_folder/10-antialias.conf $latest_folder/10-antialias.conf
ln -s ${antialiasConf} $support_folder/10-antialias.conf
ln -s ${antialiasConf} $latest_folder/10-antialias.conf
rm $support_folder/10-hinting.conf $latest_folder/10-hinting.conf
ln -s ${hintingConf} $support_folder/10-hinting.conf
ln -s ${hintingConf} $latest_folder/10-hinting.conf
${optionalString cfg.useEmbeddedBitmaps ''
rm $support_folder/10-no-embedded-bitmaps.conf
rm $latest_folder/10-no-embedded-bitmaps.conf
''}
rm $support_folder/10-subpixel.conf $latest_folder/10-subpixel.conf
ln -s ${subpixelConf} $support_folder/10-subpixel.conf
ln -s ${subpixelConf} $latest_folder/10-subpixel.conf
${optionalString (cfg.dpi != 0) ''
ln -s ${dpiConf} $support_folder/11-dpi.conf
ln -s ${dpiConf} $latest_folder/11-dpi.conf
''}
${optionalString (!cfg.includeUserConf) ''
rm $support_folder/50-user.conf
rm $latest_folder/50-user.conf
''}
# 51-local.conf
rm $latest_folder/51-local.conf
substitute \
${pkgs.fontconfig-penultimate}/etc/fonts/conf.d/51-local.conf \
$latest_folder/51-local.conf \
--replace local.conf /etc/fonts/${latestVersion}/local.conf
# local.conf (indirect priority 51)
${optionalString (cfg.localConf != "") ''
ln -s ${localConf} $out/etc/fonts/local.conf
ln -s ${localConf} $out/etc/fonts/${latestVersion}/local.conf
''}
ln -s ${defaultFontsConf} $support_folder/52-default-fonts.conf
ln -s ${defaultFontsConf} $latest_folder/52-default-fonts.conf
${optionalString cfg.allowBitmaps ''
rm $support_folder/53-no-bitmaps.conf
rm $latest_folder/53-no-bitmaps.conf
''}
${optionalString (!cfg.allowType1) ''
ln -s ${rejectType1} $support_folder/53-no-type1.conf
ln -s ${rejectType1} $latest_folder/53-no-type1.conf
''}
'';
# rendering settings configuration files
# priority 10
hintingConf = pkgs.writeText "fc-10-hinting.conf" ''
<?xml version='1.0'?>
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
@ -199,6 +125,8 @@ let
</fontconfig>
'';
# default fonts configuration file
# priority 52
defaultFontsConf =
let genDefault = fonts: name:
optionalString (fonts != []) ''
@ -228,7 +156,9 @@ let
</fontconfig>
'';
rejectType1 = pkgs.writeText "fc-53-no-type1.conf" ''
# reject Type 1 fonts
# priority 53
rejectType1 = pkgs.writeText "fc-53-nixos-reject-type1.conf" ''
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
@ -245,6 +175,88 @@ let
</fontconfig>
'';
# The configuration to be included in /etc/font/
penultimateConf = pkgs.runCommand "fontconfig-penultimate-conf" {
preferLocalBuild = true;
} ''
support_folder=$out/etc/fonts/conf.d
latest_folder=$out/etc/fonts/${latestVersion}/conf.d
mkdir -p $support_folder
mkdir -p $latest_folder
# fonts.conf
ln -s ${supportFontsConf} $support_folder/../fonts.conf
ln -s ${latestPkg.out}/etc/fonts/fonts.conf \
$latest_folder/../fonts.conf
# fontconfig-penultimate various configuration files
ln -s ${pkgs.fontconfig-penultimate}/etc/fonts/conf.d/*.conf \
$support_folder
ln -s ${pkgs.fontconfig-penultimate}/etc/fonts/conf.d/*.conf \
$latest_folder
ln -s ${cacheConfSupport} $support_folder/00-nixos-cache.conf
ln -s ${cacheConfLatest} $latest_folder/00-nixos-cache.conf
rm $support_folder/10-antialias.conf $latest_folder/10-antialias.conf
ln -s ${antialiasConf} $support_folder/10-antialias.conf
ln -s ${antialiasConf} $latest_folder/10-antialias.conf
rm $support_folder/10-hinting.conf $latest_folder/10-hinting.conf
ln -s ${hintingConf} $support_folder/10-hinting.conf
ln -s ${hintingConf} $latest_folder/10-hinting.conf
${optionalString cfg.useEmbeddedBitmaps ''
rm $support_folder/10-no-embedded-bitmaps.conf
rm $latest_folder/10-no-embedded-bitmaps.conf
''}
rm $support_folder/10-subpixel.conf $latest_folder/10-subpixel.conf
ln -s ${subpixelConf} $support_folder/10-subpixel.conf
ln -s ${subpixelConf} $latest_folder/10-subpixel.conf
${optionalString (cfg.dpi != 0) ''
ln -s ${dpiConf} $support_folder/11-dpi.conf
ln -s ${dpiConf} $latest_folder/11-dpi.conf
''}
# 50-user.conf
${optionalString (!cfg.includeUserConf) ''
rm $support_folder/50-user.conf
rm $latest_folder/50-user.conf
''}
# 51-local.conf
rm $latest_folder/51-local.conf
substitute \
${pkgs.fontconfig-penultimate}/etc/fonts/conf.d/51-local.conf \
$latest_folder/51-local.conf \
--replace local.conf /etc/fonts/${latestVersion}/local.conf
# local.conf (indirect priority 51)
${optionalString (cfg.localConf != "") ''
ln -s ${localConf} $support_folder/../local.conf
ln -s ${localConf} $latest_folder/../local.conf
''}
# 52-nixos-default-fonts.conf
ln -s ${defaultFontsConf} $support_folder/52-nixos-default-fonts.conf
ln -s ${defaultFontsConf} $latest_folder/52-nixos-default-fonts.conf
# 53-no-bitmaps.conf
${optionalString cfg.allowBitmaps ''
rm $support_folder/53-no-bitmaps.conf
rm $latest_folder/53-no-bitmaps.conf
''}
${optionalString (!cfg.allowType1) ''
# 53-nixos-reject-type1.conf
ln -s ${rejectType1} $support_folder/53-nixos-reject-type1.conf
ln -s ${rejectType1} $latest_folder/53-nixos-reject-type1.conf
''}
'';
in
{

View file

@ -14,250 +14,252 @@ Low number means high priority.
*/
{ config, lib, pkgs, ... }:
{ config, pkgs, lib, ... }:
with lib;
let cfg = config.fonts.fontconfig;
let
cfg = config.fonts.fontconfig;
fcBool = x: "<bool>" + (boolToString x) + "</bool>";
fcBool = x: "<bool>" + (boolToString x) + "</bool>";
# back-supported fontconfig version and package
# version is used for font cache generation
supportVersion = "210";
supportPkg = pkgs."fontconfig_${supportVersion}";
# back-supported fontconfig version and package
# version is used for font cache generation
supportVersion = "210";
supportPkg = pkgs."fontconfig_${supportVersion}";
# latest fontconfig version and package
# version is used for configuration folder name, /etc/fonts/VERSION/
# note: format differs from supportVersion and can not be used with makeCacheConf
latestVersion = pkgs.fontconfig.configVersion;
latestPkg = pkgs.fontconfig;
# latest fontconfig version and package
# version is used for configuration folder name, /etc/fonts/VERSION/
# note: format differs from supportVersion and can not be used with makeCacheConf
latestVersion = pkgs.fontconfig.configVersion;
latestPkg = pkgs.fontconfig;
# supported version fonts.conf
supportFontsConf = pkgs.makeFontsConf { fontconfig = supportPkg; fontDirectories = config.fonts.fonts; };
# supported version fonts.conf
supportFontsConf = pkgs.makeFontsConf { fontconfig = supportPkg; fontDirectories = config.fonts.fonts; };
# configuration file to read fontconfig cache
# version dependent
# priority 0
cacheConfSupport = makeCacheConf { version = supportVersion; };
cacheConfLatest = makeCacheConf {};
# configuration file to read fontconfig cache
# version dependent
# priority 0
cacheConfSupport = makeCacheConf { version = supportVersion; };
cacheConfLatest = makeCacheConf {};
# generate the font cache setting file for a fontconfig version
# use latest when no version is passed
makeCacheConf = { version ? null }:
let
fcPackage = if version == null
then "fontconfig"
else "fontconfig_${version}";
makeCache = fontconfig: pkgs.makeFontsCache { inherit fontconfig; fontDirectories = config.fonts.fonts; };
cache = makeCache pkgs.${fcPackage};
cache32 = makeCache pkgs.pkgsi686Linux.${fcPackage};
in
pkgs.writeText "fc-00-nixos-cache.conf" ''
<?xml version='1.0'?>
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
<fontconfig>
<!-- Font directories -->
${concatStringsSep "\n" (map (font: "<dir>${font}</dir>") config.fonts.fonts)}
<!-- Pre-generated font caches -->
<cachedir>${cache}</cachedir>
${optionalString (pkgs.stdenv.isx86_64 && cfg.cache32Bit) ''
<cachedir>${cache32}</cachedir>
''}
</fontconfig>
'';
# rendering settings configuration file
# priority 10
renderConf = pkgs.writeText "fc-10-nixos-rendering.conf" ''
# generate the font cache setting file for a fontconfig version
# use latest when no version is passed
makeCacheConf = { version ? null }:
let
fcPackage = if version == null
then "fontconfig"
else "fontconfig_${version}";
makeCache = fontconfig: pkgs.makeFontsCache { inherit fontconfig; fontDirectories = config.fonts.fonts; };
cache = makeCache pkgs."${fcPackage}";
cache32 = makeCache pkgs.pkgsi686Linux."${fcPackage}";
in
pkgs.writeText "fc-00-nixos-cache.conf" ''
<?xml version='1.0'?>
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
<fontconfig>
<!-- Default rendering settings -->
<match target="pattern">
<edit mode="append" name="hinting">
${fcBool cfg.hinting.enable}
</edit>
<edit mode="append" name="autohint">
${fcBool cfg.hinting.autohint}
</edit>
<edit mode="append" name="hintstyle">
<const>hintslight</const>
</edit>
<edit mode="append" name="antialias">
${fcBool cfg.antialias}
</edit>
<edit mode="append" name="rgba">
<const>${cfg.subpixel.rgba}</const>
</edit>
<edit mode="append" name="lcdfilter">
<const>lcd${cfg.subpixel.lcdfilter}</const>
</edit>
</match>
${optionalString (cfg.dpi != 0) ''
<match target="pattern">
<edit name="dpi" mode="assign">
<double>${toString cfg.dpi}</double>
</edit>
</match>
<!-- Font directories -->
${concatStringsSep "\n" (map (font: "<dir>${font}</dir>") config.fonts.fonts)}
<!-- Pre-generated font caches -->
<cachedir>${cache}</cachedir>
${optionalString (pkgs.stdenv.isx86_64 && cfg.cache32Bit) ''
<cachedir>${cache32}</cachedir>
''}
</fontconfig>
'';
# local configuration file
# priority 51
localConf = pkgs.writeText "fc-local.conf" cfg.localConf;
# rendering settings configuration file
# priority 10
renderConf = pkgs.writeText "fc-10-nixos-rendering.conf" ''
<?xml version='1.0'?>
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
<fontconfig>
# default fonts configuration file
# priority 52
defaultFontsConf =
let genDefault = fonts: name:
optionalString (fonts != []) ''
<alias>
<family>${name}</family>
<prefer>
${concatStringsSep ""
(map (font: ''
<family>${font}</family>
'') fonts)}
</prefer>
</alias>
'';
in
pkgs.writeText "fc-52-nixos-default-fonts.conf" ''
<?xml version='1.0'?>
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
<fontconfig>
<!-- Default fonts -->
${genDefault cfg.defaultFonts.sansSerif "sans-serif"}
${genDefault cfg.defaultFonts.serif "serif"}
${genDefault cfg.defaultFonts.monospace "monospace"}
</fontconfig>
'';
# bitmap font options
# priority 53
rejectBitmaps = pkgs.writeText "fc-53-nixos-bitmaps.conf" ''
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
${optionalString (!cfg.allowBitmaps) ''
<!-- Reject bitmap fonts -->
<selectfont>
<rejectfont>
<pattern>
<patelt name="scalable"><bool>false</bool></patelt>
</pattern>
</rejectfont>
</selectfont>
''}
<!-- Use embedded bitmaps in fonts like Calibri? -->
<match target="font">
<edit name="embeddedbitmap" mode="assign">
${fcBool cfg.useEmbeddedBitmaps}
<!-- Default rendering settings -->
<match target="pattern">
<edit mode="append" name="hinting">
${fcBool cfg.hinting.enable}
</edit>
<edit mode="append" name="autohint">
${fcBool cfg.hinting.autohint}
</edit>
<edit mode="append" name="hintstyle">
<const>hintslight</const>
</edit>
<edit mode="append" name="antialias">
${fcBool cfg.antialias}
</edit>
<edit mode="append" name="rgba">
<const>${cfg.subpixel.rgba}</const>
</edit>
<edit mode="append" name="lcdfilter">
<const>lcd${cfg.subpixel.lcdfilter}</const>
</edit>
</match>
</fontconfig>
'';
# reject Type 1 fonts
# priority 53
rejectType1 = pkgs.writeText "fc-53-nixos-reject-type1.conf" ''
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<!-- Reject Type 1 fonts -->
<selectfont>
<rejectfont>
<pattern>
<patelt name="fontformat"><string>Type 1</string></patelt>
</pattern>
</rejectfont>
</selectfont>
</fontconfig>
'';
# fontconfig configuration package
confPkg = pkgs.runCommand "fontconfig-conf" { preferLocalBuild = true; } ''
support_folder=$out/etc/fonts
latest_folder=$out/etc/fonts/${latestVersion}
mkdir -p $support_folder/conf.d
mkdir -p $latest_folder/conf.d
# fonts.conf
ln -s ${supportFontsConf} $support_folder/fonts.conf
ln -s ${latestPkg.out}/etc/fonts/fonts.conf \
$latest_folder/fonts.conf
# fontconfig default config files
ln -s ${supportPkg.out}/etc/fonts/conf.d/*.conf \
$support_folder/conf.d/
ln -s ${latestPkg.out}/etc/fonts/conf.d/*.conf \
$latest_folder/conf.d/
# update latest 51-local.conf path to look at the latest local.conf
rm $latest_folder/conf.d/51-local.conf
substitute ${latestPkg.out}/etc/fonts/conf.d/51-local.conf \
$latest_folder/conf.d/51-local.conf \
--replace local.conf /etc/fonts/${latestVersion}/local.conf
# 00-nixos-cache.conf
ln -s ${cacheConfSupport} \
$support_folder/conf.d/00-nixos-cache.conf
ln -s ${cacheConfLatest} $latest_folder/conf.d/00-nixos-cache.conf
# 10-nixos-rendering.conf
ln -s ${renderConf} $support_folder/conf.d/10-nixos-rendering.conf
ln -s ${renderConf} $latest_folder/conf.d/10-nixos-rendering.conf
# 50-user.conf
${optionalString (! cfg.includeUserConf) ''
rm $support_folder/conf.d/50-user.conf
rm $latest_folder/conf.d/50-user.conf
${optionalString (cfg.dpi != 0) ''
<match target="pattern">
<edit name="dpi" mode="assign">
<double>${toString cfg.dpi}</double>
</edit>
</match>
''}
# local.conf (indirect priority 51)
${optionalString (cfg.localConf != "") ''
ln -s ${localConf} $support_folder/local.conf
ln -s ${localConf} $latest_folder/local.conf
''}
</fontconfig>
'';
# 52-nixos-default-fonts.conf
ln -s ${defaultFontsConf} $support_folder/conf.d/52-nixos-default-fonts.conf
ln -s ${defaultFontsConf} $latest_folder/conf.d/52-nixos-default-fonts.conf
# local configuration file
localConf = pkgs.writeText "fc-local.conf" cfg.localConf;
# 53-nixos-bitmaps.conf
ln -s ${rejectBitmaps} $support_folder/conf.d/53-nixos-bitmaps.conf
ln -s ${rejectBitmaps} $latest_folder/conf.d/53-nixos-bitmaps.conf
# default fonts configuration file
# priority 52
defaultFontsConf =
let genDefault = fonts: name:
optionalString (fonts != []) ''
<alias>
<family>${name}</family>
<prefer>
${concatStringsSep ""
(map (font: ''
<family>${font}</family>
'') fonts)}
</prefer>
</alias>
'';
in
pkgs.writeText "fc-52-nixos-default-fonts.conf" ''
<?xml version='1.0'?>
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
<fontconfig>
${optionalString (! cfg.allowType1) ''
# 53-nixos-reject-type1.conf
ln -s ${rejectType1} $support_folder/conf.d/53-nixos-reject-type1.conf
ln -s ${rejectType1} $latest_folder/conf.d/53-nixos-reject-type1.conf
''}
'';
<!-- Default fonts -->
${genDefault cfg.defaultFonts.sansSerif "sans-serif"}
# Package with configuration files
# this merge all the packages in the fonts.fontconfig.confPackages list
fontconfigEtc = pkgs.buildEnv {
name = "fontconfig-etc";
paths = cfg.confPackages;
ignoreCollisions = true;
};
${genDefault cfg.defaultFonts.serif "serif"}
${genDefault cfg.defaultFonts.monospace "monospace"}
</fontconfig>
'';
# bitmap font options
# priority 53
rejectBitmaps = pkgs.writeText "fc-53-no-bitmaps.conf" ''
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
${optionalString (!cfg.allowBitmaps) ''
<!-- Reject bitmap fonts -->
<selectfont>
<rejectfont>
<pattern>
<patelt name="scalable"><bool>false</bool></patelt>
</pattern>
</rejectfont>
</selectfont>
''}
<!-- Use embedded bitmaps in fonts like Calibri? -->
<match target="font">
<edit name="embeddedbitmap" mode="assign">
${fcBool cfg.useEmbeddedBitmaps}
</edit>
</match>
</fontconfig>
'';
# reject Type 1 fonts
# priority 53
rejectType1 = pkgs.writeText "fc-53-nixos-reject-type1.conf" ''
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<!-- Reject Type 1 fonts -->
<selectfont>
<rejectfont>
<pattern>
<patelt name="fontformat"><string>Type 1</string></patelt>
</pattern>
</rejectfont>
</selectfont>
</fontconfig>
'';
# fontconfig configuration package
confPkg = pkgs.runCommand "fontconfig-conf" {
preferLocalBuild = true;
} ''
support_folder=$out/etc/fonts/conf.d
latest_folder=$out/etc/fonts/${latestVersion}/conf.d
mkdir -p $support_folder
mkdir -p $latest_folder
# fonts.conf
ln -s ${supportFontsConf} $support_folder/../fonts.conf
ln -s ${latestPkg.out}/etc/fonts/fonts.conf \
$latest_folder/../fonts.conf
# fontconfig default config files
ln -s ${supportPkg.out}/etc/fonts/conf.d/*.conf \
$support_folder/
ln -s ${latestPkg.out}/etc/fonts/conf.d/*.conf \
$latest_folder/
# update latest 51-local.conf path to look at the latest local.conf
rm $latest_folder/51-local.conf
substitute ${latestPkg.out}/etc/fonts/conf.d/51-local.conf \
$latest_folder/51-local.conf \
--replace local.conf /etc/fonts/${latestVersion}/local.conf
# 00-nixos-cache.conf
ln -s ${cacheConfSupport} \
$support_folder/00-nixos-cache.conf
ln -s ${cacheConfLatest} $latest_folder/00-nixos-cache.conf
# 10-nixos-rendering.conf
ln -s ${renderConf} $support_folder/10-nixos-rendering.conf
ln -s ${renderConf} $latest_folder/10-nixos-rendering.conf
# 50-user.conf
${optionalString (!cfg.includeUserConf) ''
rm $support_folder/50-user.conf
rm $latest_folder/50-user.conf
''}
# local.conf (indirect priority 51)
${optionalString (cfg.localConf != "") ''
ln -s ${localConf} $support_folder/../local.conf
ln -s ${localConf} $latest_folder/../local.conf
''}
# 52-nixos-default-fonts.conf
ln -s ${defaultFontsConf} $support_folder/52-nixos-default-fonts.conf
ln -s ${defaultFontsConf} $latest_folder/52-nixos-default-fonts.conf
# 53-no-bitmaps.conf
ln -s ${rejectBitmaps} $support_folder/53-no-bitmaps.conf
ln -s ${rejectBitmaps} $latest_folder/53-no-bitmaps.conf
${optionalString (!cfg.allowType1) ''
# 53-nixos-reject-type1.conf
ln -s ${rejectType1} $support_folder/53-nixos-reject-type1.conf
ln -s ${rejectType1} $latest_folder/53-nixos-reject-type1.conf
''}
'';
# Package with configuration files
# this merge all the packages in the fonts.fontconfig.confPackages list
fontconfigEtc = pkgs.buildEnv {
name = "fontconfig-etc";
paths = cfg.confPackages;
ignoreCollisions = true;
};
in
{

View file

@ -0,0 +1,102 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.qt5;
isQGnome = cfg.platformTheme == "gnome" && cfg.style == "adwaita";
isQtStyle = cfg.platformTheme == "gtk2" && cfg.style != "adwaita";
packages = if isQGnome then [ pkgs.qgnomeplatform pkgs.adwaita-qt ]
else if isQtStyle then [ pkgs.qtstyleplugins ]
else throw "`qt5.platformTheme` ${cfg.platformTheme} and `qt5.style` ${cfg.style} are not compatible.";
in
{
options = {
qt5 = {
enable = mkEnableOption "Qt5 theming configuration";
platformTheme = mkOption {
type = types.enum [
"gtk2"
"gnome"
];
example = "gnome";
relatedPackages = [
"qgnomeplatform"
["libsForQt5" "qtstyleplugins"]
];
description = ''
Selects the platform theme to use for Qt5 applications.</para>
<para>The options are
<variablelist>
<varlistentry>
<term><literal>gtk</literal></term>
<listitem><para>Use GTK theme with
<link xlink:href="https://github.com/qt/qtstyleplugins">qtstyleplugins</link>
</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>gnome</literal></term>
<listitem><para>Use GNOME theme with
<link xlink:href="https://github.com/FedoraQt/QGnomePlatform">qgnomeplatform</link>
</para></listitem>
</varlistentry>
</variablelist>
'';
};
style = mkOption {
type = types.enum [
"adwaita"
"cleanlooks"
"gtk2"
"motif"
"plastique"
];
example = "adwaita";
relatedPackages = [
"adwaita-qt"
["libsForQt5" "qtstyleplugins"]
];
description = ''
Selects the style to use for Qt5 applications.</para>
<para>The options are
<variablelist>
<varlistentry>
<term><literal>adwaita</literal></term>
<listitem><para>Use Adwaita Qt style with
<link xlink:href="https://github.com/FedoraQt/adwaita-qt">adwaita</link>
</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>cleanlooks</literal></term>
<term><literal>gtk2</literal></term>
<term><literal>motif</literal></term>
<term><literal>plastique</literal></term>
<listitem><para>Use styles from
<link xlink:href="https://github.com/qt/qtstyleplugins">qtstyleplugins</link>
</para></listitem>
</varlistentry>
</variablelist>
'';
};
};
};
config = mkIf cfg.enable {
environment.variables.QT_QPA_PLATFORMTHEME = cfg.platformTheme;
environment.variables.QT_STYLE_OVERRIDE = cfg.style;
environment.systemPackages = packages;
};
}

View file

@ -42,22 +42,16 @@ in
config = {
environment.etc."sysctl.d/nixos.conf".text =
environment.etc."sysctl.d/60-nixos.conf".text =
concatStrings (mapAttrsToList (n: v:
optionalString (v != null) "${n}=${if v == false then "0" else toString v}\n"
) config.boot.kernel.sysctl);
systemd.services.systemd-sysctl =
{ wantedBy = [ "multi-user.target" ];
restartTriggers = [ config.environment.etc."sysctl.d/nixos.conf".source ];
restartTriggers = [ config.environment.etc."sysctl.d/60-nixos.conf".source ];
};
# Enable hardlink and symlink restrictions. See
# https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=800179c9b8a1e796e441674776d11cd4c05d61d7
# for details.
boot.kernel.sysctl."fs.protected_hardlinks" = true;
boot.kernel.sysctl."fs.protected_symlinks" = true;
# Hide kernel pointers (e.g. in /proc/modules) for unprivileged
# users as these make it easier to exploit kernel vulnerabilities.
boot.kernel.sysctl."kernel.kptr_restrict" = 1;

View file

@ -267,6 +267,7 @@ foreach my $line (-f "/etc/shadow" ? read_file("/etc/shadow") : ()) {
next if !defined $u;
$hashedPassword = "!" if !$spec->{mutableUsers};
$hashedPassword = $u->{hashedPassword} if defined $u->{hashedPassword} && !$spec->{mutableUsers}; # FIXME
chomp $hashedPassword;
push @shadowNew, join(":", $name, $hashedPassword, @rest) . "\n";
$shadowSeen{$name} = 1;
}

View file

@ -0,0 +1,52 @@
# VTE
{ config, pkgs, lib, ... }:
with lib;
let
vteInitSnippet = ''
# Show current working directory in VTE terminals window title.
# Supports both bash and zsh, requires interactive shell.
. ${pkgs.vte}/etc/profile.d/vte.sh
'';
in
{
options = {
programs.bash.vteIntegration = mkOption {
default = false;
type = types.bool;
description = ''
Whether to enable Bash integration for VTE terminals.
This allows it to preserve the current directory of the shell
across terminals.
'';
};
programs.zsh.vteIntegration = mkOption {
default = false;
type = types.bool;
description = ''
Whether to enable Zsh integration for VTE terminals.
This allows it to preserve the current directory of the shell
across terminals.
'';
};
};
config = mkMerge [
(mkIf config.programs.bash.vteIntegration {
programs.bash.interactiveShellInit = mkBefore vteInitSnippet;
})
(mkIf config.programs.zsh.vteIntegration {
programs.zsh.interactiveShellInit = vteInitSnippet;
})
];
}

View file

@ -73,8 +73,8 @@ in
firmwareSize = mkOption {
type = types.int;
# As of 2019-05-31 the Raspberry pi firmware + u-bot takes ~13MiB
default = 20;
# As of 2019-08-18 the Raspberry pi firmware + u-boot takes ~18MiB
default = 30;
description = ''
Size of the /boot/firmware partition, in megabytes.
'';

View file

@ -251,7 +251,7 @@
gale = 223;
matrix-synapse = 224;
rspamd = 225;
rmilter = 226;
# rmilter = 226; # unused, removed 2019-08-22
cfdyndns = 227;
gammu-smsd = 228;
pdnsd = 229;
@ -340,6 +340,7 @@
cockroachdb = 313;
zoneminder = 314;
paperless = 315;
mailman = 316;
# When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
@ -559,7 +560,7 @@
gale = 223;
matrix-synapse = 224;
rspamd = 225;
rmilter = 226;
# rmilter = 226; # unused, removed 2019-08-22
cfdyndns = 227;
pdnsd = 229;
octoprint = 230;
@ -640,6 +641,7 @@
cockroachdb = 313;
zoneminder = 314;
paperless = 315;
mailman = 316;
# When adding a gid, make sure it doesn't match an existing
# uid. Users and groups with the same name should have equal

View file

@ -27,6 +27,7 @@
./config/nsswitch.nix
./config/power-management.nix
./config/pulseaudio.nix
./config/qt5.nix
./config/resolvconf.nix
./config/shells-environment.nix
./config/swap.nix
@ -37,6 +38,7 @@
./config/unix-odbc-drivers.nix
./config/users-groups.nix
./config/vpnc.nix
./config/vte.nix
./config/zram.nix
./hardware/acpilight.nix
./hardware/all-firmware.nix
@ -115,6 +117,7 @@
./programs/fuse.nix
./programs/gnome-disks.nix
./programs/gnome-documents.nix
./programs/gnome-terminal.nix
./programs/gpaste.nix
./programs/gnupg.nix
./programs/gphoto2.nix
@ -285,6 +288,7 @@
./services/desktops/flatpak.nix
./services/desktops/geoclue2.nix
./services/desktops/gsignond.nix
./services/desktops/gvfs.nix
./services/desktops/pipewire.nix
./services/desktops/gnome3/at-spi2-core.nix
./services/desktops/gnome3/chrome-gnome-shell.nix
@ -295,9 +299,7 @@
./services/desktops/gnome3/gnome-remote-desktop.nix
./services/desktops/gnome3/gnome-online-miners.nix
./services/desktops/gnome3/gnome-settings-daemon.nix
./services/desktops/gnome3/gnome-terminal-server.nix
./services/desktops/gnome3/gnome-user-share.nix
./services/desktops/gnome3/gvfs.nix
./services/desktops/gnome3/rygel.nix
./services/desktops/gnome3/seahorse.nix
./services/desktops/gnome3/sushi.nix
@ -385,7 +387,6 @@
./services/mail/spamassassin.nix
./services/mail/rspamd.nix
./services/mail/rss2email.nix
./services/mail/rmilter.nix
./services/mail/roundcube.nix
./services/mail/nullmailer.nix
./services/misc/airsonic.nix
@ -436,13 +437,13 @@
./services/misc/logkeys.nix
./services/misc/leaps.nix
./services/misc/lidarr.nix
./services/misc/mantisbt.nix
./services/misc/mathics.nix
./services/misc/matrix-synapse.nix
./services/misc/mbpfan.nix
./services/misc/mediatomb.nix
./services/misc/mesos-master.nix
./services/misc/mesos-slave.nix
./services/misc/metabase.nix
./services/misc/mwlib.nix
./services/misc/nix-daemon.nix
./services/misc/nix-gc.nix
@ -520,7 +521,6 @@
./services/monitoring/scollector.nix
./services/monitoring/smartd.nix
./services/monitoring/sysstat.nix
./services/monitoring/systemhealth.nix
./services/monitoring/teamviewer.nix
./services/monitoring/telegraf.nix
./services/monitoring/thanos.nix
@ -608,6 +608,7 @@
./services/networking/iodine.nix
./services/networking/iperf3.nix
./services/networking/ircd-hybrid/default.nix
./services/networking/jormungandr.nix
./services/networking/iwd.nix
./services/networking/keepalived/default.nix
./services/networking/keybase.nix
@ -647,6 +648,7 @@
./services/networking/nullidentdmod.nix
./services/networking/nylon.nix
./services/networking/ocserv.nix
./services/networking/ofono.nix
./services/networking/oidentd.nix
./services/networking/openfire.nix
./services/networking/openntpd.nix
@ -787,6 +789,7 @@
./services/web-apps/mattermost.nix
./services/web-apps/mediawiki.nix
./services/web-apps/miniflux.nix
./services/web-apps/moodle.nix
./services/web-apps/nextcloud.nix
./services/web-apps/nexus.nix
./services/web-apps/pgpkeyserver-lite.nix
@ -800,6 +803,7 @@
./services/web-apps/zabbix.nix
./services/web-servers/apache-httpd/default.nix
./services/web-servers/caddy.nix
./services/web-servers/darkhttpd.nix
./services/web-servers/fcgiwrap.nix
./services/web-servers/hitch/default.nix
./services/web-servers/hydron.nix
@ -862,7 +866,6 @@
./system/activation/activation-script.nix
./system/activation/top-level.nix
./system/boot/binfmt.nix
./system/boot/coredump.nix
./system/boot/emergency-mode.nix
./system/boot/grow-partition.nix
./system/boot/initrd-network.nix

View file

@ -14,8 +14,6 @@ with lib;
nix.allowedUsers = mkDefault [ "@users" ];
environment.memoryAllocator.provider = mkDefault "graphene-hardened";
security.hideProcessInformation = mkDefault true;
security.lockKernelModules = mkDefault true;
@ -95,23 +93,17 @@ with lib;
# Disable ftrace debugging
boot.kernel.sysctl."kernel.ftrace_enabled" = mkDefault false;
# Enable reverse path filtering (that is, do not attempt to route packets
# that "obviously" do not belong to the iface's network; dropped packets are
# logged as martians).
# Enable strict reverse path filtering (that is, do not attempt to route
# packets that "obviously" do not belong to the iface's network; dropped
# packets are logged as martians).
boot.kernel.sysctl."net.ipv4.conf.all.log_martians" = mkDefault true;
boot.kernel.sysctl."net.ipv4.conf.all.rp_filter" = mkDefault true;
boot.kernel.sysctl."net.ipv4.conf.all.rp_filter" = mkDefault "1";
boot.kernel.sysctl."net.ipv4.conf.default.log_martians" = mkDefault true;
boot.kernel.sysctl."net.ipv4.conf.default.rp_filter" = mkDefault true;
boot.kernel.sysctl."net.ipv4.conf.default.rp_filter" = mkDefault "1";
# Ignore broadcast ICMP (mitigate SMURF)
boot.kernel.sysctl."net.ipv4.icmp_echo_ignore_broadcasts" = mkDefault true;
# Ignore route information from sender
boot.kernel.sysctl."net.ipv4.conf.all.accept_source_route" = mkDefault false;
boot.kernel.sysctl."net.ipv4.conf.default.accept_source_route" = mkDefault false;
boot.kernel.sysctl."net.ipv6.conf.all.accept_source_route" = mkDefault false;
boot.kernel.sysctl."net.ipv6.conf.default.accept_source_route" = mkDefault false;
# Ignore incoming ICMP redirects (note: default is needed to ensure that the
# setting is applied to interfaces added after the sysctls are set)
boot.kernel.sysctl."net.ipv4.conf.all.accept_redirects" = mkDefault false;

View file

@ -34,11 +34,11 @@ in
services.dbus.packages = [ pkgs.gnome3.dconf ];
environment.variables.GIO_EXTRA_MODULES = optional cfg.enable
"${pkgs.gnome3.dconf.lib}/lib/gio/modules";
# https://github.com/NixOS/nixpkgs/pull/31891
#environment.variables.XDG_DATA_DIRS = optional cfg.enable
# "$(echo ${pkgs.gsettings-desktop-schemas}/share/gsettings-schemas/gsettings-desktop-schemas-*)";
# For dconf executable
environment.systemPackages = [ pkgs.gnome3.dconf ];
# Needed for unwrapped applications
environment.variables.GIO_EXTRA_MODULES = mkIf cfg.enable [ "${pkgs.gnome3.dconf.lib}/lib/gio/modules" ];
};
}

View file

@ -21,6 +21,7 @@ in
PAGER = mkDefault "less -R";
EDITOR = mkDefault "nano";
XCURSOR_PATH = [ "$HOME/.icons" ];
XDG_CONFIG_DIRS = [ "/etc/xdg" ]; # needs to be before profile-relative paths to allow changes through environment.etc
};
environment.profiles = mkAfter

View file

@ -0,0 +1,36 @@
# GNOME Terminal.
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.programs.gnome-terminal;
in
{
# Added 2019-08-19
imports = [
(mkRenamedOptionModule
[ "services" "gnome3" "gnome-terminal-server" "enable" ]
[ "programs" "gnome-terminal" "enable" ])
];
options = {
programs.gnome-terminal.enable = mkEnableOption "GNOME Terminal";
};
config = mkIf cfg.enable {
environment.systemPackages = [ pkgs.gnome3.gnome-terminal ];
services.dbus.packages = [ pkgs.gnome3.gnome-terminal ];
systemd.packages = [ pkgs.gnome3.gnome-terminal ];
programs.bash.vteIntegration = true;
programs.zsh.vteIntegration = true;
};
}

View file

@ -83,7 +83,8 @@ in
systemd.user.sockets.dirmngr = mkIf cfg.dirmngr.enable {
wantedBy = [ "sockets.target" ];
};
environment.systemPackages = with pkgs; [ cfg.package ];
systemd.packages = [ cfg.package ];
environment.interactiveShellInit = ''

View file

@ -69,9 +69,7 @@ in
promptInit = mkOption {
default = ''
if [ "$TERM" != dumb ]; then
autoload -U promptinit && promptinit && prompt walters
fi
autoload -U promptinit && promptinit && prompt walters && setopt prompt_sp
'';
description = ''
Shell script code used to initialise the zsh prompt.
@ -213,6 +211,15 @@ in
${cfg.promptInit}
# Need to disable features to support TRAMP
if [ "$TERM" = dumb ]; then
unsetopt zle prompt_cr prompt_subst
unfunction precmd preexec
unset RPS1 RPROMPT
PS1='$ '
PROMPT='$ '
fi
# Read system-wide modifications.
if test -f /etc/zshrc.local; then
. /etc/zshrc.local

View file

@ -72,8 +72,8 @@ with lib;
# PAM
(mkRenamedOptionModule [ "security" "pam" "enableU2F" ] [ "security" "pam" "u2f" "enable" ])
(mkRemovedOptionModule [ "services" "rmilter" "bindInetSockets" ] "Use services.rmilter.bindSocket.* instead")
(mkRemovedOptionModule [ "services" "rmilter" "bindUnixSockets" ] "Use services.rmilter.bindSocket.* instead")
# rmilter/rspamd
(mkRemovedOptionModule [ "services" "rmilter" ] "Use services.rspamd.* instead to set up milter service")
# Xsession script
(mkRenamedOptionModule [ "services" "xserver" "displayManager" "job" "logsXsession" ] [ "services" "xserver" "displayManager" "job" "logToFile" ])
@ -178,6 +178,9 @@ with lib;
The starting time can be configured via <literal>services.postgresqlBackup.startAt</literal>.
'')
# phpfpm
(mkRemovedOptionModule [ "services" "phpfpm" "poolConfigs" ] "Use services.phpfpm.pools instead.")
# zabbixServer
(mkRenamedOptionModule [ "services" "zabbixServer" "dbServer" ] [ "services" "zabbixServer" "database" "host" ])
@ -226,6 +229,7 @@ with lib;
(mkRemovedOptionModule [ "services" "mysql" "rootPassword" ] "Use socket authentication or set the password outside of the nix store.")
(mkRemovedOptionModule [ "services" "zabbixServer" "dbPassword" ] "Use services.zabbixServer.database.passwordFile instead.")
(mkRemovedOptionModule [ "systemd" "generator-packages" ] "Use systemd.packages instead.")
(mkRemovedOptionModule [ "systemd" "coredump" "enable" ] "Enabled by default. Set boot.kernel.sysctl.\"kernel.core_pattern\" = \"core\"; to disable.")
# ZSH
(mkRenamedOptionModule [ "programs" "zsh" "enableSyntaxHighlighting" ] [ "programs" "zsh" "syntaxHighlighting" "enable" ])
@ -276,7 +280,7 @@ with lib;
throw "services.redshift.longitude is set to null, you can remove this"
else builtins.fromJSON value))
] ++ (flip map [ "blackboxExporter" "collectdExporter" "fritzboxExporter"
] ++ (forEach [ "blackboxExporter" "collectdExporter" "fritzboxExporter"
"jsonExporter" "minioExporter" "nginxExporter" "nodeExporter"
"snmpExporter" "unifiExporter" "varnishExporter" ]
(opt: mkRemovedOptionModule [ "services" "prometheus" "${opt}" ] ''

View file

@ -19,6 +19,20 @@ in {
TCP: 9100 - 9200
'';
};
user = mkOption {
type = types.str;
default = "roon-server";
description = ''
User to run the Roon Server as.
'';
};
group = mkOption {
type = types.str;
default = "roon-server";
description = ''
Group to run the Roon Server as.
'';
};
};
};
@ -33,8 +47,8 @@ in {
serviceConfig = {
ExecStart = "${pkgs.roon-server}/opt/start.sh";
LimitNOFILE = 8192;
DynamicUser = true;
SupplementaryGroups = "audio";
User = cfg.user;
Group = cfg.group;
StateDirectory = name;
};
};
@ -45,5 +59,15 @@ in {
];
allowedUDPPorts = [ 9003 ];
};
users.groups."${cfg.group}" = {};
users.users."${cfg.user}" =
if cfg.user == "roon-server" then {
isSystemUser = true;
description = "Roon Server user";
groups = [ cfg.group "audio" ];
}
else {};
};
}

View file

@ -103,7 +103,6 @@ in
LockPersonality = true;
RestrictRealtime = true;
PrivateMounts = true;
PrivateUsers = true;
MemoryDenyWriteExecute = true;
};
};

View file

@ -30,9 +30,9 @@ with lib;
config = mkIf config.services.gnome3.gnome-online-accounts.enable {
environment.systemPackages = [ pkgs.gnome3.gnome-online-accounts ];
environment.systemPackages = [ pkgs.gnome-online-accounts ];
services.dbus.packages = [ pkgs.gnome3.gnome-online-accounts ];
services.dbus.packages = [ pkgs.gnome-online-accounts ];
};

View file

@ -1,41 +0,0 @@
# GNOME Documents daemon.
{ config, pkgs, lib, ... }:
with lib;
{
###### interface
options = {
services.gnome3.gnome-terminal-server = {
enable = mkOption {
type = types.bool;
default = false;
description = ''
Whether to enable GNOME Terminal server service,
needed for gnome-terminal.
'';
};
};
};
###### implementation
config = mkIf config.services.gnome3.gnome-terminal-server.enable {
environment.systemPackages = [ pkgs.gnome3.gnome-terminal ];
services.dbus.packages = [ pkgs.gnome3.gnome-terminal ];
systemd.packages = [ pkgs.gnome3.gnome-terminal ];
};
}

View file

@ -1,43 +0,0 @@
# gvfs backends
{ config, lib, pkgs, ... }:
with lib;
{
###### interface
options = {
services.gnome3.gvfs = {
enable = mkOption {
type = types.bool;
default = false;
description = ''
Whether to enable gvfs backends, userspace virtual filesystem used
by GNOME components via D-Bus.
'';
};
};
};
###### implementation
config = mkIf config.services.gnome3.gvfs.enable {
environment.systemPackages = [ pkgs.gnome3.gvfs ];
services.dbus.packages = [ pkgs.gnome3.gvfs ];
systemd.packages = [ pkgs.gnome3.gvfs ];
services.udev.packages = [ pkgs.libmtp.bin ];
};
}

View file

@ -30,11 +30,11 @@ with lib;
config = mkIf config.services.gnome3.tracker-miners.enable {
environment.systemPackages = [ pkgs.gnome3.tracker-miners ];
environment.systemPackages = [ pkgs.tracker-miners ];
services.dbus.packages = [ pkgs.gnome3.tracker-miners ];
services.dbus.packages = [ pkgs.tracker-miners ];
systemd.packages = [ pkgs.gnome3.tracker-miners ];
systemd.packages = [ pkgs.tracker-miners ];
};

View file

@ -30,11 +30,11 @@ with lib;
config = mkIf config.services.gnome3.tracker.enable {
environment.systemPackages = [ pkgs.gnome3.tracker ];
environment.systemPackages = [ pkgs.tracker ];
services.dbus.packages = [ pkgs.gnome3.tracker ];
services.dbus.packages = [ pkgs.tracker ];
systemd.packages = [ pkgs.gnome3.tracker ];
systemd.packages = [ pkgs.tracker ];
};

View file

@ -0,0 +1,59 @@
# GVfs
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.gvfs;
in
{
# Added 2019-08-19
imports = [
(mkRenamedOptionModule
[ "services" "gnome3" "gvfs" "enable" ]
[ "services" "gvfs" "enable" ])
];
###### interface
options = {
services.gvfs = {
enable = mkEnableOption "GVfs, a userspace virtual filesystem";
# gvfs can be built with multiple configurations
package = mkOption {
type = types.package;
default = pkgs.gnome3.gvfs;
description = "Which GVfs package to use.";
};
};
};
###### implementation
config = mkIf cfg.enable {
environment.systemPackages = [ cfg.package ];
services.dbus.packages = [ cfg.package ];
systemd.packages = [ cfg.package ];
services.udev.packages = [ pkgs.libmtp.bin ];
# Needed for unwrapped applications
environment.variables.GIO_EXTRA_MODULES = [ "${cfg.package}/lib/gio/modules" ];
};
}

View file

@ -4,6 +4,12 @@ with lib;
let
cfg = config.services.trezord;
in {
### docs
meta = {
doc = ./trezord.xml;
};
### interface
@ -16,6 +22,22 @@ in {
Enable Trezor bridge daemon, for use with Trezor hardware bitcoin wallets.
'';
};
emulator.enable = mkOption {
type = types.bool;
default = false;
description = ''
Enable Trezor emulator support.
'';
};
emulator.port = mkOption {
type = types.port;
default = 21324;
description = ''
Listening port for the Trezor emulator.
'';
};
};
};
@ -44,7 +66,7 @@ in {
path = [];
serviceConfig = {
Type = "simple";
ExecStart = "${pkgs.trezord}/bin/trezord-go";
ExecStart = "${pkgs.trezord}/bin/trezord-go ${optionalString cfg.emulator.enable "-e ${builtins.toString cfg.emulator.port}"}";
User = "trezord";
};
};

View file

@ -0,0 +1,26 @@
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
version="5.0"
xml:id="trezor">
<title>Trezor</title>
<para>
Trezor is an open-source cryptocurrency hardware wallet and security token
allowing secure storage of private keys.
</para>
<para>
It offers advanced features such U2F two-factor authorization, SSH login
through
<link xlink:href="https://wiki.trezor.io/Apps:SSH_agent">Trezor SSH agent</link>,
<link xlink:href="https://wiki.trezor.io/GPG">GPG</link> and a
<link xlink:href="https://wiki.trezor.io/Trezor_Password_Manager">password manager</link>.
For more information, guides and documentation, see <link xlink:href="https://wiki.trezor.io"/>.
</para>
<para>
To enable Trezor support, add the following to your <filename>configuration.nix</filename>:
<programlisting>
<xref linkend="opt-services.trezord.enable"/> = true;
</programlisting>
This will add all necessary udev rules and start Trezor Bridge.
</para>
</chapter>

View file

@ -4,6 +4,7 @@ with lib;
let
cfg = config.services.awstats;
httpd = config.services.httpd;
package = pkgs.awstats;
in
@ -67,50 +68,43 @@ in
environment.etc."awstats/awstats.conf".source = pkgs.runCommand "awstats.conf"
{ preferLocalBuild = true; }
( let
cfg-httpd = config.services.httpd;
logFormat =
if cfg-httpd.logFormat == "combined" then "1" else
if cfg-httpd.logFormat == "common" then "4" else
throw "awstats service doesn't support Apache log format `${cfg-httpd.logFormat}`";
if httpd.logFormat == "combined" then "1" else
if httpd.logFormat == "common" then "4" else
throw "awstats service doesn't support Apache log format `${httpd.logFormat}`";
in
''
sed \
-e 's|^\(DirData\)=.*$|\1="${cfg.vardir}"|' \
-e 's|^\(DirIcons\)=.*$|\1="icons"|' \
-e 's|^\(CreateDirDataIfNotExists\)=.*$|\1=1|' \
-e 's|^\(SiteDomain\)=.*$|\1="${cfg-httpd.hostName}"|' \
-e 's|^\(LogFile\)=.*$|\1="${cfg-httpd.logDir}/access_log"|' \
-e 's|^\(SiteDomain\)=.*$|\1="${httpd.hostName}"|' \
-e 's|^\(LogFile\)=.*$|\1="${httpd.logDir}/access_log"|' \
-e 's|^\(LogFormat\)=.*$|\1=${logFormat}|' \
< '${package.out}/wwwroot/cgi-bin/awstats.model.conf' > "$out"
echo '${cfg.extraConfig}' >> "$out"
'');
# The httpd sub-service showing awstats.
services.httpd.enable = mkIf cfg.service.enable true;
services.httpd.extraSubservices = mkIf cfg.service.enable [ { function = { serverInfo, ... }: {
extraConfig =
''
Alias ${cfg.service.urlPrefix}/classes "${package.out}/wwwroot/classes/"
Alias ${cfg.service.urlPrefix}/css "${package.out}/wwwroot/css/"
Alias ${cfg.service.urlPrefix}/icons "${package.out}/wwwroot/icon/"
ScriptAlias ${cfg.service.urlPrefix}/ "${package.out}/wwwroot/cgi-bin/"
systemd.tmpfiles.rules = optionals cfg.service.enable [
"d '${cfg.vardir}' - ${httpd.user} ${httpd.group} - -"
"Z '${cfg.vardir}' - ${httpd.user} ${httpd.group} - -"
];
<Directory "${package.out}/wwwroot">
Options None
AllowOverride None
Order allow,deny
Allow from all
</Directory>
'';
startupScript =
let
inherit (serverInfo.serverConfig) user group;
in pkgs.writeScript "awstats_startup.sh"
''
mkdir -p '${cfg.vardir}'
chown '${user}:${group}' '${cfg.vardir}'
'';
};}];
# The httpd sub-service showing awstats.
services.httpd = optionalAttrs cfg.service.enable {
enable = true;
extraConfig = ''
Alias ${cfg.service.urlPrefix}/classes "${package.out}/wwwroot/classes/"
Alias ${cfg.service.urlPrefix}/css "${package.out}/wwwroot/css/"
Alias ${cfg.service.urlPrefix}/icons "${package.out}/wwwroot/icon/"
ScriptAlias ${cfg.service.urlPrefix}/ "${package.out}/wwwroot/cgi-bin/"
<Directory "${package.out}/wwwroot">
Options None
Require all granted
</Directory>
'';
};
systemd.services.awstats-update = mkIf (cfg.updateAt != null) {
description = "awstats log collector";

View file

@ -1,252 +0,0 @@
{ config, lib, pkgs, ... }:
with lib;
let
rspamdCfg = config.services.rspamd;
postfixCfg = config.services.postfix;
cfg = config.services.rmilter;
inetSocket = addr: port: "inet:${addr}:${toString port}";
unixSocket = sock: "unix:${sock}";
systemdSocket = if cfg.bindSocket.type == "unix" then cfg.bindSocket.path
else "${cfg.bindSocket.address}:${toString cfg.bindSocket.port}";
rmilterSocket = if cfg.bindSocket.type == "unix" then unixSocket cfg.bindSocket.path
else inetSocket cfg.bindSocket.address cfg.bindSocket.port;
rmilterConf = ''
pidfile = /run/rmilter/rmilter.pid;
bind_socket = ${if cfg.socketActivation then "fd:3" else rmilterSocket};
tempdir = /tmp;
'' + (with cfg.rspamd; if enable then ''
spamd {
servers = ${concatStringsSep ", " servers};
connect_timeout = 1s;
results_timeout = 20s;
error_time = 10;
dead_time = 300;
maxerrors = 10;
reject_message = "${rejectMessage}";
${optionalString (length whitelist != 0) "whitelist = ${concatStringsSep ", " whitelist};"}
# rspamd_metric - metric for using with rspamd
# Default: "default"
rspamd_metric = "default";
${extraConfig}
};
'' else "") + cfg.extraConfig;
rmilterConfigFile = pkgs.writeText "rmilter.conf" rmilterConf;
in
{
###### interface
options = {
services.rmilter = {
enable = mkOption {
type = types.bool;
default = false;
description = "Whether to run the rmilter daemon.";
};
debug = mkOption {
type = types.bool;
default = false;
description = "Whether to run the rmilter daemon in debug mode.";
};
user = mkOption {
type = types.string;
default = "rmilter";
description = ''
User to use when no root privileges are required.
'';
};
group = mkOption {
type = types.string;
default = "rmilter";
description = ''
Group to use when no root privileges are required.
'';
};
bindSocket.type = mkOption {
type = types.enum [ "unix" "inet" ];
default = "unix";
description = ''
What kind of socket rmilter should listen on. Either "unix"
for an Unix domain socket or "inet" for a TCP socket.
'';
};
bindSocket.path = mkOption {
type = types.str;
default = "/run/rmilter.sock";
description = ''
Path to Unix domain socket to listen on.
'';
};
bindSocket.address = mkOption {
type = types.str;
default = "[::1]";
example = "0.0.0.0";
description = ''
Inet address to listen on.
'';
};
bindSocket.port = mkOption {
type = types.int;
default = 11990;
description = ''
Inet port to listen on.
'';
};
socketActivation = mkOption {
type = types.bool;
default = true;
description = ''
Enable systemd socket activation for rmilter.
Disabling socket activation is not recommended when a Unix
domain socket is used and could lead to incorrect
permissions.
'';
};
rspamd = {
enable = mkOption {
type = types.bool;
default = rspamdCfg.enable;
description = "Whether to use rspamd to filter mails";
};
servers = mkOption {
type = types.listOf types.str;
default = ["r:/run/rspamd/rspamd.sock"];
description = ''
Spamd socket definitions.
Is server name is prefixed with r: it is rspamd server.
'';
};
whitelist = mkOption {
type = types.listOf types.str;
default = [ ];
description = "list of ips or nets that should be not checked with spamd";
};
rejectMessage = mkOption {
type = types.str;
default = "Spam message rejected; If this is not spam contact abuse";
description = "reject message for spam";
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = "Custom snippet to append to end of `spamd' section";
};
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = "Custom snippet to append to rmilter config";
};
postfix = {
enable = mkOption {
type = types.bool;
default = false;
description = "Add rmilter to postfix main.conf";
};
configFragment = mkOption {
type = types.str;
description = "Addon to postfix configuration";
default = ''
smtpd_milters = ${rmilterSocket}
milter_protocol = 6
milter_mail_macros = i {mail_addr} {client_addr} {client_name} {auth_authen}
'';
};
};
};
};
###### implementation
config = mkMerge [
(mkIf cfg.enable {
warnings = [
''`config.services.rmilter' is deprecated, `rmilter' deprecated and unsupported by upstream, and will be removed from next releases. Use built-in rspamd milter instead.''
];
users.users = singleton {
name = cfg.user;
description = "rmilter daemon";
uid = config.ids.uids.rmilter;
group = cfg.group;
};
users.groups = singleton {
name = cfg.group;
gid = config.ids.gids.rmilter;
};
systemd.services.rmilter = {
description = "Rmilter Service";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
serviceConfig = {
ExecStart = "${pkgs.rmilter}/bin/rmilter ${optionalString cfg.debug "-d"} -n -c ${rmilterConfigFile}";
ExecReload = "${pkgs.coreutils}/bin/kill -USR1 $MAINPID";
User = cfg.user;
Group = cfg.group;
PermissionsStartOnly = true;
Restart = "always";
RuntimeDirectory = "rmilter";
RuntimeDirectoryMode = "0750";
};
};
systemd.sockets.rmilter = mkIf cfg.socketActivation {
description = "Rmilter service socket";
wantedBy = [ "sockets.target" ];
socketConfig = {
ListenStream = systemdSocket;
SocketUser = cfg.user;
SocketGroup = cfg.group;
SocketMode = "0660";
};
};
})
(mkIf (cfg.enable && cfg.rspamd.enable && rspamdCfg.enable) {
users.users.${cfg.user}.extraGroups = [ rspamdCfg.group ];
})
(mkIf (cfg.enable && cfg.postfix.enable) {
services.postfix.extraConfig = cfg.postfix.configFragment;
users.users.${postfixCfg.user}.extraGroups = [ cfg.group ];
})
];
}

View file

@ -4,6 +4,7 @@ with lib;
let
cfg = config.services.roundcube;
fpm = config.services.phpfpm.pools.roundcube;
in
{
options.services.roundcube = {
@ -105,7 +106,7 @@ in
extraConfig = ''
location ~* \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/phpfpm/roundcube;
fastcgi_pass unix:${fpm.socket};
include ${pkgs.nginx}/conf/fastcgi_params;
include ${pkgs.nginx}/conf/fastcgi.conf;
}
@ -119,24 +120,27 @@ in
enable = true;
};
services.phpfpm.poolConfigs.roundcube = ''
listen = /run/phpfpm/roundcube
listen.owner = nginx
listen.group = nginx
listen.mode = 0660
user = nginx
pm = dynamic
pm.max_children = 75
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 20
pm.max_requests = 500
php_admin_value[error_log] = 'stderr'
php_admin_flag[log_errors] = on
php_admin_value[post_max_size] = 25M
php_admin_value[upload_max_filesize] = 25M
catch_workers_output = yes
'';
services.phpfpm.pools.roundcube = {
user = "nginx";
phpOptions = ''
error_log = 'stderr'
log_errors = on
post_max_size = 25M
upload_max_filesize = 25M
'';
settings = mapAttrs (name: mkDefault) {
"listen.owner" = "nginx";
"listen.group" = "nginx";
"listen.mode" = "0660";
"pm" = "dynamic";
"pm.max_children" = 75;
"pm.start_servers" = 2;
"pm.min_spare_servers" = 1;
"pm.max_spare_servers" = 20;
"pm.max_requests" = 500;
"catch_workers_output" = true;
};
};
systemd.services.phpfpm-roundcube.after = [ "roundcube-setup.service" ];
systemd.services.roundcube-setup = let

View file

@ -659,7 +659,7 @@ in {
fi
# We remove potentially broken links to old gitlab-shell versions
rm -f ${cfg.statePath}/repositories/**/*.git/hooks
rm -Rf ${cfg.statePath}/repositories/**/*.git/hooks
${pkgs.sudo}/bin/sudo -u ${cfg.user} -H ${pkgs.git}/bin/git config --global core.autocrlf "input"
'';

View file

@ -1,68 +0,0 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.mantisbt;
freshInstall = cfg.extraConfig == "";
# combined code+config directory
mantisbt = let
config_inc = pkgs.writeText "config_inc.php" ("<?php\n" + cfg.extraConfig);
src = pkgs.fetchurl {
url = "mirror://sourceforge/mantisbt/${name}.tar.gz";
sha256 = "1pl6xn793p3mxc6ibpr2bhg85vkdlcf57yk7pfc399g47l8x4508";
};
name = "mantisbt-1.2.19";
in
# We have to copy every time; otherwise config won't be found.
pkgs.runCommand name
{ preferLocalBuild = true; allowSubstitutes = false; }
(''
mkdir -p "$out"
cd "$out"
tar -xf '${src}' --strip-components=1
ln -s '${config_inc}' config_inc.php
''
+ lib.optionalString (!freshInstall) "rm -r admin/"
);
in
{
options.services.mantisbt = {
enable = mkOption {
type = types.bool;
default = false;
description = ''
Enable the mantisbt web service.
This switches on httpd with PHP and database.
'';
};
urlPrefix = mkOption {
type = types.string;
default = "/mantisbt";
description = "The URL prefix under which the mantisbt service appears.";
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = ''
The contents of config_inc.php, without leading &lt;?php.
If left empty, the admin directory will be accessible.
'';
};
};
config = mkIf cfg.enable {
services.mysql.enable = true;
services.httpd.enable = true;
services.httpd.enablePHP = true;
# The httpd sub-service showing mantisbt.
services.httpd.extraSubservices = [ { function = { ... }: {
extraConfig =
''
Alias ${cfg.urlPrefix} "${mantisbt}"
'';
};}];
};
}

View file

@ -684,7 +684,7 @@ in {
fi
'';
serviceConfig = {
Type = "simple";
Type = "notify";
User = "matrix-synapse";
Group = "matrix-synapse";
WorkingDirectory = cfg.dataDir;

View file

@ -0,0 +1,103 @@
{ config, lib, pkgs, ... }:
let
cfg = config.services.metabase;
inherit (lib) mkEnableOption mkIf mkOption;
inherit (lib) optional optionalAttrs types;
dataDir = "/var/lib/metabase";
in {
options = {
services.metabase = {
enable = mkEnableOption "Metabase service";
listen = {
ip = mkOption {
type = types.str;
default = "0.0.0.0";
description = ''
IP address that Metabase should listen on.
'';
};
port = mkOption {
type = types.port;
default = 3000;
description = ''
Listen port for Metabase.
'';
};
};
ssl = {
enable = mkOption {
type = types.bool;
default = false;
description = ''
Whether to enable SSL (https) support.
'';
};
port = mkOption {
type = types.port;
default = 8443;
description = ''
Listen port over SSL (https) for Metabase.
'';
};
keystore = mkOption {
type = types.nullOr types.path;
default = "${dataDir}/metabase.jks";
example = "/etc/secrets/keystore.jks";
description = ''
<link xlink:href="https://www.digitalocean.com/community/tutorials/java-keytool-essentials-working-with-java-keystores">Java KeyStore</link> file containing the certificates.
'';
};
};
openFirewall = mkOption {
type = types.bool;
default = false;
description = ''
Open ports in the firewall for Metabase.
'';
};
};
};
config = mkIf cfg.enable {
systemd.services.metabase = {
description = "Metabase server";
wantedBy = [ "multi-user.target" ];
after = [ "network-online.target" ];
environment = {
MB_PLUGINS_DIR = "${dataDir}/plugins";
MB_DB_FILE = "${dataDir}/metabase.db";
MB_JETTY_HOST = cfg.listen.ip;
MB_JETTY_PORT = toString cfg.listen.port;
} // optionalAttrs (cfg.ssl.enable) {
MB_JETTY_SSL = true;
MB_JETTY_SSL_PORT = toString cfg.ssl.port;
MB_JETTY_SSL_KEYSTORE = cfg.ssl.keystore;
};
serviceConfig = {
DynamicUser = true;
StateDirectory = baseNameOf dataDir;
ExecStart = "${pkgs.metabase}/bin/metabase";
};
};
networking.firewall = mkIf cfg.openFirewall {
allowedTCPPorts = [ cfg.listen.port ] ++ optional cfg.ssl.enable cfg.ssl.port;
};
};
}

View file

@ -2,6 +2,7 @@
let
cfg = config.services.zoneminder;
fpm = config.services.phpfpm.pools.zoneminder;
pkg = pkgs.zoneminder;
dirName = pkg.dirName;
@ -19,8 +20,6 @@ let
useCustomDir = cfg.storageDir != null;
socket = "/run/phpfpm/${dirName}.sock";
zms = "/cgi-bin/zms";
dirs = dirList: [ dirName ] ++ map (e: "${dirName}/${e}") dirList;
@ -201,7 +200,10 @@ in {
"zoneminder/80-nixos.conf".source = configFile;
};
networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall [ cfg.port ];
networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall [
cfg.port
6802 # zmtrigger
];
services = {
fcgiwrap = lib.mkIf useNginx {
@ -274,7 +276,7 @@ in {
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_param HTTP_PROXY "";
fastcgi_pass unix:${socket};
fastcgi_pass unix:${fpm.socket};
}
}
'';
@ -284,30 +286,27 @@ in {
phpfpm = lib.mkIf useNginx {
pools.zoneminder = {
listen = socket;
inherit user group;
phpOptions = ''
date.timezone = "${config.time.timeZone}"
${lib.concatStringsSep "\n" (map (e:
"extension=${e.pkg}/lib/php/extensions/${e.name}.so") phpExtensions)}
'';
extraConfig = ''
user = ${user}
group = ${group}
settings = lib.mapAttrs (name: lib.mkDefault) {
"listen.owner" = user;
"listen.group" = group;
"listen.mode" = "0660";
listen.owner = ${user}
listen.group = ${group}
listen.mode = 0660
pm = dynamic
pm.start_servers = 1
pm.min_spare_servers = 1
pm.max_spare_servers = 2
pm.max_requests = 500
pm.max_children = 5
pm.status_path = /$pool-status
ping.path = /$pool-ping
'';
"pm" = "dynamic";
"pm.start_servers" = 1;
"pm.min_spare_servers" = 1;
"pm.max_spare_servers" = 2;
"pm.max_requests" = 500;
"pm.max_children" = 5;
"pm.status_path" = "/$pool-status";
"ping.path" = "/$pool-ping";
};
};
};
};

View file

@ -84,6 +84,16 @@ in {
type = types.bool;
description = "Cadvisor storage driver, enable secure communication.";
};
extraOptions = mkOption {
type = types.listOf types.str;
default = [];
description = ''
Additional cadvisor options.
See <link xlink:href='https://github.com/google/cadvisor/blob/master/docs/runtime_options.md'/> for available options.
'';
};
};
};
@ -112,6 +122,7 @@ in {
-logtostderr=true \
-listen_ip="${cfg.listenAddress}" \
-port="${toString cfg.port}" \
${escapeShellArgs cfg.extraOptions} \
${optionalString (cfg.storageDriver != null) ''
-storage_driver "${cfg.storageDriver}" \
-storage_driver_user "${cfg.storageDriverHost}" \

View file

@ -11,7 +11,7 @@ let
healthLauncher = writeScriptBin "riemann-health" ''
#!/bin/sh
exec ${pkgs.riemann-tools}/bin/riemann-health --host ${riemannHost}
exec ${pkgs.riemann-tools}/bin/riemann-health ${builtins.concatStringsSep " " cfg.extraArgs} --host ${riemannHost}
'';
@ -34,8 +34,16 @@ in {
Address of the host riemann node. Defaults to localhost.
'';
};
extraArgs = mkOption {
type = types.listOf types.string;
default = [];
description = ''
A list of commandline-switches forwarded to a riemann-tool.
See for example `riemann-health --help` for available options.
'';
example = ["-p 5555" "--timeout=30" "--attribute=myattribute=42"];
};
};
};
config = mkIf cfg.enableHealth {

View file

@ -1,133 +0,0 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.systemhealth;
systemhealth = with pkgs; stdenv.mkDerivation {
name = "systemhealth-1.0";
src = fetchurl {
url = "https://www.brianlane.com/downloads/systemhealth/systemhealth-1.0.tar.bz2";
sha256 = "1q69lz7hmpbdpbz36zb06nzfkj651413n9icx0njmyr3xzq1j9qy";
};
buildInputs = [ python ];
installPhase = ''
mkdir -p $out/bin
# Make it work for kernels 3.x, not so different than 2.6
sed -i 's/2\.6/4.0/' system_health.py
cp system_health.py $out/bin
'';
};
rrdDir = "/var/lib/health/rrd";
htmlDir = "/var/lib/health/html";
configFile = rrdDir + "/.syshealthrc";
# The program will try to read $HOME/.syshealthrc, so we set the proper home.
command = "HOME=${rrdDir} ${systemhealth}/bin/system_health.py";
cronJob = ''
*/5 * * * * wwwrun ${command} --log
5 * * * * wwwrun ${command} --graph
'';
nameEqualName = s: "${s} = ${s}";
interfacesSection = concatStringsSep "\n" (map nameEqualName cfg.interfaces);
driveLine = d: "${d.path} = ${d.name}";
drivesSection = concatStringsSep "\n" (map driveLine cfg.drives);
in
{
options = {
services.systemhealth = {
enable = mkOption {
default = false;
description = ''
Enable the system health monitor and its generation of graphs.
'';
};
urlPrefix = mkOption {
default = "/health";
description = ''
The URL prefix under which the System Health web pages appear in httpd.
'';
};
interfaces = mkOption {
default = [ "lo" ];
example = [ "lo" "eth0" "eth1" ];
description = ''
Interfaces to monitor (minimum one).
'';
};
drives = mkOption {
default = [ ];
example = [ { name = "root"; path = "/"; } ];
description = ''
Drives to monitor.
'';
};
};
};
config = mkIf cfg.enable {
services.cron.systemCronJobs = [ cronJob ];
system.activationScripts.systemhealth = stringAfter [ "var" ]
''
mkdir -p ${rrdDir} ${htmlDir}
chown wwwrun:wwwrun ${rrdDir} ${htmlDir}
cat >${configFile} << EOF
[paths]
rrdtool = ${pkgs.rrdtool}/bin/rrdtool
loadavg_rrd = loadavg
ps = /run/current-system/sw/bin/ps
df = /run/current-system/sw/bin/df
meminfo_rrd = meminfo
uptime_rrd = uptime
rrd_path = ${rrdDir}
png_path = ${htmlDir}
[processes]
[interfaces]
${interfacesSection}
[drives]
${drivesSection}
[graphs]
width = 400
time = ['-3hours', '-32hours', '-8days', '-5weeks', '-13months']
height = 100
[external]
EOF
chown wwwrun:wwwrun ${configFile}
${pkgs.su}/bin/su -s "/bin/sh" -c "${command} --check" wwwrun
${pkgs.su}/bin/su -s "/bin/sh" -c "${command} --html" wwwrun
'';
services.httpd.extraSubservices = [
{ function = f: {
extraConfig = ''
Alias ${cfg.urlPrefix} ${htmlDir}
<Directory ${htmlDir}>
Order allow,deny
Allow from all
</Directory>
'';
};
}
];
};
}

View file

@ -225,7 +225,7 @@ in
''
maxstartdelay = ${toString cfg.maxStartDelay}
${flip concatStringsSep (flip map (attrValues cfg.ups) (ups: ups.summary)) "
${flip concatStringsSep (forEach (attrValues cfg.ups) (ups: ups.summary)) "
"}
'';

View file

@ -55,6 +55,7 @@ in
sockets.u9fs = {
description = "U9fs Listening Socket";
wantedBy = [ "sockets.target" ];
after = [ "network.target" ];
inherit (cfg) listenStreams;
socketConfig.Accept = "yes";
};

View file

@ -44,9 +44,7 @@ let
parseModules = x:
x // { connectTo = mapAttrs (name: value: { inherit (value) password publicKey; }) x.connectTo; };
# would be nice to merge 'cfg' with a //,
# but the json nesting is wacky.
cjdrouteConf = builtins.toJSON ( {
cjdrouteConf = builtins.toJSON ( recursiveUpdate {
admin = {
bind = cfg.admin.bind;
password = "@CJDNS_ADMIN_PASSWORD@";
@ -71,7 +69,7 @@ let
security = [ { exemptAngel = 1; setuser = "nobody"; } ];
});
} cfg.extraConfig);
in
@ -91,6 +89,16 @@ in
'';
};
extraConfig = mkOption {
type = types.attrs;
default = {};
example = { router.interface.tunDevice = "tun10"; };
description = ''
Extra configuration, given as attrs, that will be merged recursively
with the rest of the JSON generated by this module, at the root node.
'';
};
confFile = mkOption {
type = types.nullOr types.path;
default = null;
@ -246,7 +254,10 @@ in
if cfg.confFile != null then "${pkg}/bin/cjdroute < ${cfg.confFile}" else
''
source /etc/cjdns.keys
echo '${cjdrouteConf}' | sed \
(cat <<'EOF'
${cjdrouteConf}
EOF
) | sed \
-e "s/@CJDNS_ADMIN_PASSWORD@/$CJDNS_ADMIN_PASSWORD/g" \
-e "s/@CJDNS_PRIVATE_KEY@/$CJDNS_PRIVATE_KEY/g" \
| ${pkg}/bin/cjdroute

View file

@ -15,7 +15,7 @@ let
++ cfg.extraConfigFiles;
devices = attrValues (filterAttrs (_: i: i != null) cfg.interface);
systemdDevices = flip map devices
systemdDevices = forEach devices
(i: "sys-subsystem-net-devices-${utils.escapeSystemdPath i}.device");
in
{

View file

@ -136,10 +136,16 @@ in
"/.dns/127.0.0.1#${toString cfg.dns.port}"
];
services.pdns-recursor.forwardZones = mkIf cfgs.pdns-recursor.resolveDNSChainQueries
{ bit = "127.0.0.1:${toString cfg.dns.port}";
dns = "127.0.0.1:${toString cfg.dns.port}";
};
services.pdns-recursor = mkIf cfgs.pdns-recursor.resolveDNSChainQueries {
forwardZones =
{ bit = "127.0.0.1:${toString cfg.dns.port}";
dns = "127.0.0.1:${toString cfg.dns.port}";
};
luaConfig =''
addNTA("bit", "namecoin doesn't support DNSSEC")
addNTA("dns", "namecoin doesn't support DNSSEC")
'';
};
users.users = singleton {
name = username;

View file

@ -7,7 +7,7 @@ let
inherit (lib) concatStringsSep optionalString;
cfg = config.services.hylafax;
mapModems = lib.flip map (lib.attrValues cfg.modems);
mapModems = lib.forEach (lib.attrValues cfg.modems);
mkConfigFile = name: conf:
# creates hylafax config file,

View file

@ -0,0 +1,97 @@
{ config, lib, pkgs, ... }:
let
cfg = config.services.jormungandr;
inherit (lib) mkEnableOption mkIf mkOption;
inherit (lib) optionalString types;
dataDir = "/var/lib/jormungandr";
# Default settings so far, as the service matures we will
# move these out as separate settings
configSettings = {
storage = dataDir;
p2p = {
public_address = "/ip4/127.0.0.1/tcp/8299";
messages = "high";
blocks = "high";
};
rest = {
listen = "127.0.0.1:8607";
};
};
configFile = if cfg.configFile == null then
pkgs.writeText "jormungandr.yaml" (builtins.toJSON configSettings)
else cfg.configFile;
in {
options = {
services.jormungandr = {
enable = mkEnableOption "jormungandr service";
configFile = mkOption {
type = types.nullOr types.path;
default = null;
example = "/var/lib/jormungandr/node.yaml";
description = ''
The path of the jormungandr blockchain configuration file in YAML format.
If no file is specified, a file is generated using the other options.
'';
};
secretFile = mkOption {
type = types.nullOr types.path;
default = null;
example = "/etc/secret/jormungandr.yaml";
description = ''
The path of the jormungandr blockchain secret node configuration file in
YAML format. Do not store this in nix store!
'';
};
genesisBlockHash = mkOption {
type = types.nullOr types.string;
default = null;
example = "d70495af81ae8600aca3e642b2427327cb6001ec4d7a0037e96a00dabed163f9";
description = ''
Set the genesis block hash (the hash of the block0) so we can retrieve
the genesis block (and the blockchain configuration) from the existing
storage or from the network.
'';
};
genesisBlockFile = mkOption {
type = types.nullOr types.path;
default = null;
example = "/var/lib/jormungandr/block-0.bin";
description = ''
The path of the genesis block file if we are hosting it locally.
'';
};
};
};
config = mkIf cfg.enable {
systemd.services.jormungandr = {
description = "jormungandr server";
wantedBy = [ "multi-user.target" ];
after = [ "network-online.target" ];
serviceConfig = {
DynamicUser = true;
StateDirectory = baseNameOf dataDir;
ExecStart = ''
${pkgs.jormungandr}/bin/jormungandr --config ${configFile} \
${optionalString (cfg.secretFile != null) " --secret ${cfg.secretFile}"} \
${optionalString (cfg.genesisBlockHash != null) " --genesis-block-hash ${cfg.genesisBlockHash}"} \
${optionalString (cfg.genesisBlockFile != null) " --genesis-block ${cfg.genesisBlockFile}"}
'';
};
};
};
}

View file

@ -0,0 +1,44 @@
# Ofono daemon.
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.ofono;
plugin_path =
lib.concatMapStringsSep ":"
(plugin: "${plugin}/lib/ofono/plugins")
cfg.plugins
;
in
{
###### interface
options = {
services.ofono = {
enable = mkEnableOption "Ofono";
plugins = mkOption {
type = types.listOf types.package;
default = [];
example = literalExample "[ pkgs.modem-manager-gui ]";
description = ''
The list of plugins to install.
'';
};
};
};
###### implementation
config = mkIf cfg.enable {
services.dbus.packages = [ pkgs.ofono ];
systemd.packages = [ pkgs.ofono ];
systemd.services.ofono.environment.OFONO_PLUGIN_PATH = mkIf (cfg.plugins != []) plugin_path;
};
}

View file

@ -6,25 +6,27 @@ let
dataDir = "/var/lib/pdns-recursor";
username = "pdns-recursor";
cfg = config.services.pdns-recursor;
zones = mapAttrsToList (zone: uri: "${zone}.=${uri}") cfg.forwardZones;
cfg = config.services.pdns-recursor;
configFile = pkgs.writeText "recursor.conf" ''
local-address=${cfg.dns.address}
local-port=${toString cfg.dns.port}
allow-from=${concatStringsSep "," cfg.dns.allowFrom}
oneOrMore = type: with types; either type (listOf type);
valueType = with types; oneOf [ int str bool path ];
configType = with types; attrsOf (nullOr (oneOrMore valueType));
webserver-address=${cfg.api.address}
webserver-port=${toString cfg.api.port}
webserver-allow-from=${concatStringsSep "," cfg.api.allowFrom}
toBool = val: if val then "yes" else "no";
serialize = val: with types;
if str.check val then val
else if int.check val then toString val
else if path.check val then toString val
else if bool.check val then toBool val
else if builtins.isList val then (concatMapStringsSep "," serialize val)
else "";
forward-zones=${concatStringsSep "," zones}
export-etc-hosts=${if cfg.exportHosts then "yes" else "no"}
dnssec=${cfg.dnssecValidation}
serve-rfc1918=${if cfg.serveRFC1918 then "yes" else "no"}
configFile = pkgs.writeText "recursor.conf"
(concatStringsSep "\n"
(flip mapAttrsToList cfg.settings
(name: val: "${name}=${serialize val}")));
${cfg.extraConfig}
'';
mkDefaultAttrs = mapAttrs (n: v: mkDefault v);
in {
options.services.pdns-recursor = {
@ -117,18 +119,56 @@ in {
'';
};
extraConfig = mkOption {
settings = mkOption {
type = configType;
default = { };
example = literalExample ''
{
loglevel = 8;
log-common-errors = true;
}
'';
description = ''
PowerDNS Recursor settings. Use this option to configure Recursor
settings not exposed in a NixOS option or to bypass one.
See the full documentation at
<link xlink:href="https://doc.powerdns.com/recursor/settings.html"/>
for the available options.
'';
};
luaConfig = mkOption {
type = types.lines;
default = "";
description = ''
Extra options to be appended to the configuration file.
The content Lua configuration file for PowerDNS Recursor. See
<link xlink:href="https://doc.powerdns.com/recursor/lua-config/index.html"/>.
'';
};
};
config = mkIf cfg.enable {
users.users.${username} = {
services.pdns-recursor.settings = mkDefaultAttrs {
local-address = cfg.dns.address;
local-port = cfg.dns.port;
allow-from = cfg.dns.allowFrom;
webserver-address = cfg.api.address;
webserver-port = cfg.api.port;
webserver-allow-from = cfg.api.allowFrom;
forward-zones = mapAttrsToList (zone: uri: "${zone}.=${uri}") cfg.forwardZones;
export-etc-hosts = cfg.exportHosts;
dnssec = cfg.dnssecValidation;
serve-rfc1918 = cfg.serveRFC1918;
lua-config-file = pkgs.writeText "recursor.lua" cfg.luaConfig;
log-timestamp = false;
disable-syslog = true;
};
users.users."${username}" = {
home = dataDir;
createHome = true;
uid = config.ids.uids.pdns-recursor;
@ -150,8 +190,7 @@ in {
AmbientCapabilities = "cap_net_bind_service";
ExecStart = ''${pkgs.pdns-recursor}/bin/pdns_recursor \
--config-dir=${dataDir} \
--socket-dir=${dataDir} \
--disable-syslog
--socket-dir=${dataDir}
'';
};
@ -165,4 +204,10 @@ in {
'';
};
};
imports = [
(mkRemovedOptionModule [ "services" "pdns-recursor" "extraConfig" ]
"To change extra Recursor settings use services.pdns-recursor.settings instead.")
];
}

View file

@ -35,10 +35,10 @@ in
};
localAddress = mkOption {
type = types.str;
default = "0.0.0.0";
type = types.coercedTo types.str singleton (types.listOf types.str);
default = [ "[::0]" "0.0.0.0" ];
description = ''
Local address to which the server binds.
Local addresses to which the server binds.
'';
};

View file

@ -502,7 +502,7 @@ in
assertions = [{ assertion = if cfg.forwardX11 then cfgc.setXAuthLocation else true;
message = "cannot enable X11 forwarding without setting xauth location";}]
++ flip map cfg.listenAddresses ({ addr, ... }: {
++ forEach cfg.listenAddresses ({ addr, ... }: {
assertion = addr != null;
message = "addr must be specified in each listenAddresses entry";
});

View file

@ -168,7 +168,7 @@ in
default = defaultUpstream;
type = types.lines;
description = ''
Add additional upstreams. See <citerefentry><refentrytitle>stubby
Replace default upstreams. See <citerefentry><refentrytitle>stubby
</refentrytitle><manvolnum>1</manvolnum></citerefentry> for an
example of the entry formatting. In Strict mode, at least one of the
following settings must be supplied for each nameserver:

View file

@ -176,6 +176,7 @@ in
Type = "simple";
ExecStart = "${(removeSuffix "\n" cmd)} start";
ExecStop = "${(removeSuffix "\n" cmd)} stop";
Restart = "on-failure";
User = "unifi";
UMask = "0077";
WorkingDirectory = "${stateDir}";

View file

@ -131,6 +131,7 @@ in {
description = "Extra elasticsearch plugins";
default = [];
type = types.listOf types.package;
example = lib.literalExample "[ pkgs.elasticsearchPlugins.discovery-ec2 ]";
};
};

View file

@ -106,14 +106,24 @@ in {
path = with pkgs; [ iptables ipset iproute systemd ];
postStart = ''
# The sshguard ipsets must exist before we invoke
# iptables. sshguard creates the ipsets after startup if
# necessary, but if we let sshguard do it, we can't reliably add
# the iptables rules because postStart races with the creation
# of the ipsets. So instead, we create both the ipsets and
# firewall rules before sshguard starts.
preStart = ''
${pkgs.ipset}/bin/ipset -quiet create -exist sshguard4 hash:net family inet
${pkgs.ipset}/bin/ipset -quiet create -exist sshguard6 hash:net family inet6
${pkgs.iptables}/bin/iptables -I INPUT -m set --match-set sshguard4 src -j DROP
${pkgs.iptables}/bin/ip6tables -I INPUT -m set --match-set sshguard6 src -j DROP
'';
preStop = ''
postStop = ''
${pkgs.iptables}/bin/iptables -D INPUT -m set --match-set sshguard4 src -j DROP
${pkgs.iptables}/bin/ip6tables -D INPUT -m set --match-set sshguard6 src -j DROP
${pkgs.ipset}/bin/ipset -quiet destroy sshguard4
${pkgs.ipset}/bin/ipset -quiet destroy sshguard6
'';
unitConfig.Documentation = "man:sshguard(8)";

View file

@ -39,6 +39,16 @@ in {
services.usbguard = {
enable = mkEnableOption "USBGuard daemon";
package = mkOption {
type = types.package;
default = pkgs.usbguard;
defaultText = "pkgs.usbguard";
description = ''
The usbguard package to use. If you do not need the Qt GUI, use
<literal>pkgs.usbguard-nox</literal> to save disk space.
'';
};
ruleFile = mkOption {
type = types.path;
default = "/var/lib/usbguard/rules.conf";
@ -179,7 +189,7 @@ in {
config = mkIf cfg.enable {
environment.systemPackages = [ pkgs.usbguard ];
environment.systemPackages = [ cfg.package ];
systemd.services.usbguard = {
description = "USBGuard daemon";
@ -195,7 +205,7 @@ in {
serviceConfig = {
Type = "simple";
ExecStart = ''${pkgs.usbguard}/bin/usbguard-daemon -P -k -c ${daemonConfFile}'';
ExecStart = ''${cfg.package}/bin/usbguard-daemon -P -k -c ${daemonConfFile}'';
Restart = "on-failure";
};
};

View file

@ -84,6 +84,18 @@ in
The directory where transmission will create files.
'';
};
user = mkOption {
type = types.str;
default = "transmission";
description = "User account under which Transmission runs.";
};
group = mkOption {
type = types.str;
default = "transmission";
description = "Group account under which Transmission runs.";
};
};
};
@ -99,7 +111,8 @@ in
serviceConfig.ExecStartPre = preStart;
serviceConfig.ExecStart = "${pkgs.transmission}/bin/transmission-daemon -f --port ${toString config.services.transmission.port}";
serviceConfig.ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
serviceConfig.User = "transmission";
serviceConfig.User = cfg.user;
serviceConfig.Group = cfg.group;
# NOTE: transmission has an internal umask that also must be set (in settings.json)
serviceConfig.UMask = "0002";
};
@ -107,14 +120,19 @@ in
# It's useful to have transmission in path, e.g. for remote control
environment.systemPackages = [ pkgs.transmission ];
users.groups.transmission.gid = config.ids.gids.transmission;
users.users.transmission = {
group = "transmission";
uid = config.ids.uids.transmission;
description = "Transmission BitTorrent user";
home = homeDir;
createHome = true;
};
users.users = optionalAttrs (cfg.user == "transmission") (singleton
{ name = "transmission";
group = cfg.group;
uid = config.ids.uids.transmission;
description = "Transmission BitTorrent user";
home = homeDir;
createHome = true;
});
users.groups = optionalAttrs (cfg.group == "transmission") (singleton
{ name = "transmission";
gid = config.ids.gids.transmission;
});
# AppArmor profile
security.apparmor.profiles = mkIf apparmor [

View file

@ -1,14 +1,16 @@
{ config, lib, pkgs, ... }: with lib; let
cfg = config.services.icingaweb2;
fpm = config.services.phpfpm.pools.${poolName};
poolName = "icingaweb2";
phpfpmSocketName = "/var/run/phpfpm/${poolName}.sock";
defaultConfig = {
global = {
module_path = "${pkgs.icingaweb2}/modules${optionalString (builtins.length config.modulePath > 0) ":${concatStringsSep ":" config.modulePath}"}";
module_path = "${pkgs.icingaweb2}/modules";
};
};
in {
meta.maintainers = with maintainers; [ das_j ];
options.services.icingaweb2 = with types; {
enable = mkEnableOption "the icingaweb2 web interface";
@ -162,27 +164,26 @@ in {
};
config = mkIf cfg.enable {
services.phpfpm.poolConfigs = mkIf (cfg.pool == "${poolName}") {
${poolName} = ''
listen = "${phpfpmSocketName}"
listen.owner = nginx
listen.group = nginx
listen.mode = 0600
user = icingaweb2
pm = dynamic
pm.max_children = 75
pm.start_servers = 2
pm.min_spare_servers = 2
pm.max_spare_servers = 10
'';
services.phpfpm.pools = mkIf (cfg.pool == "${poolName}") {
"${poolName}" = {
user = "icingaweb2";
phpOptions = ''
extension = ${pkgs.phpPackages.imagick}/lib/php/extensions/imagick.so
date.timezone = "${cfg.timezone}"
'';
settings = mapAttrs (name: mkDefault) {
"listen.owner" = "nginx";
"listen.group" = "nginx";
"listen.mode" = "0600";
"pm" = "dynamic";
"pm.max_children" = 75;
"pm.start_servers" = 2;
"pm.min_spare_servers" = 2;
"pm.max_spare_servers" = 10;
};
};
};
services.phpfpm.phpOptions = mkIf (cfg.pool == "${poolName}")
''
extension = ${pkgs.phpPackages.imagick}/lib/php/extensions/imagick.so
date.timezone = "${cfg.timezone}"
'';
systemd.services."phpfpm-${poolName}".serviceConfig.ReadWritePaths = [ "/etc/icingaweb2" ];
services.nginx = {
@ -206,7 +207,7 @@ in {
include ${config.services.nginx.package}/conf/fastcgi.conf;
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:${phpfpmSocketName};
fastcgi_pass unix:${fpm.socket};
fastcgi_param SCRIPT_FILENAME ${pkgs.icingaweb2}/public/index.php;
'';
};

View file

@ -120,15 +120,15 @@ in
};
poolConfig = mkOption {
type = types.lines;
default = ''
pm = dynamic
pm.max_children = 32
pm.start_servers = 2
pm.min_spare_servers = 2
pm.max_spare_servers = 4
pm.max_requests = 500
'';
type = with types; attrsOf (oneOf [ str int bool ]);
default = {
"pm" = "dynamic";
"pm.max_children" = 32;
"pm.start_servers" = 2;
"pm.min_spare_servers" = 2;
"pm.max_spare_servers" = 4;
"pm.max_requests" = 500;
};
description = ''
Options for the LimeSurvey PHP pool. See the documentation on <literal>php-fpm.conf</literal>
for details on configuration directives.
@ -203,17 +203,12 @@ in
};
services.phpfpm.pools.limesurvey = {
listen = "/run/phpfpm/limesurvey.sock";
extraConfig = ''
listen.owner = ${config.services.httpd.user};
listen.group = ${config.services.httpd.group};
user = ${user};
group = ${group};
env[LIMESURVEY_CONFIG] = ${limesurveyConfig}
${cfg.poolConfig}
'';
inherit user group;
phpEnv.LIMESURVEY_CONFIG = "${limesurveyConfig}";
settings = {
"listen.owner" = config.services.httpd.user;
"listen.group" = config.services.httpd.group;
} // cfg.poolConfig;
};
services.httpd = {
@ -241,7 +236,7 @@ in
<Directory "${pkg}/share/limesurvey">
<FilesMatch "\.php$">
<If "-f %{REQUEST_FILENAME}">
SetHandler "proxy:unix:${fpm.listen}|fcgi://localhost/"
SetHandler "proxy:unix:${fpm.socket}|fcgi://localhost/"
</If>
</FilesMatch>

View file

@ -176,7 +176,7 @@ in {
# Use User-Private Group scheme to protect Matomo data, but allow administration / backup via 'matomo' group
# Copy config folder
chmod g+s "${dataDir}"
cp -r "${cfg.package}/config" "${dataDir}/"
cp -r "${cfg.package}/share/config" "${dataDir}/"
chmod -R u+rwX,g+rwX,o-rwx "${dataDir}"
# check whether user setup has already been done
@ -225,22 +225,24 @@ in {
serviceConfig.UMask = "0007";
};
services.phpfpm.poolConfigs = let
services.phpfpm.pools = let
# workaround for when both are null and need to generate a string,
# which is illegal, but as assertions apparently are being triggered *after* config generation,
# we have to avoid already throwing errors at this previous stage.
socketOwner = if (cfg.nginx != null) then config.services.nginx.user
else if (cfg.webServerUser != null) then cfg.webServerUser else "";
in {
${pool} = ''
listen = "${phpSocket}"
listen.owner = ${socketOwner}
listen.group = root
listen.mode = 0600
user = ${user}
env[PIWIK_USER_PATH] = ${dataDir}
${cfg.phpfpmProcessManagerConfig}
'';
${pool} = {
listen = phpSocket;
extraConfig = ''
listen.owner = ${socketOwner}
listen.group = root
listen.mode = 0600
user = ${user}
env[PIWIK_USER_PATH] = ${dataDir}
${cfg.phpfpmProcessManagerConfig}
'';
};
};

View file

@ -312,17 +312,17 @@ in
};
poolConfig = mkOption {
type = types.lines;
default = ''
pm = dynamic
pm.max_children = 32
pm.start_servers = 2
pm.min_spare_servers = 2
pm.max_spare_servers = 4
pm.max_requests = 500
'';
type = with types; attrsOf (oneOf [ str int bool ]);
default = {
"pm" = "dynamic";
"pm.max_children" = 32;
"pm.start_servers" = 2;
"pm.min_spare_servers" = 2;
"pm.max_spare_servers" = 4;
"pm.max_requests" = 500;
};
description = ''
Options for MediaWiki's PHP pool. See the documentation on <literal>php-fpm.conf</literal>
Options for the MediaWiki PHP pool. See the documentation on <literal>php-fpm.conf</literal>
for details on configuration directives.
'';
};
@ -379,17 +379,12 @@ in
};
services.phpfpm.pools.mediawiki = {
listen = "/run/phpfpm/mediawiki.sock";
extraConfig = ''
listen.owner = ${config.services.httpd.user}
listen.group = ${config.services.httpd.group}
user = ${user}
group = ${group}
env[MEDIAWIKI_CONFIG] = ${mediawikiConfig}
${cfg.poolConfig}
'';
inherit user group;
phpEnv.MEDIAWIKI_CONFIG = "${mediawikiConfig}";
settings = {
"listen.owner" = config.services.httpd.user;
"listen.group" = config.services.httpd.group;
} // cfg.poolConfig;
};
services.httpd = {
@ -403,7 +398,7 @@ in
<Directory "${pkg}/share/mediawiki">
<FilesMatch "\.php$">
<If "-f %{REQUEST_FILENAME}">
SetHandler "proxy:unix:${fpm.listen}|fcgi://localhost/"
SetHandler "proxy:unix:${fpm.socket}|fcgi://localhost/"
</If>
</FilesMatch>

View file

@ -0,0 +1,300 @@
{ config, lib, pkgs, ... }:
let
inherit (lib) mkDefault mkEnableOption mkForce mkIf mkMerge mkOption types;
inherit (lib) concatStringsSep literalExample mapAttrsToList optional optionalString;
cfg = config.services.moodle;
fpm = config.services.phpfpm.pools.moodle;
user = "moodle";
group = config.services.httpd.group;
stateDir = "/var/lib/moodle";
moodleConfig = pkgs.writeText "config.php" ''
<?php // Moodle configuration file
unset($CFG);
global $CFG;
$CFG = new stdClass();
$CFG->dbtype = '${ { "mysql" = "mariadb"; "pgsql" = "pgsql"; }.${cfg.database.type} }';
$CFG->dblibrary = 'native';
$CFG->dbhost = '${cfg.database.host}';
$CFG->dbname = '${cfg.database.name}';
$CFG->dbuser = '${cfg.database.user}';
${optionalString (cfg.database.passwordFile != null) "$CFG->dbpass = file_get_contents('${cfg.database.passwordFile}');"}
$CFG->prefix = 'mdl_';
$CFG->dboptions = array (
'dbpersist' => 0,
'dbport' => '${toString cfg.database.port}',
${optionalString (cfg.database.socket != null) "'dbsocket' => '${cfg.database.socket}',"}
'dbcollation' => 'utf8mb4_unicode_ci',
);
$CFG->wwwroot = '${if cfg.virtualHost.enableSSL then "https" else "http"}://${cfg.virtualHost.hostName}';
$CFG->dataroot = '${stateDir}';
$CFG->admin = 'admin';
$CFG->directorypermissions = 02777;
$CFG->disableupdateautodeploy = true;
$CFG->pathtogs = '${pkgs.ghostscript}/bin/gs';
$CFG->pathtophp = '${pkgs.php}/bin/php';
$CFG->pathtodu = '${pkgs.coreutils}/bin/du';
$CFG->aspellpath = '${pkgs.aspell}/bin/aspell';
$CFG->pathtodot = '${pkgs.graphviz}/bin/dot';
require_once('${cfg.package}/share/moodle/lib/setup.php');
// There is no php closing tag in this file,
// it is intentional because it prevents trailing whitespace problems!
'';
mysqlLocal = cfg.database.createLocally && cfg.database.type == "mysql";
pgsqlLocal = cfg.database.createLocally && cfg.database.type == "pgsql";
in
{
# interface
options.services.moodle = {
enable = mkEnableOption "Moodle web application";
package = mkOption {
type = types.package;
default = pkgs.moodle;
defaultText = "pkgs.moodle";
description = "The Moodle package to use.";
};
initialPassword = mkOption {
type = types.str;
example = "correcthorsebatterystaple";
description = ''
Specifies the initial password for the admin, i.e. the password assigned if the user does not already exist.
The password specified here is world-readable in the Nix store, so it should be changed promptly.
'';
};
database = {
type = mkOption {
type = types.enum [ "mysql" "pgsql" ];
default = "mysql";
description = ''Database engine to use.'';
};
host = mkOption {
type = types.str;
default = "localhost";
description = "Database host address.";
};
port = mkOption {
type = types.int;
description = "Database host port.";
default = {
"mysql" = 3306;
"pgsql" = 5432;
}.${cfg.database.type};
defaultText = "3306";
};
name = mkOption {
type = types.str;
default = "moodle";
description = "Database name.";
};
user = mkOption {
type = types.str;
default = "moodle";
description = "Database user.";
};
passwordFile = mkOption {
type = types.nullOr types.path;
default = null;
example = "/run/keys/moodle-dbpassword";
description = ''
A file containing the password corresponding to
<option>database.user</option>.
'';
};
socket = mkOption {
type = types.nullOr types.path;
default =
if mysqlLocal then "/run/mysqld/mysqld.sock"
else if pgsqlLocal then "/run/postgresql"
else null;
defaultText = "/run/mysqld/mysqld.sock";
description = "Path to the unix socket file to use for authentication.";
};
createLocally = mkOption {
type = types.bool;
default = true;
description = "Create the database and database user locally.";
};
};
virtualHost = mkOption {
type = types.submodule ({
options = import ../web-servers/apache-httpd/per-server-options.nix {
inherit lib;
forMainServer = false;
};
});
example = {
hostName = "moodle.example.org";
enableSSL = true;
adminAddr = "webmaster@example.org";
sslServerCert = "/var/lib/acme/moodle.example.org/full.pem";
sslServerKey = "/var/lib/acme/moodle.example.org/key.pem";
};
description = ''
Apache configuration can be done by adapting <option>services.httpd.virtualHosts</option>.
See <xref linkend="opt-services.httpd.virtualHosts"/> for further information.
'';
};
poolConfig = mkOption {
type = with types; attrsOf (oneOf [ str int bool ]);
default = {
"pm" = "dynamic";
"pm.max_children" = 32;
"pm.start_servers" = 2;
"pm.min_spare_servers" = 2;
"pm.max_spare_servers" = 4;
"pm.max_requests" = 500;
};
description = ''
Options for the Moodle PHP pool. See the documentation on <literal>php-fpm.conf</literal>
for details on configuration directives.
'';
};
};
# implementation
config = mkIf cfg.enable {
assertions = [
{ assertion = cfg.database.createLocally -> cfg.database.user == user;
message = "services.moodle.database.user must be set to ${user} if services.moodle.database.createLocally is set true";
}
{ assertion = cfg.database.createLocally -> cfg.database.passwordFile == null;
message = "a password cannot be specified if services.moodle.database.createLocally is set to true";
}
];
services.mysql = mkIf mysqlLocal {
enable = true;
package = mkDefault pkgs.mariadb;
ensureDatabases = [ cfg.database.name ];
ensureUsers = [
{ name = cfg.database.user;
ensurePermissions = {
"${cfg.database.name}.*" = "SELECT, INSERT, UPDATE, DELETE, CREATE, CREATE TEMPORARY TABLES, DROP, INDEX, ALTER";
};
}
];
};
services.postgresql = mkIf pgsqlLocal {
enable = true;
ensureDatabases = [ cfg.database.name ];
ensureUsers = [
{ name = cfg.database.user;
ensurePermissions = { "DATABASE ${cfg.database.name}" = "ALL PRIVILEGES"; };
}
];
};
services.phpfpm.pools.moodle = {
inherit user group;
phpEnv.MOODLE_CONFIG = "${moodleConfig}";
phpOptions = ''
zend_extension = opcache.so
opcache.enable = 1
'';
settings = {
"listen.owner" = config.services.httpd.user;
"listen.group" = config.services.httpd.group;
} // cfg.poolConfig;
};
services.httpd = {
enable = true;
adminAddr = mkDefault cfg.virtualHost.adminAddr;
extraModules = [ "proxy_fcgi" ];
virtualHosts = [ (mkMerge [
cfg.virtualHost {
documentRoot = mkForce "${cfg.package}/share/moodle";
extraConfig = ''
<Directory "${cfg.package}/share/moodle">
<FilesMatch "\.php$">
<If "-f %{REQUEST_FILENAME}">
SetHandler "proxy:unix:${fpm.socket}|fcgi://localhost/"
</If>
</FilesMatch>
Options -Indexes
DirectoryIndex index.php
</Directory>
'';
}
]) ];
};
systemd.tmpfiles.rules = [
"d '${stateDir}' 0750 ${user} ${group} - -"
];
systemd.services.moodle-init = {
wantedBy = [ "multi-user.target" ];
before = [ "phpfpm-moodle.service" ];
after = optional mysqlLocal "mysql.service" ++ optional pgsqlLocal "postgresql.service";
environment.MOODLE_CONFIG = moodleConfig;
script = ''
${pkgs.php}/bin/php ${cfg.package}/share/moodle/admin/cli/check_database_schema.php && rc=$? || rc=$?
[ "$rc" == 1 ] && ${pkgs.php}/bin/php ${cfg.package}/share/moodle/admin/cli/upgrade.php \
--non-interactive \
--allow-unstable
[ "$rc" == 2 ] && ${pkgs.php}/bin/php ${cfg.package}/share/moodle/admin/cli/install_database.php \
--agree-license \
--adminpass=${cfg.initialPassword}
true
'';
serviceConfig = {
User = user;
Group = group;
Type = "oneshot";
};
};
systemd.services.moodle-cron = {
description = "Moodle cron service";
after = [ "moodle-init.service" ];
environment.MOODLE_CONFIG = moodleConfig;
serviceConfig = {
User = user;
Group = group;
ExecStart = "${pkgs.php}/bin/php ${cfg.package}/share/moodle/admin/cli/cron.php";
};
};
systemd.timers.moodle-cron = {
description = "Moodle cron timer";
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = "minutely";
};
};
systemd.services.httpd.after = optional mysqlLocal "mysql.service" ++ optional pgsqlLocal "postgresql.service";
users.users."${user}".group = group;
};
}

View file

@ -4,6 +4,7 @@ with lib;
let
cfg = config.services.nextcloud;
fpm = config.services.phpfpm.pools.nextcloud;
phpPackage = pkgs.php73;
phpPackages = pkgs.php73Packages;
@ -410,25 +411,20 @@ in {
};
services.phpfpm = {
pools.nextcloud = let
phpAdminValues = (toKeyValue
(foldr (a: b: a // b) {}
(mapAttrsToList (k: v: { "php_admin_value[${k}]" = v; })
phpOptions)));
in {
phpOptions = phpOptionsExtensions;
pools.nextcloud = {
user = "nextcloud";
group = "nginx";
phpOptions = phpOptionsExtensions + phpOptionsStr;
phpPackage = phpPackage;
listen = "/run/phpfpm/nextcloud";
extraConfig = ''
listen.owner = nginx
listen.group = nginx
user = nextcloud
group = nginx
${cfg.poolConfig}
env[NEXTCLOUD_CONFIG_DIR] = ${cfg.home}/config
env[PATH] = /run/wrappers/bin:/nix/var/nix/profiles/default/bin:/run/current-system/sw/bin:/usr/bin:/bin
${phpAdminValues}
'';
phpEnv = {
NEXTCLOUD_CONFIG_DIR = "${cfg.home}/config";
PATH = "/run/wrappers/bin:/nix/var/nix/profiles/default/bin:/run/current-system/sw/bin:/usr/bin:/bin";
};
settings = mapAttrs (name: mkDefault) {
"listen.owner" = "nginx";
"listen.group" = "nginx";
};
extraConfig = cfg.poolConfig;
};
};
@ -489,7 +485,7 @@ in {
fastcgi_param HTTPS ${if cfg.https then "on" else "off"};
fastcgi_param modHeadersAvailable true;
fastcgi_param front_controller_active true;
fastcgi_pass unix:/run/phpfpm/nextcloud;
fastcgi_pass unix:${fpm.socket};
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
fastcgi_read_timeout 120s;

View file

@ -9,11 +9,11 @@ with lib;
let
cfg = config.services.restya-board;
fpm = config.services.phpfpm.pools.${poolName};
runDir = "/run/restya-board";
poolName = "restya-board";
phpfpmSocketName = "/run/phpfpm/${poolName}.sock";
in
@ -179,8 +179,9 @@ in
config = mkIf cfg.enable {
services.phpfpm.pools = {
${poolName} = {
listen = phpfpmSocketName;
"${poolName}" = {
inherit (cfg) user group;
phpOptions = ''
date.timezone = "CET"
@ -191,20 +192,18 @@ in
auth_password = ${cfg.email.password}
''}
'';
extraConfig = ''
listen.owner = nginx
listen.group = nginx
listen.mode = 0600
user = ${cfg.user}
group = ${cfg.group}
pm = dynamic
pm.max_children = 75
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.max_requests = 500
catch_workers_output = 1
'';
settings = mapAttrs (name: mkDefault) {
"listen.owner" = "nginx";
"listen.group" = "nginx";
"listen.mode" = "0600";
"pm" = "dynamic";
"pm.max_children" = 75;
"pm.start_servers" = 10;
"pm.min_spare_servers" = 5;
"pm.max_spare_servers" = 20;
"pm.max_requests" = 500;
"catch_workers_output" = 1;
};
};
};
@ -241,7 +240,7 @@ in
tryFiles = "$uri =404";
extraConfig = ''
include ${pkgs.nginx}/conf/fastcgi_params;
fastcgi_pass unix:${phpfpmSocketName};
fastcgi_pass unix:${fpm.socket};
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PHP_VALUE "upload_max_filesize=9G \n post_max_size=9G \n max_execution_time=200 \n max_input_time=200 \n memory_limit=256M";

View file

@ -4,7 +4,6 @@ let
cfg = config.services.selfoss;
poolName = "selfoss_pool";
phpfpmSocketName = "/run/phpfpm/${poolName}.sock";
dataDir = "/var/lib/selfoss";
@ -115,22 +114,22 @@ in
};
config = mkIf cfg.enable {
services.phpfpm.poolConfigs = mkIf (cfg.pool == "${poolName}") {
${poolName} = ''
listen = "${phpfpmSocketName}";
listen.owner = nginx
listen.group = nginx
listen.mode = 0600
user = nginx
pm = dynamic
pm.max_children = 75
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.max_requests = 500
catch_workers_output = 1
'';
services.phpfpm.pools = mkIf (cfg.pool == "${poolName}") {
"${poolName}" = {
user = "nginx";
settings = mapAttrs (name: mkDefault) {
"listen.owner" = "nginx";
"listen.group" = "nginx";
"listen.mode" = "0600";
"pm" = "dynamic";
"pm.max_children" = 75;
"pm.start_servers" = 10;
"pm.min_spare_servers" = 5;
"pm.max_spare_servers" = 20;
"pm.max_requests" = 500;
"catch_workers_output" = 1;
};
};
};
systemd.services.selfoss-config = {

View file

@ -520,21 +520,20 @@ let
];
services.phpfpm.pools = mkIf (cfg.pool == "${poolName}") {
${poolName} = {
listen = "/var/run/phpfpm/${poolName}.sock";
extraConfig = ''
listen.owner = nginx
listen.group = nginx
listen.mode = 0600
user = ${cfg.user}
pm = dynamic
pm.max_children = 75
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.max_requests = 500
catch_workers_output = 1
'';
"${poolName}" = {
inherit (cfg) user;
settings = mapAttrs (name: mkDefault) {
"listen.owner" = "nginx";
"listen.group" = "nginx";
"listen.mode" = "0600";
"pm" = "dynamic";
"pm.max_children" = 75;
"pm.start_servers" = 10;
"pm.min_spare_servers" = 5;
"pm.max_spare_servers" = 20;
"pm.max_requests" = 500;
"catch_workers_output" = 1;
};
};
};
@ -552,7 +551,7 @@ let
locations."~ \.php$" = {
extraConfig = ''
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:${config.services.phpfpm.pools.${cfg.pool}.listen};
fastcgi_pass unix:${config.services.phpfpm.pools.${cfg.pool}.socket};
fastcgi_index index.php;
'';
};

View file

@ -216,15 +216,15 @@ let
};
poolConfig = mkOption {
type = types.lines;
default = ''
pm = dynamic
pm.max_children = 32
pm.start_servers = 2
pm.min_spare_servers = 2
pm.max_spare_servers = 4
pm.max_requests = 500
'';
type = with types; attrsOf (oneOf [ str int bool ]);
default = {
"pm" = "dynamic";
"pm.max_children" = 32;
"pm.start_servers" = 2;
"pm.min_spare_servers" = 2;
"pm.max_spare_servers" = 4;
"pm.max_requests" = 500;
};
description = ''
Options for the WordPress PHP pool. See the documentation on <literal>php-fpm.conf</literal>
for details on configuration directives.
@ -280,15 +280,11 @@ in
services.phpfpm.pools = mapAttrs' (hostName: cfg: (
nameValuePair "wordpress-${hostName}" {
listen = "/run/phpfpm/wordpress-${hostName}.sock";
extraConfig = ''
listen.owner = ${config.services.httpd.user}
listen.group = ${config.services.httpd.group}
user = ${user}
group = ${group}
${cfg.poolConfig}
'';
inherit user group;
settings = {
"listen.owner" = config.services.httpd.user;
"listen.group" = config.services.httpd.group;
} // cfg.poolConfig;
}
)) eachSite;
@ -303,7 +299,7 @@ in
<Directory "${pkg hostName cfg}/share/wordpress">
<FilesMatch "\.php$">
<If "-f %{REQUEST_FILENAME}">
SetHandler "proxy:unix:/run/phpfpm/wordpress-${hostName}.sock|fcgi://localhost/"
SetHandler "proxy:unix:${config.services.phpfpm.pools."wordpress-${hostName}".socket}|fcgi://localhost/"
</If>
</FilesMatch>

View file

@ -133,15 +133,15 @@ in
};
poolConfig = mkOption {
type = types.lines;
default = ''
pm = dynamic
pm.max_children = 32
pm.start_servers = 2
pm.min_spare_servers = 2
pm.max_spare_servers = 4
pm.max_requests = 500
'';
type = with types; attrsOf (oneOf [ str int bool ]);
default = {
"pm" = "dynamic";
"pm.max_children" = 32;
"pm.start_servers" = 2;
"pm.min_spare_servers" = 2;
"pm.max_spare_servers" = 4;
"pm.max_requests" = 500;
};
description = ''
Options for the Zabbix PHP pool. See the documentation on <literal>php-fpm.conf</literal> for details on configuration directives.
'';
@ -160,6 +160,8 @@ in
];
services.phpfpm.pools.zabbix = {
inherit user;
group = config.services.httpd.group;
phpOptions = ''
# https://www.zabbix.com/documentation/current/manual/installation/install
memory_limit = 128M
@ -177,15 +179,11 @@ in
'' + optionalString (cfg.database.type == "oracle") ''
extension=${pkgs.phpPackages.oci8}/lib/php/extensions/oci8.so
'';
listen = "/run/phpfpm/zabbix.sock";
extraConfig = ''
listen.owner = ${config.services.httpd.user};
listen.group = ${config.services.httpd.group};
user = ${user};
group = ${config.services.httpd.group};
env[ZABBIX_CONFIG] = ${zabbixConfig}
${cfg.poolConfig}
'';
phpEnv.ZABBIX_CONFIG = zabbixConfig;
settings = {
"listen.owner" = config.services.httpd.user;
"listen.group" = config.services.httpd.group;
} // cfg.poolConfig;
};
services.httpd = {

View file

@ -70,7 +70,7 @@ in {
{ CADDYPATH = cfg.dataDir; };
serviceConfig = {
ExecStart = ''
${cfg.package.bin}/bin/caddy -root=/var/tmp -conf=${configFile} \
${cfg.package}/bin/caddy -root=/var/tmp -conf=${configFile} \
-ca=${cfg.ca} -email=${cfg.email} ${optionalString cfg.agree "-agree"}
'';
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";

View file

@ -0,0 +1,77 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.darkhttpd;
args = concatStringsSep " " ([
cfg.rootDir
"--port ${toString cfg.port}"
"--addr ${cfg.address}"
] ++ cfg.extraArgs
++ optional cfg.hideServerId "--no-server-id"
++ optional config.networking.enableIPv6 "--ipv6");
in {
options.services.darkhttpd = with types; {
enable = mkEnableOption "DarkHTTPd web server";
port = mkOption {
default = 80;
type = ints.u16;
description = ''
Port to listen on.
Pass 0 to let the system choose any free port for you.
'';
};
address = mkOption {
default = "127.0.0.1";
type = str;
description = ''
Address to listen on.
Pass `all` to listen on all interfaces.
'';
};
rootDir = mkOption {
type = path;
description = ''
Path from which to serve files.
'';
};
hideServerId = mkOption {
type = bool;
default = true;
description = ''
Don't identify the server type in headers or directory listings.
'';
};
extraArgs = mkOption {
type = listOf str;
default = [];
description = ''
Additional configuration passed to the executable.
'';
};
};
config = mkIf cfg.enable {
systemd.services.darkhttpd = {
description = "Dark HTTPd";
wants = [ "network.target" ];
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
DynamicUser = true;
ExecStart = "${cfg.package}/bin/darkhttpd ${args}";
AmbientCapabilities = lib.mkIf (cfg.port < 1024) [ "CAP_NET_BIND_SERVICE" ];
Restart = "on-failure";
RestartSec = "2s";
};
};
};
}

View file

@ -162,6 +162,10 @@ let
${cfg.appendConfig}
'';
configPath = if cfg.enableReload
then "/etc/nginx/nginx.conf"
else configFile;
vhosts = concatStringsSep "\n" (mapAttrsToList (vhostName: vhost:
let
onlySSL = vhost.onlySSL || vhost.enableSSL;
@ -431,6 +435,16 @@ in
";
};
enableReload = mkOption {
default = false;
type = types.bool;
description = ''
Reload nginx when configuration file changes (instead of restart).
The configuration file is exposed at <filename>/etc/nginx/nginx.conf</filename>.
See also <literal>systemd.services.*.restartIfChanged</literal>.
'';
};
stateDir = mkOption {
default = "/var/spool/nginx";
description = "
@ -638,10 +652,10 @@ in
preStart =
''
${cfg.preStart}
${cfg.package}/bin/nginx -c ${configFile} -p ${cfg.stateDir} -t
${cfg.package}/bin/nginx -c ${configPath} -p ${cfg.stateDir} -t
'';
serviceConfig = {
ExecStart = "${cfg.package}/bin/nginx -c ${configFile} -p ${cfg.stateDir}";
ExecStart = "${cfg.package}/bin/nginx -c ${configPath} -p ${cfg.stateDir}";
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
Restart = "always";
RestartSec = "10s";
@ -649,6 +663,21 @@ in
};
};
environment.etc."nginx/nginx.conf" = mkIf cfg.enableReload {
source = configFile;
};
systemd.services.nginx-config-reload = mkIf cfg.enableReload {
wantedBy = [ "nginx.service" ];
restartTriggers = [ configFile ];
script = ''
if ${pkgs.systemd}/bin/systemctl -q is-active nginx.service ; then
${pkgs.systemd}/bin/systemctl reload nginx.service
fi
'';
serviceConfig.RemainAfterExit = true;
};
security.acme.certs = filterAttrs (n: v: v != {}) (
let
vhostsConfigs = mapAttrsToList (vhostName: vhostConfig: vhostConfig) virtualHosts;

View file

@ -4,41 +4,27 @@ with lib;
let
cfg = config.services.phpfpm;
enabled = cfg.poolConfigs != {} || cfg.pools != {};
stateDir = "/run/phpfpm";
runtimeDir = "/run/phpfpm";
poolConfigs =
(mapAttrs mapPoolConfig cfg.poolConfigs) //
(mapAttrs mapPool cfg.pools);
toStr = value:
if true == value then "yes"
else if false == value then "no"
else toString value;
mapPoolConfig = n: p: {
phpPackage = cfg.phpPackage;
phpOptions = cfg.phpOptions;
config = p;
};
mapPool = n: p: {
phpPackage = p.phpPackage;
phpOptions = p.phpOptions;
config = ''
listen = ${p.listen}
${p.extraConfig}
'';
};
fpmCfgFile = pool: conf: pkgs.writeText "phpfpm-${pool}.conf" ''
fpmCfgFile = pool: poolOpts: pkgs.writeText "phpfpm-${pool}.conf" ''
[global]
error_log = syslog
daemonize = no
${cfg.extraConfig}
${concatStringsSep "\n" (mapAttrsToList (n: v: "${n} = ${toStr v}") cfg.settings)}
${optionalString (cfg.extraConfig != null) cfg.extraConfig}
[${pool}]
${conf}
${concatStringsSep "\n" (mapAttrsToList (n: v: "${n} = ${toStr v}") poolOpts.settings)}
${concatStringsSep "\n" (mapAttrsToList (n: v: "env[${n}] = ${toStr v}") poolOpts.phpEnv)}
${optionalString (poolOpts.extraConfig != null) poolOpts.extraConfig}
'';
phpIni = pool: pkgs.runCommand "php.ini" {
inherit (pool) phpPackage phpOptions;
phpIni = poolOpts: pkgs.runCommand "php.ini" {
inherit (poolOpts) phpPackage phpOptions;
preferLocalBuild = true;
nixDefaults = ''
sendmail_path = "/run/wrappers/bin/sendmail -t -i"
@ -48,13 +34,138 @@ let
cat $phpPackage/etc/php.ini $nixDefaultsPath $phpOptionsPath > $out
'';
poolOpts = { name, ... }:
let
poolOpts = cfg.pools."${name}";
in
{
options = {
socket = mkOption {
type = types.str;
readOnly = true;
description = ''
Path to the unix socket file on which to accept FastCGI requests.
<note><para>This option is read-only and managed by NixOS.</para></note>
'';
};
listen = mkOption {
type = types.str;
default = "";
example = "/path/to/unix/socket";
description = ''
The address on which to accept FastCGI requests.
'';
};
phpPackage = mkOption {
type = types.package;
default = cfg.phpPackage;
defaultText = "config.services.phpfpm.phpPackage";
description = ''
The PHP package to use for running this PHP-FPM pool.
'';
};
phpOptions = mkOption {
type = types.lines;
default = cfg.phpOptions;
defaultText = "config.services.phpfpm.phpOptions";
description = ''
"Options appended to the PHP configuration file <filename>php.ini</filename> used for this PHP-FPM pool."
'';
};
phpEnv = lib.mkOption {
type = with types; attrsOf str;
default = {};
description = ''
Environment variables used for this PHP-FPM pool.
'';
example = literalExample ''
{
HOSTNAME = "$HOSTNAME";
TMP = "/tmp";
TMPDIR = "/tmp";
TEMP = "/tmp";
}
'';
};
user = mkOption {
type = types.str;
description = "User account under which this pool runs.";
};
group = mkOption {
type = types.str;
description = "Group account under which this pool runs.";
};
settings = mkOption {
type = with types; attrsOf (oneOf [ str int bool ]);
default = {};
description = ''
PHP-FPM pool directives. Refer to the "List of pool directives" section of
<link xlink:href="https://www.php.net/manual/en/install.fpm.configuration.php"/>
for details. Note that settings names must be enclosed in quotes (e.g.
<literal>"pm.max_children"</literal> instead of <literal>pm.max_children</literal>).
'';
example = literalExample ''
{
"pm" = "dynamic";
"pm.max_children" = 75;
"pm.start_servers" = 10;
"pm.min_spare_servers" = 5;
"pm.max_spare_servers" = 20;
"pm.max_requests" = 500;
}
'';
};
extraConfig = mkOption {
type = with types; nullOr lines;
default = null;
description = ''
Extra lines that go into the pool configuration.
See the documentation on <literal>php-fpm.conf</literal> for
details on configuration directives.
'';
};
};
config = {
socket = if poolOpts.listen == "" then "${runtimeDir}/${name}.sock" else poolOpts.listen;
group = mkDefault poolOpts.user;
settings = mapAttrs (name: mkDefault){
listen = poolOpts.socket;
user = poolOpts.user;
group = poolOpts.group;
};
};
};
in {
options = {
services.phpfpm = {
settings = mkOption {
type = with types; attrsOf (oneOf [ str int bool ]);
default = {};
description = ''
PHP-FPM global directives. Refer to the "List of global php-fpm.conf directives" section of
<link xlink:href="https://www.php.net/manual/en/install.fpm.configuration.php"/>
for details. Note that settings names must be enclosed in quotes (e.g.
<literal>"pm.max_children"</literal> instead of <literal>pm.max_children</literal>).
You need not specify the options <literal>error_log</literal> or
<literal>daemonize</literal> here, since they are generated by NixOS.
'';
};
extraConfig = mkOption {
type = types.lines;
default = "";
type = with types; nullOr lines;
default = null;
description = ''
Extra configuration that should be put in the global section of
the PHP-FPM configuration file. Do not specify the options
@ -80,64 +191,56 @@ in {
''
date.timezone = "CET"
'';
description =
"Options appended to the PHP configuration file <filename>php.ini</filename>.";
};
poolConfigs = mkOption {
default = {};
type = types.attrsOf types.lines;
example = literalExample ''
{ mypool = '''
listen = /run/phpfpm/mypool
user = nobody
pm = dynamic
pm.max_children = 75
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.max_requests = 500
''';
}
'';
description = ''
A mapping between PHP-FPM pool names and their configurations.
See the documentation on <literal>php-fpm.conf</literal> for
details on configuration directives. If no pools are defined,
the phpfpm service is disabled.
Options appended to the PHP configuration file <filename>php.ini</filename>.
'';
};
pools = mkOption {
type = types.attrsOf (types.submodule (import ./pool-options.nix {
inherit lib config;
}));
type = types.attrsOf (types.submodule poolOpts);
default = {};
example = literalExample ''
{
mypool = {
listen = "/path/to/unix/socket";
user = "php";
group = "php";
phpPackage = pkgs.php;
extraConfig = '''
user = nobody
pm = dynamic
pm.max_children = 75
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.max_requests = 500
settings = '''
"pm" = "dynamic";
"pm.max_children" = 75;
"pm.start_servers" = 10;
"pm.min_spare_servers" = 5;
"pm.max_spare_servers" = 20;
"pm.max_requests" = 500;
''';
}
}'';
description = ''
PHP-FPM pools. If no pools or poolConfigs are defined, the PHP-FPM
PHP-FPM pools. If no pools are defined, the PHP-FPM
service is disabled.
'';
};
};
};
config = mkIf enabled {
config = mkIf (cfg.pools != {}) {
warnings =
mapAttrsToList (pool: poolOpts: ''
Using config.services.phpfpm.pools.${pool}.listen is deprecated and will become unsupported in a future release. Please reference the read-only option config.services.phpfpm.pools.${pool}.socket to access the path of your socket.
'') (filterAttrs (pool: poolOpts: poolOpts.listen != "") cfg.pools) ++
mapAttrsToList (pool: poolOpts: ''
Using config.services.phpfpm.pools.${pool}.extraConfig is deprecated and will become unsupported in a future release. Please migrate your configuration to config.services.phpfpm.pools.${pool}.settings.
'') (filterAttrs (pool: poolOpts: poolOpts.extraConfig != null) cfg.pools) ++
optional (cfg.extraConfig != null) ''
Using config.services.phpfpm.extraConfig is deprecated and will become unsupported in a future release. Please migrate your configuration to config.services.phpfpm.settings.
''
;
services.phpfpm.settings = {
error_log = "syslog";
daemonize = false;
};
systemd.slices.phpfpm = {
description = "PHP FastCGI Process manager pools slice";
@ -148,18 +251,15 @@ in {
wantedBy = [ "multi-user.target" ];
};
systemd.services = flip mapAttrs' poolConfigs (pool: poolConfig:
systemd.services = mapAttrs' (pool: poolOpts:
nameValuePair "phpfpm-${pool}" {
description = "PHP FastCGI Process Manager service for pool ${pool}";
after = [ "network.target" ];
wantedBy = [ "phpfpm.target" ];
partOf = [ "phpfpm.target" ];
preStart = ''
mkdir -p ${stateDir}
'';
serviceConfig = let
cfgFile = fpmCfgFile pool poolConfig.config;
iniFile = phpIni poolConfig;
cfgFile = fpmCfgFile pool poolOpts;
iniFile = phpIni poolOpts;
in {
Slice = "phpfpm.slice";
PrivateDevices = true;
@ -168,10 +268,12 @@ in {
# XXX: We need AF_NETLINK to make the sendmail SUID binary from postfix work
RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6 AF_NETLINK";
Type = "notify";
ExecStart = "${poolConfig.phpPackage}/bin/php-fpm -y ${cfgFile} -c ${iniFile}";
ExecStart = "${poolOpts.phpPackage}/bin/php-fpm -y ${cfgFile} -c ${iniFile}";
ExecReload = "${pkgs.coreutils}/bin/kill -USR2 $MAINPID";
RuntimeDirectory = "phpfpm";
RuntimeDirectoryPreserve = true; # Relevant when multiple processes are running
};
}
);
) cfg.pools;
};
}

View file

@ -1,57 +0,0 @@
{ lib, config }:
let
fpmCfg = config.services.phpfpm;
in
with lib; {
options = {
listen = mkOption {
type = types.str;
example = "/path/to/unix/socket";
description = ''
The address on which to accept FastCGI requests.
'';
};
phpPackage = mkOption {
type = types.package;
default = fpmCfg.phpPackage;
defaultText = "config.services.phpfpm.phpPackage";
description = ''
The PHP package to use for running this PHP-FPM pool.
'';
};
phpOptions = mkOption {
type = types.lines;
default = fpmCfg.phpOptions;
defaultText = "config.services.phpfpm.phpOptions";
description = ''
"Options appended to the PHP configuration file <filename>php.ini</filename> used for this PHP-FPM pool."
'';
};
extraConfig = mkOption {
type = types.lines;
example = ''
user = nobody
pm = dynamic
pm.max_children = 75
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.max_requests = 500
'';
description = ''
Extra lines that go into the pool configuration.
See the documentation on <literal>php-fpm.conf</literal> for
details on configuration directives.
'';
};
};
}

View file

@ -3,7 +3,9 @@
with lib;
let
cfg = config.services.xserver.desktopManager.gnome3;
serviceCfg = config.services.gnome3;
# Prioritize nautilus by default when opening directories
mimeAppsList = pkgs.writeTextFile {
@ -29,10 +31,10 @@ let
chmod -R a+w $out/share/gsettings-schemas/nixos-gsettings-overrides
cat - > $out/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas/nixos-defaults.gschema.override <<- EOF
[org.gnome.desktop.background]
picture-uri='${pkgs.nixos-artwork.wallpapers.simple-dark-gray}/share/artwork/gnome/nix-wallpaper-simple-dark-gray.png'
picture-uri='file://${pkgs.nixos-artwork.wallpapers.simple-dark-gray}/share/artwork/gnome/nix-wallpaper-simple-dark-gray.png'
[org.gnome.desktop.screensaver]
picture-uri='${pkgs.nixos-artwork.wallpapers.simple-dark-gray-bottom}/share/artwork/gnome/nix-wallpaper-simple-dark-gray_bottom.png'
picture-uri='file://${pkgs.nixos-artwork.wallpapers.simple-dark-gray-bottom}/share/artwork/gnome/nix-wallpaper-simple-dark-gray_bottom.png'
[org.gnome.shell]
favorite-apps=[ 'org.gnome.Epiphany.desktop', 'evolution.desktop', 'org.gnome.Music.desktop', 'org.gnome.Photos.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.Software.desktop' ]
@ -45,10 +47,19 @@ let
flashbackEnabled = cfg.flashback.enableMetacity || length cfg.flashback.customSessions > 0;
in {
in
{
options = {
services.gnome3 = {
core-os-services.enable = mkEnableOption "essential services for GNOME3";
core-shell.enable = mkEnableOption "GNOME Shell services";
core-utilities.enable = mkEnableOption "GNOME core utilities";
games.enable = mkEnableOption "GNOME games";
};
services.xserver.desktopManager.gnome3 = {
enable = mkOption {
default = false;
@ -121,62 +132,40 @@ in {
};
config = mkIf cfg.enable {
config = mkMerge [
(mkIf (cfg.enable || flashbackEnabled) {
services.gnome3.core-os-services.enable = true;
services.gnome3.core-shell.enable = true;
services.gnome3.core-utilities.enable = mkDefault true;
# Enable helpful DBus services.
security.polkit.enable = true;
services.udisks2.enable = true;
services.accounts-daemon.enable = true;
services.dleyna-renderer.enable = mkDefault true;
services.dleyna-server.enable = mkDefault true;
services.gnome3.at-spi2-core.enable = true;
services.gnome3.evolution-data-server.enable = true;
services.gnome3.glib-networking.enable = true;
services.gnome3.gnome-keyring.enable = true;
services.gnome3.gnome-online-accounts.enable = mkDefault true;
services.gnome3.gnome-remote-desktop.enable = mkDefault true;
services.gnome3.gnome-settings-daemon.enable = true;
services.gnome3.gnome-terminal-server.enable = mkDefault true;
services.gnome3.gnome-user-share.enable = mkDefault true;
services.gnome3.gvfs.enable = true;
services.gnome3.rygel.enable = mkDefault true;
services.gnome3.seahorse.enable = mkDefault true;
services.gnome3.sushi.enable = mkDefault true;
services.gnome3.tracker.enable = mkDefault true;
services.gnome3.tracker-miners.enable = mkDefault true;
hardware.pulseaudio.enable = mkDefault true;
services.telepathy.enable = mkDefault true;
networking.networkmanager.enable = mkDefault true;
services.upower.enable = config.powerManagement.enable;
services.dbus.packages =
optional config.services.printing.enable pkgs.system-config-printer ++
optional flashbackEnabled pkgs.gnome3.gnome-screensaver;
services.colord.enable = mkDefault true;
services.packagekit.enable = mkDefault true;
hardware.bluetooth.enable = mkDefault true;
services.hardware.bolt.enable = mkDefault true;
services.xserver.libinput.enable = mkDefault true; # for controlling touchpad settings via gnome control center
systemd.packages = [ pkgs.gnome3.vino ];
xdg.portal.enable = true;
xdg.portal.extraPortals = [ pkgs.xdg-desktop-portal-gtk ];
services.xserver.displayManager.extraSessionFilePackages = [ pkgs.gnome3.gnome-session ];
# Enable default programs
programs.evince.enable = mkDefault true;
programs.file-roller.enable = mkDefault true;
programs.gnome-disks.enable = mkDefault true;
programs.gnome-documents.enable = mkDefault true;
environment.extraInit = ''
${concatMapStrings (p: ''
if [ -d "${p}/share/gsettings-schemas/${p.name}" ]; then
export XDG_DATA_DIRS=$XDG_DATA_DIRS''${XDG_DATA_DIRS:+:}${p}/share/gsettings-schemas/${p.name}
fi
# If gnome3 is installed, build vim for gtk3 too.
nixpkgs.config.vim.gui = "gtk3";
if [ -d "${p}/lib/girepository-1.0" ]; then
export GI_TYPELIB_PATH=$GI_TYPELIB_PATH''${GI_TYPELIB_PATH:+:}${p}/lib/girepository-1.0
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH''${LD_LIBRARY_PATH:+:}${p}/lib
fi
'') cfg.sessionPath}
'';
fonts.fonts = [
pkgs.dejavu_fonts pkgs.cantarell-fonts
pkgs.source-sans-pro
pkgs.source-code-pro # Default monospace font in 3.32
];
environment.systemPackages = cfg.sessionPath;
services.xserver.displayManager.extraSessionFilePackages = [ pkgs.gnome3.gnome-session ]
++ map
environment.variables.GNOME_SESSION_DEBUG = mkIf cfg.debug "1";
# Override GSettings schemas
environment.variables.NIX_GSETTINGS_OVERRIDES_DIR = "${nixos-gsettings-desktop-schemas}/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas";
# If gnome3 is installed, build vim for gtk3 too.
nixpkgs.config.vim.gui = "gtk3";
})
(mkIf flashbackEnabled {
services.xserver.displayManager.extraSessionFilePackages = map
(wm: pkgs.gnome3.gnome-flashback.mkSessionForWm {
inherit (wm) wmName wmLabel wmCommand;
}) (optional cfg.flashback.enableMetacity {
@ -185,75 +174,152 @@ in {
wmCommand = "${pkgs.gnome3.metacity}/bin/metacity";
} ++ cfg.flashback.customSessions);
environment.extraInit = ''
${concatMapStrings (p: ''
if [ -d "${p}/share/gsettings-schemas/${p.name}" ]; then
export XDG_DATA_DIRS=$XDG_DATA_DIRS''${XDG_DATA_DIRS:+:}${p}/share/gsettings-schemas/${p.name}
fi
security.pam.services.gnome-screensaver = {
enableGnomeKeyring = true;
};
if [ -d "${p}/lib/girepository-1.0" ]; then
export GI_TYPELIB_PATH=$GI_TYPELIB_PATH''${GI_TYPELIB_PATH:+:}${p}/lib/girepository-1.0
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH''${LD_LIBRARY_PATH:+:}${p}/lib
fi
'') cfg.sessionPath}
'';
services.dbus.packages = [
pkgs.gnome3.gnome-screensaver
];
})
(mkIf serviceCfg.core-os-services.enable {
hardware.bluetooth.enable = mkDefault true;
hardware.pulseaudio.enable = mkDefault true;
programs.dconf.enable = true;
security.polkit.enable = true;
services.accounts-daemon.enable = true;
services.dleyna-renderer.enable = mkDefault true;
services.dleyna-server.enable = mkDefault true;
services.gnome3.at-spi2-core.enable = true;
services.gnome3.evolution-data-server.enable = true;
services.gnome3.gnome-keyring.enable = true;
services.gnome3.gnome-online-accounts.enable = mkDefault true;
services.gnome3.gnome-online-miners.enable = true;
services.gnome3.tracker-miners.enable = mkDefault true;
services.gnome3.tracker.enable = mkDefault true;
services.hardware.bolt.enable = mkDefault true;
services.packagekit.enable = mkDefault true;
services.udisks2.enable = true;
services.upower.enable = config.powerManagement.enable;
services.xserver.libinput.enable = mkDefault true; # for controlling touchpad settings via gnome control center
services.geoclue2.enable = mkDefault true;
# GNOME should have its own geoclue agent
services.geoclue2.enableDemoAgent = false;
xdg.portal.enable = true;
xdg.portal.extraPortals = [ pkgs.xdg-desktop-portal-gtk ];
services.geoclue2.appConfig.gnome-datetime-panel = {
isAllowed = true;
isSystem = true;
};
services.geoclue2.appConfig.gnome-color-panel = {
isAllowed = true;
isSystem = true;
};
services.geoclue2.appConfig."org.gnome.Shell" = {
isAllowed = true;
isSystem = true;
};
networking.networkmanager.enable = mkDefault true;
environment.variables.GNOME_SESSION_DEBUG = optionalString cfg.debug "1";
# Override default mimeapps
environment.variables.XDG_DATA_DIRS = [ "${mimeAppsList}/share" ];
# Override GSettings schemas
environment.variables.NIX_GSETTINGS_OVERRIDES_DIR = "${nixos-gsettings-desktop-schemas}/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas";
# Let nautilus find extensions
# TODO: Create nautilus-with-extensions package
environment.variables.NAUTILUS_EXTENSION_DIR = "${config.system.path}/lib/nautilus/extensions-3.0";
services.xserver.updateDbusEnvironment = true;
environment.variables.GIO_EXTRA_MODULES = [ "${lib.getLib pkgs.gnome3.dconf}/lib/gio/modules"
"${pkgs.gnome3.gvfs}/lib/gio/modules" ];
environment.systemPackages = pkgs.gnome3.corePackages ++ cfg.sessionPath
++ (pkgs.gnome3.removePackagesByName pkgs.gnome3.optionalPackages config.environment.gnome3.excludePackages) ++ [
pkgs.xdg-user-dirs # Update user dirs as described in http://freedesktop.org/wiki/Software/xdg-user-dirs/
];
# Use the correct gnome3 packageSet
networking.networkmanager.basePackages =
{ inherit (pkgs) networkmanager modemmanager wpa_supplicant crda;
# Use the correct gnome3 packageSet
networking.networkmanager.basePackages = {
inherit (pkgs) networkmanager modemmanager wpa_supplicant crda;
inherit (pkgs.gnome3) networkmanager-openvpn networkmanager-vpnc
networkmanager-openconnect networkmanager-fortisslvpn
networkmanager-iodine networkmanager-l2tp; };
networkmanager-openconnect networkmanager-fortisslvpn
networkmanager-iodine networkmanager-l2tp;
};
# Needed for themes and backgrounds
environment.pathsToLink = [
"/share"
"/share/nautilus-python/extensions"
];
services.xserver.updateDbusEnvironment = true;
security.pam.services.gnome-screensaver = mkIf flashbackEnabled {
enableGnomeKeyring = true;
};
};
# Needed for themes and backgrounds
environment.pathsToLink = [
"/share" # TODO: https://github.com/NixOS/nixpkgs/issues/47173
];
})
(mkIf serviceCfg.core-shell.enable {
services.colord.enable = mkDefault true;
services.gnome3.glib-networking.enable = true;
services.gnome3.gnome-remote-desktop.enable = mkDefault true;
services.gnome3.gnome-settings-daemon.enable = true;
services.gnome3.gnome-user-share.enable = mkDefault true;
services.gnome3.rygel.enable = mkDefault true;
services.gvfs.enable = true;
services.telepathy.enable = mkDefault true;
systemd.packages = [ pkgs.gnome3.vino ];
services.dbus.packages =
optional config.services.printing.enable pkgs.system-config-printer;
services.geoclue2.enable = mkDefault true;
services.geoclue2.enableDemoAgent = false; # GNOME has its own geoclue agent
services.geoclue2.appConfig."gnome-datetime-panel" = {
isAllowed = true;
isSystem = true;
};
services.geoclue2.appConfig."gnome-color-panel" = {
isAllowed = true;
isSystem = true;
};
services.geoclue2.appConfig."org.gnome.Shell" = {
isAllowed = true;
isSystem = true;
};
fonts.fonts = with pkgs; [
cantarell-fonts
dejavu_fonts
source-code-pro # Default monospace font in 3.32
source-sans-pro
];
environment.systemPackages = with pkgs.gnome3; [
adwaita-icon-theme
gnome-backgrounds
gnome-bluetooth
gnome-control-center
gnome-getting-started-docs
gnome-shell
gnome-shell-extensions
gnome-themes-extra
gnome-user-docs
pkgs.glib # for gsettings
pkgs.gnome-menus
pkgs.gtk3.out # for gtk-launch
pkgs.hicolor-icon-theme
pkgs.shared-mime-info # for update-mime-database
pkgs.xdg-user-dirs # Update user dirs as described in http://freedesktop.org/wiki/Software/xdg-user-dirs/
vino
];
})
(mkIf serviceCfg.core-utilities.enable {
environment.systemPackages = (with pkgs.gnome3; removePackagesByName [
baobab eog epiphany evince gucharmap nautilus totem yelp gnome-calculator
gnome-contacts gnome-font-viewer gnome-screenshot gnome-system-monitor simple-scan
gnome-terminal evolution file-roller gedit gnome-clocks gnome-music gnome-tweaks
pkgs.gnome-photos nautilus-sendto dconf-editor vinagre gnome-weather gnome-logs
gnome-maps gnome-characters gnome-calendar accerciser gnome-nettool gnome-packagekit
gnome-software gnome-power-manager gnome-todo pkgs.gnome-usage
] config.environment.gnome3.excludePackages);
# Enable default programs
programs.evince.enable = mkDefault true;
programs.file-roller.enable = mkDefault true;
programs.gnome-disks.enable = mkDefault true;
programs.gnome-documents.enable = mkDefault true;
programs.gnome-terminal.enable = mkDefault true;
services.gnome3.seahorse.enable = mkDefault true;
services.gnome3.sushi.enable = mkDefault true;
# Let nautilus find extensions
# TODO: Create nautilus-with-extensions package
environment.variables.NAUTILUS_EXTENSION_DIR = "${config.system.path}/lib/nautilus/extensions-3.0";
# Override default mimeapps for nautilus
environment.variables.XDG_DATA_DIRS = [ "${mimeAppsList}/share" ];
environment.pathsToLink = [
"/share/nautilus-python/extensions"
];
})
(mkIf serviceCfg.games.enable {
environment.systemPackages = (with pkgs.gnome3; removePackagesByName [
aisleriot atomix five-or-more four-in-a-row gnome-chess gnome-klotski
gnome-mahjongg gnome-mines gnome-nibbles gnome-robots gnome-sudoku
gnome-taquin gnome-tetravex hitori iagno lightsoff quadrapassel
swell-foop tali
] config.environment.gnome3.excludePackages);
})
];
}

View file

@ -58,7 +58,8 @@ in
# Link some extra directories in /run/current-system/software/share
environment.pathsToLink = [ "/share" ];
environment.variables.GIO_EXTRA_MODULES = [ "${pkgs.gvfs}/lib/gio/modules" ];
services.gvfs.enable = true;
services.gvfs.package = pkgs.gvfs;
services.upower.enable = config.powerManagement.enable;
};

View file

@ -94,17 +94,19 @@ in
];
programs.dconf.enable = true;
# Shell integration for VTE terminals
programs.bash.vteIntegration = mkDefault true;
programs.zsh.vteIntegration = mkDefault true;
services.gnome3.at-spi2-core.enable = true;
services.gnome3.gnome-keyring.enable = true;
services.gnome3.gnome-settings-daemon.enable = true;
services.gnome3.gnome-settings-daemon.package = pkgs.mate.mate-settings-daemon;
services.gnome3.gvfs.enable = true;
services.gvfs.enable = true;
services.upower.enable = config.powerManagement.enable;
security.pam.services.mate-screensaver.unixAuth = true;
environment.variables.GIO_EXTRA_MODULES = [ "${pkgs.gnome3.gvfs}/lib/gio/modules" ];
environment.pathsToLink = [ "/share" ];
};

View file

@ -99,10 +99,6 @@ in
fi
'') cfg.sessionPath}
# Makes qt applications look less alien
export QT_QPA_PLATFORMTHEME=gtk3
export QT_STYLE_OVERRIDE=adwaita
# Settings from elementary-default-settings
export GTK_CSD=1
export GTK_MODULES=$GTK_MODULES:pantheon-filechooser-module
@ -129,7 +125,7 @@ in
services.gnome3.gnome-keyring.enable = true;
services.gnome3.gnome-settings-daemon.enable = true;
services.gnome3.gnome-settings-daemon.package = pkgs.pantheon.elementary-settings-daemon;
services.gnome3.gvfs.enable = true;
services.gvfs.enable = true;
services.gnome3.rygel.enable = mkDefault true;
services.gsignond.enable = mkDefault true;
services.gsignond.plugins = with pkgs.gsignondPlugins; [ lastfm mail oauth ];
@ -146,9 +142,19 @@ in
isSystem = true;
};
programs.dconf.enable = true;
programs.evince.enable = mkDefault true;
programs.file-roller.enable = mkDefault true;
# Shell integration for VTE terminals
programs.bash.vteIntegration = mkDefault true;
programs.zsh.vteIntegration = mkDefault true;
# Harmonize Qt5 applications under Pantheon
qt5.enable = true;
qt5.platformTheme = "gnome";
qt5.style = "adwaita";
networking.networkmanager.enable = mkDefault true;
networking.networkmanager.basePackages =
{ inherit (pkgs) networkmanager modemmanager wpa_supplicant crda;
@ -161,11 +167,6 @@ in
environment.variables.GNOME_SESSION_DEBUG = optionalString cfg.debug "1";
environment.variables.GIO_EXTRA_MODULES = [
"${lib.getLib pkgs.gnome3.dconf}/lib/gio/modules"
"${pkgs.gnome3.gvfs}/lib/gio/modules"
];
environment.pathsToLink = [
# FIXME: modules should link subdirs of `/share` rather than relying on this
"/share"
@ -187,7 +188,6 @@ in
glib-networking
gnome-menus
gnome3.adwaita-icon-theme
gnome3.dconf
gtk3.out
hicolor-icon-theme
lightlocker

View file

@ -66,7 +66,6 @@ in
exo
garcon
gtk-xfce-engine
gvfs
libxfce4ui
tumbler
xfconf
@ -100,10 +99,6 @@ in
"/share/gtksourceview-2.0"
];
environment.variables = {
GIO_EXTRA_MODULES = [ "${pkgs.xfce.gvfs}/lib/gio/modules" ];
};
services.xserver.gdk-pixbuf.modulePackages = [ pkgs.librsvg ];
services.xserver.desktopManager.session = [{
@ -128,5 +123,7 @@ in
# Enable helpful DBus services.
services.udisks2.enable = true;
services.upower.enable = config.powerManagement.enable;
services.gvfs.enable = true;
services.gvfs.package = pkgs.xfce.gvfs;
};
}

View file

@ -129,7 +129,7 @@ in
assertion = cfg.killer != null -> cfg.killtime >= 10;
message = "killtime has to be at least 10 minutes according to `man xautolock`";
}
] ++ (lib.flip map [ "locker" "notifier" "nowlocker" "killer" ]
] ++ (lib.forEach [ "locker" "notifier" "nowlocker" "killer" ]
(option:
{
assertion = cfg.${option} != null -> builtins.substring 0 1 cfg.${option} == "/";

View file

@ -78,7 +78,7 @@ let
in imap1 mkHead cfg.xrandrHeads;
xrandrDeviceSection = let
monitors = flip map xrandrHeads (h: ''
monitors = forEach xrandrHeads (h: ''
Option "monitor-${h.config.output}" "${h.name}"
'');
# First option is indented through the space in the config but any

View file

@ -1,66 +0,0 @@
{ config, lib, pkgs, ... }:
with lib;
{
options = {
systemd.coredump = {
enable = mkOption {
default = false;
type = types.bool;
description = ''
Enables storing core dumps in systemd.
Note that this alone is not enough to enable core dumps. The maximum
file size for core dumps must be specified in limits.conf as well. See
<option>security.pam.loginLimits</option> and the limits.conf(5)
man page (these specify the core dump limits for user login sessions)
and <option>systemd.extraConfig</option> (where e.g.
<literal>DefaultLimitCORE=1000000</literal> can be specified to set
the core dump limit for systemd system-level services).
'';
};
extraConfig = mkOption {
default = "";
type = types.lines;
example = "Storage=journal";
description = ''
Extra config options for systemd-coredump. See coredump.conf(5) man page
for available options.
'';
};
};
};
config = mkMerge [
(mkIf config.systemd.coredump.enable {
systemd.additionalUpstreamSystemUnits = [ "systemd-coredump.socket" "systemd-coredump@.service" ];
environment.etc."systemd/coredump.conf".text =
''
[Coredump]
${config.systemd.coredump.extraConfig}
'';
# Have the kernel pass core dumps to systemd's coredump helper binary.
# From systemd's 50-coredump.conf file. See:
# <https://github.com/systemd/systemd/blob/v218/sysctl.d/50-coredump.conf.in>
boot.kernel.sysctl."kernel.core_pattern" = "|${pkgs.systemd}/lib/systemd/systemd-coredump %P %u %g %s %t %c %e";
})
(mkIf (!config.systemd.coredump.enable) {
boot.kernel.sysctl."kernel.core_pattern" = mkDefault "core";
systemd.extraConfig =
''
DefaultLimitCORE=0:infinity
'';
})
];
}

View file

@ -36,6 +36,7 @@ in
boot.kernelPackages = mkOption {
default = pkgs.linuxPackages;
type = types.unspecified // { merge = mergeEqualOption; };
apply = kernelPackages: kernelPackages.extend (self: super: {
kernel = super.kernel.override {
inherit randstructSeed;

View file

@ -684,7 +684,7 @@ in
assertion = if args.efiSysMountPoint == null then true else hasPrefix "/" args.efiSysMountPoint;
message = "EFI paths must be absolute, not ${args.efiSysMountPoint}";
}
] ++ flip map args.devices (device: {
] ++ forEach args.devices (device: {
assertion = device == "nodev" || hasPrefix "/" device;
message = "GRUB devices must be absolute paths, not ${device} in ${args.path}";
}));

View file

@ -55,6 +55,27 @@ let
(assertMacAddress "MACAddress")
];
# NOTE The PrivateKey directive is missing on purpose here, please
# do not add it to this list. The nix store is world-readable let's
# refrain ourselves from providing a footgun.
checkWireGuard = checkUnitConfig "WireGuard" [
(assertOnlyFields [
"PrivateKeyFile" "ListenPort" "FwMark"
])
(assertRange "FwMark" 1 4294967295)
];
# NOTE The PresharedKey directive is missing on purpose here, please
# do not add it to this list. The nix store is world-readable,let's
# refrain ourselves from providing a footgun.
checkWireGuardPeer = checkUnitConfig "WireGuardPeer" [
(assertOnlyFields [
"PublicKey" "PresharedKeyFile" "AllowedIPs"
"Endpoint" "PersistentKeepalive"
])
(assertRange "PersistentKeepalive" 1 65535)
];
checkVlan = checkUnitConfig "VLAN" [
(assertOnlyFields ["Id" "GVRP" "MVRP" "LooseBinding" "ReorderHeader"])
(assertRange "Id" 0 4094)
@ -320,6 +341,46 @@ let
'';
};
wireguardConfig = mkOption {
default = {};
example = {
PrivateKeyFile = "/etc/wireguard/secret.key";
ListenPort = 51820;
FwMark = 42;
};
type = types.addCheck (types.attrsOf unitOption) checkWireGuard;
description = ''
Each attribute in this set specifies an option in the
<literal>[WireGuard]</literal> section of the unit. See
<citerefentry><refentrytitle>systemd.netdev</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
Use <literal>PrivateKeyFile</literal> instead of
<literal>PrivateKey</literal>: the nix store is
world-readable.
'';
};
wireguardPeers = mkOption {
default = [];
example = [ { wireguardPeerConfig={
Endpoint = "192.168.1.1:51820";
PublicKey = "27s0OvaBBdHoJYkH9osZpjpgSOVNw+RaKfboT/Sfq0g=";
PresharedKeyFile = "/etc/wireguard/psk.key";
AllowedIPs = [ "10.0.0.1/32" ];
PersistentKeepalive = 15;
};}];
type = with types; listOf (submodule wireguardPeerOptions);
description = ''
Each item in this array specifies an option in the
<literal>[WireGuardPeer]</literal> section of the unit. See
<citerefentry><refentrytitle>systemd.netdev</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
Use <literal>PresharedKeyFile</literal> instead of
<literal>PresharedKey</literal>: the nix store is
world-readable.
'';
};
vlanConfig = mkOption {
default = {};
example = { Id = "4"; };
@ -450,6 +511,23 @@ let
};
};
wireguardPeerOptions = {
options = {
wireguardPeerConfig = mkOption {
default = {};
example = { };
type = types.addCheck (types.attrsOf unitOption) checkWireGuardPeer;
description = ''
Each attribute in this set specifies an option in the
<literal>[WireGuardPeer]</literal> section of the unit. See
<citerefentry><refentrytitle>systemd.network</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
'';
};
};
};
networkOptions = commonNetworkOptions // {
networkConfig = mkOption {
@ -732,6 +810,16 @@ let
${attrsToSection def.bondConfig}
''}
${optionalString (def.wireguardConfig != { }) ''
[WireGuard]
${attrsToSection def.wireguardConfig}
''}
${flip concatMapStrings def.wireguardPeers (x: ''
[WireGuardPeer]
${attrsToSection x.wireguardPeerConfig}
'')}
${def.extraConfig}
'';
};

View file

@ -44,13 +44,13 @@ EOF
*) to ignore the error and continue
EOF
read reply
read -n 1 reply
if [ -n "$allowShell" -a "$reply" = f ]; then
exec setsid @shell@ -c "exec @shell@ < /dev/$console >/dev/$console 2>/dev/$console"
elif [ -n "$allowShell" -a "$reply" = i ]; then
echo "Starting interactive shell..."
setsid @shell@ -c "@shell@ < /dev/$console >/dev/$console 2>/dev/$console" || fail
setsid @shell@ -c "exec @shell@ < /dev/$console >/dev/$console 2>/dev/$console" || fail
elif [ "$reply" = r ]; then
echo "Rebooting..."
reboot -f

View file

@ -76,6 +76,10 @@ let
"systemd-journald-dev-log.socket"
"syslog.socket"
# Coredumps.
"systemd-coredump.socket"
"systemd-coredump@.service"
# SysV init compatibility.
"systemd-initctl.socket"
"systemd-initctl.service"
@ -533,13 +537,23 @@ in
};
systemd.enableCgroupAccounting = mkOption {
default = false;
default = true;
type = types.bool;
description = ''
Whether to enable cgroup accounting.
'';
};
systemd.coredump.extraConfig = mkOption {
default = "";
type = types.lines;
example = "Storage=journal";
description = ''
Extra config options for systemd-coredump. See coredump.conf(5) man page
for available options.
'';
};
systemd.extraConfig = mkOption {
default = "";
type = types.lines;
@ -790,11 +804,12 @@ in
[Manager]
${optionalString config.systemd.enableCgroupAccounting ''
DefaultCPUAccounting=yes
DefaultBlockIOAccounting=yes
DefaultIOAccounting=yes
DefaultBlockIOAccounting=yes
DefaultMemoryAccounting=yes
DefaultTasksAccounting=yes
DefaultIPAccounting=yes
''}
DefaultLimitCORE=infinity
${config.systemd.extraConfig}
'';
@ -818,6 +833,12 @@ in
${config.services.journald.extraConfig}
'';
"systemd/coredump.conf".text =
''
[Coredump]
${config.systemd.coredump.extraConfig}
'';
"systemd/logind.conf".text = ''
[Login]
KillUserProcesses=${if config.services.logind.killUserProcesses then "yes" else "no"}
@ -831,6 +852,10 @@ in
[Sleep]
'';
# install provided sysctl snippets
"sysctl.d/50-coredump.conf".source = "${systemd}/example/sysctl.d/50-coredump.conf";
"sysctl.d/50-default.conf".source = "${systemd}/example/sysctl.d/50-default.conf";
"tmpfiles.d/systemd.conf".source = "${systemd}/example/tmpfiles.d/systemd.conf";
"tmpfiles.d/x11.conf".source = "${systemd}/example/tmpfiles.d/x11.conf";

View file

@ -74,7 +74,7 @@ in
enable = true;
networks."99-main" = genericNetwork mkDefault;
}
(mkMerge (flip map interfaces (i: {
(mkMerge (forEach interfaces (i: {
netdevs = mkIf i.virtual ({
"40-${i.name}" = {
netdevConfig = {
@ -90,7 +90,7 @@ in
name = mkDefault i.name;
DHCP = mkForce (dhcpStr
(if i.useDHCP != null then i.useDHCP else cfg.useDHCP && interfaceIps i == [ ]));
address = flip map (interfaceIps i)
address = forEach (interfaceIps i)
(ip: "${ip.address}/${toString ip.prefixLength}");
networkConfig.IPv6PrivacyExtensions = "kernel";
} ];
@ -102,7 +102,7 @@ in
Kind = "bridge";
};
};
networks = listToAttrs (flip map bridge.interfaces (bi:
networks = listToAttrs (forEach bridge.interfaces (bi:
nameValuePair "40-${bi}" (mkMerge [ (genericNetwork (mkOverride 999)) {
DHCP = mkOverride 0 (dhcpStr false);
networkConfig.Bridge = name;
@ -173,7 +173,7 @@ in
};
networks = listToAttrs (flip map bond.interfaces (bi:
networks = listToAttrs (forEach bond.interfaces (bi:
nameValuePair "40-${bi}" (mkMerge [ (genericNetwork (mkOverride 999)) {
DHCP = mkOverride 0 (dhcpStr false);
networkConfig.Bond = name;

View file

@ -926,7 +926,7 @@ in
warnings = concatMap (i: i.warnings) interfaces;
assertions =
(flip map interfaces (i: {
(forEach interfaces (i: {
# With the linux kernel, interface name length is limited by IFNAMSIZ
# to 16 bytes, including the trailing null byte.
# See include/linux/if.h in the kernel sources
@ -934,12 +934,12 @@ in
message = ''
The name of networking.interfaces."${i.name}" is too long, it needs to be less than 16 characters.
'';
})) ++ (flip map slaveIfs (i: {
})) ++ (forEach slaveIfs (i: {
assertion = i.ipv4.addresses == [ ] && i.ipv6.addresses == [ ];
message = ''
The networking.interfaces."${i.name}" must not have any defined ips when it is a slave.
'';
})) ++ (flip map interfaces (i: {
})) ++ (forEach interfaces (i: {
assertion = i.preferTempAddress -> cfg.enableIPv6;
message = ''
Temporary addresses are only needed when IPv6 is enabled.
@ -967,8 +967,8 @@ in
"net.ipv6.conf.default.disable_ipv6" = mkDefault (!cfg.enableIPv6);
"net.ipv6.conf.all.forwarding" = mkDefault (any (i: i.proxyARP) interfaces);
} // listToAttrs (flip concatMap (filter (i: i.proxyARP) interfaces)
(i: flip map [ "4" "6" ] (v: nameValuePair "net.ipv${v}.conf.${i.name}.proxy_arp" true)))
// listToAttrs (flip map (filter (i: i.preferTempAddress) interfaces)
(i: forEach [ "4" "6" ] (v: nameValuePair "net.ipv${v}.conf.${i.name}.proxy_arp" true)))
// listToAttrs (forEach (filter (i: i.preferTempAddress) interfaces)
(i: nameValuePair "net.ipv6.conf.${i.name}.use_tempaddr" 2));
# Capabilities won't work unless we have at-least a 4.3 Linux
@ -1050,7 +1050,7 @@ in
${cfg.localCommands}
'';
};
} // (listToAttrs (flip map interfaces (i:
} // (listToAttrs (forEach interfaces (i:
let
deviceDependency = if (config.boot.isContainer || i.name == "lo")
then []

View file

@ -138,7 +138,7 @@ let
--bind-ro=/nix/var/nix/daemon-socket \
--bind="/nix/var/nix/profiles/per-container/$INSTANCE:/nix/var/nix/profiles" \
--bind="/nix/var/nix/gcroots/per-container/$INSTANCE:/nix/var/nix/gcroots" \
--link-journal=try-guest \
${optionalString (!cfg.ephemeral) "--link-journal=try-guest"} \
--setenv PRIVATE_NETWORK="$PRIVATE_NETWORK" \
--setenv HOST_BRIDGE="$HOST_BRIDGE" \
--setenv HOST_ADDRESS="$HOST_ADDRESS" \
@ -147,6 +147,7 @@ let
--setenv LOCAL_ADDRESS6="$LOCAL_ADDRESS6" \
--setenv HOST_PORT="$HOST_PORT" \
--setenv PATH="$PATH" \
${optionalString cfg.ephemeral "--ephemeral"} \
${if cfg.additionalCapabilities != null && cfg.additionalCapabilities != [] then
''--capability="${concatStringsSep " " cfg.additionalCapabilities}"'' else ""
} \
@ -247,6 +248,8 @@ let
Type = "notify";
RuntimeDirectory = lib.optional cfg.ephemeral "containers/%i";
# Note that on reboot, systemd-nspawn returns 133, so this
# unit will be restarted. On poweroff, it returns 0, so the
# unit won't be restarted.
@ -419,6 +422,7 @@ let
{
extraVeths = {};
additionalCapabilities = [];
ephemeral = false;
allowedDevices = [];
hostAddress = null;
hostAddress6 = null;
@ -511,6 +515,26 @@ in
information.
'';
};
ephemeral = mkOption {
type = types.bool;
default = false;
description = ''
Runs container in ephemeral mode with the empty root filesystem at boot.
This way container will be bootstrapped from scratch on each boot
and will be cleaned up on shutdown leaving no traces behind.
Useful for completely stateless, reproducible containers.
Note that this option might require to do some adjustments to the container configuration,
e.g. you might want to set
<varname>systemd.network.networks.$interface.dhcpConfig.ClientIdentifier</varname> to "mac"
if you use <varname>macvlans</varname> option.
This way dhcp client identifier will be stable between the container restarts.
Note that the container journal will not be linked to the host if this option is enabled.
'';
};
enableTun = mkOption {
type = types.bool;
default = false;
@ -659,12 +683,14 @@ in
unit = {
description = "Container '%i'";
unitConfig.RequiresMountsFor = [ "/var/lib/containers/%i" ];
unitConfig.RequiresMountsFor = "/var/lib/containers/%i";
path = [ pkgs.iproute ];
environment.INSTANCE = "%i";
environment.root = "/var/lib/containers/%i";
environment = {
root = "/var/lib/containers/%i";
INSTANCE = "%i";
};
preStart = preStartScript dummyConfig;
@ -703,11 +729,13 @@ in
}
else {});
in
unit // {
recursiveUpdate unit {
preStart = preStartScript containerConfig;
script = startScript containerConfig;
postStart = postStartScript containerConfig;
serviceConfig = serviceDirectives containerConfig;
unitConfig.RequiresMountsFor = lib.optional (!containerConfig.ephemeral) "/var/lib/containers/%i";
environment.root = if containerConfig.ephemeral then "/run/containers/%i" else "/var/lib/containers/%i";
} // (
if containerConfig.autoStart then
{

View file

@ -159,12 +159,6 @@ in
# functionality/features (e.g. TCP Window scaling).
"net.ipv4.tcp_syncookies" = mkDefault "1";
# ignores source-routed packets
"net.ipv4.conf.all.accept_source_route" = mkDefault "0";
# ignores source-routed packets
"net.ipv4.conf.default.accept_source_route" = mkDefault "0";
# ignores ICMP redirects
"net.ipv4.conf.all.accept_redirects" = mkDefault "0";
@ -186,10 +180,10 @@ in
# don't allow traffic between networks or act as a router
"net.ipv4.conf.default.send_redirects" = mkDefault "0";
# reverse path filtering - IP spoofing protection
# strict reverse path filtering - IP spoofing protection
"net.ipv4.conf.all.rp_filter" = mkDefault "1";
# reverse path filtering - IP spoofing protection
# strict path filtering - IP spoofing protection
"net.ipv4.conf.default.rp_filter" = mkDefault "1";
# ignores ICMP broadcasts to avoid participating in Smurf attacks

View file

@ -104,6 +104,18 @@ in {
'';
};
onBoot = mkOption {
type = types.enum ["start" "ignore" ];
default = "start";
description = ''
Specifies the action to be done to / on the guests when the host boots.
The "start" option starts all guests that were running prior to shutdown
regardless of their autostart settings. The "ignore" option will not
start the formally running guest on boot. However, any guest marked as
autostart will still be automatically started by libvirtd.
'';
};
onShutdown = mkOption {
type = types.enum ["shutdown" "suspend" ];
default = "suspend";
@ -221,6 +233,7 @@ in {
path = with pkgs; [ coreutils libvirt gawk ];
restartIfChanged = false;
environment.ON_BOOT = "${cfg.onBoot}";
environment.ON_SHUTDOWN = "${cfg.onShutdown}";
};

View file

@ -47,6 +47,7 @@ in
codimd = handleTest ./codimd.nix {};
colord = handleTest ./colord.nix {};
containers-bridge = handleTest ./containers-bridge.nix {};
containers-ephemeral = handleTest ./containers-ephemeral.nix {};
containers-extra_veth = handleTest ./containers-extra_veth.nix {};
containers-hosts = handleTest ./containers-hosts.nix {};
containers-imperative = handleTest ./containers-imperative.nix {};
@ -73,7 +74,7 @@ in
#ec2-config = (handleTestOn ["x86_64-linux"] ./ec2.nix {}).boot-ec2-config or {};
ec2-nixops = (handleTestOn ["x86_64-linux"] ./ec2.nix {}).boot-ec2-nixops or {};
ecryptfs = handleTest ./ecryptfs.nix {};
ejabberd = handleTest ./ejabberd.nix {};
ejabberd = handleTest ./xmpp/ejabberd.nix {};
elk = handleTestOn ["x86_64-linux"] ./elk.nix {};
env = handleTest ./env.nix {};
etcd = handleTestOn ["x86_64-linux"] ./etcd.nix {};
@ -93,8 +94,10 @@ in
gitlab = handleTest ./gitlab.nix {};
gitolite = handleTest ./gitolite.nix {};
gjs = handleTest ./gjs.nix {};
glusterfs = handleTest ./glusterfs.nix {};
gnome3-xorg = handleTest ./gnome3-xorg.nix {};
gnome3 = handleTest ./gnome3.nix {};
gnome-photos = handleTest ./gnome-photos.nix {};
gocd-agent = handleTest ./gocd-agent.nix {};
gocd-server = handleTest ./gocd-server.nix {};
google-oslogin = handleTest ./google-oslogin {};
@ -114,6 +117,7 @@ in
hound = handleTest ./hound.nix {};
hydra = handleTest ./hydra {};
i3wm = handleTest ./i3wm.nix {};
icingaweb2 = handleTest ./icingaweb2.nix {};
iftop = handleTest ./iftop.nix {};
incron = handleTest ./incron.nix {};
influxdb = handleTest ./influxdb.nix {};
@ -124,6 +128,7 @@ in
jackett = handleTest ./jackett.nix {};
jellyfin = handleTest ./jellyfin.nix {};
jenkins = handleTest ./jenkins.nix {};
jormungandr = handleTest ./jormungandr.nix {};
kafka = handleTest ./kafka.nix {};
kerberos = handleTest ./kerberos/default.nix {};
kernel-latest = handleTest ./kernel-latest.nix {};
@ -138,6 +143,7 @@ in
latestKernel.login = handleTest ./login.nix { latestKernel = true; };
ldap = handleTest ./ldap.nix {};
leaps = handleTest ./leaps.nix {};
libxmlb = handleTest ./libxmlb.nix {};
lidarr = handleTest ./lidarr.nix {};
lightdm = handleTest ./lightdm.nix {};
limesurvey = handleTest ./limesurvey.nix {};
@ -150,10 +156,12 @@ in
mediawiki = handleTest ./mediawiki.nix {};
memcached = handleTest ./memcached.nix {};
mesos = handleTest ./mesos.nix {};
metabase = handleTest ./metabase.nix {};
miniflux = handleTest ./miniflux.nix {};
minio = handleTest ./minio.nix {};
misc = handleTest ./misc.nix {};
mongodb = handleTest ./mongodb.nix {};
moodle = handleTest ./moodle.nix {};
morty = handleTest ./morty.nix {};
mosquitto = handleTest ./mosquitto.nix {};
mpd = handleTest ./mpd.nix {};
@ -217,7 +225,8 @@ in
prometheus = handleTest ./prometheus.nix {};
prometheus2 = handleTest ./prometheus-2.nix {};
prometheus-exporters = handleTest ./prometheus-exporters.nix {};
prosody = handleTest ./prosody.nix {};
prosody = handleTest ./xmpp/prosody.nix {};
prosodyMysql = handleTest ./xmpp/prosody-mysql.nix {};
proxy = handleTest ./proxy.nix {};
quagga = handleTest ./quagga.nix {};
quake3 = handleTest ./quake3.nix {};
@ -249,6 +258,7 @@ in
systemd = handleTest ./systemd.nix {};
systemd-confinement = handleTest ./systemd-confinement.nix {};
systemd-timesyncd = handleTest ./systemd-timesyncd.nix {};
systemd-networkd-wireguard = handleTest ./systemd-networkd-wireguard.nix {};
pdns-recursor = handleTest ./pdns-recursor.nix {};
taskserver = handleTest ./taskserver.nix {};
telegraf = handleTest ./telegraf.nix {};
@ -256,6 +266,7 @@ in
tinydns = handleTest ./tinydns.nix {};
tor = handleTest ./tor.nix {};
transmission = handleTest ./transmission.nix {};
trezord = handleTest ./trezord.nix {};
udisks2 = handleTest ./udisks2.nix {};
upnp = handleTest ./upnp.nix {};
uwsgi = handleTest ./uwsgi.nix {};

Some files were not shown because too many files have changed in this diff Show more