aboutsummaryrefslogtreecommitdiff
path: root/nixpkgs/nixos/modules
diff options
context:
space:
mode:
authorKaiden Fey <kookie@spacekookie.de>2020-09-19 15:00:33 +0200
committerKatharina Fey <kookie@spacekookie.de>2020-09-19 15:00:33 +0200
commite0800985dab8f8ebb4cebdfd7e361fd1fafdb2a7 (patch)
tree289f43c72dd1fffeec4eb18ced05ae91e50c179a /nixpkgs/nixos/modules
parent5581b5521e14317c3507a6e8451a3f14996e5c4d (diff)
parent441a7da8080352881bb52f85e910d8855e83fc55 (diff)
Merge commit '441a7da8080352881bb52f85e910d8855e83fc55'
Diffstat (limited to 'nixpkgs/nixos/modules')
-rw-r--r--nixpkgs/nixos/modules/config/appstream.nix8
-rw-r--r--nixpkgs/nixos/modules/config/fonts/fontconfig-penultimate.nix292
-rw-r--r--nixpkgs/nixos/modules/config/fonts/fontconfig.nix97
-rw-r--r--nixpkgs/nixos/modules/config/krb5/default.nix34
-rw-r--r--nixpkgs/nixos/modules/config/no-x-libs.nix2
-rw-r--r--nixpkgs/nixos/modules/config/system-path.nix28
-rw-r--r--nixpkgs/nixos/modules/config/users-groups.nix4
-rw-r--r--nixpkgs/nixos/modules/hardware/bladeRF.nix2
-rw-r--r--nixpkgs/nixos/modules/hardware/ckb-next.nix1
-rw-r--r--nixpkgs/nixos/modules/hardware/device-tree.nix164
-rw-r--r--nixpkgs/nixos/modules/hardware/onlykey.nix2
-rw-r--r--nixpkgs/nixos/modules/hardware/tuxedo-keyboard.nix4
-rw-r--r--nixpkgs/nixos/modules/i18n/input-method/uim.nix2
-rw-r--r--nixpkgs/nixos/modules/installer/cd-dvd/iso-image.nix9
-rw-r--r--nixpkgs/nixos/modules/installer/cd-dvd/sd-image-raspberrypi4.nix2
-rw-r--r--nixpkgs/nixos/modules/installer/cd-dvd/sd-image.nix12
-rw-r--r--nixpkgs/nixos/modules/installer/cd-dvd/system-tarball-pc-readme.txt2
-rw-r--r--nixpkgs/nixos/modules/installer/tools/nixos-build-vms/nixos-build-vms.sh2
-rw-r--r--nixpkgs/nixos/modules/installer/tools/nixos-enter.sh2
-rw-r--r--nixpkgs/nixos/modules/installer/tools/nixos-install.sh75
-rw-r--r--nixpkgs/nixos/modules/installer/tools/nixos-option/nixos-option.cc2
-rw-r--r--nixpkgs/nixos/modules/installer/tools/nixos-rebuild.sh19
-rw-r--r--nixpkgs/nixos/modules/installer/tools/nixos-version.sh2
-rw-r--r--nixpkgs/nixos/modules/installer/tools/tools.nix11
-rw-r--r--nixpkgs/nixos/modules/misc/ids.nix8
-rw-r--r--nixpkgs/nixos/modules/misc/locate.nix2
-rw-r--r--nixpkgs/nixos/modules/misc/nixpkgs.nix2
-rw-r--r--nixpkgs/nixos/modules/module-list.nix20
-rw-r--r--nixpkgs/nixos/modules/profiles/base.nix1
-rw-r--r--nixpkgs/nixos/modules/profiles/hardened.nix5
-rw-r--r--nixpkgs/nixos/modules/profiles/installation-device.nix15
-rw-r--r--nixpkgs/nixos/modules/programs/autojump.nix4
-rw-r--r--nixpkgs/nixos/modules/programs/ccache.nix2
-rw-r--r--nixpkgs/nixos/modules/programs/environment.nix1
-rw-r--r--nixpkgs/nixos/modules/programs/freetds.nix4
-rw-r--r--nixpkgs/nixos/modules/programs/gpaste.nix2
-rw-r--r--nixpkgs/nixos/modules/programs/nm-applet.nix15
-rw-r--r--nixpkgs/nixos/modules/programs/qt5ct.nix2
-rw-r--r--nixpkgs/nixos/modules/programs/ssh.nix2
-rw-r--r--nixpkgs/nixos/modules/programs/tsm-client.nix4
-rw-r--r--nixpkgs/nixos/modules/programs/xss-lock.nix2
-rw-r--r--nixpkgs/nixos/modules/programs/zsh/oh-my-zsh.xml2
-rw-r--r--nixpkgs/nixos/modules/rename.nix7
-rw-r--r--nixpkgs/nixos/modules/security/acme.nix664
-rw-r--r--nixpkgs/nixos/modules/security/acme.xml20
-rw-r--r--nixpkgs/nixos/modules/security/apparmor.nix6
-rw-r--r--nixpkgs/nixos/modules/security/duosec.nix2
-rw-r--r--nixpkgs/nixos/modules/security/misc.nix14
-rw-r--r--nixpkgs/nixos/modules/security/pam.nix6
-rw-r--r--nixpkgs/nixos/modules/security/rngd.nix13
-rw-r--r--nixpkgs/nixos/modules/security/systemd-confinement.nix2
-rw-r--r--nixpkgs/nixos/modules/security/tpm2.nix1
-rw-r--r--nixpkgs/nixos/modules/security/wrappers/default.nix3
-rw-r--r--nixpkgs/nixos/modules/services/audio/icecast.nix6
-rw-r--r--nixpkgs/nixos/modules/services/audio/mpd.nix31
-rw-r--r--nixpkgs/nixos/modules/services/backup/bacula.nix36
-rw-r--r--nixpkgs/nixos/modules/services/backup/borgbackup.xml22
-rw-r--r--nixpkgs/nixos/modules/services/backup/restic.nix2
-rw-r--r--nixpkgs/nixos/modules/services/backup/znapzend.nix4
-rw-r--r--nixpkgs/nixos/modules/services/cluster/kubernetes/pki.nix5
-rw-r--r--nixpkgs/nixos/modules/services/computing/torque/mom.nix2
-rw-r--r--nixpkgs/nixos/modules/services/computing/torque/server.nix2
-rw-r--r--nixpkgs/nixos/modules/services/continuous-integration/hercules-ci-agent/common.nix213
-rw-r--r--nixpkgs/nixos/modules/services/continuous-integration/hercules-ci-agent/default.nix86
-rw-r--r--nixpkgs/nixos/modules/services/databases/couchdb.nix25
-rw-r--r--nixpkgs/nixos/modules/services/databases/mysql.nix260
-rw-r--r--nixpkgs/nixos/modules/services/databases/postgresql.nix143
-rw-r--r--nixpkgs/nixos/modules/services/databases/riak-cs.nix2
-rw-r--r--nixpkgs/nixos/modules/services/databases/victoriametrics.nix4
-rw-r--r--nixpkgs/nixos/modules/services/desktops/deepin/deepin.nix123
-rw-r--r--nixpkgs/nixos/modules/services/desktops/espanso.nix25
-rw-r--r--nixpkgs/nixos/modules/services/desktops/geoclue2.nix2
-rw-r--r--nixpkgs/nixos/modules/services/development/jupyterhub/default.nix190
-rw-r--r--nixpkgs/nixos/modules/services/development/lorri.nix13
-rw-r--r--nixpkgs/nixos/modules/services/editors/emacs.nix47
-rw-r--r--nixpkgs/nixos/modules/services/editors/emacs.xml14
-rw-r--r--nixpkgs/nixos/modules/services/games/minetest-server.nix16
-rw-r--r--nixpkgs/nixos/modules/services/games/terraria.nix20
-rw-r--r--nixpkgs/nixos/modules/services/hardware/fancontrol.nix2
-rw-r--r--nixpkgs/nixos/modules/services/hardware/sane_extra_backends/brscan4.nix2
-rw-r--r--nixpkgs/nixos/modules/services/hardware/thinkfan.nix2
-rw-r--r--nixpkgs/nixos/modules/services/hardware/trezord.nix4
-rw-r--r--nixpkgs/nixos/modules/services/hardware/undervolt.nix18
-rw-r--r--nixpkgs/nixos/modules/services/logging/logrotate.nix146
-rw-r--r--nixpkgs/nixos/modules/services/logging/logstash.nix6
-rw-r--r--nixpkgs/nixos/modules/services/mail/dovecot.nix33
-rw-r--r--nixpkgs/nixos/modules/services/mail/mailhog.nix68
-rw-r--r--nixpkgs/nixos/modules/services/mail/opendkim.nix30
-rw-r--r--nixpkgs/nixos/modules/services/mail/pfix-srsd.nix2
-rw-r--r--nixpkgs/nixos/modules/services/mail/postfix.nix14
-rw-r--r--nixpkgs/nixos/modules/services/misc/beanstalkd.nix10
-rw-r--r--nixpkgs/nixos/modules/services/misc/gammu-smsd.nix2
-rw-r--r--nixpkgs/nixos/modules/services/misc/gitea.nix144
-rw-r--r--nixpkgs/nixos/modules/services/misc/gitlab.nix75
-rw-r--r--nixpkgs/nixos/modules/services/misc/gitlab.xml6
-rw-r--r--nixpkgs/nixos/modules/services/misc/gollum.nix9
-rw-r--r--nixpkgs/nixos/modules/services/misc/jellyfin.nix15
-rw-r--r--nixpkgs/nixos/modules/services/misc/mathics.nix54
-rw-r--r--nixpkgs/nixos/modules/services/misc/matrix-synapse.nix2
-rw-r--r--nixpkgs/nixos/modules/services/misc/mesos-master.nix125
-rw-r--r--nixpkgs/nixos/modules/services/misc/mesos-slave.nix220
-rw-r--r--nixpkgs/nixos/modules/services/misc/nix-daemon.nix21
-rw-r--r--nixpkgs/nixos/modules/services/misc/octoprint.nix4
-rw-r--r--nixpkgs/nixos/modules/services/misc/pinnwand.nix78
-rw-r--r--nixpkgs/nixos/modules/services/misc/redmine.nix102
-rw-r--r--nixpkgs/nixos/modules/services/misc/siproxd.nix8
-rw-r--r--nixpkgs/nixos/modules/services/misc/ssm-agent.nix6
-rw-r--r--nixpkgs/nixos/modules/services/misc/sssd.nix4
-rw-r--r--nixpkgs/nixos/modules/services/misc/tzupdate.nix4
-rw-r--r--nixpkgs/nixos/modules/services/monitoring/cadvisor.nix2
-rw-r--r--nixpkgs/nixos/modules/services/monitoring/datadog-agent.nix14
-rw-r--r--nixpkgs/nixos/modules/services/monitoring/dd-agent/dd-agent.nix4
-rw-r--r--nixpkgs/nixos/modules/services/monitoring/monit.nix18
-rw-r--r--nixpkgs/nixos/modules/services/monitoring/netdata.nix45
-rw-r--r--nixpkgs/nixos/modules/services/monitoring/prometheus/default.nix27
-rw-r--r--nixpkgs/nixos/modules/services/monitoring/prometheus/exporters.nix4
-rw-r--r--nixpkgs/nixos/modules/services/monitoring/prometheus/exporters/unifi-poller.nix34
-rw-r--r--nixpkgs/nixos/modules/services/monitoring/smartd.nix18
-rw-r--r--nixpkgs/nixos/modules/services/monitoring/teamviewer.nix2
-rw-r--r--nixpkgs/nixos/modules/services/monitoring/unifi-poller.nix242
-rw-r--r--nixpkgs/nixos/modules/services/monitoring/zabbix-proxy.nix17
-rw-r--r--nixpkgs/nixos/modules/services/monitoring/zabbix-server.nix17
-rw-r--r--nixpkgs/nixos/modules/services/network-filesystems/cachefilesd.nix18
-rw-r--r--nixpkgs/nixos/modules/services/network-filesystems/ipfs.nix22
-rw-r--r--nixpkgs/nixos/modules/services/network-filesystems/orangefs/server.nix4
-rw-r--r--nixpkgs/nixos/modules/services/network-filesystems/samba.nix2
-rw-r--r--nixpkgs/nixos/modules/services/networking/biboumi.nix269
-rw-r--r--nixpkgs/nixos/modules/services/networking/bitcoind.nix6
-rw-r--r--nixpkgs/nixos/modules/services/networking/blockbook-frontend.nix3
-rw-r--r--nixpkgs/nixos/modules/services/networking/corerad.nix1
-rw-r--r--nixpkgs/nixos/modules/services/networking/gateone.nix2
-rw-r--r--nixpkgs/nixos/modules/services/networking/hylafax/options.nix4
-rw-r--r--nixpkgs/nixos/modules/services/networking/kresd.nix12
-rw-r--r--nixpkgs/nixos/modules/services/networking/monero.nix2
-rw-r--r--nixpkgs/nixos/modules/services/networking/mstpd.nix2
-rw-r--r--nixpkgs/nixos/modules/services/networking/namecoind.nix2
-rw-r--r--nixpkgs/nixos/modules/services/networking/networkmanager.nix2
-rw-r--r--nixpkgs/nixos/modules/services/networking/nextdns.nix44
-rw-r--r--nixpkgs/nixos/modules/services/networking/nghttpx/default.nix6
-rw-r--r--nixpkgs/nixos/modules/services/networking/ntp/chrony.nix1
-rw-r--r--nixpkgs/nixos/modules/services/networking/nylon.nix2
-rw-r--r--nixpkgs/nixos/modules/services/networking/onedrive.nix2
-rw-r--r--nixpkgs/nixos/modules/services/networking/openvpn.nix2
-rw-r--r--nixpkgs/nixos/modules/services/networking/prosody.nix4
-rw-r--r--nixpkgs/nixos/modules/services/networking/prosody.xml13
-rw-r--r--nixpkgs/nixos/modules/services/networking/robustirc-bridge.nix47
-rw-r--r--nixpkgs/nixos/modules/services/networking/shadowsocks.nix54
-rw-r--r--nixpkgs/nixos/modules/services/networking/ssh/sshd.nix12
-rw-r--r--nixpkgs/nixos/modules/services/networking/supplicant.nix26
-rw-r--r--nixpkgs/nixos/modules/services/networking/syncthing.nix13
-rw-r--r--nixpkgs/nixos/modules/services/networking/trickster.nix5
-rw-r--r--nixpkgs/nixos/modules/services/networking/websockify.nix6
-rw-r--r--nixpkgs/nixos/modules/services/networking/wpa_supplicant.nix3
-rw-r--r--nixpkgs/nixos/modules/services/networking/xandikos.nix2
-rw-r--r--nixpkgs/nixos/modules/services/scheduling/chronos.nix54
-rw-r--r--nixpkgs/nixos/modules/services/scheduling/marathon.nix98
-rw-r--r--nixpkgs/nixos/modules/services/security/bitwarden_rs/default.nix19
-rw-r--r--nixpkgs/nixos/modules/services/security/haveged.nix18
-rw-r--r--nixpkgs/nixos/modules/services/security/physlock.nix10
-rw-r--r--nixpkgs/nixos/modules/services/security/privacyidea.nix1
-rw-r--r--nixpkgs/nixos/modules/services/security/tor.nix22
-rw-r--r--nixpkgs/nixos/modules/services/security/usbguard.nix124
-rw-r--r--nixpkgs/nixos/modules/services/system/earlyoom.nix1
-rw-r--r--nixpkgs/nixos/modules/services/torrent/transmission.nix451
-rw-r--r--nixpkgs/nixos/modules/services/video/epgstation/default.nix295
-rwxr-xr-xnixpkgs/nixos/modules/services/video/epgstation/generate31
-rw-r--r--nixpkgs/nixos/modules/services/video/epgstation/streaming.json119
-rw-r--r--nixpkgs/nixos/modules/services/video/mirakurun.nix183
-rw-r--r--nixpkgs/nixos/modules/services/wayland/cage.nix3
-rw-r--r--nixpkgs/nixos/modules/services/web-apps/dokuwiki.nix24
-rw-r--r--nixpkgs/nixos/modules/services/web-apps/jitsi-meet.nix1
-rw-r--r--nixpkgs/nixos/modules/services/web-apps/jitsi-meet.xml55
-rw-r--r--nixpkgs/nixos/modules/services/web-apps/nextcloud.nix248
-rw-r--r--nixpkgs/nixos/modules/services/web-apps/nextcloud.xml61
-rw-r--r--nixpkgs/nixos/modules/services/web-apps/pgpkeyserver-lite.nix2
-rw-r--r--nixpkgs/nixos/modules/services/web-apps/rss-bridge.nix127
-rw-r--r--nixpkgs/nixos/modules/services/web-apps/sogo.nix1
-rw-r--r--nixpkgs/nixos/modules/services/web-apps/trilium.nix2
-rw-r--r--nixpkgs/nixos/modules/services/web-apps/tt-rss.nix2
-rw-r--r--nixpkgs/nixos/modules/services/web-servers/apache-httpd/default.nix110
-rw-r--r--nixpkgs/nixos/modules/services/web-servers/caddy.nix66
-rw-r--r--nixpkgs/nixos/modules/services/web-servers/jboss/builder.sh12
-rw-r--r--nixpkgs/nixos/modules/services/web-servers/meguca.nix174
-rw-r--r--nixpkgs/nixos/modules/services/web-servers/nginx/default.nix103
-rw-r--r--nixpkgs/nixos/modules/services/web-servers/phpfpm/default.nix1
-rw-r--r--nixpkgs/nixos/modules/services/web-servers/shellinabox.nix2
-rw-r--r--nixpkgs/nixos/modules/services/web-servers/unit/default.nix3
-rw-r--r--nixpkgs/nixos/modules/services/x11/desktop-managers/cinnamon.nix205
-rw-r--r--nixpkgs/nixos/modules/services/x11/desktop-managers/default.nix1
-rw-r--r--nixpkgs/nixos/modules/services/x11/desktop-managers/pantheon.nix2
-rw-r--r--nixpkgs/nixos/modules/services/x11/desktop-managers/plasma5.nix18
-rw-r--r--nixpkgs/nixos/modules/services/x11/display-managers/default.nix33
-rw-r--r--nixpkgs/nixos/modules/services/x11/display-managers/gdm.nix9
-rw-r--r--nixpkgs/nixos/modules/services/x11/display-managers/lightdm.nix1
-rw-r--r--nixpkgs/nixos/modules/services/x11/imwheel.nix3
-rw-r--r--nixpkgs/nixos/modules/services/x11/urserver.nix38
-rw-r--r--nixpkgs/nixos/modules/services/x11/window-managers/qtile.nix2
-rw-r--r--nixpkgs/nixos/modules/services/x11/window-managers/xmonad.nix30
-rw-r--r--nixpkgs/nixos/modules/system/boot/emergency-mode.nix2
-rw-r--r--nixpkgs/nixos/modules/system/boot/initrd-openvpn.nix18
-rw-r--r--nixpkgs/nixos/modules/system/boot/loader/generations-dir/generations-dir-builder.sh2
-rw-r--r--nixpkgs/nixos/modules/system/boot/loader/init-script/init-script-builder.sh2
-rw-r--r--nixpkgs/nixos/modules/system/boot/loader/raspberrypi/raspberrypi-builder.nix4
-rw-r--r--nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py4
-rw-r--r--nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix4
-rw-r--r--nixpkgs/nixos/modules/system/boot/luksroot.nix4
-rw-r--r--nixpkgs/nixos/modules/system/boot/networkd.nix1490
-rw-r--r--nixpkgs/nixos/modules/system/boot/stage-1-init.sh6
-rw-r--r--nixpkgs/nixos/modules/system/boot/stage-1.nix14
-rw-r--r--nixpkgs/nixos/modules/system/boot/systemd-nspawn.nix6
-rw-r--r--nixpkgs/nixos/modules/system/boot/systemd-unit-options.nix11
-rw-r--r--nixpkgs/nixos/modules/system/boot/systemd.nix27
-rw-r--r--nixpkgs/nixos/modules/system/boot/tmp.nix2
-rw-r--r--nixpkgs/nixos/modules/system/etc/etc.nix2
-rw-r--r--nixpkgs/nixos/modules/system/etc/make-etc.sh7
-rw-r--r--nixpkgs/nixos/modules/tasks/auto-upgrade.nix98
-rw-r--r--nixpkgs/nixos/modules/tasks/bcache.nix2
-rw-r--r--nixpkgs/nixos/modules/tasks/encrypted-devices.nix2
-rw-r--r--nixpkgs/nixos/modules/tasks/filesystems.nix4
-rw-r--r--nixpkgs/nixos/modules/tasks/filesystems/zfs.nix32
-rw-r--r--nixpkgs/nixos/modules/tasks/network-interfaces-scripted.nix4
-rw-r--r--nixpkgs/nixos/modules/tasks/network-interfaces.nix8
-rw-r--r--nixpkgs/nixos/modules/testing/test-instrumentation.nix27
-rw-r--r--nixpkgs/nixos/modules/virtualisation/azure-image.nix2
-rw-r--r--nixpkgs/nixos/modules/virtualisation/containers.nix12
-rw-r--r--nixpkgs/nixos/modules/virtualisation/cri-o.nix5
-rw-r--r--nixpkgs/nixos/modules/virtualisation/docker-preloader.nix134
-rw-r--r--nixpkgs/nixos/modules/virtualisation/nixos-containers.nix2
-rw-r--r--nixpkgs/nixos/modules/virtualisation/parallels-guest.nix2
-rw-r--r--nixpkgs/nixos/modules/virtualisation/qemu-vm.nix1
-rw-r--r--nixpkgs/nixos/modules/virtualisation/railcar.nix16
231 files changed, 6380 insertions, 3496 deletions
diff --git a/nixpkgs/nixos/modules/config/appstream.nix b/nixpkgs/nixos/modules/config/appstream.nix
index 483ac9c3cd7..a72215c2f56 100644
--- a/nixpkgs/nixos/modules/config/appstream.nix
+++ b/nixpkgs/nixos/modules/config/appstream.nix
@@ -7,18 +7,18 @@ with lib;
type = types.bool;
default = true;
description = ''
- Whether to install files to support the
+ Whether to install files to support the
<link xlink:href="https://www.freedesktop.org/software/appstream/docs/index.html">AppStream metadata specification</link>.
'';
};
};
config = mkIf config.appstream.enable {
- environment.pathsToLink = [
+ environment.pathsToLink = [
# per component metadata
- "/share/metainfo"
+ "/share/metainfo"
# legacy path for above
- "/share/appdata"
+ "/share/appdata"
];
};
diff --git a/nixpkgs/nixos/modules/config/fonts/fontconfig-penultimate.nix b/nixpkgs/nixos/modules/config/fonts/fontconfig-penultimate.nix
deleted file mode 100644
index 7e311a21acf..00000000000
--- a/nixpkgs/nixos/modules/config/fonts/fontconfig-penultimate.nix
+++ /dev/null
@@ -1,292 +0,0 @@
-{ config, pkgs, lib, ... }:
-
-with lib;
-
-let
- cfg = config.fonts.fontconfig;
-
- 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}";
-
- # 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; };
-
- # 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>
- '';
-
- # local configuration file
- localConf = pkgs.writeText "fc-local.conf" cfg.localConf;
-
- # rendering settings configuration files
- # priority 10
- hintingConf = pkgs.writeText "fc-10-hinting.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>
- </match>
-
- </fontconfig>
- '';
-
- antialiasConf = pkgs.writeText "fc-10-antialias.conf" ''
- <?xml version='1.0'?>
- <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
- <fontconfig>
-
- <!-- Default rendering settings -->
- <match target="pattern">
- <edit mode="append" name="antialias">
- ${fcBool cfg.antialias}
- </edit>
- </match>
-
- </fontconfig>
- '';
-
- subpixelConf = pkgs.writeText "fc-10-subpixel.conf" ''
- <?xml version='1.0'?>
- <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
- <fontconfig>
-
- <!-- Default rendering settings -->
- <match target="pattern">
- <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>
- '';
-
- dpiConf = pkgs.writeText "fc-11-dpi.conf" ''
- <?xml version='1.0'?>
- <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
- <fontconfig>
-
- <match target="pattern">
- <edit name="dpi" mode="assign">
- <double>${toString cfg.dpi}</double>
- </edit>
- </match>
-
- </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>
- '';
-
- # 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>
- '';
-
- # 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
-{
-
- options = {
-
- fonts = {
-
- fontconfig = {
-
- penultimate = {
- enable = mkOption {
- type = types.bool;
- default = false;
- description = ''
- Enable fontconfig-penultimate settings to supplement the
- NixOS defaults by providing per-font rendering defaults and
- metric aliases.
- '';
- };
- };
-
- };
- };
-
- };
-
- config = mkIf (config.fonts.fontconfig.enable && config.fonts.fontconfig.penultimate.enable) {
-
- fonts.fontconfig.confPackages = [ penultimateConf ];
-
- };
-
-}
diff --git a/nixpkgs/nixos/modules/config/fonts/fontconfig.nix b/nixpkgs/nixos/modules/config/fonts/fontconfig.nix
index 52d284f739b..5b681ca5946 100644
--- a/nixpkgs/nixos/modules/config/fonts/fontconfig.nix
+++ b/nixpkgs/nixos/modules/config/fonts/fontconfig.nix
@@ -1,11 +1,6 @@
/*
-NixOS support 2 fontconfig versions, "support" and "latest".
-
-- "latest" refers to default fontconfig package (pkgs.fontconfig).
- configuration files are linked to /etc/fonts/VERSION/conf.d/
-- "support" refers to supportPkg (pkgs."fontconfig_${supportVersion}").
- configuration files are linked to /etc/fonts/conf.d/
+Configuration files are linked to /etc/fonts/conf.d/
This module generates a package containing configuration files and link it in /etc/fonts.
@@ -22,44 +17,25 @@ let
cfg = config.fonts.fontconfig;
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}";
-
- # 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; };
+ pkg = pkgs.fontconfig;
# configuration file to read fontconfig cache
- # version dependent
# priority 0
- cacheConfSupport = makeCacheConf { version = supportVersion; };
- cacheConfLatest = makeCacheConf {};
+ cacheConf = makeCacheConf {};
- # generate the font cache setting file for a fontconfig version
- # use latest when no version is passed
+ # generate the font cache setting file
# When cross-compiling, we can’t generate the cache, so we skip the
# <cachedir> part. fontconfig still works but is a little slower in
# looking things up.
- makeCacheConf = { version ? null }:
+ makeCacheConf = { }:
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};
+ cache = makeCache pkgs.fontconfig;
+ cache32 = makeCache pkgs.pkgsi686Linux.fontconfig;
in
pkgs.writeText "fc-00-nixos-cache.conf" ''
<?xml version='1.0'?>
- <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
+ <!DOCTYPE fontconfig SYSTEM 'urn:fontconfig:fonts.dtd'>
<fontconfig>
<!-- Font directories -->
${concatStringsSep "\n" (map (font: "<dir>${font}</dir>") config.fonts.fonts)}
@@ -77,7 +53,7 @@ let
# priority 10
renderConf = pkgs.writeText "fc-10-nixos-rendering.conf" ''
<?xml version='1.0'?>
- <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
+ <!DOCTYPE fontconfig SYSTEM 'urn:fontconfig:fonts.dtd'>
<fontconfig>
<!-- Default rendering settings -->
@@ -134,7 +110,7 @@ let
in
pkgs.writeText "fc-52-nixos-default-fonts.conf" ''
<?xml version='1.0'?>
- <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
+ <!DOCTYPE fontconfig SYSTEM 'urn:fontconfig:fonts.dtd'>
<fontconfig>
<!-- Default fonts -->
@@ -153,7 +129,7 @@ let
# priority 53
rejectBitmaps = pkgs.writeText "fc-53-no-bitmaps.conf" ''
<?xml version="1.0"?>
- <!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+ <!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
<fontconfig>
${optionalString (!cfg.allowBitmaps) ''
@@ -181,7 +157,7 @@ let
# priority 53
rejectType1 = pkgs.writeText "fc-53-nixos-reject-type1.conf" ''
<?xml version="1.0"?>
- <!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+ <!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
<fontconfig>
<!-- Reject Type 1 fonts -->
@@ -200,59 +176,46 @@ let
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
+ dst=$out/etc/fonts/conf.d
+ mkdir -p $dst
# fonts.conf
- ln -s ${supportFontsConf} $support_folder/../fonts.conf
- ln -s ${latestPkg.out}/etc/fonts/fonts.conf \
- $latest_folder/../fonts.conf
+ ln -s ${pkg.out}/etc/fonts/fonts.conf \
+ $dst/../fonts.conf
+ # TODO: remove this legacy symlink once people stop using packages built before #95358 was merged
+ mkdir -p $out/etc/fonts/2.11
+ ln -s /etc/fonts/fonts.conf \
+ $out/etc/fonts/2.11/fonts.conf
# fontconfig default config files
- ln -s ${supportPkg.out}/etc/fonts/conf.d/*.conf \
- $support_folder/
- # Latest fontconfig is configured to look for the upstream defaults inside the package.
+ ln -s ${pkg.out}/etc/fonts/conf.d/*.conf \
+ $dst/
# 00-nixos-cache.conf
- ln -s ${cacheConfSupport} \
- $support_folder/00-nixos-cache.conf
- ln -s ${cacheConfLatest} $latest_folder/00-nixos-cache.conf
+ ln -s ${cacheConf} $dst/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
+ ln -s ${renderConf} $dst/10-nixos-rendering.conf
# 50-user.conf
${optionalString (!cfg.includeUserConf) ''
- rm $support_folder/50-user.conf
- ''}
- # Since latest fontconfig looks for default files inside the package,
- # we had to move this one elsewhere to be able to exclude it here.
- ${optionalString cfg.includeUserConf ''
- ln -s ${latestPkg.out}/etc/fonts/conf.d.bak/50-user.conf $latest_folder/50-user.conf
+ rm $dst/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
+ ln -s ${localConf} $dst/../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
+ ln -s ${defaultFontsConf} $dst/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
+ ln -s ${rejectBitmaps} $dst/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
+ ln -s ${rejectType1} $dst/53-nixos-reject-type1.conf
''}
'';
@@ -486,7 +449,7 @@ in
environment.systemPackages = [ pkgs.fontconfig ];
environment.etc.fonts.source = "${fontconfigEtc}/etc/fonts/";
})
- (mkIf (cfg.enable && !cfg.penultimate.enable) {
+ (mkIf cfg.enable {
fonts.fontconfig.confPackages = [ confPkg ];
})
];
diff --git a/nixpkgs/nixos/modules/config/krb5/default.nix b/nixpkgs/nixos/modules/config/krb5/default.nix
index ff16ffcf9c6..c2302451d70 100644
--- a/nixpkgs/nixos/modules/config/krb5/default.nix
+++ b/nixpkgs/nixos/modules/config/krb5/default.nix
@@ -41,31 +41,30 @@ let
value)
else value;
- mkIndent = depth: concatStrings (builtins.genList (_: " ") (2 * depth));
+ indent = " ";
- mkRelation = name: value: "${name} = ${mkVal { inherit value; }}";
+ mkRelation = name: value:
+ if (isList value) then
+ concatMapStringsSep "\n" (mkRelation name) value
+ else "${name} = ${mkVal value}";
- mkVal = { value, depth ? 0 }:
+ mkVal = value:
if (value == true) then "true"
else if (value == false) then "false"
else if (isInt value) then (toString value)
- else if (isList value) then
- concatMapStringsSep " " mkVal { inherit value depth; }
else if (isAttrs value) then
- (concatStringsSep "\n${mkIndent (depth + 1)}"
- ([ "{" ] ++ (mapAttrsToList
- (attrName: attrValue: let
- mappedAttrValue = mkVal {
- value = attrValue;
- depth = depth + 1;
- };
- in "${attrName} = ${mappedAttrValue}")
- value))) + "\n${mkIndent depth}}"
+ let configLines = concatLists
+ (map (splitString "\n")
+ (mapAttrsToList mkRelation value));
+ in
+ (concatStringsSep "\n${indent}"
+ ([ "{" ] ++ configLines))
+ + "\n}"
else value;
mkMappedAttrsOrString = value: concatMapStringsSep "\n"
(line: if builtins.stringLength line > 0
- then "${mkIndent 1}${line}"
+ then "${indent}${line}"
else line)
(splitString "\n"
(if isAttrs value then
@@ -114,7 +113,10 @@ in {
{
"ATHENA.MIT.EDU" = {
admin_server = "athena.mit.edu";
- kdc = "athena.mit.edu";
+ kdc = [
+ "athena01.mit.edu"
+ "athena02.mit.edu"
+ ];
};
};
'';
diff --git a/nixpkgs/nixos/modules/config/no-x-libs.nix b/nixpkgs/nixos/modules/config/no-x-libs.nix
index 873b8073fed..941ab78f863 100644
--- a/nixpkgs/nixos/modules/config/no-x-libs.nix
+++ b/nixpkgs/nixos/modules/config/no-x-libs.nix
@@ -27,6 +27,7 @@ with lib;
fonts.fontconfig.enable = false;
nixpkgs.overlays = singleton (const (super: {
+ cairo = super.cairo.override { x11Support = false; };
dbus = super.dbus.override { x11Support = false; };
networkmanager-fortisslvpn = super.networkmanager-fortisslvpn.override { withGnome = false; };
networkmanager-l2tp = super.networkmanager-l2tp.override { withGnome = false; };
@@ -35,6 +36,7 @@ with lib;
networkmanager-vpnc = super.networkmanager-vpnc.override { withGnome = false; };
networkmanager-iodine = super.networkmanager-iodine.override { withGnome = false; };
gobject-introspection = super.gobject-introspection.override { x11Support = false; };
+ qemu = super.qemu.override { gtkSupport = false; spiceSupport = false; sdlSupport = false; };
}));
};
}
diff --git a/nixpkgs/nixos/modules/config/system-path.nix b/nixpkgs/nixos/modules/config/system-path.nix
index ae9710e3518..67305e8499c 100644
--- a/nixpkgs/nixos/modules/config/system-path.nix
+++ b/nixpkgs/nixos/modules/config/system-path.nix
@@ -33,17 +33,20 @@ let
pkgs.ncurses
pkgs.netcat
config.programs.ssh.package
- pkgs.perl
pkgs.procps
- pkgs.rsync
- pkgs.strace
pkgs.su
pkgs.time
pkgs.utillinux
- pkgs.which # 88K size
+ pkgs.which
pkgs.zstd
];
+ defaultPackages = map (pkg: setPrio ((pkg.meta.priority or 5) + 3) pkg)
+ [ pkgs.perl
+ pkgs.rsync
+ pkgs.strace
+ ];
+
in
{
@@ -66,6 +69,21 @@ in
'';
};
+ defaultPackages = mkOption {
+ type = types.listOf types.package;
+ default = defaultPackages;
+ example = literalExample "[]";
+ description = ''
+ Set of packages users expect from a minimal linux istall.
+ Like systemPackages, they appear in
+ /run/current-system/sw. These packages are
+ automatically available to all users, and are
+ automatically updated every time you rebuild the system
+ configuration.
+ If you want a more minimal system, set it to an empty list.
+ '';
+ };
+
pathsToLink = mkOption {
type = types.listOf types.str;
# Note: We need `/lib' to be among `pathsToLink' for NSS modules
@@ -105,7 +123,7 @@ in
config = {
- environment.systemPackages = requiredPackages;
+ environment.systemPackages = requiredPackages ++ config.environment.defaultPackages;
environment.pathsToLink =
[ "/bin"
diff --git a/nixpkgs/nixos/modules/config/users-groups.nix b/nixpkgs/nixos/modules/config/users-groups.nix
index 56b7af98b61..0ab303d0ae4 100644
--- a/nixpkgs/nixos/modules/config/users-groups.nix
+++ b/nixpkgs/nixos/modules/config/users-groups.nix
@@ -463,7 +463,7 @@ in {
users.users = mkOption {
default = {};
- type = with types; loaOf (submodule userOpts);
+ type = with types; attrsOf (submodule userOpts);
example = {
alice = {
uid = 1234;
@@ -487,7 +487,7 @@ in {
{ students.gid = 1001;
hackers = { };
};
- type = with types; loaOf (submodule groupOpts);
+ type = with types; attrsOf (submodule groupOpts);
description = ''
Additional groups to be created automatically by the system.
'';
diff --git a/nixpkgs/nixos/modules/hardware/bladeRF.nix b/nixpkgs/nixos/modules/hardware/bladeRF.nix
index 92544347714..35b74b8382e 100644
--- a/nixpkgs/nixos/modules/hardware/bladeRF.nix
+++ b/nixpkgs/nixos/modules/hardware/bladeRF.nix
@@ -25,4 +25,4 @@ in
services.udev.packages = [ pkgs.libbladeRF ];
users.groups.bladerf = {};
};
-} \ No newline at end of file
+}
diff --git a/nixpkgs/nixos/modules/hardware/ckb-next.nix b/nixpkgs/nixos/modules/hardware/ckb-next.nix
index fe0ca9f26d5..6932be1c54c 100644
--- a/nixpkgs/nixos/modules/hardware/ckb-next.nix
+++ b/nixpkgs/nixos/modules/hardware/ckb-next.nix
@@ -43,7 +43,6 @@ in
serviceConfig = {
ExecStart = "${cfg.package}/bin/ckb-next-daemon ${optionalString (cfg.gid != null) "--gid=${builtins.toString cfg.gid}"}";
Restart = "on-failure";
- StandardOutput = "syslog";
};
};
};
diff --git a/nixpkgs/nixos/modules/hardware/device-tree.nix b/nixpkgs/nixos/modules/hardware/device-tree.nix
index b3f1dda98c8..e0ab37bca63 100644
--- a/nixpkgs/nixos/modules/hardware/device-tree.nix
+++ b/nixpkgs/nixos/modules/hardware/device-tree.nix
@@ -4,7 +4,114 @@ with lib;
let
cfg = config.hardware.deviceTree;
-in {
+
+ overlayType = types.submodule {
+ options = {
+ name = mkOption {
+ type = types.str;
+ description = ''
+ Name of this overlay
+ '';
+ };
+
+ dtsFile = mkOption {
+ type = types.nullOr types.path;
+ description = ''
+ Path to .dts overlay file, overlay is applied to
+ each .dtb file matching "compatible" of the overlay.
+ '';
+ default = null;
+ example = literalExample "./dts/overlays.dts";
+ };
+
+ dtsText = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ description = ''
+ Literal DTS contents, overlay is applied to
+ each .dtb file matching "compatible" of the overlay.
+ '';
+ example = literalExample ''
+ /dts-v1/;
+ /plugin/;
+ / {
+ compatible = "raspberrypi";
+ fragment@0 {
+ target-path = "/soc";
+ __overlay__ {
+ pps {
+ compatible = "pps-gpio";
+ status = "okay";
+ };
+ };
+ };
+ };
+ '';
+ };
+
+ dtboFile = mkOption {
+ type = types.nullOr types.path;
+ default = null;
+ description = ''
+ Path to .dtbo compiled overlay file.
+ '';
+ };
+ };
+ };
+
+ # this requires kernel package
+ dtbsWithSymbols = pkgs.stdenv.mkDerivation {
+ name = "dtbs-with-symbols";
+ inherit (cfg.kernelPackage) src nativeBuildInputs depsBuildBuild;
+ patches = map (patch: patch.patch) cfg.kernelPackage.kernelPatches;
+ buildPhase = ''
+ patchShebangs scripts/*
+ substituteInPlace scripts/Makefile.lib \
+ --replace 'DTC_FLAGS += $(DTC_FLAGS_$(basetarget))' 'DTC_FLAGS += $(DTC_FLAGS_$(basetarget)) -@'
+ make ${pkgs.stdenv.hostPlatform.platform.kernelBaseConfig} ARCH="${pkgs.stdenv.hostPlatform.platform.kernelArch}"
+ make dtbs ARCH="${pkgs.stdenv.hostPlatform.platform.kernelArch}"
+ '';
+ installPhase = ''
+ make dtbs_install INSTALL_DTBS_PATH=$out/dtbs ARCH="${pkgs.stdenv.hostPlatform.platform.kernelArch}"
+ '';
+ };
+
+ filterDTBs = src: if isNull cfg.filter
+ then "${src}/dtbs"
+ else
+ pkgs.runCommand "dtbs-filtered" {} ''
+ mkdir -p $out
+ cd ${src}/dtbs
+ find . -type f -name '${cfg.filter}' -print0 \
+ | xargs -0 cp -v --no-preserve=mode --target-directory $out --parents
+ '';
+
+ # Compile single Device Tree overlay source
+ # file (.dts) into its compiled variant (.dtbo)
+ compileDTS = name: f: pkgs.callPackage({ dtc }: pkgs.stdenv.mkDerivation {
+ name = "${name}-dtbo";
+
+ nativeBuildInputs = [ dtc ];
+
+ buildCommand = ''
+ dtc -I dts ${f} -O dtb -@ -o $out
+ '';
+ }) {};
+
+ # Fill in `dtboFile` for each overlay if not set already.
+ # Existence of one of these is guarded by assertion below
+ withDTBOs = xs: flip map xs (o: o // { dtboFile =
+ if isNull o.dtboFile then
+ if !isNull o.dtsFile then compileDTS o.name o.dtsFile
+ else compileDTS o.name (pkgs.writeText "dts" o.dtsText)
+ else o.dtboFile; } );
+
+in
+{
+ imports = [
+ (mkRemovedOptionModule [ "hardware" "deviceTree" "base" ] "Use hardware.deviceTree.kernelPackage instead")
+ ];
+
options = {
hardware.deviceTree = {
enable = mkOption {
@@ -16,13 +123,13 @@ in {
'';
};
- base = mkOption {
- default = "${config.boot.kernelPackages.kernel}/dtbs";
- defaultText = "\${config.boot.kernelPackages.kernel}/dtbs";
- example = literalExample "pkgs.device-tree_rpi";
+ kernelPackage = mkOption {
+ default = config.boot.kernelPackages.kernel;
+ defaultText = "config.boot.kernelPackages.kernel";
+ example = literalExample "pkgs.linux_latest";
type = types.path;
description = ''
- The path containing the base device-tree (.dtb) to boot. Contains
+ Kernel package containing the base device-tree (.dtb) to boot. Uses
device trees bundled with the Linux kernel by default.
'';
};
@@ -38,14 +145,32 @@ in {
'';
};
+ filter = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ example = "*rpi*.dtb";
+ description = ''
+ Only include .dtb files matching glob expression.
+ '';
+ };
+
overlays = mkOption {
default = [];
- example = literalExample
- "[\"\${pkgs.device-tree_rpi.overlays}/w1-gpio.dtbo\"]";
- type = types.listOf types.path;
+ example = literalExample ''
+ [
+ { name = "pps"; dtsFile = ./dts/pps.dts; }
+ { name = "spi";
+ dtsText = "...";
+ }
+ { name = "precompiled"; dtboFile = ./dtbos/example.dtbo; }
+ ]
+ '';
+ type = types.listOf (types.coercedTo types.path (path: {
+ name = baseNameOf path;
+ dtboFile = path;
+ }) overlayType);
description = ''
- A path containing device tree overlays (.dtbo) to be applied to all
- base device-trees.
+ List of overlays to apply to base device-tree (.dtb) files.
'';
};
@@ -54,14 +179,27 @@ in {
type = types.nullOr types.path;
internal = true;
description = ''
- A path containing the result of applying `overlays` to `base`.
+ A path containing the result of applying `overlays` to `kernelPackage`.
'';
};
};
};
config = mkIf (cfg.enable) {
+
+ assertions = let
+ invalidOverlay = o: isNull o.dtsFile && isNull o.dtsText && isNull o.dtboFile;
+ in lib.singleton {
+ assertion = lib.all (o: !invalidOverlay o) cfg.overlays;
+ message = ''
+ deviceTree overlay needs one of dtsFile, dtsText or dtboFile set.
+ Offending overlay(s):
+ ${toString (map (o: o.name) (builtins.filter invalidOverlay cfg.overlays))}
+ '';
+ };
+
hardware.deviceTree.package = if (cfg.overlays != [])
- then pkgs.deviceTree.applyOverlays cfg.base cfg.overlays else cfg.base;
+ then pkgs.deviceTree.applyOverlays (filterDTBs dtbsWithSymbols) (withDTBOs cfg.overlays)
+ else (filterDTBs cfg.kernelPackage);
};
}
diff --git a/nixpkgs/nixos/modules/hardware/onlykey.nix b/nixpkgs/nixos/modules/hardware/onlykey.nix
index b6820fe0191..07358c8a878 100644
--- a/nixpkgs/nixos/modules/hardware/onlykey.nix
+++ b/nixpkgs/nixos/modules/hardware/onlykey.nix
@@ -26,7 +26,7 @@ with lib;
####### implementation
config = mkIf config.hardware.onlykey.enable {
- services.udev.extraRules = builtin.readFile ./onlykey.udev;
+ services.udev.extraRules = builtins.readFile ./onlykey.udev;
};
diff --git a/nixpkgs/nixos/modules/hardware/tuxedo-keyboard.nix b/nixpkgs/nixos/modules/hardware/tuxedo-keyboard.nix
index 898eed24493..97af7c61f3c 100644
--- a/nixpkgs/nixos/modules/hardware/tuxedo-keyboard.nix
+++ b/nixpkgs/nixos/modules/hardware/tuxedo-keyboard.nix
@@ -2,7 +2,7 @@
with lib;
-let
+let
cfg = config.hardware.tuxedo-keyboard;
tuxedo-keyboard = config.boot.kernelPackages.tuxedo-keyboard;
in
@@ -27,7 +27,7 @@ in
'';
};
- config = mkIf cfg.enable
+ config = mkIf cfg.enable
{
boot.kernelModules = ["tuxedo_keyboard"];
boot.extraModulePackages = [ tuxedo-keyboard ];
diff --git a/nixpkgs/nixos/modules/i18n/input-method/uim.nix b/nixpkgs/nixos/modules/i18n/input-method/uim.nix
index 7ad68bf851f..459294657e0 100644
--- a/nixpkgs/nixos/modules/i18n/input-method/uim.nix
+++ b/nixpkgs/nixos/modules/i18n/input-method/uim.nix
@@ -2,7 +2,7 @@
with lib;
-let
+let
cfg = config.i18n.inputMethod.uim;
in
{
diff --git a/nixpkgs/nixos/modules/installer/cd-dvd/iso-image.nix b/nixpkgs/nixos/modules/installer/cd-dvd/iso-image.nix
index 1cd2252ecf2..405fbfa10db 100644
--- a/nixpkgs/nixos/modules/installer/cd-dvd/iso-image.nix
+++ b/nixpkgs/nixos/modules/installer/cd-dvd/iso-image.nix
@@ -417,6 +417,14 @@ in
'';
};
+ isoImage.squashfsCompression = mkOption {
+ default = "xz -Xdict-size 100%";
+ description = ''
+ Compression settings to use for the squashfs nix store.
+ '';
+ example = "zstd -Xcompression-level 6";
+ };
+
isoImage.edition = mkOption {
default = "";
description = ''
@@ -614,6 +622,7 @@ in
# Create the squashfs image that contains the Nix store.
system.build.squashfsStore = pkgs.callPackage ../../../lib/make-squashfs.nix {
storeContents = config.isoImage.storeContents;
+ comp = config.isoImage.squashfsCompression;
};
# Individual files to be included on the CD, outside of the Nix
diff --git a/nixpkgs/nixos/modules/installer/cd-dvd/sd-image-raspberrypi4.nix b/nixpkgs/nixos/modules/installer/cd-dvd/sd-image-raspberrypi4.nix
index 79c835dc390..87545e84203 100644
--- a/nixpkgs/nixos/modules/installer/cd-dvd/sd-image-raspberrypi4.nix
+++ b/nixpkgs/nixos/modules/installer/cd-dvd/sd-image-raspberrypi4.nix
@@ -27,7 +27,7 @@
};
fileSystems."/boot/firmware" = {
- # This effectively "renames" the loaOf entry set in sd-image.nix
+ # This effectively "renames" the attrsOf entry set in sd-image.nix
mountPoint = "/boot";
neededForBoot = true;
};
diff --git a/nixpkgs/nixos/modules/installer/cd-dvd/sd-image.nix b/nixpkgs/nixos/modules/installer/cd-dvd/sd-image.nix
index ddad1116c94..231c7bf0a6c 100644
--- a/nixpkgs/nixos/modules/installer/cd-dvd/sd-image.nix
+++ b/nixpkgs/nixos/modules/installer/cd-dvd/sd-image.nix
@@ -108,6 +108,15 @@ in
'';
};
+ postBuildCommands = mkOption {
+ example = literalExample "'' dd if=\${pkgs.myBootLoader}/SPL of=$img bs=1024 seek=1 conv=notrunc ''";
+ default = "";
+ description = ''
+ Shell commands to run after the image is built.
+ Can be used for boards requiring to dd u-boot SPL before actual partitions.
+ '';
+ };
+
compressImage = mkOption {
type = types.bool;
default = true;
@@ -197,6 +206,9 @@ in
# Verify the FAT partition before copying it.
fsck.vfat -vn firmware_part.img
dd conv=notrunc if=firmware_part.img of=$img seek=$START count=$SECTORS
+
+ ${config.sdImage.postBuildCommands}
+
if test -n "$compressImage"; then
zstd -T$NIX_BUILD_CORES --rm $img
fi
diff --git a/nixpkgs/nixos/modules/installer/cd-dvd/system-tarball-pc-readme.txt b/nixpkgs/nixos/modules/installer/cd-dvd/system-tarball-pc-readme.txt
index 84252f292c5..887bf60d0fb 100644
--- a/nixpkgs/nixos/modules/installer/cd-dvd/system-tarball-pc-readme.txt
+++ b/nixpkgs/nixos/modules/installer/cd-dvd/system-tarball-pc-readme.txt
@@ -63,7 +63,7 @@ Activate the system: look for a directory in nix/store similar to:
Having found it, activate that nixos system *twice*:
chroot . /nix/store/SOMETHING-nixos-SOMETHING/activate
chroot . /nix/store/SOMETHING-nixos-SOMETHING/activate
-
+
This runs a 'hostname' command. Restore your old hostname with:
hostname OLDHOSTNAME
diff --git a/nixpkgs/nixos/modules/installer/tools/nixos-build-vms/nixos-build-vms.sh b/nixpkgs/nixos/modules/installer/tools/nixos-build-vms/nixos-build-vms.sh
index 25106733087..2a6c3ab1149 100644
--- a/nixpkgs/nixos/modules/installer/tools/nixos-build-vms/nixos-build-vms.sh
+++ b/nixpkgs/nixos/modules/installer/tools/nixos-build-vms/nixos-build-vms.sh
@@ -1,4 +1,4 @@
-#! @shell@ -e
+#! @runtimeShell@ -e
# Shows the usage of this command to the user
diff --git a/nixpkgs/nixos/modules/installer/tools/nixos-enter.sh b/nixpkgs/nixos/modules/installer/tools/nixos-enter.sh
index 1fdd4627a90..c72ef6e9c28 100644
--- a/nixpkgs/nixos/modules/installer/tools/nixos-enter.sh
+++ b/nixpkgs/nixos/modules/installer/tools/nixos-enter.sh
@@ -1,4 +1,4 @@
-#! @shell@
+#! @runtimeShell@
set -e
diff --git a/nixpkgs/nixos/modules/installer/tools/nixos-install.sh b/nixpkgs/nixos/modules/installer/tools/nixos-install.sh
index 0b62bca8367..a180d1bc4c1 100644
--- a/nixpkgs/nixos/modules/installer/tools/nixos-install.sh
+++ b/nixpkgs/nixos/modules/installer/tools/nixos-install.sh
@@ -1,4 +1,4 @@
-#! @shell@
+#! @runtimeShell@
set -e
shopt -s nullglob
@@ -10,6 +10,7 @@ umask 0022
# Parse the command line for the -I flag
extraBuildFlags=()
+flakeFlags=()
mountPoint=/mnt
channelPath=
@@ -34,6 +35,23 @@ while [ "$#" -gt 0 ]; do
--system|--closure)
system="$1"; shift 1
;;
+ --flake)
+ flake="$1"
+ flakeFlags=(--experimental-features 'nix-command flakes')
+ shift 1
+ ;;
+ --recreate-lock-file|--no-update-lock-file|--no-write-lock-file|--no-registries|--commit-lock-file)
+ lockFlags+=("$i")
+ ;;
+ --update-input)
+ j="$1"; shift 1
+ lockFlags+=("$i" "$j")
+ ;;
+ --override-input)
+ j="$1"; shift 1
+ k="$1"; shift 1
+ lockFlags+=("$i" "$j" "$k")
+ ;;
--channel)
channelPath="$1"; shift 1
;;
@@ -92,14 +110,32 @@ if [[ ${NIXOS_CONFIG:0:1} != / ]]; then
exit 1
fi
-if [[ ! -e $NIXOS_CONFIG && -z $system ]]; then
+if [[ -n $flake ]]; then
+ if [[ $flake =~ ^(.*)\#([^\#\"]*)$ ]]; then
+ flake="${BASH_REMATCH[1]}"
+ flakeAttr="${BASH_REMATCH[2]}"
+ fi
+ if [[ -z "$flakeAttr" ]]; then
+ echo "Please specify the name of the NixOS configuration to be installed, as a URI fragment in the flake-uri."
+ echo "For example, to use the output nixosConfigurations.foo from the flake.nix, append \"#foo\" to the flake-uri."
+ exit 1
+ fi
+ flakeAttr="nixosConfigurations.\"$flakeAttr\""
+fi
+
+# Resolve the flake.
+if [[ -n $flake ]]; then
+ flake=$(nix "${flakeFlags[@]}" flake info --json "${extraBuildFlags[@]}" "${lockFlags[@]}" -- "$flake" | jq -r .url)
+fi
+
+if [[ ! -e $NIXOS_CONFIG && -z $system && -z $flake ]]; then
echo "configuration file $NIXOS_CONFIG doesn't exist"
exit 1
fi
# A place to drop temporary stuff.
-tmpdir="$(mktemp -d -p $mountPoint)"
-trap "rm -rf $tmpdir" EXIT
+tmpdir="$(mktemp -d -p "$mountPoint")"
+trap 'rm -rf $tmpdir' EXIT
# store temporary files on target filesystem by default
export TMPDIR=${TMPDIR:-$tmpdir}
@@ -108,12 +144,19 @@ sub="auto?trusted=1"
# Build the system configuration in the target filesystem.
if [[ -z $system ]]; then
- echo "building the configuration in $NIXOS_CONFIG..."
outLink="$tmpdir/system"
- nix-build --out-link "$outLink" --store "$mountPoint" "${extraBuildFlags[@]}" \
- --extra-substituters "$sub" \
- '<nixpkgs/nixos>' -A system -I "nixos-config=$NIXOS_CONFIG" ${verbosity[@]}
- system=$(readlink -f $outLink)
+ if [[ -z $flake ]]; then
+ echo "building the configuration in $NIXOS_CONFIG..."
+ nix-build --out-link "$outLink" --store "$mountPoint" "${extraBuildFlags[@]}" \
+ --extra-substituters "$sub" \
+ '<nixpkgs/nixos>' -A system -I "nixos-config=$NIXOS_CONFIG" "${verbosity[@]}"
+ else
+ echo "building the flake in $flake..."
+ nix "${flakeFlags[@]}" build "$flake#$flakeAttr.config.system.build.toplevel" \
+ --extra-substituters "$sub" "${verbosity[@]}" \
+ "${extraBuildFlags[@]}" "${lockFlags[@]}" --out-link "$outLink"
+ fi
+ system=$(readlink -f "$outLink")
fi
# Set the system profile to point to the configuration. TODO: combine
@@ -121,7 +164,7 @@ fi
# a progress bar.
nix-env --store "$mountPoint" "${extraBuildFlags[@]}" \
--extra-substituters "$sub" \
- -p $mountPoint/nix/var/nix/profiles/system --set "$system" ${verbosity[@]}
+ -p "$mountPoint"/nix/var/nix/profiles/system --set "$system" "${verbosity[@]}"
# Copy the NixOS/Nixpkgs sources to the target as the initial contents
# of the NixOS channel.
@@ -131,12 +174,12 @@ if [[ -z $noChannelCopy ]]; then
fi
if [[ -n $channelPath ]]; then
echo "copying channel..."
- mkdir -p $mountPoint/nix/var/nix/profiles/per-user/root
+ mkdir -p "$mountPoint"/nix/var/nix/profiles/per-user/root
nix-env --store "$mountPoint" "${extraBuildFlags[@]}" --extra-substituters "$sub" \
- -p $mountPoint/nix/var/nix/profiles/per-user/root/channels --set "$channelPath" --quiet \
- ${verbosity[@]}
- install -m 0700 -d $mountPoint/root/.nix-defexpr
- ln -sfn /nix/var/nix/profiles/per-user/root/channels $mountPoint/root/.nix-defexpr/channels
+ -p "$mountPoint"/nix/var/nix/profiles/per-user/root/channels --set "$channelPath" --quiet \
+ "${verbosity[@]}"
+ install -m 0700 -d "$mountPoint"/root/.nix-defexpr
+ ln -sfn /nix/var/nix/profiles/per-user/root/channels "$mountPoint"/root/.nix-defexpr/channels
fi
fi
@@ -150,7 +193,7 @@ touch "$mountPoint/etc/NIXOS"
if [[ -z $noBootLoader ]]; then
echo "installing the boot loader..."
# Grub needs an mtab.
- ln -sfn /proc/mounts $mountPoint/etc/mtab
+ ln -sfn /proc/mounts "$mountPoint"/etc/mtab
NIXOS_INSTALL_BOOTLOADER=1 nixos-enter --root "$mountPoint" -- /run/current-system/bin/switch-to-configuration boot
fi
diff --git a/nixpkgs/nixos/modules/installer/tools/nixos-option/nixos-option.cc b/nixpkgs/nixos/modules/installer/tools/nixos-option/nixos-option.cc
index 1a7b07a74f8..f779d82edbd 100644
--- a/nixpkgs/nixos/modules/installer/tools/nixos-option/nixos-option.cc
+++ b/nixpkgs/nixos/modules/installer/tools/nixos-option/nixos-option.cc
@@ -224,7 +224,7 @@ bool optionTypeIs(Context & ctx, Value & v, const std::string & soughtType)
bool isAggregateOptionType(Context & ctx, Value & v)
{
- return optionTypeIs(ctx, v, "attrsOf") || optionTypeIs(ctx, v, "listOf") || optionTypeIs(ctx, v, "loaOf");
+ return optionTypeIs(ctx, v, "attrsOf") || optionTypeIs(ctx, v, "listOf");
}
MakeError(OptionPathError, EvalError);
diff --git a/nixpkgs/nixos/modules/installer/tools/nixos-rebuild.sh b/nixpkgs/nixos/modules/installer/tools/nixos-rebuild.sh
index 354274478a3..ad40fd2811d 100644
--- a/nixpkgs/nixos/modules/installer/tools/nixos-rebuild.sh
+++ b/nixpkgs/nixos/modules/installer/tools/nixos-rebuild.sh
@@ -1,6 +1,6 @@
-#! @shell@
+#! @runtimeShell@
-if [ -x "@shell@" ]; then export SHELL="@shell@"; fi;
+if [ -x "@runtimeShell@" ]; then export SHELL="@runtimeShell@"; fi;
set -e
set -o pipefail
@@ -17,6 +17,7 @@ showSyntax() {
origArgs=("$@")
extraBuildFlags=()
lockFlags=()
+flakeFlags=()
action=
buildNix=1
fast=
@@ -99,6 +100,7 @@ while [ "$#" -gt 0 ]; do
;;
--flake)
flake="$1"
+ flakeFlags=(--experimental-features 'nix-command flakes')
shift 1
;;
--recreate-lock-file|--no-update-lock-file|--no-write-lock-file|--no-registries|--commit-lock-file)
@@ -281,16 +283,19 @@ fi
# Resolve the flake.
if [[ -n $flake ]]; then
- flake=$(nix flake info --json "${extraBuildFlags[@]}" "${lockFlags[@]}" -- "$flake" | jq -r .url)
+ flake=$(nix "${flakeFlags[@]}" flake info --json "${extraBuildFlags[@]}" "${lockFlags[@]}" -- "$flake" | jq -r .url)
fi
# Find configuration.nix and open editor instead of building.
if [ "$action" = edit ]; then
if [[ -z $flake ]]; then
NIXOS_CONFIG=${NIXOS_CONFIG:-$(nix-instantiate --find-file nixos-config)}
- exec "${EDITOR:-nano}" "$NIXOS_CONFIG"
+ if [[ -d $NIXOS_CONFIG ]]; then
+ NIXOS_CONFIG=$NIXOS_CONFIG/default.nix
+ fi
+ exec ${EDITOR:-nano} "$NIXOS_CONFIG"
else
- exec nix edit "${lockFlags[@]}" -- "$flake#$flakeAttr"
+ exec nix "${flakeFlags[@]}" edit "${lockFlags[@]}" -- "$flake#$flakeAttr"
fi
exit 1
fi
@@ -416,7 +421,7 @@ if [ -z "$rollback" ]; then
pathToConfig="$(nixBuild '<nixpkgs/nixos>' --no-out-link -A system "${extraBuildFlags[@]}")"
else
outLink=$tmpDir/result
- nix build "$flake#$flakeAttr.config.system.build.toplevel" \
+ nix "${flakeFlags[@]}" build "$flake#$flakeAttr.config.system.build.toplevel" \
"${extraBuildFlags[@]}" "${lockFlags[@]}" --out-link $outLink
pathToConfig="$(readlink -f $outLink)"
fi
@@ -426,7 +431,7 @@ if [ -z "$rollback" ]; then
if [[ -z $flake ]]; then
pathToConfig="$(nixBuild '<nixpkgs/nixos>' -A system -k "${extraBuildFlags[@]}")"
else
- nix build "$flake#$flakeAttr.config.system.build.toplevel" "${extraBuildFlags[@]}" "${lockFlags[@]}"
+ nix "${flakeFlags[@]}" build "$flake#$flakeAttr.config.system.build.toplevel" "${extraBuildFlags[@]}" "${lockFlags[@]}"
pathToConfig="$(readlink -f ./result)"
fi
elif [ "$action" = build-vm ]; then
diff --git a/nixpkgs/nixos/modules/installer/tools/nixos-version.sh b/nixpkgs/nixos/modules/installer/tools/nixos-version.sh
index fb0fe26116a..f5e3f32b3c6 100644
--- a/nixpkgs/nixos/modules/installer/tools/nixos-version.sh
+++ b/nixpkgs/nixos/modules/installer/tools/nixos-version.sh
@@ -1,4 +1,4 @@
-#! @shell@
+#! @runtimeShell@
case "$1" in
-h|--help)
diff --git a/nixpkgs/nixos/modules/installer/tools/tools.nix b/nixpkgs/nixos/modules/installer/tools/tools.nix
index 11128621424..1da3a5b27eb 100644
--- a/nixpkgs/nixos/modules/installer/tools/tools.nix
+++ b/nixpkgs/nixos/modules/installer/tools/tools.nix
@@ -14,13 +14,19 @@ let
nixos-build-vms = makeProg {
name = "nixos-build-vms";
src = ./nixos-build-vms/nixos-build-vms.sh;
+ inherit (pkgs) runtimeShell;
};
nixos-install = makeProg {
name = "nixos-install";
src = ./nixos-install.sh;
+ inherit (pkgs) runtimeShell;
nix = config.nix.package.out;
- path = makeBinPath [ nixos-enter ];
+ path = makeBinPath [
+ pkgs.nixUnstable
+ pkgs.jq
+ nixos-enter
+ ];
};
nixos-rebuild =
@@ -28,6 +34,7 @@ let
makeProg {
name = "nixos-rebuild";
src = ./nixos-rebuild.sh;
+ inherit (pkgs) runtimeShell;
nix = config.nix.package.out;
nix_x86_64_linux = fallback.x86_64-linux;
nix_i686_linux = fallback.i686-linux;
@@ -50,6 +57,7 @@ let
nixos-version = makeProg {
name = "nixos-version";
src = ./nixos-version.sh;
+ inherit (pkgs) runtimeShell;
inherit (config.system.nixos) version codeName revision;
inherit (config.system) configurationRevision;
json = builtins.toJSON ({
@@ -64,6 +72,7 @@ let
nixos-enter = makeProg {
name = "nixos-enter";
src = ./nixos-enter.sh;
+ inherit (pkgs) runtimeShell;
};
in
diff --git a/nixpkgs/nixos/modules/misc/ids.nix b/nixpkgs/nixos/modules/misc/ids.nix
index 4692ea32656..394da9a3889 100644
--- a/nixpkgs/nixos/modules/misc/ids.nix
+++ b/nixpkgs/nixos/modules/misc/ids.nix
@@ -198,7 +198,7 @@ in
bosun = 161;
kubernetes = 162;
peerflix = 163;
- chronos = 164;
+ #chronos = 164; # removed 2020-08-15
gitlab = 165;
tox-bootstrapd = 166;
cadvisor = 167;
@@ -247,7 +247,7 @@ in
bepasty = 215;
# pumpio = 216; # unused, removed 2018-02-24
nm-openvpn = 217;
- mathics = 218;
+ # mathics = 218; # unused, removed 2020-08-15
ejabberd = 219;
postsrsd = 220;
opendkim = 221;
@@ -321,7 +321,7 @@ in
monetdb = 290;
restic = 291;
openvpn = 292;
- meguca = 293;
+ # meguca = 293; # removed 2020-08-21
yarn = 294;
hdfs = 295;
mapred = 296;
@@ -622,7 +622,7 @@ in
monetdb = 290;
restic = 291;
openvpn = 292;
- meguca = 293;
+ # meguca = 293; # removed 2020-08-21
yarn = 294;
hdfs = 295;
mapred = 296;
diff --git a/nixpkgs/nixos/modules/misc/locate.nix b/nixpkgs/nixos/modules/misc/locate.nix
index dc668796c78..92aa3be0a36 100644
--- a/nixpkgs/nixos/modules/misc/locate.nix
+++ b/nixpkgs/nixos/modules/misc/locate.nix
@@ -127,7 +127,7 @@ in {
{ LOCATE_PATH = cfg.output;
};
- warnings = optional (isMLocate && cfg.localuser != null) "mlocate does not support searching as user other than root"
+ warnings = optional (isMLocate && cfg.localuser != null) "mlocate does not support the services.locate.localuser option; updatedb will run as root. (Silence with services.locate.localuser = null.)"
++ optional (isFindutils && cfg.pruneNames != []) "findutils locate does not support pruning by directory component"
++ optional (isFindutils && cfg.pruneBindMounts) "findutils locate does not support skipping bind mounts";
diff --git a/nixpkgs/nixos/modules/misc/nixpkgs.nix b/nixpkgs/nixos/modules/misc/nixpkgs.nix
index 4f5a9250eaa..25ac94b8e0f 100644
--- a/nixpkgs/nixos/modules/misc/nixpkgs.nix
+++ b/nixpkgs/nixos/modules/misc/nixpkgs.nix
@@ -178,8 +178,6 @@ in
type = types.nullOr types.attrs; # TODO utilize lib.systems.parsedPlatform
default = null;
example = { system = "aarch64-linux"; config = "aarch64-unknown-linux-gnu"; };
- defaultText = literalExample
- ''(import "''${nixos}/../lib").lib.systems.examples.aarch64-multiplatform'';
description = ''
Specifies the platform for which NixOS should be
built. Specify this only if it is different from
diff --git a/nixpkgs/nixos/modules/module-list.nix b/nixpkgs/nixos/modules/module-list.nix
index 5e78103f0dd..7420545f244 100644
--- a/nixpkgs/nixos/modules/module-list.nix
+++ b/nixpkgs/nixos/modules/module-list.nix
@@ -1,7 +1,6 @@
[
./config/debug-info.nix
./config/fonts/fontconfig.nix
- ./config/fonts/fontconfig-penultimate.nix
./config/fonts/fontdir.nix
./config/fonts/fonts.nix
./config/fonts/ghostscript.nix
@@ -263,6 +262,7 @@
./services/continuous-integration/buildbot/worker.nix
./services/continuous-integration/buildkite-agents.nix
./services/continuous-integration/hail.nix
+ ./services/continuous-integration/hercules-ci-agent/default.nix
./services/continuous-integration/hydra/default.nix
./services/continuous-integration/gitlab-runner.nix
./services/continuous-integration/gocd-agent/default.nix
@@ -297,10 +297,10 @@
./services/desktops/accountsservice.nix
./services/desktops/bamf.nix
./services/desktops/blueman.nix
- ./services/desktops/deepin/deepin.nix
./services/desktops/dleyna-renderer.nix
./services/desktops/dleyna-server.nix
./services/desktops/pantheon/files.nix
+ ./services/desktops/espanso.nix
./services/desktops/flatpak.nix
./services/desktops/geoclue2.nix
./services/desktops/gsignond.nix
@@ -331,6 +331,7 @@
./services/development/bloop.nix
./services/development/hoogle.nix
./services/development/jupyter/default.nix
+ ./services/development/jupyterhub/default.nix
./services/development/lorri.nix
./services/editors/emacs.nix
./services/editors/infinoted.nix
@@ -465,14 +466,11 @@
./services/misc/leaps.nix
./services/misc/lidarr.nix
./services/misc/mame.nix
- ./services/misc/mathics.nix
./services/misc/matrix-appservice-discord.nix
./services/misc/matrix-synapse.nix
./services/misc/mautrix-telegram.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
@@ -488,6 +486,7 @@
./services/misc/parsoid.nix
./services/misc/plex.nix
./services/misc/tautulli.nix
+ ./services/misc/pinnwand.nix
./services/misc/pykms.nix
./services/misc/radarr.nix
./services/misc/redmine.nix
@@ -555,6 +554,7 @@
./services/monitoring/telegraf.nix
./services/monitoring/thanos.nix
./services/monitoring/tuptime.nix
+ ./services/monitoring/unifi-poller.nix
./services/monitoring/ups.nix
./services/monitoring/uptime.nix
./services/monitoring/vnstat.nix
@@ -588,6 +588,7 @@
./services/networking/atftpd.nix
./services/networking/avahi-daemon.nix
./services/networking/babeld.nix
+ ./services/networking/biboumi.nix
./services/networking/bind.nix
./services/networking/bitcoind.nix
./services/networking/autossh.nix
@@ -677,6 +678,7 @@
./services/networking/nat.nix
./services/networking/ndppd.nix
./services/networking/networkmanager.nix
+ ./services/networking/nextdns.nix
./services/networking/nftables.nix
./services/networking/ngircd.nix
./services/networking/nghttpx/default.nix
@@ -719,6 +721,7 @@
./services/networking/rdnssd.nix
./services/networking/redsocks.nix
./services/networking/resilio.nix
+ ./services/networking/robustirc-bridge.nix
./services/networking/rpcbind.nix
./services/networking/rxe.nix
./services/networking/sabnzbd.nix
@@ -784,10 +787,8 @@
./services/networking/znc/default.nix
./services/printing/cupsd.nix
./services/scheduling/atd.nix
- ./services/scheduling/chronos.nix
./services/scheduling/cron.nix
./services/scheduling/fcron.nix
- ./services/scheduling/marathon.nix
./services/search/elasticsearch.nix
./services/search/elasticsearch-curator.nix
./services/search/hound.nix
@@ -838,6 +839,8 @@
./services/ttys/gpm.nix
./services/ttys/kmscon.nix
./services/wayland/cage.nix
+ ./services/video/epgstation/default.nix
+ ./services/video/mirakurun.nix
./services/web-apps/atlassian/confluence.nix
./services/web-apps/atlassian/crowd.nix
./services/web-apps/atlassian/jira.nix
@@ -868,6 +871,7 @@
./services/web-apps/moinmoin.nix
./services/web-apps/restya-board.nix
./services/web-apps/sogo.nix
+ ./services/web-apps/rss-bridge.nix
./services/web-apps/tt-rss.nix
./services/web-apps/trac.nix
./services/web-apps/trilium.nix
@@ -888,7 +892,6 @@
./services/web-servers/lighttpd/collectd.nix
./services/web-servers/lighttpd/default.nix
./services/web-servers/lighttpd/gitweb.nix
- ./services/web-servers/meguca.nix
./services/web-servers/mighttpd2.nix
./services/web-servers/minio.nix
./services/web-servers/molly-brown.nix
@@ -926,6 +929,7 @@
./services/x11/gdk-pixbuf.nix
./services/x11/imwheel.nix
./services/x11/redshift.nix
+ ./services/x11/urserver.nix
./services/x11/urxvtd.nix
./services/x11/window-managers/awesome.nix
./services/x11/window-managers/default.nix
diff --git a/nixpkgs/nixos/modules/profiles/base.nix b/nixpkgs/nixos/modules/profiles/base.nix
index 2a2fe119d30..3b67d628f9f 100644
--- a/nixpkgs/nixos/modules/profiles/base.nix
+++ b/nixpkgs/nixos/modules/profiles/base.nix
@@ -26,6 +26,7 @@
pkgs.fuse
pkgs.fuse3
pkgs.sshfs-fuse
+ pkgs.rsync
pkgs.socat
pkgs.screen
diff --git a/nixpkgs/nixos/modules/profiles/hardened.nix b/nixpkgs/nixos/modules/profiles/hardened.nix
index ef8c0d74f06..7bff79e8273 100644
--- a/nixpkgs/nixos/modules/profiles/hardened.nix
+++ b/nixpkgs/nixos/modules/profiles/hardened.nix
@@ -1,7 +1,7 @@
# A profile with most (vanilla) hardening options enabled by default,
# potentially at the cost of features and performance.
-{ lib, pkgs, ... }:
+{ config, lib, pkgs, ... }:
with lib;
@@ -27,6 +27,9 @@ with lib;
security.forcePageTableIsolation = mkDefault true;
+ # This is required by podman to run containers in rootless mode.
+ security.unprivilegedUsernsClone = mkDefault config.virtualisation.containers.enable;
+
security.virtualisation.flushL1DataCache = mkDefault "always";
security.apparmor.enable = mkDefault true;
diff --git a/nixpkgs/nixos/modules/profiles/installation-device.nix b/nixpkgs/nixos/modules/profiles/installation-device.nix
index d05c0c50e82..e68ea1b0877 100644
--- a/nixpkgs/nixos/modules/profiles/installation-device.nix
+++ b/nixpkgs/nixos/modules/profiles/installation-device.nix
@@ -51,22 +51,23 @@ with lib;
services.mingetty.helpLine = ''
The "nixos" and "root" accounts have empty passwords.
- Type `sudo systemctl start sshd` to start the SSH daemon.
- You then must set a password for either "root" or "nixos"
- with `passwd` to be able to login.
+ An ssh daemon is running. You then must set a password
+ for either "root" or "nixos" with `passwd` or add an ssh key
+ to /home/nixos/.ssh/authorized_keys be able to login.
'' + optionalString config.services.xserver.enable ''
Type `sudo systemctl start display-manager' to
start the graphical user interface.
'';
- # Allow sshd to be started manually through "systemctl start sshd".
+ # We run sshd by default. Login via root is only possible after adding a
+ # password via "passwd" or by adding a ssh key to /home/nixos/.ssh/authorized_keys.
+ # The latter one is particular useful if keys are manually added to
+ # installation device for head-less systems i.e. arm boards by manually
+ # mounting the storage in a different system.
services.openssh = {
enable = true;
- # Allow password login to the installation, if the user sets a password via "passwd"
- # It is safe as root doesn't have a password by default and SSH is disabled by default
permitRootLogin = "yes";
};
- systemd.services.sshd.wantedBy = mkOverride 50 [];
# Enable wpa_supplicant, but don't start it by default.
networking.wireless.enable = mkDefault true;
diff --git a/nixpkgs/nixos/modules/programs/autojump.nix b/nixpkgs/nixos/modules/programs/autojump.nix
index 3a8feec4bb4..ecfc2f65807 100644
--- a/nixpkgs/nixos/modules/programs/autojump.nix
+++ b/nixpkgs/nixos/modules/programs/autojump.nix
@@ -18,7 +18,7 @@ in
'';
};
};
- };
+ };
###### implementation
@@ -26,7 +26,7 @@ in
environment.pathsToLink = [ "/share/autojump" ];
environment.systemPackages = [ pkgs.autojump ];
- programs.bash.interactiveShellInit = "source ${pkgs.autojump}/share/autojump/autojump.bash";
+ programs.bash.interactiveShellInit = "source ${pkgs.autojump}/share/autojump/autojump.bash";
programs.zsh.interactiveShellInit = mkIf prg.zsh.enable "source ${pkgs.autojump}/share/autojump/autojump.zsh";
programs.fish.interactiveShellInit = mkIf prg.fish.enable "source ${pkgs.autojump}/share/autojump/autojump.fish";
};
diff --git a/nixpkgs/nixos/modules/programs/ccache.nix b/nixpkgs/nixos/modules/programs/ccache.nix
index 874774c72b4..3c9e64932f1 100644
--- a/nixpkgs/nixos/modules/programs/ccache.nix
+++ b/nixpkgs/nixos/modules/programs/ccache.nix
@@ -80,4 +80,4 @@ in {
];
})
];
-} \ No newline at end of file
+}
diff --git a/nixpkgs/nixos/modules/programs/environment.nix b/nixpkgs/nixos/modules/programs/environment.nix
index 38bdabb4fa8..8877356360a 100644
--- a/nixpkgs/nixos/modules/programs/environment.nix
+++ b/nixpkgs/nixos/modules/programs/environment.nix
@@ -33,7 +33,6 @@ in
{ PATH = [ "/bin" ];
INFOPATH = [ "/info" "/share/info" ];
KDEDIRS = [ "" ];
- STRIGI_PLUGIN_PATH = [ "/lib/strigi/" ];
QT_PLUGIN_PATH = [ "/lib/qt4/plugins" "/lib/kde4/plugins" ];
QTWEBKIT_PLUGIN_PATH = [ "/lib/mozilla/plugins/" ];
GTK_PATH = [ "/lib/gtk-2.0" "/lib/gtk-3.0" ];
diff --git a/nixpkgs/nixos/modules/programs/freetds.nix b/nixpkgs/nixos/modules/programs/freetds.nix
index e0860a242b7..b4b657e391b 100644
--- a/nixpkgs/nixos/modules/programs/freetds.nix
+++ b/nixpkgs/nixos/modules/programs/freetds.nix
@@ -25,7 +25,7 @@ in
''';
}
'';
- description =
+ description =
''
Configure freetds database entries. Each attribute denotes
a section within freetds.conf, and the value (a string) is the config
@@ -47,7 +47,7 @@ in
environment.variables.FREETDS = "/etc/freetds.conf";
environment.variables.SYBASE = "${pkgs.freetds}";
- environment.etc."freetds.conf" = { text =
+ environment.etc."freetds.conf" = { text =
(concatStrings (mapAttrsToList (name: value:
''
[${name}]
diff --git a/nixpkgs/nixos/modules/programs/gpaste.nix b/nixpkgs/nixos/modules/programs/gpaste.nix
index 4f6deb77e5e..8bc52c28d81 100644
--- a/nixpkgs/nixos/modules/programs/gpaste.nix
+++ b/nixpkgs/nixos/modules/programs/gpaste.nix
@@ -30,5 +30,7 @@ with lib;
environment.systemPackages = [ pkgs.gnome3.gpaste ];
services.dbus.packages = [ pkgs.gnome3.gpaste ];
systemd.packages = [ pkgs.gnome3.gpaste ];
+ # gnome-control-center crashes in Keyboard Shortcuts pane without the GSettings schemas.
+ services.xserver.desktopManager.gnome3.sessionPath = [ pkgs.gnome3.gpaste ];
};
}
diff --git a/nixpkgs/nixos/modules/programs/nm-applet.nix b/nixpkgs/nixos/modules/programs/nm-applet.nix
index 273a6dec59a..5bcee30125b 100644
--- a/nixpkgs/nixos/modules/programs/nm-applet.nix
+++ b/nixpkgs/nixos/modules/programs/nm-applet.nix
@@ -5,14 +5,25 @@
maintainers = lib.teams.freedesktop.members;
};
- options.programs.nm-applet.enable = lib.mkEnableOption "nm-applet";
+ options.programs.nm-applet = {
+ enable = lib.mkEnableOption "nm-applet";
+
+ indicator = lib.mkOption {
+ type = lib.types.bool;
+ default = true;
+ description = ''
+ Whether to use indicator instead of status icon.
+ It is needed for Appindicator environments, like Enlightenment.
+ '';
+ };
+ };
config = lib.mkIf config.programs.nm-applet.enable {
systemd.user.services.nm-applet = {
description = "Network manager applet";
wantedBy = [ "graphical-session.target" ];
partOf = [ "graphical-session.target" ];
- serviceConfig.ExecStart = "${pkgs.networkmanagerapplet}/bin/nm-applet";
+ serviceConfig.ExecStart = "${pkgs.networkmanagerapplet}/bin/nm-applet ${lib.optionalString config.programs.nm-applet.indicator "--indicator"}";
};
services.dbus.packages = [ pkgs.gcr ];
diff --git a/nixpkgs/nixos/modules/programs/qt5ct.nix b/nixpkgs/nixos/modules/programs/qt5ct.nix
index aeb7fc50849..3f2bcf62283 100644
--- a/nixpkgs/nixos/modules/programs/qt5ct.nix
+++ b/nixpkgs/nixos/modules/programs/qt5ct.nix
@@ -26,6 +26,6 @@ with lib;
###### implementation
config = mkIf config.programs.qt5ct.enable {
environment.variables.QT_QPA_PLATFORMTHEME = "qt5ct";
- environment.systemPackages = with pkgs; [ qt5ct libsForQt5.qtstyleplugins ];
+ environment.systemPackages = with pkgs; [ qt5ct ];
};
}
diff --git a/nixpkgs/nixos/modules/programs/ssh.nix b/nixpkgs/nixos/modules/programs/ssh.nix
index a983ffa4b89..40af4d0ff5a 100644
--- a/nixpkgs/nixos/modules/programs/ssh.nix
+++ b/nixpkgs/nixos/modules/programs/ssh.nix
@@ -131,7 +131,7 @@ in
knownHosts = mkOption {
default = {};
- type = types.loaOf (types.submodule ({ name, ... }: {
+ type = types.attrsOf (types.submodule ({ name, ... }: {
options = {
certAuthority = mkOption {
type = types.bool;
diff --git a/nixpkgs/nixos/modules/programs/tsm-client.nix b/nixpkgs/nixos/modules/programs/tsm-client.nix
index eb6f1247528..7ac4086d5f0 100644
--- a/nixpkgs/nixos/modules/programs/tsm-client.nix
+++ b/nixpkgs/nixos/modules/programs/tsm-client.nix
@@ -7,7 +7,7 @@ let
inherit (lib.modules) mkDefault mkIf;
inherit (lib.options) literalExample mkEnableOption mkOption;
inherit (lib.strings) concatStringsSep optionalString toLower;
- inherit (lib.types) addCheck attrsOf lines loaOf nullOr package path port str strMatching submodule;
+ inherit (lib.types) addCheck attrsOf lines nullOr package path port str strMatching submodule;
# Checks if given list of strings contains unique
# elements when compared without considering case.
@@ -178,7 +178,7 @@ let
client system-options file "dsm.sys"
'';
servers = mkOption {
- type = loaOf (submodule [ serverOptions ]);
+ type = attrsOf (submodule [ serverOptions ]);
default = {};
example.mainTsmServer = {
server = "tsmserver.company.com";
diff --git a/nixpkgs/nixos/modules/programs/xss-lock.nix b/nixpkgs/nixos/modules/programs/xss-lock.nix
index a7ad9b89db4..83ed7138640 100644
--- a/nixpkgs/nixos/modules/programs/xss-lock.nix
+++ b/nixpkgs/nixos/modules/programs/xss-lock.nix
@@ -34,7 +34,7 @@ in
partOf = [ "graphical-session.target" ];
serviceConfig.ExecStart = with lib;
strings.concatStringsSep " " ([
- "${pkgs.xss-lock}/bin/xss-lock"
+ "${pkgs.xss-lock}/bin/xss-lock" "--session \${XDG_SESSION_ID}"
] ++ (map escapeShellArg cfg.extraOptions) ++ [
"--"
cfg.lockerCommand
diff --git a/nixpkgs/nixos/modules/programs/zsh/oh-my-zsh.xml b/nixpkgs/nixos/modules/programs/zsh/oh-my-zsh.xml
index 568c2de6557..14a7228ad9b 100644
--- a/nixpkgs/nixos/modules/programs/zsh/oh-my-zsh.xml
+++ b/nixpkgs/nixos/modules/programs/zsh/oh-my-zsh.xml
@@ -73,7 +73,7 @@
<programlisting>
{ pkgs, ... }:
{
- programs.zsh.ohMyZsh.customPkgs = with pkgs; [
+ programs.zsh.ohMyZsh.customPkgs = [
pkgs.nix-zsh-completions
# and even more...
];
diff --git a/nixpkgs/nixos/modules/rename.nix b/nixpkgs/nixos/modules/rename.nix
index cfe216d512b..fad0b40a9db 100644
--- a/nixpkgs/nixos/modules/rename.nix
+++ b/nixpkgs/nixos/modules/rename.nix
@@ -17,8 +17,13 @@ with lib;
(mkAliasOptionModule [ "environment" "checkConfigurationOptions" ] [ "_module" "check" ])
# Completely removed modules
+ (mkRemovedOptionModule [ "fonts" "fontconfig" "penultimate" ] "The corresponding package has removed from nixpkgs.")
+ (mkRemovedOptionModule [ "services" "chronos" ] "The corresponding package was removed from nixpkgs.")
+ (mkRemovedOptionModule [ "services" "deepin" ] "The corresponding packages were removed from nixpkgs.")
(mkRemovedOptionModule [ "services" "firefox" "syncserver" "user" ] "")
(mkRemovedOptionModule [ "services" "firefox" "syncserver" "group" ] "")
+ (mkRemovedOptionModule [ "services" "marathon" ] "The corresponding package was removed from nixpkgs.")
+ (mkRemovedOptionModule [ "services" "mesos" ] "The corresponding package was removed from nixpkgs.")
(mkRemovedOptionModule [ "services" "winstone" ] "The corresponding package was removed from nixpkgs.")
(mkRemovedOptionModule [ "networking" "vpnc" ] "Use environment.etc.\"vpnc/service.conf\" instead.")
(mkRemovedOptionModule [ "environment" "blcr" "enable" ] "The BLCR module has been removed")
@@ -28,6 +33,7 @@ with lib;
(mkRemovedOptionModule [ "services" "osquery" ] "The osquery module has been removed")
(mkRemovedOptionModule [ "services" "fourStore" ] "The fourStore module has been removed")
(mkRemovedOptionModule [ "services" "fourStoreEndpoint" ] "The fourStoreEndpoint module has been removed")
+ (mkRemovedOptionModule [ "services" "mathics" ] "The Mathics module has been removed")
(mkRemovedOptionModule [ "programs" "way-cooler" ] ("way-cooler is abandoned by its author: " +
"https://way-cooler.org/blog/2020/01/09/way-cooler-post-mortem.html"))
(mkRemovedOptionModule [ "services" "xserver" "multitouch" ] ''
@@ -43,6 +49,7 @@ with lib;
instead, or any other display manager in NixOS as they all support auto-login.
'')
(mkRemovedOptionModule [ "services" "dnscrypt-proxy" ] "Use services.dnscrypt-proxy2 instead")
+ (mkRemovedOptionModule [ "services" "meguca" ] "Use meguca has been removed from nixpkgs")
(mkRemovedOptionModule ["hardware" "brightnessctl" ] ''
The brightnessctl module was removed because newer versions of
brightnessctl don't require the udev rules anymore (they can use the
diff --git a/nixpkgs/nixos/modules/security/acme.nix b/nixpkgs/nixos/modules/security/acme.nix
index 1f63e7b88bd..8e67d4ff871 100644
--- a/nixpkgs/nixos/modules/security/acme.nix
+++ b/nixpkgs/nixos/modules/security/acme.nix
@@ -1,11 +1,314 @@
-{ config, lib, pkgs, ... }:
+{ config, lib, pkgs, options, ... }:
with lib;
let
-
cfg = config.security.acme;
+ # Used to calculate timer accuracy for coalescing
+ numCerts = length (builtins.attrNames cfg.certs);
+ _24hSecs = 60 * 60 * 24;
+
+ # There are many services required to make cert renewals work.
+ # They all follow a common structure:
+ # - They inherit this commonServiceConfig
+ # - They all run as the acme user
+ # - They all use BindPath and StateDirectory where possible
+ # to set up a sort of build environment in /tmp
+ # The Group can vary depending on what the user has specified in
+ # security.acme.certs.<cert>.group on some of the services.
+ commonServiceConfig = {
+ Type = "oneshot";
+ User = "acme";
+ Group = mkDefault "acme";
+ UMask = 0027;
+ StateDirectoryMode = 750;
+ ProtectSystem = "full";
+ PrivateTmp = true;
+
+ WorkingDirectory = "/tmp";
+ };
+
+ # In order to avoid race conditions creating the CA for selfsigned certs,
+ # we have a separate service which will create the necessary files.
+ selfsignCAService = {
+ description = "Generate self-signed certificate authority";
+
+ path = with pkgs; [ minica ];
+
+ unitConfig = {
+ ConditionPathExists = "!/var/lib/acme/.minica/key.pem";
+ };
+
+ serviceConfig = commonServiceConfig // {
+ StateDirectory = "acme/.minica";
+ BindPaths = "/var/lib/acme/.minica:/tmp/ca";
+ };
+
+ # Working directory will be /tmp
+ script = ''
+ minica \
+ --ca-key ca/key.pem \
+ --ca-cert ca/cert.pem \
+ --domains selfsigned.local
+
+ chmod 600 ca/*
+ '';
+ };
+
+ # Previously, all certs were owned by whatever user was configured in
+ # config.security.acme.certs.<cert>.user. Now everything is owned by and
+ # run by the acme user.
+ userMigrationService = {
+ description = "Fix owner and group of all ACME certificates";
+
+ script = with builtins; concatStringsSep "\n" (mapAttrsToList (cert: data: ''
+ for fixpath in /var/lib/acme/${escapeShellArg cert} /var/lib/acme/.lego/${escapeShellArg cert}; do
+ if [ -d "$fixpath" ]; then
+ chmod -R 750 "$fixpath"
+ chown -R acme:${data.group} "$fixpath"
+ fi
+ done
+ '') certConfigs);
+
+ # We don't want this to run every time a renewal happens
+ serviceConfig.RemainAfterExit = true;
+ };
+
+ certToConfig = cert: data: let
+ acmeServer = if data.server != null then data.server else cfg.server;
+ useDns = data.dnsProvider != null;
+ destPath = "/var/lib/acme/${cert}";
+ selfsignedDeps = optionals (cfg.preliminarySelfsigned) [ "acme-selfsigned-${cert}.service" ];
+
+ # Minica and lego have a "feature" which replaces * with _. We need
+ # to make this substitution to reference the output files from both programs.
+ # End users never see this since we rename the certs.
+ keyName = builtins.replaceStrings ["*"] ["_"] data.domain;
+
+ # FIXME when mkChangedOptionModule supports submodules, change to that.
+ # This is a workaround
+ extraDomains = data.extraDomainNames ++ (
+ optionals
+ (data.extraDomains != "_mkMergedOptionModule")
+ (builtins.attrNames data.extraDomains)
+ );
+
+ # Create hashes for cert data directories based on configuration
+ # Flags are separated to avoid collisions
+ hashData = with builtins; ''
+ ${concatStringsSep " " data.extraLegoFlags} -
+ ${concatStringsSep " " data.extraLegoRunFlags} -
+ ${concatStringsSep " " data.extraLegoRenewFlags} -
+ ${toString acmeServer} ${toString data.dnsProvider}
+ ${toString data.ocspMustStaple} ${data.keyType}
+ '';
+ mkHash = with builtins; val: substring 0 20 (hashString "sha256" val);
+ certDir = mkHash hashData;
+ domainHash = mkHash "${concatStringsSep " " extraDomains} ${data.domain}";
+ othersHash = mkHash "${toString acmeServer} ${data.keyType}";
+ accountDir = "/var/lib/acme/.lego/accounts/" + othersHash;
+
+ protocolOpts = if useDns then (
+ [ "--dns" data.dnsProvider ]
+ ++ optionals (!data.dnsPropagationCheck) [ "--dns.disable-cp" ]
+ ) else (
+ [ "--http" "--http.webroot" data.webroot ]
+ );
+
+ commonOpts = [
+ "--accept-tos" # Checking the option is covered by the assertions
+ "--path" "."
+ "-d" data.domain
+ "--email" data.email
+ "--key-type" data.keyType
+ ] ++ protocolOpts
+ ++ optionals data.ocspMustStaple [ "--must-staple" ]
+ ++ optionals (acmeServer != null) [ "--server" acmeServer ]
+ ++ concatMap (name: [ "-d" name ]) extraDomains
+ ++ data.extraLegoFlags;
+
+ runOpts = escapeShellArgs (
+ commonOpts
+ ++ [ "run" ]
+ ++ data.extraLegoRunFlags
+ );
+ renewOpts = escapeShellArgs (
+ commonOpts
+ ++ [ "renew" "--reuse-key" ]
+ ++ data.extraLegoRenewFlags
+ );
+
+ in {
+ inherit accountDir selfsignedDeps;
+
+ webroot = data.webroot;
+ group = data.group;
+
+ renewTimer = {
+ description = "Renew ACME Certificate for ${cert}";
+ wantedBy = [ "timers.target" ];
+ timerConfig = {
+ OnCalendar = cfg.renewInterval;
+ Unit = "acme-${cert}.service";
+ Persistent = "yes";
+
+ # Allow systemd to pick a convenient time within the day
+ # to run the check.
+ # This allows the coalescing of multiple timer jobs.
+ # We divide by the number of certificates so that if you
+ # have many certificates, the renewals are distributed over
+ # the course of the day to avoid rate limits.
+ AccuracySec = "${toString (_24hSecs / numCerts)}s";
+
+ # Skew randomly within the day, per https://letsencrypt.org/docs/integration-guide/.
+ RandomizedDelaySec = "24h";
+ };
+ };
+
+ selfsignService = {
+ description = "Generate self-signed certificate for ${cert}";
+ after = [ "acme-selfsigned-ca.service" "acme-fixperms.service" ];
+ requires = [ "acme-selfsigned-ca.service" "acme-fixperms.service" ];
+
+ path = with pkgs; [ minica ];
+
+ unitConfig = {
+ ConditionPathExists = "!/var/lib/acme/${cert}/key.pem";
+ };
+
+ serviceConfig = commonServiceConfig // {
+ Group = data.group;
+
+ StateDirectory = "acme/${cert}";
+
+ BindPaths = "/var/lib/acme/.minica:/tmp/ca /var/lib/acme/${cert}:/tmp/${keyName}";
+ };
+
+ # Working directory will be /tmp
+ # minica will output to a folder sharing the name of the first domain
+ # in the list, which will be ${data.domain}
+ script = ''
+ minica \
+ --ca-key ca/key.pem \
+ --ca-cert ca/cert.pem \
+ --domains ${escapeShellArg (builtins.concatStringsSep "," ([ data.domain ] ++ extraDomains))}
+
+ # Create files to match directory layout for real certificates
+ cd '${keyName}'
+ cp ../ca/cert.pem chain.pem
+ cat cert.pem chain.pem > fullchain.pem
+ cat key.pem fullchain.pem > full.pem
+
+ chmod 640 *
+
+ # Group might change between runs, re-apply it
+ chown 'acme:${data.group}' *
+ '';
+ };
+
+ renewService = {
+ description = "Renew ACME certificate for ${cert}";
+ after = [ "network.target" "network-online.target" "acme-fixperms.service" ] ++ selfsignedDeps;
+ wants = [ "network-online.target" "acme-fixperms.service" ] ++ selfsignedDeps;
+
+ # https://github.com/NixOS/nixpkgs/pull/81371#issuecomment-605526099
+ wantedBy = optionals (!config.boot.isContainer) [ "multi-user.target" ];
+
+ path = with pkgs; [ lego coreutils diffutils ];
+
+ serviceConfig = commonServiceConfig // {
+ Group = data.group;
+
+ # AccountDir dir will be created by tmpfiles to ensure correct permissions
+ # And to avoid deletion during systemctl clean
+ # acme/.lego/${cert} is listed so that it is deleted during systemctl clean
+ StateDirectory = "acme/${cert} acme/.lego/${cert} acme/.lego/${cert}/${certDir}";
+
+ # Needs to be space separated, but can't use a multiline string because that'll include newlines
+ BindPaths =
+ "${accountDir}:/tmp/accounts " +
+ "/var/lib/acme/${cert}:/tmp/out " +
+ "/var/lib/acme/.lego/${cert}/${certDir}:/tmp/certificates ";
+
+ # Only try loading the credentialsFile if the dns challenge is enabled
+ EnvironmentFile = mkIf useDns data.credentialsFile;
+
+ # Run as root (Prefixed with +)
+ ExecStartPost = "+" + (pkgs.writeShellScript "acme-postrun" ''
+ cd /var/lib/acme/${escapeShellArg cert}
+ if [ -e renewed ]; then
+ rm renewed
+ ${data.postRun}
+ fi
+ '');
+ };
+
+ # Working directory will be /tmp
+ script = ''
+ set -euo pipefail
+
+ echo '${domainHash}' > domainhash.txt
+
+ # Check if we can renew
+ if [ -e 'certificates/${keyName}.key' -a -e 'certificates/${keyName}.crt' ]; then
+
+ # When domains are updated, there's no need to do a full
+ # Lego run, but it's likely renew won't work if days is too low.
+ if [ -e certificates/domainhash.txt ] && cmp -s domainhash.txt certificates/domainhash.txt; then
+ lego ${renewOpts} --days ${toString cfg.validMinDays}
+ else
+ # Any number > 90 works, but this one is over 9000 ;-)
+ lego ${renewOpts} --days 9001
+ fi
+
+ # Otherwise do a full run
+ else
+ lego ${runOpts}
+ fi
+
+ mv domainhash.txt certificates/
+ chmod 640 certificates/*
+ chmod -R 700 accounts/*
+
+ # Group might change between runs, re-apply it
+ chown 'acme:${data.group}' certificates/*
+
+ # Copy all certs to the "real" certs directory
+ CERT='certificates/${keyName}.crt'
+ if [ -e "$CERT" ] && ! cmp -s "$CERT" out/fullchain.pem; then
+ touch out/renewed
+ echo Installing new certificate
+ cp -vp 'certificates/${keyName}.crt' out/fullchain.pem
+ cp -vp 'certificates/${keyName}.key' out/key.pem
+ cp -vp 'certificates/${keyName}.issuer.crt' out/chain.pem
+ ln -sf fullchain.pem out/cert.pem
+ cat out/key.pem out/fullchain.pem > out/full.pem
+ fi
+ '';
+ };
+ };
+
+ certConfigs = mapAttrs certToConfig cfg.certs;
+
certOpts = { name, ... }: {
options = {
+ # user option has been removed
+ user = mkOption {
+ visible = false;
+ default = "_mkRemovedOptionModule";
+ };
+
+ # allowKeysForGroup option has been removed
+ allowKeysForGroup = mkOption {
+ visible = false;
+ default = "_mkRemovedOptionModule";
+ };
+
+ # extraDomains was replaced with extraDomainNames
+ extraDomains = mkOption {
+ visible = false;
+ default = "_mkMergedOptionModule";
+ };
+
webroot = mkOption {
type = types.nullOr types.str;
default = null;
@@ -41,35 +344,19 @@ let
description = "Contact email address for the CA to be able to reach you.";
};
- user = mkOption {
- type = types.str;
- default = "root";
- description = "User running the ACME client.";
- };
-
group = mkOption {
type = types.str;
- default = "root";
+ default = "acme";
description = "Group running the ACME client.";
};
- allowKeysForGroup = mkOption {
- type = types.bool;
- default = false;
- description = ''
- Give read permissions to the specified group
- (<option>security.acme.cert.&lt;name&gt;.group</option>) to read SSL private certificates.
- '';
- };
-
postRun = mkOption {
type = types.lines;
default = "";
- example = "systemctl reload nginx.service";
+ example = "cp full.pem backup.pem";
description = ''
- Commands to run after new certificates go live. Typically
- the web server and other servers using certificates need to
- be reloaded.
+ Commands to run after new certificates go live. Note that
+ these commands run as the root user.
Executed in the same directory with the new certificate.
'';
@@ -82,18 +369,17 @@ let
description = "Directory where certificate and other state is stored.";
};
- extraDomains = mkOption {
- type = types.attrsOf (types.nullOr types.str);
- default = {};
+ extraDomainNames = mkOption {
+ type = types.listOf types.str;
+ default = [];
example = literalExample ''
- {
- "example.org" = null;
- "mydomain.org" = null;
- }
+ [
+ "example.org"
+ "mydomain.org"
+ ]
'';
description = ''
A list of extra domain names, which are included in the one certificate to be issued.
- Setting a distinct server root is deprecated and not functional in 20.03+
'';
};
@@ -150,6 +436,14 @@ let
'';
};
+ extraLegoFlags = mkOption {
+ type = types.listOf types.str;
+ default = [];
+ description = ''
+ Additional global flags to pass to all lego commands.
+ '';
+ };
+
extraLegoRenewFlags = mkOption {
type = types.listOf types.str;
default = [];
@@ -157,27 +451,19 @@ let
Additional flags to pass to lego renew.
'';
};
+
+ extraLegoRunFlags = mkOption {
+ type = types.listOf types.str;
+ default = [];
+ description = ''
+ Additional flags to pass to lego run.
+ '';
+ };
};
};
-in
-
-{
-
- ###### interface
- imports = [
- (mkRemovedOptionModule [ "security" "acme" "production" ] ''
- Use security.acme.server to define your staging ACME server URL instead.
+in {
- To use Let's Encrypt's staging server, use security.acme.server =
- "https://acme-staging-v02.api.letsencrypt.org/directory".
- ''
- )
- (mkRemovedOptionModule [ "security" "acme" "directory"] "ACME Directory is now hardcoded to /var/lib/acme and its permisisons are managed by systemd. See https://github.com/NixOS/nixpkgs/issues/53852 for more info.")
- (mkRemovedOptionModule [ "security" "acme" "preDelay"] "This option has been removed. If you want to make sure that something executes before certificates are provisioned, add a RequiredBy=acme-\${cert}.service to the service you want to execute before the cert renewal")
- (mkRemovedOptionModule [ "security" "acme" "activationDelay"] "This option has been removed. If you want to make sure that something executes before certificates are provisioned, add a RequiredBy=acme-\${cert}.service to the service you want to execute before the cert renewal")
- (mkChangedOptionModule [ "security" "acme" "validMin"] [ "security" "acme" "validMinDays"] (config: config.security.acme.validMin / (24 * 3600)))
- ];
options = {
security.acme = {
@@ -250,7 +536,7 @@ in
"example.com" = {
webroot = "/var/www/challenges/";
email = "foo@example.com";
- extraDomains = { "www.example.com" = null; "foo.example.com" = null; };
+ extraDomainNames = [ "www.example.com" "foo.example.com" ];
};
"bar.example.com" = {
webroot = "/var/www/challenges/";
@@ -262,25 +548,40 @@ in
};
};
- ###### implementation
+ imports = [
+ (mkRemovedOptionModule [ "security" "acme" "production" ] ''
+ Use security.acme.server to define your staging ACME server URL instead.
+
+ To use the let's encrypt staging server, use security.acme.server =
+ "https://acme-staging-v02.api.letsencrypt.org/directory".
+ ''
+ )
+ (mkRemovedOptionModule [ "security" "acme" "directory" ] "ACME Directory is now hardcoded to /var/lib/acme and its permisisons are managed by systemd. See https://github.com/NixOS/nixpkgs/issues/53852 for more info.")
+ (mkRemovedOptionModule [ "security" "acme" "preDelay" ] "This option has been removed. If you want to make sure that something executes before certificates are provisioned, add a RequiredBy=acme-\${cert}.service to the service you want to execute before the cert renewal")
+ (mkRemovedOptionModule [ "security" "acme" "activationDelay" ] "This option has been removed. If you want to make sure that something executes before certificates are provisioned, add a RequiredBy=acme-\${cert}.service to the service you want to execute before the cert renewal")
+ (mkChangedOptionModule [ "security" "acme" "validMin" ] [ "security" "acme" "validMinDays" ] (config: config.security.acme.validMin / (24 * 3600)))
+ ];
+
config = mkMerge [
(mkIf (cfg.certs != { }) {
+ # FIXME Most of these custom warnings and filters for security.acme.certs.* are required
+ # because using mkRemovedOptionModule/mkChangedOptionModule with attrsets isn't possible.
+ warnings = filter (w: w != "") (mapAttrsToList (cert: data: if data.extraDomains != "_mkMergedOptionModule" then ''
+ The option definition `security.acme.certs.${cert}.extraDomains` has changed
+ to `security.acme.certs.${cert}.extraDomainNames` and is now a list of strings.
+ Setting a custom webroot for extra domains is not possible, instead use separate certs.
+ '' else "") cfg.certs);
+
assertions = let
- certs = (mapAttrsToList (k: v: v) cfg.certs);
+ certs = attrValues cfg.certs;
in [
{
- assertion = all (certOpts: certOpts.dnsProvider == null || certOpts.webroot == null) certs;
- message = ''
- Options `security.acme.certs.<name>.dnsProvider` and
- `security.acme.certs.<name>.webroot` are mutually exclusive.
- '';
- }
- {
assertion = cfg.email != null || all (certOpts: certOpts.email != null) certs;
message = ''
You must define `security.acme.certs.<name>.email` or
- `security.acme.email` to register with the CA.
+ `security.acme.email` to register with the CA. Note that using
+ many different addresses for certs may trigger account rate limits.
'';
}
{
@@ -291,183 +592,78 @@ in
to `true`. For Let's Encrypt's ToS see https://letsencrypt.org/repository/
'';
}
- ];
-
- systemd.services = let
- services = concatLists servicesLists;
- servicesLists = mapAttrsToList certToServices cfg.certs;
- certToServices = cert: data:
- let
- # StateDirectory must be relative, and will be created under /var/lib by systemd
- lpath = "acme/${cert}";
- apath = "/var/lib/${lpath}";
- spath = "/var/lib/acme/.lego/${cert}";
- keyName = builtins.replaceStrings ["*"] ["_"] data.domain;
- requestedDomains = pipe ([ data.domain ] ++ (attrNames data.extraDomains)) [
- (domains: sort builtins.lessThan domains)
- (domains: concatStringsSep "," domains)
- ];
- fileMode = if data.allowKeysForGroup then "640" else "600";
- globalOpts = [ "-d" data.domain "--email" data.email "--path" "." "--key-type" data.keyType ]
- ++ optionals (cfg.acceptTerms) [ "--accept-tos" ]
- ++ optionals (data.dnsProvider != null && !data.dnsPropagationCheck) [ "--dns.disable-cp" ]
- ++ concatLists (mapAttrsToList (name: root: [ "-d" name ]) data.extraDomains)
- ++ (if data.dnsProvider != null then [ "--dns" data.dnsProvider ] else [ "--http" "--http.webroot" data.webroot ])
- ++ optionals (cfg.server != null || data.server != null) ["--server" (if data.server == null then cfg.server else data.server)];
- certOpts = optionals data.ocspMustStaple [ "--must-staple" ];
- runOpts = escapeShellArgs (globalOpts ++ [ "run" ] ++ certOpts);
- renewOpts = escapeShellArgs (globalOpts ++
- [ "renew" "--days" (toString cfg.validMinDays) ] ++
- certOpts ++ data.extraLegoRenewFlags);
- acmeService = {
- description = "Renew ACME Certificate for ${cert}";
- path = with pkgs; [ openssl ];
- after = [ "network.target" "network-online.target" ];
- wants = [ "network-online.target" ];
- wantedBy = mkIf (!config.boot.isContainer) [ "multi-user.target" ];
- serviceConfig = {
- Type = "oneshot";
- User = data.user;
- Group = data.group;
- PrivateTmp = true;
- StateDirectory = "acme/.lego/${cert} acme/.lego/accounts ${lpath}";
- StateDirectoryMode = if data.allowKeysForGroup then "750" else "700";
- WorkingDirectory = spath;
- # Only try loading the credentialsFile if the dns challenge is enabled
- EnvironmentFile = if data.dnsProvider != null then data.credentialsFile else null;
- ExecStart = pkgs.writeScript "acme-start" ''
- #!${pkgs.runtimeShell} -e
- test -L ${spath}/accounts -o -d ${spath}/accounts || ln -s ../accounts ${spath}/accounts
- LEGO_ARGS=(${runOpts})
- if [ -e ${spath}/certificates/${keyName}.crt ]; then
- REQUESTED_DOMAINS="${requestedDomains}"
- EXISTING_DOMAINS="$(openssl x509 -in ${spath}/certificates/${keyName}.crt -noout -ext subjectAltName | tail -n1 | sed -e 's/ *DNS://g')"
- if [ "''${REQUESTED_DOMAINS}" == "''${EXISTING_DOMAINS}" ]; then
- LEGO_ARGS=(${renewOpts})
- fi
- fi
- ${pkgs.lego}/bin/lego ''${LEGO_ARGS[@]}
- '';
- ExecStartPost =
- let
- script = pkgs.writeScript "acme-post-start" ''
- #!${pkgs.runtimeShell} -e
- cd ${apath}
-
- # Test that existing cert is older than new cert
- KEY=${spath}/certificates/${keyName}.key
- KEY_CHANGED=no
- if [ -e $KEY -a $KEY -nt key.pem ]; then
- KEY_CHANGED=yes
- cp -p ${spath}/certificates/${keyName}.key key.pem
- cp -p ${spath}/certificates/${keyName}.crt fullchain.pem
- cp -p ${spath}/certificates/${keyName}.issuer.crt chain.pem
- ln -sf fullchain.pem cert.pem
- cat key.pem fullchain.pem > full.pem
- fi
-
- chmod ${fileMode} *.pem
- chown '${data.user}:${data.group}' *.pem
-
- if [ "$KEY_CHANGED" = "yes" ]; then
- : # noop in case postRun is empty
- ${data.postRun}
- fi
- '';
- in
- "+${script}";
- };
-
- };
- selfsignedService = {
- description = "Create preliminary self-signed certificate for ${cert}";
- path = [ pkgs.openssl ];
- script =
- ''
- workdir="$(mktemp -d)"
-
- # Create CA
- openssl genrsa -des3 -passout pass:xxxx -out $workdir/ca.pass.key 2048
- openssl rsa -passin pass:xxxx -in $workdir/ca.pass.key -out $workdir/ca.key
- openssl req -new -key $workdir/ca.key -out $workdir/ca.csr \
- -subj "/C=UK/ST=Warwickshire/L=Leamington/O=OrgName/OU=Security Department/CN=example.com"
- openssl x509 -req -days 1 -in $workdir/ca.csr -signkey $workdir/ca.key -out $workdir/ca.crt
-
- # Create key
- openssl genrsa -des3 -passout pass:xxxx -out $workdir/server.pass.key 2048
- openssl rsa -passin pass:xxxx -in $workdir/server.pass.key -out $workdir/server.key
- openssl req -new -key $workdir/server.key -out $workdir/server.csr \
- -subj "/C=UK/ST=Warwickshire/L=Leamington/O=OrgName/OU=IT Department/CN=example.com"
- openssl x509 -req -days 1 -in $workdir/server.csr -CA $workdir/ca.crt \
- -CAkey $workdir/ca.key -CAserial $workdir/ca.srl -CAcreateserial \
- -out $workdir/server.crt
-
- # Copy key to destination
- cp $workdir/server.key ${apath}/key.pem
-
- # Create fullchain.pem (same format as "simp_le ... -f fullchain.pem" creates)
- cat $workdir/{server.crt,ca.crt} > "${apath}/fullchain.pem"
-
- # Create full.pem for e.g. lighttpd
- cat $workdir/{server.key,server.crt,ca.crt} > "${apath}/full.pem"
-
- # Give key acme permissions
- chown '${data.user}:${data.group}' "${apath}/"{key,fullchain,full}.pem
- chmod ${fileMode} "${apath}/"{key,fullchain,full}.pem
- '';
- serviceConfig = {
- Type = "oneshot";
- PrivateTmp = true;
- StateDirectory = lpath;
- User = data.user;
- Group = data.group;
- };
- unitConfig = {
- # Do not create self-signed key when key already exists
- ConditionPathExists = "!${apath}/key.pem";
- };
- };
- in (
- [ { name = "acme-${cert}"; value = acmeService; } ]
- ++ optional cfg.preliminarySelfsigned { name = "acme-selfsigned-${cert}"; value = selfsignedService; }
- );
- servicesAttr = listToAttrs services;
- in
- servicesAttr;
-
- systemd.tmpfiles.rules =
- map (data: "d ${data.webroot}/.well-known/acme-challenge - ${data.user} ${data.group}") (filter (data: data.webroot != null) (attrValues cfg.certs));
-
- systemd.timers = let
- # Allow systemd to pick a convenient time within the day
- # to run the check.
- # This allows the coalescing of multiple timer jobs.
- # We divide by the number of certificates so that if you
- # have many certificates, the renewals are distributed over
- # the course of the day to avoid rate limits.
- numCerts = length (attrNames cfg.certs);
- _24hSecs = 60 * 60 * 24;
- AccuracySec = "${toString (_24hSecs / numCerts)}s";
- in flip mapAttrs' cfg.certs (cert: data: nameValuePair
- ("acme-${cert}")
- ({
- description = "Renew ACME Certificate for ${cert}";
- wantedBy = [ "timers.target" ];
- timerConfig = {
- OnCalendar = cfg.renewInterval;
- Unit = "acme-${cert}.service";
- Persistent = "yes";
- inherit AccuracySec;
- # Skew randomly within the day, per https://letsencrypt.org/docs/integration-guide/.
- RandomizedDelaySec = "24h";
- };
- })
- );
-
- systemd.targets.acme-selfsigned-certificates = mkIf cfg.preliminarySelfsigned {};
- systemd.targets.acme-certificates = {};
- })
+ ] ++ (builtins.concatLists (mapAttrsToList (cert: data: [
+ {
+ assertion = data.user == "_mkRemovedOptionModule";
+ message = ''
+ The option definition `security.acme.certs.${cert}.user' no longer has any effect; Please remove it.
+ Certificate user is now hard coded to the "acme" user. If you would
+ like another user to have access, consider adding them to the
+ "acme" group or changing security.acme.certs.${cert}.group.
+ '';
+ }
+ {
+ assertion = data.allowKeysForGroup == "_mkRemovedOptionModule";
+ message = ''
+ The option definition `security.acme.certs.${cert}.allowKeysForGroup' no longer has any effect; Please remove it.
+ All certs are readable by the configured group. If this is undesired,
+ consider changing security.acme.certs.${cert}.group to an unused group.
+ '';
+ }
+ # * in the cert value breaks building of systemd services, and makes
+ # referencing them as a user quite weird too. Best practice is to use
+ # the domain option.
+ {
+ assertion = ! hasInfix "*" cert;
+ message = ''
+ The cert option path `security.acme.certs.${cert}.dnsProvider`
+ cannot contain a * character.
+ Instead, set `security.acme.certs.${cert}.domain = "${cert}";`
+ and remove the wildcard from the path.
+ '';
+ }
+ {
+ assertion = data.dnsProvider == null || data.webroot == null;
+ message = ''
+ Options `security.acme.certs.${cert}.dnsProvider` and
+ `security.acme.certs.${cert}.webroot` are mutually exclusive.
+ '';
+ }
+ ]) cfg.certs));
+
+ users.users.acme = {
+ home = "/var/lib/acme";
+ group = "acme";
+ isSystemUser = true;
+ };
+ users.groups.acme = {};
+
+ systemd.services = {
+ "acme-fixperms" = userMigrationService;
+ } // (mapAttrs' (cert: conf: nameValuePair "acme-${cert}" conf.renewService) certConfigs)
+ // (optionalAttrs (cfg.preliminarySelfsigned) ({
+ "acme-selfsigned-ca" = selfsignCAService;
+ } // (mapAttrs' (cert: conf: nameValuePair "acme-selfsigned-${cert}" conf.selfsignService) certConfigs)));
+
+ systemd.timers = mapAttrs' (cert: conf: nameValuePair "acme-${cert}" conf.renewTimer) certConfigs;
+
+ # .lego and .lego/accounts specified to fix any incorrect permissions
+ systemd.tmpfiles.rules = [
+ "d /var/lib/acme/.lego - acme acme"
+ "d /var/lib/acme/.lego/accounts - acme acme"
+ ] ++ (unique (concatMap (conf: [
+ "d ${conf.accountDir} - acme acme"
+ ] ++ (optional (conf.webroot != null) "d ${conf.webroot}/.well-known/acme-challenge - acme ${conf.group}")
+ ) (attrValues certConfigs)));
+
+ # Create some targets which can be depended on to be "active" after cert renewals
+ systemd.targets = mapAttrs' (cert: conf: nameValuePair "acme-finished-${cert}" {
+ wantedBy = [ "default.target" ];
+ requires = [ "acme-${cert}.service" ] ++ conf.selfsignedDeps;
+ after = [ "acme-${cert}.service" ] ++ conf.selfsignedDeps;
+ }) certConfigs;
+ })
];
meta = {
diff --git a/nixpkgs/nixos/modules/security/acme.xml b/nixpkgs/nixos/modules/security/acme.xml
index f802faee974..17e94bc12fb 100644
--- a/nixpkgs/nixos/modules/security/acme.xml
+++ b/nixpkgs/nixos/modules/security/acme.xml
@@ -72,7 +72,7 @@ services.nginx = {
"foo.example.com" = {
<link linkend="opt-services.nginx.virtualHosts._name_.forceSSL">forceSSL</link> = true;
<link linkend="opt-services.nginx.virtualHosts._name_.enableACME">enableACME</link> = true;
- # All serverAliases will be added as <link linkend="opt-security.acme.certs._name_.extraDomains">extra domains</link> on the certificate.
+ # All serverAliases will be added as <link linkend="opt-security.acme.certs._name_.extraDomainNames">extra domain names</link> on the certificate.
<link linkend="opt-services.nginx.virtualHosts._name_.serverAliases">serverAliases</link> = [ "bar.example.com" ];
locations."/" = {
<link linkend="opt-services.nginx.virtualHosts._name_.locations._name_.root">root</link> = "/var/www";
@@ -80,8 +80,8 @@ services.nginx = {
};
# We can also add a different vhost and reuse the same certificate
- # but we have to append extraDomains manually.
- <link linkend="opt-security.acme.certs._name_.extraDomains">security.acme.certs."foo.example.com".extraDomains."baz.example.com"</link> = null;
+ # but we have to append extraDomainNames manually.
+ <link linkend="opt-security.acme.certs._name_.extraDomainNames">security.acme.certs."foo.example.com".extraDomainNames</link> = [ "baz.example.com" ];
"baz.example.com" = {
<link linkend="opt-services.nginx.virtualHosts._name_.forceSSL">forceSSL</link> = true;
<link linkend="opt-services.nginx.virtualHosts._name_.useACMEHost">useACMEHost</link> = "foo.example.com";
@@ -165,7 +165,7 @@ services.httpd = {
# Since we have a wildcard vhost to handle port 80,
# we can generate certs for anything!
# Just make sure your DNS resolves them.
- <link linkend="opt-security.acme.certs._name_.extraDomains">extraDomains</link> = [ "mail.example.com" ];
+ <link linkend="opt-security.acme.certs._name_.extraDomainNames">extraDomainNames</link> = [ "mail.example.com" ];
};
</programlisting>
@@ -251,4 +251,16 @@ chmod 400 /var/lib/secrets/certs.secret
journalctl -fu acme-example.com.service</literal> and watching its log output.
</para>
</section>
+ <section xml:id="module-security-acme-regenerate">
+ <title>Regenerating certificates</title>
+
+ <para>
+ Should you need to regenerate a particular certificate in a hurry, such
+ as when a vulnerability is found in Let's Encrypt, there is now a convenient
+ mechanism for doing so. Running <literal>systemctl clean acme-example.com.service</literal>
+ will remove all certificate files for the given domain, allowing you to then
+ <literal>systemctl start acme-example.com.service</literal> to generate fresh
+ ones.
+ </para>
+ </section>
</chapter>
diff --git a/nixpkgs/nixos/modules/security/apparmor.nix b/nixpkgs/nixos/modules/security/apparmor.nix
index cfc65b347bc..2ee10454fd2 100644
--- a/nixpkgs/nixos/modules/security/apparmor.nix
+++ b/nixpkgs/nixos/modules/security/apparmor.nix
@@ -23,11 +23,17 @@ in
default = [];
description = "List of packages to be added to apparmor's include path";
};
+ parserConfig = mkOption {
+ type = types.str;
+ default = "";
+ description = "AppArmor parser configuration file content";
+ };
};
};
config = mkIf cfg.enable {
environment.systemPackages = [ pkgs.apparmor-utils ];
+ environment.etc."apparmor/parser.conf".text = cfg.parserConfig;
boot.kernelParams = [ "apparmor=1" "security=apparmor" ];
diff --git a/nixpkgs/nixos/modules/security/duosec.nix b/nixpkgs/nixos/modules/security/duosec.nix
index 71428b82f5d..c47be80b9dc 100644
--- a/nixpkgs/nixos/modules/security/duosec.nix
+++ b/nixpkgs/nixos/modules/security/duosec.nix
@@ -51,7 +51,7 @@ in
};
secretKeyFile = mkOption {
- type = types.path;
+ type = types.nullOr types.path;
default = null;
description = ''
A file containing your secret key. The security of your Duo application is tied to the security of your secret key.
diff --git a/nixpkgs/nixos/modules/security/misc.nix b/nixpkgs/nixos/modules/security/misc.nix
index 16e3bfb1419..d51dbbb77f7 100644
--- a/nixpkgs/nixos/modules/security/misc.nix
+++ b/nixpkgs/nixos/modules/security/misc.nix
@@ -27,6 +27,16 @@ with lib;
'';
};
+ security.unprivilegedUsernsClone = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ When disabled, unprivileged users will not be able to create new namespaces.
+ By default unprivileged user namespaces are disabled.
+ This option only works in a hardened profile.
+ '';
+ };
+
security.protectKernelImage = mkOption {
type = types.bool;
default = false;
@@ -115,6 +125,10 @@ with lib;
];
})
+ (mkIf config.security.unprivilegedUsernsClone {
+ boot.kernel.sysctl."kernel.unprivileged_userns_clone" = mkDefault true;
+ })
+
(mkIf config.security.protectKernelImage {
# Disable hibernation (allows replacing the running kernel)
boot.kernelParams = [ "nohibernate" ];
diff --git a/nixpkgs/nixos/modules/security/pam.nix b/nixpkgs/nixos/modules/security/pam.nix
index 565c15dec24..4141a17c507 100644
--- a/nixpkgs/nixos/modules/security/pam.nix
+++ b/nixpkgs/nixos/modules/security/pam.nix
@@ -394,7 +394,7 @@ let
"auth optional ${pkgs.pam_mount}/lib/security/pam_mount.so"}
${optionalString cfg.enableKwallet
("auth optional ${pkgs.plasma5.kwallet-pam}/lib/security/pam_kwallet5.so" +
- " kwalletd=${pkgs.libsForQt5.kwallet.bin}/bin/kwalletd5")}
+ " kwalletd=${pkgs.kdeFrameworks.kwallet.bin}/bin/kwalletd5")}
${optionalString cfg.enableGnomeKeyring
"auth optional ${pkgs.gnome3.gnome-keyring}/lib/security/pam_gnome_keyring.so"}
${optionalString cfg.googleAuthenticator.enable
@@ -471,7 +471,7 @@ let
"session optional ${pkgs.apparmor-pam}/lib/security/pam_apparmor.so order=user,group,default debug"}
${optionalString (cfg.enableKwallet)
("session optional ${pkgs.plasma5.kwallet-pam}/lib/security/pam_kwallet5.so" +
- " kwalletd=${pkgs.libsForQt5.kwallet.bin}/bin/kwalletd5")}
+ " kwalletd=${pkgs.kdeFrameworks.kwallet.bin}/bin/kwalletd5")}
${optionalString (cfg.enableGnomeKeyring)
"session optional ${pkgs.gnome3.gnome-keyring}/lib/security/pam_gnome_keyring.so auto_start"}
${optionalString (config.virtualisation.lxc.lxcfs.enable)
@@ -544,7 +544,7 @@ in
security.pam.services = mkOption {
default = [];
- type = with types; loaOf (submodule pamOpts);
+ type = with types; attrsOf (submodule pamOpts);
description =
''
This option defines the PAM services. A service typically
diff --git a/nixpkgs/nixos/modules/security/rngd.nix b/nixpkgs/nixos/modules/security/rngd.nix
index cffa1a5849f..cb885c4762d 100644
--- a/nixpkgs/nixos/modules/security/rngd.nix
+++ b/nixpkgs/nixos/modules/security/rngd.nix
@@ -10,11 +10,10 @@ in
security.rngd = {
enable = mkOption {
type = types.bool;
- default = true;
+ default = false;
description = ''
- Whether to enable the rng daemon, which adds entropy from
- hardware sources of randomness to the kernel entropy pool when
- available.
+ Whether to enable the rng daemon. Devices that the kernel recognises
+ as entropy sources are handled automatically by krngd.
'';
};
debug = mkOption {
@@ -26,12 +25,6 @@ in
};
config = mkIf cfg.enable {
- services.udev.extraRules = ''
- KERNEL=="random", TAG+="systemd"
- SUBSYSTEM=="cpu", ENV{MODALIAS}=="cpu:type:x86,*feature:*009E*", TAG+="systemd", ENV{SYSTEMD_WANTS}+="rngd.service"
- KERNEL=="hw_random", TAG+="systemd", ENV{SYSTEMD_WANTS}+="rngd.service"
- '';
-
systemd.services.rngd = {
bindsTo = [ "dev-random.device" ];
diff --git a/nixpkgs/nixos/modules/security/systemd-confinement.nix b/nixpkgs/nixos/modules/security/systemd-confinement.nix
index 0a400f1d535..2927d424a8a 100644
--- a/nixpkgs/nixos/modules/security/systemd-confinement.nix
+++ b/nixpkgs/nixos/modules/security/systemd-confinement.nix
@@ -135,7 +135,7 @@ in {
];
execPkgs = lib.concatMap (opt: let
isSet = config.serviceConfig ? ${opt};
- in lib.optional isSet config.serviceConfig.${opt}) execOpts;
+ in lib.flatten (lib.optional isSet config.serviceConfig.${opt})) execOpts;
unitAttrs = toplevelConfig.systemd.units."${name}.service";
allPkgs = lib.singleton (builtins.toJSON unitAttrs);
unitPkgs = if fullUnit then allPkgs else execPkgs;
diff --git a/nixpkgs/nixos/modules/security/tpm2.nix b/nixpkgs/nixos/modules/security/tpm2.nix
index 13804fb82cb..27f9b58c975 100644
--- a/nixpkgs/nixos/modules/security/tpm2.nix
+++ b/nixpkgs/nixos/modules/security/tpm2.nix
@@ -170,7 +170,6 @@ in {
Restart = "always";
RestartSec = 30;
BusName = "com.intel.tss2.Tabrmd";
- StandardOutput = "syslog";
ExecStart = "${cfg.abrmd.package}/bin/tpm2-abrmd";
User = "tss";
Group = "nogroup";
diff --git a/nixpkgs/nixos/modules/security/wrappers/default.nix b/nixpkgs/nixos/modules/security/wrappers/default.nix
index a0fadb018ec..2def74f8535 100644
--- a/nixpkgs/nixos/modules/security/wrappers/default.nix
+++ b/nixpkgs/nixos/modules/security/wrappers/default.nix
@@ -160,8 +160,11 @@ in
config = {
security.wrappers = {
+ # These are mount related wrappers that require the +s permission.
fusermount.source = "${pkgs.fuse}/bin/fusermount";
fusermount3.source = "${pkgs.fuse3}/bin/fusermount3";
+ mount.source = "${lib.getBin pkgs.utillinux}/bin/mount";
+ umount.source = "${lib.getBin pkgs.utillinux}/bin/umount";
};
boot.specialFileSystems.${parentWrapperDir} = {
diff --git a/nixpkgs/nixos/modules/services/audio/icecast.nix b/nixpkgs/nixos/modules/services/audio/icecast.nix
index 6a8a0f9975b..6ca20a7a108 100644
--- a/nixpkgs/nixos/modules/services/audio/icecast.nix
+++ b/nixpkgs/nixos/modules/services/audio/icecast.nix
@@ -23,7 +23,7 @@ let
<listen-socket>
<port>${toString cfg.listen.port}</port>
<bind-address>${cfg.listen.address}</bind-address>
- </listen-socket>
+ </listen-socket>
<security>
<chroot>0</chroot>
@@ -47,7 +47,7 @@ in {
enable = mkEnableOption "Icecast server";
hostname = mkOption {
- type = types.str;
+ type = types.nullOr types.str;
description = "DNS name or IP address that will be used for the stream directory lookups or possibily the playlist generation if a Host header is not provided.";
default = config.networking.domain;
};
@@ -70,7 +70,7 @@ in {
description = "Base directory used for logging.";
default = "/var/log/icecast";
};
-
+
listen = {
port = mkOption {
type = types.int;
diff --git a/nixpkgs/nixos/modules/services/audio/mpd.nix b/nixpkgs/nixos/modules/services/audio/mpd.nix
index 1d2a982ac53..ba20b1b98d9 100644
--- a/nixpkgs/nixos/modules/services/audio/mpd.nix
+++ b/nixpkgs/nixos/modules/services/audio/mpd.nix
@@ -11,6 +11,10 @@ let
cfg = config.services.mpd;
mpdConf = pkgs.writeText "mpd.conf" ''
+ # This file was automatically generated by NixOS. Edit mpd's configuration
+ # via NixOS' configuration.nix, as this file will be rewritten upon mpd's
+ # restart.
+
music_directory "${cfg.musicDirectory}"
playlist_directory "${cfg.playlistDirectory}"
${lib.optionalString (cfg.dbFile != null) ''
@@ -140,6 +144,18 @@ in {
'';
};
+ credentialsFile = mkOption {
+ type = types.path;
+ description = ''
+ Path to a file to be merged with the settings during the service startup.
+ Useful to merge a file which is better kept out of the Nix store
+ because it contains sensible data like MPD's password. Example may look like this:
+ <literal>password "myMpdPassword@read,add,control,admin"</literal>
+ '';
+ default = "/dev/null";
+ example = "/var/lib/secrets/mpd.conf";
+ };
+
fluidsynth = mkOption {
type = types.bool;
default = false;
@@ -181,7 +197,12 @@ in {
serviceConfig = {
User = "${cfg.user}";
- ExecStart = "${pkgs.mpd}/bin/mpd --no-daemon ${mpdConf}";
+ ExecStart = "${pkgs.mpd}/bin/mpd --no-daemon /etc/mpd.conf";
+ ExecStartPre = pkgs.writeScript "mpd-start-pre" ''
+ #!${pkgs.runtimeShell}
+ set -euo pipefail
+ cat ${mpdConf} ${cfg.credentialsFile} > /etc/mpd.conf
+ '';
Type = "notify";
LimitRTPRIO = 50;
LimitRTTIME = "infinity";
@@ -195,6 +216,14 @@ in {
Restart = "always";
};
};
+ environment.etc."mpd.conf" = {
+ mode = "0640";
+ group = cfg.group;
+ user = cfg.user;
+ # To be modified by the service' ExecStartPre
+ text = ''
+ '';
+ };
users.users = optionalAttrs (cfg.user == name) {
${name} = {
diff --git a/nixpkgs/nixos/modules/services/backup/bacula.nix b/nixpkgs/nixos/modules/services/backup/bacula.nix
index cef304734ae..3d69a69038a 100644
--- a/nixpkgs/nixos/modules/services/backup/bacula.nix
+++ b/nixpkgs/nixos/modules/services/backup/bacula.nix
@@ -18,7 +18,7 @@ let
Pid Directory = "/run";
${fd_cfg.extraClientConfig}
}
-
+
${concatStringsSep "\n" (mapAttrsToList (name: value: ''
Director {
Name = "${name}";
@@ -26,7 +26,7 @@ let
Monitor = "${value.monitor}";
}
'') fd_cfg.director)}
-
+
Messages {
Name = Standard;
syslog = all, !skipped, !restored
@@ -35,7 +35,7 @@ let
'';
sd_cfg = config.services.bacula-sd;
- sd_conf = pkgs.writeText "bacula-sd.conf"
+ sd_conf = pkgs.writeText "bacula-sd.conf"
''
Storage {
Name = "${sd_cfg.name}";
@@ -80,7 +80,7 @@ let
'';
dir_cfg = config.services.bacula-dir;
- dir_conf = pkgs.writeText "bacula-dir.conf"
+ dir_conf = pkgs.writeText "bacula-dir.conf"
''
Director {
Name = "${dir_cfg.name}";
@@ -125,10 +125,10 @@ let
The password is plain text. It is not generated through any special
process but as noted above, it is better to use random text for
- security reasons.
+ security reasons.
'';
};
-
+
monitor = mkOption {
default = "no";
example = "yes";
@@ -140,7 +140,7 @@ let
Please note that if this director is being used by a Monitor, we
highly recommend to set this directive to yes to avoid serious
- security problems.
+ security problems.
'';
};
};
@@ -163,7 +163,7 @@ let
type of autochanger, what you specify here can vary. This directive
is optional. See the Using AutochangersAutochangersChapter chapter of
this manual for more details of using this and the following
- autochanger directives.
+ autochanger directives.
'';
};
@@ -200,7 +200,7 @@ let
Extra configuration to be passed in Autochanger directive.
'';
example = ''
-
+
'';
};
};
@@ -222,7 +222,7 @@ let
if you are archiving to disk storage. In this case, you must supply
the full absolute path to the directory. When specifying a tape
device, it is preferable that the "non-rewind" variant of the device
- file name be given.
+ file name be given.
'';
};
@@ -290,7 +290,7 @@ in {
Whether to enable the Bacula File Daemon.
'';
};
-
+
name = mkOption {
default = "${config.networking.hostName}-fd";
description = ''
@@ -300,7 +300,7 @@ in {
Clients. This directive is required.
'';
};
-
+
port = mkOption {
default = 9102;
type = types.int;
@@ -310,7 +310,7 @@ in {
the Client resource of the Director's configuration file.
'';
};
-
+
director = mkOption {
default = {};
description = ''
@@ -349,14 +349,14 @@ in {
Whether to enable Bacula Storage Daemon.
'';
};
-
+
name = mkOption {
default = "${config.networking.hostName}-sd";
description = ''
Specifies the Name of the Storage daemon.
'';
};
-
+
port = mkOption {
default = 9103;
type = types.int;
@@ -410,7 +410,7 @@ in {
console = all
'';
};
-
+
};
services.bacula-dir = {
@@ -429,7 +429,7 @@ in {
required.
'';
};
-
+
port = mkOption {
default = 9101;
type = types.int;
@@ -442,7 +442,7 @@ in {
specify DirAddresses (N.B plural) directive.
'';
};
-
+
password = mkOption {
# TODO: required?
description = ''
diff --git a/nixpkgs/nixos/modules/services/backup/borgbackup.xml b/nixpkgs/nixos/modules/services/backup/borgbackup.xml
index bef7db608f8..a197f38ffb9 100644
--- a/nixpkgs/nixos/modules/services/backup/borgbackup.xml
+++ b/nixpkgs/nixos/modules/services/backup/borgbackup.xml
@@ -197,26 +197,8 @@ sudo borg init --encryption=repokey-blake2 \
disk failure, ransomware and theft.
</para>
<para>
- It is available as a flatpak package. To enable it you must set the
- following two configuration items.
- </para>
- <para>
- <programlisting>
-services.flatpak.enable = true ;
-# next line is needed to avoid the Error
-# Error deploying: GDBus.Error:org.freedesktop.DBus.Error.ServiceUnknown:
-services.accounts-daemon.enable = true;
- </programlisting>
- </para>
- <para>As a normal user you must first install, then run vorta using the
- following commands:
- <programlisting>
-flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
-flatpak install flathub com.borgbase.Vorta
-flatpak run --branch=stable --arch=x86_64 --command=vorta com.borgbase.Vorta
-</programlisting>
- After running <code>flatpak install</code> you can start Vorta also via
- the KDE application menu.
+ It can be installed in NixOS e.g. by adding <package>pkgs.vorta</package>
+ to <xref linkend="opt-environment.systemPackages" />.
</para>
<para>
Details about using Vorta can be found under <link
diff --git a/nixpkgs/nixos/modules/services/backup/restic.nix b/nixpkgs/nixos/modules/services/backup/restic.nix
index c38fd361d35..d869835bf07 100644
--- a/nixpkgs/nixos/modules/services/backup/restic.nix
+++ b/nixpkgs/nixos/modules/services/backup/restic.nix
@@ -55,7 +55,7 @@ in
Configuration for the rclone remote being used for backup.
See the remote's specific options under rclone's docs at
<link xlink:href="https://rclone.org/docs/"/>. When specifying
- option names, use the "config" name specified in the docs.
+ option names, use the "config" name specified in the docs.
For example, to set <literal>--b2-hard-delete</literal> for a B2
remote, use <literal>hard_delete = true</literal> in the
attribute set.
diff --git a/nixpkgs/nixos/modules/services/backup/znapzend.nix b/nixpkgs/nixos/modules/services/backup/znapzend.nix
index 8098617d11f..0ca71b413ce 100644
--- a/nixpkgs/nixos/modules/services/backup/znapzend.nix
+++ b/nixpkgs/nixos/modules/services/backup/znapzend.nix
@@ -220,7 +220,7 @@ let
};
destinations = mkOption {
- type = loaOf (destType config);
+ type = attrsOf (destType config);
description = "Additional destinations.";
default = {};
example = literalExample ''
@@ -328,7 +328,7 @@ in
};
zetup = mkOption {
- type = loaOf srcType;
+ type = attrsOf srcType;
description = "Znapzend configuration.";
default = {};
example = literalExample ''
diff --git a/nixpkgs/nixos/modules/services/cluster/kubernetes/pki.nix b/nixpkgs/nixos/modules/services/cluster/kubernetes/pki.nix
index 4275563f1a3..933ae481e96 100644
--- a/nixpkgs/nixos/modules/services/cluster/kubernetes/pki.nix
+++ b/nixpkgs/nixos/modules/services/cluster/kubernetes/pki.nix
@@ -20,7 +20,7 @@ let
size = 2048;
};
CN = top.masterAddress;
- hosts = cfg.cfsslAPIExtraSANs;
+ hosts = [top.masterAddress] ++ cfg.cfsslAPIExtraSANs;
});
cfsslAPITokenBaseName = "apitoken.secret";
@@ -228,7 +228,8 @@ in
};
private_key = cert.privateKeyOptions;
request = {
- inherit (cert) CN hosts;
+ hosts = [cert.CN] ++ cert.hosts;
+ inherit (cert) CN;
key = {
algo = "rsa";
size = 2048;
diff --git a/nixpkgs/nixos/modules/services/computing/torque/mom.nix b/nixpkgs/nixos/modules/services/computing/torque/mom.nix
index 83772539a7a..0c5f43cf3e6 100644
--- a/nixpkgs/nixos/modules/services/computing/torque/mom.nix
+++ b/nixpkgs/nixos/modules/services/computing/torque/mom.nix
@@ -60,4 +60,4 @@ in
};
};
-}
+}
diff --git a/nixpkgs/nixos/modules/services/computing/torque/server.nix b/nixpkgs/nixos/modules/services/computing/torque/server.nix
index 655d1500497..21c5a4f4672 100644
--- a/nixpkgs/nixos/modules/services/computing/torque/server.nix
+++ b/nixpkgs/nixos/modules/services/computing/torque/server.nix
@@ -93,4 +93,4 @@ in
};
};
-}
+}
diff --git a/nixpkgs/nixos/modules/services/continuous-integration/hercules-ci-agent/common.nix b/nixpkgs/nixos/modules/services/continuous-integration/hercules-ci-agent/common.nix
new file mode 100644
index 00000000000..4aed493c0fb
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/continuous-integration/hercules-ci-agent/common.nix
@@ -0,0 +1,213 @@
+/*
+
+This file is for options that NixOS and nix-darwin have in common.
+
+Platform-specific code is in the respective default.nix files.
+
+ */
+
+{ config, lib, options, pkgs, ... }:
+
+let
+ inherit (lib) mkOption mkIf types filterAttrs literalExample mkRenamedOptionModule;
+
+ cfg =
+ config.services.hercules-ci-agent;
+
+ format = pkgs.formats.toml {};
+
+ settingsModule = { config, ... }: {
+ freeformType = format.type;
+ options = {
+ baseDirectory = mkOption {
+ type = types.path;
+ default = "/var/lib/hercules-ci-agent";
+ description = ''
+ State directory (secrets, work directory, etc) for agent
+ '';
+ };
+ concurrentTasks = mkOption {
+ description = ''
+ Number of tasks to perform simultaneously, such as evaluations, derivations.
+
+ You must have a total capacity across agents of at least 2 concurrent tasks on <literal>x86_64-linux</literal>
+ to allow for import from derivation.
+ '';
+ type = types.int;
+ default = 4;
+ };
+ workDirectory = mkOption {
+ description = ''
+ The directory in which temporary subdirectories are created for task state. This includes sources for Nix evaluation.
+ '';
+ type = types.path;
+ default = config.baseDirectory + "/work";
+ defaultText = literalExample ''baseDirectory + "/work"'';
+ };
+ staticSecretsDirectory = mkOption {
+ description = ''
+ This is the default directory to look for statically configured secrets like <literal>cluster-join-token.key</literal>.
+ '';
+ type = types.path;
+ default = config.baseDirectory + "/secrets";
+ defaultText = literalExample ''baseDirectory + "/secrets"'';
+ };
+ clusterJoinTokenPath = mkOption {
+ description = ''
+ Location of the cluster-join-token.key file.
+ '';
+ type = types.path;
+ default = config.staticSecretsDirectory + "/cluster-join-token.key";
+ defaultText = literalExample ''staticSecretsDirectory + "/cluster-join-token.key"'';
+ # internal: It's a bit too detailed to show by default in the docs,
+ # but useful to define explicitly to allow reuse by other modules.
+ internal = true;
+ };
+ binaryCachesPath = mkOption {
+ description = ''
+ Location of the binary-caches.json file.
+ '';
+ type = types.path;
+ default = config.staticSecretsDirectory + "/binary-caches.json";
+ defaultText = literalExample ''staticSecretsDirectory + "/binary-caches.json"'';
+ # internal: It's a bit too detailed to show by default in the docs,
+ # but useful to define explicitly to allow reuse by other modules.
+ internal = true;
+ };
+ };
+ };
+
+ checkNix =
+ if !cfg.checkNix
+ then ""
+ else if lib.versionAtLeast config.nix.package.version "2.4.0"
+ then ""
+ else pkgs.stdenv.mkDerivation {
+ name = "hercules-ci-check-system-nix-src";
+ inherit (config.nix.package) src patches;
+ configurePhase = ":";
+ buildPhase = ''
+ echo "Checking in-memory pathInfoCache expiry"
+ if ! grep 'struct PathInfoCacheValue' src/libstore/store-api.hh >/dev/null; then
+ cat 1>&2 <<EOF
+
+ You are deploying Hercules CI Agent on a system with an incompatible
+ nix-daemon. Please
+ - either upgrade Nix to version 2.4.0 (when released),
+ - or set option services.hercules-ci-agent.patchNix = true;
+ - or set option nix.package to a build of Nix 2.3 with this patch applied:
+ https://github.com/NixOS/nix/pull/3405
+
+ The patch is required for Nix-daemon clients that expect a change in binary
+ cache contents while running, like the agent's evaluator. Without it, import
+ from derivation will fail if your cluster has more than one machine.
+ We are conservative with changes to the overall system, which is why we
+ keep changes to a minimum and why we ask for confirmation in the form of
+ services.hercules-ci-agent.patchNix = true before applying.
+
+ EOF
+ exit 1
+ fi
+ '';
+ installPhase = "touch $out";
+ };
+
+ patchedNix = lib.mkIf (!lib.versionAtLeast pkgs.nix.version "2.4.0") (
+ if lib.versionAtLeast pkgs.nix.version "2.4pre"
+ then lib.warn "Hercules CI Agent module will not patch 2.4 pre-release. Make sure it includes (equivalently) PR #3043, commit d048577909 or is no older than 2020-03-13." pkgs.nix
+ else pkgs.nix.overrideAttrs (
+ o: {
+ patches = (o.patches or []) ++ [ backportNix3398 ];
+ }
+ )
+ );
+
+ backportNix3398 = pkgs.fetchurl {
+ url = "https://raw.githubusercontent.com/hercules-ci/hercules-ci-agent/hercules-ci-agent-0.7.3/for-upstream/issue-3398-path-info-cache-ttls-backport-2.3.patch";
+ sha256 = "0jfckqjir9il2il7904yc1qyadw366y7xqzg81sp9sl3f1pw70ib";
+ };
+in
+{
+ imports = [
+ (mkRenamedOptionModule ["services" "hercules-ci-agent" "extraOptions"] ["services" "hercules-ci-agent" "settings"])
+ (mkRenamedOptionModule ["services" "hercules-ci-agent" "baseDirectory"] ["services" "hercules-ci-agent" "settings" "baseDirectory"])
+ (mkRenamedOptionModule ["services" "hercules-ci-agent" "concurrentTasks"] ["services" "hercules-ci-agent" "settings" "concurrentTasks"])
+ ];
+
+ options.services.hercules-ci-agent = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Enable to run Hercules CI Agent as a system service.
+
+ <link xlink:href="https://hercules-ci.com">Hercules CI</link> is a
+ continuous integation service that is centered around Nix.
+
+ Support is available at <link xlink:href="mailto:help@hercules-ci.com">help@hercules-ci.com</link>.
+ '';
+ };
+ patchNix = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Fix Nix 2.3 cache path metadata caching behavior. Has the effect of <literal>nix.package = patch pkgs.nix;</literal>
+
+ This option will be removed when Hercules CI Agent moves to Nix 2.4 (upcoming Nix release).
+ '';
+ };
+ checkNix = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Whether to make sure that the system's Nix (nix-daemon) is compatible.
+
+ If you set this to false, please keep up with the change log.
+ '';
+ };
+ package = mkOption {
+ description = ''
+ Package containing the bin/hercules-ci-agent executable.
+ '';
+ type = types.package;
+ default = pkgs.hercules-ci-agent;
+ defaultText = literalExample "pkgs.hercules-ci-agent";
+ };
+ settings = mkOption {
+ description = ''
+ These settings are written to the <literal>agent.toml</literal> file.
+
+ Not all settings are listed as options, can be set nonetheless.
+
+ For the exhaustive list of settings, see <link xlink:href="https://docs.hercules-ci.com/hercules-ci/reference/agent-config/"/>.
+ '';
+ type = types.submoduleWith { modules = [ settingsModule ]; };
+ };
+
+ /*
+ Internal and/or computed values.
+
+ These are written as options instead of let binding to allow sharing with
+ default.nix on both NixOS and nix-darwin.
+ */
+ tomlFile = mkOption {
+ type = types.path;
+ internal = true;
+ defaultText = "generated hercules-ci-agent.toml";
+ description = ''
+ The fully assembled config file.
+ '';
+ };
+ };
+
+ config = mkIf cfg.enable {
+ nix.extraOptions = lib.addContextFrom checkNix ''
+ # A store path that was missing at first may well have finished building,
+ # even shortly after the previous lookup. This *also* applies to the daemon.
+ narinfo-cache-negative-ttl = 0
+ '';
+ nix.package = mkIf cfg.patchNix patchedNix;
+ services.hercules-ci-agent.tomlFile =
+ format.generate "hercules-ci-agent.toml" cfg.settings;
+ };
+}
diff --git a/nixpkgs/nixos/modules/services/continuous-integration/hercules-ci-agent/default.nix b/nixpkgs/nixos/modules/services/continuous-integration/hercules-ci-agent/default.nix
new file mode 100644
index 00000000000..d2e7e8e18f9
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/continuous-integration/hercules-ci-agent/default.nix
@@ -0,0 +1,86 @@
+/*
+
+This file is for NixOS-specific options and configs.
+
+Code that is shared with nix-darwin goes in common.nix.
+
+ */
+
+{ pkgs, config, lib, ... }:
+
+let
+
+ inherit (lib) mkIf mkDefault;
+
+ cfg = config.services.hercules-ci-agent;
+
+ command = "${cfg.package}/bin/hercules-ci-agent --config ${cfg.tomlFile}";
+ testCommand = "${command} --test-configuration";
+
+in
+{
+ imports = [
+ ./common.nix
+ (lib.mkRenamedOptionModule ["services" "hercules-ci-agent" "user"] ["systemd" "services" "hercules-ci-agent" "serviceConfig" "User"])
+ ];
+
+ config = mkIf cfg.enable {
+
+ systemd.services.hercules-ci-agent = {
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network-online.target" ];
+ wants = [ "network-online.target" ];
+ path = [ config.nix.package ];
+ serviceConfig = {
+ User = "hercules-ci-agent";
+ ExecStart = command;
+ ExecStartPre = testCommand;
+ Restart = "on-failure";
+ RestartSec = 120;
+ StartLimitBurst = 30 * 1000000; # practically infinite
+ };
+ };
+
+ # Changes in the secrets do not affect the unit in any way that would cause
+ # a restart, which is currently necessary to reload the secrets.
+ systemd.paths.hercules-ci-agent-restart-files = {
+ wantedBy = [ "hercules-ci-agent.service" ];
+ pathConfig = {
+ Unit = "hercules-ci-agent-restarter.service";
+ PathChanged = [ cfg.settings.clusterJoinTokenPath cfg.settings.binaryCachesPath ];
+ };
+ };
+ systemd.services.hercules-ci-agent-restarter = {
+ serviceConfig.Type = "oneshot";
+ script = ''
+ # Wait a bit, with the effect of bundling up file changes into a single
+ # run of this script and hopefully a single restart.
+ sleep 10
+ if systemctl is-active --quiet hercules-ci-agent.service; then
+ if ${testCommand}; then
+ systemctl restart hercules-ci-agent.service
+ else
+ echo 1>&2 "WARNING: Not restarting agent because config is not valid at this time."
+ fi
+ else
+ echo 1>&2 "Not restarting hercules-ci-agent despite config file update, because it is not already active."
+ fi
+ '';
+ };
+
+ # Trusted user allows simplified configuration and better performance
+ # when operating in a cluster.
+ nix.trustedUsers = [ config.systemd.services.hercules-ci-agent.serviceConfig.User ];
+ services.hercules-ci-agent.settings.nixUserIsTrusted = true;
+
+ users.users.hercules-ci-agent = {
+ home = cfg.settings.baseDirectory;
+ createHome = true;
+ group = "hercules-ci-agent";
+ description = "Hercules CI Agent system user";
+ isSystemUser = true;
+ };
+
+ users.groups.hercules-ci-agent = {};
+ };
+}
diff --git a/nixpkgs/nixos/modules/services/databases/couchdb.nix b/nixpkgs/nixos/modules/services/databases/couchdb.nix
index 53224db1d89..f385331e878 100644
--- a/nixpkgs/nixos/modules/services/databases/couchdb.nix
+++ b/nixpkgs/nixos/modules/services/databases/couchdb.nix
@@ -11,7 +11,13 @@ let
database_dir = ${cfg.databaseDir}
uri_file = ${cfg.uriFile}
view_index_dir = ${cfg.viewIndexDir}
- '' + (if useVersion2 then
+ '' + (if cfg.adminPass != null then
+ ''
+ [admins]
+ ${cfg.adminUser} = ${cfg.adminPass}
+ '' else
+ ''
+ '') + (if useVersion2 then
''
[chttpd]
'' else
@@ -54,6 +60,23 @@ in {
'';
};
+ adminUser = mkOption {
+ type = types.str;
+ default = "admin";
+ description = ''
+ Couchdb (i.e. fauxton) account with permission for all dbs and
+ tasks.
+ '';
+ };
+
+ adminPass = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ description = ''
+ Couchdb (i.e. fauxton) account with permission for all dbs and
+ tasks.
+ '';
+ };
user = mkOption {
type = types.str;
diff --git a/nixpkgs/nixos/modules/services/databases/mysql.nix b/nixpkgs/nixos/modules/services/databases/mysql.nix
index 2e8c5b7640b..7d0a3f9afc4 100644
--- a/nixpkgs/nixos/modules/services/databases/mysql.nix
+++ b/nixpkgs/nixos/modules/services/databases/mysql.nix
@@ -6,12 +6,10 @@ let
cfg = config.services.mysql;
- mysql = cfg.package;
-
- isMariaDB = lib.getName mysql == lib.getName pkgs.mariadb;
+ isMariaDB = lib.getName cfg.package == lib.getName pkgs.mariadb;
mysqldOptions =
- "--user=${cfg.user} --datadir=${cfg.dataDir} --basedir=${mysql}";
+ "--user=${cfg.user} --datadir=${cfg.dataDir} --basedir=${cfg.package}";
settingsFile = pkgs.writeText "my.cnf" (
generators.toINI { listsAsDuplicateKeys = true; } cfg.settings +
@@ -22,7 +20,7 @@ in
{
imports = [
- (mkRemovedOptionModule [ "services" "mysql" "pidDir" ] "Don't wait for pidfiles, describe dependencies through systemd")
+ (mkRemovedOptionModule [ "services" "mysql" "pidDir" ] "Don't wait for pidfiles, describe dependencies through systemd.")
(mkRemovedOptionModule [ "services" "mysql" "rootPassword" ] "Use socket authentication or set the password outside of the nix store.")
];
@@ -46,25 +44,31 @@ in
type = types.nullOr types.str;
default = null;
example = literalExample "0.0.0.0";
- description = "Address to bind to. The default is to bind to all addresses";
+ description = "Address to bind to. The default is to bind to all addresses.";
};
port = mkOption {
type = types.int;
default = 3306;
- description = "Port of MySQL";
+ description = "Port of MySQL.";
};
user = mkOption {
type = types.str;
default = "mysql";
- description = "User account under which MySQL runs";
+ description = "User account under which MySQL runs.";
+ };
+
+ group = mkOption {
+ type = types.str;
+ default = "mysql";
+ description = "Group under which MySQL runs.";
};
dataDir = mkOption {
type = types.path;
example = "/var/lib/mysql";
- description = "Location where MySQL stores its table files";
+ description = "Location where MySQL stores its table files.";
};
configFile = mkOption {
@@ -171,7 +175,7 @@ in
initialScript = mkOption {
type = types.nullOr types.path;
default = null;
- description = "A file containing SQL statements to be executed on the first startup. Can be used for granting certain permissions on the database";
+ description = "A file containing SQL statements to be executed on the first startup. Can be used for granting certain permissions on the database.";
};
ensureDatabases = mkOption {
@@ -259,33 +263,33 @@ in
serverId = mkOption {
type = types.int;
default = 1;
- description = "Id of the MySQL server instance. This number must be unique for each instance";
+ description = "Id of the MySQL server instance. This number must be unique for each instance.";
};
masterHost = mkOption {
type = types.str;
- description = "Hostname of the MySQL master server";
+ description = "Hostname of the MySQL master server.";
};
slaveHost = mkOption {
type = types.str;
- description = "Hostname of the MySQL slave server";
+ description = "Hostname of the MySQL slave server.";
};
masterUser = mkOption {
type = types.str;
- description = "Username of the MySQL replication user";
+ description = "Username of the MySQL replication user.";
};
masterPassword = mkOption {
type = types.str;
- description = "Password of the MySQL replication user";
+ description = "Password of the MySQL replication user.";
};
masterPort = mkOption {
type = types.int;
default = 3306;
- description = "Port number on which the MySQL master server runs";
+ description = "Port number on which the MySQL master server runs.";
};
};
};
@@ -317,29 +321,33 @@ in
binlog-ignore-db = [ "information_schema" "performance_schema" "mysql" ];
})
(mkIf (!isMariaDB) {
- plugin-load-add = optional (cfg.ensureUsers != []) "auth_socket.so";
+ plugin-load-add = "auth_socket.so";
})
];
- users.users.mysql = {
- description = "MySQL server user";
- group = "mysql";
- uid = config.ids.uids.mysql;
+ users.users = optionalAttrs (cfg.user == "mysql") {
+ mysql = {
+ description = "MySQL server user";
+ group = cfg.group;
+ uid = config.ids.uids.mysql;
+ };
};
- users.groups.mysql.gid = config.ids.gids.mysql;
+ users.groups = optionalAttrs (cfg.group == "mysql") {
+ mysql.gid = config.ids.gids.mysql;
+ };
- environment.systemPackages = [mysql];
+ environment.systemPackages = [ cfg.package ];
environment.etc."my.cnf".source = cfg.configFile;
systemd.tmpfiles.rules = [
- "d '${cfg.dataDir}' 0700 ${cfg.user} mysql - -"
- "z '${cfg.dataDir}' 0700 ${cfg.user} mysql - -"
+ "d '${cfg.dataDir}' 0700 '${cfg.user}' '${cfg.group}' - -"
+ "z '${cfg.dataDir}' 0700 '${cfg.user}' '${cfg.group}' - -"
];
systemd.services.mysql = let
- hasNotify = (cfg.package == pkgs.mariadb);
+ hasNotify = isMariaDB;
in {
description = "MySQL Server";
@@ -357,125 +365,127 @@ in
preStart = if isMariaDB then ''
if ! test -e ${cfg.dataDir}/mysql; then
- ${mysql}/bin/mysql_install_db --defaults-file=/etc/my.cnf ${mysqldOptions}
+ ${cfg.package}/bin/mysql_install_db --defaults-file=/etc/my.cnf ${mysqldOptions}
touch ${cfg.dataDir}/mysql_init
fi
'' else ''
if ! test -e ${cfg.dataDir}/mysql; then
- ${mysql}/bin/mysqld --defaults-file=/etc/my.cnf ${mysqldOptions} --initialize-insecure
+ ${cfg.package}/bin/mysqld --defaults-file=/etc/my.cnf ${mysqldOptions} --initialize-insecure
touch ${cfg.dataDir}/mysql_init
fi
'';
- serviceConfig = {
- Type = if hasNotify then "notify" else "simple";
- Restart = "on-abort";
- RestartSec = "5s";
- # The last two environment variables are used for starting Galera clusters
- ExecStart = "${mysql}/bin/mysqld --defaults-file=/etc/my.cnf ${mysqldOptions} $_WSREP_NEW_CLUSTER $_WSREP_START_POSITION";
- ExecStartPost =
- let
- setupScript = pkgs.writeScript "mysql-setup" ''
- #!${pkgs.runtimeShell} -e
-
- ${optionalString (!hasNotify) ''
- # Wait until the MySQL server is available for use
- count=0
- while [ ! -e /run/mysqld/mysqld.sock ]
- do
- if [ $count -eq 30 ]
- then
- echo "Tried 30 times, giving up..."
- exit 1
- fi
-
- echo "MySQL daemon not yet started. Waiting for 1 second..."
- count=$((count++))
- sleep 1
- done
- ''}
-
- if [ -f ${cfg.dataDir}/mysql_init ]
+ postStart = let
+ # The super user account to use on *first* run of MySQL server
+ superUser = if isMariaDB then cfg.user else "root";
+ in ''
+ ${optionalString (!hasNotify) ''
+ # Wait until the MySQL server is available for use
+ count=0
+ while [ ! -e /run/mysqld/mysqld.sock ]
+ do
+ if [ $count -eq 30 ]
then
- ${concatMapStrings (database: ''
- # Create initial databases
- if ! test -e "${cfg.dataDir}/${database.name}"; then
- echo "Creating initial database: ${database.name}"
- ( echo 'create database `${database.name}`;'
-
- ${optionalString (database.schema != null) ''
- echo 'use `${database.name}`;'
-
- # TODO: this silently falls through if database.schema does not exist,
- # we should catch this somehow and exit, but can't do it here because we're in a subshell.
- if [ -f "${database.schema}" ]
- then
- cat ${database.schema}
- elif [ -d "${database.schema}" ]
- then
- cat ${database.schema}/mysql-databases/*.sql
- fi
- ''}
- ) | ${mysql}/bin/mysql -u root -N
- fi
- '') cfg.initialDatabases}
-
- ${optionalString (cfg.replication.role == "master")
- ''
- # Set up the replication master
+ echo "Tried 30 times, giving up..."
+ exit 1
+ fi
- ( echo "use mysql;"
- echo "CREATE USER '${cfg.replication.masterUser}'@'${cfg.replication.slaveHost}' IDENTIFIED WITH mysql_native_password;"
- echo "SET PASSWORD FOR '${cfg.replication.masterUser}'@'${cfg.replication.slaveHost}' = PASSWORD('${cfg.replication.masterPassword}');"
- echo "GRANT REPLICATION SLAVE ON *.* TO '${cfg.replication.masterUser}'@'${cfg.replication.slaveHost}';"
- ) | ${mysql}/bin/mysql -u root -N
+ echo "MySQL daemon not yet started. Waiting for 1 second..."
+ count=$((count++))
+ sleep 1
+ done
+ ''}
+
+ if [ -f ${cfg.dataDir}/mysql_init ]
+ then
+ # While MariaDB comes with a 'mysql' super user account since 10.4.x, MySQL does not
+ # Since we don't want to run this service as 'root' we need to ensure the account exists on first run
+ ( echo "CREATE USER IF NOT EXISTS '${cfg.user}'@'localhost' IDENTIFIED WITH ${if isMariaDB then "unix_socket" else "auth_socket"};"
+ echo "GRANT ALL PRIVILEGES ON *.* TO '${cfg.user}'@'localhost' WITH GRANT OPTION;"
+ ) | ${cfg.package}/bin/mysql -u ${superUser} -N
+
+ ${concatMapStrings (database: ''
+ # Create initial databases
+ if ! test -e "${cfg.dataDir}/${database.name}"; then
+ echo "Creating initial database: ${database.name}"
+ ( echo 'create database `${database.name}`;'
+
+ ${optionalString (database.schema != null) ''
+ echo 'use `${database.name}`;'
+
+ # TODO: this silently falls through if database.schema does not exist,
+ # we should catch this somehow and exit, but can't do it here because we're in a subshell.
+ if [ -f "${database.schema}" ]
+ then
+ cat ${database.schema}
+ elif [ -d "${database.schema}" ]
+ then
+ cat ${database.schema}/mysql-databases/*.sql
+ fi
''}
+ ) | ${cfg.package}/bin/mysql -u ${superUser} -N
+ fi
+ '') cfg.initialDatabases}
- ${optionalString (cfg.replication.role == "slave")
- ''
- # Set up the replication slave
+ ${optionalString (cfg.replication.role == "master")
+ ''
+ # Set up the replication master
- ( echo "stop slave;"
- echo "change master to master_host='${cfg.replication.masterHost}', master_user='${cfg.replication.masterUser}', master_password='${cfg.replication.masterPassword}';"
- echo "start slave;"
- ) | ${mysql}/bin/mysql -u root -N
- ''}
+ ( echo "use mysql;"
+ echo "CREATE USER '${cfg.replication.masterUser}'@'${cfg.replication.slaveHost}' IDENTIFIED WITH mysql_native_password;"
+ echo "SET PASSWORD FOR '${cfg.replication.masterUser}'@'${cfg.replication.slaveHost}' = PASSWORD('${cfg.replication.masterPassword}');"
+ echo "GRANT REPLICATION SLAVE ON *.* TO '${cfg.replication.masterUser}'@'${cfg.replication.slaveHost}';"
+ ) | ${cfg.package}/bin/mysql -u ${superUser} -N
+ ''}
- ${optionalString (cfg.initialScript != null)
- ''
- # Execute initial script
- # using toString to avoid copying the file to nix store if given as path instead of string,
- # as it might contain credentials
- cat ${toString cfg.initialScript} | ${mysql}/bin/mysql -u root -N
- ''}
+ ${optionalString (cfg.replication.role == "slave")
+ ''
+ # Set up the replication slave
- rm ${cfg.dataDir}/mysql_init
- fi
+ ( echo "stop slave;"
+ echo "change master to master_host='${cfg.replication.masterHost}', master_user='${cfg.replication.masterUser}', master_password='${cfg.replication.masterPassword}';"
+ echo "start slave;"
+ ) | ${cfg.package}/bin/mysql -u ${superUser} -N
+ ''}
- ${optionalString (cfg.ensureDatabases != []) ''
- (
- ${concatMapStrings (database: ''
- echo "CREATE DATABASE IF NOT EXISTS \`${database}\`;"
- '') cfg.ensureDatabases}
- ) | ${mysql}/bin/mysql -u root -N
+ ${optionalString (cfg.initialScript != null)
+ ''
+ # Execute initial script
+ # using toString to avoid copying the file to nix store if given as path instead of string,
+ # as it might contain credentials
+ cat ${toString cfg.initialScript} | ${cfg.package}/bin/mysql -u ${superUser} -N
''}
- ${concatMapStrings (user:
- ''
- ( echo "CREATE USER IF NOT EXISTS '${user.name}'@'localhost' IDENTIFIED WITH ${if isMariaDB then "unix_socket" else "auth_socket"};"
- ${concatStringsSep "\n" (mapAttrsToList (database: permission: ''
- echo "GRANT ${permission} ON ${database} TO '${user.name}'@'localhost';"
- '') user.ensurePermissions)}
- ) | ${mysql}/bin/mysql -u root -N
- '') cfg.ensureUsers}
- '';
- in
- # ensureDatbases & ensureUsers depends on this script being run as root
- # when the user has secured their mysql install
- "+${setupScript}";
+ rm ${cfg.dataDir}/mysql_init
+ fi
+
+ ${optionalString (cfg.ensureDatabases != []) ''
+ (
+ ${concatMapStrings (database: ''
+ echo "CREATE DATABASE IF NOT EXISTS \`${database}\`;"
+ '') cfg.ensureDatabases}
+ ) | ${cfg.package}/bin/mysql -N
+ ''}
+
+ ${concatMapStrings (user:
+ ''
+ ( echo "CREATE USER IF NOT EXISTS '${user.name}'@'localhost' IDENTIFIED WITH ${if isMariaDB then "unix_socket" else "auth_socket"};"
+ ${concatStringsSep "\n" (mapAttrsToList (database: permission: ''
+ echo "GRANT ${permission} ON ${database} TO '${user.name}'@'localhost';"
+ '') user.ensurePermissions)}
+ ) | ${cfg.package}/bin/mysql -N
+ '') cfg.ensureUsers}
+ '';
+
+ serviceConfig = {
+ Type = if hasNotify then "notify" else "simple";
+ Restart = "on-abort";
+ RestartSec = "5s";
+ # The last two environment variables are used for starting Galera clusters
+ ExecStart = "${cfg.package}/bin/mysqld --defaults-file=/etc/my.cnf ${mysqldOptions} $_WSREP_NEW_CLUSTER $_WSREP_START_POSITION";
# User and group
User = cfg.user;
- Group = "mysql";
+ Group = cfg.group;
# Runtime directory and mode
RuntimeDirectory = "mysqld";
RuntimeDirectoryMode = "0755";
diff --git a/nixpkgs/nixos/modules/services/databases/postgresql.nix b/nixpkgs/nixos/modules/services/databases/postgresql.nix
index 579b6a4d9c6..5056d50153f 100644
--- a/nixpkgs/nixos/modules/services/databases/postgresql.nix
+++ b/nixpkgs/nixos/modules/services/databases/postgresql.nix
@@ -11,23 +11,23 @@ let
then cfg.package
else cfg.package.withPackages (_: cfg.extraPlugins);
+ toStr = value:
+ if true == value then "yes"
+ else if false == value then "no"
+ else if isString value then "'${lib.replaceStrings ["'"] ["''"] value}'"
+ else toString value;
+
# The main PostgreSQL configuration file.
- configFile = pkgs.writeText "postgresql.conf"
- ''
- hba_file = '${pkgs.writeText "pg_hba.conf" cfg.authentication}'
- ident_file = '${pkgs.writeText "pg_ident.conf" cfg.identMap}'
- log_destination = 'stderr'
- log_line_prefix = '${cfg.logLinePrefix}'
- listen_addresses = '${if cfg.enableTCPIP then "*" else "localhost"}'
- port = ${toString cfg.port}
- ${cfg.extraConfig}
- '';
+ configFile = pkgs.writeText "postgresql.conf" (concatStringsSep "\n" (mapAttrsToList (n: v: "${n} = ${toStr v}") cfg.settings));
groupAccessAvailable = versionAtLeast postgresql.version "11.0";
in
{
+ imports = [
+ (mkRemovedOptionModule [ "services" "postgresql" "extraConfig" ] "Use services.postgresql.settings instead.")
+ ];
###### interface
@@ -55,9 +55,13 @@ in
dataDir = mkOption {
type = types.path;
+ defaultText = "/var/lib/postgresql/\${config.services.postgresql.package.psqlSchema}";
example = "/var/lib/postgresql/11";
description = ''
- Data directory for PostgreSQL.
+ The data directory for PostgreSQL. If left as the default value
+ this directory will automatically be created before the PostgreSQL server starts, otherwise
+ the sysadmin is responsible for ensuring the directory exists with appropriate ownership
+ and permissions.
'';
};
@@ -208,10 +212,28 @@ in
'';
};
- extraConfig = mkOption {
- type = types.lines;
- default = "";
- description = "Additional text to be appended to <filename>postgresql.conf</filename>.";
+ settings = mkOption {
+ type = with types; attrsOf (oneOf [ bool float int str ]);
+ default = {};
+ description = ''
+ PostgreSQL configuration. Refer to
+ <link xlink:href="https://www.postgresql.org/docs/11/config-setting.html#CONFIG-SETTING-CONFIGURATION-FILE"/>
+ for an overview of <literal>postgresql.conf</literal>.
+
+ <note><para>
+ String values will automatically be enclosed in single quotes. Single quotes will be
+ escaped with two single quotes as described by the upstream documentation linked above.
+ </para></note>
+ '';
+ example = literalExample ''
+ {
+ log_connections = true;
+ log_statement = "all";
+ logging_collector = true
+ log_disconnections = true
+ log_destination = lib.mkForce "syslog";
+ }
+ '';
};
recoveryConfig = mkOption {
@@ -221,14 +243,15 @@ in
Contents of the <filename>recovery.conf</filename> file.
'';
};
+
superUser = mkOption {
type = types.str;
- default= if versionAtLeast config.system.stateVersion "17.09" then "postgres" else "root";
+ default = "postgres";
internal = true;
+ readOnly = true;
description = ''
- NixOS traditionally used 'root' as superuser, most other distros use 'postgres'.
- From 17.09 we also try to follow this standard. Internal since changing this value
- would lead to breakage while setting up databases.
+ PostgreSQL superuser account to use for various operations. Internal since changing
+ this value would lead to breakage while setting up databases.
'';
};
};
@@ -240,6 +263,16 @@ in
config = mkIf cfg.enable {
+ services.postgresql.settings =
+ {
+ hba_file = "${pkgs.writeText "pg_hba.conf" cfg.authentication}";
+ ident_file = "${pkgs.writeText "pg_ident.conf" cfg.identMap}";
+ log_destination = "stderr";
+ log_line_prefix = cfg.logLinePrefix;
+ listen_addresses = if cfg.enableTCPIP then "*" else "localhost";
+ port = cfg.port;
+ };
+
services.postgresql.package =
# Note: when changing the default, make it conditional on
# ‘system.stateVersion’ to maintain compatibility with existing
@@ -249,10 +282,7 @@ in
else if versionAtLeast config.system.stateVersion "16.03" then pkgs.postgresql_9_5
else throw "postgresql_9_4 was removed, please upgrade your postgresql version.");
- services.postgresql.dataDir =
- mkDefault (if versionAtLeast config.system.stateVersion "17.09"
- then "/var/lib/postgresql/${cfg.package.psqlSchema}"
- else "/var/db/postgresql");
+ services.postgresql.dataDir = mkDefault "/var/lib/postgresql/${cfg.package.psqlSchema}";
services.postgresql.authentication = mkAfter
''
@@ -291,59 +321,28 @@ in
preStart =
''
- # Create data directory.
if ! test -e ${cfg.dataDir}/PG_VERSION; then
- mkdir -m 0700 -p ${cfg.dataDir}
+ # Cleanup the data directory.
rm -f ${cfg.dataDir}/*.conf
- chown -R postgres:postgres ${cfg.dataDir}
- fi
- ''; # */
- script =
- ''
- # Initialise the database.
- if ! test -e ${cfg.dataDir}/PG_VERSION; then
+ # Initialise the database.
initdb -U ${cfg.superUser} ${concatStringsSep " " cfg.initdbArgs}
+
# See postStart!
touch "${cfg.dataDir}/.first_startup"
fi
+
ln -sfn "${configFile}" "${cfg.dataDir}/postgresql.conf"
${optionalString (cfg.recoveryConfig != null) ''
ln -sfn "${pkgs.writeText "recovery.conf" cfg.recoveryConfig}" \
"${cfg.dataDir}/recovery.conf"
''}
- ${optionalString (!groupAccessAvailable) ''
- # postgresql pre 11.0 doesn't start if state directory mode is group accessible
- chmod 0700 "${cfg.dataDir}"
- ''}
-
- exec postgres
'';
- serviceConfig =
- { ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
- User = "postgres";
- Group = "postgres";
- PermissionsStartOnly = true;
- RuntimeDirectory = "postgresql";
- Type = if versionAtLeast cfg.package.version "9.6"
- then "notify"
- else "simple";
-
- # Shut down Postgres using SIGINT ("Fast Shutdown mode"). See
- # http://www.postgresql.org/docs/current/static/server-shutdown.html
- KillSignal = "SIGINT";
- KillMode = "mixed";
-
- # Give Postgres a decent amount of time to clean up after
- # receiving systemd's SIGINT.
- TimeoutSec = 120;
- };
-
# Wait for PostgreSQL to be ready to accept connections.
postStart =
''
- PSQL="${pkgs.utillinux}/bin/runuser -u ${cfg.superUser} -- psql --port=${toString cfg.port}"
+ PSQL="psql --port=${toString cfg.port}"
while ! $PSQL -d postgres -c "" 2> /dev/null; do
if ! kill -0 "$MAINPID"; then exit 1; fi
@@ -369,6 +368,32 @@ in
'') cfg.ensureUsers}
'';
+ serviceConfig = mkMerge [
+ { ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
+ User = "postgres";
+ Group = "postgres";
+ RuntimeDirectory = "postgresql";
+ Type = if versionAtLeast cfg.package.version "9.6"
+ then "notify"
+ else "simple";
+
+ # Shut down Postgres using SIGINT ("Fast Shutdown mode"). See
+ # http://www.postgresql.org/docs/current/static/server-shutdown.html
+ KillSignal = "SIGINT";
+ KillMode = "mixed";
+
+ # Give Postgres a decent amount of time to clean up after
+ # receiving systemd's SIGINT.
+ TimeoutSec = 120;
+
+ ExecStart = "${postgresql}/bin/postgres";
+ }
+ (mkIf (cfg.dataDir == "/var/lib/postgresql/${cfg.package.psqlSchema}") {
+ StateDirectory = "postgresql postgresql/${cfg.package.psqlSchema}";
+ StateDirectoryMode = if groupAccessAvailable then "0750" else "0700";
+ })
+ ];
+
unitConfig.RequiresMountsFor = "${cfg.dataDir}";
};
diff --git a/nixpkgs/nixos/modules/services/databases/riak-cs.nix b/nixpkgs/nixos/modules/services/databases/riak-cs.nix
index 2cb204f729a..fa6ac886331 100644
--- a/nixpkgs/nixos/modules/services/databases/riak-cs.nix
+++ b/nixpkgs/nixos/modules/services/databases/riak-cs.nix
@@ -35,7 +35,7 @@ in
Name of the Erlang node.
'';
};
-
+
anonymousUserCreation = mkOption {
type = types.bool;
default = false;
diff --git a/nixpkgs/nixos/modules/services/databases/victoriametrics.nix b/nixpkgs/nixos/modules/services/databases/victoriametrics.nix
index cb6bf8508fb..0af5d2adf37 100644
--- a/nixpkgs/nixos/modules/services/databases/victoriametrics.nix
+++ b/nixpkgs/nixos/modules/services/databases/victoriametrics.nix
@@ -49,8 +49,8 @@ let cfg = config.services.victoriametrics; in
ExecStart = ''
${cfg.package}/bin/victoria-metrics \
-storageDataPath=/var/lib/victoriametrics \
- -httpListenAddr ${cfg.listenAddress}
- -retentionPeriod ${toString cfg.retentionPeriod}
+ -httpListenAddr ${cfg.listenAddress} \
+ -retentionPeriod ${toString cfg.retentionPeriod} \
${lib.escapeShellArgs cfg.extraOptions}
'';
};
diff --git a/nixpkgs/nixos/modules/services/desktops/deepin/deepin.nix b/nixpkgs/nixos/modules/services/desktops/deepin/deepin.nix
deleted file mode 100644
index f8fb73701af..00000000000
--- a/nixpkgs/nixos/modules/services/desktops/deepin/deepin.nix
+++ /dev/null
@@ -1,123 +0,0 @@
-# deepin
-
-{ config, pkgs, lib, ... }:
-
-{
-
- ###### interface
-
- options = {
-
- services.deepin.core.enable = lib.mkEnableOption "
- Basic dbus and systemd services, groups and users needed by the
- Deepin Desktop Environment.
- ";
-
- services.deepin.deepin-menu.enable = lib.mkEnableOption "
- DBus service for unified menus in Deepin Desktop Environment.
- ";
-
- services.deepin.deepin-turbo.enable = lib.mkEnableOption "
- Turbo service for the Deepin Desktop Environment. It is a daemon
- that helps to launch applications faster.
- ";
-
- };
-
-
- ###### implementation
-
- config = lib.mkMerge [
-
- (lib.mkIf config.services.deepin.core.enable {
- environment.systemPackages = [
- pkgs.deepin.dde-api
- pkgs.deepin.dde-calendar
- pkgs.deepin.dde-control-center
- pkgs.deepin.dde-daemon
- pkgs.deepin.dde-dock
- pkgs.deepin.dde-launcher
- pkgs.deepin.dde-file-manager
- pkgs.deepin.dde-session-ui
- pkgs.deepin.deepin-anything
- pkgs.deepin.deepin-image-viewer
- ];
-
- services.dbus.packages = [
- pkgs.deepin.dde-api
- pkgs.deepin.dde-calendar
- pkgs.deepin.dde-control-center
- pkgs.deepin.dde-daemon
- pkgs.deepin.dde-dock
- pkgs.deepin.dde-launcher
- pkgs.deepin.dde-file-manager
- pkgs.deepin.dde-session-ui
- pkgs.deepin.deepin-anything
- pkgs.deepin.deepin-image-viewer
- ];
-
- systemd.packages = [
- pkgs.deepin.dde-api
- pkgs.deepin.dde-daemon
- pkgs.deepin.dde-file-manager
- pkgs.deepin.deepin-anything
- ];
-
- boot.extraModulePackages = [ config.boot.kernelPackages.deepin-anything ];
-
- boot.kernelModules = [ "vfs_monitor" ];
-
- users.groups.deepin-sound-player = { };
-
- users.users.deepin-sound-player = {
- description = "Deepin sound player";
- group = "deepin-sound-player";
- isSystemUser = true;
- };
-
- users.groups.deepin-daemon = { };
-
- users.users.deepin-daemon = {
- description = "Deepin daemon user";
- group = "deepin-daemon";
- isSystemUser = true;
- };
-
- users.groups.deepin_anything_server = { };
-
- users.users.deepin_anything_server = {
- description = "Deepin Anything Server";
- group = "deepin_anything_server";
- isSystemUser = true;
- };
-
- security.pam.services.deepin-auth-keyboard.text = ''
- # original at ${pkgs.deepin.dde-daemon}/etc/pam.d/deepin-auth-keyboard
- auth [success=2 default=ignore] pam_lsass.so
- auth [success=1 default=ignore] pam_unix.so nullok_secure try_first_pass
- auth requisite pam_deny.so
- auth required pam_permit.so
- '';
-
- environment.etc = {
- "polkit-1/localauthority/10-vendor.d/com.deepin.api.device.pkla".source = "${pkgs.deepin.dde-api}/etc/polkit-1/localauthority/10-vendor.d/com.deepin.api.device.pkla";
- "polkit-1/localauthority/10-vendor.d/com.deepin.daemon.Accounts.pkla".source = "${pkgs.deepin.dde-daemon}/etc/polkit-1/localauthority/10-vendor.d/com.deepin.daemon.Accounts.pkla";
- "polkit-1/localauthority/10-vendor.d/com.deepin.daemon.Grub2.pkla".source = "${pkgs.deepin.dde-daemon}/etc/polkit-1/localauthority/10-vendor.d/com.deepin.daemon.Grub2.pkla";
- };
-
- services.deepin.deepin-menu.enable = true;
- services.deepin.deepin-turbo.enable = true;
- })
-
- (lib.mkIf config.services.deepin.deepin-menu.enable {
- services.dbus.packages = [ pkgs.deepin.deepin-menu ];
- })
-
- (lib.mkIf config.services.deepin.deepin-turbo.enable {
- environment.systemPackages = [ pkgs.deepin.deepin-turbo ];
- systemd.packages = [ pkgs.deepin.deepin-turbo ];
- })
-
- ];
-
-}
diff --git a/nixpkgs/nixos/modules/services/desktops/espanso.nix b/nixpkgs/nixos/modules/services/desktops/espanso.nix
new file mode 100644
index 00000000000..cd2eadf8816
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/desktops/espanso.nix
@@ -0,0 +1,25 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+let cfg = config.services.espanso;
+in {
+ meta = { maintainers = with lib.maintainers; [ numkem ]; };
+
+ options = {
+ services.espanso = { enable = options.mkEnableOption "Espanso"; };
+ };
+
+ config = mkIf cfg.enable {
+ systemd.user.services.espanso = {
+ description = "Espanso daemon";
+ path = with pkgs; [ espanso libnotify xclip ];
+ serviceConfig = {
+ ExecStart = "${pkgs.espanso}/bin/espanso daemon";
+ Restart = "on-failure";
+ };
+ wantedBy = [ "default.target" ];
+ };
+
+ environment.systemPackages = [ pkgs.espanso ];
+ };
+}
diff --git a/nixpkgs/nixos/modules/services/desktops/geoclue2.nix b/nixpkgs/nixos/modules/services/desktops/geoclue2.nix
index 542b2ead410..6702bd395a0 100644
--- a/nixpkgs/nixos/modules/services/desktops/geoclue2.nix
+++ b/nixpkgs/nixos/modules/services/desktops/geoclue2.nix
@@ -160,7 +160,7 @@ in
};
appConfig = mkOption {
- type = types.loaOf appConfigModule;
+ type = types.attrsOf appConfigModule;
default = {};
example = literalExample ''
"com.github.app" = {
diff --git a/nixpkgs/nixos/modules/services/development/jupyterhub/default.nix b/nixpkgs/nixos/modules/services/development/jupyterhub/default.nix
new file mode 100644
index 00000000000..f1dcab68b00
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/development/jupyterhub/default.nix
@@ -0,0 +1,190 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+ cfg = config.services.jupyterhub;
+
+ kernels = (pkgs.jupyter-kernel.create {
+ definitions = if cfg.kernels != null
+ then cfg.kernels
+ else pkgs.jupyter-kernel.default;
+ });
+
+ jupyterhubConfig = pkgs.writeText "jupyterhub_config.py" ''
+ c.JupyterHub.bind_url = "http://${cfg.host}:${toString cfg.port}"
+
+ c.JupyterHub.authenticator_class = "${cfg.authentication}"
+ c.JupyterHub.spawner_class = "${cfg.spawner}"
+
+ c.SystemdSpawner.default_url = '/lab'
+ c.SystemdSpawner.cmd = "${cfg.jupyterlabEnv}/bin/jupyterhub-singleuser"
+ c.SystemdSpawner.environment = {
+ 'JUPYTER_PATH': '${kernels}'
+ }
+
+ ${cfg.extraConfig}
+ '';
+in {
+ meta.maintainers = with maintainers; [ costrouc ];
+
+ options.services.jupyterhub = {
+ enable = mkEnableOption "Jupyterhub development server";
+
+ authentication = mkOption {
+ type = types.str;
+ default = "jupyterhub.auth.PAMAuthenticator";
+ description = ''
+ Jupyterhub authentication to use
+
+ There are many authenticators available including: oauth, pam,
+ ldap, kerberos, etc.
+ '';
+ };
+
+ spawner = mkOption {
+ type = types.str;
+ default = "systemdspawner.SystemdSpawner";
+ description = ''
+ Jupyterhub spawner to use
+
+ There are many spawners available including: local process,
+ systemd, docker, kubernetes, yarn, batch, etc.
+ '';
+ };
+
+ extraConfig = mkOption {
+ type = types.lines;
+ default = "";
+ description = ''
+ Extra contents appended to the jupyterhub configuration
+
+ Jupyterhub configuration is a normal python file using
+ Traitlets. https://jupyterhub.readthedocs.io/en/stable/getting-started/config-basics.html. The
+ base configuration of this module was designed to have sane
+ defaults for configuration but you can override anything since
+ this is a python file.
+ '';
+ example = literalExample ''
+ c.SystemdSpawner.mem_limit = '8G'
+ c.SystemdSpawner.cpu_limit = 2.0
+ '';
+ };
+
+ jupyterhubEnv = mkOption {
+ type = types.package;
+ default = (pkgs.python3.withPackages (p: with p; [
+ jupyterhub
+ jupyterhub-systemdspawner
+ ]));
+ description = ''
+ Python environment to run jupyterhub
+
+ Customizing will affect the packages available in the hub and
+ proxy. This will allow packages to be available for the
+ extraConfig that you may need. This will not normally need to
+ be changed.
+ '';
+ };
+
+ jupyterlabEnv = mkOption {
+ type = types.package;
+ default = (pkgs.python3.withPackages (p: with p; [
+ jupyterhub
+ jupyterlab
+ ]));
+ description = ''
+ Python environment to run jupyterlab
+
+ Customizing will affect the packages available in the
+ jupyterlab server and the default kernel provided. This is the
+ way to customize the jupyterlab extensions and jupyter
+ notebook extensions. This will not normally need to
+ be changed.
+ '';
+ };
+
+ kernels = mkOption {
+ type = types.nullOr (types.attrsOf(types.submodule (import ../jupyter/kernel-options.nix {
+ inherit lib;
+ })));
+
+ default = null;
+ example = literalExample ''
+ {
+ python3 = let
+ env = (pkgs.python3.withPackages (pythonPackages: with pythonPackages; [
+ ipykernel
+ pandas
+ scikitlearn
+ ]));
+ in {
+ displayName = "Python 3 for machine learning";
+ argv = [
+ "''${env.interpreter}"
+ "-m"
+ "ipykernel_launcher"
+ "-f"
+ "{connection_file}"
+ ];
+ language = "python";
+ logo32 = "''${env}/''${env.sitePackages}/ipykernel/resources/logo-32x32.png";
+ logo64 = "''${env}/''${env.sitePackages}/ipykernel/resources/logo-64x64.png";
+ };
+ }
+ '';
+ description = ''
+ Declarative kernel config
+
+ Kernels can be declared in any language that supports and has
+ the required dependencies to communicate with a jupyter server.
+ In python's case, it means that ipykernel package must always be
+ included in the list of packages of the targeted environment.
+ '';
+ };
+
+ port = mkOption {
+ type = types.port;
+ default = 8000;
+ description = ''
+ Port number Jupyterhub will be listening on
+ '';
+ };
+
+ host = mkOption {
+ type = types.str;
+ default = "0.0.0.0";
+ description = ''
+ Bind IP JupyterHub will be listening on
+ '';
+ };
+
+ stateDirectory = mkOption {
+ type = types.str;
+ default = "jupyterhub";
+ description = ''
+ Directory for jupyterhub state (token + database)
+ '';
+ };
+ };
+
+ config = mkMerge [
+ (mkIf cfg.enable {
+ systemd.services.jupyterhub = {
+ description = "Jupyterhub development server";
+
+ after = [ "network.target" ];
+ wantedBy = [ "multi-user.target" ];
+
+ serviceConfig = {
+ Restart = "always";
+ ExecStart = "${cfg.jupyterhubEnv}/bin/jupyterhub --config ${jupyterhubConfig}";
+ User = "root";
+ StateDirectory = cfg.stateDirectory;
+ WorkingDirectory = "/var/lib/${cfg.stateDirectory}";
+ };
+ };
+ })
+ ];
+}
diff --git a/nixpkgs/nixos/modules/services/development/lorri.nix b/nixpkgs/nixos/modules/services/development/lorri.nix
index c843aa56d13..fc576e4c18b 100644
--- a/nixpkgs/nixos/modules/services/development/lorri.nix
+++ b/nixpkgs/nixos/modules/services/development/lorri.nix
@@ -15,6 +15,15 @@ in {
issued by the `lorri` command.
'';
};
+ package = lib.mkOption {
+ default = pkgs.lorri;
+ type = lib.types.package;
+ description = ''
+ The lorri package to use.
+ '';
+ defaultText = lib.literalExample "pkgs.lorri";
+ example = lib.literalExample "pkgs.lorri";
+ };
};
};
@@ -34,7 +43,7 @@ in {
after = [ "lorri.socket" ];
path = with pkgs; [ config.nix.package git gnutar gzip ];
serviceConfig = {
- ExecStart = "${pkgs.lorri}/bin/lorri daemon";
+ ExecStart = "${cfg.package}/bin/lorri daemon";
PrivateTmp = true;
ProtectSystem = "strict";
ProtectHome = "read-only";
@@ -42,6 +51,6 @@ in {
};
};
- environment.systemPackages = [ pkgs.lorri ];
+ environment.systemPackages = [ cfg.package ];
};
}
diff --git a/nixpkgs/nixos/modules/services/editors/emacs.nix b/nixpkgs/nixos/modules/services/editors/emacs.nix
index d791b387665..00d9eaad9eb 100644
--- a/nixpkgs/nixos/modules/services/editors/emacs.nix
+++ b/nixpkgs/nixos/modules/services/editors/emacs.nix
@@ -15,26 +15,27 @@ let
fi
'';
-desktopApplicationFile = pkgs.writeTextFile {
- name = "emacsclient.desktop";
- destination = "/share/applications/emacsclient.desktop";
- text = ''
-[Desktop Entry]
-Name=Emacsclient
-GenericName=Text Editor
-Comment=Edit text
-MimeType=text/english;text/plain;text/x-makefile;text/x-c++hdr;text/x-c++src;text/x-chdr;text/x-csrc;text/x-java;text/x-moc;text/x-pascal;text/x-tcl;text/x-tex;application/x-shellscript;text/x-c;text/x-c++;
-Exec=emacseditor %F
-Icon=emacs
-Type=Application
-Terminal=false
-Categories=Development;TextEditor;
-StartupWMClass=Emacs
-Keywords=Text;Editor;
-'';
-};
-
-in {
+ desktopApplicationFile = pkgs.writeTextFile {
+ name = "emacsclient.desktop";
+ destination = "/share/applications/emacsclient.desktop";
+ text = ''
+ [Desktop Entry]
+ Name=Emacsclient
+ GenericName=Text Editor
+ Comment=Edit text
+ MimeType=text/english;text/plain;text/x-makefile;text/x-c++hdr;text/x-c++src;text/x-chdr;text/x-csrc;text/x-java;text/x-moc;text/x-pascal;text/x-tcl;text/x-tex;application/x-shellscript;text/x-c;text/x-c++;
+ Exec=emacseditor %F
+ Icon=emacs
+ Type=Application
+ Terminal=false
+ Categories=Development;TextEditor;
+ StartupWMClass=Emacs
+ Keywords=Text;Editor;
+ '';
+ };
+
+in
+{
options.services.emacs = {
enable = mkOption {
@@ -86,10 +87,10 @@ in {
description = "Emacs: the extensible, self-documenting text editor";
serviceConfig = {
- Type = "forking";
+ Type = "forking";
ExecStart = "${pkgs.bash}/bin/bash -c 'source ${config.system.build.setEnvironment}; exec ${cfg.package}/bin/emacs --daemon'";
- ExecStop = "${cfg.package}/bin/emacsclient --eval (kill-emacs)";
- Restart = "always";
+ ExecStop = "${cfg.package}/bin/emacsclient --eval (kill-emacs)";
+ Restart = "always";
};
} // optionalAttrs cfg.enable { wantedBy = [ "default.target" ]; };
diff --git a/nixpkgs/nixos/modules/services/editors/emacs.xml b/nixpkgs/nixos/modules/services/editors/emacs.xml
index 74c60014dce..302aa1ed7c4 100644
--- a/nixpkgs/nixos/modules/services/editors/emacs.xml
+++ b/nixpkgs/nixos/modules/services/editors/emacs.xml
@@ -53,11 +53,11 @@
<varname>emacs</varname>
</term>
<term>
- <varname>emacs25</varname>
+ <varname>emacs</varname>
</term>
<listitem>
<para>
- The latest stable version of Emacs 25 using the
+ The latest stable version of Emacs using the
<link
xlink:href="http://www.gtk.org">GTK 2</link>
widget toolkit.
@@ -66,11 +66,11 @@
</varlistentry>
<varlistentry>
<term>
- <varname>emacs25-nox</varname>
+ <varname>emacs-nox</varname>
</term>
<listitem>
<para>
- Emacs 25 built without any dependency on X11 libraries.
+ Emacs built without any dependency on X11 libraries.
</para>
</listitem>
</varlistentry>
@@ -79,11 +79,11 @@
<varname>emacsMacport</varname>
</term>
<term>
- <varname>emacs25Macport</varname>
+ <varname>emacsMacport</varname>
</term>
<listitem>
<para>
- Emacs 25 with the "Mac port" patches, providing a more native look and
+ Emacs with the "Mac port" patches, providing a more native look and
feel under macOS.
</para>
</listitem>
@@ -322,7 +322,7 @@ https://nixos.org/nixpkgs/manual/#sec-modify-via-packageOverrides
If you want, you can tweak the Emacs package itself from your
<filename>emacs.nix</filename>. For example, if you want to have a
GTK 3-based Emacs instead of the default GTK 2-based binary and remove the
- automatically generated <filename>emacs.desktop</filename> (useful is you
+ automatically generated <filename>emacs.desktop</filename> (useful if you
only use <command>emacsclient</command>), you can change your file
<filename>emacs.nix</filename> in this way:
</para>
diff --git a/nixpkgs/nixos/modules/services/games/minetest-server.nix b/nixpkgs/nixos/modules/services/games/minetest-server.nix
index 98e69c6dc0e..f52079fc1ef 100644
--- a/nixpkgs/nixos/modules/services/games/minetest-server.nix
+++ b/nixpkgs/nixos/modules/services/games/minetest-server.nix
@@ -5,12 +5,12 @@ with lib;
let
cfg = config.services.minetest-server;
flag = val: name: if val != null then "--${name} ${val} " else "";
- flags = [
- (flag cfg.gameId "gameid")
- (flag cfg.world "world")
- (flag cfg.configPath "config")
- (flag cfg.logPath "logfile")
- (flag cfg.port "port")
+ flags = [
+ (flag cfg.gameId "gameid")
+ (flag cfg.world "world")
+ (flag cfg.configPath "config")
+ (flag cfg.logPath "logfile")
+ (flag cfg.port "port")
];
in
{
@@ -26,7 +26,7 @@ in
type = types.nullOr types.str;
default = null;
description = ''
- Id of the game to use. To list available games run
+ Id of the game to use. To list available games run
`minetestserver --gameid list`.
If only one game exists, this option can be null.
@@ -59,7 +59,7 @@ in
type = types.nullOr types.path;
default = null;
description = ''
- Path to logfile for logging.
+ Path to logfile for logging.
If set to null, logging will be output to stdout which means
all output will be catched by systemd.
diff --git a/nixpkgs/nixos/modules/services/games/terraria.nix b/nixpkgs/nixos/modules/services/games/terraria.nix
index a59b74c0b4c..34c8ff137d6 100644
--- a/nixpkgs/nixos/modules/services/games/terraria.nix
+++ b/nixpkgs/nixos/modules/services/games/terraria.nix
@@ -7,7 +7,7 @@ let
worldSizeMap = { small = 1; medium = 2; large = 3; };
valFlag = name: val: optionalString (val != null) "-${name} \"${escape ["\\" "\""] (toString val)}\"";
boolFlag = name: val: optionalString val "-${name}";
- flags = [
+ flags = [
(valFlag "port" cfg.port)
(valFlag "maxPlayers" cfg.maxPlayers)
(valFlag "password" cfg.password)
@@ -25,7 +25,7 @@ let
exit 0
fi
- ${getBin pkgs.tmux}/bin/tmux -S /var/lib/terraria/terraria.sock send-keys Enter exit Enter
+ ${getBin pkgs.tmux}/bin/tmux -S ${cfg.dataDir}/terraria.sock send-keys Enter exit Enter
${getBin pkgs.coreutils}/bin/tail --pid="$1" -f /dev/null
'';
in
@@ -36,7 +36,7 @@ in
type = types.bool;
default = false;
description = ''
- If enabled, starts a Terraria server. The server can be connected to via <literal>tmux -S /var/lib/terraria/terraria.sock attach</literal>
+ If enabled, starts a Terraria server. The server can be connected to via <literal>tmux -S ${cfg.dataDir}/terraria.sock attach</literal>
for administration by users who are a part of the <literal>terraria</literal> group (use <literal>C-b d</literal> shortcut to detach again).
'';
};
@@ -111,13 +111,19 @@ in
default = false;
description = "Disables automatic Universal Plug and Play.";
};
+ dataDir = mkOption {
+ type = types.str;
+ default = "/var/lib/terraria";
+ example = "/srv/terraria";
+ description = "Path to variable state data directory for terraria.";
+ };
};
};
config = mkIf cfg.enable {
users.users.terraria = {
description = "Terraria server service user";
- home = "/var/lib/terraria";
+ home = cfg.dataDir;
createHome = true;
uid = config.ids.uids.terraria;
};
@@ -136,13 +142,13 @@ in
User = "terraria";
Type = "forking";
GuessMainPID = true;
- ExecStart = "${getBin pkgs.tmux}/bin/tmux -S /var/lib/terraria/terraria.sock new -d ${pkgs.terraria-server}/bin/TerrariaServer ${concatStringsSep " " flags}";
+ ExecStart = "${getBin pkgs.tmux}/bin/tmux -S ${cfg.dataDir}/terraria.sock new -d ${pkgs.terraria-server}/bin/TerrariaServer ${concatStringsSep " " flags}";
ExecStop = "${stopScript} $MAINPID";
};
postStart = ''
- ${pkgs.coreutils}/bin/chmod 660 /var/lib/terraria/terraria.sock
- ${pkgs.coreutils}/bin/chgrp terraria /var/lib/terraria/terraria.sock
+ ${pkgs.coreutils}/bin/chmod 660 ${cfg.dataDir}/terraria.sock
+ ${pkgs.coreutils}/bin/chgrp terraria ${cfg.dataDir}/terraria.sock
'';
};
};
diff --git a/nixpkgs/nixos/modules/services/hardware/fancontrol.nix b/nixpkgs/nixos/modules/services/hardware/fancontrol.nix
index bb4541a784d..e1ce11a5aef 100644
--- a/nixpkgs/nixos/modules/services/hardware/fancontrol.nix
+++ b/nixpkgs/nixos/modules/services/hardware/fancontrol.nix
@@ -12,7 +12,7 @@ in{
config = mkOption {
default = null;
- type = types.lines;
+ type = types.nullOr types.lines;
description = "Fancontrol configuration file content. See <citerefentry><refentrytitle>pwmconfig</refentrytitle><manvolnum>8</manvolnum></citerefentry> from the lm_sensors package.";
example = ''
# Configuration file generated by pwmconfig
diff --git a/nixpkgs/nixos/modules/services/hardware/sane_extra_backends/brscan4.nix b/nixpkgs/nixos/modules/services/hardware/sane_extra_backends/brscan4.nix
index 6f49a1ab6d4..a6afa01dd81 100644
--- a/nixpkgs/nixos/modules/services/hardware/sane_extra_backends/brscan4.nix
+++ b/nixpkgs/nixos/modules/services/hardware/sane_extra_backends/brscan4.nix
@@ -81,7 +81,7 @@ in
{ office1 = { model = "MFC-7860DW"; ip = "192.168.1.2"; };
office2 = { model = "MFC-7860DW"; nodename = "BRW0080927AFBCE"; };
};
- type = with types; loaOf (submodule netDeviceOpts);
+ type = with types; attrsOf (submodule netDeviceOpts);
description = ''
The list of network devices that will be registered against the brscan4
sane backend.
diff --git a/nixpkgs/nixos/modules/services/hardware/thinkfan.nix b/nixpkgs/nixos/modules/services/hardware/thinkfan.nix
index 7c105e99ca5..3bda61ed1a9 100644
--- a/nixpkgs/nixos/modules/services/hardware/thinkfan.nix
+++ b/nixpkgs/nixos/modules/services/hardware/thinkfan.nix
@@ -67,7 +67,7 @@ in {
type = types.bool;
default = false;
description = ''
- Whether to build thinkfan with SMART support to read temperatures
+ Whether to build thinkfan with SMART support to read temperatures
directly from hard disks.
'';
};
diff --git a/nixpkgs/nixos/modules/services/hardware/trezord.nix b/nixpkgs/nixos/modules/services/hardware/trezord.nix
index c517e9fbb2b..2594ac74371 100644
--- a/nixpkgs/nixos/modules/services/hardware/trezord.nix
+++ b/nixpkgs/nixos/modules/services/hardware/trezord.nix
@@ -10,7 +10,7 @@ in {
meta = {
doc = ./trezord.xml;
};
-
+
### interface
options = {
@@ -40,7 +40,7 @@ in {
};
};
};
-
+
### implementation
config = mkIf cfg.enable {
diff --git a/nixpkgs/nixos/modules/services/hardware/undervolt.nix b/nixpkgs/nixos/modules/services/hardware/undervolt.nix
index 828032dc573..054ffa35050 100644
--- a/nixpkgs/nixos/modules/services/hardware/undervolt.nix
+++ b/nixpkgs/nixos/modules/services/hardware/undervolt.nix
@@ -103,6 +103,17 @@ in
The temperature target on battery power in Celsius degrees.
'';
};
+
+ useTimer = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to set a timer that applies the undervolt settings every 30s.
+ This will cause spam in the journal but might be required for some
+ hardware under specific conditions.
+ Enable this if your undervolt settings don't hold.
+ '';
+ };
};
config = mkIf cfg.enable {
@@ -114,6 +125,11 @@ in
path = [ pkgs.undervolt ];
description = "Intel Undervolting Service";
+
+ # Apply undervolt on boot, nixos generation switch and resume
+ wantedBy = [ "multi-user.target" "post-resume.target" ];
+ after = [ "post-resume.target" ]; # Not sure why but it won't work without this
+
serviceConfig = {
Type = "oneshot";
Restart = "no";
@@ -121,7 +137,7 @@ in
};
};
- systemd.timers.undervolt = {
+ systemd.timers.undervolt = mkIf cfg.useTimer {
description = "Undervolt timer to ensure voltage settings are always applied";
partOf = [ "undervolt.service" ];
wantedBy = [ "multi-user.target" ];
diff --git a/nixpkgs/nixos/modules/services/logging/logrotate.nix b/nixpkgs/nixos/modules/services/logging/logrotate.nix
index 565618b27a8..7d6102b8255 100644
--- a/nixpkgs/nixos/modules/services/logging/logrotate.nix
+++ b/nixpkgs/nixos/modules/services/logging/logrotate.nix
@@ -5,54 +5,93 @@ with lib;
let
cfg = config.services.logrotate;
- pathOptions = {
+ pathOpts = {
options = {
+ enable = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Whether to enable log rotation for this path. This can be used to explicitly disable
+ logging that has been configured by NixOS.
+ '';
+ };
+
path = mkOption {
type = types.str;
- description = "The path to log files to be rotated";
+ description = ''
+ The path to log files to be rotated.
+ '';
};
+
user = mkOption {
- type = types.str;
- description = "The user account to use for rotation";
+ type = with types; nullOr str;
+ default = null;
+ description = ''
+ The user account to use for rotation.
+ '';
};
+
group = mkOption {
- type = types.str;
- description = "The group to use for rotation";
+ type = with types; nullOr str;
+ default = null;
+ description = ''
+ The group to use for rotation.
+ '';
};
+
frequency = mkOption {
- type = types.enum [
- "daily" "weekly" "monthly" "yearly"
- ];
+ type = types.enum [ "daily" "weekly" "monthly" "yearly" ];
default = "daily";
- description = "How often to rotate the logs";
+ description = ''
+ How often to rotate the logs.
+ '';
};
+
keep = mkOption {
type = types.int;
default = 20;
- description = "How many rotations to keep";
+ description = ''
+ How many rotations to keep.
+ '';
};
+
extraConfig = mkOption {
type = types.lines;
default = "";
- description = "Extra logrotate config options for this path";
+ description = ''
+ Extra logrotate config options for this path. Refer to
+ <link xlink:href="https://linux.die.net/man/8/logrotate"/> for details.
+ '';
+ };
+
+ priority = mkOption {
+ type = types.int;
+ default = 1000;
+ description = ''
+ Order of this logrotate block in relation to the others. The semantics are
+ the same as with `lib.mkOrder`. Smaller values have a greater priority.
+ '';
};
};
- };
- pathConfig = options: ''
- "${options.path}" {
- su ${options.user} ${options.group}
- ${options.frequency}
+ config.extraConfig = ''
missingok
notifempty
- rotate ${toString options.keep}
- ${options.extraConfig}
+ '';
+ };
+
+ mkConf = pathOpts: ''
+ # generated by NixOS using the `services.logrotate.paths.${pathOpts.name}` attribute set
+ "${pathOpts.path}" {
+ ${optionalString (pathOpts.user != null || pathOpts.group != null) "su ${pathOpts.user} ${pathOpts.group}"}
+ ${pathOpts.frequency}
+ rotate ${toString pathOpts.keep}
+ ${pathOpts.extraConfig}
}
'';
- configFile = pkgs.writeText "logrotate.conf" (
- (concatStringsSep "\n" ((map pathConfig cfg.paths) ++ [cfg.extraConfig]))
- );
+ paths = sortProperties (mapAttrsToList (name: pathOpts: pathOpts // { name = name; }) (filterAttrs (_: pathOpts: pathOpts.enable) cfg.paths));
+ configFile = pkgs.writeText "logrotate.conf" (concatStringsSep "\n" ((map mkConf paths) ++ [ cfg.extraConfig ]));
in
{
@@ -65,41 +104,66 @@ in
enable = mkEnableOption "the logrotate systemd service";
paths = mkOption {
- type = types.listOf (types.submodule pathOptions);
- default = [];
- description = "List of attribute sets with paths to rotate";
- example = {
- "/var/log/myapp/*.log" = {
- user = "myuser";
- group = "mygroup";
- rotate = "weekly";
- keep = 5;
- };
- };
+ type = with types; attrsOf (submodule pathOpts);
+ default = {};
+ description = ''
+ Attribute set of paths to rotate. The order each block appears in the generated configuration file
+ can be controlled by the <link linkend="opt-services.logrotate.paths._name_.priority">priority</link> option
+ using the same semantics as `lib.mkOrder`. Smaller values have a greater priority.
+ '';
+ example = literalExample ''
+ {
+ httpd = {
+ path = "/var/log/httpd/*.log";
+ user = config.services.httpd.user;
+ group = config.services.httpd.group;
+ keep = 7;
+ };
+
+ myapp = {
+ path = "/var/log/myapp/*.log";
+ user = "myuser";
+ group = "mygroup";
+ frequency = "weekly";
+ keep = 5;
+ priority = 1;
+ };
+ }
+ '';
};
extraConfig = mkOption {
default = "";
type = types.lines;
description = ''
- Extra contents to add to the logrotate config file.
- See https://linux.die.net/man/8/logrotate
+ Extra contents to append to the logrotate configuration file. Refer to
+ <link xlink:href="https://linux.die.net/man/8/logrotate"/> for details.
'';
};
};
};
config = mkIf cfg.enable {
- systemd.services.logrotate = {
- description = "Logrotate Service";
- wantedBy = [ "multi-user.target" ];
- startAt = "*-*-* *:05:00";
+ assertions = mapAttrsToList (name: pathOpts:
+ { assertion = (pathOpts.user != null) == (pathOpts.group != null);
+ message = ''
+ If either of `services.logrotate.paths.${name}.user` or `services.logrotate.paths.${name}.group` are specified then *both* must be specified.
+ '';
+ }
+ ) cfg.paths;
- serviceConfig.Restart = "no";
- serviceConfig.User = "root";
+ systemd.services.logrotate = {
+ description = "Logrotate Service";
+ wantedBy = [ "multi-user.target" ];
+ startAt = "*-*-* *:05:00";
script = ''
exec ${pkgs.logrotate}/sbin/logrotate ${configFile}
'';
+
+ serviceConfig = {
+ Restart = "no";
+ User = "root";
+ };
};
};
}
diff --git a/nixpkgs/nixos/modules/services/logging/logstash.nix b/nixpkgs/nixos/modules/services/logging/logstash.nix
index 21a83803fd8..bf92425f998 100644
--- a/nixpkgs/nixos/modules/services/logging/logstash.nix
+++ b/nixpkgs/nixos/modules/services/logging/logstash.nix
@@ -4,13 +4,9 @@ with lib;
let
cfg = config.services.logstash;
- pluginPath = lib.concatStringsSep ":" cfg.plugins;
- havePluginPath = lib.length cfg.plugins > 0;
ops = lib.optionalString;
verbosityFlag = "--log.level " + cfg.logLevel;
- pluginsPath = "--path.plugins ${pluginPath}";
-
logstashConf = pkgs.writeText "logstash.conf" ''
input {
${cfg.inputConfig}
@@ -173,7 +169,7 @@ in
ExecStart = concatStringsSep " " (filter (s: stringLength s != 0) [
"${cfg.package}/bin/logstash"
"-w ${toString cfg.filterWorkers}"
- (ops havePluginPath pluginsPath)
+ (concatMapStringsSep " " (x: "--path.plugins ${x}") cfg.plugins)
"${verbosityFlag}"
"-f ${logstashConf}"
"--path.settings ${logstashSettingsDir}"
diff --git a/nixpkgs/nixos/modules/services/mail/dovecot.nix b/nixpkgs/nixos/modules/services/mail/dovecot.nix
index 51cbcbf1cbc..c166ef68f29 100644
--- a/nixpkgs/nixos/modules/services/mail/dovecot.nix
+++ b/nixpkgs/nixos/modules/services/mail/dovecot.nix
@@ -1,4 +1,4 @@
-{ config, lib, pkgs, ... }:
+{ options, config, lib, pkgs, ... }:
with lib;
@@ -83,11 +83,11 @@ let
)
(
- optionalString (cfg.mailboxes != []) ''
+ optionalString (cfg.mailboxes != {}) ''
protocol imap {
namespace inbox {
inbox=yes
- ${concatStringsSep "\n" (map mailboxConfig cfg.mailboxes)}
+ ${concatStringsSep "\n" (map mailboxConfig (attrValues cfg.mailboxes))}
}
}
''
@@ -131,12 +131,13 @@ let
special_use = \${toString mailbox.specialUse}
'' + "}";
- mailboxes = { ... }: {
+ mailboxes = { name, ... }: {
options = {
name = mkOption {
- type = types.nullOr (types.strMatching ''[^"]+'');
+ type = types.strMatching ''[^"]+'';
example = "Spam";
- default = null;
+ default = name;
+ readOnly = true;
description = "The name of the mailbox.";
};
auto = mkOption {
@@ -335,19 +336,11 @@ in
};
mailboxes = mkOption {
- type = with types; let m = submodule mailboxes; in either (listOf m) (attrsOf m);
+ type = with types; coercedTo
+ (listOf unspecified)
+ (list: listToAttrs (map (entry: { name = entry.name; value = removeAttrs entry ["name"]; }) list))
+ (attrsOf (submodule mailboxes));
default = {};
- apply = x:
- if isList x then warn "Declaring `services.dovecot2.mailboxes' as a list is deprecated and will break eval in 21.03!" x
- else mapAttrsToList (name: value:
- if value.name != null
- then throw ''
- When specifying dovecot2 mailboxes as attributes, declaring
- a `name'-attribute is prohibited! The name ${value.name} should
- be the attribute key!
- ''
- else value // { inherit name; }
- ) x;
example = literalExample ''
{
Spam = { specialUse = "Junk"; auto = "create"; };
@@ -471,6 +464,10 @@ in
environment.systemPackages = [ dovecotPkg ];
+ warnings = mkIf (any isList options.services.dovecot2.mailboxes.definitions) [
+ "Declaring `services.dovecot2.mailboxes' as a list is deprecated and will break eval in 21.03! See the release notes for more info for migration."
+ ];
+
assertions = [
{
assertion = intersectLists cfg.protocols [ "pop3" "imap" ] != [];
diff --git a/nixpkgs/nixos/modules/services/mail/mailhog.nix b/nixpkgs/nixos/modules/services/mail/mailhog.nix
index 0f998c6d0ea..b113f4ff3de 100644
--- a/nixpkgs/nixos/modules/services/mail/mailhog.nix
+++ b/nixpkgs/nixos/modules/services/mail/mailhog.nix
@@ -4,17 +4,59 @@ with lib;
let
cfg = config.services.mailhog;
-in {
+
+ args = lib.concatStringsSep " " (
+ [
+ "-api-bind-addr :${toString cfg.apiPort}"
+ "-smtp-bind-addr :${toString cfg.smtpPort}"
+ "-ui-bind-addr :${toString cfg.uiPort}"
+ "-storage ${cfg.storage}"
+ ] ++ lib.optional (cfg.storage == "maildir")
+ "-maildir-path $STATE_DIRECTORY"
+ ++ cfg.extraArgs
+ );
+
+in
+{
###### interface
+ imports = [
+ (mkRemovedOptionModule [ "services" "mailhog" "user" ] "")
+ ];
+
options = {
services.mailhog = {
enable = mkEnableOption "MailHog";
- user = mkOption {
- type = types.str;
- default = "mailhog";
- description = "User account under which mailhog runs.";
+
+ storage = mkOption {
+ type = types.enum [ "maildir" "memory" ];
+ default = "memory";
+ description = "Store mails on disk or in memory.";
+ };
+
+ apiPort = mkOption {
+ type = types.port;
+ default = 8025;
+ description = "Port on which the API endpoint will listen.";
+ };
+
+ smtpPort = mkOption {
+ type = types.port;
+ default = 1025;
+ description = "Port on which the SMTP endpoint will listen.";
+ };
+
+ uiPort = mkOption {
+ type = types.port;
+ default = 8025;
+ description = "Port on which the HTTP UI will listen.";
+ };
+
+ extraArgs = mkOption {
+ type = types.listOf types.str;
+ default = [];
+ description = "List of additional arguments to pass to the MailHog process.";
};
};
};
@@ -24,20 +66,16 @@ in {
config = mkIf cfg.enable {
- users.users.mailhog = {
- name = cfg.user;
- description = "MailHog service user";
- isSystemUser = true;
- };
-
systemd.services.mailhog = {
- description = "MailHog service";
+ description = "MailHog - Web and API based SMTP testing";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
- Type = "simple";
- ExecStart = "${pkgs.mailhog}/bin/MailHog";
- User = cfg.user;
+ Type = "exec";
+ ExecStart = "${pkgs.mailhog}/bin/MailHog ${args}";
+ DynamicUser = true;
+ Restart = "on-failure";
+ StateDirectory = "mailhog";
};
};
};
diff --git a/nixpkgs/nixos/modules/services/mail/opendkim.nix b/nixpkgs/nixos/modules/services/mail/opendkim.nix
index eb6a426684d..9bf6f338d93 100644
--- a/nixpkgs/nixos/modules/services/mail/opendkim.nix
+++ b/nixpkgs/nixos/modules/services/mail/opendkim.nix
@@ -129,6 +129,36 @@ in {
User = cfg.user;
Group = cfg.group;
RuntimeDirectory = optional (cfg.socket == defaultSock) "opendkim";
+ StateDirectory = "opendkim";
+ StateDirectoryMode = "0700";
+ ReadWritePaths = [ cfg.keyPath ];
+
+ AmbientCapabilities = [];
+ CapabilityBoundingSet = [];
+ DevicePolicy = "closed";
+ LockPersonality = true;
+ MemoryDenyWriteExecute = true;
+ NoNewPrivileges = true;
+ PrivateDevices = true;
+ PrivateMounts = true;
+ PrivateTmp = true;
+ PrivateUsers = true;
+ ProtectClock = true;
+ ProtectControlGroups = true;
+ ProtectHome = true;
+ ProtectHostname = true;
+ ProtectKernelLogs = true;
+ ProtectKernelModules = true;
+ ProtectKernelTunables = true;
+ ProtectSystem = "strict";
+ RemoveIPC = true;
+ RestrictAddressFamilies = [ "AF_INET" "AF_INET6 AF_UNIX" ];
+ RestrictNamespaces = true;
+ RestrictRealtime = true;
+ RestrictSUIDSGID = true;
+ SystemCallArchitectures = "native";
+ SystemCallFilter = [ "@system-service" "~@privileged @resources" ];
+ UMask = "0077";
};
};
diff --git a/nixpkgs/nixos/modules/services/mail/pfix-srsd.nix b/nixpkgs/nixos/modules/services/mail/pfix-srsd.nix
index 38984f896d6..e3dbf2a014f 100644
--- a/nixpkgs/nixos/modules/services/mail/pfix-srsd.nix
+++ b/nixpkgs/nixos/modules/services/mail/pfix-srsd.nix
@@ -53,4 +53,4 @@ with lib;
};
};
};
-} \ No newline at end of file
+}
diff --git a/nixpkgs/nixos/modules/services/mail/postfix.nix b/nixpkgs/nixos/modules/services/mail/postfix.nix
index ad10ba1d909..fd4d16cdc37 100644
--- a/nixpkgs/nixos/modules/services/mail/postfix.nix
+++ b/nixpkgs/nixos/modules/services/mail/postfix.nix
@@ -25,6 +25,8 @@ let
clientRestrictions = concatStringsSep ", " (clientAccess ++ dnsBl);
+ smtpTlsSecurityLevel = if cfg.useDane then "dane" else "may";
+
mainCf = let
escape = replaceStrings ["$"] ["$$"];
mkList = items: "\n " + concatStringsSep ",\n " items;
@@ -508,6 +510,14 @@ in
'';
};
+ useDane = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Sets smtp_tls_security_level to "dane" rather than "may". See postconf(5) for details.
+ '';
+ };
+
sslCert = mkOption {
type = types.str;
default = "";
@@ -809,13 +819,13 @@ in
// optionalAttrs cfg.enableHeaderChecks { header_checks = [ "regexp:/etc/postfix/header_checks" ]; }
// optionalAttrs (cfg.tlsTrustedAuthorities != "") {
smtp_tls_CAfile = cfg.tlsTrustedAuthorities;
- smtp_tls_security_level = "may";
+ smtp_tls_security_level = smtpTlsSecurityLevel;
}
// optionalAttrs (cfg.sslCert != "") {
smtp_tls_cert_file = cfg.sslCert;
smtp_tls_key_file = cfg.sslKey;
- smtp_tls_security_level = "may";
+ smtp_tls_security_level = smtpTlsSecurityLevel;
smtpd_tls_cert_file = cfg.sslCert;
smtpd_tls_key_file = cfg.sslKey;
diff --git a/nixpkgs/nixos/modules/services/misc/beanstalkd.nix b/nixpkgs/nixos/modules/services/misc/beanstalkd.nix
index bcd133c9741..1c674a5b23b 100644
--- a/nixpkgs/nixos/modules/services/misc/beanstalkd.nix
+++ b/nixpkgs/nixos/modules/services/misc/beanstalkd.nix
@@ -28,6 +28,12 @@ in
example = "0.0.0.0";
};
};
+
+ openFirewall = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Whether to open ports in the firewall for the server.";
+ };
};
};
@@ -35,6 +41,10 @@ in
config = mkIf cfg.enable {
+ networking.firewall = mkIf cfg.openFirewall {
+ allowedTCPPorts = [ cfg.listen.port ];
+ };
+
environment.systemPackages = [ pkg ];
systemd.services.beanstalkd = {
diff --git a/nixpkgs/nixos/modules/services/misc/gammu-smsd.nix b/nixpkgs/nixos/modules/services/misc/gammu-smsd.nix
index 3057d7fd1a0..552725f1384 100644
--- a/nixpkgs/nixos/modules/services/misc/gammu-smsd.nix
+++ b/nixpkgs/nixos/modules/services/misc/gammu-smsd.nix
@@ -172,7 +172,7 @@ in {
};
database = mkOption {
- type = types.str;
+ type = types.nullOr types.str;
default = null;
description = "Database name to store sms data";
};
diff --git a/nixpkgs/nixos/modules/services/misc/gitea.nix b/nixpkgs/nixos/modules/services/misc/gitea.nix
index f8bcedc94fe..af80e99746b 100644
--- a/nixpkgs/nixos/modules/services/misc/gitea.nix
+++ b/nixpkgs/nixos/modules/services/misc/gitea.nix
@@ -162,6 +162,45 @@ in
<manvolnum>7</manvolnum></citerefentry>.
'';
};
+
+ backupDir = mkOption {
+ type = types.str;
+ default = "${cfg.stateDir}/dump";
+ description = "Path to the dump files.";
+ };
+ };
+
+ ssh = {
+ enable = mkOption {
+ type = types.bool;
+ default = true;
+ description = "Enable external SSH feature.";
+ };
+
+ clonePort = mkOption {
+ type = types.int;
+ default = 22;
+ example = 2222;
+ description = ''
+ SSH port displayed in clone URL.
+ The option is required to configure a service when the external visible port
+ differs from the local listening port i.e. if port forwarding is used.
+ '';
+ };
+ };
+
+ lfs = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Enables git-lfs support.";
+ };
+
+ contentDir = mkOption {
+ type = types.str;
+ default = "${cfg.stateDir}/data/lfs";
+ description = "Where to store LFS files.";
+ };
};
appName = mkOption {
@@ -200,6 +239,12 @@ in
description = "HTTP listen port.";
};
+ enableUnixSocket = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Configure Gitea to listen on a unix socket instead of the default TCP port.";
+ };
+
cookieSecure = mkOption {
type = types.bool;
default = false;
@@ -300,14 +345,34 @@ in
ROOT = cfg.repositoryRoot;
};
- server = {
- DOMAIN = cfg.domain;
- HTTP_ADDR = cfg.httpAddress;
- HTTP_PORT = cfg.httpPort;
- ROOT_URL = cfg.rootUrl;
- STATIC_ROOT_PATH = cfg.staticRootPath;
- LFS_JWT_SECRET = "#jwtsecret#";
- };
+ server = mkMerge [
+ {
+ DOMAIN = cfg.domain;
+ STATIC_ROOT_PATH = cfg.staticRootPath;
+ LFS_JWT_SECRET = "#jwtsecret#";
+ ROOT_URL = cfg.rootUrl;
+ }
+ (mkIf cfg.enableUnixSocket {
+ PROTOCOL = "unix";
+ HTTP_ADDR = "/run/gitea/gitea.sock";
+ })
+ (mkIf (!cfg.enableUnixSocket) {
+ HTTP_ADDR = cfg.httpAddress;
+ HTTP_PORT = cfg.httpPort;
+ })
+ (mkIf cfg.ssh.enable {
+ DISABLE_SSH = false;
+ SSH_PORT = cfg.ssh.clonePort;
+ })
+ (mkIf (!cfg.ssh.enable) {
+ DISABLE_SSH = true;
+ })
+ (mkIf cfg.lfs.enable {
+ LFS_START_SERVER = true;
+ LFS_CONTENT_PATH = cfg.lfs.contentDir;
+ })
+
+ ];
session = {
COOKIE_NAME = "session";
@@ -357,12 +422,26 @@ in
};
systemd.tmpfiles.rules = [
- "d '${cfg.stateDir}' - ${cfg.user} gitea - -"
- "d '${cfg.stateDir}/conf' - ${cfg.user} gitea - -"
- "d '${cfg.stateDir}/custom' - ${cfg.user} gitea - -"
- "d '${cfg.stateDir}/custom/conf' - ${cfg.user} gitea - -"
- "d '${cfg.stateDir}/log' - ${cfg.user} gitea - -"
- "d '${cfg.repositoryRoot}' - ${cfg.user} gitea - -"
+ "d '${cfg.dump.backupDir}' 0750 ${cfg.user} gitea - -"
+ "z '${cfg.dump.backupDir}' 0750 ${cfg.user} gitea - -"
+ "Z '${cfg.dump.backupDir}' - ${cfg.user} gitea - -"
+ "d '${cfg.lfs.contentDir}' 0750 ${cfg.user} gitea - -"
+ "z '${cfg.lfs.contentDir}' 0750 ${cfg.user} gitea - -"
+ "Z '${cfg.lfs.contentDir}' - ${cfg.user} gitea - -"
+ "d '${cfg.repositoryRoot}' 0750 ${cfg.user} gitea - -"
+ "z '${cfg.repositoryRoot}' 0750 ${cfg.user} gitea - -"
+ "Z '${cfg.repositoryRoot}' - ${cfg.user} gitea - -"
+ "d '${cfg.stateDir}' 0750 ${cfg.user} gitea - -"
+ "d '${cfg.stateDir}/conf' 0750 ${cfg.user} gitea - -"
+ "d '${cfg.stateDir}/custom' 0750 ${cfg.user} gitea - -"
+ "d '${cfg.stateDir}/custom/conf' 0750 ${cfg.user} gitea - -"
+ "d '${cfg.stateDir}/log' 0750 ${cfg.user} gitea - -"
+ "z '${cfg.stateDir}' 0750 ${cfg.user} gitea - -"
+ "z '${cfg.stateDir}/.ssh' 0700 ${cfg.user} gitea - -"
+ "z '${cfg.stateDir}/conf' 0750 ${cfg.user} gitea - -"
+ "z '${cfg.stateDir}/custom' 0750 ${cfg.user} gitea - -"
+ "z '${cfg.stateDir}/custom/conf' 0750 ${cfg.user} gitea - -"
+ "z '${cfg.stateDir}/log' 0750 ${cfg.user} gitea - -"
"Z '${cfg.stateDir}' - ${cfg.user} gitea - -"
# If we have a folder or symlink with gitea locales, remove it
@@ -431,28 +510,39 @@ in
User = cfg.user;
Group = "gitea";
WorkingDirectory = cfg.stateDir;
- ExecStart = "${gitea}/bin/gitea web";
+ ExecStart = "${gitea}/bin/gitea web --pid /run/gitea/gitea.pid";
Restart = "always";
-
- # Filesystem
+ # Runtime directory and mode
+ RuntimeDirectory = "gitea";
+ RuntimeDirectoryMode = "0755";
+ # Access write directories
+ ReadWritePaths = [ cfg.dump.backupDir cfg.repositoryRoot cfg.stateDir cfg.lfs.contentDir ];
+ UMask = "0027";
+ # Capabilities
+ CapabilityBoundingSet = "";
+ # Security
+ NoNewPrivileges = true;
+ # Sandboxing
+ ProtectSystem = "strict";
ProtectHome = true;
+ PrivateTmp = true;
PrivateDevices = true;
+ PrivateUsers = true;
+ ProtectHostname = true;
+ ProtectClock = true;
ProtectKernelTunables = true;
ProtectKernelModules = true;
+ ProtectKernelLogs = true;
ProtectControlGroups = true;
- ReadWritePaths = cfg.stateDir;
- # Caps
- CapabilityBoundingSet = "";
- NoNewPrivileges = true;
- # Misc.
+ RestrictAddressFamilies = [ "AF_UNIX AF_INET AF_INET6" ];
LockPersonality = true;
+ MemoryDenyWriteExecute = true;
RestrictRealtime = true;
+ RestrictSUIDSGID = true;
PrivateMounts = true;
- PrivateUsers = true;
- MemoryDenyWriteExecute = true;
- SystemCallFilter = "~@clock @cpu-emulation @debug @keyring @memlock @module @mount @obsolete @raw-io @reboot @resources @setuid @swap";
+ # System Call Filtering
SystemCallArchitectures = "native";
- RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6";
+ SystemCallFilter = "~@clock @cpu-emulation @debug @keyring @memlock @module @mount @obsolete @raw-io @reboot @resources @setuid @swap";
};
environment = {
@@ -504,7 +594,7 @@ in
Type = "oneshot";
User = cfg.user;
ExecStart = "${gitea}/bin/gitea dump";
- WorkingDirectory = cfg.stateDir;
+ WorkingDirectory = cfg.dump.backupDir;
};
};
diff --git a/nixpkgs/nixos/modules/services/misc/gitlab.nix b/nixpkgs/nixos/modules/services/misc/gitlab.nix
index be59b53e5ce..9896b8023e4 100644
--- a/nixpkgs/nixos/modules/services/misc/gitlab.nix
+++ b/nixpkgs/nixos/modules/services/misc/gitlab.nix
@@ -54,7 +54,7 @@ let
'') gitlabConfig.production.repositories.storages))}
'';
- gitlabShellConfig = {
+ gitlabShellConfig = flip recursiveUpdate cfg.extraShellConfig {
user = cfg.user;
gitlab_url = "http+unix://${pathUrlQuote gitlabSocket}";
http_settings.self_signed_cert = false;
@@ -517,6 +517,12 @@ in {
'';
};
+ extraShellConfig = mkOption {
+ type = types.attrs;
+ default = {};
+ description = "Extra configuration to merge into shell-config.yml";
+ };
+
extraConfig = mkOption {
type = types.attrs;
default = {};
@@ -618,26 +624,38 @@ in {
enable = true;
ensureUsers = singleton { name = cfg.databaseUsername; };
};
+
# The postgresql module doesn't currently support concepts like
# objects owners and extensions; for now we tack on what's needed
# here.
- systemd.services.postgresql.postStart = mkAfter (optionalString databaseActuallyCreateLocally ''
- set -eu
-
- $PSQL -tAc "SELECT 1 FROM pg_database WHERE datname = '${cfg.databaseName}'" | grep -q 1 || $PSQL -tAc 'CREATE DATABASE "${cfg.databaseName}" OWNER "${cfg.databaseUsername}"'
- current_owner=$($PSQL -tAc "SELECT pg_catalog.pg_get_userbyid(datdba) FROM pg_catalog.pg_database WHERE datname = '${cfg.databaseName}'")
- if [[ "$current_owner" != "${cfg.databaseUsername}" ]]; then
- $PSQL -tAc 'ALTER DATABASE "${cfg.databaseName}" OWNER TO "${cfg.databaseUsername}"'
- if [[ -e "${config.services.postgresql.dataDir}/.reassigning_${cfg.databaseName}" ]]; then
- echo "Reassigning ownership of database ${cfg.databaseName} to user ${cfg.databaseUsername} failed on last boot. Failing..."
- exit 1
- fi
- touch "${config.services.postgresql.dataDir}/.reassigning_${cfg.databaseName}"
- $PSQL "${cfg.databaseName}" -tAc "REASSIGN OWNED BY \"$current_owner\" TO \"${cfg.databaseUsername}\""
- rm "${config.services.postgresql.dataDir}/.reassigning_${cfg.databaseName}"
- fi
- $PSQL '${cfg.databaseName}' -tAc "CREATE EXTENSION IF NOT EXISTS pg_trgm"
- '');
+ systemd.services.gitlab-postgresql = let pgsql = config.services.postgresql; in mkIf databaseActuallyCreateLocally {
+ after = [ "postgresql.service" ];
+ wantedBy = [ "multi-user.target" ];
+ path = [ pgsql.package ];
+ script = ''
+ set -eu
+
+ PSQL="${pkgs.utillinux}/bin/runuser -u ${pgsql.superUser} -- psql --port=${toString pgsql.port}"
+
+ $PSQL -tAc "SELECT 1 FROM pg_database WHERE datname = '${cfg.databaseName}'" | grep -q 1 || $PSQL -tAc 'CREATE DATABASE "${cfg.databaseName}" OWNER "${cfg.databaseUsername}"'
+ current_owner=$($PSQL -tAc "SELECT pg_catalog.pg_get_userbyid(datdba) FROM pg_catalog.pg_database WHERE datname = '${cfg.databaseName}'")
+ if [[ "$current_owner" != "${cfg.databaseUsername}" ]]; then
+ $PSQL -tAc 'ALTER DATABASE "${cfg.databaseName}" OWNER TO "${cfg.databaseUsername}"'
+ if [[ -e "${config.services.postgresql.dataDir}/.reassigning_${cfg.databaseName}" ]]; then
+ echo "Reassigning ownership of database ${cfg.databaseName} to user ${cfg.databaseUsername} failed on last boot. Failing..."
+ exit 1
+ fi
+ touch "${config.services.postgresql.dataDir}/.reassigning_${cfg.databaseName}"
+ $PSQL "${cfg.databaseName}" -tAc "REASSIGN OWNED BY \"$current_owner\" TO \"${cfg.databaseUsername}\""
+ rm "${config.services.postgresql.dataDir}/.reassigning_${cfg.databaseName}"
+ fi
+ $PSQL '${cfg.databaseName}' -tAc "CREATE EXTENSION IF NOT EXISTS pg_trgm"
+ '';
+
+ serviceConfig = {
+ Type = "oneshot";
+ };
+ };
# Use postfix to send out mails.
services.postfix.enable = mkDefault true;
@@ -684,7 +702,6 @@ in {
"L+ /run/gitlab/shell-config.yml - - - - ${pkgs.writeText "config.yml" (builtins.toJSON gitlabShellConfig)}"
"L+ ${cfg.statePath}/config/unicorn.rb - - - - ${./defaultUnicornConfig.rb}"
- "L+ ${cfg.statePath}/config/initializers/extra-gitlab.rb - - - - ${extraGitlabRb}"
];
systemd.services.gitlab-sidekiq = {
@@ -766,8 +783,25 @@ in {
};
};
+ systemd.services.gitlab-mailroom = mkIf (gitlabConfig.production.incoming_email.enabled or false) {
+ description = "GitLab incoming mail daemon";
+ after = [ "network.target" "redis.service" "gitlab.service" ]; # gitlab.service creates configs
+ wantedBy = [ "multi-user.target" ];
+ environment = gitlabEnv;
+ serviceConfig = {
+ Type = "simple";
+ TimeoutSec = "infinity";
+ Restart = "on-failure";
+
+ User = cfg.user;
+ Group = cfg.group;
+ ExecStart = "${cfg.packages.gitlab.rubyEnv}/bin/bundle exec mail_room -c ${cfg.packages.gitlab}/share/gitlab/config.dist/mail_room.yml";
+ WorkingDirectory = gitlabEnv.HOME;
+ };
+ };
+
systemd.services.gitlab = {
- after = [ "gitlab-workhorse.service" "gitaly.service" "network.target" "postgresql.service" "redis.service" ];
+ after = [ "gitlab-workhorse.service" "gitaly.service" "network.target" "gitlab-postgresql.service" "redis.service" ];
requires = [ "gitlab-sidekiq.service" ];
wantedBy = [ "multi-user.target" ];
environment = gitlabEnv;
@@ -804,6 +838,7 @@ in {
rm -f ${cfg.statePath}/lib
cp -rf --no-preserve=mode ${cfg.packages.gitlab}/share/gitlab/config.dist/* ${cfg.statePath}/config
cp -rf --no-preserve=mode ${cfg.packages.gitlab}/share/gitlab/db/* ${cfg.statePath}/db
+ ln -sf ${extraGitlabRb} ${cfg.statePath}/config/initializers/extra-gitlab.rb
${cfg.packages.gitlab-shell}/bin/install
diff --git a/nixpkgs/nixos/modules/services/misc/gitlab.xml b/nixpkgs/nixos/modules/services/misc/gitlab.xml
index b6171a9a194..19a3df0a5f6 100644
--- a/nixpkgs/nixos/modules/services/misc/gitlab.xml
+++ b/nixpkgs/nixos/modules/services/misc/gitlab.xml
@@ -98,6 +98,12 @@ services.gitlab = {
</para>
<para>
+ When <literal>icoming_mail.enabled</literal> is set to <literal>true</literal>
+ in <link linkend="opt-services.gitlab.extraConfig">extraConfig</link> an additional
+ service called <literal>gitlab-mailroom</literal> is enabled for fetching incoming mail.
+ </para>
+
+ <para>
Refer to <xref linkend="ch-options" /> for all available configuration
options for the
<link linkend="opt-services.gitlab.enable">services.gitlab</link> module.
diff --git a/nixpkgs/nixos/modules/services/misc/gollum.nix b/nixpkgs/nixos/modules/services/misc/gollum.nix
index f4a9c72b154..0c9c7548305 100644
--- a/nixpkgs/nixos/modules/services/misc/gollum.nix
+++ b/nixpkgs/nixos/modules/services/misc/gollum.nix
@@ -50,6 +50,12 @@ in
description = "Parse and interpret emoji tags";
};
+ h1-title = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Use the first h1 as page title";
+ };
+
branch = mkOption {
type = types.str;
default = "master";
@@ -98,10 +104,11 @@ in
${pkgs.gollum}/bin/gollum \
--port ${toString cfg.port} \
--host ${cfg.address} \
- --config ${builtins.toFile "gollum-config.rb" cfg.extraConfig} \
+ --config ${pkgs.writeText "gollum-config.rb" cfg.extraConfig} \
--ref ${cfg.branch} \
${optionalString cfg.mathjax "--mathjax"} \
${optionalString cfg.emoji "--emoji"} \
+ ${optionalString cfg.h1-title "--h1-title"} \
${optionalString (cfg.allowUploads != null) "--allow-uploads ${cfg.allowUploads}"} \
${cfg.stateDir}
'';
diff --git a/nixpkgs/nixos/modules/services/misc/jellyfin.nix b/nixpkgs/nixos/modules/services/misc/jellyfin.nix
index 6ecdfb57dc3..0493dadea94 100644
--- a/nixpkgs/nixos/modules/services/misc/jellyfin.nix
+++ b/nixpkgs/nixos/modules/services/misc/jellyfin.nix
@@ -16,6 +16,14 @@ in
description = "User account under which Jellyfin runs.";
};
+ package = mkOption {
+ type = types.package;
+ example = literalExample "pkgs.jellyfin";
+ description = ''
+ Jellyfin package to use.
+ '';
+ };
+
group = mkOption {
type = types.str;
default = "jellyfin";
@@ -35,11 +43,16 @@ in
Group = cfg.group;
StateDirectory = "jellyfin";
CacheDirectory = "jellyfin";
- ExecStart = "${pkgs.jellyfin}/bin/jellyfin --datadir '/var/lib/${StateDirectory}' --cachedir '/var/cache/${CacheDirectory}'";
+ ExecStart = "${cfg.package}/bin/jellyfin --datadir '/var/lib/${StateDirectory}' --cachedir '/var/cache/${CacheDirectory}'";
Restart = "on-failure";
};
};
+ services.jellyfin.package = mkDefault (
+ if versionAtLeast config.system.stateVersion "20.09" then pkgs.jellyfin
+ else pkgs.jellyfin_10_5
+ );
+
users.users = mkIf (cfg.user == "jellyfin") {
jellyfin = {
group = cfg.group;
diff --git a/nixpkgs/nixos/modules/services/misc/mathics.nix b/nixpkgs/nixos/modules/services/misc/mathics.nix
deleted file mode 100644
index c588a30d76c..00000000000
--- a/nixpkgs/nixos/modules/services/misc/mathics.nix
+++ /dev/null
@@ -1,54 +0,0 @@
-{ pkgs, lib, config, ... }:
-
-with lib;
-
-let
- cfg = config.services.mathics;
-
-in {
- options = {
- services.mathics = {
- enable = mkEnableOption "Mathics notebook service";
-
- external = mkOption {
- type = types.bool;
- default = false;
- description = "Listen on all interfaces, rather than just localhost?";
- };
-
- port = mkOption {
- type = types.int;
- default = 8000;
- description = "TCP port to listen on.";
- };
- };
- };
-
- config = mkIf cfg.enable {
-
- users.users.mathics = {
- group = config.users.groups.mathics.name;
- description = "Mathics user";
- home = "/var/lib/mathics";
- createHome = true;
- uid = config.ids.uids.mathics;
- };
-
- users.groups.mathics.gid = config.ids.gids.mathics;
-
- systemd.services.mathics = {
- description = "Mathics notebook server";
- wantedBy = [ "multi-user.target" ];
- after = [ "network.target" ];
- serviceConfig = {
- User = config.users.users.mathics.name;
- Group = config.users.groups.mathics.name;
- ExecStart = concatStringsSep " " [
- "${pkgs.mathics}/bin/mathicsserver"
- "--port" (toString cfg.port)
- (if cfg.external then "--external" else "")
- ];
- };
- };
- };
-}
diff --git a/nixpkgs/nixos/modules/services/misc/matrix-synapse.nix b/nixpkgs/nixos/modules/services/misc/matrix-synapse.nix
index e982eb16fa7..3eb1073387f 100644
--- a/nixpkgs/nixos/modules/services/misc/matrix-synapse.nix
+++ b/nixpkgs/nixos/modules/services/misc/matrix-synapse.nix
@@ -675,7 +675,7 @@ in {
}
];
- users.users.matrix-synapse = {
+ users.users.matrix-synapse = {
group = "matrix-synapse";
home = cfg.dataDir;
createHome = true;
diff --git a/nixpkgs/nixos/modules/services/misc/mesos-master.nix b/nixpkgs/nixos/modules/services/misc/mesos-master.nix
deleted file mode 100644
index 572a9847e46..00000000000
--- a/nixpkgs/nixos/modules/services/misc/mesos-master.nix
+++ /dev/null
@@ -1,125 +0,0 @@
-{ config, lib, pkgs, ... }:
-
-with lib;
-
-let
- cfg = config.services.mesos.master;
-
-in {
-
- options.services.mesos = {
-
- master = {
- enable = mkOption {
- description = "Whether to enable the Mesos Master.";
- default = false;
- type = types.bool;
- };
-
- ip = mkOption {
- description = "IP address to listen on.";
- default = "0.0.0.0";
- type = types.str;
- };
-
- port = mkOption {
- description = "Mesos Master port";
- default = 5050;
- type = types.int;
- };
-
- advertiseIp = mkOption {
- description = "IP address advertised to reach this master.";
- default = null;
- type = types.nullOr types.str;
- };
-
- advertisePort = mkOption {
- description = "Port advertised to reach this Mesos master.";
- default = null;
- type = types.nullOr types.int;
- };
-
- zk = mkOption {
- description = ''
- ZooKeeper URL (used for leader election amongst masters).
- May be one of:
- zk://host1:port1,host2:port2,.../mesos
- zk://username:password@host1:port1,host2:port2,.../mesos
- '';
- type = types.str;
- };
-
- workDir = mkOption {
- description = "The Mesos work directory.";
- default = "/var/lib/mesos/master";
- type = types.str;
- };
-
- extraCmdLineOptions = mkOption {
- description = ''
- Extra command line options for Mesos Master.
-
- See https://mesos.apache.org/documentation/latest/configuration/
- '';
- default = [ "" ];
- type = types.listOf types.str;
- example = [ "--credentials=VALUE" ];
- };
-
- quorum = mkOption {
- description = ''
- The size of the quorum of replicas when using 'replicated_log' based
- registry. It is imperative to set this value to be a majority of
- masters i.e., quorum > (number of masters)/2.
-
- If 0 will fall back to --registry=in_memory.
- '';
- default = 0;
- type = types.int;
- };
-
- logLevel = mkOption {
- description = ''
- The logging level used. Possible values:
- 'INFO', 'WARNING', 'ERROR'
- '';
- default = "INFO";
- type = types.str;
- };
-
- };
-
-
- };
-
-
- config = mkIf cfg.enable {
- systemd.tmpfiles.rules = [
- "d '${cfg.workDir}' 0700 - - - -"
- ];
- systemd.services.mesos-master = {
- description = "Mesos Master";
- wantedBy = [ "multi-user.target" ];
- after = [ "network.target" ];
- serviceConfig = {
- ExecStart = ''
- ${pkgs.mesos}/bin/mesos-master \
- --ip=${cfg.ip} \
- --port=${toString cfg.port} \
- ${optionalString (cfg.advertiseIp != null) "--advertise_ip=${cfg.advertiseIp}"} \
- ${optionalString (cfg.advertisePort != null) "--advertise_port=${toString cfg.advertisePort}"} \
- ${if cfg.quorum == 0
- then "--registry=in_memory"
- else "--zk=${cfg.zk} --registry=replicated_log --quorum=${toString cfg.quorum}"} \
- --work_dir=${cfg.workDir} \
- --logging_level=${cfg.logLevel} \
- ${toString cfg.extraCmdLineOptions}
- '';
- Restart = "on-failure";
- };
- };
- };
-
-}
-
diff --git a/nixpkgs/nixos/modules/services/misc/mesos-slave.nix b/nixpkgs/nixos/modules/services/misc/mesos-slave.nix
deleted file mode 100644
index 170065d0065..00000000000
--- a/nixpkgs/nixos/modules/services/misc/mesos-slave.nix
+++ /dev/null
@@ -1,220 +0,0 @@
-{ config, lib, pkgs, ... }:
-
-with lib;
-
-let
- cfg = config.services.mesos.slave;
-
- mkAttributes =
- attrs: concatStringsSep ";" (mapAttrsToList
- (k: v: "${k}:${v}")
- (filterAttrs (k: v: v != null) attrs));
- attribsArg = optionalString (cfg.attributes != {})
- "--attributes=${mkAttributes cfg.attributes}";
-
- containerizersArg = concatStringsSep "," (
- lib.unique (
- cfg.containerizers ++ (optional cfg.withDocker "docker")
- )
- );
-
- imageProvidersArg = concatStringsSep "," (
- lib.unique (
- cfg.imageProviders ++ (optional cfg.withDocker "docker")
- )
- );
-
- isolationArg = concatStringsSep "," (
- lib.unique (
- cfg.isolation ++ (optionals cfg.withDocker [ "filesystem/linux" "docker/runtime"])
- )
- );
-
-in {
-
- options.services.mesos = {
- slave = {
- enable = mkOption {
- description = "Whether to enable the Mesos Slave.";
- default = false;
- type = types.bool;
- };
-
- ip = mkOption {
- description = "IP address to listen on.";
- default = "0.0.0.0";
- type = types.str;
- };
-
- port = mkOption {
- description = "Port to listen on.";
- default = 5051;
- type = types.int;
- };
-
- advertiseIp = mkOption {
- description = "IP address advertised to reach this agent.";
- default = null;
- type = types.nullOr types.str;
- };
-
- advertisePort = mkOption {
- description = "Port advertised to reach this agent.";
- default = null;
- type = types.nullOr types.int;
- };
-
- containerizers = mkOption {
- description = ''
- List of containerizer implementations to compose in order to provide
- containerization. Available options are mesos and docker.
- The order the containerizers are specified is the order they are tried.
- '';
- default = [ "mesos" ];
- type = types.listOf types.str;
- };
-
- imageProviders = mkOption {
- description = "List of supported image providers, e.g., APPC,DOCKER.";
- default = [ ];
- type = types.listOf types.str;
- };
-
- imageProvisionerBackend = mkOption {
- description = ''
- Strategy for provisioning container rootfs from images,
- e.g., aufs, bind, copy, overlay.
- '';
- default = "copy";
- type = types.str;
- };
-
- isolation = mkOption {
- description = ''
- Isolation mechanisms to use, e.g., posix/cpu,posix/mem, or
- cgroups/cpu,cgroups/mem, or network/port_mapping, or `gpu/nvidia` for nvidia
- specific gpu isolation.
- '';
- default = [ "posix/cpu" "posix/mem" ];
- type = types.listOf types.str;
- };
-
- master = mkOption {
- description = ''
- May be one of:
- zk://host1:port1,host2:port2,.../path
- zk://username:password@host1:port1,host2:port2,.../path
- '';
- type = types.str;
- };
-
- withHadoop = mkOption {
- description = "Add the HADOOP_HOME to the slave.";
- default = false;
- type = types.bool;
- };
-
- withDocker = mkOption {
- description = "Enable the docker containerizer.";
- default = config.virtualisation.docker.enable;
- type = types.bool;
- };
-
- dockerRegistry = mkOption {
- description = ''
- The default url for pulling Docker images.
- It could either be a Docker registry server url,
- or a local path in which Docker image archives are stored.
- '';
- default = null;
- type = types.nullOr (types.either types.str types.path);
- };
-
- workDir = mkOption {
- description = "The Mesos work directory.";
- default = "/var/lib/mesos/slave";
- type = types.str;
- };
-
- extraCmdLineOptions = mkOption {
- description = ''
- Extra command line options for Mesos Slave.
-
- See https://mesos.apache.org/documentation/latest/configuration/
- '';
- default = [ "" ];
- type = types.listOf types.str;
- example = [ "--gc_delay=3days" ];
- };
-
- logLevel = mkOption {
- description = ''
- The logging level used. Possible values:
- 'INFO', 'WARNING', 'ERROR'
- '';
- default = "INFO";
- type = types.str;
- };
-
- attributes = mkOption {
- description = ''
- Machine attributes for the slave instance.
-
- Use caution when changing this; you may need to manually reset slave
- metadata before the slave can re-register.
- '';
- default = {};
- type = types.attrsOf types.str;
- example = { rack = "aa";
- host = "aabc123";
- os = "nixos"; };
- };
-
- executorEnvironmentVariables = mkOption {
- description = ''
- The environment variables that should be passed to the executor, and thus subsequently task(s).
- '';
- default = {
- PATH = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin";
- };
- type = types.attrsOf types.str;
- };
- };
-
- };
-
- config = mkIf cfg.enable {
- systemd.tmpfiles.rules = [
- "d '${cfg.workDir}' 0701 - - - -"
- ];
- systemd.services.mesos-slave = {
- description = "Mesos Slave";
- wantedBy = [ "multi-user.target" ];
- after = [ "network.target" ] ++ optionals cfg.withDocker [ "docker.service" ] ;
- path = [ pkgs.runtimeShellPackage ];
- serviceConfig = {
- ExecStart = ''
- ${pkgs.mesos}/bin/mesos-slave \
- --containerizers=${containerizersArg} \
- --image_providers=${imageProvidersArg} \
- --image_provisioner_backend=${cfg.imageProvisionerBackend} \
- --isolation=${isolationArg} \
- --ip=${cfg.ip} \
- --port=${toString cfg.port} \
- ${optionalString (cfg.advertiseIp != null) "--advertise_ip=${cfg.advertiseIp}"} \
- ${optionalString (cfg.advertisePort != null) "--advertise_port=${toString cfg.advertisePort}"} \
- --master=${cfg.master} \
- --work_dir=${cfg.workDir} \
- --logging_level=${cfg.logLevel} \
- ${attribsArg} \
- ${optionalString cfg.withHadoop "--hadoop-home=${pkgs.hadoop}"} \
- ${optionalString cfg.withDocker "--docker=${pkgs.docker}/libexec/docker/docker"} \
- ${optionalString (cfg.dockerRegistry != null) "--docker_registry=${cfg.dockerRegistry}"} \
- --executor_environment_variables=${lib.escapeShellArg (builtins.toJSON cfg.executorEnvironmentVariables)} \
- ${toString cfg.extraCmdLineOptions}
- '';
- };
- };
- };
-
-}
diff --git a/nixpkgs/nixos/modules/services/misc/nix-daemon.nix b/nixpkgs/nixos/modules/services/misc/nix-daemon.nix
index 924a007efc6..2680b1cc0d3 100644
--- a/nixpkgs/nixos/modules/services/misc/nix-daemon.nix
+++ b/nixpkgs/nixos/modules/services/misc/nix-daemon.nix
@@ -500,13 +500,6 @@ in
config = {
- assertions = [
- {
- assertion = config.nix.distributedBuilds || config.nix.buildMachines == [];
- message = "You must set `nix.distributedBuilds = true` to use nix.buildMachines";
- }
- ];
-
nix.binaryCachePublicKeys = [ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" ];
nix.binaryCaches = [ "https://cache.nixos.org/" ];
@@ -594,16 +587,10 @@ in
nix.systemFeatures = mkDefault (
[ "nixos-test" "benchmark" "big-parallel" "kvm" ] ++
- optionals (pkgs.stdenv.isx86_64 && pkgs.hostPlatform.platform ? gcc.arch) (
- # a x86_64 builder can run code for `platform.gcc.arch` and minor architectures:
- [ "gccarch-${pkgs.hostPlatform.platform.gcc.arch}" ] ++ {
- sandybridge = [ "gccarch-westmere" ];
- ivybridge = [ "gccarch-westmere" "gccarch-sandybridge" ];
- haswell = [ "gccarch-westmere" "gccarch-sandybridge" "gccarch-ivybridge" ];
- broadwell = [ "gccarch-westmere" "gccarch-sandybridge" "gccarch-ivybridge" "gccarch-haswell" ];
- skylake = [ "gccarch-westmere" "gccarch-sandybridge" "gccarch-ivybridge" "gccarch-haswell" "gccarch-broadwell" ];
- skylake-avx512 = [ "gccarch-westmere" "gccarch-sandybridge" "gccarch-ivybridge" "gccarch-haswell" "gccarch-broadwell" "gccarch-skylake" ];
- }.${pkgs.hostPlatform.platform.gcc.arch} or []
+ optionals (pkgs.hostPlatform.platform ? gcc.arch) (
+ # a builder can run code for `platform.gcc.arch` and inferior architectures
+ [ "gccarch-${pkgs.hostPlatform.platform.gcc.arch}" ] ++
+ map (x: "gccarch-${x}") lib.systems.architectures.inferiors.${pkgs.hostPlatform.platform.gcc.arch}
)
);
diff --git a/nixpkgs/nixos/modules/services/misc/octoprint.nix b/nixpkgs/nixos/modules/services/misc/octoprint.nix
index 7a71d2c8c6a..e2fbd3b401c 100644
--- a/nixpkgs/nixos/modules/services/misc/octoprint.nix
+++ b/nixpkgs/nixos/modules/services/misc/octoprint.nix
@@ -68,8 +68,8 @@ in
plugins = mkOption {
default = plugins: [];
defaultText = "plugins: []";
- example = literalExample "plugins: [ m3d-fio ]";
- description = "Additional plugins.";
+ example = literalExample "plugins: with plugins; [ m33-fio stlviewer ]";
+ description = "Additional plugins to be used. Available plugins are passed through the plugins input.";
};
extraConfig = mkOption {
diff --git a/nixpkgs/nixos/modules/services/misc/pinnwand.nix b/nixpkgs/nixos/modules/services/misc/pinnwand.nix
new file mode 100644
index 00000000000..aa1ee5cfaa7
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/misc/pinnwand.nix
@@ -0,0 +1,78 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.pinnwand;
+
+ format = pkgs.formats.toml {};
+ configFile = format.generate "pinnwand.toml" cfg.settings;
+in
+{
+ options.services.pinnwand = {
+ enable = mkEnableOption "Pinnwand";
+
+ port = mkOption {
+ type = types.port;
+ description = "The port to listen on.";
+ default = 8000;
+ };
+
+ settings = mkOption {
+ type = format.type;
+ description = ''
+ Your <filename>pinnwand.toml</filename> as a Nix attribute set. Look up
+ possible options in the <link xlink:href="https://github.com/supakeen/pinnwand/blob/master/pinnwand.toml-example">pinnwand.toml-example</link>.
+ '';
+ default = {
+ # https://github.com/supakeen/pinnwand/blob/master/pinnwand.toml-example
+ database_uri = "sqlite:///var/lib/pinnwand/pinnwand.db";
+ preferred_lexeres = [];
+ paste_size = 262144;
+ paste_help = ''
+ <p>Welcome to pinnwand, this site is a pastebin. It allows you to share code with others. If you write code in the text area below and press the paste button you will be given a link you can share with others so they can view your code as well.</p><p>People with the link can view your pasted code, only you can remove your paste and it expires automatically. Note that anyone could guess the URI to your paste so don't rely on it being private.</p>
+ '';
+ footer = ''
+ View <a href="//github.com/supakeen/pinnwand" target="_BLANK">source code</a>, the <a href="/removal">removal</a> or <a href="/expiry">expiry</a> stories, or read the <a href="/about">about</a> page.
+ '';
+ };
+ };
+ };
+
+ config = mkIf cfg.enable {
+ systemd.services.pinnwand = {
+ description = "Pinnwannd HTTP Server";
+ after = [ "network.target" ];
+ wantedBy = [ "multi-user.target" ];
+
+ unitConfig.Documentation = "https://pinnwand.readthedocs.io/en/latest/";
+ serviceConfig = {
+ ExecStart = "${pkgs.pinnwand}/bin/pinnwand --configuration-path ${configFile} http --port ${toString(cfg.port)}";
+ StateDirectory = "pinnwand";
+ StateDirectoryMode = "0700";
+
+ AmbientCapabilities = [];
+ CapabilityBoundingSet = "";
+ DevicePolicy = "closed";
+ DynamicUser = true;
+ LockPersonality = true;
+ MemoryDenyWriteExecute = true;
+ PrivateDevices = true;
+ PrivateUsers = true;
+ ProtectClock = true;
+ ProtectControlGroups = true;
+ ProtectKernelLogs = true;
+ ProtectHome = true;
+ ProtectHostname = true;
+ ProtectKernelModules = true;
+ ProtectKernelTunables = true;
+ RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ];
+ RestrictNamespaces = true;
+ RestrictRealtime = true;
+ SystemCallArchitectures = "native";
+ SystemCallFilter = "@system-service";
+ UMask = "0077";
+ };
+ };
+ };
+}
diff --git a/nixpkgs/nixos/modules/services/misc/redmine.nix b/nixpkgs/nixos/modules/services/misc/redmine.nix
index 0e71cf92569..1313bdaccc4 100644
--- a/nixpkgs/nixos/modules/services/misc/redmine.nix
+++ b/nixpkgs/nixos/modules/services/misc/redmine.nix
@@ -1,12 +1,12 @@
{ config, lib, pkgs, ... }:
let
- inherit (lib) mkDefault mkEnableOption mkIf mkOption types;
+ inherit (lib) mkBefore mkDefault mkEnableOption mkIf mkOption mkRemovedOptionModule types;
inherit (lib) concatStringsSep literalExample mapAttrsToList;
- inherit (lib) optional optionalAttrs optionalString singleton versionAtLeast;
+ inherit (lib) optional optionalAttrs optionalString;
cfg = config.services.redmine;
-
+ format = pkgs.formats.yaml {};
bundle = "${cfg.package}/share/redmine/bin/bundle";
databaseYml = pkgs.writeText "database.yml" ''
@@ -20,24 +20,8 @@ let
${optionalString (cfg.database.type == "mysql2" && cfg.database.socket != null) "socket: ${cfg.database.socket}"}
'';
- configurationYml = pkgs.writeText "configuration.yml" ''
- default:
- scm_subversion_command: ${pkgs.subversion}/bin/svn
- scm_mercurial_command: ${pkgs.mercurial}/bin/hg
- scm_git_command: ${pkgs.gitAndTools.git}/bin/git
- scm_cvs_command: ${pkgs.cvs}/bin/cvs
- scm_bazaar_command: ${pkgs.breezy}/bin/bzr
- scm_darcs_command: ${pkgs.darcs}/bin/darcs
-
- ${cfg.extraConfig}
- '';
-
- additionalEnvironment = pkgs.writeText "additional_environment.rb" ''
- config.logger = Logger.new("${cfg.stateDir}/log/production.log", 14, 1048576)
- config.logger.level = Logger::INFO
-
- ${cfg.extraEnv}
- '';
+ configurationYml = format.generate "configuration.yml" cfg.settings;
+ additionalEnvironment = pkgs.writeText "additional_environment.rb" cfg.extraEnv;
unpackTheme = unpack "theme";
unpackPlugin = unpack "plugin";
@@ -56,8 +40,13 @@ let
pgsqlLocal = cfg.database.createLocally && cfg.database.type == "postgresql";
in
-
{
+ imports = [
+ (mkRemovedOptionModule [ "services" "redmine" "extraConfig" ] "Use services.redmine.settings instead.")
+ (mkRemovedOptionModule [ "services" "redmine" "database" "password" ] "Use services.redmine.database.passwordFile instead.")
+ ];
+
+ # interface
options = {
services.redmine = {
enable = mkEnableOption "Redmine";
@@ -93,21 +82,24 @@ in
description = "The state directory, logs and plugins are stored here.";
};
- extraConfig = mkOption {
- type = types.lines;
- default = "";
+ settings = mkOption {
+ type = format.type;
+ default = {};
description = ''
- Extra configuration in configuration.yml.
-
- See <link xlink:href="https://guides.rubyonrails.org/action_mailer_basics.html#action-mailer-configuration"/>
+ Redmine configuration (<filename>configuration.yml</filename>). Refer to
+ <link xlink:href="https://guides.rubyonrails.org/action_mailer_basics.html#action-mailer-configuration"/>
for details.
'';
example = literalExample ''
- email_delivery:
- delivery_method: smtp
- smtp_settings:
- address: mail.example.com
- port: 25
+ {
+ email_delivery = {
+ delivery_method = "smtp";
+ smtp_settings = {
+ address = "mail.example.com";
+ port = 25;
+ };
+ };
+ }
'';
};
@@ -186,16 +178,6 @@ in
description = "Database user.";
};
- password = mkOption {
- type = types.str;
- default = "";
- description = ''
- The password corresponding to <option>database.user</option>.
- Warning: this is stored in cleartext in the Nix store!
- Use <option>database.passwordFile</option> instead.
- '';
- };
-
passwordFile = mkOption {
type = types.nullOr types.path;
default = null;
@@ -226,11 +208,12 @@ in
};
};
+ # implementation
config = mkIf cfg.enable {
assertions = [
- { assertion = cfg.database.passwordFile != null || cfg.database.password != "" || cfg.database.socket != null;
- message = "one of services.redmine.database.socket, services.redmine.database.passwordFile, or services.redmine.database.password must be set";
+ { assertion = cfg.database.passwordFile != null || cfg.database.socket != null;
+ message = "one of services.redmine.database.socket or services.redmine.database.passwordFile must be set";
}
{ assertion = cfg.database.createLocally -> cfg.database.user == cfg.user;
message = "services.redmine.database.user must be set to ${cfg.user} if services.redmine.database.createLocally is set true";
@@ -243,6 +226,22 @@ in
}
];
+ services.redmine.settings = {
+ production = {
+ scm_subversion_command = "${pkgs.subversion}/bin/svn";
+ scm_mercurial_command = "${pkgs.mercurial}/bin/hg";
+ scm_git_command = "${pkgs.gitAndTools.git}/bin/git";
+ scm_cvs_command = "${pkgs.cvs}/bin/cvs";
+ scm_bazaar_command = "${pkgs.breezy}/bin/bzr";
+ scm_darcs_command = "${pkgs.darcs}/bin/darcs";
+ };
+ };
+
+ services.redmine.extraEnv = mkBefore ''
+ config.logger = Logger.new("${cfg.stateDir}/log/production.log", 14, 1048576)
+ config.logger.level = Logger::INFO
+ '';
+
services.mysql = mkIf mysqlLocal {
enable = true;
package = mkDefault pkgs.mariadb;
@@ -338,7 +337,7 @@ in
# handle database.passwordFile & permissions
- DBPASS=$(head -n1 ${cfg.database.passwordFile})
+ DBPASS=${optionalString (cfg.database.passwordFile != null) "$(head -n1 ${cfg.database.passwordFile})"}
cp -f ${databaseYml} "${cfg.stateDir}/config/database.yml"
sed -e "s,#dbpass#,$DBPASS,g" -i "${cfg.stateDir}/config/database.yml"
chmod 440 "${cfg.stateDir}/config/database.yml"
@@ -379,17 +378,6 @@ in
redmine.gid = config.ids.gids.redmine;
};
- warnings = optional (cfg.database.password != "")
- ''config.services.redmine.database.password will be stored as plaintext
- in the Nix store. Use database.passwordFile instead.'';
-
- # Create database passwordFile default when password is configured.
- services.redmine.database.passwordFile =
- (mkDefault (toString (pkgs.writeTextFile {
- name = "redmine-database-password";
- text = cfg.database.password;
- })));
-
};
}
diff --git a/nixpkgs/nixos/modules/services/misc/siproxd.nix b/nixpkgs/nixos/modules/services/misc/siproxd.nix
index ae7b27de8e7..0e87fc461d3 100644
--- a/nixpkgs/nixos/modules/services/misc/siproxd.nix
+++ b/nixpkgs/nixos/modules/services/misc/siproxd.nix
@@ -38,7 +38,7 @@ in
type = types.bool;
default = false;
description = ''
- Whether to enable the Siproxd SIP
+ Whether to enable the Siproxd SIP
proxy/masquerading daemon.
'';
};
@@ -111,7 +111,7 @@ in
type = types.int;
default = 300;
description = ''
- Timeout for an RTP stream. If for the specified
+ Timeout for an RTP stream. If for the specified
number of seconds no data is relayed on an active
stream, it is considered dead and will be killed.
'';
@@ -122,7 +122,7 @@ in
default = 46;
description = ''
DSCP (differentiated services) value to be assigned
- to RTP packets. Allows QOS aware routers to handle
+ to RTP packets. Allows QOS aware routers to handle
different types traffic with different priorities.
'';
};
@@ -132,7 +132,7 @@ in
default = 0;
description = ''
DSCP (differentiated services) value to be assigned
- to SIP packets. Allows QOS aware routers to handle
+ to SIP packets. Allows QOS aware routers to handle
different types traffic with different priorities.
'';
};
diff --git a/nixpkgs/nixos/modules/services/misc/ssm-agent.nix b/nixpkgs/nixos/modules/services/misc/ssm-agent.nix
index f7c05deeecb..00e806695fd 100644
--- a/nixpkgs/nixos/modules/services/misc/ssm-agent.nix
+++ b/nixpkgs/nixos/modules/services/misc/ssm-agent.nix
@@ -29,13 +29,15 @@ in {
config = mkIf cfg.enable {
systemd.services.ssm-agent = {
+ users.extraUsers.ssm-user = {};
+
inherit (cfg.package.meta) description;
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
- path = [ fake-lsb-release ];
+ path = [ fake-lsb-release pkgs.coreutils ];
serviceConfig = {
- ExecStart = "${cfg.package}/bin/agent";
+ ExecStart = "${cfg.package}/bin/amazon-ssm-agent";
KillMode = "process";
Restart = "on-failure";
RestartSec = "15min";
diff --git a/nixpkgs/nixos/modules/services/misc/sssd.nix b/nixpkgs/nixos/modules/services/misc/sssd.nix
index 3da99a3b38c..386281e2b7c 100644
--- a/nixpkgs/nixos/modules/services/misc/sssd.nix
+++ b/nixpkgs/nixos/modules/services/misc/sssd.nix
@@ -69,7 +69,7 @@ in {
mode = "0400";
};
- system.nssModules = pkgs.sssd;
+ system.nssModules = [ pkgs.sssd ];
system.nssDatabases = {
group = [ "sss" ];
passwd = [ "sss" ];
@@ -92,4 +92,6 @@ in {
services.openssh.authorizedKeysCommand = "/etc/ssh/authorized_keys_command";
services.openssh.authorizedKeysCommandUser = "nobody";
})];
+
+ meta.maintainers = with maintainers; [ bbigras ];
}
diff --git a/nixpkgs/nixos/modules/services/misc/tzupdate.nix b/nixpkgs/nixos/modules/services/misc/tzupdate.nix
index 570982ced29..eac1e1112a5 100644
--- a/nixpkgs/nixos/modules/services/misc/tzupdate.nix
+++ b/nixpkgs/nixos/modules/services/misc/tzupdate.nix
@@ -11,7 +11,7 @@ in {
default = false;
description = ''
Enable the tzupdate timezone updating service. This provides
- a one-shot service which can be activated with systemctl to
+ a one-shot service which can be activated with systemctl to
update the timezone.
'';
};
@@ -21,7 +21,7 @@ in {
# We need to have imperative time zone management for this to work.
# This will give users an error if they have set an explicit time
# zone, which is better than silently overriding it.
- time.timeZone = null;
+ time.timeZone = null;
# We provide a one-shot service which can be manually run. We could
# provide a service that runs on startup, but it's tricky to get
diff --git a/nixpkgs/nixos/modules/services/monitoring/cadvisor.nix b/nixpkgs/nixos/modules/services/monitoring/cadvisor.nix
index 655a6934a26..da051dbe465 100644
--- a/nixpkgs/nixos/modules/services/monitoring/cadvisor.nix
+++ b/nixpkgs/nixos/modules/services/monitoring/cadvisor.nix
@@ -90,7 +90,7 @@ in {
default = [];
description = ''
Additional cadvisor options.
-
+
See <link xlink:href='https://github.com/google/cadvisor/blob/master/docs/runtime_options.md'/> for available options.
'';
};
diff --git a/nixpkgs/nixos/modules/services/monitoring/datadog-agent.nix b/nixpkgs/nixos/modules/services/monitoring/datadog-agent.nix
index f1cb890794e..673bc7b02b2 100644
--- a/nixpkgs/nixos/modules/services/monitoring/datadog-agent.nix
+++ b/nixpkgs/nixos/modules/services/monitoring/datadog-agent.nix
@@ -6,7 +6,7 @@ let
cfg = config.services.datadog-agent;
ddConf = {
- dd_url = "https://app.datadoghq.com";
+ dd_url = cfg.ddUrl;
skip_ssl_validation = false;
confd_path = "/etc/datadog-agent/conf.d";
additional_checksd = "/etc/datadog-agent/checks.d";
@@ -77,6 +77,18 @@ in {
type = types.path;
};
+ ddUrl = mkOption {
+ description = ''
+ Custom dd_url to configure the agent with.
+ Useful when you want to point datadog to another endpoint, either
+ because you need a proxy to send out data, or because you use their EU
+ endpoint.
+ '';
+ default = "https://app.datadoghq.com";
+ example = "https://app.datadoghq.eu";
+ type = types.str;
+ };
+
tags = mkOption {
description = "The tags to mark this Datadog agent";
example = [ "test" "service" ];
diff --git a/nixpkgs/nixos/modules/services/monitoring/dd-agent/dd-agent.nix b/nixpkgs/nixos/modules/services/monitoring/dd-agent/dd-agent.nix
index e91717fb205..a290dae8d4b 100644
--- a/nixpkgs/nixos/modules/services/monitoring/dd-agent/dd-agent.nix
+++ b/nixpkgs/nixos/modules/services/monitoring/dd-agent/dd-agent.nix
@@ -97,11 +97,11 @@ let
"dd-agent/conf.d/nginx.yaml".source = nginxConfig;
}) //
(optionalAttrs (cfg.mongoConfig != null)
- {
+ {
"dd-agent/conf.d/mongo.yaml".source = mongoConfig;
}) //
(optionalAttrs (cfg.processConfig != null)
- {
+ {
"dd-agent/conf.d/process.yaml".source = processConfig;
}) //
(optionalAttrs (cfg.jmxConfig != null)
diff --git a/nixpkgs/nixos/modules/services/monitoring/monit.nix b/nixpkgs/nixos/modules/services/monitoring/monit.nix
index ca935227217..aa51b83912c 100644
--- a/nixpkgs/nixos/modules/services/monitoring/monit.nix
+++ b/nixpkgs/nixos/modules/services/monitoring/monit.nix
@@ -4,19 +4,29 @@ with lib;
let
cfg = config.services.monit;
+ extraConfig = pkgs.writeText "monitConfig" cfg.extraConfig;
in
{
+ imports = [
+ (mkRenamedOptionModule [ "services" "monit" "config" ] ["services" "monit" "extraConfig" ])
+ ];
+
options.services.monit = {
enable = mkEnableOption "Monit";
- config = mkOption {
+ configFiles = mkOption {
+ type = types.listOf types.path;
+ default = [];
+ description = "List of paths to be included in the monitrc file";
+ };
+
+ extraConfig = mkOption {
type = types.lines;
default = "";
- description = "monitrc content";
+ description = "Additional monit config as string";
};
-
};
config = mkIf cfg.enable {
@@ -24,7 +34,7 @@ in
environment.systemPackages = [ pkgs.monit ];
environment.etc.monitrc = {
- text = cfg.config;
+ text = concatMapStringsSep "\n" (path: "include ${path}") (cfg.configFiles ++ [extraConfig]);
mode = "0400";
};
diff --git a/nixpkgs/nixos/modules/services/monitoring/netdata.nix b/nixpkgs/nixos/modules/services/monitoring/netdata.nix
index a5233a46e34..2e73e15d3a8 100644
--- a/nixpkgs/nixos/modules/services/monitoring/netdata.nix
+++ b/nixpkgs/nixos/modules/services/monitoring/netdata.nix
@@ -133,16 +133,6 @@ in {
}
];
- systemd.tmpfiles.rules = [
- "d /var/cache/netdata 0755 ${cfg.user} ${cfg.group} -"
- "Z /var/cache/netdata - ${cfg.user} ${cfg.group} -"
- "d /var/log/netdata 0755 ${cfg.user} ${cfg.group} -"
- "Z /var/log/netdata - ${cfg.user} ${cfg.group} -"
- "d /var/lib/netdata 0755 ${cfg.user} ${cfg.group} -"
- "Z /var/lib/netdata - ${cfg.user} ${cfg.group} -"
- "d /etc/netdata 0755 ${cfg.user} ${cfg.group} -"
- "Z /etc/netdata - ${cfg.user} ${cfg.group} -"
- ];
systemd.services.netdata = {
description = "Real time performance monitoring";
after = [ "network.target" ];
@@ -158,11 +148,40 @@ in {
# User and group
User = cfg.user;
Group = cfg.group;
- # Runtime directory and mode
- RuntimeDirectory = "netdata";
- RuntimeDirectoryMode = "0755";
# Performance
LimitNOFILE = "30000";
+ # Runtime directory and mode
+ RuntimeDirectory = "netdata";
+ RuntimeDirectoryMode = "0750";
+ # State directory and mode
+ StateDirectory = "netdata";
+ StateDirectoryMode = "0750";
+ # Cache directory and mode
+ CacheDirectory = "netdata";
+ CacheDirectoryMode = "0750";
+ # Logs directory and mode
+ LogsDirectory = "netdata";
+ LogsDirectoryMode = "0750";
+ # Configuration directory and mode
+ ConfigurationDirectory = "netdata";
+ ConfigurationDirectoryMode = "0755";
+ # Capabilities
+ CapabilityBoundingSet = [
+ "CAP_DAC_OVERRIDE" # is required for freeipmi and slabinfo plugins
+ "CAP_DAC_READ_SEARCH" # is required for apps plugin
+ "CAP_FOWNER" # is required for freeipmi plugin
+ "CAP_SETPCAP" # is required for apps, perf and slabinfo plugins
+ "CAP_SYS_ADMIN" # is required for perf plugin
+ "CAP_SYS_PTRACE" # is required for apps plugin
+ "CAP_SYS_RESOURCE" # is required for ebpf plugin
+ "CAP_NET_RAW" # is required for fping app
+ ];
+ # Sandboxing
+ ProtectSystem = "full";
+ ProtectHome = "read-only";
+ PrivateTmp = true;
+ ProtectControlGroups = true;
+ PrivateMounts = true;
};
};
diff --git a/nixpkgs/nixos/modules/services/monitoring/prometheus/default.nix b/nixpkgs/nixos/modules/services/monitoring/prometheus/default.nix
index 84a72afac2f..d7e06484b69 100644
--- a/nixpkgs/nixos/modules/services/monitoring/prometheus/default.nix
+++ b/nixpkgs/nixos/modules/services/monitoring/prometheus/default.nix
@@ -46,7 +46,7 @@ let
cmdlineArgs = cfg.extraFlags ++ [
"--storage.tsdb.path=${workingDir}/data/"
"--config.file=${prometheusYml}"
- "--web.listen-address=${cfg.listenAddress}"
+ "--web.listen-address=${cfg.listenAddress}:${builtins.toString cfg.port}"
"--alertmanager.notification-queue-capacity=${toString cfg.alertmanagerNotificationQueueCapacity}"
"--alertmanager.timeout=${toString cfg.alertmanagerTimeout}s"
] ++
@@ -489,9 +489,17 @@ in {
'';
};
+ port = mkOption {
+ type = types.port;
+ default = 9090;
+ description = ''
+ Port to listen on.
+ '';
+ };
+
listenAddress = mkOption {
type = types.str;
- default = "0.0.0.0:9090";
+ default = "0.0.0.0";
description = ''
Address to listen on for the web interface, API, and telemetry.
'';
@@ -619,6 +627,21 @@ in {
};
config = mkIf cfg.enable {
+ assertions = [
+ ( let
+ legacy = builtins.match "(.*):(.*)" cfg.listenAddress;
+ in {
+ assertion = legacy == null;
+ message = ''
+ Do not specify the port for Prometheus to listen on in the
+ listenAddress option; use the port option instead:
+ services.prometheus.listenAddress = ${builtins.elemAt legacy 0};
+ services.prometheus.port = ${builtins.elemAt legacy 1};
+ '';
+ }
+ )
+ ];
+
users.groups.prometheus.gid = config.ids.gids.prometheus;
users.users.prometheus = {
description = "Prometheus daemon user";
diff --git a/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters.nix b/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters.nix
index 59748efe0de..cc71451bf20 100644
--- a/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters.nix
+++ b/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters.nix
@@ -46,6 +46,7 @@ let
"surfboard"
"tor"
"unifi"
+ "unifi-poller"
"varnish"
"wireguard"
] (name:
@@ -84,7 +85,8 @@ let
};
firewallFilter = mkOption {
type = types.str;
- default = "-p tcp -m tcp --dport ${toString port}";
+ default = "-p tcp -m tcp --dport ${toString cfg.${name}.port}";
+ defaultText = "-p tcp -m tcp --dport ${toString port}";
example = literalExample ''
"-i eth0 -p tcp -m tcp --dport ${toString port}"
'';
diff --git a/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters/unifi-poller.nix b/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters/unifi-poller.nix
new file mode 100644
index 00000000000..394e6e201f0
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters/unifi-poller.nix
@@ -0,0 +1,34 @@
+{ config, lib, pkgs, options }:
+
+with lib;
+
+let
+ cfg = config.services.prometheus.exporters.unifi-poller;
+
+ configFile = pkgs.writeText "prometheus-unifi-poller-exporter.json" (generators.toJSON {} {
+ poller = { inherit (cfg.log) debug quiet; };
+ unifi = { inherit (cfg) controllers; };
+ influxdb.disable = true;
+ prometheus = {
+ http_listen = "${cfg.listenAddress}:${toString cfg.port}";
+ report_errors = cfg.log.prometheusErrors;
+ };
+ });
+
+in {
+ port = 9130;
+
+ extraOpts = {
+ inherit (options.services.unifi-poller.unifi) controllers;
+ log = {
+ debug = mkEnableOption "debug logging including line numbers, high resolution timestamps, per-device logs.";
+ quiet = mkEnableOption "startup and error logs only.";
+ prometheusErrors = mkEnableOption "emitting errors to prometheus.";
+ };
+ };
+
+ serviceOpts.serviceConfig = {
+ ExecStart = "${pkgs.unifi-poller}/bin/unifi-poller --config ${configFile}";
+ DynamicUser = false;
+ };
+}
diff --git a/nixpkgs/nixos/modules/services/monitoring/smartd.nix b/nixpkgs/nixos/modules/services/monitoring/smartd.nix
index c345ec48a01..c72b4abfcdc 100644
--- a/nixpkgs/nixos/modules/services/monitoring/smartd.nix
+++ b/nixpkgs/nixos/modules/services/monitoring/smartd.nix
@@ -18,9 +18,9 @@ let
${optionalString nm.enable ''
{
${pkgs.coreutils}/bin/cat << EOF
- From: smartd on ${host} <root>
+ From: smartd on ${host} <${nm.sender}>
To: undisclosed-recipients:;
- Subject: SMART error on $SMARTD_DEVICESTRING: $SMARTD_FAILTYPE
+ Subject: $SMARTD_SUBJECT
$SMARTD_FULLMESSAGE
EOF
@@ -129,6 +129,16 @@ in
description = "Whenever to send e-mail notifications.";
};
+ sender = mkOption {
+ default = "root";
+ example = "example@domain.tld";
+ type = types.str;
+ description = ''
+ Sender of the notification messages.
+ Acts as the value of <literal>email</literal> in the emails' <literal>From: ... </literal> field.
+ '';
+ };
+
recipient = mkOption {
default = "root";
type = types.str;
@@ -229,11 +239,7 @@ in
systemd.services.smartd = {
description = "S.M.A.R.T. Daemon";
-
wantedBy = [ "multi-user.target" ];
-
- path = [ pkgs.nettools ]; # for hostname and dnsdomanname calls in smartd
-
serviceConfig.ExecStart = "${pkgs.smartmontools}/sbin/smartd ${lib.concatStringsSep " " cfg.extraOptions} --no-fork --configfile=${smartdConf}";
};
diff --git a/nixpkgs/nixos/modules/services/monitoring/teamviewer.nix b/nixpkgs/nixos/modules/services/monitoring/teamviewer.nix
index dd98ecab828..8d781d82d08 100644
--- a/nixpkgs/nixos/modules/services/monitoring/teamviewer.nix
+++ b/nixpkgs/nixos/modules/services/monitoring/teamviewer.nix
@@ -15,7 +15,7 @@ in
options = {
services.teamviewer.enable = mkEnableOption "TeamViewer daemon";
-
+
};
###### implementation
diff --git a/nixpkgs/nixos/modules/services/monitoring/unifi-poller.nix b/nixpkgs/nixos/modules/services/monitoring/unifi-poller.nix
new file mode 100644
index 00000000000..208f5e4875b
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/monitoring/unifi-poller.nix
@@ -0,0 +1,242 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.unifi-poller;
+
+ configFile = pkgs.writeText "unifi-poller.json" (generators.toJSON {} {
+ inherit (cfg) poller influxdb prometheus unifi;
+ });
+
+in {
+ options.services.unifi-poller = {
+ enable = mkEnableOption "unifi-poller";
+
+ poller = {
+ debug = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Turns on line numbers, microsecond logging, and a per-device log.
+ This may be noisy if you have a lot of devices. It adds one line per device.
+ '';
+ };
+ quiet = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Turns off per-interval logs. Only startup and error logs will be emitted.
+ '';
+ };
+ plugins = mkOption {
+ type = with types; listOf str;
+ default = [];
+ description = ''
+ Load additional plugins.
+ '';
+ };
+ };
+
+ prometheus = {
+ disable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to disable the prometheus ouput plugin.
+ '';
+ };
+ http_listen = mkOption {
+ type = types.str;
+ default = "[::]:9130";
+ description = ''
+ Bind the prometheus exporter to this IP or hostname.
+ '';
+ };
+ report_errors = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to report errors.
+ '';
+ };
+ };
+
+ influxdb = {
+ disable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to disable the influxdb ouput plugin.
+ '';
+ };
+ url = mkOption {
+ type = types.str;
+ default = "http://127.0.0.1:8086";
+ description = ''
+ URL of the influxdb host.
+ '';
+ };
+ user = mkOption {
+ type = types.str;
+ default = "unifipoller";
+ description = ''
+ Username for the influxdb.
+ '';
+ };
+ pass = mkOption {
+ type = types.path;
+ default = pkgs.writeText "unifi-poller-influxdb-default.password" "unifipoller";
+ defaultText = "unifi-poller-influxdb-default.password";
+ description = ''
+ Path of a file containing the password for influxdb.
+ This file needs to be readable by the unifi-poller user.
+ '';
+ apply = v: "file://${v}";
+ };
+ db = mkOption {
+ type = types.str;
+ default = "unifi";
+ description = ''
+ Database name. Database should exist.
+ '';
+ };
+ verify_ssl = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Verify the influxdb's certificate.
+ '';
+ };
+ interval = mkOption {
+ type = types.str;
+ default = "30s";
+ description = ''
+ Setting this lower than the Unifi controller's refresh
+ interval may lead to zeroes in your database.
+ '';
+ };
+ };
+
+ unifi = let
+ controllerOptions = {
+ user = mkOption {
+ type = types.str;
+ default = "unifi";
+ description = ''
+ Unifi service user name.
+ '';
+ };
+ pass = mkOption {
+ type = types.path;
+ default = pkgs.writeText "unifi-poller-unifi-default.password" "unifi";
+ defaultText = "unifi-poller-unifi-default.password";
+ description = ''
+ Path of a file containing the password for the unifi service user.
+ This file needs to be readable by the unifi-poller user.
+ '';
+ apply = v: "file://${v}";
+ };
+ url = mkOption {
+ type = types.str;
+ default = "https://unifi:8443";
+ description = ''
+ URL of the Unifi controller.
+ '';
+ };
+ sites = mkOption {
+ type = with types; either (enum [ "default" "all" ]) (listOf str);
+ default = "all";
+ description = ''
+ List of site names for which statistics should be exported.
+ Or the string "default" for the default site or the string "all" for all sites.
+ '';
+ apply = toList;
+ };
+ save_ids = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Collect and save data from the intrusion detection system to influxdb.
+ '';
+ };
+ save_dpi = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Collect and save data from deep packet inspection.
+ Adds around 150 data points and impacts performance.
+ '';
+ };
+ save_sites = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Collect and save site data.
+ '';
+ };
+ hash_pii = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Hash, with md5, client names and MAC addresses. This attempts
+ to protect personally identifiable information.
+ '';
+ };
+ verify_ssl = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Verify the Unifi controller's certificate.
+ '';
+ };
+ };
+
+ in {
+ dynamic = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Let prometheus select which controller to poll when scraping.
+ Use with default credentials. See unifi-poller wiki for more.
+ '';
+ };
+
+ defaults = controllerOptions;
+
+ controllers = mkOption {
+ type = with types; listOf (submodule { options = controllerOptions; });
+ default = [];
+ description = ''
+ List of Unifi controllers to poll. Use defaults if empty.
+ '';
+ apply = map (flip removeAttrs [ "_module" ]);
+ };
+ };
+ };
+
+ config = mkIf cfg.enable {
+ users.groups.unifi-poller = { };
+ users.users.unifi-poller = {
+ description = "unifi-poller Service User";
+ group = "unifi-poller";
+ isSystemUser = true;
+ };
+
+ systemd.services.unifi-poller = {
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network.target" ];
+ serviceConfig = {
+ ExecStart = "${pkgs.unifi-poller}/bin/unifi-poller --config ${configFile}";
+ Restart = "always";
+ PrivateTmp = true;
+ ProtectHome = true;
+ ProtectSystem = "full";
+ DevicePolicy = "closed";
+ NoNewPrivileges = true;
+ User = "unifi-poller";
+ WorkingDirectory = "/tmp";
+ };
+ };
+ };
+}
diff --git a/nixpkgs/nixos/modules/services/monitoring/zabbix-proxy.nix b/nixpkgs/nixos/modules/services/monitoring/zabbix-proxy.nix
index d51507c91a1..2c8b8b92cb3 100644
--- a/nixpkgs/nixos/modules/services/monitoring/zabbix-proxy.nix
+++ b/nixpkgs/nixos/modules/services/monitoring/zabbix-proxy.nix
@@ -5,8 +5,8 @@ let
pgsql = config.services.postgresql;
mysql = config.services.mysql;
- inherit (lib) mkDefault mkEnableOption mkIf mkMerge mkOption;
- inherit (lib) attrValues concatMapStringsSep literalExample optional optionalAttrs optionalString types;
+ inherit (lib) mkAfter mkDefault mkEnableOption mkIf mkMerge mkOption;
+ inherit (lib) attrValues concatMapStringsSep getName literalExample optional optionalAttrs optionalString types;
inherit (lib.generators) toKeyValue;
user = "zabbix";
@@ -232,14 +232,15 @@ in
services.mysql = optionalAttrs mysqlLocal {
enable = true;
package = mkDefault pkgs.mariadb;
- ensureDatabases = [ cfg.database.name ];
- ensureUsers = [
- { name = cfg.database.user;
- ensurePermissions = { "${cfg.database.name}.*" = "ALL PRIVILEGES"; };
- }
- ];
};
+ systemd.services.mysql.postStart = mkAfter (optionalString mysqlLocal ''
+ ( echo "CREATE DATABASE IF NOT EXISTS \`${cfg.database.name}\` CHARACTER SET utf8 COLLATE utf8_bin;"
+ echo "CREATE USER IF NOT EXISTS '${cfg.database.user}'@'localhost' IDENTIFIED WITH ${if (getName config.services.mysql.package == getName pkgs.mariadb) then "unix_socket" else "auth_socket"};"
+ echo "GRANT ALL PRIVILEGES ON \`${cfg.database.name}\`.* TO '${cfg.database.user}'@'localhost';"
+ ) | ${config.services.mysql.package}/bin/mysql -N
+ '');
+
services.postgresql = optionalAttrs pgsqlLocal {
enable = true;
ensureDatabases = [ cfg.database.name ];
diff --git a/nixpkgs/nixos/modules/services/monitoring/zabbix-server.nix b/nixpkgs/nixos/modules/services/monitoring/zabbix-server.nix
index df09488a8cc..c8658634ecb 100644
--- a/nixpkgs/nixos/modules/services/monitoring/zabbix-server.nix
+++ b/nixpkgs/nixos/modules/services/monitoring/zabbix-server.nix
@@ -5,8 +5,8 @@ let
pgsql = config.services.postgresql;
mysql = config.services.mysql;
- inherit (lib) mkDefault mkEnableOption mkIf mkMerge mkOption;
- inherit (lib) attrValues concatMapStringsSep literalExample optional optionalAttrs optionalString types;
+ inherit (lib) mkAfter mkDefault mkEnableOption mkIf mkMerge mkOption;
+ inherit (lib) attrValues concatMapStringsSep getName literalExample optional optionalAttrs optionalString types;
inherit (lib.generators) toKeyValue;
user = "zabbix";
@@ -220,14 +220,15 @@ in
services.mysql = optionalAttrs mysqlLocal {
enable = true;
package = mkDefault pkgs.mariadb;
- ensureDatabases = [ cfg.database.name ];
- ensureUsers = [
- { name = cfg.database.user;
- ensurePermissions = { "${cfg.database.name}.*" = "ALL PRIVILEGES"; };
- }
- ];
};
+ systemd.services.mysql.postStart = mkAfter (optionalString mysqlLocal ''
+ ( echo "CREATE DATABASE IF NOT EXISTS \`${cfg.database.name}\` CHARACTER SET utf8 COLLATE utf8_bin;"
+ echo "CREATE USER IF NOT EXISTS '${cfg.database.user}'@'localhost' IDENTIFIED WITH ${if (getName config.services.mysql.package == getName pkgs.mariadb) then "unix_socket" else "auth_socket"};"
+ echo "GRANT ALL PRIVILEGES ON \`${cfg.database.name}\`.* TO '${cfg.database.user}'@'localhost';"
+ ) | ${config.services.mysql.package}/bin/mysql -N
+ '');
+
services.postgresql = optionalAttrs pgsqlLocal {
enable = true;
ensureDatabases = [ cfg.database.name ];
diff --git a/nixpkgs/nixos/modules/services/network-filesystems/cachefilesd.nix b/nixpkgs/nixos/modules/services/network-filesystems/cachefilesd.nix
index 61981340840..229c9665419 100644
--- a/nixpkgs/nixos/modules/services/network-filesystems/cachefilesd.nix
+++ b/nixpkgs/nixos/modules/services/network-filesystems/cachefilesd.nix
@@ -43,17 +43,21 @@ in
config = mkIf cfg.enable {
+ boot.kernelModules = [ "cachefiles" ];
+
systemd.services.cachefilesd = {
description = "Local network file caching management daemon";
wantedBy = [ "multi-user.target" ];
- path = [ pkgs.kmod pkgs.cachefilesd ];
- script = ''
- modprobe -qab cachefiles
- mkdir -p ${cfg.cacheDir}
- chmod 700 ${cfg.cacheDir}
- exec cachefilesd -n -f ${cfgFile}
- '';
+ serviceConfig = {
+ Type = "exec";
+ ExecStart = "${pkgs.cachefilesd}/bin/cachefilesd -n -f ${cfgFile}";
+ Restart = "on-failure";
+ PrivateTmp = true;
+ };
};
+ systemd.tmpfiles.rules = [
+ "d ${cfg.cacheDir} 0700 root root - -"
+ ];
};
}
diff --git a/nixpkgs/nixos/modules/services/network-filesystems/ipfs.nix b/nixpkgs/nixos/modules/services/network-filesystems/ipfs.nix
index 7d18410ff0a..f298f831fa7 100644
--- a/nixpkgs/nixos/modules/services/network-filesystems/ipfs.nix
+++ b/nixpkgs/nixos/modules/services/network-filesystems/ipfs.nix
@@ -25,6 +25,15 @@ let
then "/${lib.concatStringsSep "/" (lib.tail addr)}"
else null; # not valid for listen stream, skip
+ multiaddrToListenDatagram = addrRaw: let
+ addr = splitMulitaddr addrRaw;
+ s = builtins.elemAt addr;
+ in if s 0 == "ip4" && s 2 == "udp"
+ then "${s 1}:${s 3}"
+ else if s 0 == "ip6" && s 2 == "udp"
+ then "[${s 1}]:${s 3}"
+ else null; # not valid for listen datagram, skip
+
in {
###### interface
@@ -96,6 +105,8 @@ in {
default = [
"/ip4/0.0.0.0/tcp/4001"
"/ip6/::/tcp/4001"
+ "/ip4/0.0.0.0/udp/4001/quic"
+ "/ip6/::/udp/4001/quic"
];
description = "Where IPFS listens for incoming p2p connections";
};
@@ -266,9 +277,14 @@ in {
systemd.sockets.ipfs-gateway = {
wantedBy = [ "sockets.target" ];
- socketConfig.ListenStream = let
- fromCfg = multiaddrToListenStream cfg.gatewayAddress;
- in [ "" ] ++ lib.optional (fromCfg != null) fromCfg;
+ socketConfig = {
+ ListenStream = let
+ fromCfg = multiaddrToListenStream cfg.gatewayAddress;
+ in [ "" ] ++ lib.optional (fromCfg != null) fromCfg;
+ ListenDatagram = let
+ fromCfg = multiaddrToListenDatagram cfg.gatewayAddress;
+ in [ "" ] ++ lib.optional (fromCfg != null) fromCfg;
+ };
};
systemd.sockets.ipfs-api = {
diff --git a/nixpkgs/nixos/modules/services/network-filesystems/orangefs/server.nix b/nixpkgs/nixos/modules/services/network-filesystems/orangefs/server.nix
index 74ebdc13402..8eb754fe611 100644
--- a/nixpkgs/nixos/modules/services/network-filesystems/orangefs/server.nix
+++ b/nixpkgs/nixos/modules/services/network-filesystems/orangefs/server.nix
@@ -83,14 +83,14 @@ in {
};
dataStorageSpace = mkOption {
- type = types.str;
+ type = types.nullOr types.str;
default = null;
example = "/data/storage";
description = "Directory for data storage.";
};
metadataStorageSpace = mkOption {
- type = types.str;
+ type = types.nullOr types.str;
default = null;
example = "/data/meta";
description = "Directory for meta data storage.";
diff --git a/nixpkgs/nixos/modules/services/network-filesystems/samba.nix b/nixpkgs/nixos/modules/services/network-filesystems/samba.nix
index 08c912e0fcd..7d3c601d6cd 100644
--- a/nixpkgs/nixos/modules/services/network-filesystems/samba.nix
+++ b/nixpkgs/nixos/modules/services/network-filesystems/samba.nix
@@ -248,7 +248,7 @@ in
};
security.pam.services.samba = {};
-
+ environment.systemPackages = [ config.services.samba.package ];
})
];
diff --git a/nixpkgs/nixos/modules/services/networking/biboumi.nix b/nixpkgs/nixos/modules/services/networking/biboumi.nix
new file mode 100644
index 00000000000..66ddca93d81
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/networking/biboumi.nix
@@ -0,0 +1,269 @@
+{ config, lib, pkgs, options, ... }:
+with lib;
+let
+ cfg = config.services.biboumi;
+ inherit (config.environment) etc;
+ rootDir = "/run/biboumi/mnt-root";
+ stateDir = "/var/lib/biboumi";
+ settingsFile = pkgs.writeText "biboumi.cfg" (
+ generators.toKeyValue {
+ mkKeyValue = k: v:
+ if v == null then ""
+ else generators.mkKeyValueDefault {} "=" k v;
+ } cfg.settings);
+ need_CAP_NET_BIND_SERVICE = cfg.settings.identd_port != 0 && cfg.settings.identd_port < 1024;
+in
+{
+ options = {
+ services.biboumi = {
+ enable = mkEnableOption "the Biboumi XMPP gateway to IRC";
+
+ settings = mkOption {
+ description = ''
+ See <link xlink:href="https://lab.louiz.org/louiz/biboumi/blob/8.5/doc/biboumi.1.rst">biboumi 8.5</link>
+ for documentation.
+ '';
+ default = {};
+ type = types.submodule {
+ freeformType = with types;
+ (attrsOf (nullOr (oneOf [str int bool]))) // {
+ description = "settings option";
+ };
+ options.admin = mkOption {
+ type = with types; listOf str;
+ default = [];
+ example = ["admin@example.org"];
+ apply = concatStringsSep ":";
+ description = ''
+ The bare JID of the gateway administrator. This JID will have more
+ privileges than other standard users, for example some administration
+ ad-hoc commands will only be available to that JID.
+ '';
+ };
+ options.ca_file = mkOption {
+ type = types.path;
+ default = "/etc/ssl/certs/ca-certificates.crt";
+ description = ''
+ Specifies which file should be used as the list of trusted CA
+ when negociating a TLS session.
+ '';
+ };
+ options.db_name = mkOption {
+ type = with types; either path str;
+ default = "${stateDir}/biboumi.sqlite";
+ description = ''
+ The name of the database to use.
+ '';
+ example = "postgresql://user:secret@localhost";
+ };
+ options.hostname = mkOption {
+ type = types.str;
+ example = "biboumi.example.org";
+ description = ''
+ The hostname served by the XMPP gateway.
+ This domain must be configured in the XMPP server
+ as an external component.
+ '';
+ };
+ options.identd_port = mkOption {
+ type = types.port;
+ default = 113;
+ example = 0;
+ description = ''
+ The TCP port on which to listen for identd queries.
+ '';
+ };
+ options.log_level = mkOption {
+ type = types.ints.between 0 3;
+ default = 1;
+ description = ''
+ Indicate what type of log messages to write in the logs.
+ 0 is debug, 1 is info, 2 is warning, 3 is error.
+ '';
+ };
+ options.password = mkOption {
+ type = with types; nullOr str;
+ description = ''
+ The password used to authenticate the XMPP component to your XMPP server.
+ This password must be configured in the XMPP server,
+ associated with the external component on
+ <link linkend="opt-services.biboumi.settings.hostname">hostname</link>.
+
+ Set it to null and use <link linkend="opt-services.biboumi.credentialsFile">credentialsFile</link>
+ if you do not want this password to go into the Nix store.
+ '';
+ };
+ options.persistent_by_default = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether all rooms will be persistent by default:
+ the value of the “persistent” option in the global configuration of each
+ user will be “true”, but the value of each individual room will still
+ default to false. This means that a user just needs to change the global
+ “persistent” configuration option to false in order to override this.
+ '';
+ };
+ options.policy_directory = mkOption {
+ type = types.path;
+ default = "${pkgs.biboumi}/etc/biboumi";
+ description = ''
+ A directory that should contain the policy files,
+ used to customize Botan’s behaviour
+ when negociating the TLS connections with the IRC servers.
+ '';
+ };
+ options.port = mkOption {
+ type = types.port;
+ default = 5347;
+ description = ''
+ The TCP port to use to connect to the local XMPP component.
+ '';
+ };
+ options.realname_customization = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Whether the users will be able to use
+ the ad-hoc commands that lets them configure
+ their realname and username.
+ '';
+ };
+ options.realname_from_jid = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether the realname and username of each biboumi
+ user will be extracted from their JID.
+ Otherwise they will be set to the nick
+ they used to connect to the IRC server.
+ '';
+ };
+ options.xmpp_server_ip = mkOption {
+ type = types.str;
+ default = "127.0.0.1";
+ description = ''
+ The IP address to connect to the XMPP server on.
+ The connection to the XMPP server is unencrypted,
+ so the biboumi instance and the server should
+ normally be on the same host.
+ '';
+ };
+ };
+ };
+
+ credentialsFile = mkOption {
+ type = types.path;
+ description = ''
+ Path to a configuration file to be merged with the settings.
+ Beware not to surround "=" with spaces when setting biboumi's options in this file.
+ Useful to merge a file which is better kept out of the Nix store
+ because it contains sensible data like
+ <link linkend="opt-services.biboumi.settings.password">password</link>.
+ '';
+ default = "/dev/null";
+ example = "/run/keys/biboumi.cfg";
+ };
+
+ openFirewall = mkEnableOption "opening of the identd port in the firewall";
+ };
+ };
+
+ config = mkIf cfg.enable {
+ networking.firewall = mkIf (cfg.openFirewall && cfg.settings.identd_port != 0)
+ { allowedTCPPorts = [ cfg.settings.identd_port ]; };
+
+ systemd.services.biboumi = {
+ description = "Biboumi, XMPP to IRC gateway";
+ after = [ "network.target" ];
+ wantedBy = [ "multi-user.target" ];
+
+ serviceConfig = {
+ Type = "notify";
+ # Biboumi supports systemd's watchdog.
+ WatchdogSec = 20;
+ Restart = "always";
+ # Use "+" because credentialsFile may not be accessible to User= or Group=.
+ ExecStartPre = [("+" + pkgs.writeShellScript "biboumi-prestart" ''
+ set -eux
+ cat ${settingsFile} '${cfg.credentialsFile}' |
+ install -m 644 /dev/stdin /run/biboumi/biboumi.cfg
+ '')];
+ ExecStart = "${pkgs.biboumi}/bin/biboumi /run/biboumi/biboumi.cfg";
+ ExecReload = "${pkgs.coreutils}/bin/kill -USR1 $MAINPID";
+ # Firewalls needing opening for output connections can still do that
+ # selectively for biboumi with:
+ # users.users.biboumi.isSystemUser = true;
+ # and, for example:
+ # networking.nftables.ruleset = ''
+ # add rule inet filter output meta skuid biboumi tcp accept
+ # '';
+ DynamicUser = true;
+ RootDirectory = rootDir;
+ RootDirectoryStartOnly = true;
+ InaccessiblePaths = [ "-+${rootDir}" ];
+ RuntimeDirectory = [ "biboumi" (removePrefix "/run/" rootDir) ];
+ RuntimeDirectoryMode = "700";
+ StateDirectory = "biboumi";
+ StateDirectoryMode = "700";
+ MountAPIVFS = true;
+ UMask = "0066";
+ BindPaths = [
+ stateDir
+ # This is for Type="notify"
+ # See https://github.com/systemd/systemd/issues/3544
+ "/run/systemd/notify"
+ "/run/systemd/journal/socket"
+ ];
+ BindReadOnlyPaths = [
+ builtins.storeDir
+ "/etc"
+ ];
+ # The following options are only for optimizing:
+ # systemd-analyze security biboumi
+ AmbientCapabilities = [ (optionalString need_CAP_NET_BIND_SERVICE "CAP_NET_BIND_SERVICE") ];
+ CapabilityBoundingSet = [ (optionalString need_CAP_NET_BIND_SERVICE "CAP_NET_BIND_SERVICE") ];
+ # ProtectClock= adds DeviceAllow=char-rtc r
+ DeviceAllow = "";
+ LockPersonality = true;
+ MemoryDenyWriteExecute = true;
+ NoNewPrivileges = true;
+ PrivateDevices = true;
+ PrivateMounts = true;
+ PrivateNetwork = mkDefault false;
+ PrivateTmp = true;
+ # PrivateUsers=true breaks AmbientCapabilities=CAP_NET_BIND_SERVICE
+ # See https://bugs.archlinux.org/task/65921
+ PrivateUsers = !need_CAP_NET_BIND_SERVICE;
+ ProtectClock = true;
+ ProtectControlGroups = true;
+ ProtectHome = true;
+ ProtectHostname = true;
+ ProtectKernelLogs = true;
+ ProtectKernelModules = true;
+ ProtectKernelTunables = true;
+ ProtectSystem = "strict";
+ RemoveIPC = true;
+ # AF_UNIX is for /run/systemd/notify
+ RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ];
+ RestrictNamespaces = true;
+ RestrictRealtime = true;
+ RestrictSUIDSGID = true;
+ SystemCallFilter = [
+ "@system-service"
+ # Groups in @system-service which do not contain a syscall
+ # listed by perf stat -e 'syscalls:sys_enter_*' biboumi biboumi.cfg
+ # in tests, and seem likely not necessary for biboumi.
+ # To run such a perf in ExecStart=, you have to:
+ # - AmbientCapabilities="CAP_SYS_ADMIN"
+ # - mount -o remount,mode=755 /sys/kernel/debug/{,tracing}
+ "~@aio" "~@chown" "~@ipc" "~@keyring" "~@resources" "~@setuid" "~@timer"
+ ];
+ SystemCallArchitectures = "native";
+ SystemCallErrorNumber = "EPERM";
+ };
+ };
+ };
+
+ meta.maintainers = with maintainers; [ julm ];
+}
diff --git a/nixpkgs/nixos/modules/services/networking/bitcoind.nix b/nixpkgs/nixos/modules/services/networking/bitcoind.nix
index 38537ad2de7..bc9aa53f49a 100644
--- a/nixpkgs/nixos/modules/services/networking/bitcoind.nix
+++ b/nixpkgs/nixos/modules/services/networking/bitcoind.nix
@@ -183,8 +183,8 @@ in
}
]) eachBitcoind);
- environment.systemPackages = flatten (mapAttrsToList (bitcoindName: cfg: [
- cfg.package
+ environment.systemPackages = flatten (mapAttrsToList (bitcoindName: cfg: [
+ cfg.package
]) eachBitcoind);
systemd.services = mapAttrs' (bitcoindName: cfg: (
@@ -256,6 +256,6 @@ in
};
- meta.maintainers = with maintainers; [ maintainers."1000101" ];
+ meta.maintainers = with maintainers; [ _1000101 ];
}
diff --git a/nixpkgs/nixos/modules/services/networking/blockbook-frontend.nix b/nixpkgs/nixos/modules/services/networking/blockbook-frontend.nix
index 61938e51e06..dde24522756 100644
--- a/nixpkgs/nixos/modules/services/networking/blockbook-frontend.nix
+++ b/nixpkgs/nixos/modules/services/networking/blockbook-frontend.nix
@@ -269,4 +269,7 @@ in
users.groups = mapAttrs' (instanceName: cfg: (
nameValuePair "${cfg.group}" { })) eachBlockbook;
};
+
+ meta.maintainers = with maintainers; [ _1000101 ];
+
}
diff --git a/nixpkgs/nixos/modules/services/networking/corerad.nix b/nixpkgs/nixos/modules/services/networking/corerad.nix
index 1c414c53a98..d90a5923bc6 100644
--- a/nixpkgs/nixos/modules/services/networking/corerad.nix
+++ b/nixpkgs/nixos/modules/services/networking/corerad.nix
@@ -81,6 +81,7 @@ in {
NotifyAccess = "main";
ExecStart = "${getBin cfg.package}/bin/corerad -c=${cfg.configFile}";
Restart = "on-failure";
+ RestartKillSignal = "SIGHUP";
};
};
};
diff --git a/nixpkgs/nixos/modules/services/networking/gateone.nix b/nixpkgs/nixos/modules/services/networking/gateone.nix
index 4456a95402e..56f2ba21a12 100644
--- a/nixpkgs/nixos/modules/services/networking/gateone.nix
+++ b/nixpkgs/nixos/modules/services/networking/gateone.nix
@@ -56,4 +56,4 @@ config = mkIf cfg.enable {
};
};
}
-
+
diff --git a/nixpkgs/nixos/modules/services/networking/hylafax/options.nix b/nixpkgs/nixos/modules/services/networking/hylafax/options.nix
index 4ac6d3fa843..9e28d09dffc 100644
--- a/nixpkgs/nixos/modules/services/networking/hylafax/options.nix
+++ b/nixpkgs/nixos/modules/services/networking/hylafax/options.nix
@@ -3,7 +3,7 @@
let
inherit (lib.options) literalExample mkEnableOption mkOption;
- inherit (lib.types) bool enum int lines loaOf nullOr path str submodule;
+ inherit (lib.types) bool enum int lines attrsOf nullOr path str submodule;
inherit (lib.modules) mkDefault mkIf mkMerge;
commonDescr = ''
@@ -248,7 +248,7 @@ in
};
modems = mkOption {
- type = loaOf (submodule [ modemConfigOptions ]);
+ type = attrsOf (submodule [ modemConfigOptions ]);
default = {};
example.ttyS1 = {
type = "cirrus";
diff --git a/nixpkgs/nixos/modules/services/networking/kresd.nix b/nixpkgs/nixos/modules/services/networking/kresd.nix
index 26ddd4e811e..ccb34163d5f 100644
--- a/nixpkgs/nixos/modules/services/networking/kresd.nix
+++ b/nixpkgs/nixos/modules/services/networking/kresd.nix
@@ -129,13 +129,17 @@ in {
systemd.services."kresd@".serviceConfig = {
ExecStart = "${package}/bin/kresd --noninteractive "
+ "-c ${package}/lib/knot-resolver/distro-preconfig.lua -c ${configFile}";
- # Ensure correct ownership in case UID or GID changes.
+ # Ensure /run/knot-resolver exists
+ RuntimeDirectory = "knot-resolver";
+ RuntimeDirectoryMode = "0770";
+ # Ensure /var/lib/knot-resolver exists
+ StateDirectory = "knot-resolver";
+ StateDirectoryMode = "0770";
+ # Ensure /var/cache/knot-resolver exists
CacheDirectory = "knot-resolver";
- CacheDirectoryMode = "0750";
+ CacheDirectoryMode = "0770";
};
- systemd.tmpfiles.packages = [ package ];
-
# Try cleaning up the previously default location of cache file.
# Note that /var/cache/* should always be safe to remove.
# TODO: remove later, probably between 20.09 and 21.03
diff --git a/nixpkgs/nixos/modules/services/networking/monero.nix b/nixpkgs/nixos/modules/services/networking/monero.nix
index 97af2997839..fde3293fc13 100644
--- a/nixpkgs/nixos/modules/services/networking/monero.nix
+++ b/nixpkgs/nixos/modules/services/networking/monero.nix
@@ -87,7 +87,7 @@ in
};
rpc.password = mkOption {
- type = types.str;
+ type = types.nullOr types.str;
default = null;
description = ''
Password for RPC connections.
diff --git a/nixpkgs/nixos/modules/services/networking/mstpd.nix b/nixpkgs/nixos/modules/services/networking/mstpd.nix
index 5d1fc4a6542..bd71010ce54 100644
--- a/nixpkgs/nixos/modules/services/networking/mstpd.nix
+++ b/nixpkgs/nixos/modules/services/networking/mstpd.nix
@@ -5,7 +5,7 @@ in
with lib;
{
options.services.mstpd = {
-
+
enable = mkOption {
default = false;
type = types.bool;
diff --git a/nixpkgs/nixos/modules/services/networking/namecoind.nix b/nixpkgs/nixos/modules/services/networking/namecoind.nix
index 6ca99e1321b..16f85df2e77 100644
--- a/nixpkgs/nixos/modules/services/networking/namecoind.nix
+++ b/nixpkgs/nixos/modules/services/networking/namecoind.nix
@@ -89,7 +89,7 @@ in
};
rpc.password = mkOption {
- type = types.str;
+ type = types.nullOr types.str;
default = null;
description = ''
Password for RPC connections.
diff --git a/nixpkgs/nixos/modules/services/networking/networkmanager.nix b/nixpkgs/nixos/modules/services/networking/networkmanager.nix
index cc789897b29..17c549d42c3 100644
--- a/nixpkgs/nixos/modules/services/networking/networkmanager.nix
+++ b/nixpkgs/nixos/modules/services/networking/networkmanager.nix
@@ -458,7 +458,7 @@ in {
systemd.services.NetworkManager-dispatcher = {
wantedBy = [ "network.target" ];
- restartTriggers = [ configFile ];
+ restartTriggers = [ configFile overrideNameserversScript ];
# useful binaries for user-specified hooks
path = [ pkgs.iproute pkgs.utillinux pkgs.coreutils ];
diff --git a/nixpkgs/nixos/modules/services/networking/nextdns.nix b/nixpkgs/nixos/modules/services/networking/nextdns.nix
new file mode 100644
index 00000000000..a633bff62ec
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/networking/nextdns.nix
@@ -0,0 +1,44 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.nextdns;
+in {
+ options = {
+ services.nextdns = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Whether to enable the NextDNS DNS/53 to DoH Proxy service.";
+ };
+ arguments = mkOption {
+ type = types.listOf types.str;
+ default = [];
+ example = [ "-config" "10.0.3.0/24=abcdef" ];
+ description = "Additional arguments to be passed to nextdns run.";
+ };
+ };
+ };
+
+ # https://github.com/nextdns/nextdns/blob/628ea509eaaccd27adb66337db03e5b56f6f38a8/host/service/systemd/service.go
+ config = mkIf cfg.enable {
+ systemd.services.nextdns = {
+ description = "NextDNS DNS/53 to DoH Proxy";
+ environment = {
+ SERVICE_RUN_MODE = "1";
+ };
+ serviceConfig = {
+ StartLimitInterval = 5;
+ StartLimitBurst = 10;
+ ExecStart = "${pkgs.nextdns}/bin/nextdns run ${escapeShellArgs config.services.nextdns.arguments}";
+ RestartSec = 120;
+ LimitMEMLOCK = "infinity";
+ };
+ after = [ "network.target" ];
+ before = [ "nss-lookup.target" ];
+ wants = [ "nss-lookup.target" ];
+ wantedBy = [ "multi-user.target" ];
+ };
+ };
+}
diff --git a/nixpkgs/nixos/modules/services/networking/nghttpx/default.nix b/nixpkgs/nixos/modules/services/networking/nghttpx/default.nix
index 881a2670f5d..b8a0a24e3aa 100644
--- a/nixpkgs/nixos/modules/services/networking/nghttpx/default.nix
+++ b/nixpkgs/nixos/modules/services/networking/nghttpx/default.nix
@@ -60,7 +60,7 @@ let
# NB: nghttpx doesn't accept "tls", you must omit "no-tls" for
# the default behavior of turning on TLS.
params1 = lib.remove "tls" params0;
-
+
sections = [ host] ++ params1;
formattedSections = lib.concatStringsSep ";" sections;
in
@@ -90,7 +90,7 @@ in
{ imports = [
./nghttpx-options.nix
];
-
+
config = lib.mkIf cfg.enable {
users.groups.nghttpx = { };
@@ -98,7 +98,7 @@ in
group = config.users.groups.nghttpx.name;
isSystemUser = true;
};
-
+
systemd.services = {
nghttpx = {
diff --git a/nixpkgs/nixos/modules/services/networking/ntp/chrony.nix b/nixpkgs/nixos/modules/services/networking/ntp/chrony.nix
index b7e4c89a155..78de50583f3 100644
--- a/nixpkgs/nixos/modules/services/networking/ntp/chrony.nix
+++ b/nixpkgs/nixos/modules/services/networking/ntp/chrony.nix
@@ -117,7 +117,6 @@ in
ProtectHome = "yes";
ProtectSystem = "full";
PrivateTmp = "yes";
- StateDirectory = "chrony";
};
};
diff --git a/nixpkgs/nixos/modules/services/networking/nylon.nix b/nixpkgs/nixos/modules/services/networking/nylon.nix
index 7c171281a92..bfc358cb12f 100644
--- a/nixpkgs/nixos/modules/services/networking/nylon.nix
+++ b/nixpkgs/nixos/modules/services/networking/nylon.nix
@@ -140,7 +140,7 @@ in
services.nylon = mkOption {
default = {};
description = "Collection of named nylon instances";
- type = with types; loaOf (submodule nylonOpts);
+ type = with types; attrsOf (submodule nylonOpts);
internal = true;
};
diff --git a/nixpkgs/nixos/modules/services/networking/onedrive.nix b/nixpkgs/nixos/modules/services/networking/onedrive.nix
index a945250fa9e..210d2217b27 100644
--- a/nixpkgs/nixos/modules/services/networking/onedrive.nix
+++ b/nixpkgs/nixos/modules/services/networking/onedrive.nix
@@ -23,7 +23,7 @@ in {
### Documentation
# meta.doc = ./onedrive.xml;
- ### Interface
+ ### Interface
options.services.onedrive = {
enable = lib.mkOption {
diff --git a/nixpkgs/nixos/modules/services/networking/openvpn.nix b/nixpkgs/nixos/modules/services/networking/openvpn.nix
index dcd7e9e5fa4..650f9c84ac7 100644
--- a/nixpkgs/nixos/modules/services/networking/openvpn.nix
+++ b/nixpkgs/nixos/modules/services/networking/openvpn.nix
@@ -11,7 +11,7 @@ let
makeOpenVPNJob = cfg: name:
let
- path = (getAttr "openvpn-${name}" config.systemd.services).path;
+ path = makeBinPath (getAttr "openvpn-${name}" config.systemd.services).path;
upScript = ''
#! /bin/sh
diff --git a/nixpkgs/nixos/modules/services/networking/prosody.nix b/nixpkgs/nixos/modules/services/networking/prosody.nix
index cdd341c9fb6..a6c1cb0f479 100644
--- a/nixpkgs/nixos/modules/services/networking/prosody.nix
+++ b/nixpkgs/nixos/modules/services/networking/prosody.nix
@@ -655,7 +655,7 @@ in
description = "Define the virtual hosts";
- type = with types; loaOf (submodule vHostOpts);
+ type = with types; attrsOf (submodule vHostOpts);
example = {
myhost = {
@@ -772,7 +772,7 @@ in
};
disco_items = {
- ${ lib.concatStringsSep "\n" (builtins.map (x: ''{ "${x.url}", "${x.description}"};'') discoItems)}
+ ${ lib.concatStringsSep "\n" (builtins.map (x: ''{ "${x.url}", "${x.description}"};'') discoItems)}
};
allow_registration = ${toLua cfg.allowRegistration}
diff --git a/nixpkgs/nixos/modules/services/networking/prosody.xml b/nixpkgs/nixos/modules/services/networking/prosody.xml
index 7859cb1578b..471240cd147 100644
--- a/nixpkgs/nixos/modules/services/networking/prosody.xml
+++ b/nixpkgs/nixos/modules/services/networking/prosody.xml
@@ -43,10 +43,10 @@ services.prosody = {
<link linkend="opt-services.prosody.ssl.cert">ssl.cert</link> = "/var/lib/acme/example.org/fullchain.pem";
<link linkend="opt-services.prosody.ssl.key">ssl.key</link> = "/var/lib/acme/example.org/key.pem";
<link linkend="opt-services.prosody.virtualHosts">virtualHosts</link>."example.org" = {
- <link linkend="opt-services.prosody.virtualHosts._name__.enabled">enabled</link> = true;
- <link linkend="opt-services.prosody.virtualHosts._name__.domain">domain</link> = "example.org";
- <link linkend="opt-services.prosody.virtualHosts._name__.ssl.cert">ssl.cert</link> = "/var/lib/acme/example.org/fullchain.pem";
- <link linkend="opt-services.prosody.virtualHosts._name__.ssl.key">ssl.key</link> = "/var/lib/acme/example.org/key.pem";
+ <link linkend="opt-services.prosody.virtualHosts._name_.enabled">enabled</link> = true;
+ <link linkend="opt-services.prosody.virtualHosts._name_.domain">domain</link> = "example.org";
+ <link linkend="opt-services.prosody.virtualHosts._name_.ssl.cert">ssl.cert</link> = "/var/lib/acme/example.org/fullchain.pem";
+ <link linkend="opt-services.prosody.virtualHosts._name_.ssl.key">ssl.key</link> = "/var/lib/acme/example.org/key.pem";
};
<link linkend="opt-services.prosody.muc">muc</link> = [ {
<link linkend="opt-services.prosody.muc">domain</link> = "conference.example.org";
@@ -65,7 +65,7 @@ services.prosody = {
you'll need a single TLS certificate covering your main endpoint,
the MUC one as well as the HTTP Upload one. We can generate such a
certificate by leveraging the ACME
- <link linkend="opt-security.acme.certs._name_.extraDomains">extraDomains</link> module option.
+ <link linkend="opt-security.acme.certs._name_.extraDomainNames">extraDomainNames</link> module option.
</para>
<para>
Provided the setup detailed in the previous section, you'll need the following acme configuration to generate
@@ -78,8 +78,7 @@ security.acme = {
"example.org" = {
<link linkend="opt-security.acme.certs._name_.webroot">webroot</link> = "/var/www/example.org";
<link linkend="opt-security.acme.certs._name_.email">email</link> = "root@example.org";
- <link linkend="opt-security.acme.certs._name_.extraDomains">extraDomains."conference.example.org"</link> = null;
- <link linkend="opt-security.acme.certs._name_.extraDomains">extraDomains."upload.example.org"</link> = null;
+ <link linkend="opt-security.acme.certs._name_.extraDomainNames">extraDomainNames</link> = [ "conference.example.org" "upload.example.org" ];
};
};
};</programlisting>
diff --git a/nixpkgs/nixos/modules/services/networking/robustirc-bridge.nix b/nixpkgs/nixos/modules/services/networking/robustirc-bridge.nix
new file mode 100644
index 00000000000..255af79ec04
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/networking/robustirc-bridge.nix
@@ -0,0 +1,47 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.robustirc-bridge;
+in
+{
+ options = {
+ services.robustirc-bridge = {
+ enable = mkEnableOption "RobustIRC bridge";
+
+ extraFlags = mkOption {
+ type = types.listOf types.str;
+ default = [];
+ description = ''Extra flags passed to the <command>robustirc-bridge</command> command. See <link xlink:href="https://robustirc.net/docs/adminguide.html#_bridge">RobustIRC Documentation</link> or robustirc-bridge(1) for details.'';
+ example = [
+ "-network robustirc.net"
+ ];
+ };
+ };
+ };
+
+ config = mkIf cfg.enable {
+ systemd.services.robustirc-bridge = {
+ description = "RobustIRC bridge";
+ documentation = [
+ "man:robustirc-bridge(1)"
+ "https://robustirc.net/"
+ ];
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network.target" ];
+
+ serviceConfig = {
+ DynamicUser = true;
+ ExecStart = "${pkgs.robustirc-bridge}/bin/robustirc-bridge ${concatStringsSep " " cfg.extraFlags}";
+ Restart = "on-failure";
+
+ # Hardening
+ PrivateDevices = true;
+ ProtectSystem = true;
+ ProtectHome = true;
+ PrivateTmp = true;
+ };
+ };
+ };
+}
diff --git a/nixpkgs/nixos/modules/services/networking/shadowsocks.nix b/nixpkgs/nixos/modules/services/networking/shadowsocks.nix
index af12db590f0..d2541f9a6df 100644
--- a/nixpkgs/nixos/modules/services/networking/shadowsocks.nix
+++ b/nixpkgs/nixos/modules/services/networking/shadowsocks.nix
@@ -11,8 +11,13 @@ let
method = cfg.encryptionMethod;
mode = cfg.mode;
user = "nobody";
- fast_open = true;
- } // optionalAttrs (cfg.password != null) { password = cfg.password; };
+ fast_open = cfg.fastOpen;
+ } // optionalAttrs (cfg.plugin != null) {
+ plugin = cfg.plugin;
+ plugin_opts = cfg.pluginOpts;
+ } // optionalAttrs (cfg.password != null) {
+ password = cfg.password;
+ } // cfg.extraConfig;
configFile = pkgs.writeText "shadowsocks.json" (builtins.toJSON opts);
@@ -74,6 +79,14 @@ in
'';
};
+ fastOpen = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ use TCP fast-open
+ '';
+ };
+
encryptionMethod = mkOption {
type = types.str;
default = "chacha20-ietf-poly1305";
@@ -82,6 +95,41 @@ in
'';
};
+ plugin = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ example = "\${pkgs.shadowsocks-v2ray-plugin}/bin/v2ray-plugin";
+ description = ''
+ SIP003 plugin for shadowsocks
+ '';
+ };
+
+ pluginOpts = mkOption {
+ type = types.str;
+ default = "";
+ example = "server;host=example.com";
+ description = ''
+ Options to pass to the plugin if one was specified
+ '';
+ };
+
+ extraConfig = mkOption {
+ type = types.attrs;
+ default = {};
+ example = ''
+ {
+ nameserver = "8.8.8.8";
+ }
+ '';
+ description = ''
+ Additional configuration for shadowsocks that is not covered by the
+ provided options. The provided attrset will be serialized to JSON and
+ has to contain valid shadowsocks options. Unfortunately most
+ additional options are undocumented but it's easy to find out what is
+ available by looking into the source code of
+ <link xlink:href="https://github.com/shadowsocks/shadowsocks-libev/blob/master/src/jconf.c"/>
+ '';
+ };
};
};
@@ -99,7 +147,7 @@ in
description = "shadowsocks-libev Daemon";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
- path = [ pkgs.shadowsocks-libev ] ++ optional (cfg.passwordFile != null) pkgs.jq;
+ path = [ pkgs.shadowsocks-libev ] ++ optional (cfg.plugin != null) cfg.plugin ++ optional (cfg.passwordFile != null) pkgs.jq;
serviceConfig.PrivateTmp = true;
script = ''
${optionalString (cfg.passwordFile != null) ''
diff --git a/nixpkgs/nixos/modules/services/networking/ssh/sshd.nix b/nixpkgs/nixos/modules/services/networking/ssh/sshd.nix
index 17f31e3a488..5365b8b9b10 100644
--- a/nixpkgs/nixos/modules/services/networking/ssh/sshd.nix
+++ b/nixpkgs/nixos/modules/services/networking/ssh/sshd.nix
@@ -232,6 +232,14 @@ in
'';
};
+ banner = mkOption {
+ type = types.nullOr types.lines;
+ default = null;
+ description = ''
+ Message to display to the remote user before authentication is allowed.
+ '';
+ };
+
authorizedKeysFiles = mkOption {
type = types.listOf types.str;
default = [];
@@ -361,7 +369,7 @@ in
};
users.users = mkOption {
- type = with types; loaOf (submodule userOptions);
+ type = with types; attrsOf (submodule userOptions);
};
};
@@ -474,6 +482,8 @@ in
''
UsePAM yes
+ Banner ${if cfg.banner == null then "none" else pkgs.writeText "ssh_banner" cfg.banner}
+
AddressFamily ${if config.networking.enableIPv6 then "any" else "inet"}
${concatMapStrings (port: ''
Port ${toString port}
diff --git a/nixpkgs/nixos/modules/services/networking/supplicant.nix b/nixpkgs/nixos/modules/services/networking/supplicant.nix
index b5b9989ce18..20704be9b36 100644
--- a/nixpkgs/nixos/modules/services/networking/supplicant.nix
+++ b/nixpkgs/nixos/modules/services/networking/supplicant.nix
@@ -76,9 +76,9 @@ in
networking.supplicant = mkOption {
type = with types; attrsOf (submodule {
options = {
-
+
configFile = {
-
+
path = mkOption {
type = types.nullOr types.path;
default = null;
@@ -89,7 +89,7 @@ in
precedence over options defined in <literal>configFile</literal>.
'';
};
-
+
writable = mkOption {
type = types.bool;
default = false;
@@ -98,9 +98,9 @@ in
<literal>wpa_supplicant</literal>.
'';
};
-
+
};
-
+
extraConf = mkOption {
type = types.lines;
default = "";
@@ -126,7 +126,7 @@ in
use the <literal>configFile</literal> instead.
'';
};
-
+
extraCmdArgs = mkOption {
type = types.str;
default = "";
@@ -134,21 +134,21 @@ in
description =
"Command line arguments to add when executing <literal>wpa_supplicant</literal>.";
};
-
+
driver = mkOption {
type = types.nullOr types.str;
default = "nl80211,wext";
description = "Force a specific wpa_supplicant driver.";
};
-
+
bridge = mkOption {
type = types.str;
default = "";
description = "Name of the bridge interface that wpa_supplicant should listen at.";
};
-
+
userControlled = {
-
+
enable = mkOption {
type = types.bool;
default = false;
@@ -159,20 +159,20 @@ in
access points.
'';
};
-
+
socketDir = mkOption {
type = types.str;
default = "/run/wpa_supplicant";
description = "Directory of sockets for controlling wpa_supplicant.";
};
-
+
group = mkOption {
type = types.str;
default = "wheel";
example = "network";
description = "Members of this group can control wpa_supplicant.";
};
-
+
};
};
});
diff --git a/nixpkgs/nixos/modules/services/networking/syncthing.nix b/nixpkgs/nixos/modules/services/networking/syncthing.nix
index e717d78feed..28348c7893a 100644
--- a/nixpkgs/nixos/modules/services/networking/syncthing.nix
+++ b/nixpkgs/nixos/modules/services/networking/syncthing.nix
@@ -18,6 +18,7 @@ let
fsWatcherEnabled = folder.watch;
fsWatcherDelayS = folder.watchDelay;
ignorePerms = folder.ignorePerms;
+ ignoreDelete = folder.ignoreDelete;
versioning = folder.versioning;
}) (filterAttrs (
_: folder:
@@ -284,8 +285,6 @@ in {
});
};
-
-
rescanInterval = mkOption {
type = types.int;
default = 3600;
@@ -327,6 +326,16 @@ in {
'';
};
+ ignoreDelete = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to delete files in destination. See <link
+ xlink:href="https://docs.syncthing.net/advanced/folder-ignoredelete.html">
+ upstream's docs</link>.
+ '';
+ };
+
};
}));
};
diff --git a/nixpkgs/nixos/modules/services/networking/trickster.nix b/nixpkgs/nixos/modules/services/networking/trickster.nix
index 8760dd5a938..49c945adb80 100644
--- a/nixpkgs/nixos/modules/services/networking/trickster.nix
+++ b/nixpkgs/nixos/modules/services/networking/trickster.nix
@@ -106,7 +106,8 @@ in
Restart = "always";
};
};
+ };
- };
-}
+ meta.maintainers = with maintainers; [ _1000101 ];
+}
diff --git a/nixpkgs/nixos/modules/services/networking/websockify.nix b/nixpkgs/nixos/modules/services/networking/websockify.nix
index d9177df65bd..27cb47be12f 100644
--- a/nixpkgs/nixos/modules/services/networking/websockify.nix
+++ b/nixpkgs/nixos/modules/services/networking/websockify.nix
@@ -5,12 +5,12 @@ with lib;
let cfg = config.services.networking.websockify; in {
options = {
services.networking.websockify = {
- enable = mkOption {
+ enable = mkOption {
description = "Whether to enable websockify to forward websocket connections to TCP connections.";
- default = false;
+ default = false;
- type = types.bool;
+ type = types.bool;
};
sslCert = mkOption {
diff --git a/nixpkgs/nixos/modules/services/networking/wpa_supplicant.nix b/nixpkgs/nixos/modules/services/networking/wpa_supplicant.nix
index 08a17d20ed7..39513987903 100644
--- a/nixpkgs/nixos/modules/services/networking/wpa_supplicant.nix
+++ b/nixpkgs/nixos/modules/services/networking/wpa_supplicant.nix
@@ -233,6 +233,9 @@ in {
path = [ pkgs.wpa_supplicant ];
script = ''
+ if [ -f /etc/wpa_supplicant.conf -a "/etc/wpa_supplicant.conf" != "${configFile}" ]
+ then echo >&2 "<3>/etc/wpa_supplicant.conf present but ignored. Generated ${configFile} is used instead."
+ fi
iface_args="-s -u -D${cfg.driver} -c ${configFile}"
${if ifaces == [] then ''
for i in $(cd /sys/class/net && echo *); do
diff --git a/nixpkgs/nixos/modules/services/networking/xandikos.nix b/nixpkgs/nixos/modules/services/networking/xandikos.nix
index f1882261656..3c40bb956f5 100644
--- a/nixpkgs/nixos/modules/services/networking/xandikos.nix
+++ b/nixpkgs/nixos/modules/services/networking/xandikos.nix
@@ -90,7 +90,7 @@ in
config = mkIf cfg.enable (
mkMerge [
{
- meta.maintainers = [ lib.maintainers."0x4A6F" ];
+ meta.maintainers = with lib.maintainers; [ _0x4A6F ];
systemd.services.xandikos = {
description = "A Simple Calendar and Contact Server";
diff --git a/nixpkgs/nixos/modules/services/scheduling/chronos.nix b/nixpkgs/nixos/modules/services/scheduling/chronos.nix
deleted file mode 100644
index 9a8ed4c09ac..00000000000
--- a/nixpkgs/nixos/modules/services/scheduling/chronos.nix
+++ /dev/null
@@ -1,54 +0,0 @@
-{ config, lib, pkgs, ... }:
-
-with lib;
-
-let
- cfg = config.services.chronos;
-
-in {
-
- ###### interface
-
- options.services.chronos = {
- enable = mkOption {
- description = "Whether to enable graphite web frontend.";
- default = false;
- type = types.bool;
- };
-
- httpPort = mkOption {
- description = "Chronos listening port";
- default = 4400;
- type = types.int;
- };
-
- master = mkOption {
- description = "Chronos mesos master zookeeper address";
- default = "zk://${head cfg.zookeeperHosts}/mesos";
- type = types.str;
- };
-
- zookeeperHosts = mkOption {
- description = "Chronos mesos zookepper addresses";
- default = [ "localhost:2181" ];
- type = types.listOf types.str;
- };
- };
-
- ###### implementation
-
- config = mkIf cfg.enable {
- systemd.services.chronos = {
- description = "Chronos Service";
- wantedBy = [ "multi-user.target" ];
- after = [ "network.target" "zookeeper.service" ];
-
- serviceConfig = {
- ExecStart = "${pkgs.chronos}/bin/chronos --master ${cfg.master} --zk_hosts ${concatStringsSep "," cfg.zookeeperHosts} --http_port ${toString cfg.httpPort}";
- User = "chronos";
- };
- };
-
- users.users.chronos.uid = config.ids.uids.chronos;
- };
-}
diff --git a/nixpkgs/nixos/modules/services/scheduling/marathon.nix b/nixpkgs/nixos/modules/services/scheduling/marathon.nix
deleted file mode 100644
index 2e0d20c64b2..00000000000
--- a/nixpkgs/nixos/modules/services/scheduling/marathon.nix
+++ /dev/null
@@ -1,98 +0,0 @@
-{ config, lib, pkgs, ... }:
-
-with lib;
-
-let
-
- cfg = config.services.marathon;
-
-in {
-
- ###### interface
-
- options.services.marathon = {
- enable = mkOption {
- type = types.bool;
- default = false;
- description = ''
- Whether to enable the marathon mesos framework.
- '';
- };
-
- master = mkOption {
- type = types.str;
- default = "zk://${concatStringsSep "," cfg.zookeeperHosts}/mesos";
- example = "zk://1.2.3.4:2181,2.3.4.5:2181,3.4.5.6:2181/mesos";
- description = ''
- Mesos master address. See <link xlink:href="https://mesosphere.github.io/marathon/docs/"/> for details.
- '';
- };
-
- zookeeperHosts = mkOption {
- type = types.listOf types.str;
- default = [ "localhost:2181" ];
- example = [ "1.2.3.4:2181" "2.3.4.5:2181" "3.4.5.6:2181" ];
- description = ''
- ZooKeeper hosts' addresses.
- '';
- };
-
- user = mkOption {
- type = types.str;
- default = "marathon";
- example = "root";
- description = ''
- The user that the Marathon framework will be launched as. If the user doesn't exist it will be created.
- If you want to run apps that require root access or you want to launch apps using arbitrary users, that
- is using the `--mesos_user` flag then you need to change this to `root`.
- '';
- };
-
- httpPort = mkOption {
- type = types.int;
- default = 8080;
- description = ''
- Marathon listening port for HTTP connections.
- '';
- };
-
- extraCmdLineOptions = mkOption {
- type = types.listOf types.str;
- default = [ ];
- example = [ "--https_port=8443" "--zk_timeout=10000" "--marathon_store_timeout=2000" ];
- description = ''
- Extra command line options to pass to Marathon.
- See <link xlink:href="https://mesosphere.github.io/marathon/docs/command-line-flags.html"/> for all possible flags.
- '';
- };
-
- environment = mkOption {
- default = { };
- type = types.attrs;
- example = { JAVA_OPTS = "-Xmx512m"; MESOSPHERE_HTTP_CREDENTIALS = "username:password"; };
- description = ''
- Environment variables passed to Marathon.
- '';
- };
- };
-
- ###### implementation
-
- config = mkIf cfg.enable {
- systemd.services.marathon = {
- description = "Marathon Service";
- environment = cfg.environment;
- wantedBy = [ "multi-user.target" ];
- after = [ "network.target" "zookeeper.service" "mesos-master.service" "mesos-slave.service" ];
-
- serviceConfig = {
- ExecStart = "${pkgs.marathon}/bin/marathon --master ${cfg.master} --zk zk://${concatStringsSep "," cfg.zookeeperHosts}/marathon --http_port ${toString cfg.httpPort} ${concatStringsSep " " cfg.extraCmdLineOptions}";
- User = cfg.user;
- Restart = "always";
- RestartSec = "2";
- };
- };
-
- users.users.${cfg.user}.isSystemUser = true;
- };
-}
diff --git a/nixpkgs/nixos/modules/services/security/bitwarden_rs/default.nix b/nixpkgs/nixos/modules/services/security/bitwarden_rs/default.nix
index 903a5327037..a04bc883bf0 100644
--- a/nixpkgs/nixos/modules/services/security/bitwarden_rs/default.nix
+++ b/nixpkgs/nixos/modules/services/security/bitwarden_rs/default.nix
@@ -81,6 +81,23 @@ in {
<link xlink:href="https://github.com/dani-garcia/bitwarden_rs/blob/${bitwarden_rs.version}/.env.template">the environment template file</link>.
'';
};
+
+ environmentFile = mkOption {
+ type = with types; nullOr path;
+ default = null;
+ example = "/root/bitwarden_rs.env";
+ description = ''
+ Additional environment file as defined in <citerefentry>
+ <refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>.
+
+ Secrets like <envar>ADMIN_TOKEN</envar> and <envar>SMTP_PASSWORD</envar>
+ may be passed to the service without adding them to the world-readable Nix store.
+
+ Note that this file needs to be available on the host on which
+ <literal>bitwarden_rs</literal> is running.
+ '';
+ };
};
config = mkIf cfg.enable {
@@ -101,7 +118,7 @@ in {
serviceConfig = {
User = user;
Group = group;
- EnvironmentFile = configFile;
+ EnvironmentFile = [ configFile ] ++ optional (cfg.environmentFile != null) cfg.environmentFile;
ExecStart = "${bitwarden_rs}/bin/bitwarden_rs";
LimitNOFILE = "1048576";
LimitNPROC = "64";
diff --git a/nixpkgs/nixos/modules/services/security/haveged.nix b/nixpkgs/nixos/modules/services/security/haveged.nix
index eca52918881..22ece188344 100644
--- a/nixpkgs/nixos/modules/services/security/haveged.nix
+++ b/nixpkgs/nixos/modules/services/security/haveged.nix
@@ -21,11 +21,11 @@ in
type = types.bool;
default = false;
description = ''
- Whether to enable to haveged entropy daemon, which refills
+ Whether to enable to haveged entropy daemon, which refills
/dev/random when low.
'';
};
-
+
refill_threshold = mkOption {
type = types.int;
default = 1024;
@@ -34,16 +34,16 @@ in
haveged should refill the entropy pool.
'';
};
-
+
};
-
+
};
-
-
+
+
###### implementation
-
+
config = mkIf cfg.enable {
-
+
systemd.services.haveged =
{ description = "Entropy Harvesting Daemon";
unitConfig.Documentation = "man:haveged(8)";
@@ -63,5 +63,5 @@ in
};
};
-
+
}
diff --git a/nixpkgs/nixos/modules/services/security/physlock.nix b/nixpkgs/nixos/modules/services/security/physlock.nix
index 690eb70079d..da5c22a90a0 100644
--- a/nixpkgs/nixos/modules/services/security/physlock.nix
+++ b/nixpkgs/nixos/modules/services/security/physlock.nix
@@ -52,6 +52,14 @@ in
'';
};
+ lockMessage = mkOption {
+ type = types.str;
+ default = "";
+ description = ''
+ Message to show on physlock login terminal.
+ '';
+ };
+
lockOn = {
suspend = mkOption {
@@ -111,7 +119,7 @@ in
++ cfg.lockOn.extraTargets;
serviceConfig = {
Type = "forking";
- ExecStart = "${pkgs.physlock}/bin/physlock -d${optionalString cfg.disableSysRq "s"}";
+ ExecStart = "${pkgs.physlock}/bin/physlock -d${optionalString cfg.disableSysRq "s"}${optionalString (cfg.lockMessage != "") " -p \"${cfg.lockMessage}\""}";
};
};
diff --git a/nixpkgs/nixos/modules/services/security/privacyidea.nix b/nixpkgs/nixos/modules/services/security/privacyidea.nix
index d6abfd0e271..c2988858e56 100644
--- a/nixpkgs/nixos/modules/services/security/privacyidea.nix
+++ b/nixpkgs/nixos/modules/services/security/privacyidea.nix
@@ -234,7 +234,6 @@ in
ExecStop = "${pkgs.coreutils}/bin/kill -INT $MAINPID";
NotifyAccess = "main";
KillSignal = "SIGQUIT";
- StandardError = "syslog";
};
};
diff --git a/nixpkgs/nixos/modules/services/security/tor.nix b/nixpkgs/nixos/modules/services/security/tor.nix
index b33e905c67d..38dc378887a 100644
--- a/nixpkgs/nixos/modules/services/security/tor.nix
+++ b/nixpkgs/nixos/modules/services/security/tor.nix
@@ -34,8 +34,8 @@ let
User tor
DataDirectory ${torDirectory}
${optionalString cfg.enableGeoIP ''
- GeoIPFile ${pkgs.tor.geoip}/share/tor/geoip
- GeoIPv6File ${pkgs.tor.geoip}/share/tor/geoip6
+ GeoIPFile ${cfg.package.geoip}/share/tor/geoip
+ GeoIPv6File ${cfg.package.geoip}/share/tor/geoip6
''}
${optint "ControlPort" cfg.controlPort}
@@ -123,6 +123,16 @@ in
'';
};
+ package = mkOption {
+ type = types.package;
+ default = pkgs.tor;
+ defaultText = "pkgs.tor";
+ example = literalExample "pkgs.tor";
+ description = ''
+ Tor package to use
+ '';
+ };
+
enableGeoIP = mkOption {
type = types.bool;
default = true;
@@ -597,7 +607,7 @@ in
];
}
'';
- type = types.loaOf (types.submodule ({name, ...}: {
+ type = types.attrsOf (types.submodule ({name, ...}: {
options = {
name = mkOption {
@@ -749,8 +759,8 @@ in
serviceConfig =
{ Type = "simple";
# Translated from the upstream contrib/dist/tor.service.in
- ExecStartPre = "${pkgs.tor}/bin/tor -f ${torRcFile} --verify-config";
- ExecStart = "${pkgs.tor}/bin/tor -f ${torRcFile}";
+ ExecStartPre = "${cfg.package}/bin/tor -f ${torRcFile} --verify-config";
+ ExecStart = "${cfg.package}/bin/tor -f ${torRcFile}";
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
KillSignal = "SIGINT";
TimeoutSec = 30;
@@ -773,7 +783,7 @@ in
};
};
- environment.systemPackages = [ pkgs.tor ];
+ environment.systemPackages = [ cfg.package ];
services.privoxy = mkIf (cfg.client.enable && cfg.client.privoxy.enable) {
enable = true;
diff --git a/nixpkgs/nixos/modules/services/security/usbguard.nix b/nixpkgs/nixos/modules/services/security/usbguard.nix
index f4118eb87fc..16a90da5231 100644
--- a/nixpkgs/nixos/modules/services/security/usbguard.nix
+++ b/nixpkgs/nixos/modules/services/security/usbguard.nix
@@ -1,37 +1,39 @@
-{config, lib, pkgs, ... }:
+{ config, lib, pkgs, ... }:
with lib;
-
let
-
cfg = config.services.usbguard;
# valid policy options
policy = (types.enum [ "allow" "block" "reject" "keep" "apply-policy" ]);
+ defaultRuleFile = "/var/lib/usbguard/rules.conf";
+
# decide what file to use for rules
- ruleFile = if cfg.rules != null then pkgs.writeText "usbguard-rules" cfg.rules else cfg.ruleFile;
+ ruleFile = if cfg.rules != null then pkgs.writeText "usbguard-rules" cfg.rules else defaultRuleFile;
daemonConf = ''
- # generated by nixos/modules/services/security/usbguard.nix
- RuleFile=${ruleFile}
- ImplicitPolicyTarget=${cfg.implictPolicyTarget}
- PresentDevicePolicy=${cfg.presentDevicePolicy}
- PresentControllerPolicy=${cfg.presentControllerPolicy}
- InsertedDevicePolicy=${cfg.insertedDevicePolicy}
- RestoreControllerDeviceState=${if cfg.restoreControllerDeviceState then "true" else "false"}
- # this does not seem useful for endusers to change
- DeviceManagerBackend=uevent
- IPCAllowedUsers=${concatStringsSep " " cfg.IPCAllowedUsers}
- IPCAllowedGroups=${concatStringsSep " " cfg.IPCAllowedGroups}
- IPCAccessControlFiles=${cfg.IPCAccessControlFiles}
- DeviceRulesWithPort=${if cfg.deviceRulesWithPort then "true" else "false"}
- AuditFilePath=${cfg.auditFilePath}
- '';
-
- daemonConfFile = pkgs.writeText "usbguard-daemon-conf" daemonConf;
-
-in {
+ # generated by nixos/modules/services/security/usbguard.nix
+ RuleFile=${ruleFile}
+ ImplicitPolicyTarget=${cfg.implictPolicyTarget}
+ PresentDevicePolicy=${cfg.presentDevicePolicy}
+ PresentControllerPolicy=${cfg.presentControllerPolicy}
+ InsertedDevicePolicy=${cfg.insertedDevicePolicy}
+ RestoreControllerDeviceState=${if cfg.restoreControllerDeviceState then "true" else "false"}
+ # this does not seem useful for endusers to change
+ DeviceManagerBackend=uevent
+ IPCAllowedUsers=${concatStringsSep " " cfg.IPCAllowedUsers}
+ IPCAllowedGroups=${concatStringsSep " " cfg.IPCAllowedGroups}
+ IPCAccessControlFiles=/var/lib/usbguard/IPCAccessControl.d/
+ DeviceRulesWithPort=${if cfg.deviceRulesWithPort then "true" else "false"}
+ # HACK: that way audit logs still land in the journal
+ AuditFilePath=/dev/null
+ '';
+
+ daemonConfFile = pkgs.writeText "usbguard-daemon-conf" daemonConf;
+
+in
+{
###### interface
@@ -49,22 +51,6 @@ in {
'';
};
- ruleFile = mkOption {
- type = types.path;
- default = "/var/lib/usbguard/rules.conf";
- description = ''
- The USBGuard daemon will use this file to load the policy rule set
- from it and to write new rules received via the IPC interface.
-
- Running the command <literal>usbguard generate-policy</literal> as
- root will generate a config for your currently plugged in devices.
- For a in depth guide consult the official documentation.
-
- Setting the <literal>rules</literal> option will ignore the
- <literal>ruleFile</literal> option.
- '';
- };
-
rules = mkOption {
type = types.nullOr types.lines;
default = null;
@@ -72,16 +58,20 @@ in {
allow with-interface equals { 08:*:* }
'';
description = ''
- The USBGuard daemon will load this policy rule set. Modifying it via
- the IPC interface won't work if you use this option, since the
- contents of this option will be written into the nix-store it will be
- read-only.
+ The USBGuard daemon will load this as the policy rule set.
+ As these rules are NixOS managed they are immutable and can't
+ be changed by the IPC interface.
+
+ If you do not set this option, the USBGuard daemon will load
+ it's policy rule set from <literal>${defaultRuleFile}</literal>.
+ This file can be changed manually or via the IPC interface.
- You can still use <literal> usbguard generate-policy</literal> to
- generate rules, but you would have to insert them here.
+ Running <literal>usbguard generate-policy</literal> as root will
+ generate a config for your currently plugged in devices.
- Setting the <literal>rules</literal> option will ignore the
- <literal>ruleFile</literal> option.
+ For more details see <citerefentry>
+ <refentrytitle>usbguard-rules.conf</refentrytitle>
+ <manvolnum>5</manvolnum></citerefentry>.
'';
};
@@ -155,17 +145,6 @@ in {
'';
};
- IPCAccessControlFiles = mkOption {
- type = types.path;
- default = "/var/lib/usbguard/IPCAccessControl.d/";
- description = ''
- The files at this location will be interpreted by the daemon as IPC
- access control definition files. See the IPC ACCESS CONTROL section
- in <citerefentry><refentrytitle>usbguard-daemon.conf</refentrytitle>
- <manvolnum>5</manvolnum></citerefentry> for more details.
- '';
- };
-
deviceRulesWithPort = mkOption {
type = types.bool;
default = false;
@@ -173,14 +152,6 @@ in {
Generate device specific rules including the "via-port" attribute.
'';
};
-
- auditFilePath = mkOption {
- type = types.path;
- default = "/var/log/usbguard/usbguard-audit.log";
- description = ''
- USBGuard audit events log file path.
- '';
- };
};
};
@@ -197,17 +168,19 @@ in {
wantedBy = [ "basic.target" ];
wants = [ "systemd-udevd.service" ];
- # make sure an empty rule file and required directories exist
- preStart = ''
- mkdir -p $(dirname "${cfg.ruleFile}") $(dirname "${cfg.auditFilePath}") "${cfg.IPCAccessControlFiles}" \
- && ([ -f "${cfg.ruleFile}" ] || touch ${cfg.ruleFile})
- '';
+ # make sure an empty rule file exists
+ preStart = ''[ -f "${ruleFile}" ] || touch ${ruleFile}'';
serviceConfig = {
Type = "simple";
ExecStart = ''${cfg.package}/bin/usbguard-daemon -P -k -c ${daemonConfFile}'';
Restart = "on-failure";
+ StateDirectory = [
+ "usbguard"
+ "usbguard/IPCAccessControl.d"
+ ];
+
AmbientCapabilities = "";
CapabilityBoundingSet = "CAP_CHOWN CAP_FOWNER";
DeviceAllow = "/dev/null rw";
@@ -223,8 +196,8 @@ in {
ProtectKernelModules = true;
ProtectSystem = true;
ReadOnlyPaths = "-/";
- ReadWritePaths = "-/dev/shm -${dirOf cfg.auditFilePath} -/tmp -${dirOf cfg.ruleFile}";
- RestrictAddressFamilies = "AF_UNIX AF_NETLINK";
+ ReadWritePaths = "-/dev/shm -/tmp";
+ RestrictAddressFamilies = [ "AF_UNIX" "AF_NETLINK" ];
RestrictNamespaces = true;
RestrictRealtime = true;
SystemCallArchitectures = "native";
@@ -233,4 +206,9 @@ in {
};
};
};
+ imports = [
+ (mkRemovedOptionModule [ "services" "usbguard" "ruleFile" ] "The usbguard module now uses ${defaultRuleFile} as ruleFile. Alternatively, use services.usbguard.rules to configure rules.")
+ (mkRemovedOptionModule [ "services" "usbguard" "IPCAccessControlFiles" ] "The usbguard module now hardcodes IPCAccessControlFiles to /var/lib/usbguard/IPCAccessControl.d.")
+ (mkRemovedOptionModule [ "services" "usbguard" "auditFilePath" ] "Removed usbguard module audit log files. Audit logs can be found in the systemd journal.")
+ ];
}
diff --git a/nixpkgs/nixos/modules/services/system/earlyoom.nix b/nixpkgs/nixos/modules/services/system/earlyoom.nix
index c6a001d30ee..e29bdbe264c 100644
--- a/nixpkgs/nixos/modules/services/system/earlyoom.nix
+++ b/nixpkgs/nixos/modules/services/system/earlyoom.nix
@@ -106,7 +106,6 @@ in
path = optional ecfg.enableNotifications pkgs.dbus;
serviceConfig = {
StandardOutput = "null";
- StandardError = "syslog";
ExecStart = ''
${pkgs.earlyoom}/bin/earlyoom \
-m ${toString ecfg.freeMemThreshold} \
diff --git a/nixpkgs/nixos/modules/services/torrent/transmission.nix b/nixpkgs/nixos/modules/services/torrent/transmission.nix
index 1bfcf2de82f..014a22bb5a8 100644
--- a/nixpkgs/nixos/modules/services/torrent/transmission.nix
+++ b/nixpkgs/nixos/modules/services/torrent/transmission.nix
@@ -1,52 +1,54 @@
-{ config, lib, pkgs, ... }:
+{ config, lib, pkgs, options, ... }:
with lib;
let
cfg = config.services.transmission;
+ inherit (config.environment) etc;
apparmor = config.security.apparmor.enable;
-
- homeDir = cfg.home;
- downloadDirPermissions = cfg.downloadDirPermissions;
- downloadDir = "${homeDir}/Downloads";
- incompleteDir = "${homeDir}/.incomplete";
-
- settingsDir = "${homeDir}/config";
- settingsFile = pkgs.writeText "settings.json" (builtins.toJSON fullSettings);
-
- # for users in group "transmission" to have access to torrents
- fullSettings = { umask = 2; download-dir = downloadDir; incomplete-dir = incompleteDir; } // cfg.settings;
-
- preStart = pkgs.writeScript "transmission-pre-start" ''
- #!${pkgs.runtimeShell}
- set -ex
- cp -f ${settingsFile} ${settingsDir}/settings.json
- '';
+ rootDir = "/run/transmission";
+ homeDir = "/var/lib/transmission";
+ settingsDir = ".config/transmission-daemon";
+ downloadsDir = "Downloads";
+ incompleteDir = ".incomplete";
+ watchDir = "watchdir";
+ # TODO: switch to configGen.json once RFC0042 is implemented
+ settingsFile = pkgs.writeText "settings.json" (builtins.toJSON cfg.settings);
in
{
options = {
services.transmission = {
- enable = mkOption {
- type = types.bool;
- default = false;
- description = ''
- Whether or not to enable the headless Transmission BitTorrent daemon.
+ enable = mkEnableOption ''the headless Transmission BitTorrent daemon.
- Transmission daemon can be controlled via the RPC interface using
- transmission-remote or the WebUI (http://localhost:9091/ by default).
+ Transmission daemon can be controlled via the RPC interface using
+ transmission-remote, the WebUI (http://127.0.0.1:9091/ by default),
+ or other clients like stig or tremc.
- Torrents are downloaded to ${downloadDir} by default and are
- accessible to users in the "transmission" group.
- '';
- };
+ Torrents are downloaded to ${homeDir}/${downloadsDir} by default and are
+ accessible to users in the "transmission" group'';
- settings = mkOption {
+ settings = mkOption rec {
+ # TODO: switch to types.config.json as prescribed by RFC0042 once it's implemented
type = types.attrs;
+ apply = recursiveUpdate default;
default =
{
- download-dir = downloadDir;
- incomplete-dir = incompleteDir;
+ download-dir = "${cfg.home}/${downloadsDir}";
+ incomplete-dir = "${cfg.home}/${incompleteDir}";
incomplete-dir-enabled = true;
+ watch-dir = "${cfg.home}/${watchDir}";
+ watch-dir-enabled = false;
+ message-level = 1;
+ peer-port = 51413;
+ peer-port-random-high = 65535;
+ peer-port-random-low = 49152;
+ peer-port-random-on-start = false;
+ rpc-bind-address = "127.0.0.1";
+ rpc-port = 9091;
+ script-torrent-done-enabled = false;
+ script-torrent-done-filename = "";
+ umask = 2; # 0o002 in decimal as expected by Transmission
+ utp-enabled = true;
};
example =
{
@@ -56,11 +58,12 @@ in
rpc-whitelist = "127.0.0.1,192.168.*.*";
};
description = ''
- Attribute set whos fields overwrites fields in settings.json (each
- time the service starts). String values must be quoted, integer and
+ Attribute set whose fields overwrites fields in
+ <literal>.config/transmission-daemon/settings.json</literal>
+ (each time the service starts). String values must be quoted, integer and
boolean values must not.
- See https://github.com/transmission/transmission/wiki/Editing-Configuration-Files
+ See <link xlink:href="https://github.com/transmission/transmission/wiki/Editing-Configuration-Files">Transmission's Wiki</link>
for documentation.
'';
};
@@ -70,22 +73,32 @@ in
default = "770";
example = "775";
description = ''
- The permissions to set for download-dir and incomplete-dir.
- They will be applied on every service start.
+ The permissions set by <literal>systemd.activationScripts.transmission-daemon</literal>
+ on the directories <link linkend="opt-services.transmission.settings">settings.download-dir</link>
+ and <link linkend="opt-services.transmission.settings">settings.incomplete-dir</link>.
+ Note that you may also want to change
+ <link linkend="opt-services.transmission.settings">settings.umask</link>.
'';
};
port = mkOption {
- type = types.int;
- default = 9091;
- description = "TCP port number to run the RPC/web interface.";
+ type = types.port;
+ description = ''
+ TCP port number to run the RPC/web interface.
+
+ If instead you want to change the peer port,
+ use <link linkend="opt-services.transmission.settings">settings.peer-port</link>
+ or <link linkend="opt-services.transmission.settings">settings.peer-port-random-on-start</link>.
+ '';
};
home = mkOption {
type = types.path;
- default = "/var/lib/transmission";
+ default = homeDir;
description = ''
- The directory where transmission will create files.
+ The directory where Transmission will create <literal>${settingsDir}</literal>.
+ as well as <literal>${downloadsDir}/</literal> unless <link linkend="opt-services.transmission.settings">settings.download-dir</link> is changed,
+ and <literal>${incompleteDir}/</literal> unless <link linkend="opt-services.transmission.settings">settings.incomplete-dir</link> is changed.
'';
};
@@ -100,32 +113,179 @@ in
default = "transmission";
description = "Group account under which Transmission runs.";
};
+
+ credentialsFile = mkOption {
+ type = types.path;
+ description = ''
+ Path to a JSON file to be merged with the settings.
+ Useful to merge a file which is better kept out of the Nix store
+ because it contains sensible data like <link linkend="opt-services.transmission.settings">settings.rpc-password</link>.
+ '';
+ default = "/dev/null";
+ example = "/var/lib/secrets/transmission/settings.json";
+ };
+
+ openFirewall = mkEnableOption "opening of the peer port(s) in the firewall";
+
+ performanceNetParameters = mkEnableOption ''tweaking of kernel parameters
+ to open many more connections at the same time.
+
+ Note that you may also want to increase
+ <link linkend="opt-services.transmission.settings">settings.peer-limit-global</link>.
+ And be aware that these settings are quite aggressive
+ and might not suite your regular desktop use.
+ For instance, SSH sessions may time out more easily'';
};
};
config = mkIf cfg.enable {
- systemd.tmpfiles.rules = [
- "d '${homeDir}' 0770 '${cfg.user}' '${cfg.group}' - -"
- "d '${settingsDir}' 0700 '${cfg.user}' '${cfg.group}' - -"
- "d '${fullSettings.download-dir}' '${downloadDirPermissions}' '${cfg.user}' '${cfg.group}' - -"
- "d '${fullSettings.incomplete-dir}' '${downloadDirPermissions}' '${cfg.user}' '${cfg.group}' - -"
+ # Note that using systemd.tmpfiles would not work here
+ # because it would fail when creating a directory
+ # with a different owner than its parent directory, by saying:
+ # Detected unsafe path transition /home/foo → /home/foo/Downloads during canonicalization of /home/foo/Downloads
+ # when /home/foo is not owned by cfg.user.
+ # Note also that using an ExecStartPre= wouldn't work either
+ # because BindPaths= needs these directories before.
+ system.activationScripts.transmission-daemon = ''
+ install -d -m 700 '${cfg.home}/${settingsDir}'
+ chown -R '${cfg.user}:${cfg.group}' ${cfg.home}/${settingsDir}
+ install -d -m '${cfg.downloadDirPermissions}' -o '${cfg.user}' -g '${cfg.group}' '${cfg.settings.download-dir}'
+ '' + optionalString cfg.settings.incomplete-dir-enabled ''
+ install -d -m '${cfg.downloadDirPermissions}' -o '${cfg.user}' -g '${cfg.group}' '${cfg.settings.incomplete-dir}'
+ '';
+
+ assertions = [
+ { assertion = builtins.match "^/.*" cfg.home != null;
+ message = "`services.transmission.home' must be an absolute path.";
+ }
+ { assertion = types.path.check cfg.settings.download-dir;
+ message = "`services.transmission.settings.download-dir' must be an absolute path.";
+ }
+ { assertion = types.path.check cfg.settings.incomplete-dir;
+ message = "`services.transmission.settings.incomplete-dir' must be an absolute path.";
+ }
+ { assertion = types.path.check cfg.settings.watch-dir;
+ message = "`services.transmission.settings.watch-dir' must be an absolute path.";
+ }
+ { assertion = cfg.settings.script-torrent-done-filename == "" || types.path.check cfg.settings.script-torrent-done-filename;
+ message = "`services.transmission.settings.script-torrent-done-filename' must be an absolute path.";
+ }
+ { assertion = types.port.check cfg.settings.rpc-port;
+ message = "${toString cfg.settings.rpc-port} is not a valid port number for `services.transmission.settings.rpc-port`.";
+ }
+ # In case both port and settings.rpc-port are explicitely defined: they must be the same.
+ { assertion = !options.services.transmission.port.isDefined || cfg.port == cfg.settings.rpc-port;
+ message = "`services.transmission.port' is not equal to `services.transmission.settings.rpc-port'";
+ }
];
+ services.transmission.settings =
+ optionalAttrs options.services.transmission.port.isDefined { rpc-port = cfg.port; };
+
systemd.services.transmission = {
description = "Transmission BitTorrent Service";
after = [ "network.target" ] ++ optional apparmor "apparmor.service";
- requires = mkIf apparmor [ "apparmor.service" ];
+ requires = optional apparmor "apparmor.service";
wantedBy = [ "multi-user.target" ];
+ environment.CURL_CA_BUNDLE = etc."ssl/certs/ca-certificates.crt".source;
- # 1) Only the "transmission" user and group have access to torrents.
- # 2) Optionally update/force specific fields into the configuration file.
- serviceConfig.ExecStartPre = preStart;
- serviceConfig.ExecStart = "${pkgs.transmission}/bin/transmission-daemon -f --port ${toString config.services.transmission.port} --config-dir ${settingsDir}";
- serviceConfig.ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
- 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";
+ serviceConfig = {
+ # Use "+" because credentialsFile may not be accessible to User= or Group=.
+ ExecStartPre = [("+" + pkgs.writeShellScript "transmission-prestart" ''
+ set -eu${lib.optionalString (cfg.settings.message-level >= 3) "x"}
+ ${pkgs.jq}/bin/jq --slurp add ${settingsFile} '${cfg.credentialsFile}' |
+ install -D -m 600 -o '${cfg.user}' -g '${cfg.group}' /dev/stdin \
+ '${cfg.home}/${settingsDir}/settings.json'
+ '')];
+ ExecStart="${pkgs.transmission}/bin/transmission-daemon -f";
+ ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
+ User = cfg.user;
+ Group = cfg.group;
+ # Create rootDir in the host's mount namespace.
+ RuntimeDirectory = [(baseNameOf rootDir)];
+ RuntimeDirectoryMode = "755";
+ # Avoid mounting rootDir in the own rootDir of ExecStart='s mount namespace.
+ InaccessiblePaths = ["-+${rootDir}"];
+ # This is for BindPaths= and BindReadOnlyPaths=
+ # to allow traversal of directories they create in RootDirectory=.
+ UMask = "0066";
+ # Using RootDirectory= makes it possible
+ # to use the same paths download-dir/incomplete-dir
+ # (which appear in user's interfaces) without requiring cfg.user
+ # to have access to their parent directories,
+ # by using BindPaths=/BindReadOnlyPaths=.
+ # Note that TemporaryFileSystem= could have been used instead
+ # but not without adding some BindPaths=/BindReadOnlyPaths=
+ # that would only be needed for ExecStartPre=,
+ # because RootDirectoryStartOnly=true would not help.
+ RootDirectory = rootDir;
+ RootDirectoryStartOnly = true;
+ MountAPIVFS = true;
+ BindPaths =
+ [ "${cfg.home}/${settingsDir}"
+ cfg.settings.download-dir
+ ] ++
+ optional cfg.settings.incomplete-dir-enabled
+ cfg.settings.incomplete-dir
+ ++
+ optional cfg.settings.watch-dir-enabled
+ cfg.settings.watch-dir
+ ;
+ BindReadOnlyPaths = [
+ # No confinement done of /nix/store here like in systemd-confinement.nix,
+ # an AppArmor profile is provided to get a confinement based upon paths and rights.
+ builtins.storeDir
+ "/etc"
+ ] ++
+ optional (cfg.settings.script-torrent-done-enabled &&
+ cfg.settings.script-torrent-done-filename != "")
+ cfg.settings.script-torrent-done-filename;
+ # The following options are only for optimizing:
+ # systemd-analyze security transmission
+ AmbientCapabilities = "";
+ CapabilityBoundingSet = "";
+ # ProtectClock= adds DeviceAllow=char-rtc r
+ DeviceAllow = "";
+ LockPersonality = true;
+ MemoryDenyWriteExecute = true;
+ NoNewPrivileges = true;
+ PrivateDevices = true;
+ PrivateMounts = true;
+ PrivateNetwork = mkDefault false;
+ PrivateTmp = true;
+ PrivateUsers = true;
+ ProtectClock = true;
+ ProtectControlGroups = true;
+ # ProtectHome=true would not allow BindPaths= to work accross /home,
+ # and ProtectHome=tmpfs would break statfs(),
+ # preventing transmission-daemon to report the available free space.
+ # However, RootDirectory= is used, so this is not a security concern
+ # since there would be nothing in /home but any BindPaths= wanted by the user.
+ ProtectHome = "read-only";
+ ProtectHostname = true;
+ ProtectKernelLogs = true;
+ ProtectKernelModules = true;
+ ProtectKernelTunables = true;
+ ProtectSystem = "strict";
+ RemoveIPC = true;
+ # AF_UNIX may become usable one day:
+ # https://github.com/transmission/transmission/issues/441
+ RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ];
+ RestrictNamespaces = true;
+ RestrictRealtime = true;
+ RestrictSUIDSGID = true;
+ SystemCallFilter = [
+ "@system-service"
+ # Groups in @system-service which do not contain a syscall
+ # listed by perf stat -e 'syscalls:sys_enter_*' transmission-daemon -f
+ # in tests, and seem likely not necessary for transmission-daemon.
+ "~@aio" "~@chown" "~@keyring" "~@memlock" "~@resources" "~@setuid" "~@timer"
+ # In the @privileged group, but reached when querying infos through RPC (eg. with stig).
+ "quotactl"
+ ];
+ SystemCallArchitectures = "native";
+ SystemCallErrorNumber = "EPERM";
+ };
};
# It's useful to have transmission in path, e.g. for remote control
@@ -133,70 +293,159 @@ in
users.users = optionalAttrs (cfg.user == "transmission") ({
transmission = {
- name = "transmission";
group = cfg.group;
uid = config.ids.uids.transmission;
description = "Transmission BitTorrent user";
- home = homeDir;
- createHome = true;
+ home = cfg.home;
};
});
users.groups = optionalAttrs (cfg.group == "transmission") ({
transmission = {
- name = "transmission";
gid = config.ids.gids.transmission;
};
});
- # AppArmor profile
+ networking.firewall = mkIf cfg.openFirewall (
+ if cfg.settings.peer-port-random-on-start
+ then
+ { allowedTCPPortRanges =
+ [ { from = cfg.settings.peer-port-random-low;
+ to = cfg.settings.peer-port-random-high;
+ }
+ ];
+ allowedUDPPortRanges =
+ [ { from = cfg.settings.peer-port-random-low;
+ to = cfg.settings.peer-port-random-high;
+ }
+ ];
+ }
+ else
+ { allowedTCPPorts = [ cfg.settings.peer-port ];
+ allowedUDPPorts = [ cfg.settings.peer-port ];
+ }
+ );
+
+ boot.kernel.sysctl = mkMerge [
+ # Transmission uses a single UDP socket in order to implement multiple uTP sockets,
+ # and thus expects large kernel buffers for the UDP socket,
+ # https://trac.transmissionbt.com/browser/trunk/libtransmission/tr-udp.c?rev=11956.
+ # at least up to the values hardcoded here:
+ (mkIf cfg.settings.utp-enabled {
+ "net.core.rmem_max" = mkDefault "4194304"; # 4MB
+ "net.core.wmem_max" = mkDefault "1048576"; # 1MB
+ })
+ (mkIf cfg.performanceNetParameters {
+ # Increase the number of available source (local) TCP and UDP ports to 49151.
+ # Usual default is 32768 60999, ie. 28231 ports.
+ # Find out your current usage with: ss -s
+ "net.ipv4.ip_local_port_range" = "16384 65535";
+ # Timeout faster generic TCP states.
+ # Usual default is 600.
+ # Find out your current usage with: watch -n 1 netstat -nptuo
+ "net.netfilter.nf_conntrack_generic_timeout" = 60;
+ # Timeout faster established but inactive connections.
+ # Usual default is 432000.
+ "net.netfilter.nf_conntrack_tcp_timeout_established" = 600;
+ # Clear immediately TCP states after timeout.
+ # Usual default is 120.
+ "net.netfilter.nf_conntrack_tcp_timeout_time_wait" = 1;
+ # Increase the number of trackable connections.
+ # Usual default is 262144.
+ # Find out your current usage with: conntrack -C
+ "net.netfilter.nf_conntrack_max" = 1048576;
+ })
+ ];
+
security.apparmor.profiles = mkIf apparmor [
(pkgs.writeText "apparmor-transmission-daemon" ''
- #include <tunables/global>
+ include <tunables/global>
${pkgs.transmission}/bin/transmission-daemon {
- #include <abstractions/base>
- #include <abstractions/nameservice>
-
- ${getLib pkgs.glibc}/lib/*.so mr,
- ${getLib pkgs.libevent}/lib/libevent*.so* mr,
- ${getLib pkgs.curl}/lib/libcurl*.so* mr,
- ${getLib pkgs.openssl}/lib/libssl*.so* mr,
- ${getLib pkgs.openssl}/lib/libcrypto*.so* mr,
- ${getLib pkgs.zlib}/lib/libz*.so* mr,
- ${getLib pkgs.libssh2}/lib/libssh2*.so* mr,
- ${getLib pkgs.systemd}/lib/libsystemd*.so* mr,
- ${getLib pkgs.xz}/lib/liblzma*.so* mr,
- ${getLib pkgs.libgcrypt}/lib/libgcrypt*.so* mr,
- ${getLib pkgs.libgpgerror}/lib/libgpg-error*.so* mr,
- ${getLib pkgs.nghttp2}/lib/libnghttp2*.so* mr,
- ${getLib pkgs.c-ares}/lib/libcares*.so* mr,
- ${getLib pkgs.libcap}/lib/libcap*.so* mr,
- ${getLib pkgs.attr}/lib/libattr*.so* mr,
- ${getLib pkgs.lz4}/lib/liblz4*.so* mr,
- ${getLib pkgs.libkrb5}/lib/lib*.so* mr,
- ${getLib pkgs.keyutils}/lib/libkeyutils*.so* mr,
- ${getLib pkgs.utillinuxMinimal.out}/lib/libblkid.so.* mr,
- ${getLib pkgs.utillinuxMinimal.out}/lib/libmount.so.* mr,
- ${getLib pkgs.utillinuxMinimal.out}/lib/libuuid.so.* mr,
- ${getLib pkgs.gcc.cc.lib}/lib/libstdc++.so.* mr,
- ${getLib pkgs.gcc.cc.lib}/lib/libgcc_s.so.* mr,
-
- @{PROC}/sys/kernel/random/uuid r,
- @{PROC}/sys/vm/overcommit_memory r,
-
- ${pkgs.openssl.out}/etc/** r,
- ${pkgs.transmission}/share/transmission/** r,
-
- owner ${settingsDir}/** rw,
-
- ${fullSettings.download-dir}/** rw,
- ${optionalString fullSettings.incomplete-dir-enabled ''
- ${fullSettings.incomplete-dir}/** rw,
+ include <abstractions/base>
+ include <abstractions/nameservice>
+
+ # NOTE: https://github.com/NixOS/nixpkgs/pull/93457
+ # will remove the need for these by fixing <abstractions/base>
+ r ${etc."hosts".source},
+ r /etc/ld-nix.so.preload,
+ ${lib.optionalString (builtins.hasAttr "ld-nix.so.preload" etc) ''
+ r ${etc."ld-nix.so.preload".source},
+ ${concatMapStrings (p: optionalString (p != "") ("mr ${p},\n"))
+ (splitString "\n" config.environment.etc."ld-nix.so.preload".text)}
''}
+ r ${etc."ssl/certs/ca-certificates.crt".source},
+ r ${pkgs.tzdata}/share/zoneinfo/**,
+ r ${pkgs.stdenv.cc.libc}/share/i18n/**,
+ r ${pkgs.stdenv.cc.libc}/share/locale/**,
+
+ mr ${getLib pkgs.stdenv.cc.cc}/lib/*.so*,
+ mr ${getLib pkgs.stdenv.cc.libc}/lib/*.so*,
+ mr ${getLib pkgs.attr}/lib/libattr*.so*,
+ mr ${getLib pkgs.c-ares}/lib/libcares*.so*,
+ mr ${getLib pkgs.curl}/lib/libcurl*.so*,
+ mr ${getLib pkgs.keyutils}/lib/libkeyutils*.so*,
+ mr ${getLib pkgs.libcap}/lib/libcap*.so*,
+ mr ${getLib pkgs.libevent}/lib/libevent*.so*,
+ mr ${getLib pkgs.libgcrypt}/lib/libgcrypt*.so*,
+ mr ${getLib pkgs.libgpgerror}/lib/libgpg-error*.so*,
+ mr ${getLib pkgs.libkrb5}/lib/lib*.so*,
+ mr ${getLib pkgs.libssh2}/lib/libssh2*.so*,
+ mr ${getLib pkgs.lz4}/lib/liblz4*.so*,
+ mr ${getLib pkgs.nghttp2}/lib/libnghttp2*.so*,
+ mr ${getLib pkgs.openssl}/lib/libcrypto*.so*,
+ mr ${getLib pkgs.openssl}/lib/libssl*.so*,
+ mr ${getLib pkgs.systemd}/lib/libsystemd*.so*,
+ mr ${getLib pkgs.utillinuxMinimal.out}/lib/libblkid.so*,
+ mr ${getLib pkgs.utillinuxMinimal.out}/lib/libmount.so*,
+ mr ${getLib pkgs.utillinuxMinimal.out}/lib/libuuid.so*,
+ mr ${getLib pkgs.xz}/lib/liblzma*.so*,
+ mr ${getLib pkgs.zlib}/lib/libz*.so*,
+
+ r @{PROC}/sys/kernel/random/uuid,
+ r @{PROC}/sys/vm/overcommit_memory,
+ # @{pid} is not a kernel variable yet but a regexp
+ #r @{PROC}/@{pid}/environ,
+ r @{PROC}/@{pid}/mounts,
+ rwk /tmp/tr_session_id_*,
+
+ r ${pkgs.openssl.out}/etc/**,
+ r ${config.systemd.services.transmission.environment.CURL_CA_BUNDLE},
+ r ${pkgs.transmission}/share/transmission/**,
+
+ owner rw ${cfg.home}/${settingsDir}/**,
+ rw ${cfg.settings.download-dir}/**,
+ ${optionalString cfg.settings.incomplete-dir-enabled ''
+ rw ${cfg.settings.incomplete-dir}/**,
+ ''}
+ ${optionalString cfg.settings.watch-dir-enabled ''
+ rw ${cfg.settings.watch-dir}/**,
+ ''}
+ profile dirs {
+ rw ${cfg.settings.download-dir}/**,
+ ${optionalString cfg.settings.incomplete-dir-enabled ''
+ rw ${cfg.settings.incomplete-dir}/**,
+ ''}
+ ${optionalString cfg.settings.watch-dir-enabled ''
+ rw ${cfg.settings.watch-dir}/**,
+ ''}
+ }
+
+ ${optionalString (cfg.settings.script-torrent-done-enabled &&
+ cfg.settings.script-torrent-done-filename != "") ''
+ # Stack transmission_directories profile on top of
+ # any existing profile for script-torrent-done-filename
+ # FIXME: to be tested as I'm not sure it works well with NoNewPrivileges=
+ # https://gitlab.com/apparmor/apparmor/-/wikis/AppArmorStacking#seccomp-and-no_new_privs
+ px ${cfg.settings.script-torrent-done-filename} -> &@{dirs},
+ ''}
+
+ # FIXME: enable customizing using https://github.com/NixOS/nixpkgs/pull/93457
+ # include <local/transmission-daemon>
}
'')
];
};
+ meta.maintainers = with lib.maintainers; [ julm ];
}
diff --git a/nixpkgs/nixos/modules/services/video/epgstation/default.nix b/nixpkgs/nixos/modules/services/video/epgstation/default.nix
new file mode 100644
index 00000000000..8d6d431fa55
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/video/epgstation/default.nix
@@ -0,0 +1,295 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.epgstation;
+
+ username = config.users.users.epgstation.name;
+ groupname = config.users.users.epgstation.group;
+
+ settingsFmt = pkgs.formats.json {};
+ settingsTemplate = settingsFmt.generate "config.json" cfg.settings;
+ preStartScript = pkgs.writeScript "epgstation-prestart" ''
+ #!${pkgs.runtimeShell}
+
+ PASSWORD="$(head -n1 "${cfg.basicAuth.passwordFile}")"
+ DB_PASSWORD="$(head -n1 "${cfg.database.passwordFile}")"
+
+ # setup configuration
+ touch /etc/epgstation/config.json
+ chmod 640 /etc/epgstation/config.json
+ sed \
+ -e "s,@password@,$PASSWORD,g" \
+ -e "s,@dbPassword@,$DB_PASSWORD,g" \
+ ${settingsTemplate} > /etc/epgstation/config.json
+ chown "${username}:${groupname}" /etc/epgstation/config.json
+
+ # NOTE: Use password authentication, since mysqljs does not yet support auth_socket
+ if [ ! -e /var/lib/epgstation/db-created ]; then
+ ${pkgs.mysql}/bin/mysql -e \
+ "GRANT ALL ON \`${cfg.database.name}\`.* TO '${username}'@'localhost' IDENTIFIED by '$DB_PASSWORD';"
+ touch /var/lib/epgstation/db-created
+ fi
+ '';
+
+ streamingConfig = builtins.fromJSON (builtins.readFile ./streaming.json);
+ logConfig = {
+ appenders.stdout.type = "stdout";
+ categories = {
+ default = { appenders = [ "stdout" ]; level = "info"; };
+ system = { appenders = [ "stdout" ]; level = "info"; };
+ access = { appenders = [ "stdout" ]; level = "info"; };
+ stream = { appenders = [ "stdout" ]; level = "info"; };
+ };
+ };
+
+ defaultPassword = "INSECURE_GO_CHECK_CONFIGURATION_NIX\n";
+in
+{
+ options.services.epgstation = {
+ enable = mkEnableOption pkgs.epgstation.meta.description;
+
+ usePreconfiguredStreaming = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Use preconfigured default streaming options.
+
+ Upstream defaults:
+ <link xlink:href="https://github.com/l3tnun/EPGStation/blob/master/config/config.sample.json"/>
+ '';
+ };
+
+ port = mkOption {
+ type = types.port;
+ default = 20772;
+ description = ''
+ HTTP port for EPGStation to listen on.
+ '';
+ };
+
+ socketioPort = mkOption {
+ type = types.port;
+ default = cfg.port + 1;
+ description = ''
+ Socket.io port for EPGStation to listen on.
+ '';
+ };
+
+ clientSocketioPort = mkOption {
+ type = types.port;
+ default = cfg.socketioPort;
+ description = ''
+ Socket.io port that the web client is going to connect to. This may be
+ different from <option>socketioPort</option> if EPGStation is hidden
+ behind a reverse proxy.
+ '';
+ };
+
+ openFirewall = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Open ports in the firewall for the EPGStation web interface.
+
+ <warning>
+ <para>
+ Exposing EPGStation to the open internet is generally advised
+ against. Only use it inside a trusted local network, or consider
+ putting it behind a VPN if you want remote access.
+ </para>
+ </warning>
+ '';
+ };
+
+ basicAuth = {
+ user = mkOption {
+ type = with types; nullOr str;
+ default = null;
+ example = "epgstation";
+ description = ''
+ Basic auth username for EPGStation. If <literal>null</literal>, basic
+ auth will be disabled.
+
+ <warning>
+ <para>
+ Basic authentication has known weaknesses, the most critical being
+ that it sends passwords over the network in clear text. Use this
+ feature to control access to EPGStation within your family and
+ friends, but don't rely on it for security.
+ </para>
+ </warning>
+ '';
+ };
+
+ passwordFile = mkOption {
+ type = types.path;
+ default = pkgs.writeText "epgstation-password" defaultPassword;
+ example = "/run/keys/epgstation-password";
+ description = ''
+ A file containing the password for <option>basicAuth.user</option>.
+ '';
+ };
+ };
+
+ database = {
+ name = mkOption {
+ type = types.str;
+ default = "epgstation";
+ description = ''
+ Name of the MySQL database that holds EPGStation's data.
+ '';
+ };
+
+ passwordFile = mkOption {
+ type = types.path;
+ default = pkgs.writeText "epgstation-db-password" defaultPassword;
+ example = "/run/keys/epgstation-db-password";
+ description = ''
+ A file containing the password for the database named
+ <option>database.name</option>.
+ '';
+ };
+ };
+
+ settings = mkOption {
+ description = ''
+ Options to add to config.json.
+
+ Documentation:
+ <link xlink:href="https://github.com/l3tnun/EPGStation/blob/master/doc/conf-manual.md"/>
+ '';
+
+ default = {};
+ example = {
+ recPriority = 20;
+ conflictPriority = 10;
+ };
+
+ type = types.submodule {
+ freeformType = settingsFmt.type;
+
+ options.readOnlyOnce = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Don't reload configuration files at runtime.";
+ };
+
+ options.mirakurunPath = mkOption (let
+ sockPath = config.services.mirakurun.unixSocket;
+ in {
+ type = types.str;
+ default = "http+unix://${replaceStrings ["/"] ["%2F"] sockPath}";
+ example = "http://localhost:40772";
+ description = "URL to connect to Mirakurun.";
+ });
+
+ options.encode = mkOption {
+ type = with types; listOf attrs;
+ description = "Encoding presets for recorded videos.";
+ default = [
+ { name = "H264";
+ cmd = "${pkgs.epgstation}/libexec/enc.sh main";
+ suffix = ".mp4";
+ default = true; }
+ { name = "H264-sub";
+ cmd = "${pkgs.epgstation}/libexec/enc.sh sub";
+ suffix = "-sub.mp4"; }
+ ];
+ };
+ };
+ };
+ };
+
+ config = mkIf cfg.enable {
+ environment.etc = {
+ "epgstation/operatorLogConfig.json".text = builtins.toJSON logConfig;
+ "epgstation/serviceLogConfig.json".text = builtins.toJSON logConfig;
+ };
+
+ networking.firewall = mkIf cfg.openFirewall {
+ allowedTCPPorts = with cfg; [ port socketioPort ];
+ };
+
+ users.users.epgstation = {
+ description = "EPGStation user";
+ group = config.users.groups.epgstation.name;
+ isSystemUser = true;
+ };
+
+ users.groups.epgstation = {};
+
+ services.mirakurun.enable = mkDefault true;
+
+ services.mysql = {
+ enable = mkDefault true;
+ package = mkDefault pkgs.mysql;
+ ensureDatabases = [ cfg.database.name ];
+ # FIXME: enable once mysqljs supports auth_socket
+ # ensureUsers = [ {
+ # name = username;
+ # ensurePermissions = { "${cfg.database.name}.*" = "ALL PRIVILEGES"; };
+ # } ];
+ };
+
+ services.epgstation.settings = let
+ defaultSettings = {
+ serverPort = cfg.port;
+ socketioPort = cfg.socketioPort;
+ clientSocketioPort = cfg.clientSocketioPort;
+
+ dbType = mkDefault "mysql";
+ mysql = {
+ user = username;
+ database = cfg.database.name;
+ socketPath = mkDefault "/run/mysqld/mysqld.sock";
+ password = mkDefault "@dbPassword@";
+ connectTimeout = mkDefault 1000;
+ connectionLimit = mkDefault 10;
+ };
+
+ basicAuth = mkIf (cfg.basicAuth.user != null) {
+ user = mkDefault cfg.basicAuth.user;
+ password = mkDefault "@password@";
+ };
+
+ ffmpeg = mkDefault "${pkgs.ffmpeg-full}/bin/ffmpeg";
+ ffprobe = mkDefault "${pkgs.ffmpeg-full}/bin/ffprobe";
+
+ fileExtension = mkDefault ".m2ts";
+ maxEncode = mkDefault 2;
+ maxStreaming = mkDefault 2;
+ };
+ in
+ mkMerge [
+ defaultSettings
+ (mkIf cfg.usePreconfiguredStreaming streamingConfig)
+ ];
+
+ systemd.tmpfiles.rules = [
+ "d '/var/lib/epgstation/streamfiles' - ${username} ${groupname} - -"
+ "d '/var/lib/epgstation/recorded' - ${username} ${groupname} - -"
+ "d '/var/lib/epgstation/thumbnail' - ${username} ${groupname} - -"
+ ];
+
+ systemd.services.epgstation = {
+ description = pkgs.epgstation.meta.description;
+ wantedBy = [ "multi-user.target" ];
+ after = [
+ "network.target"
+ ] ++ optional config.services.mirakurun.enable "mirakurun.service"
+ ++ optional config.services.mysql.enable "mysql.service";
+
+ serviceConfig = {
+ ExecStart = "${pkgs.epgstation}/bin/epgstation start";
+ ExecStartPre = "+${preStartScript}";
+ User = username;
+ Group = groupname;
+ StateDirectory = "epgstation";
+ LogsDirectory = "epgstation";
+ ConfigurationDirectory = "epgstation";
+ };
+ };
+ };
+}
diff --git a/nixpkgs/nixos/modules/services/video/epgstation/generate b/nixpkgs/nixos/modules/services/video/epgstation/generate
new file mode 100755
index 00000000000..2940768b6d2
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/video/epgstation/generate
@@ -0,0 +1,31 @@
+#!/usr/bin/env -S nix-build --no-out-link
+
+# Script to generate default streaming configurations for EPGStation. There's
+# no need to run this script directly since generate.sh in the EPGStation
+# package directory would run this script for you.
+#
+# Usage: ./generate | xargs cat > streaming.json
+
+{ pkgs ? (import ../../../../.. {}) }:
+
+let
+ sampleConfigPath = "${pkgs.epgstation.src}/config/config.sample.json";
+ sampleConfig = builtins.fromJSON (builtins.readFile sampleConfigPath);
+ streamingConfig = {
+ inherit (sampleConfig)
+ mpegTsStreaming
+ mpegTsViewer
+ liveHLS
+ liveMP4
+ liveWebM
+ recordedDownloader
+ recordedStreaming
+ recordedViewer
+ recordedHLS;
+ };
+in
+pkgs.runCommand "streaming.json" { nativeBuildInputs = [ pkgs.jq ]; } ''
+ jq . <<<'${builtins.toJSON streamingConfig}' > $out
+''
+
+# vim:set ft=nix:
diff --git a/nixpkgs/nixos/modules/services/video/epgstation/streaming.json b/nixpkgs/nixos/modules/services/video/epgstation/streaming.json
new file mode 100644
index 00000000000..37957f6cb6a
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/video/epgstation/streaming.json
@@ -0,0 +1,119 @@
+{
+ "liveHLS": [
+ {
+ "cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 0 -map 0 -ignore_unknown -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 17 -hls_allow_cache 1 -hls_segment_filename %streamFileDir%/stream%streamNum%-%09d.ts -c:a aac -ar 48000 -b:a 192k -ac 2 -c:v libx264 -vf yadif,scale=-2:720 -b:v 3000k -preset veryfast -flags +loop-global_header %OUTPUT%",
+ "name": "720p"
+ },
+ {
+ "cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 0 -map 0 -ignore_unknown -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 17 -hls_allow_cache 1 -hls_segment_filename %streamFileDir%/stream%streamNum%-%09d.ts -c:a aac -ar 48000 -b:a 128k -ac 2 -c:v libx264 -vf yadif,scale=-2:480 -b:v 1500k -preset veryfast -flags +loop-global_header %OUTPUT%",
+ "name": "480p"
+ },
+ {
+ "cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 0 -map 0 -ignore_unknown -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 17 -hls_allow_cache 1 -hls_segment_filename %streamFileDir%/stream%streamNum%-%09d.ts -c:a aac -ar 48000 -b:a 48k -ac 2 -c:v libx264 -vf yadif,scale=-2:180 -b:v 100k -preset veryfast -maxrate 110k -bufsize 1000k -flags +loop-global_header %OUTPUT%",
+ "name": "180p"
+ }
+ ],
+ "liveMP4": [
+ {
+ "cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 0 -c:a aac -ar 48000 -b:a 192k -ac 2 -c:v libx264 -vf yadif,scale=-2:720 -b:v 3000k -profile:v baseline -preset veryfast -tune fastdecode,zerolatency -movflags frag_keyframe+empty_moov+faststart+default_base_moof -y -f mp4 pipe:1",
+ "name": "720p"
+ },
+ {
+ "cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 0 -c:a aac -ar 48000 -b:a 128k -ac 2 -c:v libx264 -vf yadif,scale=-2:480 -b:v 1500k -profile:v baseline -preset veryfast -tune fastdecode,zerolatency -movflags frag_keyframe+empty_moov+faststart+default_base_moof -y -f mp4 pipe:1",
+ "name": "480p"
+ }
+ ],
+ "liveWebM": [
+ {
+ "cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 3 -c:a libvorbis -ar 48000 -b:a 192k -ac 2 -c:v libvpx-vp9 -vf yadif,scale=-2:720 -b:v 3000k -deadline realtime -speed 4 -cpu-used -8 -y -f webm pipe:1",
+ "name": "720p"
+ },
+ {
+ "cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 2 -c:a libvorbis -ar 48000 -b:a 128k -ac 2 -c:v libvpx-vp9 -vf yadif,scale=-2:480 -b:v 1500k -deadline realtime -speed 4 -cpu-used -8 -y -f webm pipe:1",
+ "name": "480p"
+ }
+ ],
+ "mpegTsStreaming": [
+ {
+ "cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 0 -c:a aac -ar 48000 -b:a 192k -ac 2 -c:v libx264 -vf yadif,scale=-2:720 -b:v 3000k -preset veryfast -y -f mpegts pipe:1",
+ "name": "720p"
+ },
+ {
+ "cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 0 -c:a aac -ar 48000 -b:a 128k -ac 2 -c:v libx264 -vf yadif,scale=-2:480 -b:v 1500k -preset veryfast -y -f mpegts pipe:1",
+ "name": "480p"
+ },
+ {
+ "name": "Original"
+ }
+ ],
+ "mpegTsViewer": {
+ "android": "intent://ADDRESS#Intent;package=com.mxtech.videoplayer.ad;type=video;scheme=http;end",
+ "ios": "vlc-x-callback://x-callback-url/stream?url=http://ADDRESS"
+ },
+ "recordedDownloader": {
+ "android": "intent://ADDRESS#Intent;package=com.dv.adm;type=video;scheme=http;end",
+ "ios": "vlc-x-callback://x-callback-url/download?url=http://ADDRESS&filename=FILENAME"
+ },
+ "recordedHLS": [
+ {
+ "cmd": "%FFMPEG% -dual_mono_mode main -i %INPUT% -sn -threads 0 -map 0 -ignore_unknown -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 0 -hls_allow_cache 1 -hls_segment_filename %streamFileDir%/stream%streamNum%-%09d.ts -c:a aac -ar 48000 -b:a 192k -ac 2 -c:v libx264 -vf yadif,scale=-2:720 -b:v 3000k -preset veryfast -flags +loop-global_header %OUTPUT%",
+ "name": "720p"
+ },
+ {
+ "cmd": "%FFMPEG% -dual_mono_mode main -i %INPUT% -sn -threads 0 -map 0 -ignore_unknown -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 0 -hls_allow_cache 1 -hls_segment_filename %streamFileDir%/stream%streamNum%-%09d.ts -c:a aac -ar 48000 -b:a 128k -ac 2 -c:v libx264 -vf yadif,scale=-2:480 -b:v 1500k -preset veryfast -flags +loop-global_header %OUTPUT%",
+ "name": "480p"
+ },
+ {
+ "cmd": "%FFMPEG% -dual_mono_mode main -i %INPUT% -sn -map 0 -ignore_unknown -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 0 -hls_allow_cache 1 -hls_segment_type fmp4 -hls_fmp4_init_filename stream%streamNum%-init.mp4 -hls_segment_filename stream%streamNum%-%09d.m4s -c:a aac -ar 48000 -b:a 128k -ac 2 -c:v libx265 -vf yadif,scale=-2:480 -b:v 350k -preset veryfast -tag:v hvc1 %OUTPUT%",
+ "name": "480p(h265)"
+ }
+ ],
+ "recordedStreaming": {
+ "mp4": [
+ {
+ "ab": "192k",
+ "cmd": "%FFMPEG% -dual_mono_mode main %RE% -i pipe:0 -sn -threads 0 -c:a aac -ar 48000 -ac 2 -c:v libx264 -vf yadif,scale=-2:720 %VB% %VBUFFER% %AB% %ABUFFER% -profile:v baseline -preset veryfast -tune fastdecode,zerolatency -movflags frag_keyframe+empty_moov+faststart+default_base_moof -y -f mp4 pipe:1",
+ "name": "720p",
+ "vb": "3000k"
+ },
+ {
+ "ab": "128k",
+ "cmd": "%FFMPEG% -dual_mono_mode main %RE% -i pipe:0 -sn -threads 0 -c:a aac -ar 48000 -ac 2 -c:v libx264 -vf yadif,scale=-2:360 %VB% %VBUFFER% %AB% %ABUFFER% -profile:v baseline -preset veryfast -tune fastdecode,zerolatency -movflags frag_keyframe+empty_moov+faststart+default_base_moof -y -f mp4 pipe:1",
+ "name": "360p",
+ "vb": "1500k"
+ }
+ ],
+ "mpegTs": [
+ {
+ "ab": "192k",
+ "cmd": "%FFMPEG% -dual_mono_mode main %RE% -i pipe:0 -sn -threads 0 -c:a aac -ar 48000 -ac 2 -c:v libx264 -vf yadif,scale=-2:720 %VB% %VBUFFER% %AB% %ABUFFER% -profile:v baseline -preset veryfast -tune fastdecode,zerolatency -y -f mpegts pipe:1",
+ "name": "720p (H.264)",
+ "vb": "3000k"
+ },
+ {
+ "ab": "128k",
+ "cmd": "%FFMPEG% -dual_mono_mode main %RE% -i pipe:0 -sn -threads 0 -c:a aac -ar 48000 -ac 2 -c:v libx264 -vf yadif,scale=-2:360 %VB% %VBUFFER% %AB% %ABUFFER% -profile:v baseline -preset veryfast -tune fastdecode,zerolatency -y -f mpegts pipe:1",
+ "name": "360p (H.264)",
+ "vb": "1500k"
+ }
+ ],
+ "webm": [
+ {
+ "ab": "192k",
+ "cmd": "%FFMPEG% -dual_mono_mode main %RE% -i pipe:0 -sn -threads 3 -c:a libvorbis -ar 48000 -ac 2 -c:v libvpx-vp9 -vf yadif,scale=-2:720 %VB% %VBUFFER% %AB% %ABUFFER% -deadline realtime -speed 4 -cpu-used -8 -y -f webm pipe:1",
+ "name": "720p",
+ "vb": "3000k"
+ },
+ {
+ "ab": "128k",
+ "cmd": "%FFMPEG% -dual_mono_mode main %RE% -i pipe:0 -sn -threads 2 -c:a libvorbis -ar 48000 -ac 2 -c:v libvpx-vp9 -vf yadif,scale=-2:360 %VB% %VBUFFER% %AB% %ABUFFER% -deadline realtime -speed 4 -cpu-used -8 -y -f webm pipe:1",
+ "name": "360p",
+ "vb": "1500k"
+ }
+ ]
+ },
+ "recordedViewer": {
+ "android": "intent://ADDRESS#Intent;package=com.mxtech.videoplayer.ad;type=video;scheme=http;end",
+ "ios": "infuse://x-callback-url/play?url=http://ADDRESS"
+ }
+}
diff --git a/nixpkgs/nixos/modules/services/video/mirakurun.nix b/nixpkgs/nixos/modules/services/video/mirakurun.nix
new file mode 100644
index 00000000000..ce1dabe6bfa
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/video/mirakurun.nix
@@ -0,0 +1,183 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.mirakurun;
+ mirakurun = pkgs.mirakurun;
+ username = config.users.users.mirakurun.name;
+ groupname = config.users.users.mirakurun.group;
+ settingsFmt = pkgs.formats.yaml {};
+in
+ {
+ options = {
+ services.mirakurun = {
+ enable = mkEnableOption mirakurun.meta.description;
+
+ port = mkOption {
+ type = with types; nullOr port;
+ default = 40772;
+ description = ''
+ Port to listen on. If <literal>null</literal>, it won't listen on
+ any port.
+ '';
+ };
+
+ openFirewall = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Open ports in the firewall for Mirakurun.
+
+ <warning>
+ <para>
+ Exposing Mirakurun to the open internet is generally advised
+ against. Only use it inside a trusted local network, or
+ consider putting it behind a VPN if you want remote access.
+ </para>
+ </warning>
+ '';
+ };
+
+ unixSocket = mkOption {
+ type = with types; nullOr path;
+ default = "/var/run/mirakurun/mirakurun.sock";
+ description = ''
+ Path to unix socket to listen on. If <literal>null</literal>, it
+ won't listen on any unix sockets.
+ '';
+ };
+
+ serverSettings = mkOption {
+ type = settingsFmt.type;
+ default = {};
+ example = literalExample ''
+ {
+ highWaterMark = 25165824;
+ overflowTimeLimit = 30000;
+ };
+ '';
+ description = ''
+ Options for server.yml.
+
+ Documentation:
+ <link xlink:href="https://github.com/Chinachu/Mirakurun/blob/master/doc/Configuration.md"/>
+ '';
+ };
+
+ tunerSettings = mkOption {
+ type = with types; nullOr settingsFmt.type;
+ default = null;
+ example = literalExample ''
+ [
+ {
+ name = "tuner-name";
+ types = [ "GR" "BS" "CS" "SKY" ];
+ dvbDevicePath = "/dev/dvb/adapterX/dvrX";
+ }
+ ];
+ '';
+ description = ''
+ Options which are added to tuners.yml. If none is specified, it will
+ automatically be generated at runtime.
+
+ Documentation:
+ <link xlink:href="https://github.com/Chinachu/Mirakurun/blob/master/doc/Configuration.md"/>
+ '';
+ };
+
+ channelSettings = mkOption {
+ type = with types; nullOr settingsFmt.type;
+ default = null;
+ example = literalExample ''
+ [
+ {
+ name = "channel";
+ types = "GR";
+ channel = "0";
+ }
+ ];
+ '';
+ description = ''
+ Options which are added to channels.yml. If none is specified, it
+ will automatically be generated at runtime.
+
+ Documentation:
+ <link xlink:href="https://github.com/Chinachu/Mirakurun/blob/master/doc/Configuration.md"/>
+ '';
+ };
+ };
+ };
+
+ config = mkIf cfg.enable {
+ environment.systemPackages = [ mirakurun ];
+ environment.etc = {
+ "mirakurun/server.yml".source = settingsFmt.generate "server.yml" cfg.serverSettings;
+ "mirakurun/tuners.yml" = mkIf (cfg.tunerSettings != null) {
+ source = settingsFmt.generate "tuners.yml" cfg.tunerSettings;
+ mode = "0644";
+ user = username;
+ group = groupname;
+ };
+ "mirakurun/channels.yml" = mkIf (cfg.channelSettings != null) {
+ source = settingsFmt.generate "channels.yml" cfg.channelSettings;
+ mode = "0644";
+ user = username;
+ group = groupname;
+ };
+ };
+
+ networking.firewall = mkIf cfg.openFirewall {
+ allowedTCPPorts = mkIf (cfg.port != null) [ cfg.port ];
+ };
+
+ users.users.mirakurun = {
+ description = "Mirakurun user";
+ group = "video";
+ isSystemUser = true;
+ };
+
+ services.mirakurun.serverSettings = {
+ logLevel = mkDefault 2;
+ path = mkIf (cfg.unixSocket != null) cfg.unixSocket;
+ port = mkIf (cfg.port != null) cfg.port;
+ };
+
+ systemd.tmpfiles.rules = [
+ "d '/etc/mirakurun' - ${username} ${groupname} - -"
+ ];
+
+ systemd.services.mirakurun = {
+ description = mirakurun.meta.description;
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network.target" ];
+ serviceConfig = {
+ ExecStart = "${mirakurun}/bin/mirakurun";
+ User = username;
+ Group = groupname;
+ RuntimeDirectory="mirakurun";
+ StateDirectory="mirakurun";
+ Nice = -10;
+ IOSchedulingClass = "realtime";
+ IOSchedulingPriority = 7;
+ };
+
+ environment = {
+ SERVER_CONFIG_PATH = "/etc/mirakurun/server.yml";
+ TUNERS_CONFIG_PATH = "/etc/mirakurun/tuners.yml";
+ CHANNELS_CONFIG_PATH = "/etc/mirakurun/channels.yml";
+ SERVICES_DB_PATH = "/var/lib/mirakurun/services.json";
+ PROGRAMS_DB_PATH = "/var/lib/mirakurun/programs.json";
+ NODE_ENV = "production";
+ };
+
+ restartTriggers = let
+ getconf = target: config.environment.etc."mirakurun/${target}.yml".source;
+ targets = [
+ "server"
+ ] ++ optional (cfg.tunerSettings != null) "tuners"
+ ++ optional (cfg.channelSettings != null) "channels";
+ in (map getconf targets);
+ };
+ };
+ }
diff --git a/nixpkgs/nixos/modules/services/wayland/cage.nix b/nixpkgs/nixos/modules/services/wayland/cage.nix
index c59ca9983a6..14d84c4ce0f 100644
--- a/nixpkgs/nixos/modules/services/wayland/cage.nix
+++ b/nixpkgs/nixos/modules/services/wayland/cage.nix
@@ -73,8 +73,6 @@ in {
TTYVTDisallocate = "yes";
# Fail to start if not controlling the virtual terminal.
StandardInput = "tty-fail";
- StandardOutput = "syslog";
- StandardError = "syslog";
# Set up a full (custom) user session for the user, required by Cage.
PAMName = "cage";
};
@@ -84,6 +82,7 @@ in {
auth required pam_unix.so nullok
account required pam_unix.so
session required pam_unix.so
+ session required pam_env.so conffile=${config.system.build.pamEnvironment} readenv=0
session required ${pkgs.systemd}/lib/security/pam_systemd.so
'';
diff --git a/nixpkgs/nixos/modules/services/web-apps/dokuwiki.nix b/nixpkgs/nixos/modules/services/web-apps/dokuwiki.nix
index fe6b9210d24..d9ebb3a9880 100644
--- a/nixpkgs/nixos/modules/services/web-apps/dokuwiki.nix
+++ b/nixpkgs/nixos/modules/services/web-apps/dokuwiki.nix
@@ -2,7 +2,7 @@
let
- inherit (lib) mkEnableOption mkForce mkIf mkMerge mkOption optionalAttrs recursiveUpdate types;
+ inherit (lib) mkEnableOption mkForce mkIf mkMerge mkOption optionalAttrs recursiveUpdate types maintainers;
inherit (lib) concatMapStringsSep flatten mapAttrs mapAttrs' mapAttrsToList nameValuePair concatMapStringSep;
eachSite = config.services.dokuwiki;
@@ -95,7 +95,7 @@ let
aclFile = mkOption {
type = with types; nullOr str;
- default = if (config.aclUse && config.acl == null) then "/var/lib/dokuwiki/${name}/users.auth.php" else null;
+ default = if (config.aclUse && config.acl == null) then "/var/lib/dokuwiki/${name}/acl.auth.php" else null;
description = ''
Location of the dokuwiki acl rules. Mutually exclusive with services.dokuwiki.acl
Mutually exclusive with services.dokuwiki.acl which is preferred.
@@ -249,22 +249,19 @@ let
nginx = mkOption {
type = types.submodule (
recursiveUpdate
- (import ../web-servers/nginx/vhost-options.nix { inherit config lib; })
- {
- # Enable encryption by default,
- options.forceSSL.default = true;
- options.enableACME.default = true;
- }
+ (import ../web-servers/nginx/vhost-options.nix { inherit config lib; }) {}
);
- default = {forceSSL = true; enableACME = true;};
+ default = {};
example = {
serverAliases = [
"wiki.\${config.networking.domain}"
];
- enableACME = false;
+ # To enable encryption and let let's encrypt take care of certificate
+ forceSSL = true;
+ enableACME = true;
};
description = ''
- With this option, you can customize the nginx virtualHost which already has sensible defaults for DokuWiki.
+ With this option, you can customize the nginx virtualHost settings.
'';
};
};
@@ -276,7 +273,7 @@ in
services.dokuwiki = mkOption {
type = types.attrsOf (types.submodule siteOpts);
default = {};
- description = "Sepcification of one or more dokuwiki sites to service.";
+ description = "Sepcification of one or more dokuwiki sites to serve.";
};
};
@@ -385,4 +382,7 @@ in
isSystemUser = true;
};
};
+
+ meta.maintainers = with maintainers; [ _1000101 ];
+
}
diff --git a/nixpkgs/nixos/modules/services/web-apps/jitsi-meet.nix b/nixpkgs/nixos/modules/services/web-apps/jitsi-meet.nix
index 3b2b2440491..2df762882fa 100644
--- a/nixpkgs/nixos/modules/services/web-apps/jitsi-meet.nix
+++ b/nixpkgs/nixos/modules/services/web-apps/jitsi-meet.nix
@@ -329,5 +329,6 @@ in
};
};
+ meta.doc = ./jitsi-meet.xml;
meta.maintainers = lib.teams.jitsi.members;
}
diff --git a/nixpkgs/nixos/modules/services/web-apps/jitsi-meet.xml b/nixpkgs/nixos/modules/services/web-apps/jitsi-meet.xml
new file mode 100644
index 00000000000..97373bc6d9a
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/web-apps/jitsi-meet.xml
@@ -0,0 +1,55 @@
+<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="module-services-jitsi-meet">
+ <title>Jitsi Meet</title>
+ <para>
+ With Jitsi Meet on NixOS you can quickly configure a complete,
+ private, self-hosted video conferencing solution.
+ </para>
+
+ <section xml:id="module-services-jitsi-basic-usage">
+ <title>Basic usage</title>
+ <para>
+ A minimal configuration using Let's Encrypt for TLS certificates looks like this:
+<programlisting>{
+ services.jitsi-meet = {
+ <link linkend="opt-services.jitsi-meet.enable">enable</link> = true;
+ <link linkend="opt-services.jitsi-meet.enable">hostName</link> = "jitsi.example.com";
+ };
+ <link linkend="opt-services.jitsi-videobridge.openFirewall">services.jitsi-videobridge.openFirewall</link> = true;
+ <link linkend="opt-networking.firewall.allowedTCPPorts">networking.firewall.allowedTCPPorts</link> = [ 80 443 ];
+ <link linkend="opt-security.acme.email">security.acme.email</link> = "me@example.com";
+ <link linkend="opt-security.acme.acceptTerms">security.acme.acceptTerms</link> = true;
+}</programlisting>
+ </para>
+ </section>
+
+ <section xml:id="module-services-jitsi-configuration">
+ <title>Configuration</title>
+ <para>
+ Here is the minimal configuration with additional configurations:
+<programlisting>{
+ services.jitsi-meet = {
+ <link linkend="opt-services.jitsi-meet.enable">enable</link> = true;
+ <link linkend="opt-services.jitsi-meet.enable">hostName</link> = "jitsi.example.com";
+ <link linkend="opt-services.jitsi-meet.config">config</link> = {
+ enableWelcomePage = false;
+ prejoinPageEnabled = true;
+ defaultLang = "fi";
+ };
+ <link linkend="opt-services.jitsi-meet.interfaceConfig">interfaceConfig</link> = {
+ SHOW_JITSI_WATERMARK = false;
+ SHOW_WATERMARK_FOR_GUESTS = false;
+ };
+ };
+ <link linkend="opt-services.jitsi-videobridge.openFirewall">services.jitsi-videobridge.openFirewall</link> = true;
+ <link linkend="opt-networking.firewall.allowedTCPPorts">networking.firewall.allowedTCPPorts</link> = [ 80 443 ];
+ <link linkend="opt-security.acme.email">security.acme.email</link> = "me@example.com";
+ <link linkend="opt-security.acme.acceptTerms">security.acme.acceptTerms</link> = true;
+}</programlisting>
+ </para>
+ </section>
+
+</chapter>
diff --git a/nixpkgs/nixos/modules/services/web-apps/nextcloud.nix b/nixpkgs/nixos/modules/services/web-apps/nextcloud.nix
index 328561dc800..7da119758fc 100644
--- a/nixpkgs/nixos/modules/services/web-apps/nextcloud.nix
+++ b/nixpkgs/nixos/modules/services/web-apps/nextcloud.nix
@@ -45,6 +45,22 @@ let
inherit (config.system) stateVersion;
in {
+
+ imports = [
+ (mkRemovedOptionModule [ "services" "nextcloud" "nginx" "enable" ] ''
+ The nextcloud module supports `nginx` as reverse-proxy by default and doesn't
+ support other reverse-proxies officially.
+
+ However it's possible to use an alternative reverse-proxy by
+
+ * disabling nginx
+ * setting `listen.owner` & `listen.group` in the phpfpm-pool to a different value
+
+ Further details about this can be found in the `Nextcloud`-section of the NixOS-manual
+ (which can be openend e.g. by running `nixos-help`).
+ '')
+ ];
+
options.services.nextcloud = {
enable = mkEnableOption "nextcloud";
hostName = mkOption {
@@ -91,16 +107,6 @@ in {
'';
};
- nginx.enable = mkOption {
- type = types.bool;
- default = false;
- description = ''
- Whether to enable nginx virtual host management.
- Further nginx configuration can be done by adapting <literal>services.nginx.virtualHosts.&lt;name&gt;</literal>.
- See <xref linkend="opt-services.nginx.virtualHosts"/> for further information.
- '';
- };
-
webfinger = mkOption {
type = types.bool;
default = false;
@@ -468,10 +474,18 @@ in {
script = ''
chmod og+x ${cfg.home}
ln -sf ${cfg.package}/apps ${cfg.home}/
- mkdir -p ${cfg.home}/config ${cfg.home}/data ${cfg.home}/store-apps
- ln -sf ${overrideConfig} ${cfg.home}/config/override.config.php
- chown -R nextcloud:nginx ${cfg.home}/config ${cfg.home}/data ${cfg.home}/store-apps
+ # create nextcloud directories.
+ # if the directories exist already with wrong permissions, we fix that
+ for dir in ${cfg.home}/config ${cfg.home}/data ${cfg.home}/store-apps; do
+ if [ ! -e $dir ]; then
+ install -o nextcloud -g nextcloud -d $dir
+ elif [ $(stat -c "%G" $dir) != "nextcloud" ]; then
+ chgrp -R nextcloud $dir
+ fi
+ done
+
+ ln -sf ${overrideConfig} ${cfg.home}/config/override.config.php
# Do not install if already installed
if [[ ! -e ${cfg.home}/config/config.php ]]; then
@@ -484,6 +498,7 @@ in {
${occSetTrustedDomainsCmd}
'';
serviceConfig.Type = "oneshot";
+ serviceConfig.User = "nextcloud";
};
nextcloud-cron = {
environment.NEXTCLOUD_CONFIG_DIR = "${cfg.home}/config";
@@ -502,7 +517,7 @@ in {
services.phpfpm = {
pools.nextcloud = {
user = "nextcloud";
- group = "nginx";
+ group = "nextcloud";
phpOptions = phpOptionsStr;
phpPackage = phpPackage;
phpEnv = {
@@ -510,128 +525,121 @@ in {
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";
+ "listen.owner" = config.services.nginx.user;
+ "listen.group" = config.services.nginx.group;
} // cfg.poolSettings;
extraConfig = cfg.poolConfig;
};
};
- users.extraUsers.nextcloud = {
+ users.users.nextcloud = {
home = "${cfg.home}";
- group = "nginx";
+ group = "nextcloud";
createHome = true;
};
+ users.groups.nextcloud.members = [ "nextcloud" config.services.nginx.user ];
environment.systemPackages = [ occ ];
- }
- (mkIf cfg.nginx.enable {
- services.nginx = {
- enable = true;
- virtualHosts = {
- ${cfg.hostName} = {
- root = cfg.package;
- locations = {
- "= /robots.txt" = {
- priority = 100;
- extraConfig = ''
- allow all;
- log_not_found off;
- access_log off;
- '';
- };
- "/" = {
- priority = 200;
- extraConfig = "rewrite ^ /index.php;";
- };
- "~ ^/store-apps" = {
- priority = 201;
- extraConfig = "root ${cfg.home};";
- };
- "= /.well-known/carddav" = {
- priority = 210;
- extraConfig = "return 301 $scheme://$host/remote.php/dav;";
- };
- "= /.well-known/caldav" = {
- priority = 210;
- extraConfig = "return 301 $scheme://$host/remote.php/dav;";
- };
- "~ ^\\/(?:build|tests|config|lib|3rdparty|templates|data)\\/" = {
- priority = 300;
- extraConfig = "deny all;";
- };
- "~ ^\\/(?:\\.|autotest|occ|issue|indie|db_|console)" = {
- priority = 300;
- extraConfig = "deny all;";
- };
- "~ ^\\/(?:index|remote|public|cron|core/ajax\\/update|status|ocs\\/v[12]|updater\\/.+|ocs-provider\\/.+|ocm-provider\\/.+)\\.php(?:$|\\/)" = {
- priority = 500;
- extraConfig = ''
- include ${config.services.nginx.package}/conf/fastcgi.conf;
- fastcgi_split_path_info ^(.+\.php)(\\/.*)$;
- try_files $fastcgi_script_name =404;
- fastcgi_param PATH_INFO $fastcgi_path_info;
- fastcgi_param HTTPS ${if cfg.https then "on" else "off"};
- fastcgi_param modHeadersAvailable true;
- fastcgi_param front_controller_active true;
- fastcgi_pass unix:${fpm.socket};
- fastcgi_intercept_errors on;
- fastcgi_request_buffering off;
- fastcgi_read_timeout 120s;
- '';
- };
- "~ ^\\/(?:updater|ocs-provider|ocm-provider)(?:$|\\/)".extraConfig = ''
- try_files $uri/ =404;
- index index.php;
- '';
- "~ \\.(?:css|js|woff2?|svg|gif)$".extraConfig = ''
- try_files $uri /index.php$request_uri;
- add_header Cache-Control "public, max-age=15778463";
- add_header X-Content-Type-Options nosniff;
- add_header X-XSS-Protection "1; mode=block";
- add_header X-Robots-Tag none;
- add_header X-Download-Options noopen;
- add_header X-Permitted-Cross-Domain-Policies none;
- add_header X-Frame-Options sameorigin;
- add_header Referrer-Policy no-referrer;
- access_log off;
- '';
- "~ \\.(?:png|html|ttf|ico|jpg|jpeg|bcmap|mp4|webm)$".extraConfig = ''
- try_files $uri /index.php$request_uri;
- access_log off;
- '';
- };
+ services.nginx.enable = mkDefault true;
+ services.nginx.virtualHosts.${cfg.hostName} = {
+ root = cfg.package;
+ locations = {
+ "= /robots.txt" = {
+ priority = 100;
extraConfig = ''
- add_header X-Content-Type-Options nosniff;
- add_header X-XSS-Protection "1; mode=block";
- add_header X-Robots-Tag none;
- add_header X-Download-Options noopen;
- add_header X-Permitted-Cross-Domain-Policies none;
- add_header X-Frame-Options sameorigin;
- add_header Referrer-Policy no-referrer;
- add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
- error_page 403 /core/templates/403.php;
- error_page 404 /core/templates/404.php;
- client_max_body_size ${cfg.maxUploadSize};
- fastcgi_buffers 64 4K;
- fastcgi_hide_header X-Powered-By;
- gzip on;
- gzip_vary on;
- gzip_comp_level 4;
- gzip_min_length 256;
- gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
- gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
-
- ${optionalString cfg.webfinger ''
- rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
- rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;
- ''}
+ allow all;
+ log_not_found off;
+ access_log off;
'';
};
+ "/" = {
+ priority = 900;
+ extraConfig = "try_files $uri $uri/ /index.php$request_uri;";
+ };
+ "~ ^/store-apps" = {
+ priority = 201;
+ extraConfig = "root ${cfg.home};";
+ };
+ "^~ /.well-known" = {
+ priority = 210;
+ extraConfig = ''
+ location = /.well-known/carddav {
+ return 301 $scheme://$host/remote.php/dav;
+ }
+ location = /.well-known/caldav {
+ return 301 $scheme://$host/remote.php/dav;
+ }
+ try_files $uri $uri/ =404;
+ '';
+ };
+ "~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/)".extraConfig = ''
+ return 404;
+ '';
+ "~ ^/(?:\\.|autotest|occ|issue|indie|db_|console)".extraConfig = ''
+ return 404;
+ '';
+ "~ \\.php(?:$|/)" = {
+ priority = 500;
+ extraConfig = ''
+ include ${config.services.nginx.package}/conf/fastcgi.conf;
+ fastcgi_split_path_info ^(.+?\.php)(\\/.*)$;
+ set $path_info $fastcgi_path_info;
+ try_files $fastcgi_script_name =404;
+ fastcgi_param PATH_INFO $path_info;
+ fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+ fastcgi_param HTTPS ${if cfg.https then "on" else "off"};
+ fastcgi_param modHeadersAvailable true;
+ fastcgi_param front_controller_active true;
+ fastcgi_pass unix:${fpm.socket};
+ fastcgi_intercept_errors on;
+ fastcgi_request_buffering off;
+ fastcgi_read_timeout 120s;
+ '';
+ };
+ "~ \\.(?:css|js|svg|gif|map)$".extraConfig = ''
+ try_files $uri /index.php$request_uri;
+ expires 6M;
+ access_log off;
+ '';
+ "~ \\.woff2?$".extraConfig = ''
+ try_files $uri /index.php$request_uri;
+ expires 7d;
+ access_log off;
+ '';
+ "~ ^\\/(?:updater|ocs-provider|ocm-provider)(?:$|\\/)".extraConfig = ''
+ try_files $uri/ =404;
+ index index.php;
+ '';
};
+ extraConfig = ''
+ index index.php index.html /index.php$request_uri;
+ expires 1m;
+ add_header X-Content-Type-Options nosniff;
+ add_header X-XSS-Protection "1; mode=block";
+ add_header X-Robots-Tag none;
+ add_header X-Download-Options noopen;
+ add_header X-Permitted-Cross-Domain-Policies none;
+ add_header X-Frame-Options sameorigin;
+ add_header Referrer-Policy no-referrer;
+ add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
+ client_max_body_size ${cfg.maxUploadSize};
+ fastcgi_buffers 64 4K;
+ fastcgi_hide_header X-Powered-By;
+ gzip on;
+ gzip_vary on;
+ gzip_comp_level 4;
+ gzip_min_length 256;
+ gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
+ gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
+
+ ${optionalString cfg.webfinger ''
+ rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
+ rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;
+ ''}
+ '';
};
- })
+ }
]);
meta.doc = ./nextcloud.xml;
diff --git a/nixpkgs/nixos/modules/services/web-apps/nextcloud.xml b/nixpkgs/nixos/modules/services/web-apps/nextcloud.xml
index 332e4d1ff3e..02e4dba2861 100644
--- a/nixpkgs/nixos/modules/services/web-apps/nextcloud.xml
+++ b/nixpkgs/nixos/modules/services/web-apps/nextcloud.xml
@@ -29,7 +29,6 @@
services.nextcloud = {
<link linkend="opt-services.nextcloud.enable">enable</link> = true;
<link linkend="opt-services.nextcloud.hostName">hostName</link> = "nextcloud.tld";
- <link linkend="opt-services.nextcloud.nginx.enable">nginx.enable</link> = true;
config = {
<link linkend="opt-services.nextcloud.config.dbtype">dbtype</link> = "pgsql";
<link linkend="opt-services.nextcloud.config.dbuser">dbuser</link> = "nextcloud";
@@ -61,9 +60,8 @@
</para>
<para>
- The options <literal>hostName</literal> and <literal>nginx.enable</literal>
- are used internally to configure an HTTP server using
- <literal><link xlink:href="https://php-fpm.org/">PHP-FPM</link></literal>
+ The <literal>hostName</literal> option is used internally to configure an HTTP
+ server using <literal><link xlink:href="https://php-fpm.org/">PHP-FPM</link></literal>
and <literal>nginx</literal>. The <literal>config</literal> attribute set is
used by the imperative installer and all values are written to an additional file
to ensure that changes can be applied by changing the module's options.
@@ -125,6 +123,61 @@
</para>
</section>
+ <section xml:id="module-services-nextcloud-httpd">
+ <title>Using an alternative webserver as reverse-proxy (e.g. <literal>httpd</literal>)</title>
+ <para>
+ By default, <package>nginx</package> is used as reverse-proxy for <package>nextcloud</package>.
+ However, it's possible to use e.g. <package>httpd</package> by explicitly disabling
+ <package>nginx</package> using <xref linkend="opt-services.nginx.enable" /> and fixing the
+ settings <literal>listen.owner</literal> &amp; <literal>listen.group</literal> in the
+ <link linkend="opt-services.phpfpm.pools">corresponding <literal>phpfpm</literal> pool</link>.
+ </para>
+ <para>
+ An exemplary configuration may look like this:
+<programlisting>{ config, lib, pkgs, ... }: {
+ <link linkend="opt-services.nginx.enable">services.nginx.enable</link> = false;
+ services.nextcloud = {
+ <link linkend="opt-services.nextcloud.enable">enable</link> = true;
+ <link linkend="opt-services.nextcloud.hostName">hostName</link> = "localhost";
+
+ /* further, required options */
+ };
+ <link linkend="opt-services.phpfpm.pools._name_.settings">services.phpfpm.pools.nextcloud.settings</link> = {
+ "listen.owner" = config.services.httpd.user;
+ "listen.group" = config.services.httpd.group;
+ };
+ services.httpd = {
+ <link linkend="opt-services.httpd.enable">enable</link> = true;
+ <link linkend="opt-services.httpd.adminAddr">adminAddr</link> = "webmaster@localhost";
+ <link linkend="opt-services.httpd.extraModules">extraModules</link> = [ "proxy_fcgi" ];
+ virtualHosts."localhost" = {
+ <link linkend="opt-services.httpd.virtualHosts._name_.documentRoot">documentRoot</link> = config.services.nextcloud.package;
+ <link linkend="opt-services.httpd.virtualHosts._name_.extraConfig">extraConfig</link> = ''
+ &lt;Directory "${config.services.nextcloud.package}"&gt;
+ &lt;FilesMatch "\.php$"&gt;
+ &lt;If "-f %{REQUEST_FILENAME}"&gt;
+ SetHandler "proxy:unix:${config.services.phpfpm.pools.nextcloud.socket}|fcgi://localhost/"
+ &lt;/If&gt;
+ &lt;/FilesMatch&gt;
+ &lt;IfModule mod_rewrite.c&gt;
+ RewriteEngine On
+ RewriteBase /
+ RewriteRule ^index\.php$ - [L]
+ RewriteCond %{REQUEST_FILENAME} !-f
+ RewriteCond %{REQUEST_FILENAME} !-d
+ RewriteRule . /index.php [L]
+ &lt;/IfModule&gt;
+ DirectoryIndex index.php
+ Require all granted
+ Options +FollowSymLinks
+ &lt;/Directory&gt;
+ '';
+ };
+ };
+}</programlisting>
+ </para>
+ </section>
+
<section xml:id="module-services-nextcloud-maintainer-info">
<title>Maintainer information</title>
diff --git a/nixpkgs/nixos/modules/services/web-apps/pgpkeyserver-lite.nix b/nixpkgs/nixos/modules/services/web-apps/pgpkeyserver-lite.nix
index ad70ba70bbe..838fd19ad29 100644
--- a/nixpkgs/nixos/modules/services/web-apps/pgpkeyserver-lite.nix
+++ b/nixpkgs/nixos/modules/services/web-apps/pgpkeyserver-lite.nix
@@ -33,7 +33,7 @@ in
description = "
Which hostname to set the vHost to that is proxying to sks.
";
- };
+ };
hkpAddress = mkOption {
default = builtins.head sksCfg.hkpAddress;
diff --git a/nixpkgs/nixos/modules/services/web-apps/rss-bridge.nix b/nixpkgs/nixos/modules/services/web-apps/rss-bridge.nix
new file mode 100644
index 00000000000..f1d5b7660f3
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/web-apps/rss-bridge.nix
@@ -0,0 +1,127 @@
+{ config, lib, pkgs, ... }:
+with lib;
+let
+ cfg = config.services.rss-bridge;
+
+ poolName = "rss-bridge";
+
+ whitelist = pkgs.writeText "rss-bridge_whitelist.txt"
+ (concatStringsSep "\n" cfg.whitelist);
+in
+{
+ options = {
+ services.rss-bridge = {
+ enable = mkEnableOption "rss-bridge";
+
+ user = mkOption {
+ type = types.str;
+ default = "nginx";
+ example = "nginx";
+ description = ''
+ User account under which both the service and the web-application run.
+ '';
+ };
+
+ group = mkOption {
+ type = types.str;
+ default = "nginx";
+ example = "nginx";
+ description = ''
+ Group under which the web-application run.
+ '';
+ };
+
+ pool = mkOption {
+ type = types.str;
+ default = poolName;
+ description = ''
+ Name of existing phpfpm pool that is used to run web-application.
+ If not specified a pool will be created automatically with
+ default values.
+ '';
+ };
+
+ dataDir = mkOption {
+ type = types.str;
+ default = "/var/lib/rss-bridge";
+ description = ''
+ Location in which cache directory will be created.
+ You can put <literal>config.ini.php</literal> in here.
+ '';
+ };
+
+ virtualHost = mkOption {
+ type = types.nullOr types.str;
+ default = "rss-bridge";
+ description = ''
+ Name of the nginx virtualhost to use and setup. If null, do not setup any virtualhost.
+ '';
+ };
+
+ whitelist = mkOption {
+ type = types.listOf types.str;
+ default = [];
+ example = options.literalExample ''
+ [
+ "Facebook"
+ "Instagram"
+ "Twitter"
+ ]
+ '';
+ description = ''
+ List of bridges to be whitelisted.
+ If the list is empty, rss-bridge will use whitelist.default.txt.
+ Use <literal>[ "*" ]</literal> to whitelist all.
+ '';
+ };
+ };
+ };
+
+ config = mkIf cfg.enable {
+ services.phpfpm.pools = mkIf (cfg.pool == poolName) {
+ ${poolName} = {
+ user = cfg.user;
+ settings = mapAttrs (name: mkDefault) {
+ "listen.owner" = cfg.user;
+ "listen.group" = cfg.user;
+ "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.tmpfiles.rules = [
+ "d '${cfg.dataDir}/cache' 0750 ${cfg.user} ${cfg.group} - -"
+ (mkIf (cfg.whitelist != []) "L+ ${cfg.dataDir}/whitelist.txt - - - - ${whitelist}")
+ "z '${cfg.dataDir}/config.ini.php' 0750 ${cfg.user} ${cfg.group} - -"
+ ];
+
+ services.nginx = mkIf (cfg.virtualHost != null) {
+ enable = true;
+ virtualHosts = {
+ ${cfg.virtualHost} = {
+ root = "${pkgs.rss-bridge}";
+
+ locations."/" = {
+ tryFiles = "$uri /index.php$is_args$args";
+ };
+
+ locations."~ ^/index.php(/|$)" = {
+ extraConfig = ''
+ include ${pkgs.nginx}/conf/fastcgi_params;
+ fastcgi_split_path_info ^(.+\.php)(/.+)$;
+ fastcgi_pass unix:${config.services.phpfpm.pools.${cfg.pool}.socket};
+ fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+ fastcgi_param RSSBRIDGE_DATA ${cfg.dataDir};
+ '';
+ };
+ };
+ };
+ };
+ };
+}
diff --git a/nixpkgs/nixos/modules/services/web-apps/sogo.nix b/nixpkgs/nixos/modules/services/web-apps/sogo.nix
index 5f30124dd68..4610bb96cb5 100644
--- a/nixpkgs/nixos/modules/services/web-apps/sogo.nix
+++ b/nixpkgs/nixos/modules/services/web-apps/sogo.nix
@@ -77,7 +77,6 @@ in {
// Paths
WOSendMail = "/run/wrappers/bin/sendmail";
SOGoMailSpoolPath = "/var/lib/sogo/spool";
- SOGoZipPath = "${pkgs.zip}/bin/zip";
// Enable CSRF protection
SOGoXSRFValidationEnabled = YES;
// Remove dates from log (jornald does that)
diff --git a/nixpkgs/nixos/modules/services/web-apps/trilium.nix b/nixpkgs/nixos/modules/services/web-apps/trilium.nix
index 6f47193c62b..3fa8dad0490 100644
--- a/nixpkgs/nixos/modules/services/web-apps/trilium.nix
+++ b/nixpkgs/nixos/modules/services/web-apps/trilium.nix
@@ -83,7 +83,7 @@ in
};
};
- config = lib.mkIf cfg.enable (lib.mkMerge [
+ config = lib.mkIf cfg.enable (lib.mkMerge [
{
meta.maintainers = with lib.maintainers; [ kampka ];
diff --git a/nixpkgs/nixos/modules/services/web-apps/tt-rss.nix b/nixpkgs/nixos/modules/services/web-apps/tt-rss.nix
index 2ea9537b93d..6a29f10d119 100644
--- a/nixpkgs/nixos/modules/services/web-apps/tt-rss.nix
+++ b/nixpkgs/nixos/modules/services/web-apps/tt-rss.nix
@@ -632,8 +632,6 @@ let
User = "${cfg.user}";
Group = "tt_rss";
ExecStart = "${pkgs.php}/bin/php ${cfg.root}/update.php --daemon --quiet";
- StandardOutput = "syslog";
- StandardError = "syslog";
Restart = "on-failure";
RestartSec = "60";
SyslogIdentifier = "tt-rss";
diff --git a/nixpkgs/nixos/modules/services/web-servers/apache-httpd/default.nix b/nixpkgs/nixos/modules/services/web-servers/apache-httpd/default.nix
index e1d1217943b..6dd1c85132c 100644
--- a/nixpkgs/nixos/modules/services/web-servers/apache-httpd/default.nix
+++ b/nixpkgs/nixos/modules/services/web-servers/apache-httpd/default.nix
@@ -6,10 +6,18 @@ let
cfg = config.services.httpd;
+ certs = config.security.acme.certs;
+
runtimeDir = "/run/httpd";
pkg = cfg.package.out;
+ apachectl = pkgs.runCommand "apachectl" { meta.priority = -1; } ''
+ mkdir -p $out/bin
+ cp ${pkg}/bin/apachectl $out/bin/apachectl
+ sed -i $out/bin/apachectl -e 's|$HTTPD -t|$HTTPD -t -f ${httpdConf}|'
+ '';
+
httpdConf = cfg.configFile;
php = cfg.phpPackage.override { apacheHttpd = pkg; };
@@ -20,6 +28,13 @@ let
vhosts = attrValues cfg.virtualHosts;
+ # certName is used later on to determine systemd service names.
+ acmeEnabledVhosts = map (hostOpts: hostOpts // {
+ certName = if hostOpts.useACMEHost != null then hostOpts.useACMEHost else hostOpts.hostName;
+ }) (filter (hostOpts: hostOpts.enableACME || hostOpts.useACMEHost != null) vhosts);
+
+ dependentCertNames = unique (map (hostOpts: hostOpts.certName) acmeEnabledVhosts);
+
mkListenInfo = hostOpts:
if hostOpts.listen != [] then hostOpts.listen
else (
@@ -119,13 +134,13 @@ let
useACME = hostOpts.enableACME || hostOpts.useACMEHost != null;
sslCertDir =
- if hostOpts.enableACME then config.security.acme.certs.${hostOpts.hostName}.directory
- else if hostOpts.useACMEHost != null then config.security.acme.certs.${hostOpts.useACMEHost}.directory
+ if hostOpts.enableACME then certs.${hostOpts.hostName}.directory
+ else if hostOpts.useACMEHost != null then certs.${hostOpts.useACMEHost}.directory
else abort "This case should never happen.";
- sslServerCert = if useACME then "${sslCertDir}/full.pem" else hostOpts.sslServerCert;
+ sslServerCert = if useACME then "${sslCertDir}/fullchain.pem" else hostOpts.sslServerCert;
sslServerKey = if useACME then "${sslCertDir}/key.pem" else hostOpts.sslServerKey;
- sslServerChain = if useACME then "${sslCertDir}/fullchain.pem" else hostOpts.sslServerChain;
+ sslServerChain = if useACME then "${sslCertDir}/chain.pem" else hostOpts.sslServerChain;
acmeChallenge = optionalString useACME ''
Alias /.well-known/acme-challenge/ "${hostOpts.acmeRoot}/.well-known/acme-challenge/"
@@ -341,7 +356,6 @@ let
cat ${php.phpIni} > $out
echo "$options" >> $out
'';
-
in
@@ -641,19 +655,41 @@ in
wwwrun.gid = config.ids.gids.wwwrun;
};
- security.acme.certs = mapAttrs (name: hostOpts: {
- user = cfg.user;
- group = mkDefault cfg.group;
- email = if hostOpts.adminAddr != null then hostOpts.adminAddr else cfg.adminAddr;
- webroot = hostOpts.acmeRoot;
- extraDomains = genAttrs hostOpts.serverAliases (alias: null);
- postRun = "systemctl reload httpd.service";
- }) (filterAttrs (name: hostOpts: hostOpts.enableACME) cfg.virtualHosts);
-
- environment.systemPackages = [ pkg ];
+ security.acme.certs = let
+ acmePairs = map (hostOpts: nameValuePair hostOpts.hostName {
+ group = mkDefault cfg.group;
+ webroot = hostOpts.acmeRoot;
+ extraDomainNames = hostOpts.serverAliases;
+ # Use the vhost-specific email address if provided, otherwise let
+ # security.acme.email or security.acme.certs.<cert>.email be used.
+ email = mkOverride 2000 (if hostOpts.adminAddr != null then hostOpts.adminAddr else cfg.adminAddr);
+ # Filter for enableACME-only vhosts. Don't want to create dud certs
+ }) (filter (hostOpts: hostOpts.useACMEHost == null) acmeEnabledVhosts);
+ in listToAttrs acmePairs;
+
+ environment.systemPackages = [
+ apachectl
+ pkg
+ ];
- # required for "apachectl configtest"
- environment.etc."httpd/httpd.conf".source = httpdConf;
+ services.logrotate = optionalAttrs (cfg.logFormat != "none") {
+ enable = mkDefault true;
+ paths.httpd = {
+ path = "${cfg.logDir}/*.log";
+ user = cfg.user;
+ group = cfg.group;
+ frequency = "daily";
+ keep = 28;
+ extraConfig = ''
+ sharedscripts
+ compress
+ delaycompress
+ postrotate
+ systemctl reload httpd.service > /dev/null 2>/dev/null || true
+ endscript
+ '';
+ };
+ };
services.httpd.phpOptions =
''
@@ -699,16 +735,12 @@ in
"Z '${cfg.logDir}' - ${svc.User} ${svc.Group}"
];
- systemd.services.httpd =
- let
- vhostsACME = filter (hostOpts: hostOpts.enableACME) vhosts;
- in
- { description = "Apache HTTPD";
-
+ systemd.services.httpd = {
+ description = "Apache HTTPD";
wantedBy = [ "multi-user.target" ];
- wants = concatLists (map (hostOpts: [ "acme-${hostOpts.hostName}.service" "acme-selfsigned-${hostOpts.hostName}.service" ]) vhostsACME);
- after = [ "network.target" "fs.target" ] ++ map (hostOpts: "acme-selfsigned-${hostOpts.hostName}.service") vhostsACME;
- before = map (hostOpts: "acme-${hostOpts.hostName}.service") vhostsACME;
+ wants = concatLists (map (certName: [ "acme-finished-${certName}.target" ]) dependentCertNames);
+ after = [ "network.target" ] ++ map (certName: "acme-selfsigned-${certName}.service") dependentCertNames;
+ before = map (certName: "acme-${certName}.service") dependentCertNames;
path = [ pkg pkgs.coreutils pkgs.gnugrep ];
@@ -742,5 +774,31 @@ in
};
};
+ # postRun hooks on cert renew can't be used to restart Apache since renewal
+ # runs as the unprivileged acme user. sslTargets are added to wantedBy + before
+ # which allows the acme-finished-$cert.target to signify the successful updating
+ # of certs end-to-end.
+ systemd.services.httpd-config-reload = let
+ sslServices = map (certName: "acme-${certName}.service") dependentCertNames;
+ sslTargets = map (certName: "acme-finished-${certName}.target") dependentCertNames;
+ in mkIf (sslServices != []) {
+ wantedBy = sslServices ++ [ "multi-user.target" ];
+ # Before the finished targets, after the renew services.
+ # This service might be needed for HTTP-01 challenges, but we only want to confirm
+ # certs are updated _after_ config has been reloaded.
+ before = sslTargets;
+ after = sslServices;
+ # Block reloading if not all certs exist yet.
+ # Happens when config changes add new vhosts/certs.
+ unitConfig.ConditionPathExists = map (certName: certs.${certName}.directory + "/fullchain.pem") dependentCertNames;
+ serviceConfig = {
+ Type = "oneshot";
+ TimeoutSec = 60;
+ ExecCondition = "/run/current-system/systemd/bin/systemctl -q is-active httpd.service";
+ ExecStartPre = "${pkg}/bin/httpd -f ${httpdConf} -t";
+ ExecStart = "/run/current-system/systemd/bin/systemctl reload httpd.service";
+ };
+ };
+
};
}
diff --git a/nixpkgs/nixos/modules/services/web-servers/caddy.nix b/nixpkgs/nixos/modules/services/web-servers/caddy.nix
index 0e6e10a5f47..dda26fe491a 100644
--- a/nixpkgs/nixos/modules/services/web-servers/caddy.nix
+++ b/nixpkgs/nixos/modules/services/web-servers/caddy.nix
@@ -5,6 +5,26 @@ with lib;
let
cfg = config.services.caddy;
configFile = pkgs.writeText "Caddyfile" cfg.config;
+
+ # v2-specific options
+ isCaddy2 = versionAtLeast cfg.package.version "2.0";
+ tlsConfig = {
+ apps.tls.automation.policies = [{
+ issuer = {
+ inherit (cfg) ca email;
+ module = "acme";
+ };
+ }];
+ };
+
+ adaptedConfig = pkgs.runCommand "caddy-config-adapted.json" { } ''
+ ${cfg.package}/bin/caddy adapt \
+ --config ${configFile} --adapter ${cfg.adapter} > $out
+ '';
+ tlsJSON = pkgs.writeText "tls.json" (builtins.toJSON tlsConfig);
+ configJSON = pkgs.runCommand "caddy-config.json" { } ''
+ ${pkgs.jq}/bin/jq -s '.[0] * .[1]' ${adaptedConfig} ${tlsJSON} > $out
+ '';
in {
options.services.caddy = {
enable = mkEnableOption "Caddy web server";
@@ -13,15 +33,26 @@ in {
default = "";
example = ''
example.com {
- gzip
- minify
- log syslog
-
- root /srv/http
+ encode gzip
+ log
+ root /srv/http
}
'';
type = types.lines;
- description = "Verbatim Caddyfile to use";
+ description = ''
+ Verbatim Caddyfile to use.
+ Caddy v2 supports multiple config formats via adapters (see <option>services.caddy.adapter</option>).
+ '';
+ };
+
+ adapter = mkOption {
+ default = "caddyfile";
+ example = "nginx";
+ type = types.str;
+ description = ''
+ Name of the config adapter to use. Not applicable to Caddy v1.
+ See https://caddyserver.com/docs/config-adapters for the full list.
+ '';
};
ca = mkOption {
@@ -50,33 +81,46 @@ in {
The data directory, for storing certificates. Before 17.09, this
would create a .caddy directory. With 17.09 the contents of the
.caddy directory are in the specified data directory instead.
+
+ Caddy v2 replaced CADDYPATH with XDG directories.
+ See https://caddyserver.com/docs/conventions#file-locations.
'';
};
package = mkOption {
default = pkgs.caddy;
defaultText = "pkgs.caddy";
+ example = "pkgs.caddy1";
type = types.package;
- description = "Caddy package to use.";
+ description = ''
+ Caddy package to use.
+ To use Caddy v1 (obsolete), set this to <literal>pkgs.caddy1</literal>.
+ '';
};
};
config = mkIf cfg.enable {
systemd.services.caddy = {
description = "Caddy web server";
- # upstream unit: https://github.com/caddyserver/caddy/blob/master/dist/init/linux-systemd/caddy.service
+ # upstream unit: https://github.com/caddyserver/dist/blob/master/init/caddy.service
after = [ "network-online.target" ];
wants = [ "network-online.target" ]; # systemd-networkd-wait-online.service
wantedBy = [ "multi-user.target" ];
- environment = mkIf (versionAtLeast config.system.stateVersion "17.09")
+ environment = mkIf (versionAtLeast config.system.stateVersion "17.09" && !isCaddy2)
{ CADDYPATH = cfg.dataDir; };
serviceConfig = {
- ExecStart = ''
+ ExecStart = if isCaddy2 then ''
+ ${cfg.package}/bin/caddy run --config ${configJSON}
+ '' else ''
${cfg.package}/bin/caddy -log stdout -log-timestamps=false \
-root=/var/tmp -conf=${configFile} \
-ca=${cfg.ca} -email=${cfg.email} ${optionalString cfg.agree "-agree"}
'';
- ExecReload = "${pkgs.coreutils}/bin/kill -USR1 $MAINPID";
+ ExecReload =
+ if isCaddy2 then
+ "${cfg.package}/bin/caddy reload --config ${configJSON}"
+ else
+ "${pkgs.coreutils}/bin/kill -USR1 $MAINPID";
Type = "simple";
User = "caddy";
Group = "caddy";
diff --git a/nixpkgs/nixos/modules/services/web-servers/jboss/builder.sh b/nixpkgs/nixos/modules/services/web-servers/jboss/builder.sh
index 2eb89a90f67..0e5af324c13 100644
--- a/nixpkgs/nixos/modules/services/web-servers/jboss/builder.sh
+++ b/nixpkgs/nixos/modules/services/web-servers/jboss/builder.sh
@@ -28,11 +28,11 @@ stop()
if test "\$1" = start
then
trap stop 15
-
+
start
elif test "\$1" = stop
then
- stop
+ stop
elif test "\$1" = init
then
echo "Are you sure you want to create a new server instance (old server instance will be lost!)?"
@@ -42,21 +42,21 @@ then
then
exit 1
fi
-
+
rm -rf $serverDir
mkdir -p $serverDir
cd $serverDir
cp -av $jboss/server/default .
sed -i -e "s|deploy/|$deployDir|" default/conf/jboss-service.xml
-
+
if ! test "$useJK" = ""
then
sed -i -e 's|<attribute name="UseJK">false</attribute>|<attribute name="UseJK">true</attribute>|' default/deploy/jboss-web.deployer/META-INF/jboss-service.xml
sed -i -e 's|<Engine name="jboss.web" defaultHost="localhost">|<Engine name="jboss.web" defaultHost="localhost" jvmRoute="node1">|' default/deploy/jboss-web.deployer/server.xml
fi
-
+
# Make files accessible for the server user
-
+
chown -R $user $serverDir
for i in \`find $serverDir -type d\`
do
diff --git a/nixpkgs/nixos/modules/services/web-servers/meguca.nix b/nixpkgs/nixos/modules/services/web-servers/meguca.nix
deleted file mode 100644
index 5a00070dc94..00000000000
--- a/nixpkgs/nixos/modules/services/web-servers/meguca.nix
+++ /dev/null
@@ -1,174 +0,0 @@
-{ config, lib, pkgs, ... }:
-
-let
- cfg = config.services.meguca;
- postgres = config.services.postgresql;
-in with lib; {
- options.services.meguca = {
- enable = mkEnableOption "meguca";
-
- dataDir = mkOption {
- type = types.path;
- default = "/var/lib/meguca";
- example = "/home/okina/meguca";
- description = "Location where meguca stores it's database and links.";
- };
-
- password = mkOption {
- type = types.str;
- default = "meguca";
- example = "dumbpass";
- description = "Password for the meguca database.";
- };
-
- passwordFile = mkOption {
- type = types.path;
- default = "/run/keys/meguca-password-file";
- example = "/home/okina/meguca/keys/pass";
- description = "Password file for the meguca database.";
- };
-
- reverseProxy = mkOption {
- type = types.nullOr types.str;
- default = null;
- example = "192.168.1.5";
- description = "Reverse proxy IP.";
- };
-
- sslCertificate = mkOption {
- type = types.nullOr types.str;
- default = null;
- example = "/home/okina/meguca/ssl.cert";
- description = "Path to the SSL certificate.";
- };
-
- listenAddress = mkOption {
- type = types.nullOr types.str;
- default = null;
- example = "127.0.0.1:8000";
- description = "Listen on a specific IP address and port.";
- };
-
- cacheSize = mkOption {
- type = types.nullOr types.int;
- default = null;
- example = 256;
- description = "Cache size in MB.";
- };
-
- postgresArgs = mkOption {
- type = types.str;
- example = "user=meguca password=dumbpass dbname=meguca sslmode=disable";
- description = "Postgresql connection arguments.";
- };
-
- postgresArgsFile = mkOption {
- type = types.path;
- default = "/run/keys/meguca-postgres-args";
- example = "/home/okina/meguca/keys/postgres";
- description = "Postgresql connection arguments file.";
- };
-
- compressTraffic = mkOption {
- type = types.bool;
- default = false;
- description = "Compress all traffic with gzip.";
- };
-
- assumeReverseProxy = mkOption {
- type = types.bool;
- default = false;
- description = "Assume the server is behind a reverse proxy, when resolving client IPs.";
- };
-
- httpsOnly = mkOption {
- type = types.bool;
- default = false;
- description = "Serve and listen only through HTTPS.";
- };
-
- videoPaths = mkOption {
- type = types.listOf types.path;
- default = [];
- example = [ "/home/okina/Videos/tehe_pero.webm" ];
- description = "Videos that will be symlinked into www/videos.";
- };
- };
-
- config = mkIf cfg.enable {
- security.sudo.enable = cfg.enable;
- services.postgresql.enable = cfg.enable;
- services.postgresql.package = pkgs.postgresql_11;
- services.meguca.passwordFile = mkDefault (pkgs.writeText "meguca-password-file" cfg.password);
- services.meguca.postgresArgsFile = mkDefault (pkgs.writeText "meguca-postgres-args" cfg.postgresArgs);
- services.meguca.postgresArgs = mkDefault "user=meguca password=${cfg.password} dbname=meguca sslmode=disable";
-
- systemd.services.meguca = {
- description = "meguca";
- after = [ "network.target" "postgresql.service" ];
- wantedBy = [ "multi-user.target" ];
-
- preStart = ''
- # Ensure folder exists or create it and links and permissions are correct
- mkdir -p ${escapeShellArg cfg.dataDir}/www
- rm -rf ${escapeShellArg cfg.dataDir}/www/videos
- ln -sf ${pkgs.meguca}/share/meguca/www/* ${escapeShellArg cfg.dataDir}/www
- unlink ${escapeShellArg cfg.dataDir}/www/videos
- mkdir -p ${escapeShellArg cfg.dataDir}/www/videos
-
- for vid in ${escapeShellArg cfg.videoPaths}; do
- ln -sf $vid ${escapeShellArg cfg.dataDir}/www/videos
- done
-
- chmod 750 ${escapeShellArg cfg.dataDir}
- chown -R meguca:meguca ${escapeShellArg cfg.dataDir}
-
- # Ensure the database is correct or create it
- ${pkgs.sudo}/bin/sudo -u ${postgres.superUser} ${postgres.package}/bin/createuser \
- -SDR meguca || true
- ${pkgs.sudo}/bin/sudo -u ${postgres.superUser} ${postgres.package}/bin/createdb \
- -T template0 -E UTF8 -O meguca meguca || true
- ${pkgs.sudo}/bin/sudo -u meguca ${postgres.package}/bin/psql \
- -c "ALTER ROLE meguca WITH PASSWORD '$(cat ${escapeShellArg cfg.passwordFile})';" || true
- '';
-
- script = ''
- cd ${escapeShellArg cfg.dataDir}
-
- ${pkgs.meguca}/bin/meguca -d "$(cat ${escapeShellArg cfg.postgresArgsFile})"''
- + optionalString (cfg.reverseProxy != null) " -R ${cfg.reverseProxy}"
- + optionalString (cfg.sslCertificate != null) " -S ${cfg.sslCertificate}"
- + optionalString (cfg.listenAddress != null) " -a ${cfg.listenAddress}"
- + optionalString (cfg.cacheSize != null) " -c ${toString cfg.cacheSize}"
- + optionalString (cfg.compressTraffic) " -g"
- + optionalString (cfg.assumeReverseProxy) " -r"
- + optionalString (cfg.httpsOnly) " -s" + " start";
-
- serviceConfig = {
- PermissionsStartOnly = true;
- Type = "forking";
- User = "meguca";
- Group = "meguca";
- ExecStop = "${pkgs.meguca}/bin/meguca stop";
- };
- };
-
- users = {
- groups.meguca.gid = config.ids.gids.meguca;
-
- users.meguca = {
- description = "meguca server service user";
- home = cfg.dataDir;
- createHome = true;
- group = "meguca";
- uid = config.ids.uids.meguca;
- };
- };
- };
-
- imports = [
- (mkRenamedOptionModule [ "services" "meguca" "baseDir" ] [ "services" "meguca" "dataDir" ])
- ];
-
- meta.maintainers = with maintainers; [ chiiruno ];
-}
diff --git a/nixpkgs/nixos/modules/services/web-servers/nginx/default.nix b/nixpkgs/nixos/modules/services/web-servers/nginx/default.nix
index 4c4b7f39e6b..39bcb14e5af 100644
--- a/nixpkgs/nixos/modules/services/web-servers/nginx/default.nix
+++ b/nixpkgs/nixos/modules/services/web-servers/nginx/default.nix
@@ -6,23 +6,23 @@ let
cfg = config.services.nginx;
certs = config.security.acme.certs;
vhostsConfigs = mapAttrsToList (vhostName: vhostConfig: vhostConfig) virtualHosts;
- acmeEnabledVhosts = filter (vhostConfig: vhostConfig.enableACME && vhostConfig.useACMEHost == null) vhostsConfigs;
+ acmeEnabledVhosts = filter (vhostConfig: vhostConfig.enableACME || vhostConfig.useACMEHost != null) vhostsConfigs;
+ dependentCertNames = unique (map (hostOpts: hostOpts.certName) acmeEnabledVhosts);
virtualHosts = mapAttrs (vhostName: vhostConfig:
let
serverName = if vhostConfig.serverName != null
then vhostConfig.serverName
else vhostName;
+ certName = if vhostConfig.useACMEHost != null
+ then vhostConfig.useACMEHost
+ else serverName;
in
vhostConfig // {
- inherit serverName;
- } // (optionalAttrs vhostConfig.enableACME {
- sslCertificate = "${certs.${serverName}.directory}/fullchain.pem";
- sslCertificateKey = "${certs.${serverName}.directory}/key.pem";
- sslTrustedCertificate = "${certs.${serverName}.directory}/full.pem";
- }) // (optionalAttrs (vhostConfig.useACMEHost != null) {
- sslCertificate = "${certs.${vhostConfig.useACMEHost}.directory}/fullchain.pem";
- sslCertificateKey = "${certs.${vhostConfig.useACMEHost}.directory}/key.pem";
- sslTrustedCertificate = "${certs.${vhostConfig.useACMEHost}.directory}/fullchain.pem";
+ inherit serverName certName;
+ } // (optionalAttrs (vhostConfig.enableACME || vhostConfig.useACMEHost != null) {
+ sslCertificate = "${certs.${certName}.directory}/fullchain.pem";
+ sslCertificateKey = "${certs.${certName}.directory}/key.pem";
+ sslTrustedCertificate = "${certs.${certName}.directory}/chain.pem";
})
) cfg.virtualHosts;
enableIPv6 = config.networking.enableIPv6;
@@ -463,14 +463,6 @@ in
'';
};
- enableSandbox = mkOption {
- default = false;
- type = types.bool;
- description = ''
- Starting Nginx web server with additional sandbox/hardening options.
- '';
- };
-
user = mkOption {
type = types.str;
default = "nginx";
@@ -691,12 +683,12 @@ in
systemd.services.nginx = {
description = "Nginx Web Server";
wantedBy = [ "multi-user.target" ];
- wants = concatLists (map (vhostConfig: ["acme-${vhostConfig.serverName}.service" "acme-selfsigned-${vhostConfig.serverName}.service"]) acmeEnabledVhosts);
- after = [ "network.target" ] ++ map (vhostConfig: "acme-selfsigned-${vhostConfig.serverName}.service") acmeEnabledVhosts;
+ wants = concatLists (map (certName: [ "acme-finished-${certName}.target" ]) dependentCertNames);
+ after = [ "network.target" ] ++ map (certName: "acme-selfsigned-${certName}.service") dependentCertNames;
# Nginx needs to be started in order to be able to request certificates
# (it's hosting the acme challenge after all)
# This fixes https://github.com/NixOS/nixpkgs/issues/81842
- before = map (vhostConfig: "acme-${vhostConfig.serverName}.service") acmeEnabledVhosts;
+ before = map (certName: "acme-${certName}.service") dependentCertNames;
stopIfChanged = false;
preStart = ''
${cfg.preStart}
@@ -704,7 +696,10 @@ in
'';
serviceConfig = {
ExecStart = execCommand;
- ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
+ ExecReload = [
+ "${execCommand} -t"
+ "${pkgs.coreutils}/bin/kill -HUP $MAINPID"
+ ];
Restart = "always";
RestartSec = "10s";
StartLimitInterval = "1min";
@@ -725,7 +720,6 @@ in
CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" "CAP_SYS_RESOURCE" ];
# Security
NoNewPrivileges = true;
- } // optionalAttrs cfg.enableSandbox {
# Sandboxing
ProtectSystem = "strict";
ProtectHome = mkDefault true;
@@ -750,38 +744,41 @@ in
source = configFile;
};
- systemd.services.nginx-config-reload = mkIf cfg.enableReload {
- wants = [ "nginx.service" ];
- wantedBy = [ "multi-user.target" ];
- restartTriggers = [ configFile ];
- # commented, because can cause extra delays during activate for this config:
- # services.nginx.virtualHosts."_".locations."/".proxyPass = "http://blabla:3000";
- # stopIfChanged = false;
- serviceConfig.Type = "oneshot";
- serviceConfig.TimeoutSec = 60;
- script = ''
- if /run/current-system/systemd/bin/systemctl -q is-active nginx.service ; then
- ${execCommand} -t && \
- /run/current-system/systemd/bin/systemctl reload nginx.service
- fi
- '';
- serviceConfig.RemainAfterExit = true;
+ # postRun hooks on cert renew can't be used to restart Nginx since renewal
+ # runs as the unprivileged acme user. sslTargets are added to wantedBy + before
+ # which allows the acme-finished-$cert.target to signify the successful updating
+ # of certs end-to-end.
+ systemd.services.nginx-config-reload = let
+ sslServices = map (certName: "acme-${certName}.service") dependentCertNames;
+ sslTargets = map (certName: "acme-finished-${certName}.target") dependentCertNames;
+ in mkIf (cfg.enableReload || sslServices != []) {
+ wants = optionals (cfg.enableReload) [ "nginx.service" ];
+ wantedBy = sslServices ++ [ "multi-user.target" ];
+ # Before the finished targets, after the renew services.
+ # This service might be needed for HTTP-01 challenges, but we only want to confirm
+ # certs are updated _after_ config has been reloaded.
+ before = sslTargets;
+ after = sslServices;
+ restartTriggers = optionals (cfg.enableReload) [ configFile ];
+ # Block reloading if not all certs exist yet.
+ # Happens when config changes add new vhosts/certs.
+ unitConfig.ConditionPathExists = optionals (sslServices != []) (map (certName: certs.${certName}.directory + "/fullchain.pem") dependentCertNames);
+ serviceConfig = {
+ Type = "oneshot";
+ TimeoutSec = 60;
+ ExecCondition = "/run/current-system/systemd/bin/systemctl -q is-active nginx.service";
+ ExecStart = "/run/current-system/systemd/bin/systemctl reload nginx.service";
+ };
};
- security.acme.certs = filterAttrs (n: v: v != {}) (
- let
- acmePairs = map (vhostConfig: { name = vhostConfig.serverName; value = {
- user = cfg.user;
- group = lib.mkDefault cfg.group;
- webroot = vhostConfig.acmeRoot;
- extraDomains = genAttrs vhostConfig.serverAliases (alias: null);
- postRun = ''
- /run/current-system/systemd/bin/systemctl reload nginx
- '';
- }; }) acmeEnabledVhosts;
- in
- listToAttrs acmePairs
- );
+ security.acme.certs = let
+ acmePairs = map (vhostConfig: nameValuePair vhostConfig.serverName {
+ group = mkDefault cfg.group;
+ webroot = vhostConfig.acmeRoot;
+ extraDomainNames = vhostConfig.serverAliases;
+ # Filter for enableACME-only vhosts. Don't want to create dud certs
+ }) (filter (vhostConfig: vhostConfig.useACMEHost == null) acmeEnabledVhosts);
+ in listToAttrs acmePairs;
users.users = optionalAttrs (cfg.user == "nginx") {
nginx = {
diff --git a/nixpkgs/nixos/modules/services/web-servers/phpfpm/default.nix b/nixpkgs/nixos/modules/services/web-servers/phpfpm/default.nix
index d090885a8ca..759eebf768d 100644
--- a/nixpkgs/nixos/modules/services/web-servers/phpfpm/default.nix
+++ b/nixpkgs/nixos/modules/services/web-servers/phpfpm/default.nix
@@ -277,6 +277,7 @@ in {
ExecReload = "${pkgs.coreutils}/bin/kill -USR2 $MAINPID";
RuntimeDirectory = "phpfpm";
RuntimeDirectoryPreserve = true; # Relevant when multiple processes are running
+ Restart = "always";
};
}
) cfg.pools;
diff --git a/nixpkgs/nixos/modules/services/web-servers/shellinabox.nix b/nixpkgs/nixos/modules/services/web-servers/shellinabox.nix
index 58a02ac59c3..c7c51f873eb 100644
--- a/nixpkgs/nixos/modules/services/web-servers/shellinabox.nix
+++ b/nixpkgs/nixos/modules/services/web-servers/shellinabox.nix
@@ -51,7 +51,7 @@ in
Whether or not to enable SSL (https) support.
'';
};
-
+
certDirectory = mkOption {
type = types.nullOr types.path;
default = null;
diff --git a/nixpkgs/nixos/modules/services/web-servers/unit/default.nix b/nixpkgs/nixos/modules/services/web-servers/unit/default.nix
index 65dcdbed000..894271d1e55 100644
--- a/nixpkgs/nixos/modules/services/web-servers/unit/default.nix
+++ b/nixpkgs/nixos/modules/services/web-servers/unit/default.nix
@@ -120,9 +120,12 @@ in {
ProtectHome = true;
PrivateTmp = true;
PrivateDevices = true;
+ PrivateUsers = false;
ProtectHostname = true;
+ ProtectClock = true;
ProtectKernelTunables = true;
ProtectKernelModules = true;
+ ProtectKernelLogs = true;
ProtectControlGroups = true;
RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ];
LockPersonality = true;
diff --git a/nixpkgs/nixos/modules/services/x11/desktop-managers/cinnamon.nix b/nixpkgs/nixos/modules/services/x11/desktop-managers/cinnamon.nix
new file mode 100644
index 00000000000..a404143a03d
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/cinnamon.nix
@@ -0,0 +1,205 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+ cfg = config.services.xserver.desktopManager.cinnamon;
+ serviceCfg = config.services.cinnamon;
+
+ nixos-gsettings-overrides = pkgs.cinnamon.cinnamon-gsettings-overrides.override {
+ extraGSettingsOverridePackages = cfg.extraGSettingsOverridePackages;
+ extraGSettingsOverrides = cfg.extraGSettingsOverrides;
+ };
+
+in
+
+{
+ options = {
+ services.cinnamon = {
+ apps.enable = mkEnableOption "Cinnamon default applications";
+ };
+
+ services.xserver.desktopManager.cinnamon = {
+ enable = mkEnableOption "the cinnamon desktop manager";
+
+ sessionPath = mkOption {
+ default = [];
+ example = literalExample "[ pkgs.gnome3.gpaste ]";
+ description = ''
+ Additional list of packages to be added to the session search path.
+ Useful for GSettings-conditional autostart.
+
+ Note that this should be a last resort; patching the package is preferred (see GPaste).
+ '';
+ };
+
+ extraGSettingsOverrides = mkOption {
+ default = "";
+ type = types.lines;
+ description = "Additional gsettings overrides.";
+ };
+
+ extraGSettingsOverridePackages = mkOption {
+ default = [];
+ type = types.listOf types.path;
+ description = "List of packages for which gsettings are overridden.";
+ };
+ };
+
+ environment.cinnamon.excludePackages = mkOption {
+ default = [];
+ example = literalExample "[ pkgs.cinnamon.blueberry ]";
+ type = types.listOf types.package;
+ description = "Which packages cinnamon should exclude from the default environment";
+ };
+
+ };
+
+ config = mkMerge [
+ (mkIf (cfg.enable && config.services.xserver.displayManager.lightdm.enable && config.services.xserver.displayManager.lightdm.greeters.gtk.enable) {
+ services.xserver.displayManager.lightdm.greeters.gtk.extraConfig = mkDefault (builtins.readFile "${pkgs.cinnamon.mint-artwork}/etc/lightdm/lightdm-gtk-greeter.conf.d/99_linuxmint.conf");
+ })
+
+ (mkIf cfg.enable {
+ services.xserver.displayManager.sessionPackages = [ pkgs.cinnamon.cinnamon-common ];
+
+ services.xserver.displayManager.sessionCommands = ''
+ if test "$XDG_CURRENT_DESKTOP" = "Cinnamon"; then
+ true
+ ${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 [ -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}
+ fi
+ '';
+
+ # Default services
+ hardware.bluetooth.enable = mkDefault true;
+ hardware.pulseaudio.enable = mkDefault true;
+ security.polkit.enable = true;
+ services.accounts-daemon.enable = true;
+ services.system-config-printer.enable = (mkIf config.services.printing.enable (mkDefault true));
+ services.dbus.packages = with pkgs.cinnamon; [
+ cinnamon-common
+ cinnamon-screensaver
+ nemo
+ xapps
+ ];
+ services.cinnamon.apps.enable = mkDefault true;
+ services.gnome3.glib-networking.enable = true;
+ services.gnome3.gnome-keyring.enable = true;
+ services.gvfs.enable = true;
+ services.udisks2.enable = true;
+ services.upower.enable = mkDefault config.powerManagement.enable;
+ services.xserver.libinput.enable = mkDefault true;
+ services.xserver.updateDbusEnvironment = true;
+ networking.networkmanager.enable = mkDefault true;
+
+ # Enable colord server
+ services.colord.enable = true;
+
+ # Enable dconf
+ programs.dconf.enable = true;
+
+ # Enable org.a11y.Bus
+ services.gnome3.at-spi2-core.enable = true;
+
+ # Fix lockscreen
+ security.pam.services = {
+ cinnamon-screensaver = {};
+ };
+
+ environment.systemPackages = with pkgs.cinnamon // pkgs; [
+ desktop-file-utils
+ nixos-artwork.wallpapers.simple-dark-gray
+ onboard
+ sound-theme-freedesktop
+
+ # common-files
+ cinnamon-common
+ cinnamon-session
+ cinnamon-desktop
+ cinnamon-menus
+
+ # utils needed by some scripts
+ killall
+
+ # session requirements
+ cinnamon-screensaver
+ # cinnamon-killer-daemon: provided by cinnamon-common
+ gnome3.networkmanagerapplet # session requirement - also nm-applet not needed
+
+ # packages
+ nemo
+ cinnamon-control-center
+ cinnamon-settings-daemon
+ gnome3.libgnomekbd
+ orca
+
+ # theme
+ gnome3.adwaita-icon-theme
+ hicolor-icon-theme
+ gnome3.gnome-themes-extra
+ gtk3.out
+ mint-artwork
+ mint-themes
+ mint-x-icons
+ mint-y-icons
+ vanilla-dmz
+
+ # other
+ glib # for gsettings
+ shared-mime-info # for update-mime-database
+ xdg-user-dirs
+ ];
+
+ # Override GSettings schemas
+ environment.sessionVariables.NIX_GSETTINGS_OVERRIDES_DIR = "${nixos-gsettings-overrides}/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas";
+
+ environment.pathsToLink = [
+ # FIXME: modules should link subdirs of `/share` rather than relying on this
+ "/share" # TODO: https://github.com/NixOS/nixpkgs/issues/47173
+ ];
+
+ # 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";
+
+ # Default Fonts
+ fonts.fonts = with pkgs; [
+ source-code-pro # Default monospace font in 3.32
+ ubuntu_font_family # required for default theme
+ ];
+ })
+
+ (mkIf serviceCfg.apps.enable {
+ programs.geary.enable = mkDefault true;
+ programs.gnome-disks.enable = mkDefault true;
+ programs.gnome-terminal.enable = mkDefault true;
+ programs.evince.enable = mkDefault true;
+ programs.file-roller.enable = mkDefault true;
+
+ environment.systemPackages = (with pkgs // pkgs.gnome3 // pkgs.cinnamon; pkgs.gnome3.removePackagesByName [
+ # cinnamon team apps
+ blueberry
+ warpinator
+
+ # external apps shipped with linux-mint
+ hexchat
+ gnome-calculator
+ ] config.environment.cinnamon.excludePackages);
+ })
+ ];
+}
diff --git a/nixpkgs/nixos/modules/services/x11/desktop-managers/default.nix b/nixpkgs/nixos/modules/services/x11/desktop-managers/default.nix
index 5d3a84d7139..f5559eb5354 100644
--- a/nixpkgs/nixos/modules/services/x11/desktop-managers/default.nix
+++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/default.nix
@@ -21,6 +21,7 @@ in
./none.nix ./xterm.nix ./xfce.nix ./plasma5.nix ./lumina.nix
./lxqt.nix ./enlightenment.nix ./gnome3.nix ./kodi.nix
./mate.nix ./pantheon.nix ./surf-display.nix ./cde.nix
+ ./cinnamon.nix
];
options = {
diff --git a/nixpkgs/nixos/modules/services/x11/desktop-managers/pantheon.nix b/nixpkgs/nixos/modules/services/x11/desktop-managers/pantheon.nix
index 6dabca6bf09..e67e216f90d 100644
--- a/nixpkgs/nixos/modules/services/x11/desktop-managers/pantheon.nix
+++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/pantheon.nix
@@ -240,6 +240,8 @@ in
# Otherwise you can't store NetworkManager Secrets with
# "Store the password only for this user"
programs.nm-applet.enable = true;
+ # Pantheon has its own network indicator
+ programs.nm-applet.indicator = false;
# Shell integration for VTE terminals
programs.bash.vteIntegration = mkDefault true;
diff --git a/nixpkgs/nixos/modules/services/x11/desktop-managers/plasma5.nix b/nixpkgs/nixos/modules/services/x11/desktop-managers/plasma5.nix
index 75bf55a2639..149f6cbb762 100644
--- a/nixpkgs/nixos/modules/services/x11/desktop-managers/plasma5.nix
+++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/plasma5.nix
@@ -7,7 +7,9 @@ let
xcfg = config.services.xserver;
cfg = xcfg.desktopManager.plasma5;
- inherit (pkgs) kdeApplications plasma5 libsForQt5 qt5;
+ inherit (pkgs) kdeApplications kdeFrameworks plasma5;
+ libsForQt5 = pkgs.libsForQt514;
+ qt5 = pkgs.qt514;
inherit (pkgs) writeText;
pulseaudio = config.hardware.pulseaudio;
@@ -83,7 +85,7 @@ let
# recognize that software that has been removed.
rm -fv $HOME/.cache/ksycoca*
- ${pkgs.libsForQt5.kservice}/bin/kbuildsycoca5
+ ${libsForQt5.kservice}/bin/kbuildsycoca5
'';
set_XDG_CONFIG_HOME = ''
@@ -203,7 +205,9 @@ in
KERNEL=="i2c-[0-9]*", TAG+="uaccess"
'';
- environment.systemPackages = with pkgs; with qt5; with libsForQt5; with plasma5; with kdeApplications;
+ environment.systemPackages =
+ with qt5; with libsForQt5;
+ with plasma5; with kdeApplications; with kdeFrameworks;
[
frameworkintegration
kactivities
@@ -293,7 +297,7 @@ in
qtvirtualkeyboard
- xdg-user-dirs # Update user dirs as described in https://freedesktop.org/wiki/Software/xdg-user-dirs/
+ pkgs.xdg-user-dirs # Update user dirs as described in https://freedesktop.org/wiki/Software/xdg-user-dirs/
]
# Phonon audio backend
@@ -301,13 +305,13 @@ in
++ lib.optional (cfg.phononBackend == "vlc") libsForQt5.phonon-backend-vlc
# Optional hardware support features
- ++ lib.optionals config.hardware.bluetooth.enable [ bluedevil bluez-qt openobex obexftp ]
+ ++ lib.optionals config.hardware.bluetooth.enable [ bluedevil bluez-qt pkgs.openobex pkgs.obexftp ]
++ lib.optional config.networking.networkmanager.enable plasma-nm
++ lib.optional config.hardware.pulseaudio.enable plasma-pa
++ lib.optional config.powerManagement.enable powerdevil
- ++ lib.optional config.services.colord.enable colord-kde
+ ++ lib.optional config.services.colord.enable pkgs.colord-kde
++ lib.optionals config.services.samba.enable [ kdenetwork-filesharing pkgs.samba ]
- ++ lib.optional config.services.xserver.wacom.enable wacomtablet;
+ ++ lib.optional config.services.xserver.wacom.enable pkgs.wacomtablet;
environment.pathsToLink = [
# FIXME: modules should link subdirs of `/share` rather than relying on this
diff --git a/nixpkgs/nixos/modules/services/x11/display-managers/default.nix b/nixpkgs/nixos/modules/services/x11/display-managers/default.nix
index e990a66d198..08ce8edd661 100644
--- a/nixpkgs/nixos/modules/services/x11/display-managers/default.nix
+++ b/nixpkgs/nixos/modules/services/x11/display-managers/default.nix
@@ -55,13 +55,6 @@ let
exec &> >(tee ~/.xsession-errors)
''}
- # Tell systemd about our $DISPLAY and $XAUTHORITY.
- # This is needed by the ssh-agent unit.
- #
- # Also tell systemd about the dbus session bus address.
- # This is required by user units using the session bus.
- /run/current-system/systemd/bin/systemctl --user import-environment DISPLAY XAUTHORITY DBUS_SESSION_BUS_ADDRESS
-
# Load X defaults. This should probably be safe on wayland too.
${xorg.xrdb}/bin/xrdb -merge ${xresourcesXft}
if test -e ~/.Xresources; then
@@ -70,6 +63,12 @@ let
${xorg.xrdb}/bin/xrdb -merge ~/.Xdefaults
fi
+ # Import environment variables into the systemd user environment.
+ ${optionalString (cfg.displayManager.importedVariables != []) (
+ "/run/current-system/systemd/bin/systemctl --user import-environment "
+ + toString (unique cfg.displayManager.importedVariables)
+ )}
+
# Speed up application start by 50-150ms according to
# http://kdemonkey.blogspot.nl/2008/04/magic-trick.html
rm -rf "$HOME/.compose-cache"
@@ -289,6 +288,14 @@ in
'';
};
+ importedVariables = mkOption {
+ type = types.listOf (types.strMatching "[a-zA-Z_][a-zA-Z0-9_]*");
+ visible = false;
+ description = ''
+ Environment variables to import into the systemd user environment.
+ '';
+ };
+
job = {
preStart = mkOption {
@@ -353,7 +360,7 @@ in
};
};
};
-
+
default = {};
description = ''
Auto login configuration attrset.
@@ -393,6 +400,16 @@ in
services.xserver.displayManager.xserverBin = "${xorg.xorgserver.out}/bin/X";
+ services.xserver.displayManager.importedVariables = [
+ # This is required by user units using the session bus.
+ "DBUS_SESSION_BUS_ADDRESS"
+ # These are needed by the ssh-agent unit.
+ "DISPLAY"
+ "XAUTHORITY"
+ # This is required to specify session within user units (e.g. loginctl lock-session).
+ "XDG_SESSION_ID"
+ ];
+
systemd.user.targets.graphical-session = {
unitConfig = {
RefuseManualStart = false;
diff --git a/nixpkgs/nixos/modules/services/x11/display-managers/gdm.nix b/nixpkgs/nixos/modules/services/x11/display-managers/gdm.nix
index 573049ab07a..eae70a57c78 100644
--- a/nixpkgs/nixos/modules/services/x11/display-managers/gdm.nix
+++ b/nixpkgs/nixos/modules/services/x11/display-managers/gdm.nix
@@ -64,13 +64,9 @@ in
services.xserver.displayManager.gdm = {
- enable = mkEnableOption ''
- GDM, the GNOME Display Manager
- '';
+ enable = mkEnableOption "GDM, the GNOME Display Manager";
- debug = mkEnableOption ''
- debugging messages in GDM
- '';
+ debug = mkEnableOption "debugging messages in GDM";
# Auto login options specific to GDM
autoLogin.delay = mkOption {
@@ -200,7 +196,6 @@ in
KillMode = "mixed";
IgnoreSIGPIPE = "no";
BusName = "org.gnome.DisplayManager";
- StandardOutput = "syslog";
StandardError = "inherit";
ExecReload = "${pkgs.coreutils}/bin/kill -SIGHUP $MAINPID";
KeyringMode = "shared";
diff --git a/nixpkgs/nixos/modules/services/x11/display-managers/lightdm.nix b/nixpkgs/nixos/modules/services/x11/display-managers/lightdm.nix
index 3bee21fa822..143785db0b4 100644
--- a/nixpkgs/nixos/modules/services/x11/display-managers/lightdm.nix
+++ b/nixpkgs/nixos/modules/services/x11/display-managers/lightdm.nix
@@ -253,7 +253,6 @@ in
KeyringMode = "shared";
KillMode = "mixed";
StandardError = "inherit";
- StandardOutput = "syslog";
};
environment.etc."lightdm/lightdm.conf".source = lightdmConf;
diff --git a/nixpkgs/nixos/modules/services/x11/imwheel.nix b/nixpkgs/nixos/modules/services/x11/imwheel.nix
index 3923df498e7..51f72dadbd4 100644
--- a/nixpkgs/nixos/modules/services/x11/imwheel.nix
+++ b/nixpkgs/nixos/modules/services/x11/imwheel.nix
@@ -61,7 +61,8 @@ in
"--kill"
] ++ cfg.extraOptions);
ExecStop = "${pkgs.procps}/bin/pkill imwheel";
- Restart = "on-failure";
+ RestartSec = 3;
+ Restart = "always";
};
};
};
diff --git a/nixpkgs/nixos/modules/services/x11/urserver.nix b/nixpkgs/nixos/modules/services/x11/urserver.nix
new file mode 100644
index 00000000000..0beb62eb766
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/x11/urserver.nix
@@ -0,0 +1,38 @@
+# urserver service
+{ config, lib, pkgs, ... }:
+
+let
+ cfg = config.services.urserver;
+in {
+
+ options.services.urserver.enable = lib.mkEnableOption "urserver";
+
+ config = lib.mkIf cfg.enable {
+
+ networking.firewall = {
+ allowedTCPPorts = [ 9510 9512 ];
+ allowedUDPPorts = [ 9511 9512 ];
+ };
+
+ systemd.user.services.urserver = {
+ description = ''
+ Server for Unified Remote: The one-and-only remote for your computer.
+ '';
+ wantedBy = [ "graphical-session.target" ];
+ partOf = [ "graphical-session.target" ];
+ after = [ "network.target" ];
+ serviceConfig = {
+ Type = "forking";
+ ExecStart = ''
+ ${pkgs.urserver}/bin/urserver --daemon
+ '';
+ ExecStop = ''
+ ${pkgs.procps}/bin/pkill urserver
+ '';
+ RestartSec = 3;
+ Restart = "on-failure";
+ };
+ };
+ };
+
+}
diff --git a/nixpkgs/nixos/modules/services/x11/window-managers/qtile.nix b/nixpkgs/nixos/modules/services/x11/window-managers/qtile.nix
index ad3b65150b0..cadc316bbc4 100644
--- a/nixpkgs/nixos/modules/services/x11/window-managers/qtile.nix
+++ b/nixpkgs/nixos/modules/services/x11/window-managers/qtile.nix
@@ -19,7 +19,7 @@ in
waitPID=$!
'';
}];
-
+
environment.systemPackages = [ pkgs.qtile ];
};
}
diff --git a/nixpkgs/nixos/modules/services/x11/window-managers/xmonad.nix b/nixpkgs/nixos/modules/services/x11/window-managers/xmonad.nix
index 30c59b88f82..dba25da8260 100644
--- a/nixpkgs/nixos/modules/services/x11/window-managers/xmonad.nix
+++ b/nixpkgs/nixos/modules/services/x11/window-managers/xmonad.nix
@@ -16,6 +16,7 @@ let
cfg.extraPackages cfg.haskellPackages ++
optionals cfg.enableContribAndExtras
(with cfg.haskellPackages; [ xmonad-contrib xmonad-extras ]);
+ inherit (cfg) ghcArgs;
} cfg.config;
in
@@ -76,18 +77,35 @@ in
}
'';
};
+
+ xmonadCliArgs = mkOption {
+ default = [];
+ type = with lib.types; listOf str;
+ description = ''
+ Command line arguments passed to the xmonad binary.
+ '';
+ };
+
+ ghcArgs = mkOption {
+ default = [];
+ type = with lib.types; listOf str;
+ description = ''
+ Command line arguments passed to the compiler (ghc)
+ invocation when xmonad.config is set.
+ '';
+ };
+
};
};
config = mkIf cfg.enable {
services.xserver.windowManager = {
session = [{
name = "xmonad";
- start = if (cfg.config != null) then ''
- ${xmonadBin}
- waitPID=$!
- '' else ''
- systemd-cat -t xmonad ${xmonad}/bin/xmonad &
- waitPID=$!
+ start = let
+ xmonadCommand = if (cfg.config != null) then xmonadBin else "${xmonad}/bin/xmonad";
+ in ''
+ systemd-cat -t xmonad -- ${xmonadCommand} ${lib.escapeShellArgs cfg.xmonadCliArgs} &
+ waitPID=$!
'';
}];
};
diff --git a/nixpkgs/nixos/modules/system/boot/emergency-mode.nix b/nixpkgs/nixos/modules/system/boot/emergency-mode.nix
index 9cdab841619..ec697bcee26 100644
--- a/nixpkgs/nixos/modules/system/boot/emergency-mode.nix
+++ b/nixpkgs/nixos/modules/system/boot/emergency-mode.nix
@@ -34,4 +34,4 @@ with lib;
};
-} \ No newline at end of file
+}
diff --git a/nixpkgs/nixos/modules/system/boot/initrd-openvpn.nix b/nixpkgs/nixos/modules/system/boot/initrd-openvpn.nix
index 7553c2aebb1..e59bc7b6678 100644
--- a/nixpkgs/nixos/modules/system/boot/initrd-openvpn.nix
+++ b/nixpkgs/nixos/modules/system/boot/initrd-openvpn.nix
@@ -5,7 +5,7 @@ with lib;
let
cfg = config.boot.initrd.network.openvpn;
-
+
in
{
@@ -16,17 +16,17 @@ in
type = types.bool;
default = false;
description = ''
- Starts an OpenVPN client during initrd boot. It can be used to e.g.
- remotely accessing the SSH service controlled by
- <option>boot.initrd.network.ssh</option> or other network services
+ Starts an OpenVPN client during initrd boot. It can be used to e.g.
+ remotely accessing the SSH service controlled by
+ <option>boot.initrd.network.ssh</option> or other network services
included. Service is killed when stage-1 boot is finished.
'';
};
-
+
boot.initrd.network.openvpn.configuration = mkOption {
type = types.path; # Same type as boot.initrd.secrets
description = ''
- The configuration file for OpenVPN.
+ The configuration file for OpenVPN.
<warning>
<para>
@@ -47,7 +47,7 @@ in
message = "You should specify a configuration for initrd OpenVPN";
}
];
-
+
# Add kernel modules needed for OpenVPN
boot.initrd.kernelModules = [ "tun" "tap" ];
@@ -60,11 +60,11 @@ in
cp -pv ${pkgs.glibc}/lib/libresolv.so.2 $out/lib
cp -pv ${pkgs.glibc}/lib/libnss_dns.so.2 $out/lib
'';
-
+
boot.initrd.secrets = {
"/etc/initrd.ovpn" = cfg.configuration;
};
-
+
# openvpn --version would exit with 1 instead of 0
boot.initrd.extraUtilsCommandsTest = ''
$out/bin/openvpn --show-gateway
diff --git a/nixpkgs/nixos/modules/system/boot/loader/generations-dir/generations-dir-builder.sh b/nixpkgs/nixos/modules/system/boot/loader/generations-dir/generations-dir-builder.sh
index e723b9eb7cb..8ae23dc988c 100644
--- a/nixpkgs/nixos/modules/system/boot/loader/generations-dir/generations-dir-builder.sh
+++ b/nixpkgs/nixos/modules/system/boot/loader/generations-dir/generations-dir-builder.sh
@@ -63,7 +63,7 @@ addEntry() {
copyToKernelsDir $kernel; kernel=$result
copyToKernelsDir $initrd; initrd=$result
fi
-
+
mkdir -p $outdir
ln -sf $(readlink -f $path) $outdir/system
ln -sf $(readlink -f $path/init) $outdir/init
diff --git a/nixpkgs/nixos/modules/system/boot/loader/init-script/init-script-builder.sh b/nixpkgs/nixos/modules/system/boot/loader/init-script/init-script-builder.sh
index 6f48d2539ac..2a1ec479fea 100644
--- a/nixpkgs/nixos/modules/system/boot/loader/init-script/init-script-builder.sh
+++ b/nixpkgs/nixos/modules/system/boot/loader/init-script/init-script-builder.sh
@@ -53,7 +53,7 @@ addEntry() {
echo "exec $stage2"
)"
- [ "$path" != "$defaultConfig" ] || {
+ [ "$path" != "$defaultConfig" ] || {
echo "$content" > $tmp
echo "# older configurations: $targetOther" >> $tmp
chmod +x $tmp
diff --git a/nixpkgs/nixos/modules/system/boot/loader/raspberrypi/raspberrypi-builder.nix b/nixpkgs/nixos/modules/system/boot/loader/raspberrypi/raspberrypi-builder.nix
index e75aa9d1387..7eb52e3d021 100644
--- a/nixpkgs/nixos/modules/system/boot/loader/raspberrypi/raspberrypi-builder.nix
+++ b/nixpkgs/nixos/modules/system/boot/loader/raspberrypi/raspberrypi-builder.nix
@@ -3,8 +3,8 @@
pkgs.substituteAll {
src = ./raspberrypi-builder.sh;
isExecutable = true;
- inherit (pkgs.buildPackages) bash;
- path = with pkgs.buildPackages; [coreutils gnused gnugrep];
+ inherit (pkgs) bash;
+ path = [pkgs.coreutils pkgs.gnused pkgs.gnugrep];
firmware = pkgs.raspberrypifw;
inherit configTxt;
}
diff --git a/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py b/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py
index 97e824fe629..65c7b825f85 100644
--- a/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py
+++ b/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py
@@ -200,7 +200,9 @@ def main():
else:
# Update bootloader to latest if needed
systemd_version = subprocess.check_output(["@systemd@/bin/bootctl", "--version"], universal_newlines=True).split()[1]
- sdboot_status = subprocess.check_output(["@systemd@/bin/bootctl", "--path=@efiSysMountPoint@", "status"], universal_newlines=True)
+ # Ideally this should use check_output as well, but as a temporary
+ # work-around for #97433 we ignore any errors.
+ sdboot_status = subprocess.run(["@systemd@/bin/bootctl", "--path=@efiSysMountPoint@", "status"], universal_newlines=True, stdout=subprocess.PIPE).stdout
# See status_binaries() in systemd bootctl.c for code which generates this
m = re.search("^\W+File:.*/EFI/(BOOT|systemd)/.*\.efi \(systemd-boot (\d+)\)$",
diff --git a/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix b/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix
index 22d459ceb04..f0bd76a3c1d 100644
--- a/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix
+++ b/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix
@@ -64,10 +64,10 @@ in {
example = 120;
type = types.nullOr types.int;
description = ''
- Maximum number of latest generations in the boot menu.
+ Maximum number of latest generations in the boot menu.
Useful to prevent boot partition running out of disk space.
- <literal>null</literal> means no limit i.e. all generations
+ <literal>null</literal> means no limit i.e. all generations
that were not garbage collected yet.
'';
};
diff --git a/nixpkgs/nixos/modules/system/boot/luksroot.nix b/nixpkgs/nixos/modules/system/boot/luksroot.nix
index 166f89c7066..88190e8200b 100644
--- a/nixpkgs/nixos/modules/system/boot/luksroot.nix
+++ b/nixpkgs/nixos/modules/system/boot/luksroot.nix
@@ -516,7 +516,7 @@ in
<filename>/dev/mapper/<replaceable>name</replaceable></filename>.
'';
- type = with types; loaOf (submodule (
+ type = with types; attrsOf (submodule (
{ name, ... }: { options = {
name = mkOption {
@@ -641,7 +641,7 @@ in
credential = mkOption {
default = null;
example = "f1d00200d8dc783f7fb1e10ace8da27f8312d72692abfca2f7e4960a73f48e82e1f7571f6ebfcee9fb434f9886ccc8fcc52a6614d8d2";
- type = types.str;
+ type = types.nullOr types.str;
description = "The FIDO2 credential ID.";
};
diff --git a/nixpkgs/nixos/modules/system/boot/networkd.nix b/nixpkgs/nixos/modules/system/boot/networkd.nix
index 721080949e0..47689b2a470 100644
--- a/nixpkgs/nixos/modules/system/boot/networkd.nix
+++ b/nixpkgs/nixos/modules/system/boot/networkd.nix
@@ -8,359 +8,714 @@ let
cfg = config.systemd.network;
- checkLink = checkUnitConfig "Link" [
- (assertOnlyFields [
- "Description" "Alias" "MACAddressPolicy" "MACAddress" "NamePolicy" "Name" "OriginalName"
- "MTUBytes" "BitsPerSecond" "Duplex" "AutoNegotiation" "WakeOnLan" "Port" "Advertise"
- "TCPSegmentationOffload" "TCP6SegmentationOffload" "GenericSegmentationOffload"
- "GenericReceiveOffload" "LargeReceiveOffload" "RxChannels" "TxChannels"
- "OtherChannels" "CombinedChannels"
- ])
- (assertValueOneOf "MACAddressPolicy" ["persistent" "random" "none"])
- (assertMacAddress "MACAddress")
- (assertByteFormat "MTUBytes")
- (assertByteFormat "BitsPerSecond")
- (assertValueOneOf "Duplex" ["half" "full"])
- (assertValueOneOf "AutoNegotiation" boolValues)
- (assertValueOneOf "WakeOnLan" ["phy" "unicast" "multicast" "broadcast" "arp" "magic" "secureon" "off"])
- (assertValueOneOf "Port" ["tp" "aui" "bnc" "mii" "fibre"])
- (assertValueOneOf "TCPSegmentationOffload" boolValues)
- (assertValueOneOf "TCP6SegmentationOffload" boolValues)
- (assertValueOneOf "GenericSegmentationOffload" boolValues)
- (assertValueOneOf "UDPSegmentationOffload" boolValues)
- (assertValueOneOf "GenericReceiveOffload" boolValues)
- (assertValueOneOf "LargeReceiveOffload" boolValues)
- (assertInt "RxChannels")
- (assertMinimum "RxChannels" 1)
- (assertInt "TxChannels")
- (assertMinimum "TxChannels" 1)
- (assertInt "OtherChannels")
- (assertMinimum "OtherChannels" 1)
- (assertInt "CombinedChannels")
- (assertMinimum "CombinedChannels" 1)
- ];
-
- checkNetdev = checkUnitConfig "Netdev" [
- (assertOnlyFields [
- "Description" "Name" "Kind" "MTUBytes" "MACAddress"
- ])
- (assertHasField "Name")
- (assertHasField "Kind")
- (assertValueOneOf "Kind" [
- "bond" "bridge" "dummy" "gre" "gretap" "ip6gre" "ip6tnl" "ip6gretap" "ipip"
- "ipvlan" "macvlan" "macvtap" "sit" "tap" "tun" "veth" "vlan" "vti" "vti6"
- "vxlan" "geneve" "vrf" "vcan" "vxcan" "wireguard" "netdevsim" "xfrm"
- ])
- (assertByteFormat "MTUBytes")
- (assertMacAddress "MACAddress")
- ];
-
- checkVRF = checkUnitConfig "VRF" [
- (assertOnlyFields [ "Table" ])
- (assertMinimum "Table" 0)
- ];
+ check = {
+
+ link = {
+
+ sectionLink = checkUnitConfig "Link" [
+ (assertOnlyFields [
+ "Description"
+ "Alias"
+ "MACAddressPolicy"
+ "MACAddress"
+ "NamePolicy"
+ "Name"
+ "AlternativeNamesPolicy"
+ "AlternativeName"
+ "MTUBytes"
+ "BitsPerSecond"
+ "Duplex"
+ "AutoNegotiation"
+ "WakeOnLan"
+ "Port"
+ "Advertise"
+ "ReceiveChecksumOffload"
+ "TransmitChecksumOffload"
+ "TCPSegmentationOffload"
+ "TCP6SegmentationOffload"
+ "GenericSegmentationOffload"
+ "GenericReceiveOffload"
+ "LargeReceiveOffload"
+ "RxChannels"
+ "TxChannels"
+ "OtherChannels"
+ "CombinedChannels"
+ "RxBufferSize"
+ "TxBufferSize"
+ ])
+ (assertValueOneOf "MACAddressPolicy" ["persistent" "random" "none"])
+ (assertMacAddress "MACAddress")
+ (assertByteFormat "MTUBytes")
+ (assertByteFormat "BitsPerSecond")
+ (assertValueOneOf "Duplex" ["half" "full"])
+ (assertValueOneOf "AutoNegotiation" boolValues)
+ (assertValueOneOf "WakeOnLan" ["phy" "unicast" "multicast" "broadcast" "arp" "magic" "secureon" "off"])
+ (assertValueOneOf "Port" ["tp" "aui" "bnc" "mii" "fibre"])
+ (assertValueOneOf "ReceiveChecksumOffload" boolValues)
+ (assertValueOneOf "TransmitChecksumOffload" boolValues)
+ (assertValueOneOf "TCPSegmentationOffload" boolValues)
+ (assertValueOneOf "TCP6SegmentationOffload" boolValues)
+ (assertValueOneOf "GenericSegmentationOffload" boolValues)
+ (assertValueOneOf "GenericReceiveOffload" boolValues)
+ (assertValueOneOf "LargeReceiveOffload" boolValues)
+ (assertInt "RxChannels")
+ (assertRange "RxChannels" 1 4294967295)
+ (assertInt "TxChannels")
+ (assertRange "TxChannels" 1 4294967295)
+ (assertInt "OtherChannels")
+ (assertRange "OtherChannels" 1 4294967295)
+ (assertInt "CombinedChannels")
+ (assertRange "CombinedChannels" 1 4294967295)
+ (assertInt "RxBufferSize")
+ (assertInt "TxBufferSize")
+ ];
+ };
- # 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"
- ])
- # The following check won't work on nix <= 2.2
- # see https://github.com/NixOS/nix/pull/2378
- #
- # Add this again when we'll have drop the
- # nix < 2.2 support.
- # (assertRange "FwMark" 1 4294967295)
- ];
+ netdev = let
+
+ tunChecks = [
+ (assertOnlyFields [
+ "MultiQueue"
+ "PacketInfo"
+ "VNetHeader"
+ "User"
+ "Group"
+ ])
+ (assertValueOneOf "MultiQueue" boolValues)
+ (assertValueOneOf "PacketInfo" boolValues)
+ (assertValueOneOf "VNetHeader" boolValues)
+ ];
+ in {
+
+ sectionNetdev = checkUnitConfig "Netdev" [
+ (assertOnlyFields [
+ "Description"
+ "Name"
+ "Kind"
+ "MTUBytes"
+ "MACAddress"
+ ])
+ (assertHasField "Name")
+ (assertHasField "Kind")
+ (assertValueOneOf "Kind" [
+ "bond"
+ "bridge"
+ "dummy"
+ "gre"
+ "gretap"
+ "erspan"
+ "ip6gre"
+ "ip6tnl"
+ "ip6gretap"
+ "ipip"
+ "ipvlan"
+ "macvlan"
+ "macvtap"
+ "sit"
+ "tap"
+ "tun"
+ "veth"
+ "vlan"
+ "vti"
+ "vti6"
+ "vxlan"
+ "geneve"
+ "l2tp"
+ "macsec"
+ "vrf"
+ "vcan"
+ "vxcan"
+ "wireguard"
+ "netdevsim"
+ "nlmon"
+ "fou"
+ "xfrm"
+ "ifb"
+ ])
+ (assertByteFormat "MTUBytes")
+ (assertMacAddress "MACAddress")
+ ];
- # 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)
- ];
+ sectionVLAN = checkUnitConfig "VLAN" [
+ (assertOnlyFields [
+ "Id"
+ "GVRP"
+ "MVRP"
+ "LooseBinding"
+ "ReorderHeader"
+ ])
+ (assertInt "Id")
+ (assertRange "Id" 0 4094)
+ (assertValueOneOf "GVRP" boolValues)
+ (assertValueOneOf "MVRP" boolValues)
+ (assertValueOneOf "LooseBinding" boolValues)
+ (assertValueOneOf "ReorderHeader" boolValues)
+ ];
- checkVlan = checkUnitConfig "VLAN" [
- (assertOnlyFields ["Id" "GVRP" "MVRP" "LooseBinding" "ReorderHeader"])
- (assertRange "Id" 0 4094)
- (assertValueOneOf "GVRP" boolValues)
- (assertValueOneOf "MVRP" boolValues)
- (assertValueOneOf "LooseBinding" boolValues)
- (assertValueOneOf "ReorderHeader" boolValues)
- ];
+ sectionMACVLAN = checkUnitConfig "MACVLAN" [
+ (assertOnlyFields [
+ "Mode"
+ ])
+ (assertValueOneOf "Mode" ["private" "vepa" "bridge" "passthru"])
+ ];
- checkMacvlan = checkUnitConfig "MACVLAN" [
- (assertOnlyFields ["Mode"])
- (assertValueOneOf "Mode" ["private" "vepa" "bridge" "passthru"])
- ];
+ sectionVXLAN = checkUnitConfig "VXLAN" [
+ (assertOnlyFields [
+ "VNI"
+ "Remote"
+ "Local"
+ "Group"
+ "TOS"
+ "TTL"
+ "MacLearning"
+ "FDBAgeingSec"
+ "MaximumFDBEntries"
+ "ReduceARPProxy"
+ "L2MissNotification"
+ "L3MissNotification"
+ "RouteShortCircuit"
+ "UDPChecksum"
+ "UDP6ZeroChecksumTx"
+ "UDP6ZeroChecksumRx"
+ "RemoteChecksumTx"
+ "RemoteChecksumRx"
+ "GroupPolicyExtension"
+ "GenericProtocolExtension"
+ "DestinationPort"
+ "PortRange"
+ "FlowLabel"
+ "IPDoNotFragment"
+ ])
+ (assertInt "VNI")
+ (assertRange "VNI" 1 16777215)
+ (assertValueOneOf "MacLearning" boolValues)
+ (assertInt "MaximumFDBEntries")
+ (assertValueOneOf "ReduceARPProxy" boolValues)
+ (assertValueOneOf "L2MissNotification" boolValues)
+ (assertValueOneOf "L3MissNotification" boolValues)
+ (assertValueOneOf "RouteShortCircuit" boolValues)
+ (assertValueOneOf "UDPChecksum" boolValues)
+ (assertValueOneOf "UDP6ZeroChecksumTx" boolValues)
+ (assertValueOneOf "UDP6ZeroChecksumRx" boolValues)
+ (assertValueOneOf "RemoteChecksumTx" boolValues)
+ (assertValueOneOf "RemoteChecksumRx" boolValues)
+ (assertValueOneOf "GroupPolicyExtension" boolValues)
+ (assertValueOneOf "GenericProtocolExtension" boolValues)
+ (assertInt "FlowLabel")
+ (assertRange "FlowLabel" 0 1048575)
+ (assertValueOneOf "IPDoNotFragment" (boolValues + ["inherit"]))
+ ];
- checkVxlan = checkUnitConfig "VXLAN" [
- (assertOnlyFields [
- "Id" "Remote" "Local" "TOS" "TTL" "MacLearning" "FDBAgeingSec"
- "MaximumFDBEntries" "ReduceARPProxy" "L2MissNotification"
- "L3MissNotification" "RouteShortCircuit" "UDPChecksum"
- "UDP6ZeroChecksumTx" "UDP6ZeroChecksumRx" "RemoteChecksumTx"
- "RemoteChecksumRx" "GroupPolicyExtension" "DestinationPort" "PortRange"
- "FlowLabel"
- ])
- (assertRange "TTL" 0 255)
- (assertValueOneOf "MacLearning" boolValues)
- (assertValueOneOf "ReduceARPProxy" boolValues)
- (assertValueOneOf "L2MissNotification" boolValues)
- (assertValueOneOf "L3MissNotification" boolValues)
- (assertValueOneOf "RouteShortCircuit" boolValues)
- (assertValueOneOf "UDPChecksum" boolValues)
- (assertValueOneOf "UDP6ZeroChecksumTx" boolValues)
- (assertValueOneOf "UDP6ZeroChecksumRx" boolValues)
- (assertValueOneOf "RemoteChecksumTx" boolValues)
- (assertValueOneOf "RemoteChecksumRx" boolValues)
- (assertValueOneOf "GroupPolicyExtension" boolValues)
- (assertRange "FlowLabel" 0 1048575)
- ];
+ sectionTunnel = checkUnitConfig "Tunnel" [
+ (assertOnlyFields [
+ "Local"
+ "Remote"
+ "TOS"
+ "TTL"
+ "DiscoverPathMTU"
+ "IPv6FlowLabel"
+ "CopyDSCP"
+ "EncapsulationLimit"
+ "Key"
+ "InputKey"
+ "OutputKey"
+ "Mode"
+ "Independent"
+ "AssignToLoopback"
+ "AllowLocalRemote"
+ "FooOverUDP"
+ "FOUDestinationPort"
+ "FOUSourcePort"
+ "Encapsulation"
+ "IPv6RapidDeploymentPrefix"
+ "ISATAP"
+ "SerializeTunneledPackets"
+ "ERSPANIndex"
+ ])
+ (assertInt "TTL")
+ (assertRange "TTL" 0 255)
+ (assertValueOneOf "DiscoverPathMTU" boolValues)
+ (assertValueOneOf "CopyDSCP" boolValues)
+ (assertValueOneOf "Mode" ["ip6ip6" "ipip6" "any"])
+ (assertValueOneOf "Independent" boolValues)
+ (assertValueOneOf "AssignToLoopback" boolValues)
+ (assertValueOneOf "AllowLocalRemote" boolValues)
+ (assertValueOneOf "FooOverUDP" boolValues)
+ (assertPort "FOUDestinationPort")
+ (assertPort "FOUSourcePort")
+ (assertValueOneOf "Encapsulation" ["FooOverUDP" "GenericUDPEncapsulation"])
+ (assertValueOneOf "ISATAP" boolValues)
+ (assertValueOneOf "SerializeTunneledPackets" boolValues)
+ (assertInt "ERSPANIndex")
+ (assertRange "ERSPANIndex" 1 1048575)
+ ];
- checkTunnel = checkUnitConfig "Tunnel" [
- (assertOnlyFields [
- "Local" "Remote" "TOS" "TTL" "DiscoverPathMTU" "IPv6FlowLabel" "CopyDSCP"
- "EncapsulationLimit" "Key" "InputKey" "OutputKey" "Mode" "Independent"
- "AllowLocalRemote"
- ])
- (assertRange "TTL" 0 255)
- (assertValueOneOf "DiscoverPathMTU" boolValues)
- (assertValueOneOf "CopyDSCP" boolValues)
- (assertValueOneOf "Mode" ["ip6ip6" "ipip6" "any"])
- (assertValueOneOf "Independent" boolValues)
- (assertValueOneOf "AllowLocalRemote" boolValues)
- ];
+ sectionPeer = checkUnitConfig "Peer" [
+ (assertOnlyFields [
+ "Name"
+ "MACAddress"
+ ])
+ (assertMacAddress "MACAddress")
+ ];
- checkPeer = checkUnitConfig "Peer" [
- (assertOnlyFields ["Name" "MACAddress"])
- (assertMacAddress "MACAddress")
- ];
+ sectionTun = checkUnitConfig "Tun" tunChecks;
+
+ sectionTap = checkUnitConfig "Tap" tunChecks;
+
+ # 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.
+ sectionWireGuard = checkUnitConfig "WireGuard" [
+ (assertOnlyFields [
+ "PrivateKeyFile"
+ "ListenPort"
+ "FirewallMark"
+ ])
+ (assertInt "FirewallMark")
+ (assertRange "FirewallMark" 1 4294967295)
+ ];
- tunTapChecks = [
- (assertOnlyFields ["OneQueue" "MultiQueue" "PacketInfo" "VNetHeader" "User" "Group"])
- (assertValueOneOf "OneQueue" boolValues)
- (assertValueOneOf "MultiQueue" boolValues)
- (assertValueOneOf "PacketInfo" boolValues)
- (assertValueOneOf "VNetHeader" boolValues)
- ];
+ # 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.
+ sectionWireGuardPeer = checkUnitConfig "WireGuardPeer" [
+ (assertOnlyFields [
+ "PublicKey"
+ "PresharedKeyFile"
+ "AllowedIPs"
+ "Endpoint"
+ "PersistentKeepalive"
+ ])
+ (assertInt "PersistentKeepalive")
+ (assertRange "PersistentKeepalive" 0 65535)
+ ];
- checkTun = checkUnitConfig "Tun" tunTapChecks;
-
- checkTap = checkUnitConfig "Tap" tunTapChecks;
-
- checkBond = checkUnitConfig "Bond" [
- (assertOnlyFields [
- "Mode" "TransmitHashPolicy" "LACPTransmitRate" "MIIMonitorSec"
- "UpDelaySec" "DownDelaySec" "LearnPacketIntervalSec" "AdSelect"
- "FailOverMACPolicy" "ARPValidate" "ARPIntervalSec" "ARPIPTargets"
- "ARPAllTargets" "PrimaryReselectPolicy" "ResendIGMP" "PacketsPerSlave"
- "GratuitousARP" "AllSlavesActive" "MinLinks"
- ])
- (assertValueOneOf "Mode" [
- "balance-rr" "active-backup" "balance-xor"
- "broadcast" "802.3ad" "balance-tlb" "balance-alb"
- ])
- (assertValueOneOf "TransmitHashPolicy" [
- "layer2" "layer3+4" "layer2+3" "encap2+3" "encap3+4"
- ])
- (assertValueOneOf "LACPTransmitRate" ["slow" "fast"])
- (assertValueOneOf "AdSelect" ["stable" "bandwidth" "count"])
- (assertValueOneOf "FailOverMACPolicy" ["none" "active" "follow"])
- (assertValueOneOf "ARPValidate" ["none" "active" "backup" "all"])
- (assertValueOneOf "ARPAllTargets" ["any" "all"])
- (assertValueOneOf "PrimaryReselectPolicy" ["always" "better" "failure"])
- (assertRange "ResendIGMP" 0 255)
- (assertRange "PacketsPerSlave" 0 65535)
- (assertRange "GratuitousARP" 0 255)
- (assertValueOneOf "AllSlavesActive" boolValues)
- ];
+ sectionBond = checkUnitConfig "Bond" [
+ (assertOnlyFields [
+ "Mode"
+ "TransmitHashPolicy"
+ "LACPTransmitRate"
+ "MIIMonitorSec"
+ "UpDelaySec"
+ "DownDelaySec"
+ "LearnPacketIntervalSec"
+ "AdSelect"
+ "AdActorSystemPriority"
+ "AdUserPortKey"
+ "AdActorSystem"
+ "FailOverMACPolicy"
+ "ARPValidate"
+ "ARPIntervalSec"
+ "ARPIPTargets"
+ "ARPAllTargets"
+ "PrimaryReselectPolicy"
+ "ResendIGMP"
+ "PacketsPerSlave"
+ "GratuitousARP"
+ "AllSlavesActive"
+ "DynamicTransmitLoadBalancing"
+ "MinLinks"
+ ])
+ (assertValueOneOf "Mode" [
+ "balance-rr"
+ "active-backup"
+ "balance-xor"
+ "broadcast"
+ "802.3ad"
+ "balance-tlb"
+ "balance-alb"
+ ])
+ (assertValueOneOf "TransmitHashPolicy" [
+ "layer2"
+ "layer3+4"
+ "layer2+3"
+ "encap2+3"
+ "encap3+4"
+ ])
+ (assertValueOneOf "LACPTransmitRate" ["slow" "fast"])
+ (assertValueOneOf "AdSelect" ["stable" "bandwidth" "count"])
+ (assertInt "AdActorSystemPriority")
+ (assertRange "AdActorSystemPriority" 1 65535)
+ (assertInt "AdUserPortKey")
+ (assertRange "AdUserPortKey" 0 1023)
+ (assertValueOneOf "FailOverMACPolicy" ["none" "active" "follow"])
+ (assertValueOneOf "ARPValidate" ["none" "active" "backup" "all"])
+ (assertValueOneOf "ARPAllTargets" ["any" "all"])
+ (assertValueOneOf "PrimaryReselectPolicy" ["always" "better" "failure"])
+ (assertInt "ResendIGMP")
+ (assertRange "ResendIGMP" 0 255)
+ (assertInt "PacketsPerSlave")
+ (assertRange "PacketsPerSlave" 0 65535)
+ (assertInt "GratuitousARP")
+ (assertRange "GratuitousARP" 0 255)
+ (assertValueOneOf "AllSlavesActive" boolValues)
+ (assertValueOneOf "DynamicTransmitLoadBalancing" boolValues)
+ (assertInt "MinLinks")
+ (assertMinimum "MinLinks" 0)
+ ];
- checkXfrm = checkUnitConfig "Xfrm" [
- (assertOnlyFields [
- "InterfaceId" "Independent"
- ])
- # The following check won't work on nix <= 2.2
- # see https://github.com/NixOS/nix/pull/2378
- #
- # Add this again when we'll have drop the
- # nix < 2.2 support.
- # (assertRange "InterfaceId" 1 4294967295)
- (assertValueOneOf "Independent" boolValues)
- ];
+ sectionXfrm = checkUnitConfig "Xfrm" [
+ (assertOnlyFields [
+ "InterfaceId"
+ "Independent"
+ ])
+ (assertInt "InterfaceId")
+ (assertRange "InterfaceId" 1 4294967295)
+ (assertValueOneOf "Independent" boolValues)
+ ];
- checkNetwork = checkUnitConfig "Network" [
- (assertOnlyFields [
- "Description" "DHCP" "DHCPServer" "LinkLocalAddressing" "IPv4LLRoute"
- "IPv6Token" "LLMNR" "MulticastDNS" "DNSOverTLS" "DNSSEC"
- "DNSSECNegativeTrustAnchors" "LLDP" "EmitLLDP" "BindCarrier" "Address"
- "Gateway" "DNS" "Domains" "NTP" "IPForward" "IPMasquerade"
- "IPv6PrivacyExtensions" "IPv6AcceptRA" "IPv6DuplicateAddressDetection"
- "IPv6HopLimit" "IPv4ProxyARP" "IPv6ProxyNDP" "IPv6ProxyNDPAddress"
- "IPv6PrefixDelegation" "IPv6MTUBytes" "Bridge" "Bond" "VRF" "VLAN"
- "IPVLAN" "MACVLAN" "VXLAN" "Tunnel" "ActiveSlave" "PrimarySlave"
- "ConfigureWithoutCarrier" "Xfrm" "KeepConfiguration"
- ])
- # Note: For DHCP the values both, none, v4, v6 are deprecated
- (assertValueOneOf "DHCP" ["yes" "no" "ipv4" "ipv6" "both" "none" "v4" "v6"])
- (assertValueOneOf "DHCPServer" boolValues)
- (assertValueOneOf "LinkLocalAddressing" ["yes" "no" "ipv4" "ipv6" "ipv4-fallback" "fallback"])
- (assertValueOneOf "IPv4LLRoute" boolValues)
- (assertValueOneOf "LLMNR" ["yes" "resolve" "no"])
- (assertValueOneOf "MulticastDNS" ["yes" "resolve" "no"])
- (assertValueOneOf "DNSOverTLS" ["opportunistic" "no"])
- (assertValueOneOf "DNSSEC" ["yes" "allow-downgrade" "no"])
- (assertValueOneOf "LLDP" ["yes" "routers-only" "no"])
- (assertValueOneOf "EmitLLDP" ["yes" "no" "nearest-bridge" "non-tpmr-bridge" "customer-bridge"])
- (assertValueOneOf "IPForward" ["yes" "no" "ipv4" "ipv6"])
- (assertValueOneOf "IPMasquerade" boolValues)
- (assertValueOneOf "IPv6PrivacyExtensions" ["yes" "no" "prefer-public" "kernel"])
- (assertValueOneOf "IPv6AcceptRA" boolValues)
- (assertValueOneOf "IPv4ProxyARP" boolValues)
- (assertValueOneOf "IPv6ProxyNDP" boolValues)
- (assertValueOneOf "IPv6PrefixDelegation" (boolValues ++ [ "dhcpv6" "static" ]))
- (assertValueOneOf "ActiveSlave" boolValues)
- (assertValueOneOf "PrimarySlave" boolValues)
- (assertValueOneOf "ConfigureWithoutCarrier" boolValues)
- (assertValueOneOf "KeepConfiguration" (boolValues ++ ["static" "dhcp-on-stop" "dhcp"]))
- ];
+ sectionVRF = checkUnitConfig "VRF" [
+ (assertOnlyFields [
+ "Table"
+ ])
+ (assertInt "Table")
+ (assertMinimum "Table" 0)
+ ];
+ };
- checkAddress = checkUnitConfig "Address" [
- (assertOnlyFields [
- "Address" "Peer" "Broadcast" "Label" "PreferredLifetime" "Scope"
- "HomeAddress" "DuplicateAddressDetection" "ManageTemporaryAddress"
- "PrefixRoute" "AutoJoin"
- ])
- (assertHasField "Address")
- (assertValueOneOf "PreferredLifetime" ["forever" "infinity" "0" 0])
- (assertValueOneOf "HomeAddress" boolValues)
- (assertValueOneOf "DuplicateAddressDetection" boolValues)
- (assertValueOneOf "ManageTemporaryAddress" boolValues)
- (assertValueOneOf "PrefixRoute" boolValues)
- (assertValueOneOf "AutoJoin" boolValues)
- ];
+ network = {
+
+ sectionLink = checkUnitConfig "Link" [
+ (assertOnlyFields [
+ "MACAddress"
+ "MTUBytes"
+ "ARP"
+ "Multicast"
+ "AllMulticast"
+ "Unmanaged"
+ "RequiredForOnline"
+ ])
+ (assertMacAddress "MACAddress")
+ (assertByteFormat "MTUBytes")
+ (assertValueOneOf "ARP" boolValues)
+ (assertValueOneOf "Multicast" boolValues)
+ (assertValueOneOf "AllMulticast" boolValues)
+ (assertValueOneOf "Unmanaged" boolValues)
+ (assertValueOneOf "RequiredForOnline" (boolValues ++ [
+ "missing"
+ "off"
+ "no-carrier"
+ "dormant"
+ "degraded-carrier"
+ "carrier"
+ "degraded"
+ "enslaved"
+ "routable"
+ ]))
+ ];
- checkRoutingPolicyRule = checkUnitConfig "RoutingPolicyRule" [
- (assertOnlyFields [
- "TypeOfService" "From" "To" "FirewallMark" "Table" "Priority"
- "IncomingInterface" "OutgoingInterface" "SourcePort" "DestinationPort"
- "IPProtocol" "InvertRule" "Family"
- ])
- (assertRange "TypeOfService" 0 255)
- # The following check won't work on nix <= 2.2
- # see https://github.com/NixOS/nix/pull/2378
- #
- # Add this again when we'll have drop the
- # nix < 2.2 support.
- # (assertRange "FirewallMark" 1 4294967295)
- (assertInt "Priority")
- (assertPort "SourcePort")
- (assertPort "DestinationPort")
- (assertValueOneOf "InvertRule" boolValues)
- (assertValueOneOf "Family" ["ipv4" "ipv6" "both"])
- ];
+ sectionNetwork = checkUnitConfig "Network" [
+ (assertOnlyFields [
+ "Description"
+ "DHCP"
+ "DHCPServer"
+ "LinkLocalAddressing"
+ "IPv4LLRoute"
+ "DefaultRouteOnDevice"
+ "IPv6Token"
+ "LLMNR"
+ "MulticastDNS"
+ "DNSOverTLS"
+ "DNSSEC"
+ "DNSSECNegativeTrustAnchors"
+ "LLDP"
+ "EmitLLDP"
+ "BindCarrier"
+ "Address"
+ "Gateway"
+ "DNS"
+ "Domains"
+ "DNSDefaultRoute"
+ "NTP"
+ "IPForward"
+ "IPMasquerade"
+ "IPv6PrivacyExtensions"
+ "IPv6AcceptRA"
+ "IPv6DuplicateAddressDetection"
+ "IPv6HopLimit"
+ "IPv4ProxyARP"
+ "IPv6ProxyNDP"
+ "IPv6ProxyNDPAddress"
+ "IPv6PrefixDelegation"
+ "IPv6MTUBytes"
+ "Bridge"
+ "Bond"
+ "VRF"
+ "VLAN"
+ "IPVLAN"
+ "MACVLAN"
+ "VXLAN"
+ "Tunnel"
+ "MACsec"
+ "ActiveSlave"
+ "PrimarySlave"
+ "ConfigureWithoutCarrier"
+ "IgnoreCarrierLoss"
+ "Xfrm"
+ "KeepConfiguration"
+ ])
+ # Note: For DHCP the values both, none, v4, v6 are deprecated
+ (assertValueOneOf "DHCP" ["yes" "no" "ipv4" "ipv6"])
+ (assertValueOneOf "DHCPServer" boolValues)
+ (assertValueOneOf "LinkLocalAddressing" ["yes" "no" "ipv4" "ipv6" "fallback" "ipv4-fallback"])
+ (assertValueOneOf "IPv4LLRoute" boolValues)
+ (assertValueOneOf "DefaultRouteOnDevice" boolValues)
+ (assertValueOneOf "LLMNR" (boolValues ++ ["resolve"]))
+ (assertValueOneOf "MulticastDNS" (boolValues ++ ["resolve"]))
+ (assertValueOneOf "DNSOverTLS" (boolValues ++ ["opportunistic"]))
+ (assertValueOneOf "DNSSEC" (boolValues ++ ["allow-downgrade"]))
+ (assertValueOneOf "LLDP" (boolValues ++ ["routers-only"]))
+ (assertValueOneOf "EmitLLDP" (boolValues ++ ["nearest-bridge" "non-tpmr-bridge" "customer-bridge"]))
+ (assertValueOneOf "DNSDefaultRoute" boolValues)
+ (assertValueOneOf "IPForward" (boolValues ++ ["ipv4" "ipv6"]))
+ (assertValueOneOf "IPMasquerade" boolValues)
+ (assertValueOneOf "IPv6PrivacyExtensions" (boolValues ++ ["prefer-public" "kernel"]))
+ (assertValueOneOf "IPv6AcceptRA" boolValues)
+ (assertInt "IPv6DuplicateAddressDetection")
+ (assertMinimum "IPv6DuplicateAddressDetection" 0)
+ (assertInt "IPv6HopLimit")
+ (assertMinimum "IPv6HopLimit" 0)
+ (assertValueOneOf "IPv4ProxyARP" boolValues)
+ (assertValueOneOf "IPv6ProxyNDP" boolValues)
+ (assertValueOneOf "IPv6PrefixDelegation" ["static" "dhcpv6" "yes" "false"])
+ (assertByteFormat "IPv6MTUBytes")
+ (assertValueOneOf "ActiveSlave" boolValues)
+ (assertValueOneOf "PrimarySlave" boolValues)
+ (assertValueOneOf "ConfigureWithoutCarrier" boolValues)
+ (assertValueOneOf "IgnoreCarrierLoss" boolValues)
+ (assertValueOneOf "KeepConfiguration" (boolValues ++ ["static" "dhcp-on-stop" "dhcp"]))
+ ];
- checkRoute = checkUnitConfig "Route" [
- (assertOnlyFields [
- "Gateway" "GatewayOnLink" "Destination" "Source" "Metric"
- "IPv6Preference" "Scope" "PreferredSource" "Table" "Protocol" "Type"
- "InitialCongestionWindow" "InitialAdvertisedReceiveWindow" "QuickAck"
- "MTUBytes"
- ])
- ];
+ sectionAddress = checkUnitConfig "Address" [
+ (assertOnlyFields [
+ "Address"
+ "Peer"
+ "Broadcast"
+ "Label"
+ "PreferredLifetime"
+ "Scope"
+ "HomeAddress"
+ "DuplicateAddressDetection"
+ "ManageTemporaryAddress"
+ "AddPrefixRoute"
+ "AutoJoin"
+ ])
+ (assertHasField "Address")
+ (assertValueOneOf "PreferredLifetime" ["forever" "infinity" "0" 0])
+ (assertValueOneOf "HomeAddress" boolValues)
+ (assertValueOneOf "DuplicateAddressDetection" ["ipv4" "ipv6" "both" "none"])
+ (assertValueOneOf "ManageTemporaryAddress" boolValues)
+ (assertValueOneOf "AddPrefixRoute" boolValues)
+ (assertValueOneOf "AutoJoin" boolValues)
+ ];
- checkDhcpV4 = checkUnitConfig "DHCPv4" [
- (assertOnlyFields [
- "UseDNS" "RoutesToDNS" "UseNTP" "UseMTU" "Anonymize" "SendHostname" "UseHostname"
- "Hostname" "UseDomains" "UseRoutes" "UseTimezone"
- "ClientIdentifier" "VendorClassIdentifier" "UserClass" "MaxAttempts"
- "DUIDType" "DUIDRawData" "IAID" "RequestBroadcast" "RouteMetric" "RouteTable"
- "ListenPort" "SendRelease"
- ])
- (assertValueOneOf "UseDNS" boolValues)
- (assertValueOneOf "RoutesToDNS" boolValues)
- (assertValueOneOf "UseNTP" boolValues)
- (assertValueOneOf "UseMTU" boolValues)
- (assertValueOneOf "Anonymize" boolValues)
- (assertValueOneOf "SendHostname" boolValues)
- (assertValueOneOf "UseHostname" boolValues)
- (assertValueOneOf "UseDomains" ["yes" "no" "route"])
- (assertValueOneOf "UseRoutes" boolValues)
- (assertValueOneOf "UseTimezone" boolValues)
- (assertMinimum "MaxAttempts" 0)
- (assertValueOneOf "RequestBroadcast" boolValues)
- (assertInt "RouteTable")
- (assertMinimum "RouteTable" 0)
- (assertValueOneOf "SendRelease" boolValues)
- ];
+ sectionRoutingPolicyRule = checkUnitConfig "RoutingPolicyRule" [
+ (assertOnlyFields [
+ "TypeOfService"
+ "From"
+ "To"
+ "FirewallMark"
+ "Table"
+ "Priority"
+ "IncomingInterface"
+ "OutgoingInterface"
+ "SourcePort"
+ "DestinationPort"
+ "IPProtocol"
+ "InvertRule"
+ "Family"
+ "User"
+ "SuppressPrefixLength"
+ ])
+ (assertInt "TypeOfService")
+ (assertRange "TypeOfService" 0 255)
+ (assertInt "FirewallMark")
+ (assertRange "FirewallMark" 1 4294967295)
+ (assertInt "Priority")
+ (assertPort "SourcePort")
+ (assertPort "DestinationPort")
+ (assertValueOneOf "InvertRule" boolValues)
+ (assertValueOneOf "Family" ["ipv4" "ipv6" "both"])
+ (assertInt "SuppressPrefixLength")
+ (assertRange "SuppressPrefixLength" 0 128)
+ ];
- checkDhcpV6 = checkUnitConfig "DHCPv6" [
- (assertOnlyFields [
- "UseDNS" "UseNTP" "RapidCommit" "ForceDHCPv6PDOtherInformation"
- "PrefixDelegationHint"
- ])
- (assertValueOneOf "UseDNS" boolValues)
- (assertValueOneOf "UseNTP" boolValues)
- (assertValueOneOf "RapidCommit" boolValues)
- (assertValueOneOf "ForceDHCPv6PDOtherInformation" boolValues)
- ];
+ sectionRoute = checkUnitConfig "Route" [
+ (assertOnlyFields [
+ "Gateway"
+ "GatewayOnLink"
+ "Destination"
+ "Source"
+ "Metric"
+ "IPv6Preference"
+ "Scope"
+ "PreferredSource"
+ "Table"
+ "Protocol"
+ "Type"
+ "InitialCongestionWindow"
+ "InitialAdvertisedReceiveWindow"
+ "QuickAck"
+ "FastOpenNoCookie"
+ "TTLPropagate"
+ "MTUBytes"
+ "IPServiceType"
+ "MultiPathRoute"
+ ])
+ (assertValueOneOf "GatewayOnLink" boolValues)
+ (assertInt "Metric")
+ (assertValueOneOf "IPv6Preference" ["low" "medium" "high"])
+ (assertValueOneOf "Scope" ["global" "site" "link" "host" "nowhere"])
+ (assertValueOneOf "Type" [
+ "unicast"
+ "local"
+ "broadcast"
+ "anycast"
+ "multicast"
+ "blackhole"
+ "unreachable"
+ "prohibit"
+ "throw"
+ "nat"
+ "xresolve"
+ ])
+ (assertValueOneOf "QuickAck" boolValues)
+ (assertValueOneOf "FastOpenNoCookie" boolValues)
+ (assertValueOneOf "TTLPropagate" boolValues)
+ (assertByteFormat "MTUBytes")
+ (assertValueOneOf "IPServiceType" ["CS6" "CS4"])
+ ];
- checkIpv6PrefixDelegation = checkUnitConfig "IPv6PrefixDelegation" [
- (assertOnlyFields [
- "Managed" "OtherInformation" "RouterLifetimeSec"
- "RouterPreference" "EmitDNS" "DNS" "EmitDomains" "Domains"
- "DNSLifetimeSec"
- ])
- (assertValueOneOf "Managed" boolValues)
- (assertValueOneOf "OtherInformation" boolValues)
- (assertValueOneOf "RouterPreference" ["high" "medium" "low" "normal" "default"])
- (assertValueOneOf "EmitDNS" boolValues)
- (assertValueOneOf "EmitDomains" boolValues)
- (assertMinimum "DNSLifetimeSec" 0)
- ];
+ sectionDHCPv4 = checkUnitConfig "DHCPv4" [
+ (assertOnlyFields [
+ "UseDNS"
+ "RoutesToDNS"
+ "UseNTP"
+ "UseSIP"
+ "UseMTU"
+ "Anonymize"
+ "SendHostname"
+ "UseHostname"
+ "Hostname"
+ "UseDomains"
+ "UseRoutes"
+ "UseTimezone"
+ "ClientIdentifier"
+ "VendorClassIdentifier"
+ "UserClass"
+ "MaxAttempts"
+ "DUIDType"
+ "DUIDRawData"
+ "IAID"
+ "RequestBroadcast"
+ "RouteMetric"
+ "RouteTable"
+ "RouteMTUBytes"
+ "ListenPort"
+ "SendRelease"
+ "SendDecline"
+ "BlackList"
+ "RequestOptions"
+ "SendOption"
+ ])
+ (assertValueOneOf "UseDNS" boolValues)
+ (assertValueOneOf "RoutesToDNS" boolValues)
+ (assertValueOneOf "UseNTP" boolValues)
+ (assertValueOneOf "UseSIP" boolValues)
+ (assertValueOneOf "UseMTU" boolValues)
+ (assertValueOneOf "Anonymize" boolValues)
+ (assertValueOneOf "SendHostname" boolValues)
+ (assertValueOneOf "UseHostname" boolValues)
+ (assertValueOneOf "UseDomains" (boolValues ++ ["route"]))
+ (assertValueOneOf "UseRoutes" boolValues)
+ (assertValueOneOf "UseTimezone" boolValues)
+ (assertValueOneOf "ClientIdentifier" ["mac" "duid" "duid-only"])
+ (assertInt "IAID")
+ (assertValueOneOf "RequestBroadcast" boolValues)
+ (assertInt "RouteMetric")
+ (assertInt "RouteTable")
+ (assertRange "RouteTable" 0 4294967295)
+ (assertByteFormat "RouteMTUBytes")
+ (assertPort "ListenPort")
+ (assertValueOneOf "SendRelease" boolValues)
+ (assertValueOneOf "SendDecline" boolValues)
+ ];
- checkIpv6Prefix = checkUnitConfig "IPv6Prefix" [
- (assertOnlyFields [
- "AddressAutoconfiguration" "OnLink" "Prefix"
- "PreferredLifetimeSec" "ValidLifetimeSec"
- ])
- (assertValueOneOf "AddressAutoconfiguration" boolValues)
- (assertValueOneOf "OnLink" boolValues)
- (assertMinimum "PreferredLifetimeSec" 0)
- (assertMinimum "ValidLifetimeSec" 0)
- ];
+ sectionDHCPv6 = checkUnitConfig "DHCPv6" [
+ (assertOnlyFields [
+ "UseDNS"
+ "UseNTP"
+ "RapidCommit"
+ "ForceDHCPv6PDOtherInformation"
+ "PrefixDelegationHint"
+ ])
+ (assertValueOneOf "UseDNS" boolValues)
+ (assertValueOneOf "UseNTP" boolValues)
+ (assertValueOneOf "RapidCommit" boolValues)
+ (assertValueOneOf "ForceDHCPv6PDOtherInformation" boolValues)
+ ];
+ sectionDHCPServer = checkUnitConfig "DHCPServer" [
+ (assertOnlyFields [
+ "PoolOffset"
+ "PoolSize"
+ "DefaultLeaseTimeSec"
+ "MaxLeaseTimeSec"
+ "EmitDNS"
+ "DNS"
+ "EmitNTP"
+ "NTP"
+ "EmitSIP"
+ "SIP"
+ "EmitRouter"
+ "EmitTimezone"
+ "Timezone"
+ "SendOption"
+ ])
+ (assertInt "PoolOffset")
+ (assertMinimum "PoolOffset" 0)
+ (assertInt "PoolSize")
+ (assertMinimum "PoolSize" 0)
+ (assertValueOneOf "EmitDNS" boolValues)
+ (assertValueOneOf "EmitNTP" boolValues)
+ (assertValueOneOf "EmitSIP" boolValues)
+ (assertValueOneOf "EmitRouter" boolValues)
+ (assertValueOneOf "EmitTimezone" boolValues)
+ ];
- checkDhcpServer = checkUnitConfig "DHCPServer" [
- (assertOnlyFields [
- "PoolOffset" "PoolSize" "DefaultLeaseTimeSec" "MaxLeaseTimeSec"
- "EmitDNS" "DNS" "EmitNTP" "NTP" "EmitRouter" "EmitTimezone" "Timezone"
- ])
- (assertValueOneOf "EmitDNS" boolValues)
- (assertValueOneOf "EmitNTP" boolValues)
- (assertValueOneOf "EmitRouter" boolValues)
- (assertValueOneOf "EmitTimezone" boolValues)
- ];
+ sectionIPv6PrefixDelegation = checkUnitConfig "IPv6PrefixDelegation" [
+ (assertOnlyFields [
+ "Managed"
+ "OtherInformation"
+ "RouterLifetimeSec"
+ "RouterPreference"
+ "EmitDNS"
+ "DNS"
+ "EmitDomains"
+ "Domains"
+ "DNSLifetimeSec"
+ ])
+ (assertValueOneOf "Managed" boolValues)
+ (assertValueOneOf "OtherInformation" boolValues)
+ (assertValueOneOf "RouterPreference" ["high" "medium" "low" "normal" "default"])
+ (assertValueOneOf "EmitDNS" boolValues)
+ (assertValueOneOf "EmitDomains" boolValues)
+ ];
- # .network files have a [Link] section with different options than in .netlink files
- checkNetworkLink = checkUnitConfig "Link" [
- (assertOnlyFields [
- "MACAddress" "MTUBytes" "ARP" "Multicast" "Unmanaged" "RequiredForOnline"
- ])
- (assertMacAddress "MACAddress")
- (assertByteFormat "MTUBytes")
- (assertValueOneOf "ARP" boolValues)
- (assertValueOneOf "Multicast" boolValues)
- (assertValueOneOf "Unmanaged" boolValues)
- (assertValueOneOf "RequiredForOnline" (boolValues ++ ["off" "no-carrier" "dormant" "degraded-carrier" "carrier" "degraded" "enslaved" "routable"]))
- ];
+ sectionIPv6Prefix = checkUnitConfig "IPv6Prefix" [
+ (assertOnlyFields [
+ "AddressAutoconfiguration"
+ "OnLink"
+ "Prefix"
+ "PreferredLifetimeSec"
+ "ValidLifetimeSec"
+ ])
+ (assertValueOneOf "AddressAutoconfiguration" boolValues)
+ (assertValueOneOf "OnLink" boolValues)
+ ];
+ };
+ };
commonNetworkOptions = {
@@ -406,7 +761,7 @@ let
linkConfig = mkOption {
default = {};
example = { MACAddress = "00:ff:ee:aa:cc:dd"; };
- type = types.addCheck (types.attrsOf unitOption) checkLink;
+ type = types.addCheck (types.attrsOf unitOption) check.link.sectionLink;
description = ''
Each attribute in this set specifies an option in the
<literal>[Link]</literal> section of the unit. See
@@ -417,12 +772,28 @@ let
};
+ wireguardPeerOptions = {
+ options = {
+ wireguardPeerConfig = mkOption {
+ default = {};
+ example = { };
+ type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionWireGuardPeer;
+ 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.
+ '';
+ };
+ };
+ };
+
netdevOptions = commonNetworkOptions // {
netdevConfig = mkOption {
default = {};
example = { Name = "mybridge"; Kind = "bridge"; };
- type = types.addCheck (types.attrsOf unitOption) checkNetdev;
+ type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionNetdev;
description = ''
Each attribute in this set specifies an option in the
<literal>[Netdev]</literal> section of the unit. See
@@ -431,65 +802,10 @@ let
'';
};
- vrfConfig = mkOption {
- default = {};
- example = { Table = 2342; };
- type = types.addCheck (types.attrsOf unitOption) checkVRF;
- description = ''
- Each attribute in this set specifies an option in the
- <literal>[VRF]</literal> section of the unit. See
- <citerefentry><refentrytitle>systemd.netdev</refentrytitle>
- <manvolnum>5</manvolnum></citerefentry> for details.
- A detailed explanation about how VRFs work can be found in the
- <link xlink:href="https://www.kernel.org/doc/Documentation/networking/vrf.txt">kernel
- docs</link>.
- '';
- };
-
- 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; };
- type = types.addCheck (types.attrsOf unitOption) checkVlan;
+ type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionVLAN;
description = ''
Each attribute in this set specifies an option in the
<literal>[VLAN]</literal> section of the unit. See
@@ -501,7 +817,7 @@ let
macvlanConfig = mkOption {
default = {};
example = { Mode = "private"; };
- type = types.addCheck (types.attrsOf unitOption) checkMacvlan;
+ type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionMACVLAN;
description = ''
Each attribute in this set specifies an option in the
<literal>[MACVLAN]</literal> section of the unit. See
@@ -513,7 +829,7 @@ let
vxlanConfig = mkOption {
default = {};
example = { Id = "4"; };
- type = types.addCheck (types.attrsOf unitOption) checkVxlan;
+ type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionVXLAN;
description = ''
Each attribute in this set specifies an option in the
<literal>[VXLAN]</literal> section of the unit. See
@@ -525,7 +841,7 @@ let
tunnelConfig = mkOption {
default = {};
example = { Remote = "192.168.1.1"; };
- type = types.addCheck (types.attrsOf unitOption) checkTunnel;
+ type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionTunnel;
description = ''
Each attribute in this set specifies an option in the
<literal>[Tunnel]</literal> section of the unit. See
@@ -537,7 +853,7 @@ let
peerConfig = mkOption {
default = {};
example = { Name = "veth2"; };
- type = types.addCheck (types.attrsOf unitOption) checkPeer;
+ type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionPeer;
description = ''
Each attribute in this set specifies an option in the
<literal>[Peer]</literal> section of the unit. See
@@ -549,7 +865,7 @@ let
tunConfig = mkOption {
default = {};
example = { User = "openvpn"; };
- type = types.addCheck (types.attrsOf unitOption) checkTun;
+ type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionTun;
description = ''
Each attribute in this set specifies an option in the
<literal>[Tun]</literal> section of the unit. See
@@ -561,7 +877,7 @@ let
tapConfig = mkOption {
default = {};
example = { User = "openvpn"; };
- type = types.addCheck (types.attrsOf unitOption) checkTap;
+ type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionTap;
description = ''
Each attribute in this set specifies an option in the
<literal>[Tap]</literal> section of the unit. See
@@ -570,10 +886,50 @@ let
'';
};
+ wireguardConfig = mkOption {
+ default = {};
+ example = {
+ PrivateKeyFile = "/etc/wireguard/secret.key";
+ ListenPort = 51820;
+ FwMark = 42;
+ };
+ type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionWireGuard;
+ 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.
+ '';
+ };
+
bondConfig = mkOption {
default = {};
example = { Mode = "802.3ad"; };
- type = types.addCheck (types.attrsOf unitOption) checkBond;
+ type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionBond;
description = ''
Each attribute in this set specifies an option in the
<literal>[Bond]</literal> section of the unit. See
@@ -585,7 +941,7 @@ let
xfrmConfig = mkOption {
default = {};
example = { InterfaceId = 1; };
- type = types.addCheck (types.attrsOf unitOption) checkXfrm;
+ type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionXfrm;
description = ''
Each attribute in this set specifies an option in the
<literal>[Xfrm]</literal> section of the unit. See
@@ -594,6 +950,21 @@ let
'';
};
+ vrfConfig = mkOption {
+ default = {};
+ example = { Table = 2342; };
+ type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionVRF;
+ description = ''
+ Each attribute in this set specifies an option in the
+ <literal>[VRF]</literal> section of the unit. See
+ <citerefentry><refentrytitle>systemd.netdev</refentrytitle>
+ <manvolnum>5</manvolnum></citerefentry> for details.
+ A detailed explanation about how VRFs work can be found in the
+ <link xlink:href="https://www.kernel.org/doc/Documentation/networking/vrf.txt">kernel
+ docs</link>.
+ '';
+ };
+
};
addressOptions = {
@@ -601,7 +972,7 @@ let
addressConfig = mkOption {
default = {};
example = { Address = "192.168.0.100/24"; };
- type = types.addCheck (types.attrsOf unitOption) checkAddress;
+ type = types.addCheck (types.attrsOf unitOption) check.network.sectionAddress;
description = ''
Each attribute in this set specifies an option in the
<literal>[Address]</literal> section of the unit. See
@@ -617,7 +988,7 @@ let
routingPolicyRuleConfig = mkOption {
default = { };
example = { routingPolicyRuleConfig = { Table = 10; IncomingInterface = "eth1"; Family = "both"; } ;};
- type = types.addCheck (types.attrsOf unitOption) checkRoutingPolicyRule;
+ type = types.addCheck (types.attrsOf unitOption) check.network.sectionRoutingPolicyRule;
description = ''
Each attribute in this set specifies an option in the
<literal>[RoutingPolicyRule]</literal> section of the unit. See
@@ -633,7 +1004,7 @@ let
routeConfig = mkOption {
default = {};
example = { Gateway = "192.168.0.1"; };
- type = types.addCheck (types.attrsOf unitOption) checkRoute;
+ type = types.addCheck (types.attrsOf unitOption) check.network.sectionRoute;
description = ''
Each attribute in this set specifies an option in the
<literal>[Route]</literal> section of the unit. See
@@ -644,28 +1015,12 @@ 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.
- '';
- };
- };
- };
-
ipv6PrefixOptions = {
options = {
ipv6PrefixConfig = mkOption {
default = {};
example = { Prefix = "fd00::/64"; };
- type = types.addCheck (types.attrsOf unitOption) checkIpv6Prefix;
+ type = types.addCheck (types.attrsOf unitOption) check.network.sectionIPv6Prefix;
description = ''
Each attribute in this set specifies an option in the
<literal>[IPv6Prefix]</literal> section of the unit. See
@@ -676,13 +1031,24 @@ let
};
};
-
networkOptions = commonNetworkOptions // {
+ linkConfig = mkOption {
+ default = {};
+ example = { Unmanaged = true; };
+ type = types.addCheck (types.attrsOf unitOption) check.network.sectionLink;
+ description = ''
+ Each attribute in this set specifies an option in the
+ <literal>[Link]</literal> section of the unit. See
+ <citerefentry><refentrytitle>systemd.network</refentrytitle>
+ <manvolnum>5</manvolnum></citerefentry> for details.
+ '';
+ };
+
networkConfig = mkOption {
default = {};
example = { Description = "My Network"; };
- type = types.addCheck (types.attrsOf unitOption) checkNetwork;
+ type = types.addCheck (types.attrsOf unitOption) check.network.sectionNetwork;
description = ''
Each attribute in this set specifies an option in the
<literal>[Network]</literal> section of the unit. See
@@ -701,7 +1067,7 @@ let
dhcpV4Config = mkOption {
default = {};
example = { UseDNS = true; UseRoutes = true; };
- type = types.addCheck (types.attrsOf unitOption) checkDhcpV4;
+ type = types.addCheck (types.attrsOf unitOption) check.network.sectionDHCPv4;
description = ''
Each attribute in this set specifies an option in the
<literal>[DHCPv4]</literal> section of the unit. See
@@ -713,7 +1079,7 @@ let
dhcpV6Config = mkOption {
default = {};
example = { UseDNS = true; UseRoutes = true; };
- type = types.addCheck (types.attrsOf unitOption) checkDhcpV6;
+ type = types.addCheck (types.attrsOf unitOption) check.network.sectionDHCPv6;
description = ''
Each attribute in this set specifies an option in the
<literal>[DHCPv6]</literal> section of the unit. See
@@ -722,48 +1088,36 @@ let
'';
};
- ipv6PrefixDelegationConfig = mkOption {
+ dhcpServerConfig = mkOption {
default = {};
- example = { EmitDNS = true; Managed = true; OtherInformation = true; };
- type = types.addCheck (types.attrsOf unitOption) checkIpv6PrefixDelegation;
+ example = { PoolOffset = 50; EmitDNS = false; };
+ type = types.addCheck (types.attrsOf unitOption) check.network.sectionDHCPServer;
description = ''
Each attribute in this set specifies an option in the
- <literal>[IPv6PrefixDelegation]</literal> section of the unit. See
- <citerefentry><refentrytitle>systemd.network</refentrytitle>
- <manvolnum>5</manvolnum></citerefentry> for details.
- '';
- };
-
- ipv6Prefixes = mkOption {
- default = [];
- example = { AddressAutoconfiguration = true; OnLink = true; };
- type = with types; listOf (submodule ipv6PrefixOptions);
- description = ''
- A list of ipv6Prefix sections to be added to the unit. See
+ <literal>[DHCPServer]</literal> section of the unit. See
<citerefentry><refentrytitle>systemd.network</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
'';
};
- dhcpServerConfig = mkOption {
+ ipv6PrefixDelegationConfig = mkOption {
default = {};
- example = { PoolOffset = 50; EmitDNS = false; };
- type = types.addCheck (types.attrsOf unitOption) checkDhcpServer;
+ example = { EmitDNS = true; Managed = true; OtherInformation = true; };
+ type = types.addCheck (types.attrsOf unitOption) check.network.sectionIPv6PrefixDelegation;
description = ''
Each attribute in this set specifies an option in the
- <literal>[DHCPServer]</literal> section of the unit. See
+ <literal>[IPv6PrefixDelegation]</literal> section of the unit. See
<citerefentry><refentrytitle>systemd.network</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
'';
};
- linkConfig = mkOption {
- default = {};
- example = { Unmanaged = true; };
- type = types.addCheck (types.attrsOf unitOption) checkNetworkLink;
+ ipv6Prefixes = mkOption {
+ default = [];
+ example = { AddressAutoconfiguration = true; OnLink = true; };
+ type = with types; listOf (submodule ipv6PrefixOptions);
description = ''
- Each attribute in this set specifies an option in the
- <literal>[Link]</literal> section of the unit. See
+ A list of ipv6Prefix sections to be added to the unit. See
<citerefentry><refentrytitle>systemd.network</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
'';
@@ -958,160 +1312,162 @@ let
};
};
- commonMatchText = def: optionalString (def.matchConfig != {}) ''
+ commonMatchText = def: optionalString (def.matchConfig != { }) ''
[Match]
${attrsToSection def.matchConfig}
'';
linkToUnit = name: def:
{ inherit (def) enable;
- text = commonMatchText def +
- ''
+ text = commonMatchText def
+ + ''
[Link]
${attrsToSection def.linkConfig}
-
- ${def.extraConfig}
- '';
+ ''
+ + def.extraConfig;
};
netdevToUnit = name: def:
{ inherit (def) enable;
- text = commonMatchText def +
- ''
+ text = commonMatchText def
+ + ''
[NetDev]
${attrsToSection def.netdevConfig}
-
- ${optionalString (def.vlanConfig != { }) ''
- [VLAN]
- ${attrsToSection def.vlanConfig}
-
- ''}
- ${optionalString (def.macvlanConfig != { }) ''
- [MACVLAN]
- ${attrsToSection def.macvlanConfig}
-
- ''}
- ${optionalString (def.vxlanConfig != { }) ''
- [VXLAN]
- ${attrsToSection def.vxlanConfig}
-
- ''}
- ${optionalString (def.tunnelConfig != { }) ''
- [Tunnel]
- ${attrsToSection def.tunnelConfig}
-
- ''}
- ${optionalString (def.peerConfig != { }) ''
- [Peer]
- ${attrsToSection def.peerConfig}
-
- ''}
- ${optionalString (def.tunConfig != { }) ''
- [Tun]
- ${attrsToSection def.tunConfig}
-
- ''}
- ${optionalString (def.tapConfig != { }) ''
- [Tap]
- ${attrsToSection def.tapConfig}
-
- ''}
- ${optionalString (def.bondConfig != { }) ''
- [Bond]
- ${attrsToSection def.bondConfig}
-
- ''}
- ${optionalString (def.xfrmConfig != { }) ''
- [Xfrm]
- ${attrsToSection def.xfrmConfig}
-
- ''}
- ${optionalString (def.vrfConfig != { }) ''
- [VRF]
- ${attrsToSection def.vrfConfig}
-
- ''}
- ${optionalString (def.wireguardConfig != { }) ''
- [WireGuard]
- ${attrsToSection def.wireguardConfig}
-
- ''}
- ${flip concatMapStrings def.wireguardPeers (x: ''
- [WireGuardPeer]
- ${attrsToSection x.wireguardPeerConfig}
-
- '')}
- ${def.extraConfig}
- '';
+ ''
+ + optionalString (def.vlanConfig != { }) ''
+ [VLAN]
+ ${attrsToSection def.vlanConfig}
+ ''
+ + optionalString (def.macvlanConfig != { }) ''
+ [MACVLAN]
+ ${attrsToSection def.macvlanConfig}
+ ''
+ + optionalString (def.vxlanConfig != { }) ''
+ [VXLAN]
+ ${attrsToSection def.vxlanConfig}
+ ''
+ + optionalString (def.tunnelConfig != { }) ''
+ [Tunnel]
+ ${attrsToSection def.tunnelConfig}
+ ''
+ + optionalString (def.peerConfig != { }) ''
+ [Peer]
+ ${attrsToSection def.peerConfig}
+ ''
+ + optionalString (def.tunConfig != { }) ''
+ [Tun]
+ ${attrsToSection def.tunConfig}
+ ''
+ + optionalString (def.tapConfig != { }) ''
+ [Tap]
+ ${attrsToSection def.tapConfig}
+ ''
+ + optionalString (def.wireguardConfig != { }) ''
+ [WireGuard]
+ ${attrsToSection def.wireguardConfig}
+ ''
+ + flip concatMapStrings def.wireguardPeers (x: ''
+ [WireGuardPeer]
+ ${attrsToSection x.wireguardPeerConfig}
+ '')
+ + optionalString (def.bondConfig != { }) ''
+ [Bond]
+ ${attrsToSection def.bondConfig}
+ ''
+ + optionalString (def.xfrmConfig != { }) ''
+ [Xfrm]
+ ${attrsToSection def.xfrmConfig}
+ ''
+ + optionalString (def.vrfConfig != { }) ''
+ [VRF]
+ ${attrsToSection def.vrfConfig}
+ ''
+ + def.extraConfig;
};
networkToUnit = name: def:
{ inherit (def) enable;
- text = commonMatchText def +
+ text = commonMatchText def
+ + optionalString (def.linkConfig != { }) ''
+ [Link]
+ ${attrsToSection def.linkConfig}
''
- ${optionalString (def.linkConfig != { }) ''
- [Link]
- ${attrsToSection def.linkConfig}
-
- ''}
-
+ + ''
[Network]
- ${attrsToSection def.networkConfig}
+ ''
+ + attrsToSection def.networkConfig
+ + optionalString (def.address != [ ]) ''
${concatStringsSep "\n" (map (s: "Address=${s}") def.address)}
+ ''
+ + optionalString (def.gateway != [ ]) ''
${concatStringsSep "\n" (map (s: "Gateway=${s}") def.gateway)}
+ ''
+ + optionalString (def.dns != [ ]) ''
${concatStringsSep "\n" (map (s: "DNS=${s}") def.dns)}
+ ''
+ + optionalString (def.ntp != [ ]) ''
${concatStringsSep "\n" (map (s: "NTP=${s}") def.ntp)}
+ ''
+ + optionalString (def.bridge != [ ]) ''
${concatStringsSep "\n" (map (s: "Bridge=${s}") def.bridge)}
+ ''
+ + optionalString (def.bond != [ ]) ''
${concatStringsSep "\n" (map (s: "Bond=${s}") def.bond)}
+ ''
+ + optionalString (def.vrf != [ ]) ''
${concatStringsSep "\n" (map (s: "VRF=${s}") def.vrf)}
+ ''
+ + optionalString (def.vlan != [ ]) ''
${concatStringsSep "\n" (map (s: "VLAN=${s}") def.vlan)}
+ ''
+ + optionalString (def.macvlan != [ ]) ''
${concatStringsSep "\n" (map (s: "MACVLAN=${s}") def.macvlan)}
+ ''
+ + optionalString (def.vxlan != [ ]) ''
${concatStringsSep "\n" (map (s: "VXLAN=${s}") def.vxlan)}
+ ''
+ + optionalString (def.tunnel != [ ]) ''
${concatStringsSep "\n" (map (s: "Tunnel=${s}") def.tunnel)}
+ ''
+ + optionalString (def.xfrm != [ ]) ''
${concatStringsSep "\n" (map (s: "Xfrm=${s}") def.xfrm)}
+ ''
+ + ''
- ${optionalString (def.dhcpV4Config != { }) ''
- [DHCPv4]
- ${attrsToSection def.dhcpV4Config}
-
- ''}
- ${optionalString (def.dhcpV6Config != {}) ''
- [DHCPv6]
- ${attrsToSection def.dhcpV6Config}
-
- ''}
- ${optionalString (def.ipv6PrefixDelegationConfig != {}) ''
- [IPv6PrefixDelegation]
- ${attrsToSection def.ipv6PrefixDelegationConfig}
-
- ''}
- ${flip concatMapStrings def.ipv6Prefixes (x: ''
- [IPv6Prefix]
- ${attrsToSection x.ipv6PrefixConfig}
-
- '')}
- ${optionalString (def.dhcpServerConfig != { }) ''
- [DHCPServer]
- ${attrsToSection def.dhcpServerConfig}
-
- ''}
- ${flip concatMapStrings def.addresses (x: ''
- [Address]
- ${attrsToSection x.addressConfig}
-
- '')}
- ${flip concatMapStrings def.routes (x: ''
- [Route]
- ${attrsToSection x.routeConfig}
-
- '')}
- ${flip concatMapStrings def.routingPolicyRules (x: ''
- [RoutingPolicyRule]
- ${attrsToSection x.routingPolicyRuleConfig}
-
- '')}
- ${def.extraConfig}
- '';
+ ''
+ + flip concatMapStrings def.addresses (x: ''
+ [Address]
+ ${attrsToSection x.addressConfig}
+ '')
+ + flip concatMapStrings def.routingPolicyRules (x: ''
+ [RoutingPolicyRule]
+ ${attrsToSection x.routingPolicyRuleConfig}
+ '')
+ + flip concatMapStrings def.routes (x: ''
+ [Route]
+ ${attrsToSection x.routeConfig}
+ '')
+ + optionalString (def.dhcpV4Config != { }) ''
+ [DHCPv4]
+ ${attrsToSection def.dhcpV4Config}
+ ''
+ + optionalString (def.dhcpV6Config != { }) ''
+ [DHCPv6]
+ ${attrsToSection def.dhcpV6Config}
+ ''
+ + optionalString (def.dhcpServerConfig != { }) ''
+ [DHCPServer]
+ ${attrsToSection def.dhcpServerConfig}
+ ''
+ + optionalString (def.ipv6PrefixDelegationConfig != { }) ''
+ [IPv6PrefixDelegation]
+ ${attrsToSection def.ipv6PrefixDelegationConfig}
+ ''
+ + flip concatMapStrings def.ipv6Prefixes (x: ''
+ [IPv6Prefix]
+ ${attrsToSection x.ipv6PrefixConfig}
+ '')
+ + def.extraConfig;
};
unitFiles = listToAttrs (map (name: {
diff --git a/nixpkgs/nixos/modules/system/boot/stage-1-init.sh b/nixpkgs/nixos/modules/system/boot/stage-1-init.sh
index 54e3a691b2f..0c1be71cf53 100644
--- a/nixpkgs/nixos/modules/system/boot/stage-1-init.sh
+++ b/nixpkgs/nixos/modules/system/boot/stage-1-init.sh
@@ -378,12 +378,14 @@ mountFS() {
mkdir -p "/mnt-root$mountPoint"
- # For CIFS mounts, retry a few times before giving up.
+ # For ZFS and CIFS mounts, retry a few times before giving up.
+ # We do this for ZFS as a workaround for issue NixOS/nixpkgs#25383.
local n=0
while true; do
mount "/mnt-root$mountPoint" && break
- if [ "$fsType" != cifs -o "$n" -ge 10 ]; then fail; break; fi
+ if [ \( "$fsType" != cifs -a "$fsType" != zfs \) -o "$n" -ge 10 ]; then fail; break; fi
echo "retrying..."
+ sleep 1
n=$((n + 1))
done
diff --git a/nixpkgs/nixos/modules/system/boot/stage-1.nix b/nixpkgs/nixos/modules/system/boot/stage-1.nix
index 7f13f67e8ef..6823e12847c 100644
--- a/nixpkgs/nixos/modules/system/boot/stage-1.nix
+++ b/nixpkgs/nixos/modules/system/boot/stage-1.nix
@@ -36,7 +36,7 @@ let
set -euo pipefail
declare -A seen
- declare -a left
+ left=()
patchelf="${pkgs.buildPackages.patchelf}/bin/patchelf"
@@ -48,7 +48,7 @@ let
done
}
- add_needed $1
+ add_needed "$1"
while [ ''${#left[@]} -ne 0 ]; do
next=''${left[0]}
@@ -119,12 +119,13 @@ let
copy_bin_and_libs ${pkgs.mdadm}/sbin/mdmon
# Copy udev.
- copy_bin_and_libs ${udev}/lib/systemd/systemd-udevd
- copy_bin_and_libs ${udev}/lib/systemd/systemd-sysctl
copy_bin_and_libs ${udev}/bin/udevadm
+ copy_bin_and_libs ${udev}/lib/systemd/systemd-sysctl
for BIN in ${udev}/lib/udev/*_id; do
copy_bin_and_libs $BIN
done
+ # systemd-udevd is only a symlink to udevadm these days
+ ln -sf udevadm $out/bin/systemd-udevd
# Copy modprobe.
copy_bin_and_libs ${pkgs.kmod}/bin/kmod
@@ -374,7 +375,8 @@ let
) config.boot.initrd.secrets)
}
- (cd "$tmp" && find . | cpio -H newc -o) | gzip >>"$1"
+ (cd "$tmp" && find . -print0 | sort -z | cpio -o -H newc -R +0:+0 --reproducible --null) | \
+ ${config.boot.initrd.compressor} >> "$1"
'';
in
@@ -554,7 +556,7 @@ in
};
fileSystems = mkOption {
- type = with lib.types; loaOf (submodule {
+ type = with lib.types; attrsOf (submodule {
options.neededForBoot = mkOption {
default = false;
type = types.bool;
diff --git a/nixpkgs/nixos/modules/system/boot/systemd-nspawn.nix b/nixpkgs/nixos/modules/system/boot/systemd-nspawn.nix
index 06ea5ee49f7..b450d77429b 100644
--- a/nixpkgs/nixos/modules/system/boot/systemd-nspawn.nix
+++ b/nixpkgs/nixos/modules/system/boot/systemd-nspawn.nix
@@ -113,9 +113,9 @@ in {
config =
let
units = mapAttrs' (n: v: let nspawnFile = "${n}.nspawn"; in nameValuePair nspawnFile (instanceToUnit nspawnFile v)) cfg;
- in
+ in
mkMerge [
- (mkIf (cfg != {}) {
+ (mkIf (cfg != {}) {
environment.etc."systemd/nspawn".source = mkIf (cfg != {}) (generateUnits' false "nspawn" units [] []);
})
{
@@ -123,7 +123,7 @@ in {
# Workaround for https://github.com/NixOS/nixpkgs/pull/67232#issuecomment-531315437 and https://github.com/systemd/systemd/issues/13622
# Once systemd fixes this upstream, we can re-enable -U
- systemd.services."systemd-nspawn@".serviceConfig.ExecStart = [
+ systemd.services."systemd-nspawn@".serviceConfig.ExecStart = [
"" # deliberately empty. signals systemd to override the ExecStart
# Only difference between upstream is that we do not pass the -U flag
"${config.systemd.package}/bin/systemd-nspawn --quiet --keep-unit --boot --link-journal=try-guest --network-veth --settings=override --machine=%i"
diff --git a/nixpkgs/nixos/modules/system/boot/systemd-unit-options.nix b/nixpkgs/nixos/modules/system/boot/systemd-unit-options.nix
index c6dbb96951a..5addc6f9ca4 100644
--- a/nixpkgs/nixos/modules/system/boot/systemd-unit-options.nix
+++ b/nixpkgs/nixos/modules/system/boot/systemd-unit-options.nix
@@ -234,7 +234,6 @@ in rec {
path = mkOption {
default = [];
type = with types; listOf (oneOf [ package str ]);
- apply = ps: "${makeBinPath ps}:${makeSearchPathOutput "bin" "sbin" ps}";
description = ''
Packages added to the service's <envar>PATH</envar>
environment variable. Both the <filename>bin</filename>
@@ -379,6 +378,16 @@ in rec {
'';
};
+ listenDatagrams = mkOption {
+ default = [];
+ type = types.listOf types.str;
+ example = [ "0.0.0.0:993" "/run/my-socket" ];
+ description = ''
+ For each item in this list, a <literal>ListenDatagram</literal>
+ option in the <literal>[Socket]</literal> section will be created.
+ '';
+ };
+
socketConfig = mkOption {
default = {};
example = { ListenStream = "/run/my-socket"; };
diff --git a/nixpkgs/nixos/modules/system/boot/systemd.nix b/nixpkgs/nixos/modules/system/boot/systemd.nix
index 86bd81d781a..74d6957678f 100644
--- a/nixpkgs/nixos/modules/system/boot/systemd.nix
+++ b/nixpkgs/nixos/modules/system/boot/systemd.nix
@@ -25,7 +25,7 @@ let
"nss-lookup.target"
"nss-user-lookup.target"
"time-sync.target"
- #"cryptsetup.target"
+ "cryptsetup.target"
"sigpwr.target"
"timers.target"
"paths.target"
@@ -73,7 +73,7 @@ let
"systemd-journald.service"
"systemd-journal-flush.service"
"systemd-journal-catalog-update.service"
- "systemd-journald-audit.socket"
+ ] ++ (optional (!config.boot.isContainer) "systemd-journald-audit.socket") ++ [
"systemd-journald-dev-log.socket"
"syslog.socket"
@@ -81,10 +81,6 @@ let
"systemd-coredump.socket"
"systemd-coredump@.service"
- # SysV init compatibility.
- "systemd-initctl.socket"
- "systemd-initctl.service"
-
# Kernel module loading.
"systemd-modules-load.service"
"kmod-static-nodes.service"
@@ -101,7 +97,7 @@ let
"dev-hugepages.mount"
"dev-mqueue.mount"
"sys-fs-fuse-connections.mount"
- "sys-kernel-config.mount"
+ ] ++ (optional (!config.boot.isContainer) "sys-kernel-config.mount") ++ [
"sys-kernel-debug.mount"
# Maintaining state across reboots.
@@ -261,7 +257,7 @@ let
pkgs.gnused
systemd
];
- environment.PATH = config.path;
+ environment.PATH = "${makeBinPath config.path}:${makeSearchPathOutput "bin" "sbin" config.path}";
}
(mkIf (config.preStart != "")
{ serviceConfig.ExecStartPre =
@@ -354,6 +350,7 @@ let
[Socket]
${attrsToSection def.socketConfig}
${concatStringsSep "\n" (map (s: "ListenStream=${s}") def.listenStreams)}
+ ${concatStringsSep "\n" (map (s: "ListenDatagram=${s}") def.listenDatagrams)}
'';
};
@@ -906,11 +903,9 @@ in
)
]);
passwd = (mkMerge [
- [ "mymachines" ]
(mkAfter [ "systemd" ])
]);
group = (mkMerge [
- [ "mymachines" ]
(mkAfter [ "systemd" ])
]);
};
@@ -1013,16 +1008,18 @@ in
"tmpfiles.d".source = (pkgs.symlinkJoin {
name = "tmpfiles.d";
- paths = cfg.tmpfiles.packages;
+ paths = map (p: p + "/lib/tmpfiles.d") cfg.tmpfiles.packages;
postBuild = ''
for i in $(cat $pathsPath); do
- (test -d $i/lib/tmpfiles.d && test $(ls $i/lib/tmpfiles.d/*.conf | wc -l) -ge 1) || (
- echo "ERROR: The path $i was passed to systemd.tmpfiles.packages but either does not contain the folder lib/tmpfiles.d or if it contains that folder, there are no files ending in .conf in it."
+ (test -d "$i" && test $(ls "$i"/*.conf | wc -l) -ge 1) || (
+ echo "ERROR: The path '$i' from systemd.tmpfiles.packages contains no *.conf files."
exit 1
)
done
- '';
- }) + "/lib/tmpfiles.d";
+ '' + concatMapStrings (name: optionalString (hasPrefix "tmpfiles.d/" name) ''
+ rm -f $out/${removePrefix "tmpfiles.d/" name}
+ '') config.system.build.etc.targets;
+ }) + "/*";
"systemd/system-generators" = { source = hooks "generators" cfg.generators; };
"systemd/system-shutdown" = { source = hooks "shutdown" cfg.shutdown; };
diff --git a/nixpkgs/nixos/modules/system/boot/tmp.nix b/nixpkgs/nixos/modules/system/boot/tmp.nix
index 5bf5e2eb2ec..26eb172210e 100644
--- a/nixpkgs/nixos/modules/system/boot/tmp.nix
+++ b/nixpkgs/nixos/modules/system/boot/tmp.nix
@@ -36,4 +36,4 @@ with lib;
};
-} \ No newline at end of file
+}
diff --git a/nixpkgs/nixos/modules/system/etc/etc.nix b/nixpkgs/nixos/modules/system/etc/etc.nix
index 1f4d54a1ae2..7478e3e8071 100644
--- a/nixpkgs/nixos/modules/system/etc/etc.nix
+++ b/nixpkgs/nixos/modules/system/etc/etc.nix
@@ -46,7 +46,7 @@ in
Set of files that have to be linked in <filename>/etc</filename>.
'';
- type = with types; loaOf (submodule (
+ type = with types; attrsOf (submodule (
{ name, config, ... }:
{ options = {
diff --git a/nixpkgs/nixos/modules/system/etc/make-etc.sh b/nixpkgs/nixos/modules/system/etc/make-etc.sh
index 1ca4c3046f0..aabfb5e88a6 100644
--- a/nixpkgs/nixos/modules/system/etc/make-etc.sh
+++ b/nixpkgs/nixos/modules/system/etc/make-etc.sh
@@ -23,7 +23,7 @@ for ((i = 0; i < ${#targets_[@]}; i++)); do
done
else
-
+
mkdir -p $out/etc/$(dirname $target)
if ! [ -e $out/etc/$target ]; then
ln -s $source $out/etc/$target
@@ -34,13 +34,12 @@ for ((i = 0; i < ${#targets_[@]}; i++)); do
exit 1
fi
fi
-
+
if test "${modes_[$i]}" != symlink; then
echo "${modes_[$i]}" > $out/etc/$target.mode
echo "${users_[$i]}" > $out/etc/$target.uid
echo "${groups_[$i]}" > $out/etc/$target.gid
fi
-
+
fi
done
-
diff --git a/nixpkgs/nixos/modules/tasks/auto-upgrade.nix b/nixpkgs/nixos/modules/tasks/auto-upgrade.nix
index e70004e643e..69385e5f2fe 100644
--- a/nixpkgs/nixos/modules/tasks/auto-upgrade.nix
+++ b/nixpkgs/nixos/modules/tasks/auto-upgrade.nix
@@ -2,9 +2,9 @@
with lib;
-let cfg = config.system.autoUpgrade; in
+let cfg = config.system.autoUpgrade;
-{
+in {
options = {
@@ -21,6 +21,16 @@ let cfg = config.system.autoUpgrade; in
'';
};
+ flake = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ example = "github:kloenk/nix";
+ description = ''
+ The Flake URI of the NixOS configuration to build.
+ Disables the option <option>system.autoUpgrade.channel</option>.
+ '';
+ };
+
channel = mkOption {
type = types.nullOr types.str;
default = null;
@@ -35,10 +45,20 @@ let cfg = config.system.autoUpgrade; in
flags = mkOption {
type = types.listOf types.str;
- default = [];
- example = [ "-I" "stuff=/home/alice/nixos-stuff" "--option" "extra-binary-caches" "http://my-cache.example.org/" ];
+ default = [ ];
+ example = [
+ "-I"
+ "stuff=/home/alice/nixos-stuff"
+ "--option"
+ "extra-binary-caches"
+ "http://my-cache.example.org/"
+ ];
description = ''
Any additional flags passed to <command>nixos-rebuild</command>.
+
+ If you are using flakes and use a local repo you can add
+ <command>[ "--update-input" "nixpkgs" "--commit-lock-file" ]</command>
+ to update nixpkgs.
'';
};
@@ -82,11 +102,23 @@ let cfg = config.system.autoUpgrade; in
config = lib.mkIf cfg.enable {
- system.autoUpgrade.flags =
- [ "--no-build-output" ]
- ++ (if cfg.channel == null
- then [ "--upgrade" ]
- else [ "-I" "nixpkgs=${cfg.channel}/nixexprs.tar.xz" ]);
+ assertions = [{
+ assertion = !((cfg.channel != null) && (cfg.flake != null));
+ message = ''
+ The options 'system.autoUpgrade.channels' and 'system.autoUpgrade.flake' cannot both be set.
+ '';
+ }];
+
+ system.autoUpgrade.flags = [ "--no-build-output" ]
+ ++ (if cfg.flake == null then
+ (if cfg.channel == null then
+ [ "--upgrade" ]
+ else [
+ "-I"
+ "nixpkgs=${cfg.channel}/nixexprs.tar.xz"
+ ])
+ else
+ [ "--flake ${cfg.flake}" ]);
systemd.services.nixos-upgrade = {
description = "NixOS Upgrade";
@@ -96,33 +128,41 @@ let cfg = config.system.autoUpgrade; in
serviceConfig.Type = "oneshot";
- environment = config.nix.envVars //
- { inherit (config.environment.sessionVariables) NIX_PATH;
- HOME = "/root";
- } // config.networking.proxy.envVars;
+ environment = config.nix.envVars // {
+ inherit (config.environment.sessionVariables) NIX_PATH;
+ HOME = "/root";
+ } // config.networking.proxy.envVars;
- path = with pkgs; [ coreutils gnutar xz.bin gzip gitMinimal config.nix.package.out ];
+ path = with pkgs; [
+ coreutils
+ gnutar
+ xz.bin
+ gzip
+ gitMinimal
+ config.nix.package.out
+ ];
script = let
- nixos-rebuild = "${config.system.build.nixos-rebuild}/bin/nixos-rebuild";
- in
- if cfg.allowReboot then ''
- ${nixos-rebuild} boot ${toString cfg.flags}
- booted="$(readlink /run/booted-system/{initrd,kernel,kernel-modules})"
- built="$(readlink /nix/var/nix/profiles/system/{initrd,kernel,kernel-modules})"
- if [ "$booted" = "$built" ]; then
- ${nixos-rebuild} switch ${toString cfg.flags}
- else
- /run/current-system/sw/bin/shutdown -r +1
- fi
- '' else ''
- ${nixos-rebuild} switch ${toString cfg.flags}
- '';
+ nixos-rebuild =
+ "${config.system.build.nixos-rebuild}/bin/nixos-rebuild";
+ in if cfg.allowReboot then ''
+ ${nixos-rebuild} boot ${toString cfg.flags}
+ booted="$(readlink /run/booted-system/{initrd,kernel,kernel-modules})"
+ built="$(readlink /nix/var/nix/profiles/system/{initrd,kernel,kernel-modules})"
+ if [ "$booted" = "$built" ]; then
+ ${nixos-rebuild} switch ${toString cfg.flags}
+ else
+ /run/current-system/sw/bin/shutdown -r +1
+ fi
+ '' else ''
+ ${nixos-rebuild} switch ${toString cfg.flags}
+ '';
startAt = cfg.dates;
};
- systemd.timers.nixos-upgrade.timerConfig.RandomizedDelaySec = cfg.randomizedDelaySec;
+ systemd.timers.nixos-upgrade.timerConfig.RandomizedDelaySec =
+ cfg.randomizedDelaySec;
};
diff --git a/nixpkgs/nixos/modules/tasks/bcache.nix b/nixpkgs/nixos/modules/tasks/bcache.nix
index 8bab91c721f..41fb7664f3d 100644
--- a/nixpkgs/nixos/modules/tasks/bcache.nix
+++ b/nixpkgs/nixos/modules/tasks/bcache.nix
@@ -8,6 +8,6 @@
boot.initrd.extraUdevRulesCommands = ''
cp -v ${pkgs.bcache-tools}/lib/udev/rules.d/*.rules $out/
- '';
+ '';
}
diff --git a/nixpkgs/nixos/modules/tasks/encrypted-devices.nix b/nixpkgs/nixos/modules/tasks/encrypted-devices.nix
index 9c3f2d8fccb..dd337de9869 100644
--- a/nixpkgs/nixos/modules/tasks/encrypted-devices.nix
+++ b/nixpkgs/nixos/modules/tasks/encrypted-devices.nix
@@ -54,7 +54,7 @@ in
options = {
fileSystems = mkOption {
- type = with lib.types; loaOf (submodule encryptedFSOptions);
+ type = with lib.types; attrsOf (submodule encryptedFSOptions);
};
swapDevices = mkOption {
type = with lib.types; listOf (submodule encryptedFSOptions);
diff --git a/nixpkgs/nixos/modules/tasks/filesystems.nix b/nixpkgs/nixos/modules/tasks/filesystems.nix
index 0ade74b957a..3ea67dac714 100644
--- a/nixpkgs/nixos/modules/tasks/filesystems.nix
+++ b/nixpkgs/nixos/modules/tasks/filesystems.nix
@@ -159,7 +159,7 @@ in
"/bigdisk".label = "bigdisk";
}
'';
- type = types.loaOf (types.submodule [coreFileSystemOpts fileSystemOpts]);
+ type = types.attrsOf (types.submodule [coreFileSystemOpts fileSystemOpts]);
description = ''
The file systems to be mounted. It must include an entry for
the root directory (<literal>mountPoint = "/"</literal>). Each
@@ -193,7 +193,7 @@ in
boot.specialFileSystems = mkOption {
default = {};
- type = types.loaOf (types.submodule coreFileSystemOpts);
+ type = types.attrsOf (types.submodule coreFileSystemOpts);
internal = true;
description = ''
Special filesystems that are mounted very early during boot.
diff --git a/nixpkgs/nixos/modules/tasks/filesystems/zfs.nix b/nixpkgs/nixos/modules/tasks/filesystems/zfs.nix
index c9d9c6c1657..9ca7c6fb343 100644
--- a/nixpkgs/nixos/modules/tasks/filesystems/zfs.nix
+++ b/nixpkgs/nixos/modules/tasks/filesystems/zfs.nix
@@ -191,13 +191,14 @@ in
};
requestEncryptionCredentials = mkOption {
- type = types.bool;
+ type = types.either types.bool (types.listOf types.str);
default = true;
+ example = [ "tank" "data" ];
description = ''
- Request encryption keys or passwords for all encrypted datasets on import.
- For root pools the encryption key can be supplied via both an
- interactive prompt (keylocation=prompt) and from a file
- (keylocation=file://).
+ If true on import encryption keys or passwords for all encrypted datasets
+ are requested. To only decrypt selected datasets supply a list of dataset
+ names instead. For root pools the encryption key can be supplied via both
+ an interactive prompt (keylocation=prompt) and from a file (keylocation=file://).
'';
};
@@ -419,9 +420,13 @@ in
fi
poolImported "${pool}" || poolImport "${pool}" # Try one last time, e.g. to import a degraded pool.
fi
- ${lib.optionalString cfgZfs.requestEncryptionCredentials ''
- zfs load-key -a
- ''}
+ ${if isBool cfgZfs.requestEncryptionCredentials
+ then optionalString cfgZfs.requestEncryptionCredentials ''
+ zfs load-key -a
+ ''
+ else concatMapStrings (fs: ''
+ zfs load-key ${fs}
+ '') cfgZfs.requestEncryptionCredentials}
'') rootPools));
};
@@ -517,9 +522,16 @@ in
done
poolImported "${pool}" || poolImport "${pool}" # Try one last time, e.g. to import a degraded pool.
if poolImported "${pool}"; then
- ${optionalString cfgZfs.requestEncryptionCredentials ''
+ ${optionalString (if isBool cfgZfs.requestEncryptionCredentials
+ then cfgZfs.requestEncryptionCredentials
+ else cfgZfs.requestEncryptionCredentials != []) ''
${packages.zfsUser}/sbin/zfs list -rHo name,keylocation ${pool} | while IFS=$'\t' read ds kl; do
- (case "$kl" in
+ (${optionalString (!isBool cfgZfs.requestEncryptionCredentials) ''
+ if ! echo '${concatStringsSep "\n" cfgZfs.requestEncryptionCredentials}' | grep -qFx "$ds"; then
+ continue
+ fi
+ ''}
+ case "$kl" in
none )
;;
prompt )
diff --git a/nixpkgs/nixos/modules/tasks/network-interfaces-scripted.nix b/nixpkgs/nixos/modules/tasks/network-interfaces-scripted.nix
index 2e87197176b..9ba6ccfbe71 100644
--- a/nixpkgs/nixos/modules/tasks/network-interfaces-scripted.nix
+++ b/nixpkgs/nixos/modules/tasks/network-interfaces-scripted.nix
@@ -253,8 +253,8 @@ let
createTunDevice = i: nameValuePair "${i.name}-netdev"
{ description = "Virtual Network Interface ${i.name}";
- bindsTo = [ "dev-net-tun.device" ];
- after = [ "dev-net-tun.device" "network-pre.target" ];
+ bindsTo = optional (!config.boot.isContainer) "dev-net-tun.device";
+ after = optional (!config.boot.isContainer) "dev-net-tun.device" ++ [ "network-pre.target" ];
wantedBy = [ "network-setup.service" (subsystemDevice i.name) ];
partOf = [ "network-setup.service" ];
before = [ "network-setup.service" ];
diff --git a/nixpkgs/nixos/modules/tasks/network-interfaces.nix b/nixpkgs/nixos/modules/tasks/network-interfaces.nix
index 78d66966949..c0e4d3979fd 100644
--- a/nixpkgs/nixos/modules/tasks/network-interfaces.nix
+++ b/nixpkgs/nixos/modules/tasks/network-interfaces.nix
@@ -408,6 +408,9 @@ in
(this derives it from the machine-id that systemd generates) or
<literal>head -c4 /dev/urandom | od -A none -t x4</literal>
+
+ The primary use case is to ensure when using ZFS that a pool isn't imported
+ accidentally on a wrong machine.
'';
};
@@ -516,7 +519,7 @@ in
<option>networking.useDHCP</option> is true, then every
interface not listed here will be configured using DHCP.
'';
- type = with types; loaOf (submodule interfaceOpts);
+ type = with types; attrsOf (submodule interfaceOpts);
};
networking.vswitches = mkOption {
@@ -541,7 +544,7 @@ in
interfaces = mkOption {
example = [ "eth0" "eth1" ];
description = "The physical network interfaces connected by the vSwitch.";
- type = with types; loaOf (submodule vswitchInterfaceOpts);
+ type = with types; attrsOf (submodule vswitchInterfaceOpts);
};
controllers = mkOption {
@@ -1126,7 +1129,6 @@ in
++ optionals config.networking.wireless.enable [
pkgs.wirelesstools # FIXME: obsolete?
pkgs.iw
- pkgs.rfkill
]
++ bridgeStp;
diff --git a/nixpkgs/nixos/modules/testing/test-instrumentation.nix b/nixpkgs/nixos/modules/testing/test-instrumentation.nix
index 1baeab53b0c..c0ec76e8a3a 100644
--- a/nixpkgs/nixos/modules/testing/test-instrumentation.nix
+++ b/nixpkgs/nixos/modules/testing/test-instrumentation.nix
@@ -1,22 +1,13 @@
# This module allows the test driver to connect to the virtual machine
# via a root shell attached to port 514.
-{ config, lib, pkgs, ... }:
+{ options, config, lib, pkgs, ... }:
with lib;
with import ../../lib/qemu-flags.nix { inherit pkgs; };
{
- # This option is a dummy that if used in conjunction with
- # modules/virtualisation/qemu-vm.nix gets merged with the same option defined
- # there and only is declared here because some modules use
- # test-instrumentation.nix but not qemu-vm.nix.
- #
- # One particular example are the boot tests where we want instrumentation
- # within the images but not other stuff like setting up 9p filesystems.
- options.virtualisation.qemu = { };
-
config = {
systemd.services.backdoor =
@@ -55,7 +46,12 @@ with import ../../lib/qemu-flags.nix { inherit pkgs; };
systemd.services."serial-getty@hvc0".enable = false;
# Only use a serial console, no TTY.
- virtualisation.qemu.consoles = [ qemuSerialDevice ];
+ # NOTE: optionalAttrs
+ # test-instrumentation.nix appears to be used without qemu-vm.nix, so
+ # we avoid defining consoles if not possible.
+ # TODO: refactor such that test-instrumentation can import qemu-vm
+ # or declare virtualisation.qemu.console option in a module that's always imported
+ virtualisation = lib.optionalAttrs (options ? virtualisation.qemu.consoles) { qemu.consoles = [ qemuSerialDevice ]; };
boot.initrd.preDeviceCommands =
''
@@ -78,15 +74,8 @@ with import ../../lib/qemu-flags.nix { inherit pkgs; };
# OOM killer randomly get rid of processes, since this leads
# to failures that are hard to diagnose.
echo 2 > /proc/sys/vm/panic_on_oom
-
- # Coverage data is written into /tmp/coverage-data.
- mkdir -p /tmp/xchg/coverage-data
'';
- # If the kernel has been built with coverage instrumentation, make
- # it available under /proc/gcov.
- boot.kernelModules = [ "gcov-proc" ];
-
# Panic if an error occurs in stage 1 (rather than waiting for
# user intervention).
boot.kernelParams =
@@ -115,8 +104,6 @@ with import ../../lib/qemu-flags.nix { inherit pkgs; };
networking.defaultGateway = mkOverride 150 "";
networking.nameservers = mkOverride 150 [ ];
- systemd.globalEnvironment.GCOV_PREFIX = "/tmp/xchg/coverage-data";
-
system.requiredKernelConfig = with config.lib.kernelConfig; [
(isYes "SERIAL_8250_CONSOLE")
(isYes "SERIAL_8250")
diff --git a/nixpkgs/nixos/modules/virtualisation/azure-image.nix b/nixpkgs/nixos/modules/virtualisation/azure-image.nix
index 21fd58e5c90..60fed3222ef 100644
--- a/nixpkgs/nixos/modules/virtualisation/azure-image.nix
+++ b/nixpkgs/nixos/modules/virtualisation/azure-image.nix
@@ -6,7 +6,7 @@ let
in
{
imports = [ ./azure-common.nix ];
-
+
options = {
virtualisation.azureImage.diskSize = mkOption {
type = with types; int;
diff --git a/nixpkgs/nixos/modules/virtualisation/containers.nix b/nixpkgs/nixos/modules/virtualisation/containers.nix
index 3a6767d84a9..de97ba3f7bb 100644
--- a/nixpkgs/nixos/modules/virtualisation/containers.nix
+++ b/nixpkgs/nixos/modules/virtualisation/containers.nix
@@ -43,6 +43,12 @@ in
'';
};
+ ociSeccompBpfHook.enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Enable the OCI seccomp BPF hook";
+ };
+
containersConf = mkOption {
default = {};
description = "containers.conf configuration";
@@ -116,6 +122,12 @@ in
[network]
cni_plugin_dirs = ["${pkgs.cni-plugins}/bin/"]
+ ${lib.optionalString (cfg.ociSeccompBpfHook.enable == true) ''
+ [engine]
+ hooks_dir = [
+ "${config.boot.kernelPackages.oci-seccomp-bpf-hook}",
+ ]
+ ''}
'' + cfg.containersConf.extraConfig;
environment.etc."containers/registries.conf".source = toTOML "registries.conf" {
diff --git a/nixpkgs/nixos/modules/virtualisation/cri-o.nix b/nixpkgs/nixos/modules/virtualisation/cri-o.nix
index f267c97b178..aa2fb73533a 100644
--- a/nixpkgs/nixos/modules/virtualisation/cri-o.nix
+++ b/nixpkgs/nixos/modules/virtualisation/cri-o.nix
@@ -85,7 +85,7 @@ in
environment.etc."crictl.yaml".source = copyFile "${pkgs.cri-o-unwrapped.src}/crictl.yaml";
- environment.etc."crio/crio.conf".text = ''
+ environment.etc."crio/crio.conf.d/00-default.conf".text = ''
[crio]
storage_driver = "${cfg.storageDriver}"
@@ -100,6 +100,8 @@ in
cgroup_manager = "systemd"
log_level = "${cfg.logLevel}"
manage_ns_lifecycle = true
+ pinns_path = "${cfg.package}/bin/pinns"
+ hooks_dir = []
${optionalString (cfg.runtime != null) ''
default_runtime = "${cfg.runtime}"
@@ -109,6 +111,7 @@ in
'';
environment.etc."cni/net.d/10-crio-bridge.conf".source = copyFile "${pkgs.cri-o-unwrapped.src}/contrib/cni/10-crio-bridge.conf";
+ environment.etc."cni/net.d/99-loopback.conf".source = copyFile "${pkgs.cri-o-unwrapped.src}/contrib/cni/99-loopback.conf";
# Enable common /etc/containers configuration
virtualisation.containers.enable = true;
diff --git a/nixpkgs/nixos/modules/virtualisation/docker-preloader.nix b/nixpkgs/nixos/modules/virtualisation/docker-preloader.nix
deleted file mode 100644
index 6ab83058dee..00000000000
--- a/nixpkgs/nixos/modules/virtualisation/docker-preloader.nix
+++ /dev/null
@@ -1,134 +0,0 @@
-{ config, lib, pkgs, ... }:
-
-with lib;
-with builtins;
-
-let
- cfg = config.virtualisation;
-
- sanitizeImageName = image: replaceStrings ["/"] ["-"] image.imageName;
- hash = drv: head (split "-" (baseNameOf drv.outPath));
- # The label of an ext4 FS is limited to 16 bytes
- labelFromImage = image: substring 0 16 (hash image);
-
- # The Docker image is loaded and some files from /var/lib/docker/
- # are written into a qcow image.
- preload = image: pkgs.vmTools.runInLinuxVM (
- pkgs.runCommand "docker-preload-image-${sanitizeImageName image}" {
- buildInputs = with pkgs; [ docker e2fsprogs utillinux curl kmod ];
- preVM = pkgs.vmTools.createEmptyImage {
- size = cfg.dockerPreloader.qcowSize;
- fullName = "docker-deamon-image.qcow2";
- };
- }
- ''
- mkfs.ext4 /dev/vda
- e2label /dev/vda ${labelFromImage image}
- mkdir -p /var/lib/docker
- mount -t ext4 /dev/vda /var/lib/docker
-
- modprobe overlay
-
- # from https://github.com/tianon/cgroupfs-mount/blob/master/cgroupfs-mount
- mount -t tmpfs -o uid=0,gid=0,mode=0755 cgroup /sys/fs/cgroup
- cd /sys/fs/cgroup
- for sys in $(awk '!/^#/ { if ($4 == 1) print $1 }' /proc/cgroups); do
- mkdir -p $sys
- if ! mountpoint -q $sys; then
- if ! mount -n -t cgroup -o $sys cgroup $sys; then
- rmdir $sys || true
- fi
- fi
- done
-
- dockerd -H tcp://127.0.0.1:5555 -H unix:///var/run/docker.sock &
-
- until $(curl --output /dev/null --silent --connect-timeout 2 http://127.0.0.1:5555); do
- printf '.'
- sleep 1
- done
-
- docker load -i ${image}
-
- kill %1
- find /var/lib/docker/ -maxdepth 1 -mindepth 1 -not -name "image" -not -name "overlay2" | xargs rm -rf
- '');
-
- preloadedImages = map preload cfg.dockerPreloader.images;
-
-in
-
-{
- options.virtualisation.dockerPreloader = {
- images = mkOption {
- default = [ ];
- type = types.listOf types.package;
- description =
- ''
- A list of Docker images to preload (in the /var/lib/docker directory).
- '';
- };
- qcowSize = mkOption {
- default = 1024;
- type = types.int;
- description =
- ''
- The size (MB) of qcow files.
- '';
- };
- };
-
- config = mkIf (cfg.dockerPreloader.images != []) {
- assertions = [{
- # If docker.storageDriver is null, Docker choose the storage
- # driver. So, in this case, we cannot be sure overlay2 is used.
- assertion = cfg.docker.storageDriver == "overlay2"
- || cfg.docker.storageDriver == "overlay"
- || cfg.docker.storageDriver == null;
- message = "The Docker image Preloader only works with overlay2 storage driver!";
- }];
-
- virtualisation.qemu.options =
- map (path: "-drive if=virtio,file=${path}/disk-image.qcow2,readonly,media=cdrom,format=qcow2")
- preloadedImages;
-
-
- # All attached QCOW files are mounted and their contents are linked
- # to /var/lib/docker/ in order to make image available.
- systemd.services.docker-preloader = {
- description = "Preloaded Docker images";
- wantedBy = ["docker.service"];
- after = ["network.target"];
- path = with pkgs; [ mount rsync jq ];
- script = ''
- mkdir -p /var/lib/docker/overlay2/l /var/lib/docker/image/overlay2
- echo '{}' > /tmp/repositories.json
-
- for i in ${concatStringsSep " " (map labelFromImage cfg.dockerPreloader.images)}; do
- mkdir -p /mnt/docker-images/$i
-
- # The ext4 label is limited to 16 bytes
- mount /dev/disk/by-label/$(echo $i | cut -c1-16) -o ro,noload /mnt/docker-images/$i
-
- find /mnt/docker-images/$i/overlay2/ -maxdepth 1 -mindepth 1 -not -name l\
- -exec ln -s '{}' /var/lib/docker/overlay2/ \;
- cp -P /mnt/docker-images/$i/overlay2/l/* /var/lib/docker/overlay2/l/
-
- rsync -a /mnt/docker-images/$i/image/ /var/lib/docker/image/
-
- # Accumulate image definitions
- cp /tmp/repositories.json /tmp/repositories.json.tmp
- jq -s '.[0] * .[1]' \
- /tmp/repositories.json.tmp \
- /mnt/docker-images/$i/image/overlay2/repositories.json \
- > /tmp/repositories.json
- done
-
- mv /tmp/repositories.json /var/lib/docker/image/overlay2/repositories.json
- '';
- serviceConfig = {
- Type = "oneshot";
- };
- };
- };
-}
diff --git a/nixpkgs/nixos/modules/virtualisation/nixos-containers.nix b/nixpkgs/nixos/modules/virtualisation/nixos-containers.nix
index b0fa03917c8..8fbb4efd201 100644
--- a/nixpkgs/nixos/modules/virtualisation/nixos-containers.nix
+++ b/nixpkgs/nixos/modules/virtualisation/nixos-containers.nix
@@ -627,7 +627,7 @@ in
};
bindMounts = mkOption {
- type = with types; loaOf (submodule bindMountOpts);
+ type = with types; attrsOf (submodule bindMountOpts);
default = {};
example = literalExample ''
{ "/home" = { hostPath = "/home/alice";
diff --git a/nixpkgs/nixos/modules/virtualisation/parallels-guest.nix b/nixpkgs/nixos/modules/virtualisation/parallels-guest.nix
index 828419fb4b9..55605b388b7 100644
--- a/nixpkgs/nixos/modules/virtualisation/parallels-guest.nix
+++ b/nixpkgs/nixos/modules/virtualisation/parallels-guest.nix
@@ -32,7 +32,7 @@ in
};
package = mkOption {
- type = types.package;
+ type = types.nullOr types.package;
default = config.boot.kernelPackages.prl-tools;
defaultText = "config.boot.kernelPackages.prl-tools";
example = literalExample "config.boot.kernelPackages.prl-tools";
diff --git a/nixpkgs/nixos/modules/virtualisation/qemu-vm.nix b/nixpkgs/nixos/modules/virtualisation/qemu-vm.nix
index a650dd72c2a..42e43f5ee02 100644
--- a/nixpkgs/nixos/modules/virtualisation/qemu-vm.nix
+++ b/nixpkgs/nixos/modules/virtualisation/qemu-vm.nix
@@ -264,7 +264,6 @@ in
{
imports = [
../profiles/qemu-guest.nix
- ./docker-preloader.nix
];
options = {
diff --git a/nixpkgs/nixos/modules/virtualisation/railcar.nix b/nixpkgs/nixos/modules/virtualisation/railcar.nix
index 12da1c75fc3..10464f62898 100644
--- a/nixpkgs/nixos/modules/virtualisation/railcar.nix
+++ b/nixpkgs/nixos/modules/virtualisation/railcar.nix
@@ -29,9 +29,9 @@ let
default = "none";
description = ''
The type of the filesystem to be mounted.
- Linux: filesystem types supported by the kernel as listed in
- `/proc/filesystems` (e.g., "minix", "ext2", "ext3", "jfs", "xfs",
- "reiserfs", "msdos", "proc", "nfs", "iso9660"). For bind mounts
+ Linux: filesystem types supported by the kernel as listed in
+ `/proc/filesystems` (e.g., "minix", "ext2", "ext3", "jfs", "xfs",
+ "reiserfs", "msdos", "proc", "nfs", "iso9660"). For bind mounts
(when options include either bind or rbind), the type is a dummy,
often "none" (not listed in /proc/filesystems).
'';
@@ -41,13 +41,13 @@ let
description = "Source for the in-container mount";
};
options = mkOption {
- type = loaOf (str);
+ type = attrsOf (str);
default = [ "bind" ];
description = ''
Mount options of the filesystem to be used.
-
- Support optoions are listed in the mount(8) man page. Note that
- both filesystem-independent and filesystem-specific options
+
+ Support options are listed in the mount(8) man page. Note that
+ both filesystem-independent and filesystem-specific options
are listed.
'';
};
@@ -61,7 +61,7 @@ in
containers = mkOption {
default = {};
description = "Declarative container configuration";
- type = with types; loaOf (submodule ({ name, config, ... }: {
+ type = with types; attrsOf (submodule ({ name, config, ... }: {
options = {
cmd = mkOption {
type = types.lines;