aboutsummaryrefslogtreecommitdiff
path: root/nixpkgs/nixos
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
parent5581b5521e14317c3507a6e8451a3f14996e5c4d (diff)
parent441a7da8080352881bb52f85e910d8855e83fc55 (diff)
Merge commit '441a7da8080352881bb52f85e910d8855e83fc55'
Diffstat (limited to 'nixpkgs/nixos')
-rw-r--r--nixpkgs/nixos/doc/manual/administration/boot-problems.xml4
-rw-r--r--nixpkgs/nixos/doc/manual/administration/imperative-containers.xml2
-rw-r--r--nixpkgs/nixos/doc/manual/configuration/file-systems.xml8
-rw-r--r--nixpkgs/nixos/doc/manual/configuration/gpu-accel.xml106
-rw-r--r--nixpkgs/nixos/doc/manual/configuration/ipv4-config.xml2
-rw-r--r--nixpkgs/nixos/doc/manual/configuration/ipv6-config.xml2
-rw-r--r--nixpkgs/nixos/doc/manual/configuration/luks-file-systems.xml6
-rw-r--r--nixpkgs/nixos/doc/manual/configuration/network-manager.xml2
-rw-r--r--nixpkgs/nixos/doc/manual/configuration/ssh.xml2
-rw-r--r--nixpkgs/nixos/doc/manual/configuration/user-mgmt.xml12
-rw-r--r--nixpkgs/nixos/doc/manual/development/freeform-modules.xml68
-rw-r--r--nixpkgs/nixos/doc/manual/development/option-types.xml11
-rwxr-xr-xnixpkgs/nixos/doc/manual/development/releases.xml265
-rw-r--r--nixpkgs/nixos/doc/manual/development/settings-options.xml41
-rw-r--r--nixpkgs/nixos/doc/manual/development/writing-modules.xml1
-rw-r--r--nixpkgs/nixos/doc/manual/installation/changing-config.xml2
-rw-r--r--nixpkgs/nixos/doc/manual/installation/installing-from-other-distro.xml2
-rw-r--r--nixpkgs/nixos/doc/manual/installation/installing.xml12
-rw-r--r--nixpkgs/nixos/doc/manual/man-nixos-enter.xml2
-rw-r--r--nixpkgs/nixos/doc/manual/man-nixos-install.xml16
-rw-r--r--nixpkgs/nixos/doc/manual/man-nixos-rebuild.xml2
-rw-r--r--nixpkgs/nixos/doc/manual/release-notes/release-notes.xml1
-rw-r--r--nixpkgs/nixos/doc/manual/release-notes/rl-2003.xml2
-rw-r--r--nixpkgs/nixos/doc/manual/release-notes/rl-2009.xml400
-rw-r--r--nixpkgs/nixos/doc/manual/release-notes/rl-2103.xml80
-rw-r--r--nixpkgs/nixos/lib/eval-config.nix4
-rw-r--r--nixpkgs/nixos/lib/make-ext4-fs.nix5
-rw-r--r--nixpkgs/nixos/lib/make-options-doc/options-to-docbook.xsl2
-rw-r--r--nixpkgs/nixos/lib/qemu-flags.nix4
-rw-r--r--nixpkgs/nixos/lib/test-driver/Logger.pm75
-rw-r--r--nixpkgs/nixos/lib/test-driver/Machine.pm734
-rw-r--r--nixpkgs/nixos/lib/test-driver/test-driver.pl191
-rw-r--r--nixpkgs/nixos/lib/test-driver/test-driver.py31
-rw-r--r--nixpkgs/nixos/lib/testing-python.nix9
-rw-r--r--nixpkgs/nixos/lib/testing.nix258
-rw-r--r--nixpkgs/nixos/maintainers/scripts/ec2/amazon-image.nix4
-rwxr-xr-xnixpkgs/nixos/maintainers/scripts/ec2/create-amis.sh2
-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
-rw-r--r--nixpkgs/nixos/release-combined.nix18
-rw-r--r--nixpkgs/nixos/tests/3proxy.nix4
-rw-r--r--nixpkgs/nixos/tests/acme.nix368
-rw-r--r--nixpkgs/nixos/tests/all-tests.nix18
-rw-r--r--nixpkgs/nixos/tests/bitcoind.nix2
-rw-r--r--nixpkgs/nixos/tests/bittorrent.nix24
-rw-r--r--nixpkgs/nixos/tests/bitwarden.nix188
-rw-r--r--nixpkgs/nixos/tests/blockbook-frontend.nix2
-rw-r--r--nixpkgs/nixos/tests/caddy.nix18
-rw-r--r--nixpkgs/nixos/tests/charliecloud.nix43
-rw-r--r--nixpkgs/nixos/tests/common/acme/client/default.nix11
-rw-r--r--nixpkgs/nixos/tests/common/acme/server/default.nix72
-rw-r--r--nixpkgs/nixos/tests/common/acme/server/mkcerts.nix68
-rwxr-xr-xnixpkgs/nixos/tests/common/acme/server/mkcerts.sh6
-rw-r--r--nixpkgs/nixos/tests/common/acme/server/snakeoil-certs.nix206
-rw-r--r--nixpkgs/nixos/tests/common/ec2.nix58
-rw-r--r--nixpkgs/nixos/tests/containers-reloadable.nix4
-rw-r--r--nixpkgs/nixos/tests/couchdb.nix80
-rw-r--r--nixpkgs/nixos/tests/cri-o.nix19
-rw-r--r--nixpkgs/nixos/tests/docker-preloader.nix27
-rw-r--r--nixpkgs/nixos/tests/docker-tools.nix9
-rw-r--r--nixpkgs/nixos/tests/dokuwiki.nix21
-rw-r--r--nixpkgs/nixos/tests/ec2.nix140
-rw-r--r--nixpkgs/nixos/tests/firejail.nix82
-rw-r--r--nixpkgs/nixos/tests/gnome3.nix10
-rw-r--r--nixpkgs/nixos/tests/gotify-server.nix5
-rw-r--r--nixpkgs/nixos/tests/hardened.nix114
-rw-r--r--nixpkgs/nixos/tests/hocker-fetchdocker/default.nix9
-rw-r--r--nixpkgs/nixos/tests/installer.nix14
-rw-r--r--nixpkgs/nixos/tests/krb5/example-config.nix8
-rw-r--r--nixpkgs/nixos/tests/lxd-nftables.nix1
-rw-r--r--nixpkgs/nixos/tests/lxd.nix14
-rw-r--r--nixpkgs/nixos/tests/make-test.nix9
-rw-r--r--nixpkgs/nixos/tests/mathics.nix20
-rw-r--r--nixpkgs/nixos/tests/mesos.nix92
-rw-r--r--nixpkgs/nixos/tests/mesos_test.py72
-rw-r--r--nixpkgs/nixos/tests/misc.nix32
-rw-r--r--nixpkgs/nixos/tests/mysql/mysql.nix22
-rw-r--r--nixpkgs/nixos/tests/nextcloud/basic.nix1
-rw-r--r--nixpkgs/nixos/tests/nextcloud/with-mysql-and-memcached.nix1
-rw-r--r--nixpkgs/nixos/tests/nextcloud/with-postgresql-and-redis.nix1
-rw-r--r--nixpkgs/nixos/tests/nginx-sandbox.nix1
-rw-r--r--nixpkgs/nixos/tests/openstack-image.nix70
-rw-r--r--nixpkgs/nixos/tests/os-prober.nix33
-rw-r--r--nixpkgs/nixos/tests/pinnwand.nix86
-rw-r--r--nixpkgs/nixos/tests/postfix-raise-smtpd-tls-security-level.nix3
-rw-r--r--nixpkgs/nixos/tests/postfix.nix13
-rw-r--r--nixpkgs/nixos/tests/postgresql-wal-receiver.nix182
-rw-r--r--nixpkgs/nixos/tests/prometheus-exporters.nix33
-rw-r--r--nixpkgs/nixos/tests/prometheus.nix7
-rw-r--r--nixpkgs/nixos/tests/robustirc-bridge.nix29
-rw-r--r--nixpkgs/nixos/tests/shadowsocks/common.nix84
-rw-r--r--nixpkgs/nixos/tests/shadowsocks/default.nix16
-rw-r--r--nixpkgs/nixos/tests/shattered-pixel-dungeon.nix29
-rw-r--r--nixpkgs/nixos/tests/sssd-ldap.nix78
-rw-r--r--nixpkgs/nixos/tests/sssd.nix17
-rw-r--r--nixpkgs/nixos/tests/systemd-networkd-ipv6-prefix-delegation.nix8
-rw-r--r--nixpkgs/nixos/tests/systemd-networkd.nix11
-rw-r--r--nixpkgs/nixos/tests/systemd.nix32
-rw-r--r--nixpkgs/nixos/tests/transmission.nix2
-rw-r--r--nixpkgs/nixos/tests/trezord.nix2
-rw-r--r--nixpkgs/nixos/tests/trickster.nix2
-rw-r--r--nixpkgs/nixos/tests/v2ray.nix83
-rw-r--r--nixpkgs/nixos/tests/virtualbox.nix419
-rw-r--r--nixpkgs/nixos/tests/xandikos.nix2
-rw-r--r--nixpkgs/nixos/tests/xmpp/ejabberd.nix16
-rw-r--r--nixpkgs/nixos/tests/xmpp/xmpp-sendmessage.nix6
-rw-r--r--nixpkgs/nixos/tests/zfs.nix23
336 files changed, 9209 insertions, 6237 deletions
diff --git a/nixpkgs/nixos/doc/manual/administration/boot-problems.xml b/nixpkgs/nixos/doc/manual/administration/boot-problems.xml
index badc374ebcf..e0f66284010 100644
--- a/nixpkgs/nixos/doc/manual/administration/boot-problems.xml
+++ b/nixpkgs/nixos/doc/manual/administration/boot-problems.xml
@@ -58,9 +58,9 @@
Like <literal>boot.debug1</literal> or
<literal>boot.debug1devices</literal>, but runs stage1 until all
filesystems that are mounted during initrd are mounted (see
- <option><link linkend="opt-fileSystems._name__.neededForBoot">neededForBoot</link></option>
+ <option><link linkend="opt-fileSystems._name_.neededForBoot">neededForBoot</link></option>
). As a motivating example, this could be useful if you've forgotten to set
- <option><link linkend="opt-fileSystems._name__.neededForBoot">neededForBoot</link></option>
+ <option><link linkend="opt-fileSystems._name_.neededForBoot">neededForBoot</link></option>
on a file system.
</para>
</listitem>
diff --git a/nixpkgs/nixos/doc/manual/administration/imperative-containers.xml b/nixpkgs/nixos/doc/manual/administration/imperative-containers.xml
index 7ded0c11786..435ed230f51 100644
--- a/nixpkgs/nixos/doc/manual/administration/imperative-containers.xml
+++ b/nixpkgs/nixos/doc/manual/administration/imperative-containers.xml
@@ -27,7 +27,7 @@
<screen>
# nixos-container create foo --config '
<xref linkend="opt-services.openssh.enable"/> = true;
- <link linkend="opt-users.users._name__.openssh.authorizedKeys.keys">users.users.root.openssh.authorizedKeys.keys</link> = ["ssh-dss AAAAB3N…"];
+ <link linkend="opt-users.users._name_.openssh.authorizedKeys.keys">users.users.root.openssh.authorizedKeys.keys</link> = ["ssh-dss AAAAB3N…"];
'
</screen>
By default the next free address in the <literal>10.233.0.0/16</literal> subnet will be chosen
diff --git a/nixpkgs/nixos/doc/manual/configuration/file-systems.xml b/nixpkgs/nixos/doc/manual/configuration/file-systems.xml
index 3ac02a975eb..9747433375f 100644
--- a/nixpkgs/nixos/doc/manual/configuration/file-systems.xml
+++ b/nixpkgs/nixos/doc/manual/configuration/file-systems.xml
@@ -23,12 +23,12 @@
<link xlink:href="https://www.freedesktop.org/software/systemd/man/systemd-fstab-generator.html">systemd-fstab-generator</link>.
The filesystem will be mounted automatically unless
<literal>"noauto"</literal> is present in <link
- linkend="opt-fileSystems._name__.options">options</link>.
+ linkend="opt-fileSystems._name_.options">options</link>.
<literal>"noauto"</literal> filesystems can be mounted explicitly using
<command>systemctl</command> e.g. <command>systemctl start
data.mount</command>.
Mount points are created automatically if they don’t already exist. For
- <option><link linkend="opt-fileSystems._name__.device">device</link></option>,
+ <option><link linkend="opt-fileSystems._name_.device">device</link></option>,
it’s best to use the topology-independent device aliases in
<filename>/dev/disk/by-label</filename> and
<filename>/dev/disk/by-uuid</filename>, as these don’t change if the
@@ -36,7 +36,7 @@
</para>
<para>
You can usually omit the file system type
- (<option><link linkend="opt-fileSystems._name__.fsType">fsType</link></option>),
+ (<option><link linkend="opt-fileSystems._name_.fsType">fsType</link></option>),
since <command>mount</command> can usually detect the type and load the
necessary kernel module automatically. However, if the file system is needed
at early boot (in the initial ramdisk) and is not <literal>ext2</literal>,
@@ -49,7 +49,7 @@
System startup will fail if any of the filesystems fails to mount, dropping
you to the emergency shell. You can make a mount asynchronous and
non-critical by adding
- <literal><link linkend="opt-fileSystems._name__.options">options</link> = [
+ <literal><link linkend="opt-fileSystems._name_.options">options</link> = [
"nofail" ];</literal>.
</para>
</note>
diff --git a/nixpkgs/nixos/doc/manual/configuration/gpu-accel.xml b/nixpkgs/nixos/doc/manual/configuration/gpu-accel.xml
index 0aa629cce98..95ee13f4796 100644
--- a/nixpkgs/nixos/doc/manual/configuration/gpu-accel.xml
+++ b/nixpkgs/nixos/doc/manual/configuration/gpu-accel.xml
@@ -70,34 +70,40 @@ Platform Vendor Advanced Micro Devices, Inc.</screen>
Core Next</link> (GCN) GPUs are supported through the
<package>rocm-opencl-icd</package> package. Adding this package to
<xref linkend="opt-hardware.opengl.extraPackages"/> enables OpenCL
- support. However, OpenCL Image support is provided through the
- non-free <package>rocm-runtime-ext</package> package. This package can
- be added to the same configuration option, but requires that
- <varname>allowUnfree</varname> option is is enabled for nixpkgs. Full
- OpenCL support on supported AMD GPUs is thus enabled as follows:
+ support:
<programlisting><xref linkend="opt-hardware.opengl.extraPackages"/> = [
rocm-opencl-icd
- rocm-runtime-ext
];</programlisting>
</para>
+ </section>
- <para>
- It is also possible to use the OpenCL Image extension without a
- system-wide installation of the <package>rocm-runtime-ext</package>
- package by setting the <varname>ROCR_EXT_DIR</varname> environment
- variable to the directory that contains the extension:
+ <section xml:id="sec-gpu-accel-opencl-intel">
+ <title>Intel</title>
- <screen><prompt>$</prompt> export \
-ROCR_EXT_DIR=`nix-build '&lt;nixpkgs&gt;' --no-out-link -A rocm-runtime-ext`/lib/rocm-runtime-ext</screen>
+ <para>
+ <link
+ xlink:href="https://en.wikipedia.org/wiki/List_of_Intel_graphics_processing_units#Gen8">Intel
+ Gen8 and later GPUs</link> are supported by the Intel NEO OpenCL
+ runtime that is provided by the
+ <package>intel-compute-runtime</package> package. For Gen7 GPUs,
+ the deprecated Beignet runtime can be used, which is provided
+ by the <package>beignet</package> package. The proprietary Intel
+ OpenCL runtime, in the <package>intel-ocl</package> package, is
+ an alternative for Gen7 GPUs.
</para>
<para>
- With either approach, you can verify that OpenCL Image support
- is indeed working with the <command>clinfo</command> command:
+ The <package>intel-compute-runtime</package>, <package>beignet</package>,
+ or <package>intel-ocl</package> package can be added to
+ <xref linkend="opt-hardware.opengl.extraPackages"/> to enable OpenCL
+ support. For example, for Gen8 and later GPUs, the following
+ configuration can be used:
+
+ <programlisting><xref linkend="opt-hardware.opengl.extraPackages"/> = [
+ intel-compute-runtime
+];</programlisting>
- <screen><prompt>$</prompt> clinfo | grep Image
- Image support Yes</screen>
</para>
</section>
</section>
@@ -177,7 +183,12 @@ GPU1:
be forced as follows:
<programlisting><xref linkend="opt-hardware.opengl.extraPackages"/> = [
- <package>amdvlk</package>
+ pkgs.<package>amdvlk</package>
+];
+
+# To enable Vulkan support for 32-bit applications, also add:
+<xref linkend="opt-hardware.opengl.extraPackages32"/> = [
+ pkgs.driversi686Linux.<package>amdvlk</package>
];
# For amdvlk
@@ -190,4 +201,63 @@ GPU1:
</para>
</section>
</section>
+
+ <section xml:id="sec-gpu-accel-common-issues">
+ <title>Common issues</title>
+
+ <section xml:id="sec-gpu-accel-common-issues-permissions">
+ <title>User permissions</title>
+
+ <para>
+ Except where noted explicitly, it should not be necessary to
+ adjust user permissions to use these acceleration APIs. In the default
+ configuration, GPU devices have world-read/write permissions
+ (<filename>/dev/dri/renderD*</filename>) or are tagged as
+ <code>uaccess</code> (<filename>/dev/dri/card*</filename>). The
+ access control lists of devices with the <varname>uaccess</varname>
+ tag will be updated automatically when a user logs in through
+ <command>systemd-logind</command>. For example, if the user
+ <emphasis>jane</emphasis> is logged in, the access control list
+ should look as follows:
+
+ <screen><prompt>$</prompt> getfacl /dev/dri/card0
+# file: dev/dri/card0
+# owner: root
+# group: video
+user::rw-
+user:jane:rw-
+group::rw-
+mask::rw-
+other::---</screen>
+
+ If you disabled (this functionality of) <command>systemd-logind</command>,
+ you may need to add the user to the <code>video</code> group and
+ log in again.
+ </para>
+ </section>
+
+ <section xml:id="sec-gpu-accel-common-issues-mixing-nixpkgs">
+ <title>Mixing different versions of nixpkgs</title>
+
+ <para>
+ The <emphasis>Installable Client Driver</emphasis> (ICD)
+ mechanism used by OpenCL and Vulkan loads runtimes into its address
+ space using <code>dlopen</code>. Mixing an ICD loader mechanism and
+ runtimes from different version of nixpkgs may not work. For example,
+ if the ICD loader uses an older version of <package>glibc</package>
+ than the runtime, the runtime may not be loadable due to
+ missing symbols. Unfortunately, the loader will generally be quiet
+ about such issues.
+ </para>
+
+ <para>
+ If you suspect that you are running into library version mismatches
+ between an ICL loader and a runtime, you could run an application with
+ the <code>LD_DEBUG</code> variable set to get more diagnostic
+ information. For example, OpenCL can be tested with
+ <code>LD_DEBUG=files clinfo</code>, which should report missing
+ symbols.
+ </para>
+ </section>
+ </section>
</chapter>
diff --git a/nixpkgs/nixos/doc/manual/configuration/ipv4-config.xml b/nixpkgs/nixos/doc/manual/configuration/ipv4-config.xml
index 71ddf41491b..884becf0979 100644
--- a/nixpkgs/nixos/doc/manual/configuration/ipv4-config.xml
+++ b/nixpkgs/nixos/doc/manual/configuration/ipv4-config.xml
@@ -10,7 +10,7 @@
automatically configure network interfaces. However, you can configure an
interface manually as follows:
<programlisting>
-<link linkend="opt-networking.interfaces._name__.ipv4.addresses">networking.interfaces.eth0.ipv4.addresses</link> = [ {
+<link linkend="opt-networking.interfaces._name_.ipv4.addresses">networking.interfaces.eth0.ipv4.addresses</link> = [ {
address = "192.168.1.2";
prefixLength = 24;
} ];
diff --git a/nixpkgs/nixos/doc/manual/configuration/ipv6-config.xml b/nixpkgs/nixos/doc/manual/configuration/ipv6-config.xml
index 675a5d9a260..7b89b4092be 100644
--- a/nixpkgs/nixos/doc/manual/configuration/ipv6-config.xml
+++ b/nixpkgs/nixos/doc/manual/configuration/ipv6-config.xml
@@ -26,7 +26,7 @@
As with IPv4 networking interfaces are automatically configured via DHCPv6.
You can configure an interface manually:
<programlisting>
-<link linkend="opt-networking.interfaces._name__.ipv6.addresses">networking.interfaces.eth0.ipv6.addresses</link> = [ {
+<link linkend="opt-networking.interfaces._name_.ipv6.addresses">networking.interfaces.eth0.ipv6.addresses</link> = [ {
address = "fe00:aa:bb:cc::2";
prefixLength = 64;
} ];
diff --git a/nixpkgs/nixos/doc/manual/configuration/luks-file-systems.xml b/nixpkgs/nixos/doc/manual/configuration/luks-file-systems.xml
index d3007843d68..8a8168c095f 100644
--- a/nixpkgs/nixos/doc/manual/configuration/luks-file-systems.xml
+++ b/nixpkgs/nixos/doc/manual/configuration/luks-file-systems.xml
@@ -30,7 +30,7 @@ Enter passphrase for /dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d: ***
<filename>/</filename>, add the following to
<filename>configuration.nix</filename>:
<programlisting>
-<link linkend="opt-boot.initrd.luks.devices._name__.device">boot.initrd.luks.devices.crypted.device</link> = "/dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d";
+<link linkend="opt-boot.initrd.luks.devices._name_.device">boot.initrd.luks.devices.crypted.device</link> = "/dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d";
<xref linkend="opt-fileSystems"/>."/".device = "/dev/mapper/crypted";
</programlisting>
Should grub be used as bootloader, and <filename>/boot</filename> is located
@@ -60,13 +60,13 @@ Added to key to device /dev/sda2, slot: 2
To ensure that this file system is decrypted using the FIDO2 compatible key, add the following to <filename>configuration.nix</filename>:
<programlisting>
<link linkend="opt-boot.initrd.luks.fido2Support">boot.initrd.luks.fido2Support</link> = true;
-<link linkend="opt-boot.initrd.luks.devices._name__.fido2.credential">boot.initrd.luks.devices."/dev/sda2".fido2.credential</link> = "f1d00200108b9d6e849a8b388da457688e3dd653b4e53770012d8f28e5d3b269865038c346802f36f3da7278b13ad6a3bb6a1452e24ebeeaa24ba40eef559b1b287d2a2f80b7";
+<link linkend="opt-boot.initrd.luks.devices._name_.fido2.credential">boot.initrd.luks.devices."/dev/sda2".fido2.credential</link> = "f1d00200108b9d6e849a8b388da457688e3dd653b4e53770012d8f28e5d3b269865038c346802f36f3da7278b13ad6a3bb6a1452e24ebeeaa24ba40eef559b1b287d2a2f80b7";
</programlisting>
You can also use the FIDO2 passwordless setup, but for security reasons, you might want to enable it only when your device is PIN protected, such as <link xlink:href="https://trezor.io/">Trezor</link>.
<programlisting>
-<link linkend="opt-boot.initrd.luks.devices._name__.fido2.passwordLess">boot.initrd.luks.devices."/dev/sda2".fido2.passwordLess</link> = true;
+<link linkend="opt-boot.initrd.luks.devices._name_.fido2.passwordLess">boot.initrd.luks.devices."/dev/sda2".fido2.passwordLess</link> = true;
</programlisting>
</para>
</section>
diff --git a/nixpkgs/nixos/doc/manual/configuration/network-manager.xml b/nixpkgs/nixos/doc/manual/configuration/network-manager.xml
index 3953e0ffe85..94d229fd803 100644
--- a/nixpkgs/nixos/doc/manual/configuration/network-manager.xml
+++ b/nixpkgs/nixos/doc/manual/configuration/network-manager.xml
@@ -19,7 +19,7 @@
All users that should have permission to change network settings must belong
to the <code>networkmanager</code> group:
<programlisting>
-<link linkend="opt-users.users._name__.extraGroups">users.users.alice.extraGroups</link> = [ "networkmanager" ];
+<link linkend="opt-users.users._name_.extraGroups">users.users.alice.extraGroups</link> = [ "networkmanager" ];
</programlisting>
</para>
diff --git a/nixpkgs/nixos/doc/manual/configuration/ssh.xml b/nixpkgs/nixos/doc/manual/configuration/ssh.xml
index a4af1b96583..95ad3edff93 100644
--- a/nixpkgs/nixos/doc/manual/configuration/ssh.xml
+++ b/nixpkgs/nixos/doc/manual/configuration/ssh.xml
@@ -20,7 +20,7 @@
follows:
<!-- FIXME: this might not work if the user is unmanaged. -->
<programlisting>
-<link linkend="opt-users.users._name__.openssh.authorizedKeys.keys">users.users.alice.openssh.authorizedKeys.keys</link> =
+<link linkend="opt-users.users._name_.openssh.authorizedKeys.keys">users.users.alice.openssh.authorizedKeys.keys</link> =
[ "ssh-dss AAAAB3NzaC1kc3MAAACBAPIkGWVEt4..." ];
</programlisting>
</para>
diff --git a/nixpkgs/nixos/doc/manual/configuration/user-mgmt.xml b/nixpkgs/nixos/doc/manual/configuration/user-mgmt.xml
index 4b1710f3a2b..68324cc85b5 100644
--- a/nixpkgs/nixos/doc/manual/configuration/user-mgmt.xml
+++ b/nixpkgs/nixos/doc/manual/configuration/user-mgmt.xml
@@ -11,11 +11,11 @@
that a user account named <literal>alice</literal> shall exist:
<programlisting>
<xref linkend="opt-users.users"/>.alice = {
- <link linkend="opt-users.users._name__.isNormalUser">isNormalUser</link> = true;
- <link linkend="opt-users.users._name__.home">home</link> = "/home/alice";
- <link linkend="opt-users.users._name__.description">description</link> = "Alice Foobar";
- <link linkend="opt-users.users._name__.extraGroups">extraGroups</link> = [ "wheel" "networkmanager" ];
- <link linkend="opt-users.users._name__.openssh.authorizedKeys.keys">openssh.authorizedKeys.keys</link> = [ "ssh-dss AAAAB3Nza... alice@foobar" ];
+ <link linkend="opt-users.users._name_.isNormalUser">isNormalUser</link> = true;
+ <link linkend="opt-users.users._name_.home">home</link> = "/home/alice";
+ <link linkend="opt-users.users._name_.description">description</link> = "Alice Foobar";
+ <link linkend="opt-users.users._name_.extraGroups">extraGroups</link> = [ "wheel" "networkmanager" ];
+ <link linkend="opt-users.users._name_.openssh.authorizedKeys.keys">openssh.authorizedKeys.keys</link> = [ "ssh-dss AAAAB3Nza... alice@foobar" ];
};
</programlisting>
Note that <literal>alice</literal> is a member of the
@@ -36,7 +36,7 @@
account will cease to exist. Also, imperative commands for managing users and
groups, such as useradd, are no longer available. Passwords may still be
assigned by setting the user's
- <link linkend="opt-users.users._name__.hashedPassword">hashedPassword</link>
+ <link linkend="opt-users.users._name_.hashedPassword">hashedPassword</link>
option. A hashed password can be generated using <command>mkpasswd -m
sha-512</command> after installing the <literal>mkpasswd</literal> package.
</para>
diff --git a/nixpkgs/nixos/doc/manual/development/freeform-modules.xml b/nixpkgs/nixos/doc/manual/development/freeform-modules.xml
new file mode 100644
index 00000000000..257e6b11bf0
--- /dev/null
+++ b/nixpkgs/nixos/doc/manual/development/freeform-modules.xml
@@ -0,0 +1,68 @@
+<section 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="sec-freeform-modules">
+ <title>Freeform modules</title>
+ <para>
+ Freeform modules allow you to define values for option paths that have not been declared explicitly. This can be used to add attribute-specific types to what would otherwise have to be <literal>attrsOf</literal> options in order to accept all attribute names.
+ </para>
+ <para>
+ This feature can be enabled by using the attribute <literal>freeformType</literal> to define a freeform type. By doing this, all assignments without an associated option will be merged using the freeform type and combined into the resulting <literal>config</literal> set. Since this feature nullifies name checking for entire option trees, it is only recommended for use in submodules.
+ </para>
+ <example xml:id="ex-freeform-module">
+ <title>Freeform submodule</title>
+ <para>
+ The following shows a submodule assigning a freeform type that allows arbitrary attributes with <literal>str</literal> values below <literal>settings</literal>, but also declares an option for the <literal>settings.port</literal> attribute to have it type-checked and assign a default value. See <xref linkend="ex-settings-typed-attrs"/> for a more complete example.
+ </para>
+ <programlisting>
+{ lib, config, ... }: {
+
+ options.settings = lib.mkOption {
+ type = lib.types.submodule {
+
+ freeformType = with lib.types; attrsOf str;
+
+ # We want this attribute to be checked for the correct type
+ options.port = lib.mkOption {
+ type = lib.types.port;
+ # Declaring the option also allows defining a default value
+ default = 8080;
+ };
+
+ };
+ };
+}
+ </programlisting>
+ <para>
+ And the following shows what such a module then allows
+ </para>
+ <programlisting>
+{
+ # Not a declared option, but the freeform type allows this
+ settings.logLevel = "debug";
+
+ # Not allowed because the the freeform type only allows strings
+ # settings.enable = true;
+
+ # Allowed because there is a port option declared
+ settings.port = 80;
+
+ # Not allowed because the port option doesn't allow strings
+ # settings.port = "443";
+}
+ </programlisting>
+ </example>
+ <note>
+ <para>
+ Freeform attributes cannot depend on other attributes of the same set without infinite recursion:
+<programlisting>
+{
+ # This throws infinite recursion encountered
+ settings.logLevel = lib.mkIf (config.settings.port == 80) "debug";
+}
+</programlisting>
+ To prevent this, declare options for all attributes that need to depend on others. For above example this means to declare <literal>logLevel</literal> to be an option.
+ </para>
+ </note>
+</section>
diff --git a/nixpkgs/nixos/doc/manual/development/option-types.xml b/nixpkgs/nixos/doc/manual/development/option-types.xml
index 957349ad181..5a6dae6e991 100644
--- a/nixpkgs/nixos/doc/manual/development/option-types.xml
+++ b/nixpkgs/nixos/doc/manual/development/option-types.xml
@@ -387,17 +387,6 @@
</varlistentry>
<varlistentry>
<term>
- <varname>types.loaOf</varname> <replaceable>t</replaceable>
- </term>
- <listitem>
- <para>
- An attribute set or a list of <replaceable>t</replaceable> type. Multiple
- definitions are merged according to the value.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>
<varname>types.nullOr</varname> <replaceable>t</replaceable>
</term>
<listitem>
diff --git a/nixpkgs/nixos/doc/manual/development/releases.xml b/nixpkgs/nixos/doc/manual/development/releases.xml
index 8abc66dfec1..cd68a428a6f 100755
--- a/nixpkgs/nixos/doc/manual/development/releases.xml
+++ b/nixpkgs/nixos/doc/manual/development/releases.xml
@@ -8,24 +8,26 @@
<title>Release process</title>
<para>
- Going through an example of releasing NixOS 17.09:
+ Going through an example of releasing NixOS 19.09:
</para>
<section xml:id="one-month-before-the-beta">
<title>One month before the beta</title>
- <itemizedlist spacing="compact">
+ <itemizedlist>
<listitem>
<para>
- Send an email to the nix-devel mailinglist as a warning about upcoming
- beta "feature freeze" in a month.
+ Create an announcement on <link xlink:href="https://discourse.nixos.org">Discourse</link> as a warning about upcoming beta <quote>feature freeze</quote> in a month. <link xlink:href="https://discourse.nixos.org/t/nixos-19-09-feature-freeze/3707">See this post as an example</link>.
</para>
</listitem>
<listitem>
<para>
- Discuss with Eelco Dolstra and the community (via IRC, ML) about what
- will reach the deadline. Any issue or Pull Request targeting the release
- should be included in the release milestone.
+ Discuss with Eelco Dolstra and the community (via IRC, ML) about what will reach the deadline. Any issue or Pull Request targeting the release should be included in the release milestone.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Remove attributes that we know we will not be able to support, especially if there is a stable alternative. E.g. Check that our Linux kernels’ <link xlink:href="https://www.kernel.org/category/releases.html">projected end-of-life</link> are after our release projected end-of-life.
</para>
</listitem>
</itemizedlist>
@@ -34,113 +36,113 @@
<section xml:id="at-beta-release-time">
<title>At beta release time</title>
- <itemizedlist spacing="compact">
+ <orderedlist>
<listitem>
<para>
- <link xlink:href="https://github.com/NixOS/nixpkgs/issues/13559">Create
- an issue for tracking Zero Hydra Failures progress. ZHF is an effort to
- get build failures down to zero.</link>
+ From the master branch run:
</para>
+<programlisting>
+git checkout -b release-19.09
+</programlisting>
</listitem>
<listitem>
<para>
- <literal>git tag -a -s -m &quot;Release 17.09-beta&quot; 17.09-beta
- &amp;&amp; git push origin 17.09-beta</literal>
+ <link xlink:href="https://github.com/NixOS/nixpkgs/commit/10e61bf5be57736035ec7a804cb0bf3d083bf2cf#diff-9c798092bac0caeb5c52d509be0ca263R69">Bump the <literal>system.defaultChannel</literal> attribute in <literal>nixos/modules/misc/version.nix</literal></link>
</para>
</listitem>
<listitem>
<para>
- From the master branch run <literal>git checkout -b
- release-17.09</literal>.
+ <link xlink:href="https://github.com/NixOS/nixpkgs/commit/10e61bf5be57736035ec7a804cb0bf3d083bf2cf#diff-831e8d9748240fb23e6734fdc2a6d16eR15">Update <literal>versionSuffix</literal> in <literal>nixos/release.nix</literal></link>
</para>
</listitem>
+ </orderedlist>
+
+ <para>
+ To get the commit count, use the following command:
+ </para>
+
+<programlisting>
+git rev-list --count release-19.09
+</programlisting>
+
+ <orderedlist>
<listitem>
<para>
- <link xlink:href="https://github.com/NixOS/nixos-org-configurations/pull/18">
- Make sure a channel is created at https://nixos.org/channels/. </link>
+ Edit changelog at <literal>nixos/doc/manual/release-notes/rl-1909.xml</literal>.
</para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ Get all new NixOS modules:
+ </para>
+<programlisting>
+git diff release-19.03..release-19.09 nixos/modules/module-list.nix | grep ^+
+</programlisting>
+ </listitem>
+ <listitem>
+ <para>
+ Note systemd, kernel, glibc, desktop environment, and Nix upgrades.
+ </para>
+ </listitem>
+ </itemizedlist>
</listitem>
<listitem>
<para>
- <link xlink:href="https://github.com/NixOS/nixpkgs/compare/bdf161ed8d21...6b63c4616790">
- Bump the <literal>system.defaultChannel</literal> attribute in
- <literal>nixos/modules/misc/version.nix</literal> </link>
+ Tag the release:
</para>
+<programlisting>
+git tag --annotate --message="Release 19.09-beta" 19.09-beta
+git push upstream 19.09-beta
+</programlisting>
</listitem>
<listitem>
<para>
- <link xlink:href="https://github.com/NixOS/nixpkgs/commit/d6b08acd1ccac0d9d502c4b635e00b04d3387f06">
- Update <literal>versionSuffix</literal> in
- <literal>nixos/release.nix</literal></link>, use
- <literal>git rev-list --count 17.09-beta</literal>
- to get the commit count.
+ <link xlink:href="https://github.com/NixOS/nixpkgs/commit/01268fda85b7eee4e462c873d8654f975067731f#diff-2bc0e46110b507d6d5a344264ef15adaR1">On the <literal>master</literal> branch, increment the <literal>.version</literal> file</link>
</para>
+<programlisting>
+echo -n "20.03" > .version
+</programlisting>
</listitem>
<listitem>
<para>
- <literal>echo -n &quot;18.03&quot; &gt; .version</literal> on master.
+ <link xlink:href="https://github.com/NixOS/nixpkgs/commit/01268fda85b7eee4e462c873d8654f975067731f#diff-03f3d41b68f62079c55001f1a1c55c1dR137">Update <literal>codeName</literal> in <literal>lib/trivial.nix</literal></link> This will be the name for the next release.
</para>
</listitem>
<listitem>
<para>
- <link xlink:href="https://github.com/NixOS/nixpkgs/commit/b8a4095003e27659092892a4708bb3698231a842">
- Pick a new name for the unstable branch. </link>
+ <link xlink:href="https://github.com/NixOS/nixpkgs/commit/01268fda85b7eee4e462c873d8654f975067731f#diff-e7ee5ff686cdcc513ca089d6e5682587R11">Create a new release notes file for the upcoming release + 1</link>, in our case this is <literal>rl-2003.xml</literal>.
</para>
</listitem>
<listitem>
<para>
- Create a new release notes file for the upcoming release + 1, in this
- case <literal>rl-1803.xml</literal>.
+ Contact the infrastructure team to create the necessary Hydra Jobsets.
</para>
</listitem>
<listitem>
<para>
- Create two Hydra jobsets: release-17.09 and release-17.09-small with
- <literal>stableBranch</literal> set to false.
+ <link xlink:href="https://github.com/NixOS/nixos-org-configurations/blob/master/channels.nix">Create a channel at https://nixos.org/channels by creating a PR to nixos-org-configurations, changing <literal>channels.nix</literal></link>
</para>
</listitem>
<listitem>
<para>
- Remove attributes that we know we will not be able to support,
- especially if there is a stable alternative. E.g. Check that our
- Linux kernels'
- <link xlink:href="https://www.kernel.org/category/releases.html">
- projected end-of-life</link> are after our release projected
- end-of-life
+ Get all Hydra jobsets for the release to have their first evaluation.
</para>
</listitem>
<listitem>
<para>
- Edit changelog at
- <literal>nixos/doc/manual/release-notes/rl-1709.xml</literal> (double
- check desktop versions are noted)
+ <link xlink:href="https://github.com/NixOS/nixpkgs/issues/13559">Create an issue for tracking Zero Hydra Failures progress. ZHF is an effort to get build failures down to zero.</link>
</para>
- <itemizedlist spacing="compact">
- <listitem>
- <para>
- Get all new NixOS modules <literal>git diff
- release-17.03..release-17.09 nixos/modules/module-list.nix|grep
- ^+</literal>
- </para>
- </listitem>
- <listitem>
- <para>
- Note systemd, kernel, glibc and Nix upgrades.
- </para>
- </listitem>
- </itemizedlist>
</listitem>
- </itemizedlist>
+ </orderedlist>
</section>
<section xml:id="during-beta">
<title>During Beta</title>
- <itemizedlist spacing="compact">
+ <itemizedlist>
<listitem>
<para>
- Monitor the master branch for bugfixes and minor updates and cherry-pick
- them to the release branch.
+ Monitor the master branch for bugfixes and minor updates and cherry-pick them to the release branch.
</para>
</listitem>
</itemizedlist>
@@ -149,7 +151,7 @@
<section xml:id="before-the-final-release">
<title>Before the final release</title>
- <itemizedlist spacing="compact">
+ <itemizedlist>
<listitem>
<para>
Re-check that the release notes are complete.
@@ -157,21 +159,17 @@
</listitem>
<listitem>
<para>
- Release Nix (currently only Eelco Dolstra can do that).
- <link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/installer/tools/nix-fallback-paths.nix">
- Make sure fallback is updated. </link>
+ Release Nix (currently only Eelco Dolstra can do that). <link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/installer/tools/nix-fallback-paths.nix">Make sure fallback is updated.</link>
</para>
</listitem>
<listitem>
<para>
- <link xlink:href="https://github.com/NixOS/nixpkgs/commit/40fd9ae3ac8048758abdcfc7d28a78b5f22fe97e">
- Update README.md with new stable NixOS version information. </link>
+ <link xlink:href="https://github.com/NixOS/nixpkgs/commit/40fd9ae3ac8048758abdcfc7d28a78b5f22fe97e">Update README.md with new stable NixOS version information.</link>
</para>
</listitem>
<listitem>
<para>
- Change <literal>stableBranch</literal> to <literal>true</literal> in Hydra and wait for
- the channel to update.
+ Change <literal>stableBranch</literal> to <literal>true</literal> in Hydra and wait for the channel to update.
</para>
</listitem>
</itemizedlist>
@@ -180,76 +178,143 @@
<section xml:id="at-final-release-time">
<title>At final release time</title>
- <itemizedlist spacing="compact">
+ <orderedlist>
<listitem>
<para>
- <literal>git tag -s -a -m &quot;Release 15.09&quot; 15.09</literal>
+ Update <xref linkend="sec-upgrading" /> section of the manual to match new stable release version.
</para>
</listitem>
<listitem>
<para>
- Update "Chapter 4. Upgrading NixOS" section of the manual to match
- new stable release version.
+ Update <literal>rl-1909.xml</literal> with the release date.
</para>
</listitem>
<listitem>
<para>
- Update the
- <link xlink:href="https://github.com/NixOS/nixos-homepage/commit/2a37975d5a617ecdfca94696242b6f32ffcba9f1"><code>NIXOS_SERIES</code></link>
- in the
- <link xlink:href="https://github.com/NixOS/nixos-homepage">nixos-homepage</link>
- repository.
+ Tag the final release
</para>
+<programlisting>
+git tag --annotate --message="Release 19.09" 19.09
+git push upstream 19.09
+</programlisting>
+ </listitem>
+ <listitem>
+ <para>
+ Update <link xlink:href="https://github.com/NixOS/nixos-homepage">nixos-homepage</link> for the release.
+ </para>
+ <orderedlist>
+ <listitem>
+ <para>
+ <link xlink:href="https://github.com/NixOS/nixos-homepage/blob/47ac3571c4d71e841fd4e6c6e1872e762b9c4942/Makefile#L1">Update <literal>NIXOS_SERIES</literal> in the <literal>Makefile</literal></link>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <link xlink:href="https://github.com/NixOS/nixos-homepage/blob/47ac3571c4d71e841fd4e6c6e1872e762b9c4942/nixos-release.tt#L1">Update <literal>nixos-release.tt</literal> with the new NixOS version</link>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <link xlink:href="https://github.com/NixOS/nixos-homepage/blob/47ac3571c4d71e841fd4e6c6e1872e762b9c4942/flake.nix#L10">Update the <literal>flake.nix</literal> input <literal>released-nixpkgs</literal> to 19.09</link>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Run <literal>./update.sh</literal> (this updates flake.lock to updated channel).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <link xlink:href="https://github.com/NixOS/nixos-homepage/blob/a5626c71c03a2dd69086564e56f1a230a2bb177a/logo/nixos-logo-19.09-loris-lores.png">Add a compressed version of the NixOS logo for 19.09</link>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <link xlink:href="https://github.com/NixOS/nixos-homepage/commit/a5626c71c03a2dd69086564e56f1a230a2bb177a#diff-9cdc6434d3e4fd93a6e5bb0a531a7c71R5">Compose a news item for the website RSS feed</link>.
+ </para>
+ </listitem>
+ </orderedlist>
</listitem>
<listitem>
<para>
- Get number of commits for the release: <literal>git log
- release-14.04..release-14.12 --format=%an|wc -l</literal>
+ Create a new topic on <link xlink:href="https://discourse.nixos.org/">the Discourse instance</link> to announce the release.
</para>
</listitem>
+ </orderedlist>
+
+ <para>
+ You should include the following information:
+ </para>
+
+ <itemizedlist>
<listitem>
<para>
- Commits by contributor: <literal>git log release-14.04..release-14.12
- --format=%an|sort|uniq -c|sort -rn</literal>
+ Number of commits for the release:
</para>
+<programlisting>
+bash git log release-19.03..release-19.09 --format=%an | wc -l
+</programlisting>
</listitem>
<listitem>
<para>
- Create a new topic on <link xlink:href="https://discourse.nixos.org/">the
- Discourse instance</link> to announce the release with the above information.
- Best to check how previous email was formulated to see what needs to be
- included.
+ Commits by contributor:
</para>
+<programlisting>
+git shortlog --summary --numbered release-19.03..release-19.09
+</programlisting>
</listitem>
</itemizedlist>
+
+ <para>
+ Best to check how the previous post was formulated to see what needs to be included.
+ </para>
</section>
</section>
- <section xml:id="release-managers">
+ <section xml:id="release-management-team">
<title>Release Management Team</title>
+
<para>
- For each release there are two release managers. After each release the
- release manager having managed two releases steps down and the release
- management team of the last release appoints a new release manager.
+ For each release there are two release managers. After each release the release manager having managed two releases steps down and the release management team of the last release appoints a new release manager.
</para>
+
<para>
- This makes sure a release management team always consists of one release
- manager who already has managed one release and one release manager being
- introduced to their role, making it easier to pass on knowledge and
- experience.
+ This makes sure a release management team always consists of one release manager who already has managed one release and one release manager being introduced to their role, making it easier to pass on knowledge and experience.
</para>
+
<para>
- Release managers for the current NixOS release are tracked by GitHub team
- <link xlink:href="https://github.com/orgs/NixOS/teams/nixos-release-managers/members"><literal>@NixOS/nixos-release-managers</literal></link>.
+ Release managers for the current NixOS release are tracked by GitHub team <link xlink:href="https://github.com/orgs/NixOS/teams/nixos-release-managers/members"><literal>@NixOS/nixos-release-managers</literal></link>.
</para>
+
<para>
- A release manager's role and responsibilities are:
+ A release manager’s role and responsibilities are:
</para>
+
<itemizedlist>
- <listitem><para>manage the release process</para></listitem>
- <listitem><para>start discussions about features and changes for a given release</para></listitem>
- <listitem><para>create a roadmap</para></listitem>
- <listitem><para>release in cooperation with Eelco Dolstra</para></listitem>
- <listitem><para>decide which bug fixes, features, etc... get backported after a release</para></listitem>
+ <listitem>
+ <para>
+ manage the release process
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ start discussions about features and changes for a given release
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ create a roadmap
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ release in cooperation with Eelco Dolstra
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ decide which bug fixes, features, etc… get backported after a release
+ </para>
+ </listitem>
</itemizedlist>
</section>
<section xml:id="release-schedule">
diff --git a/nixpkgs/nixos/doc/manual/development/settings-options.xml b/nixpkgs/nixos/doc/manual/development/settings-options.xml
index 84895adb444..c99c3af92f8 100644
--- a/nixpkgs/nixos/doc/manual/development/settings-options.xml
+++ b/nixpkgs/nixos/doc/manual/development/settings-options.xml
@@ -137,7 +137,7 @@ in {
description = ''
Configuration for foo, see
&lt;link xlink:href="https://example.com/docs/foo"/&gt;
- for supported values.
+ for supported settings.
'';
};
};
@@ -167,13 +167,50 @@ in {
# We know that the `user` attribute exists because we set a default value
# for it above, allowing us to use it without worries here
- users.users.${cfg.settings.user} = {}
+ users.users.${cfg.settings.user} = {};
# ...
};
}
</programlisting>
</example>
+ <section xml:id="sec-settings-attrs-options">
+ <title>Option declarations for attributes</title>
+ <para>
+ Some <literal>settings</literal> attributes may deserve some extra care. They may need a different type, default or merging behavior, or they are essential options that should show their documentation in the manual. This can be done using <xref linkend='sec-freeform-modules'/>.
+ <example xml:id="ex-settings-typed-attrs">
+ <title>Declaring a type-checked <literal>settings</literal> attribute</title>
+ <para>
+ We extend above example using freeform modules to declare an option for the port, which will enforce it to be a valid integer and make it show up in the manual.
+ </para>
+<programlisting>
+settings = lib.mkOption {
+ type = lib.types.submodule {
+
+ freeformType = settingsFormat.type;
+
+ # Declare an option for the port such that the type is checked and this option
+ # is shown in the manual.
+ options.port = lib.mkOption {
+ type = lib.types.port;
+ default = 8080;
+ description = ''
+ Which port this service should listen on.
+ '';
+ };
+
+ };
+ default = {};
+ description = ''
+ Configuration for Foo, see
+ &lt;link xlink:href="https://example.com/docs/foo"/&gt;
+ for supported values.
+ '';
+};
+</programlisting>
+ </example>
+ </para>
+ </section>
</section>
</section>
diff --git a/nixpkgs/nixos/doc/manual/development/writing-modules.xml b/nixpkgs/nixos/doc/manual/development/writing-modules.xml
index 602f134f9cb..d244356dbed 100644
--- a/nixpkgs/nixos/doc/manual/development/writing-modules.xml
+++ b/nixpkgs/nixos/doc/manual/development/writing-modules.xml
@@ -183,5 +183,6 @@ in {
<xi:include href="meta-attributes.xml" />
<xi:include href="importing-modules.xml" />
<xi:include href="replace-modules.xml" />
+ <xi:include href="freeform-modules.xml" />
<xi:include href="settings-options.xml" />
</chapter>
diff --git a/nixpkgs/nixos/doc/manual/installation/changing-config.xml b/nixpkgs/nixos/doc/manual/installation/changing-config.xml
index 48193d986ab..4288806d5eb 100644
--- a/nixpkgs/nixos/doc/manual/installation/changing-config.xml
+++ b/nixpkgs/nixos/doc/manual/installation/changing-config.xml
@@ -78,7 +78,7 @@
<literal>mutableUsers = false</literal>. Another way is to temporarily add
the following to your configuration:
<screen>
-<link linkend="opt-users.users._name__.initialHashedPassword">users.users.your-user.initialHashedPassword</link> = "test";
+<link linkend="opt-users.users._name_.initialHashedPassword">users.users.your-user.initialHashedPassword</link> = "test";
</screen>
<emphasis>Important:</emphasis> delete the $hostname.qcow2 file if you have
started the virtual machine at least once without the right users, otherwise
diff --git a/nixpkgs/nixos/doc/manual/installation/installing-from-other-distro.xml b/nixpkgs/nixos/doc/manual/installation/installing-from-other-distro.xml
index 45d68f8787f..d2d1245c57a 100644
--- a/nixpkgs/nixos/doc/manual/installation/installing-from-other-distro.xml
+++ b/nixpkgs/nixos/doc/manual/installation/installing-from-other-distro.xml
@@ -211,7 +211,7 @@ nixpkgs https://nixos.org/channels/nixpkgs-unstable</screen>
use <literal>sudo</literal>)
</para>
<programlisting>
-<link linkend="opt-users.users._name__.initialHashedPassword">users.users.root.initialHashedPassword</link> = "";
+<link linkend="opt-users.users._name_.initialHashedPassword">users.users.root.initialHashedPassword</link> = "";
</programlisting>
</listitem>
<listitem>
diff --git a/nixpkgs/nixos/doc/manual/installation/installing.xml b/nixpkgs/nixos/doc/manual/installation/installing.xml
index 5f216df66f8..6df1d830348 100644
--- a/nixpkgs/nixos/doc/manual/installation/installing.xml
+++ b/nixpkgs/nixos/doc/manual/installation/installing.xml
@@ -70,9 +70,13 @@
<para>
If you would like to continue the installation from a different machine you
- need to activate the SSH daemon via <command>systemctl start
- sshd</command>. You then must set a password for either <literal>root</literal> or
- <literal>nixos</literal> with <command>passwd</command> to be able to login.
+ can use activated SSH daemon. You need to copy your ssh key to either
+ <literal>/home/nixos/.ssh/authorized_keys</literal> or
+ <literal>/root/.ssh/authorized_keys</literal> (Tip: For installers with a
+ modifiable filesystem such as the sd-card installer image a key can be manually
+ placed by mounting the image on a different machine). Alternatively you must set
+ a password for either <literal>root</literal> or <literal>nixos</literal> with
+ <command>passwd</command> to be able to login.
</para>
</section>
</section>
@@ -550,7 +554,7 @@ Retype new UNIX password: ***</screen>
# Note: setting fileSystems is generally not
# necessary, since nixos-generate-config figures them out
# automatically in hardware-configuration.nix.
- #<link linkend="opt-fileSystems._name__.device">fileSystems."/".device</link> = "/dev/disk/by-label/nixos";
+ #<link linkend="opt-fileSystems._name_.device">fileSystems."/".device</link> = "/dev/disk/by-label/nixos";
# Enable the OpenSSH server.
services.sshd.enable = true;
diff --git a/nixpkgs/nixos/doc/manual/man-nixos-enter.xml b/nixpkgs/nixos/doc/manual/man-nixos-enter.xml
index c32e1c7f8ca..f533d66099d 100644
--- a/nixpkgs/nixos/doc/manual/man-nixos-enter.xml
+++ b/nixpkgs/nixos/doc/manual/man-nixos-enter.xml
@@ -136,7 +136,7 @@
<filename>/mnt</filename>:
</para>
<screen>
-# nixos-enter /mnt
+# nixos-enter --root /mnt
</screen>
<para>
Run a shell command:
diff --git a/nixpkgs/nixos/doc/manual/man-nixos-install.xml b/nixpkgs/nixos/doc/manual/man-nixos-install.xml
index 84849282e9a..b205e230968 100644
--- a/nixpkgs/nixos/doc/manual/man-nixos-install.xml
+++ b/nixpkgs/nixos/doc/manual/man-nixos-install.xml
@@ -46,6 +46,10 @@
</arg>
<arg>
+ <option>--flake</option> <replaceable>flake-uri</replaceable>
+ </arg>
+
+ <arg>
<arg choice='plain'>
<option>--channel</option>
</arg>
@@ -200,6 +204,18 @@
</listitem>
</varlistentry>
<varlistentry>
+ <term>
+ <option>--flake</option> <replaceable>flake-uri</replaceable>#<replaceable>name</replaceable>
+ </term>
+ <listitem>
+ <para>
+ Build the NixOS system from the specified flake.
+ The flake must contain an output named
+ <literal>nixosConfigurations.<replaceable>name</replaceable></literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term>
<option>--channel</option>
</term>
diff --git a/nixpkgs/nixos/doc/manual/man-nixos-rebuild.xml b/nixpkgs/nixos/doc/manual/man-nixos-rebuild.xml
index f70f08a0f8a..7dab5c69dfb 100644
--- a/nixpkgs/nixos/doc/manual/man-nixos-rebuild.xml
+++ b/nixpkgs/nixos/doc/manual/man-nixos-rebuild.xml
@@ -521,7 +521,7 @@
<varlistentry>
<term>
- <option>--flake</option> <replaceable>flake-uri</replaceable>[<replaceable>name</replaceable>]
+ <option>--flake</option> <replaceable>flake-uri</replaceable><optional>#<replaceable>name</replaceable></optional>
</term>
<listitem>
<para>
diff --git a/nixpkgs/nixos/doc/manual/release-notes/release-notes.xml b/nixpkgs/nixos/doc/manual/release-notes/release-notes.xml
index e2913b8a535..bf18457c2b3 100644
--- a/nixpkgs/nixos/doc/manual/release-notes/release-notes.xml
+++ b/nixpkgs/nixos/doc/manual/release-notes/release-notes.xml
@@ -8,6 +8,7 @@
This section lists the release notes for each stable version of NixOS and
current unstable revision.
</para>
+ <xi:include href="rl-2103.xml" />
<xi:include href="rl-2009.xml" />
<xi:include href="rl-2003.xml" />
<xi:include href="rl-1909.xml" />
diff --git a/nixpkgs/nixos/doc/manual/release-notes/rl-2003.xml b/nixpkgs/nixos/doc/manual/release-notes/rl-2003.xml
index 0e9ba027a38..87f12285619 100644
--- a/nixpkgs/nixos/doc/manual/release-notes/rl-2003.xml
+++ b/nixpkgs/nixos/doc/manual/release-notes/rl-2003.xml
@@ -796,7 +796,7 @@ users.users.me =
or any other display manager in NixOS as they all support auto-login. If you used this module specifically
because it permitted root auto-login you can override the lightdm-autologin pam module like:
<programlisting>
-<link xlink:href="#opt-security.pam.services._name__.text">security.pam.services.lightdm-autologin.text</link> = lib.mkForce ''
+<link xlink:href="#opt-security.pam.services._name_.text">security.pam.services.lightdm-autologin.text</link> = lib.mkForce ''
auth requisite pam_nologin.so
auth required pam_succeed_if.so quiet
auth required pam_permit.so
diff --git a/nixpkgs/nixos/doc/manual/release-notes/rl-2009.xml b/nixpkgs/nixos/doc/manual/release-notes/rl-2009.xml
index a14ca76cf9b..0f5df907d88 100644
--- a/nixpkgs/nixos/doc/manual/release-notes/rl-2009.xml
+++ b/nixpkgs/nixos/doc/manual/release-notes/rl-2009.xml
@@ -28,6 +28,12 @@
</listitem>
<listitem>
<para>
+ Quickly configure a complete, private, self-hosted video
+ conferencing solution with the new Jitsi Meet module.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
<package>maxx</package> package removed along with <varname>services.xserver.desktopManager.maxx</varname> module.
Please migrate to <package>cdesktopenv</package> and <varname>services.xserver.desktopManager.cde</varname> module.
</para>
@@ -44,6 +50,11 @@
</listitem>
<listitem>
<para>
+ PHP 7.2 is no longer supported due to upstream not supporting this version for the entire lifecycle of the 20.09 release.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
Python 3 now defaults to Python 3.8 instead of 3.7.
</para>
</listitem>
@@ -109,10 +120,21 @@ systemd.services.mysql.serviceConfig.ProtectHome = lib.mkForce "read-only";
systemd.services.mysql.serviceConfig.ReadWritePaths = [ "/var/data" ];
</programlisting>
</para>
+ <para>
+ The MySQL service no longer runs its <literal>systemd</literal> service startup script as <literal>root</literal> anymore. A dedicated non <literal>root</literal>
+ super user account is required for operation. This means users with an existing MySQL or MariaDB database server are required to run the following SQL statements
+ as a super admin user before upgrading:
+<programlisting>
+CREATE USER IF NOT EXISTS 'mysql'@'localhost' identified with unix_socket;
+GRANT ALL PRIVILEGES ON *.* TO 'mysql'@'localhost' WITH GRANT OPTION;
+</programlisting>
+ If you use MySQL instead of MariaDB please replace <literal>unix_socket</literal> with <literal>auth_socket</literal>. If you have changed the value of <xref linkend="opt-services.mysql.user"/>
+ from the default of <literal>mysql</literal> to a different user please change <literal>'mysql'@'localhost'</literal> to the corresponding user instead.
+ </para>
</listitem>
<listitem>
<para>
- Two new option <link linkend="opt-documentation.man.generateCaches">documentation.man.generateCaches</link>
+ The new option <link linkend="opt-documentation.man.generateCaches">documentation.man.generateCaches</link>
has been added to automatically generate the <literal>man-db</literal> caches, which are needed by utilities
like <command>whatis</command> and <command>apropos</command>. The caches are generated during the build of
the NixOS configuration: since this can be expensive when a large number of packages are installed, the
@@ -121,7 +143,7 @@ systemd.services.mysql.serviceConfig.ReadWritePaths = [ "/var/data" ];
</listitem>
<listitem>
<para>
- <varname>services.postfix.sslCACert</varname> was replaced by <varname>services.postfix.tlsTrustedAuthorities</varname> which now defaults to system certifcate authorities.
+ <varname>services.postfix.sslCACert</varname> was replaced by <varname>services.postfix.tlsTrustedAuthorities</varname> which now defaults to system certificate authorities.
</para>
</listitem>
<listitem>
@@ -140,6 +162,64 @@ systemd.services.mysql.serviceConfig.ReadWritePaths = [ "/var/data" ];
Support for built-in LCDs in various pieces of Logitech hardware (keyboards and USB speakers). <varname>hardware.logitech.lcd.enable</varname> enables support for all hardware supported by the g15daemon project.
</para>
</listitem>
+ <listitem>
+ <para>
+ Zabbix now defaults to 5.0, updated from 4.4. Please carefully read through
+ <link xlink:href="https://www.zabbix.com/documentation/current/manual/installation/upgrade/sources">the upgrade guide</link>
+ and apply any changes required. Be sure to take special note of the section on
+ <link xlink:href="https://www.zabbix.com/documentation/current/manual/installation/upgrade_notes_500#enabling_extended_range_of_numeric_float_values">enabling extended range of numeric (float) values</link>
+ as you will need to apply this database migration manually.
+ </para>
+ <para>
+ If you are using Zabbix Server with a MySQL or MariaDB database you should note that using a character set of <literal>utf8</literal> and a collate of <literal>utf8_bin</literal> has become mandatory with
+ this release. See the upstream <link xlink:href="https://support.zabbix.com/browse/ZBX-17357">issue</link> for further discussion. Before upgrading you should check the character set and collation used by
+ your database and ensure they are correct:
+<programlisting>
+ SELECT
+ default_character_set_name,
+ default_collation_name
+ FROM
+ information_schema.schemata
+ WHERE
+ schema_name = 'zabbix';
+</programlisting>
+ If these values are not correct you should take a backup of your database and convert the character set and collation as required. Here is an
+ <link xlink:href="https://www.zabbix.com/forum/zabbix-help/396573-reinstall-after-upgrade?p=396891#post396891">example</link> of how to do so, taken from
+ the Zabbix forums:
+<programlisting>
+ ALTER DATABASE `zabbix` DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
+
+ -- the following will produce a list of SQL commands you should subsequently execute
+ SELECT CONCAT("ALTER TABLE ", TABLE_NAME," CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin;") AS ExecuteTheString
+ FROM information_schema.`COLUMNS`
+ WHERE table_schema = "zabbix" AND COLLATION_NAME = "utf8_general_ci";
+</programlisting>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The NixOS module system now supports freeform modules as a mix between <literal>types.attrsOf</literal> and <literal>types.submodule</literal>. These allow you to explicitly declare a subset of options while still permitting definitions without an associated option. See <xref linkend='sec-freeform-modules'/> for how to use them.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The GRUB module gained support for basic password protection, which
+ allows to restrict non-default entries in the boot menu to one or more
+ users. The users and passwords are defined via the option
+ <option>boot.loader.grub.users</option>.
+ Note: Password support is only avaiable in GRUB version 2.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Following its deprecation in 20.03, the Perl NixOS test driver has been removed.
+ All remaining tests have been ported to the Python test framework.
+ Code outside nixpkgs using <filename>make-test.nix</filename> or
+ <filename>testing.nix</filename> needs to be ported to
+ <filename>make-test-python.nix</filename> and
+ <filename>testing-python.nix</filename> respectively.
+ </para>
+ </listitem>
</itemizedlist>
</section>
@@ -159,6 +239,11 @@ systemd.services.mysql.serviceConfig.ReadWritePaths = [ "/var/data" ];
<para>
There is a new <xref linkend="opt-security.doas.enable"/> module that provides <command>doas</command>, a lighter alternative to <command>sudo</command> with many of the same features.
</para>
+ </listitem>
+ <listitem>
+ <para>
+ <link xlink:href="https://hercules-ci.com">Hercules CI</link> Agent is a specialized build agent for projects built with Nix. See the <link xlink:href="https://nixos.org/nixos/options.html#services.hercules-ci-agent">options</link> and <link xlink:href="https://docs.hercules-ci.com/hercules-ci/getting-started/#deploy-agent">setup</link>.
+ </para>
</listitem>
</itemizedlist>
@@ -183,12 +268,10 @@ systemd.services.mysql.serviceConfig.ReadWritePaths = [ "/var/data" ];
in the source tree for downloaded modules instead of using go's <link
xlink:href="https://golang.org/cmd/go/#hdr-Module_proxy_protocol">module
proxy protocol</link>. This storage format is simpler and therefore less
- likekly to break with future versions of go. As a result
+ likely to break with future versions of go. As a result
<literal>buildGoModule</literal> switched from
<literal>modSha256</literal> to the <literal>vendorSha256</literal>
- attribute to pin fetched version data. <literal>buildGoModule</literal>
- still accepts <literal>modSha256</literal> with a warning, but support will
- be removed in the next release.
+ attribute to pin fetched version data.
</para>
</listitem>
<listitem>
@@ -197,7 +280,7 @@ systemd.services.mysql.serviceConfig.ReadWritePaths = [ "/var/data" ];
<link xlink:href="https://grafana.com/docs/grafana/latest/guides/whats-new-in-v6-4/">deprecated in Grafana</link>
and the <package>phantomjs</package> project is
<link xlink:href="https://github.com/ariya/phantomjs/issues/15344#issue-302015362">currently unmaintained</link>.
- It can still be enabled by providing <literal>phantomJsSupport = true</literal> to the package instanciation:
+ It can still be enabled by providing <literal>phantomJsSupport = true</literal> to the package instantiation:
<programlisting>{
services.grafana.package = pkgs.grafana.overrideAttrs (oldAttrs: rec {
phantomJsSupport = false;
@@ -209,7 +292,7 @@ systemd.services.mysql.serviceConfig.ReadWritePaths = [ "/var/data" ];
<para>
The <link linkend="opt-services.supybot.enable">supybot</link> module now uses <literal>/var/lib/supybot</literal>
as its default <link linkend="opt-services.supybot.stateDir">stateDir</link> path if <literal>stateVersion</literal>
- is 20.09 or higher. It also enables number of
+ is 20.09 or higher. It also enables a number of
<link xlink:href="https://www.freedesktop.org/software/systemd/man/systemd.exec.html#Sandboxing">systemd sandboxing options</link>
which may possibly interfere with some plugins. If this is the case you can disable the options through attributes in
<option>systemd.services.supybot.serviceConfig</option>.
@@ -318,6 +401,20 @@ php.override {
</para>
</listitem>
<listitem>
+ <para>
+ The ACME module has been overhauled for simplicity and maintainability.
+ Cert generation now implicitly uses the <literal>acme</literal>
+ user, and the <literal>security.acme.certs._name_.user</literal> option
+ has been removed. Instead, certificate access from other services is now
+ managed through group permissions. The module no longer runs lego
+ twice under certain conditions, and will correctly renew certificates if
+ their configuration is changed. Services which reload nginx and httpd after
+ certificate renewal are now properly configured too so you no longer have
+ to do this manually if you are using HTTPS enabled virtual hosts. A mechanism
+ for regenerating certs on demand has also been added and documented.
+ </para>
+ </listitem>
+ <listitem>
<para>
Gollum received a major update to version 5.x and you may have to change
some links in your wiki when migrating from gollum 4.x. More information
@@ -336,8 +433,8 @@ php.override {
</listitem>
<listitem>
<para>
- Add option <literal>services.nginx.enableSandbox</literal> to starting Nginx web server with additional sandbox/hardening options.
- By default, write access to <literal>services.nginx.stateDir</literal> is allowed. To allow writing to other folders,
+ Nginx web server now starting with additional sandbox/hardening options. By default, write access
+ to <literal>services.nginx.stateDir</literal> is allowed. To allow writing to other folders,
use <literal>systemd.services.nginx.serviceConfig.ReadWritePaths</literal>
<programlisting>
systemd.services.nginx.serviceConfig.ReadWritePaths = [ "/var/www" ];
@@ -523,6 +620,46 @@ systemd.services.nginx.serviceConfig.ReadWritePaths = [ "/var/www" ];
<listitem>
<para>
In the <literal>resilio</literal> module, <xref linkend="opt-services.resilio.httpListenAddr"/> has been changed to listen to <literal>[::1]</literal> instead of <literal>0.0.0.0</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Users of <link xlink:href="http://openafs.org">OpenAFS 1.6</link> must
+ upgrade their services to OpenAFS 1.8! In this release, the OpenAFS package
+ version 1.6.24 is marked broken but can be used during transition to
+ OpenAFS 1.8.x. Use the options
+ <option>services.openafsClient.packages.module</option>,
+ <option>services.openafsClient.packages.programs</option> and
+ <option>services.openafsServer.package</option> to select a different
+ OpenAFS package. OpenAFS 1.6 will be removed in the next release. The
+ package <literal>openafs</literal> and the service options will then
+ silently point to the OpenAFS 1.8 release.
+ </para>
+ <para>
+ See also the OpenAFS <link
+ xlink:href="http://docs.openafs.org/AdminGuide/index.html">Administrator
+ Guide</link> for instructions. Beware of the following when updating
+ servers:
+ <itemizedlist>
+ <listitem>
+ <para>
+ The storage format of the server key has changed and the key must be converted before running the new release.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ When updating multiple database servers, turn off the database servers
+ from the highest IP down to the lowest with resting periods in
+ between. Start up in reverse order. Do not concurrently run database
+ servers working with different OpenAFS releases!
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Update servers first, then clients.
+ </para>
+ </listitem>
+ </itemizedlist>
</para>
</listitem>
<listitem>
@@ -593,6 +730,104 @@ systemd.services.nginx.serviceConfig.ReadWritePaths = [ "/var/www" ];
When updating Graylog from a version before 3.3.3 make sure to check the Graylog <link xlink:href="https://www.graylog.org/post/announcing-graylog-v3-3-3">release info</link> for information on how to avoid the issue.
</para>
</listitem>
+ <listitem>
+ <para>
+ The <literal>dokuwiki</literal> module has changed to multi-instance, using submodules.
+ Therefore, it is now mandatory to name each instance. Moreover, forcing SSL by default has been dropped, so
+ <literal>nginx.forceSSL</literal> and <literal>nginx.enableACME</literal> are no longer set to <literal>true</literal>.
+ To continue using your service with the original SSL settings, you have to adjust the original config, e.g.:
+<programlisting>
+services.dokuwiki = {
+ enable = true;
+ ...
+};
+</programlisting>
+ To something similar:
+<programlisting>
+services.dokuwiki."mywiki" = {
+ enable = true;
+ nginx = {
+ forceSSL = true;
+ enableACME = true;
+ };
+ ...
+};
+</programlisting>
+ The base package has also been upgraded to the 2020-07-29 "Hogfather" release. Plugins might be incompatible or require upgrading.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The <xref linkend="opt-services.postgresql.dataDir"/> option is now set to <literal>"/var/lib/postgresql/${cfg.package.psqlSchema}"</literal> regardless of your
+ <xref linkend="opt-system.stateVersion"/>. Users with an existing postgresql install that have a <xref linkend="opt-system.stateVersion"/> of <literal>17.03</literal> or below
+ should double check what the value of their <xref linkend="opt-services.postgresql.dataDir"/> option is (<literal>/var/db/postgresql</literal>) and then explicitly
+ set this value to maintain compatibility:
+<programlisting>
+services.postgresql.dataDir = "/var/db/postgresql";
+</programlisting>
+ </para>
+ <para>
+ The postgresql module now expects there to be a database super user account called <literal>postgres</literal> regardless of your <xref linkend="opt-system.stateVersion"/>. Users
+ with an existing postgresql install that have a <xref linkend="opt-system.stateVersion"/> of <literal>17.03</literal> or below should run the following SQL statements as a
+ database super admin user before upgrading:
+<programlisting>
+CREATE ROLE postgres LOGIN SUPERUSER;
+</programlisting>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The USBGuard module now removes options and instead hardcodes values for <literal>IPCAccessControlFiles</literal>, <literal>ruleFiles</literal>, and <literal>auditFilePath</literal>. Audit logs can be found in the journal.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The NixOS module system now evaluates option definitions more strictly, allowing it to detect a larger set of problems.
+ As a result, what previously evaluated may not do so anymore.
+ See <link xlink:href="https://github.com/NixOS/nixpkgs/pull/82743#issuecomment-674520472">the PR that changed this</link> for more info.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ For NixOS configuration options, the type <literal>loaOf</literal>, after
+ its initial deprecation in release 20.03, has been removed. In NixOS and
+ Nixpkgs options using this type have been converted to <literal>attrsOf</literal>.
+ For more information on this change have look at these links:
+ <link xlink:href="https://github.com/NixOS/nixpkgs/issues/1800">issue #1800</link>,
+ <link xlink:href="https://github.com/NixOS/nixpkgs/pull/63103">PR #63103</link>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>config.systemd.services.${name}.path</literal> now returns a list of paths instead of a colon-separated string.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Caddy module now uses Caddy v2 by default. Caddy v1 can still be used by setting
+ <xref linkend="opt-services.caddy.package"/> to <literal>pkgs.caddy1</literal>.
+ </para>
+ <para>
+ New option <xref linkend="opt-services.caddy.adapter"/> has been added.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The <link linkend="opt-services.jellyfin.enable">jellyfin</link> module will use and stay on the Jellyfin version <literal>10.5.5</literal>
+ if <literal>stateVersion</literal> is lower than <literal>20.09</literal>. This is because significant changes were made to the database schema,
+ and it is highly recommended to backup your instance before upgrading. After making your backup, you can upgrade to the latest version either by
+ setting your <literal>stateVersion</literal> to <literal>20.09</literal> or higher, or set the <option>services.jellyfin.package</option> to
+ <literal>pkgs.jellyfin</literal>. If you do not wish to upgrade Jellyfin, but want to change your <literal>stateVersion</literal>, you can set
+ the value of <option>services.jellyfin.package</option> to <literal>pkgs.jellyfin_10_5</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The <literal>security.rngd</literal> service is now disabled by default.
+ This choice was made because there's krngd in the linux kernel space making it (for most usecases)
+ functionally redundent.
+ </para>
+ </listitem>
</itemizedlist>
</section>
@@ -621,6 +856,17 @@ systemd.services.nginx.serviceConfig.ReadWritePaths = [ "/var/www" ];
of the default <literal>out</literal> output anymore - if you relied on the
<literal>notmuch-emacs-mua</literal> binary or the emacs lisp files, access them via
the <literal>notmuch.emacs</literal> output.
+
+ Device tree overlay support was improved in
+ <link xlink:href="https://github.com/NixOS/nixpkgs/pull/79370">#79370</link>
+ and now uses <xref linkend="opt-hardware.deviceTree.kernelPackage"/>
+ instead of <option>hardware.deviceTree.base</option>.
+
+ <xref linkend="opt-hardware.deviceTree.overlays"/> configuration was
+ extended to support <literal>.dts</literal> files with symbols.
+
+ Device trees can now be filtered by setting
+ <xref linkend="opt-hardware.deviceTree.filter"/> option.
</para>
</listitem>
<listitem>
@@ -630,6 +876,11 @@ systemd.services.nginx.serviceConfig.ReadWritePaths = [ "/var/www" ];
</listitem>
<listitem>
<para>
+ <literal>buildGoModule</literal> <literal>doCheck</literal> now defaults to <literal>true</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
Packages built using <literal>buildRustPackage</literal> now use <literal>release</literal>
mode for the <literal>checkPhase</literal> by default.
</para>
@@ -658,6 +909,12 @@ systemd.services.nginx.serviceConfig.ReadWritePaths = [ "/var/www" ];
</listitem>
<listitem>
<para>
+ The installer now enables sshd by default. This improves installation on headless machines especially ARM single-board-computer.
+ To login through ssh, either a password or an ssh key must be set for the root user or the nixos user.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
The scripted networking system now uses <literal>.link</literal> files in
<literal>/etc/systemd/network</literal> to configure mac address and link MTU,
instead of the sometimes buggy <literal>network-link-*</literal> units, which
@@ -687,6 +944,37 @@ systemd.services.nginx.serviceConfig.ReadWritePaths = [ "/var/www" ];
</listitem>
<listitem>
<para>
+ The <literal>services.transmission</literal> module
+ was enhanced with the new options:
+ <xref linkend="opt-services.transmission.credentialsFile"/>,
+ <xref linkend="opt-services.transmission.openFirewall"/>,
+ and <xref linkend="opt-services.transmission.performanceNetParameters"/>.
+ </para>
+ <para>
+ <literal>transmission-daemon</literal> is now started with additional systemd sandbox/hardening options for better security.
+ Please <link xlink:href="https://github.com/NixOS/nixpkgs/issues">report</link>
+ any use case where this is not working well.
+ In particular, the <literal>RootDirectory</literal> option newly set
+ forbids uploading or downloading a torrent outside of the default directory
+ configured at <link linkend="opt-services.transmission.settings">settings.download-dir</link>.
+ If you really need Transmission to access other directories,
+ you must include those directories into the <literal>BindPaths</literal> of the service:
+<programlisting>
+systemd.services.transmission.serviceConfig.BindPaths = [ "/path/to/alternative/download-dir" ];
+</programlisting>
+ </para>
+ <para>
+ Also, connection to the RPC (Remote Procedure Call) of <literal>transmission-daemon</literal>
+ is now only available on the local network interface by default.
+ Use:
+<programlisting>
+services.transmission.settings.rpc-bind-address = "0.0.0.0";
+</programlisting>
+ to get the previous behavior of listening on all network interfaces.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
With this release <literal>systemd-networkd</literal> (when enabled through <xref linkend="opt-networking.useNetworkd"/>)
has it's netlink socket created through a <literal>systemd.socket</literal> unit. This gives us control over
socket buffer sizes and other parameters. For larger setups where networkd has to create a lot of (virtual)
@@ -767,6 +1055,98 @@ systemd.services.nginx.serviceConfig.ReadWritePaths = [ "/var/www" ];
There are no functional changes, however this may require updating some configurations to use correct types for all attributes.
</para>
</listitem>
+ <listitem>
+ <para>
+ The <literal>fontconfig</literal> module stopped generating fontconfig 2.10.x config and cache.
+ Fontconfig 2.10.x was removed from Nixpkgs - it hasn't been used in any nixpkgs package anymore.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Nginx module <literal>nginxModules.fastcgi-cache-purge</literal> renamed to official name <literal>nginxModules.cache-purge</literal>.
+ Nginx module <literal>nginxModules.ngx_aws_auth</literal> renamed to official name <literal>nginxModules.aws-auth</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The option <option>defaultPackages</option> was added. It installs the packages <package>perl</package>, <package>rsync</package> and <package>strace</package> for now. They were added unconditionally to <option>systemPackages</option> before, but are not strictly necessary for a minimal NixOS install. You can set it to an empty list to have a more minimal system. Be aware that some functionality might still have an impure dependency on those packages, so things might break.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The <literal>undervolt</literal> option no longer needs to apply its
+ settings every 30s. If they still become undone, open an issue and restore
+ the previous behaviour using <literal>undervolt.useTimer</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Agda has been heavily reworked.
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>agda.mkDerivation</literal> has been heavily changed and
+ is now located at <package>agdaPackages.mkDerivation</package>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ New top-level packages <package>agda</package> and
+ <literal>agda.withPackages</literal> have been added, the second
+ of which sets up agda with access to chosen libraries.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ All agda libraries now live under
+ <literal>agdaPackages</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Many broken libraries have been removed.
+ </para>
+ </listitem>
+ </itemizedlist>
+ See the <link
+ xlink:href="https://nixos.org/nixpkgs/manual/#agda">new
+ documentation</link> for more information.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The <literal>deepin</literal> package set has been removed from
+ nixpkgs. It was a work in progress to package the
+ <link xlink:href="https://www.deepin.org/en/dde/">Deepin Desktop Environment (DDE)</link>,
+ including libraries, tools and applications, and it was still
+ missing a service to lauch the desktop environment. It has shown
+ to no longer be a feasible goal due to reasons discussed in
+ <link xlink:href="https://github.com/NixOS/nixpkgs/issues/94870">issue #94870</link>.
+ The package <literal>netease-cloud-music</literal> has also been
+ removed, as it depends on libraries from deepin.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The <literal>opendkim</literal> module now uses systemd sandboxing features
+ to limit the exposure of the system towards the opendkim service.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <itemizedlist>
+ <listitem>
+ <para />
+ <para>
+ Kubernetes has been upgraded to 1.19.1, which also means that the
+ golang version to build it has been bumped to 1.15. This may have
+ consequences for your existing clusters and their certificates. Please
+ consider
+ <link xlink:href="https://relnotes.k8s.io/?markdown=93264">
+ the release notes for Kubernetes 1.19 carefully
+ </link>
+ before upgrading.
+ </para>
+ </listitem>
</itemizedlist>
</section>
</section>
diff --git a/nixpkgs/nixos/doc/manual/release-notes/rl-2103.xml b/nixpkgs/nixos/doc/manual/release-notes/rl-2103.xml
new file mode 100644
index 00000000000..eccf2b69dad
--- /dev/null
+++ b/nixpkgs/nixos/doc/manual/release-notes/rl-2103.xml
@@ -0,0 +1,80 @@
+<section 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="sec-release-21.03">
+ <title>Release 21.03 (“Okapi”, 2021.03/??)</title>
+
+ <section 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="sec-release-21.03-highlights">
+ <title>Highlights</title>
+
+ <para>
+ In addition to numerous new and upgraded packages, this release has the
+ following highlights:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Support is planned until the end of October 2021, handing over to 21.09.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section 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="sec-release-21.03-new-services">
+ <title>New Services</title>
+
+ <para>
+ The following new services were added since the last release:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para />
+ </listitem>
+ </itemizedlist>
+
+ </section>
+
+ <section 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="sec-release-21.03-incompatibilities">
+ <title>Backward Incompatibilities</title>
+
+ <para>
+ When upgrading from a previous release, please be aware of the following
+ incompatible changes:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para />
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section 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="sec-release-21.03-notable-changes">
+ <title>Other Notable Changes</title>
+
+ <itemizedlist>
+ <listitem>
+ <para />
+ </listitem>
+ </itemizedlist>
+ </section>
+</section>
diff --git a/nixpkgs/nixos/lib/eval-config.nix b/nixpkgs/nixos/lib/eval-config.nix
index c8824c2690d..15429a7160c 100644
--- a/nixpkgs/nixos/lib/eval-config.nix
+++ b/nixpkgs/nixos/lib/eval-config.nix
@@ -24,11 +24,11 @@
check ? true
, prefix ? []
, lib ? import ../../lib
+, extraModules ? let e = builtins.getEnv "NIXOS_EXTRA_MODULE_PATH";
+ in if e == "" then [] else [(import e)]
}:
let extraArgs_ = extraArgs; pkgs_ = pkgs;
- extraModules = let e = builtins.getEnv "NIXOS_EXTRA_MODULE_PATH";
- in if e == "" then [] else [(import e)];
in
let
diff --git a/nixpkgs/nixos/lib/make-ext4-fs.nix b/nixpkgs/nixos/lib/make-ext4-fs.nix
index 74a6c134e64..33dbc8f5ec4 100644
--- a/nixpkgs/nixos/lib/make-ext4-fs.nix
+++ b/nixpkgs/nixos/lib/make-ext4-fs.nix
@@ -46,7 +46,10 @@ pkgs.stdenv.mkDerivation {
(
GLOBIGNORE=".:.."
shopt -u dotglob
- cp -a --reflink=auto ./files/* -t ./rootImage/
+
+ for f in ./files/*; do
+ cp -a --reflink=auto -t ./rootImage/ "$f"
+ done
)
# Also include a manifest of the closures in a format suitable for nix-store --load-db
diff --git a/nixpkgs/nixos/lib/make-options-doc/options-to-docbook.xsl b/nixpkgs/nixos/lib/make-options-doc/options-to-docbook.xsl
index 72ac89d4ff6..18d19fddaca 100644
--- a/nixpkgs/nixos/lib/make-options-doc/options-to-docbook.xsl
+++ b/nixpkgs/nixos/lib/make-options-doc/options-to-docbook.xsl
@@ -20,7 +20,7 @@
<title>Configuration Options</title>
<variablelist xml:id="configuration-variable-list">
<xsl:for-each select="attrs">
- <xsl:variable name="id" select="concat('opt-', str:replace(str:replace(str:replace(str:replace(attr[@name = 'name']/string/@value, '*', '_'), '&lt;', '_'), '>', '_'), '?', '_'))" />
+ <xsl:variable name="id" select="concat('opt-', str:replace(str:replace(str:replace(attr[@name = 'name']/string/@value, '*', '_'), '&lt;', '_'), '>', '_'))" />
<varlistentry>
<term xlink:href="#{$id}">
<xsl:attribute name="xml:id"><xsl:value-of select="$id"/></xsl:attribute>
diff --git a/nixpkgs/nixos/lib/qemu-flags.nix b/nixpkgs/nixos/lib/qemu-flags.nix
index 0cf6977af4b..0f066245893 100644
--- a/nixpkgs/nixos/lib/qemu-flags.nix
+++ b/nixpkgs/nixos/lib/qemu-flags.nix
@@ -22,9 +22,9 @@ rec {
else throw "Unknown QEMU serial device for system '${pkgs.stdenv.hostPlatform.system}'";
qemuBinary = qemuPkg: {
- x86_64-linux = "${qemuPkg}/bin/qemu-kvm -cpu host";
+ x86_64-linux = "${qemuPkg}/bin/qemu-kvm -cpu max";
armv7l-linux = "${qemuPkg}/bin/qemu-system-arm -enable-kvm -machine virt -cpu host";
aarch64-linux = "${qemuPkg}/bin/qemu-system-aarch64 -enable-kvm -machine virt,gic-version=host -cpu host";
- x86_64-darwin = "${qemuPkg}/bin/qemu-kvm -cpu host";
+ x86_64-darwin = "${qemuPkg}/bin/qemu-kvm -cpu max";
}.${pkgs.stdenv.hostPlatform.system} or "${qemuPkg}/bin/qemu-kvm";
}
diff --git a/nixpkgs/nixos/lib/test-driver/Logger.pm b/nixpkgs/nixos/lib/test-driver/Logger.pm
deleted file mode 100644
index a3384084a0e..00000000000
--- a/nixpkgs/nixos/lib/test-driver/Logger.pm
+++ /dev/null
@@ -1,75 +0,0 @@
-package Logger;
-
-use strict;
-use Thread::Queue;
-use XML::Writer;
-use Encode qw(decode encode);
-use Time::HiRes qw(clock_gettime CLOCK_MONOTONIC);
-
-sub new {
- my ($class) = @_;
-
- my $logFile = defined $ENV{LOGFILE} ? "$ENV{LOGFILE}" : "/dev/null";
- my $log = new XML::Writer(OUTPUT => new IO::File(">$logFile"));
-
- my $self = {
- log => $log,
- logQueue => Thread::Queue->new()
- };
-
- $self->{log}->startTag("logfile");
-
- bless $self, $class;
- return $self;
-}
-
-sub close {
- my ($self) = @_;
- $self->{log}->endTag("logfile");
- $self->{log}->end;
-}
-
-sub drainLogQueue {
- my ($self) = @_;
- while (defined (my $item = $self->{logQueue}->dequeue_nb())) {
- $self->{log}->dataElement("line", sanitise($item->{msg}), 'machine' => $item->{machine}, 'type' => 'serial');
- }
-}
-
-sub maybePrefix {
- my ($msg, $attrs) = @_;
- $msg = $attrs->{machine} . ": " . $msg if defined $attrs->{machine};
- return $msg;
-}
-
-sub nest {
- my ($self, $msg, $coderef, $attrs) = @_;
- print STDERR maybePrefix("$msg\n", $attrs);
- $self->{log}->startTag("nest");
- $self->{log}->dataElement("head", $msg, %{$attrs});
- my $now = clock_gettime(CLOCK_MONOTONIC);
- $self->drainLogQueue();
- eval { &$coderef };
- my $res = $@;
- $self->drainLogQueue();
- $self->log(sprintf("(%.2f seconds)", clock_gettime(CLOCK_MONOTONIC) - $now));
- $self->{log}->endTag("nest");
- die $@ if $@;
-}
-
-sub sanitise {
- my ($s) = @_;
- $s =~ s/[[:cntrl:]\xff]//g;
- $s = decode('UTF-8', $s, Encode::FB_DEFAULT);
- return encode('UTF-8', $s, Encode::FB_CROAK);
-}
-
-sub log {
- my ($self, $msg, $attrs) = @_;
- chomp $msg;
- print STDERR maybePrefix("$msg\n", $attrs);
- $self->drainLogQueue();
- $self->{log}->dataElement("line", $msg, %{$attrs});
-}
-
-1;
diff --git a/nixpkgs/nixos/lib/test-driver/Machine.pm b/nixpkgs/nixos/lib/test-driver/Machine.pm
deleted file mode 100644
index 4d3d63cd2db..00000000000
--- a/nixpkgs/nixos/lib/test-driver/Machine.pm
+++ /dev/null
@@ -1,734 +0,0 @@
-package Machine;
-
-use strict;
-use threads;
-use Socket;
-use IO::Handle;
-use POSIX qw(dup2);
-use FileHandle;
-use Cwd;
-use File::Basename;
-use File::Path qw(make_path);
-use File::Slurp;
-use Time::HiRes qw(clock_gettime CLOCK_MONOTONIC);
-
-
-my $showGraphics = defined $ENV{'DISPLAY'};
-
-my $sharedDir;
-
-
-sub new {
- my ($class, $args) = @_;
-
- my $startCommand = $args->{startCommand};
-
- my $name = $args->{name};
- if (!$name) {
- $startCommand =~ /run-(.*)-vm$/ if defined $startCommand;
- $name = $1 || "machine";
- }
-
- if (!$startCommand) {
- # !!! merge with qemu-vm.nix.
- my $netBackend = "-netdev user,id=net0";
- my $netFrontend = "-device virtio-net-pci,netdev=net0";
-
- $netBackend .= "," . $args->{netBackendArgs}
- if defined $args->{netBackendArgs};
-
- $netFrontend .= "," . $args->{netFrontendArgs}
- if defined $args->{netFrontendArgs};
-
- $startCommand =
- "qemu-kvm -m 384 $netBackend $netFrontend \$QEMU_OPTS ";
-
- if (defined $args->{hda}) {
- if ($args->{hdaInterface} eq "scsi") {
- $startCommand .= "-drive id=hda,file="
- . Cwd::abs_path($args->{hda})
- . ",werror=report,if=none "
- . "-device scsi-hd,drive=hda ";
- } else {
- $startCommand .= "-drive file=" . Cwd::abs_path($args->{hda})
- . ",if=" . $args->{hdaInterface}
- . ",werror=report ";
- }
- }
-
- $startCommand .= "-cdrom $args->{cdrom} "
- if defined $args->{cdrom};
- $startCommand .= "-device piix3-usb-uhci -drive id=usbdisk,file=$args->{usb},if=none,readonly -device usb-storage,drive=usbdisk "
- if defined $args->{usb};
- $startCommand .= "-bios $args->{bios} "
- if defined $args->{bios};
- $startCommand .= $args->{qemuFlags} || "";
- }
-
- my $tmpDir = $ENV{'TMPDIR'} || "/tmp";
- unless (defined $sharedDir) {
- $sharedDir = $tmpDir . "/xchg-shared";
- make_path($sharedDir, { mode => 0700, owner => $< });
- }
-
- my $allowReboot = 0;
- $allowReboot = $args->{allowReboot} if defined $args->{allowReboot};
-
- my $self = {
- startCommand => $startCommand,
- name => $name,
- allowReboot => $allowReboot,
- booted => 0,
- pid => 0,
- connected => 0,
- socket => undef,
- stateDir => "$tmpDir/vm-state-$name",
- monitor => undef,
- log => $args->{log},
- redirectSerial => $args->{redirectSerial} // 1,
- };
-
- mkdir $self->{stateDir}, 0700;
-
- bless $self, $class;
- return $self;
-}
-
-
-sub log {
- my ($self, $msg) = @_;
- $self->{log}->log($msg, { machine => $self->{name} });
-}
-
-
-sub nest {
- my ($self, $msg, $coderef, $attrs) = @_;
- $self->{log}->nest($msg, $coderef, { %{$attrs || {}}, machine => $self->{name} });
-}
-
-
-sub name {
- my ($self) = @_;
- return $self->{name};
-}
-
-
-sub stateDir {
- my ($self) = @_;
- return $self->{stateDir};
-}
-
-
-sub start {
- my ($self) = @_;
- return if $self->{booted};
-
- $self->log("starting vm");
-
- # Create a socket pair for the serial line input/output of the VM.
- my ($serialP, $serialC);
- socketpair($serialP, $serialC, PF_UNIX, SOCK_STREAM, 0) or die;
-
- # Create a Unix domain socket to which QEMU's monitor will connect.
- my $monitorPath = $self->{stateDir} . "/monitor";
- unlink $monitorPath;
- my $monitorS;
- socket($monitorS, PF_UNIX, SOCK_STREAM, 0) or die;
- bind($monitorS, sockaddr_un($monitorPath)) or die "cannot bind monitor socket: $!";
- listen($monitorS, 1) or die;
-
- # Create a Unix domain socket to which the root shell in the guest will connect.
- my $shellPath = $self->{stateDir} . "/shell";
- unlink $shellPath;
- my $shellS;
- socket($shellS, PF_UNIX, SOCK_STREAM, 0) or die;
- bind($shellS, sockaddr_un($shellPath)) or die "cannot bind shell socket: $!";
- listen($shellS, 1) or die;
-
- # Start the VM.
- my $pid = fork();
- die if $pid == -1;
-
- if ($pid == 0) {
- close $serialP;
- close $monitorS;
- close $shellS;
- if ($self->{redirectSerial}) {
- open NUL, "</dev/null" or die;
- dup2(fileno(NUL), fileno(STDIN));
- dup2(fileno($serialC), fileno(STDOUT));
- dup2(fileno($serialC), fileno(STDERR));
- }
- $ENV{TMPDIR} = $self->{stateDir};
- $ENV{SHARED_DIR} = $sharedDir;
- $ENV{USE_TMPDIR} = 1;
- $ENV{QEMU_OPTS} =
- ($self->{allowReboot} ? "" : "-no-reboot ") .
- "-monitor unix:./monitor -chardev socket,id=shell,path=./shell " .
- "-device virtio-serial -device virtconsole,chardev=shell " .
- "-device virtio-rng-pci " .
- ($showGraphics ? "-serial stdio" : "-nographic") . " " . ($ENV{QEMU_OPTS} || "");
- chdir $self->{stateDir} or die;
- exec $self->{startCommand};
- die "running VM script: $!";
- }
-
- # Process serial line output.
- close $serialC;
-
- threads->create(\&processSerialOutput, $self, $serialP)->detach;
-
- sub processSerialOutput {
- my ($self, $serialP) = @_;
- while (<$serialP>) {
- chomp;
- s/\r$//;
- print STDERR $self->{name}, "# $_\n";
- $self->{log}->{logQueue}->enqueue({msg => $_, machine => $self->{name}}); # !!!
- }
- }
-
- eval {
- local $SIG{CHLD} = sub { die "QEMU died prematurely\n"; };
-
- # Wait until QEMU connects to the monitor.
- accept($self->{monitor}, $monitorS) or die;
-
- # Wait until QEMU connects to the root shell socket. QEMU
- # does so immediately; this doesn't mean that the root shell
- # has connected yet inside the guest.
- accept($self->{socket}, $shellS) or die;
- $self->{socket}->autoflush(1);
- };
- die "$@" if $@;
-
- $self->waitForMonitorPrompt;
-
- $self->log("QEMU running (pid $pid)");
-
- $self->{pid} = $pid;
- $self->{booted} = 1;
-}
-
-
-# Send a command to the monitor and wait for it to finish. TODO: QEMU
-# also has a JSON-based monitor interface now, but it doesn't support
-# all commands yet. We should use it once it does.
-sub sendMonitorCommand {
- my ($self, $command) = @_;
- $self->log("sending monitor command: $command");
- syswrite $self->{monitor}, "$command\n";
- return $self->waitForMonitorPrompt;
-}
-
-
-# Wait until the monitor sends "(qemu) ".
-sub waitForMonitorPrompt {
- my ($self) = @_;
- my $res = "";
- my $s;
- while (sysread($self->{monitor}, $s, 1024)) {
- $res .= $s;
- last if $res =~ s/\(qemu\) $//;
- }
- return $res;
-}
-
-
-# Call the given code reference repeatedly, with 1 second intervals,
-# until it returns 1 or a timeout is reached.
-sub retry {
- my ($coderef) = @_;
- my $n;
- for ($n = 899; $n >=0; $n--) {
- return if &$coderef($n);
- sleep 1;
- }
- die "action timed out after $n seconds";
-}
-
-
-sub connect {
- my ($self) = @_;
- return if $self->{connected};
-
- $self->nest("waiting for the VM to finish booting", sub {
-
- $self->start;
-
- my $now = clock_gettime(CLOCK_MONOTONIC);
- local $SIG{ALRM} = sub { die "timed out waiting for the VM to connect\n"; };
- alarm 600;
- readline $self->{socket} or die "the VM quit before connecting\n";
- alarm 0;
-
- $self->log("connected to guest root shell");
- # We're interested in tracking how close we are to `alarm`.
- $self->log(sprintf("(connecting took %.2f seconds)", clock_gettime(CLOCK_MONOTONIC) - $now));
- $self->{connected} = 1;
-
- });
-}
-
-
-sub waitForShutdown {
- my ($self) = @_;
- return unless $self->{booted};
-
- $self->nest("waiting for the VM to power off", sub {
- waitpid $self->{pid}, 0;
- $self->{pid} = 0;
- $self->{booted} = 0;
- $self->{connected} = 0;
- });
-}
-
-
-sub isUp {
- my ($self) = @_;
- return $self->{booted} && $self->{connected};
-}
-
-
-sub execute_ {
- my ($self, $command) = @_;
-
- $self->connect;
-
- print { $self->{socket} } ("( $command ); echo '|!=EOF' \$?\n");
-
- my $out = "";
-
- while (1) {
- my $line = readline($self->{socket});
- die "connection to VM lost unexpectedly" unless defined $line;
- #$self->log("got line: $line");
- if ($line =~ /^(.*)\|\!\=EOF\s+(\d+)$/) {
- $out .= $1;
- $self->log("exit status $2");
- return ($2, $out);
- }
- $out .= $line;
- }
-}
-
-
-sub execute {
- my ($self, $command) = @_;
- my @res;
- $self->nest("running command: $command", sub {
- @res = $self->execute_($command);
- });
- return @res;
-}
-
-
-sub succeed {
- my ($self, @commands) = @_;
-
- my $res;
- foreach my $command (@commands) {
- $self->nest("must succeed: $command", sub {
- my ($status, $out) = $self->execute_($command);
- if ($status != 0) {
- $self->log("output: $out");
- die "command `$command' did not succeed (exit code $status)\n";
- }
- $res .= $out;
- });
- }
-
- return $res;
-}
-
-
-sub mustSucceed {
- succeed @_;
-}
-
-
-sub waitUntilSucceeds {
- my ($self, $command) = @_;
- $self->nest("waiting for success: $command", sub {
- retry sub {
- my ($status, $out) = $self->execute($command);
- return 1 if $status == 0;
- };
- });
-}
-
-
-sub waitUntilFails {
- my ($self, $command) = @_;
- $self->nest("waiting for failure: $command", sub {
- retry sub {
- my ($status, $out) = $self->execute($command);
- return 1 if $status != 0;
- };
- });
-}
-
-
-sub fail {
- my ($self, $command) = @_;
- $self->nest("must fail: $command", sub {
- my ($status, $out) = $self->execute_($command);
- die "command `$command' unexpectedly succeeded"
- if $status == 0;
- });
-}
-
-
-sub mustFail {
- fail @_;
-}
-
-
-sub getUnitInfo {
- my ($self, $unit, $user) = @_;
- my ($status, $lines) = $self->systemctl("--no-pager show \"$unit\"", $user);
- return undef if $status != 0;
- my $info = {};
- foreach my $line (split '\n', $lines) {
- $line =~ /^([^=]+)=(.*)$/ or next;
- $info->{$1} = $2;
- }
- return $info;
-}
-
-sub systemctl {
- my ($self, $q, $user) = @_;
- if ($user) {
- $q =~ s/'/\\'/g;
- return $self->execute("su -l $user -c \$'XDG_RUNTIME_DIR=/run/user/`id -u` systemctl --user $q'");
- }
-
- return $self->execute("systemctl $q");
-}
-
-# Fail if the given systemd unit is not in the "active" state.
-sub requireActiveUnit {
- my ($self, $unit) = @_;
- $self->nest("checking if unit ‘$unit’ has reached state 'active'", sub {
- my $info = $self->getUnitInfo($unit);
- my $state = $info->{ActiveState};
- if ($state ne "active") {
- die "Expected unit ‘$unit’ to to be in state 'active' but it is in state ‘$state’\n";
- };
- });
-}
-
-# Wait for a systemd unit to reach the "active" state.
-sub waitForUnit {
- my ($self, $unit, $user) = @_;
- $self->nest("waiting for unit ‘$unit’", sub {
- retry sub {
- my $info = $self->getUnitInfo($unit, $user);
- my $state = $info->{ActiveState};
- die "unit ‘$unit’ reached state ‘$state’\n" if $state eq "failed";
- if ($state eq "inactive") {
- # If there are no pending jobs, then assume this unit
- # will never reach active state.
- my ($status, $jobs) = $self->systemctl("list-jobs --full 2>&1", $user);
- if ($jobs =~ /No jobs/) { # FIXME: fragile
- # Handle the case where the unit may have started
- # between the previous getUnitInfo() and
- # list-jobs.
- my $info2 = $self->getUnitInfo($unit);
- die "unit ‘$unit’ is inactive and there are no pending jobs\n"
- if $info2->{ActiveState} eq $state;
- }
- }
- return 1 if $state eq "active";
- };
- });
-}
-
-
-sub waitForJob {
- my ($self, $jobName) = @_;
- return $self->waitForUnit($jobName);
-}
-
-
-# Wait until the specified file exists.
-sub waitForFile {
- my ($self, $fileName) = @_;
- $self->nest("waiting for file ‘$fileName’", sub {
- retry sub {
- my ($status, $out) = $self->execute("test -e $fileName");
- return 1 if $status == 0;
- }
- });
-}
-
-sub startJob {
- my ($self, $jobName, $user) = @_;
- $self->systemctl("start $jobName", $user);
- # FIXME: check result
-}
-
-sub stopJob {
- my ($self, $jobName, $user) = @_;
- $self->systemctl("stop $jobName", $user);
-}
-
-
-# Wait until the machine is listening on the given TCP port.
-sub waitForOpenPort {
- my ($self, $port) = @_;
- $self->nest("waiting for TCP port $port", sub {
- retry sub {
- my ($status, $out) = $self->execute("nc -z localhost $port");
- return 1 if $status == 0;
- }
- });
-}
-
-
-# Wait until the machine is not listening on the given TCP port.
-sub waitForClosedPort {
- my ($self, $port) = @_;
- retry sub {
- my ($status, $out) = $self->execute("nc -z localhost $port");
- return 1 if $status != 0;
- }
-}
-
-
-sub shutdown {
- my ($self) = @_;
- return unless $self->{booted};
-
- print { $self->{socket} } ("poweroff\n");
-
- $self->waitForShutdown;
-}
-
-
-sub crash {
- my ($self) = @_;
- return unless $self->{booted};
-
- $self->log("forced crash");
-
- $self->sendMonitorCommand("quit");
-
- $self->waitForShutdown;
-}
-
-
-# Make the machine unreachable by shutting down eth1 (the multicast
-# interface used to talk to the other VMs). We keep eth0 up so that
-# the test driver can continue to talk to the machine.
-sub block {
- my ($self) = @_;
- $self->sendMonitorCommand("set_link virtio-net-pci.1 off");
-}
-
-
-# Make the machine reachable.
-sub unblock {
- my ($self) = @_;
- $self->sendMonitorCommand("set_link virtio-net-pci.1 on");
-}
-
-
-# Take a screenshot of the X server on :0.0.
-sub screenshot {
- my ($self, $filename) = @_;
- my $dir = $ENV{'out'} || Cwd::abs_path(".");
- $filename = "$dir/${filename}.png" if $filename =~ /^\w+$/;
- my $tmp = "${filename}.ppm";
- my $name = basename($filename);
- $self->nest("making screenshot ‘$name’", sub {
- $self->sendMonitorCommand("screendump $tmp");
- system("pnmtopng $tmp > ${filename}") == 0
- or die "cannot convert screenshot";
- unlink $tmp;
- }, { image => $name } );
-}
-
-# Get the text of TTY<n>
-sub getTTYText {
- my ($self, $tty) = @_;
-
- my ($status, $out) = $self->execute("fold -w\$(stty -F /dev/tty${tty} size | awk '{print \$2}') /dev/vcs${tty}");
- return $out;
-}
-
-# Wait until TTY<n>'s text matches a particular regular expression
-sub waitUntilTTYMatches {
- my ($self, $tty, $regexp) = @_;
-
- $self->nest("waiting for $regexp to appear on tty $tty", sub {
- retry sub {
- my ($retries_remaining) = @_;
- if ($retries_remaining == 0) {
- $self->log("Last chance to match /$regexp/ on TTY$tty, which currently contains:");
- $self->log($self->getTTYText($tty));
- }
-
- return 1 if $self->getTTYText($tty) =~ /$regexp/;
- }
- });
-}
-
-# Debugging: Dump the contents of the TTY<n>
-sub dumpTTYContents {
- my ($self, $tty) = @_;
-
- $self->execute("fold -w 80 /dev/vcs${tty} | systemd-cat");
-}
-
-# Take a screenshot and return the result as text using optical character
-# recognition.
-sub getScreenText {
- my ($self) = @_;
-
- system("command -v tesseract &> /dev/null") == 0
- or die "getScreenText used but enableOCR is false";
-
- my $text;
- $self->nest("performing optical character recognition", sub {
- my $tmpbase = Cwd::abs_path(".")."/ocr";
- my $tmpin = $tmpbase."in.ppm";
-
- $self->sendMonitorCommand("screendump $tmpin");
-
- my $magickArgs = "-filter Catrom -density 72 -resample 300 "
- . "-contrast -normalize -despeckle -type grayscale "
- . "-sharpen 1 -posterize 3 -negate -gamma 100 "
- . "-blur 1x65535";
- my $tessArgs = "-c debug_file=/dev/null --psm 11 --oem 2";
-
- $text = `convert $magickArgs $tmpin tiff:- | tesseract - - $tessArgs`;
- my $status = $? >> 8;
- unlink $tmpin;
-
- die "OCR failed with exit code $status" if $status != 0;
- });
- return $text;
-}
-
-
-# Wait until a specific regexp matches the textual contents of the screen.
-sub waitForText {
- my ($self, $regexp) = @_;
- $self->nest("waiting for $regexp to appear on the screen", sub {
- retry sub {
- my ($retries_remaining) = @_;
- if ($retries_remaining == 0) {
- $self->log("Last chance to match /$regexp/ on the screen, which currently contains:");
- $self->log($self->getScreenText);
- }
-
- return 1 if $self->getScreenText =~ /$regexp/;
- }
- });
-}
-
-
-# Wait until it is possible to connect to the X server. Note that
-# testing the existence of /tmp/.X11-unix/X0 is insufficient.
-sub waitForX {
- my ($self, $regexp) = @_;
- $self->nest("waiting for the X11 server", sub {
- retry sub {
- my ($status, $out) = $self->execute("journalctl -b SYSLOG_IDENTIFIER=systemd | grep 'Reached target Current graphical'");
- return 0 if $status != 0;
- ($status, $out) = $self->execute("[ -e /tmp/.X11-unix/X0 ]");
- return 1 if $status == 0;
- }
- });
-}
-
-
-sub getWindowNames {
- my ($self) = @_;
- my $res = $self->mustSucceed(
- q{xwininfo -root -tree | sed 's/.*0x[0-9a-f]* \"\([^\"]*\)\".*/\1/; t; d'});
- return split /\n/, $res;
-}
-
-
-sub waitForWindow {
- my ($self, $regexp) = @_;
- $self->nest("waiting for a window to appear", sub {
- retry sub {
- my @names = $self->getWindowNames;
-
- my ($retries_remaining) = @_;
- if ($retries_remaining == 0) {
- $self->log("Last chance to match /$regexp/ on the the window list, which currently contains:");
- $self->log(join(", ", @names));
- }
-
- foreach my $n (@names) {
- return 1 if $n =~ /$regexp/;
- }
- }
- });
-}
-
-
-sub copyFileFromHost {
- my ($self, $from, $to) = @_;
- my $s = `cat $from` or die;
- $s =~ s/'/'\\''/g;
- $self->mustSucceed("echo '$s' > $to");
-}
-
-
-my %charToKey = (
- 'A' => "shift-a", 'N' => "shift-n", '-' => "0x0C", '_' => "shift-0x0C", '!' => "shift-0x02",
- 'B' => "shift-b", 'O' => "shift-o", '=' => "0x0D", '+' => "shift-0x0D", '@' => "shift-0x03",
- 'C' => "shift-c", 'P' => "shift-p", '[' => "0x1A", '{' => "shift-0x1A", '#' => "shift-0x04",
- 'D' => "shift-d", 'Q' => "shift-q", ']' => "0x1B", '}' => "shift-0x1B", '$' => "shift-0x05",
- 'E' => "shift-e", 'R' => "shift-r", ';' => "0x27", ':' => "shift-0x27", '%' => "shift-0x06",
- 'F' => "shift-f", 'S' => "shift-s", '\'' => "0x28", '"' => "shift-0x28", '^' => "shift-0x07",
- 'G' => "shift-g", 'T' => "shift-t", '`' => "0x29", '~' => "shift-0x29", '&' => "shift-0x08",
- 'H' => "shift-h", 'U' => "shift-u", '\\' => "0x2B", '|' => "shift-0x2B", '*' => "shift-0x09",
- 'I' => "shift-i", 'V' => "shift-v", ',' => "0x33", '<' => "shift-0x33", '(' => "shift-0x0A",
- 'J' => "shift-j", 'W' => "shift-w", '.' => "0x34", '>' => "shift-0x34", ')' => "shift-0x0B",
- 'K' => "shift-k", 'X' => "shift-x", '/' => "0x35", '?' => "shift-0x35",
- 'L' => "shift-l", 'Y' => "shift-y", ' ' => "spc",
- 'M' => "shift-m", 'Z' => "shift-z", "\n" => "ret",
-);
-
-
-sub sendKeys {
- my ($self, @keys) = @_;
- foreach my $key (@keys) {
- $key = $charToKey{$key} if exists $charToKey{$key};
- $self->sendMonitorCommand("sendkey $key");
- }
-}
-
-
-sub sendChars {
- my ($self, $chars) = @_;
- $self->nest("sending keys ‘$chars’", sub {
- $self->sendKeys(split //, $chars);
- });
-}
-
-
-# Sleep N seconds (in virtual guest time, not real time).
-sub sleep {
- my ($self, $time) = @_;
- $self->succeed("sleep $time");
-}
-
-
-# Forward a TCP port on the host to a TCP port on the guest. Useful
-# during interactive testing.
-sub forwardPort {
- my ($self, $hostPort, $guestPort) = @_;
- $hostPort = 8080 unless defined $hostPort;
- $guestPort = 80 unless defined $guestPort;
- $self->sendMonitorCommand("hostfwd_add tcp::$hostPort-:$guestPort");
-}
-
-
-1;
diff --git a/nixpkgs/nixos/lib/test-driver/test-driver.pl b/nixpkgs/nixos/lib/test-driver/test-driver.pl
deleted file mode 100644
index a3354fb0e1e..00000000000
--- a/nixpkgs/nixos/lib/test-driver/test-driver.pl
+++ /dev/null
@@ -1,191 +0,0 @@
-#! /somewhere/perl -w
-
-use strict;
-use Machine;
-use Term::ReadLine;
-use IO::File;
-use IO::Pty;
-use Logger;
-use Cwd;
-use POSIX qw(_exit dup2);
-use Time::HiRes qw(clock_gettime CLOCK_MONOTONIC);
-
-$SIG{PIPE} = 'IGNORE'; # because Unix domain sockets may die unexpectedly
-
-STDERR->autoflush(1);
-
-my $log = new Logger;
-
-
-# Start vde_switch for each network required by the test.
-my %vlans;
-foreach my $vlan (split / /, $ENV{VLANS} || "") {
- next if defined $vlans{$vlan};
- # Start vde_switch as a child process. We don't run it in daemon
- # mode because we want the child process to be cleaned up when we
- # die. Since we have to make sure that the control socket is
- # ready, we send a dummy command to vde_switch (via stdin) and
- # wait for a reply. Note that vde_switch requires stdin to be a
- # TTY, so we create one.
- $log->log("starting VDE switch for network $vlan");
- my $socket = Cwd::abs_path "./vde$vlan.ctl";
- my $pty = new IO::Pty;
- my ($stdoutR, $stdoutW); pipe $stdoutR, $stdoutW;
- my $pid = fork(); die "cannot fork" unless defined $pid;
- if ($pid == 0) {
- dup2(fileno($pty->slave), 0);
- dup2(fileno($stdoutW), 1);
- exec "vde_switch -s $socket --dirmode 0700" or _exit(1);
- }
- close $stdoutW;
- print $pty "version\n";
- readline $stdoutR or die "cannot start vde_switch";
- $ENV{"QEMU_VDE_SOCKET_$vlan"} = $socket;
- $vlans{$vlan} = $pty;
- die unless -e "$socket/ctl";
-}
-
-
-my %vms;
-my $context = "";
-
-sub createMachine {
- my ($args) = @_;
- my $vm = Machine->new({%{$args}, log => $log, redirectSerial => ($ENV{USE_SERIAL} // "0") ne "1"});
- $vms{$vm->name} = $vm;
- $context .= "my \$" . $vm->name . " = \$vms{'" . $vm->name . "'}; ";
- return $vm;
-}
-
-foreach my $vmScript (@ARGV) {
- my $vm = createMachine({startCommand => $vmScript});
-}
-
-
-sub startAll {
- $log->nest("starting all VMs", sub {
- $_->start foreach values %vms;
- });
-}
-
-
-# Wait until all VMs have terminated.
-sub joinAll {
- $log->nest("waiting for all VMs to finish", sub {
- $_->waitForShutdown foreach values %vms;
- });
-}
-
-
-# In interactive tests, this allows the non-interactive test script to
-# be executed conveniently.
-sub testScript {
- eval "$context $ENV{testScript};\n";
- warn $@ if $@;
-}
-
-
-my $nrTests = 0;
-my $nrSucceeded = 0;
-
-
-sub subtest {
- my ($name, $coderef) = @_;
- $log->nest("subtest: $name", sub {
- $nrTests++;
- eval { &$coderef };
- if ($@) {
- $log->log("error: $@", { error => 1 });
- } else {
- $nrSucceeded++;
- }
- });
-}
-
-
-sub runTests {
- if (defined $ENV{tests}) {
- $log->nest("running the VM test script", sub {
- eval "$context $ENV{tests}";
- if ($@) {
- $log->log("error: $@", { error => 1 });
- die $@;
- }
- }, { expanded => 1 });
- } else {
- my $term = Term::ReadLine->new('nixos-vm-test');
- $term->ReadHistory;
- while (defined ($_ = $term->readline("> "))) {
- eval "$context $_\n";
- warn $@ if $@;
- }
- $term->WriteHistory;
- }
-
- # Copy the kernel coverage data for each machine, if the kernel
- # has been compiled with coverage instrumentation.
- $log->nest("collecting coverage data", sub {
- foreach my $vm (values %vms) {
- my $gcovDir = "/sys/kernel/debug/gcov";
-
- next unless $vm->isUp();
-
- my ($status, $out) = $vm->execute("test -e $gcovDir");
- next if $status != 0;
-
- # Figure out where to put the *.gcda files so that the
- # report generator can find the corresponding kernel
- # sources.
- my $kernelDir = $vm->mustSucceed("echo \$(dirname \$(readlink -f /run/current-system/kernel))/.build/linux-*");
- chomp $kernelDir;
- my $coverageDir = "/tmp/xchg/coverage-data/$kernelDir";
-
- # Copy all the *.gcda files.
- $vm->execute("for d in $gcovDir/nix/store/*/.build/linux-*; do for i in \$(cd \$d && find -name '*.gcda'); do echo \$i; mkdir -p $coverageDir/\$(dirname \$i); cp -v \$d/\$i $coverageDir/\$i; done; done");
- }
- });
-
- $log->nest("syncing", sub {
- foreach my $vm (values %vms) {
- next unless $vm->isUp();
- $vm->execute("sync");
- }
- });
-
- if ($nrTests != 0) {
- $log->log("$nrSucceeded out of $nrTests tests succeeded",
- ($nrSucceeded < $nrTests ? { error => 1 } : { }));
- }
-}
-
-
-# Create an empty raw virtual disk with the given name and size (in
-# MiB).
-sub createDisk {
- my ($name, $size) = @_;
- system("qemu-img create -f raw $name ${size}M") == 0
- or die "cannot create image of size $size";
-}
-
-
-END {
- $log->nest("cleaning up", sub {
- foreach my $vm (values %vms) {
- if ($vm->{pid}) {
- $log->log("killing " . $vm->{name} . " (pid " . $vm->{pid} . ")");
- kill 9, $vm->{pid};
- }
- }
- });
- $log->close();
-}
-
-my $now1 = clock_gettime(CLOCK_MONOTONIC);
-
-runTests;
-
-my $now2 = clock_gettime(CLOCK_MONOTONIC);
-
-printf STDERR "test script finished in %.2fs\n", $now2 - $now1;
-
-exit ($nrSucceeded < $nrTests ? 1 : 0);
diff --git a/nixpkgs/nixos/lib/test-driver/test-driver.py b/nixpkgs/nixos/lib/test-driver/test-driver.py
index 7b8d5803aa5..156392ad1e3 100644
--- a/nixpkgs/nixos/lib/test-driver/test-driver.py
+++ b/nixpkgs/nixos/lib/test-driver/test-driver.py
@@ -217,7 +217,7 @@ class Machine:
match = re.search("run-(.+)-vm$", cmd)
if match:
self.name = match.group(1)
-
+ self.logger = args["log"]
self.script = args.get("startCommand", self.create_startcommand(args))
tmp_dir = os.environ.get("TMPDIR", tempfile.gettempdir())
@@ -227,7 +227,10 @@ class Machine:
os.makedirs(path, mode=0o700, exist_ok=True)
return path
- self.state_dir = create_dir("vm-state-{}".format(self.name))
+ self.state_dir = os.path.join(tmp_dir, f"vm-state-{self.name}")
+ if not args.get("keepVmState", False):
+ self.cleanup_statedir()
+ os.makedirs(self.state_dir, mode=0o700, exist_ok=True)
self.shared_dir = create_dir("shared-xchg")
self.booted = False
@@ -235,7 +238,6 @@ class Machine:
self.pid: Optional[int] = None
self.socket = None
self.monitor: Optional[socket.socket] = None
- self.logger: Logger = args["log"]
self.allow_reboot = args.get("allowReboot", False)
@staticmethod
@@ -424,15 +426,18 @@ class Machine:
output += out
return output
- def fail(self, *commands: str) -> None:
+ def fail(self, *commands: str) -> str:
"""Execute each command and check that it fails."""
+ output = ""
for command in commands:
with self.nested("must fail: {}".format(command)):
- status, output = self.execute(command)
+ (status, out) = self.execute(command)
if status == 0:
raise Exception(
"command `{}` unexpectedly succeeded".format(command)
)
+ output += out
+ return output
def wait_until_succeeds(self, command: str) -> str:
"""Wait until a command returns success and return its output.
@@ -777,9 +782,10 @@ class Machine:
self.log("QEMU running (pid {})".format(self.pid))
def cleanup_statedir(self) -> None:
- self.log("delete the VM state directory")
- if os.path.isfile(self.state_dir):
+ if os.path.isdir(self.state_dir):
shutil.rmtree(self.state_dir)
+ self.logger.log(f"deleting VM state directory {self.state_dir}")
+ self.logger.log("if you want to keep the VM state, pass --keep-vm-state")
def shutdown(self) -> None:
if not self.booted:
@@ -837,7 +843,8 @@ class Machine:
retry(window_is_visible)
def sleep(self, secs: int) -> None:
- time.sleep(secs)
+ # We want to sleep in *guest* time, not *host* time.
+ self.succeed(f"sleep {secs}")
def forward_port(self, host_port: int = 8080, guest_port: int = 80) -> None:
"""Forward a TCP port on the host to a TCP port on the guest.
@@ -936,10 +943,10 @@ if __name__ == "__main__":
for nr, vde_socket, _, _ in vde_sockets:
os.environ["QEMU_VDE_SOCKET_{}".format(nr)] = vde_socket
- machines = [create_machine({"startCommand": s}) for s in vm_scripts]
- for machine in machines:
- if not cli_args.keep_vm_state:
- machine.cleanup_statedir()
+ machines = [
+ create_machine({"startCommand": s, "keepVmState": cli_args.keep_vm_state})
+ for s in vm_scripts
+ ]
machine_eval = [
"{0} = machines[{1}]".format(m.name, idx) for idx, m in enumerate(machines)
]
diff --git a/nixpkgs/nixos/lib/testing-python.nix b/nixpkgs/nixos/lib/testing-python.nix
index c6939c7d698..76a2022082c 100644
--- a/nixpkgs/nixos/lib/testing-python.nix
+++ b/nixpkgs/nixos/lib/testing-python.nix
@@ -63,18 +63,12 @@ rec {
mkdir -p $out
LOGFILE=/dev/null tests='exec(os.environ["testScript"])' ${driver}/bin/nixos-test-driver
-
- for i in */xchg/coverage-data; do
- mkdir -p $out/coverage-data
- mv $i $out/coverage-data/$(dirname $(dirname $i))
- done
'';
};
makeTest =
{ testScript
- , makeCoverageReport ? false
, enableOCR ? false
, name ? "unnamed"
# Skip linting (mainly intended for faster dev cycles)
@@ -153,7 +147,6 @@ rec {
};
test = passMeta (runTests driver);
- report = passMeta (releaseTools.gcovReport { coverageRuns = [ test ]; });
nodeNames = builtins.attrNames nodes;
invalidNodeNames = lib.filter
@@ -169,7 +162,7 @@ rec {
Please stick to alphanumeric chars and underscores as separation.
''
else
- (if makeCoverageReport then report else test) // {
+ test // {
inherit nodes driver test;
};
diff --git a/nixpkgs/nixos/lib/testing.nix b/nixpkgs/nixos/lib/testing.nix
deleted file mode 100644
index 5c784c2f0ab..00000000000
--- a/nixpkgs/nixos/lib/testing.nix
+++ /dev/null
@@ -1,258 +0,0 @@
-{ system
-, pkgs ? import ../.. { inherit system config; }
- # Use a minimal kernel?
-, minimal ? false
- # Ignored
-, config ? {}
- # Modules to add to each VM
-, extraConfigurations ? [] }:
-
-with import ./build-vms.nix { inherit system pkgs minimal extraConfigurations; };
-with pkgs;
-
-rec {
-
- inherit pkgs;
-
-
- testDriver = lib.warn ''
- Perl VM tests are deprecated and will be removed for 20.09.
- Please update your tests to use the python test driver.
- See https://github.com/NixOS/nixpkgs/pull/71684 for details.
- '' stdenv.mkDerivation {
- name = "nixos-test-driver";
-
- buildInputs = [ makeWrapper perl ];
-
- dontUnpack = true;
-
- preferLocalBuild = true;
-
- installPhase =
- ''
- mkdir -p $out/bin
- cp ${./test-driver/test-driver.pl} $out/bin/nixos-test-driver
- chmod u+x $out/bin/nixos-test-driver
-
- libDir=$out/${perl.libPrefix}
- mkdir -p $libDir
- cp ${./test-driver/Machine.pm} $libDir/Machine.pm
- cp ${./test-driver/Logger.pm} $libDir/Logger.pm
-
- wrapProgram $out/bin/nixos-test-driver \
- --prefix PATH : "${lib.makeBinPath [ qemu_test vde2 netpbm coreutils ]}" \
- --prefix PERL5LIB : "${with perlPackages; makePerlPath [ TermReadLineGnu XMLWriter IOTty FileSlurp ]}:$out/${perl.libPrefix}"
- '';
- };
-
-
- # Run an automated test suite in the given virtual network.
- # `driver' is the script that runs the network.
- runTests = driver:
- stdenv.mkDerivation {
- name = "vm-test-run-${driver.testName}";
-
- requiredSystemFeatures = [ "kvm" "nixos-test" ];
-
- buildCommand =
- ''
- mkdir -p $out
-
- LOGFILE=/dev/null tests='eval $ENV{testScript}; die $@ if $@;' ${driver}/bin/nixos-test-driver
-
- for i in */xchg/coverage-data; do
- mkdir -p $out/coverage-data
- mv $i $out/coverage-data/$(dirname $(dirname $i))
- done
- '';
- };
-
-
- makeTest =
- { testScript
- , makeCoverageReport ? false
- , enableOCR ? false
- , name ? "unnamed"
- , ...
- } @ t:
-
- let
- # A standard store path to the vm monitor is built like this:
- # /tmp/nix-build-vm-test-run-$name.drv-0/vm-state-machine/monitor
- # The max filename length of a unix domain socket is 108 bytes.
- # This means $name can at most be 50 bytes long.
- maxTestNameLen = 50;
- testNameLen = builtins.stringLength name;
-
- testDriverName = with builtins;
- if testNameLen > maxTestNameLen then
- abort ("The name of the test '${name}' must not be longer than ${toString maxTestNameLen} " +
- "it's currently ${toString testNameLen} characters long.")
- else
- "nixos-test-driver-${name}";
-
- nodes = buildVirtualNetwork (
- t.nodes or (if t ? machine then { machine = t.machine; } else { }));
-
- testScript' =
- # Call the test script with the computed nodes.
- if lib.isFunction testScript
- then testScript { inherit nodes; }
- else testScript;
-
- vlans = map (m: m.config.virtualisation.vlans) (lib.attrValues nodes);
-
- vms = map (m: m.config.system.build.vm) (lib.attrValues nodes);
-
- ocrProg = tesseract4.override { enableLanguages = [ "eng" ]; };
-
- imagemagick_tiff = imagemagick_light.override { inherit libtiff; };
-
- # Generate onvenience wrappers for running the test driver
- # interactively with the specified network, and for starting the
- # VMs from the command line.
- driver = runCommand testDriverName
- { buildInputs = [ makeWrapper];
- testScript = testScript';
- preferLocalBuild = true;
- testName = name;
- }
- ''
- mkdir -p $out/bin
- echo "$testScript" > $out/test-script
- ln -s ${testDriver}/bin/nixos-test-driver $out/bin/
- vms=($(for i in ${toString vms}; do echo $i/bin/run-*-vm; done))
- wrapProgram $out/bin/nixos-test-driver \
- --add-flags "''${vms[*]}" \
- ${lib.optionalString enableOCR
- "--prefix PATH : '${ocrProg}/bin:${imagemagick_tiff}/bin'"} \
- --run "export testScript=\"\$(cat $out/test-script)\"" \
- --set VLANS '${toString vlans}'
- ln -s ${testDriver}/bin/nixos-test-driver $out/bin/nixos-run-vms
- wrapProgram $out/bin/nixos-run-vms \
- --add-flags "''${vms[*]}" \
- ${lib.optionalString enableOCR "--prefix PATH : '${ocrProg}/bin'"} \
- --set tests 'startAll; joinAll;' \
- --set VLANS '${toString vlans}' \
- ${lib.optionalString (builtins.length vms == 1) "--set USE_SERIAL 1"}
- ''; # "
-
- passMeta = drv: drv // lib.optionalAttrs (t ? meta) {
- meta = (drv.meta or {}) // t.meta;
- };
-
- test = passMeta (runTests driver);
- report = passMeta (releaseTools.gcovReport { coverageRuns = [ test ]; });
-
- nodeNames = builtins.attrNames nodes;
- invalidNodeNames = lib.filter
- (node: builtins.match "^[A-z_][A-z0-9_]+$" node == null) nodeNames;
-
- in
- if lib.length invalidNodeNames > 0 then
- throw ''
- Cannot create machines out of (${lib.concatStringsSep ", " invalidNodeNames})!
- All machines are referenced as perl variables in the testing framework which will break the
- script when special characters are used.
-
- Please stick to alphanumeric chars and underscores as separation.
- ''
- else
- (if makeCoverageReport then report else test) // {
- inherit nodes driver test;
- };
-
- runInMachine =
- { drv
- , machine
- , preBuild ? ""
- , postBuild ? ""
- , ... # ???
- }:
- let
- vm = buildVM { }
- [ machine
- { key = "run-in-machine";
- networking.hostName = "client";
- nix.readOnlyStore = false;
- virtualisation.writableStore = false;
- }
- ];
-
- buildrunner = writeText "vm-build" ''
- source $1
-
- ${coreutils}/bin/mkdir -p $TMPDIR
- cd $TMPDIR
-
- exec $origBuilder $origArgs
- '';
-
- testScript = ''
- startAll;
- $client->waitForUnit("multi-user.target");
- ${preBuild}
- $client->succeed("env -i ${bash}/bin/bash ${buildrunner} /tmp/xchg/saved-env >&2");
- ${postBuild}
- $client->succeed("sync"); # flush all data before pulling the plug
- '';
-
- vmRunCommand = writeText "vm-run" ''
- xchg=vm-state-client/xchg
- ${coreutils}/bin/mkdir $out
- ${coreutils}/bin/mkdir -p $xchg
-
- for i in $passAsFile; do
- i2=''${i}Path
- _basename=$(${coreutils}/bin/basename ''${!i2})
- ${coreutils}/bin/cp ''${!i2} $xchg/$_basename
- eval $i2=/tmp/xchg/$_basename
- ${coreutils}/bin/ls -la $xchg
- done
-
- unset i i2 _basename
- export | ${gnugrep}/bin/grep -v '^xchg=' > $xchg/saved-env
- unset xchg
-
- export tests='${testScript}'
- ${testDriver}/bin/nixos-test-driver ${vm.config.system.build.vm}/bin/run-*-vm
- ''; # */
-
- in
- lib.overrideDerivation drv (attrs: {
- requiredSystemFeatures = [ "kvm" ];
- builder = "${bash}/bin/sh";
- args = ["-e" vmRunCommand];
- origArgs = attrs.args;
- origBuilder = attrs.builder;
- });
-
-
- runInMachineWithX = { require ? [], ... } @ args:
- let
- client =
- { ... }:
- {
- inherit require;
- imports = [
- ../tests/common/auto.nix
- ];
- virtualisation.memorySize = 1024;
- services.xserver.enable = true;
- test-support.displayManager.auto.enable = true;
- services.xserver.displayManager.defaultSession = "none+icewm";
- services.xserver.windowManager.icewm.enable = true;
- };
- in
- runInMachine ({
- machine = client;
- preBuild =
- ''
- $client->waitForX;
- '';
- } // args);
-
-
- simpleTest = as: (makeTest as).test;
-
-}
diff --git a/nixpkgs/nixos/maintainers/scripts/ec2/amazon-image.nix b/nixpkgs/nixos/maintainers/scripts/ec2/amazon-image.nix
index 36f3e7af873..b09f4ca47a3 100644
--- a/nixpkgs/nixos/maintainers/scripts/ec2/amazon-image.nix
+++ b/nixpkgs/nixos/maintainers/scripts/ec2/amazon-image.nix
@@ -63,8 +63,8 @@ in {
fsType = "ext4";
configFile = pkgs.writeText "configuration.nix"
''
- {
- imports = [ <nixpkgs/nixos/modules/virtualisation/amazon-image.nix> ];
+ { modulesPath, ... }: {
+ imports = [ "''${modulesPath}/virtualisation/amazon-image.nix" ];
${optionalString config.ec2.hvm ''
ec2.hvm = true;
''}
diff --git a/nixpkgs/nixos/maintainers/scripts/ec2/create-amis.sh b/nixpkgs/nixos/maintainers/scripts/ec2/create-amis.sh
index 145eb49ced7..89e24f2ccfd 100755
--- a/nixpkgs/nixos/maintainers/scripts/ec2/create-amis.sh
+++ b/nixpkgs/nixos/maintainers/scripts/ec2/create-amis.sh
@@ -29,7 +29,7 @@ log() {
echo "$@" >&2
}
-if [ -z "$1" ]; then
+if [ "$#" -ne 1 ]; then
log "Usage: ./upload-amazon-image.sh IMAGE_OUTPUT"
exit 1
fi
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;
diff --git a/nixpkgs/nixos/release-combined.nix b/nixpkgs/nixos/release-combined.nix
index ece2d091f5a..945ba90e345 100644
--- a/nixpkgs/nixos/release-combined.nix
+++ b/nixpkgs/nixos/release-combined.nix
@@ -106,11 +106,29 @@ in rec {
(onFullSupported "nixos.tests.networking.scripted.bridge")
(onFullSupported "nixos.tests.networking.scripted.dhcpOneIf")
(onFullSupported "nixos.tests.networking.scripted.dhcpSimple")
+ (onFullSupported "nixos.tests.networking.scripted.link")
(onFullSupported "nixos.tests.networking.scripted.loopback")
(onFullSupported "nixos.tests.networking.scripted.macvlan")
+ (onFullSupported "nixos.tests.networking.scripted.privacy")
+ (onFullSupported "nixos.tests.networking.scripted.routes")
(onFullSupported "nixos.tests.networking.scripted.sit")
(onFullSupported "nixos.tests.networking.scripted.static")
+ (onFullSupported "nixos.tests.networking.scripted.virtual")
(onFullSupported "nixos.tests.networking.scripted.vlan")
+ (onFullSupported "nixos.tests.networking.networkd.bond")
+ (onFullSupported "nixos.tests.networking.networkd.bridge")
+ (onFullSupported "nixos.tests.networking.networkd.dhcpOneIf")
+ (onFullSupported "nixos.tests.networking.networkd.dhcpSimple")
+ (onFullSupported "nixos.tests.networking.networkd.link")
+ (onFullSupported "nixos.tests.networking.networkd.loopback")
+ # Fails nondeterministically (https://github.com/NixOS/nixpkgs/issues/96709)
+ #(onFullSupported "nixos.tests.networking.networkd.macvlan")
+ (onFullSupported "nixos.tests.networking.networkd.privacy")
+ (onFullSupported "nixos.tests.networking.networkd.routes")
+ (onFullSupported "nixos.tests.networking.networkd.sit")
+ (onFullSupported "nixos.tests.networking.networkd.static")
+ (onFullSupported "nixos.tests.networking.networkd.virtual")
+ (onFullSupported "nixos.tests.networking.networkd.vlan")
(onFullSupported "nixos.tests.systemd-networkd-ipv6-prefix-delegation")
(onFullSupported "nixos.tests.nfs3.simple")
(onFullSupported "nixos.tests.nfs4.simple")
diff --git a/nixpkgs/nixos/tests/3proxy.nix b/nixpkgs/nixos/tests/3proxy.nix
index 3e2061d7e42..de3056f6710 100644
--- a/nixpkgs/nixos/tests/3proxy.nix
+++ b/nixpkgs/nixos/tests/3proxy.nix
@@ -134,6 +134,10 @@ import ./make-test-python.nix ({ pkgs, ...} : {
};
testScript = ''
+ start_all()
+
+ peer0.wait_for_unit("network-online.target")
+
peer1.wait_for_unit("3proxy.service")
peer1.wait_for_open_port("9999")
diff --git a/nixpkgs/nixos/tests/acme.nix b/nixpkgs/nixos/tests/acme.nix
index a8188473721..64193ed8498 100644
--- a/nixpkgs/nixos/tests/acme.nix
+++ b/nixpkgs/nixos/tests/acme.nix
@@ -1,29 +1,43 @@
let
commonConfig = ./common/acme/client;
- dnsScript = {writeScript, dnsAddress, bash, curl}: writeScript "dns-hook.sh" ''
- #!${bash}/bin/bash
+ dnsServerIP = nodes: nodes.dnsserver.config.networking.primaryIPAddress;
+
+ dnsScript = {pkgs, nodes}: let
+ dnsAddress = dnsServerIP nodes;
+ in pkgs.writeShellScript "dns-hook.sh" ''
set -euo pipefail
echo '[INFO]' "[$2]" 'dns-hook.sh' $*
if [ "$1" = "present" ]; then
- ${curl}/bin/curl --data '{"host": "'"$2"'", "value": "'"$3"'"}' http://${dnsAddress}:8055/set-txt
+ ${pkgs.curl}/bin/curl --data '{"host": "'"$2"'", "value": "'"$3"'"}' http://${dnsAddress}:8055/set-txt
else
- ${curl}/bin/curl --data '{"host": "'"$2"'"}' http://${dnsAddress}:8055/clear-txt
+ ${pkgs.curl}/bin/curl --data '{"host": "'"$2"'"}' http://${dnsAddress}:8055/clear-txt
fi
'';
+ documentRoot = pkgs: pkgs.runCommand "docroot" {} ''
+ mkdir -p "$out"
+ echo hello world > "$out/index.html"
+ '';
+
+ vhostBase = pkgs: {
+ forceSSL = true;
+ locations."/".root = documentRoot pkgs;
+ };
+
in import ./make-test-python.nix ({ lib, ... }: {
name = "acme";
meta.maintainers = lib.teams.acme.members;
- nodes = rec {
+ nodes = {
+ # The fake ACME server which will respond to client requests
acme = { nodes, lib, ... }: {
imports = [ ./common/acme/server ];
- networking.nameservers = lib.mkForce [
- nodes.dnsserver.config.networking.primaryIPAddress
- ];
+ networking.nameservers = lib.mkForce [ (dnsServerIP nodes) ];
};
+ # A fake DNS server which can be configured with records as desired
+ # Used to test DNS-01 challenge
dnsserver = { nodes, pkgs, ... }: {
networking.firewall.allowedTCPPorts = [ 8055 53 ];
networking.firewall.allowedUDPPorts = [ 53 ];
@@ -39,112 +53,97 @@ in import ./make-test-python.nix ({ lib, ... }: {
};
};
- acmeStandalone = { nodes, lib, config, pkgs, ... }: {
- imports = [ commonConfig ];
- networking.nameservers = lib.mkForce [
- nodes.dnsserver.config.networking.primaryIPAddress
- ];
- networking.firewall.allowedTCPPorts = [ 80 ];
- security.acme.certs."standalone.test" = {
- webroot = "/var/lib/acme/acme-challenges";
- };
- systemd.targets."acme-finished-standalone.test" = {
- after = [ "acme-standalone.test.service" ];
- wantedBy = [ "acme-standalone.test.service" ];
- };
- services.nginx.enable = true;
- services.nginx.virtualHosts."standalone.test" = {
- locations."/.well-known/acme-challenge".root = "/var/lib/acme/acme-challenges";
- };
- };
-
- webserver = { nodes, config, pkgs, lib, ... }: {
+ # A web server which will be the node requesting certs
+ webserver = { pkgs, nodes, lib, config, ... }: {
imports = [ commonConfig ];
+ networking.nameservers = lib.mkForce [ (dnsServerIP nodes) ];
networking.firewall.allowedTCPPorts = [ 80 443 ];
- networking.nameservers = lib.mkForce [
- nodes.dnsserver.config.networking.primaryIPAddress
- ];
-
- # A target remains active. Use this to probe the fact that
- # a service fired eventhough it is not RemainAfterExit
- systemd.targets."acme-finished-a.example.test" = {
- after = [ "acme-a.example.test.service" ];
- wantedBy = [ "acme-a.example.test.service" ];
- };
+ # OpenSSL will be used for more thorough certificate validation
+ environment.systemPackages = [ pkgs.openssl ];
+
+ # Set log level to info so that we can see when the service is reloaded
services.nginx.enable = true;
+ services.nginx.logError = "stderr info";
- services.nginx.virtualHosts."a.example.test" = {
+ # First tests configure a basic cert and run a bunch of openssl checks
+ services.nginx.virtualHosts."a.example.test" = (vhostBase pkgs) // {
enableACME = true;
- forceSSL = true;
- locations."/".root = pkgs.runCommand "docroot" {} ''
- mkdir -p "$out"
- echo hello world > "$out/index.html"
- '';
};
- security.acme.server = "https://acme.test/dir";
+ # Used to determine if service reload was triggered
+ systemd.targets.test-renew-nginx = {
+ wants = [ "acme-a.example.test.service" ];
+ after = [ "acme-a.example.test.service" "nginx-config-reload.service" ];
+ };
- specialisation.second-cert.configuration = {pkgs, ...}: {
- systemd.targets."acme-finished-b.example.test" = {
- after = [ "acme-b.example.test.service" ];
- wantedBy = [ "acme-b.example.test.service" ];
+ # Cert config changes will not cause the nginx configuration to change.
+ # This tests that the reload service is correctly triggered.
+ # It also tests that postRun is exec'd as root
+ specialisation.cert-change.configuration = { pkgs, ... }: {
+ security.acme.certs."a.example.test".keyType = "ec384";
+ security.acme.certs."a.example.test".postRun = ''
+ set -euo pipefail
+ touch test
+ chown root:root test
+ echo testing > test
+ '';
+ };
+
+ # Now adding an alias to ensure that the certs are updated
+ specialisation.nginx-aliases.configuration = { pkgs, ... }: {
+ services.nginx.virtualHosts."a.example.test" = {
+ serverAliases = [ "b.example.test" ];
};
- services.nginx.virtualHosts."b.example.test" = {
- enableACME = true;
+ };
+
+ # Test using Apache HTTPD
+ specialisation.httpd-aliases.configuration = { pkgs, config, lib, ... }: {
+ services.nginx.enable = lib.mkForce false;
+ services.httpd.enable = true;
+ services.httpd.adminAddr = config.security.acme.email;
+ services.httpd.virtualHosts."c.example.test" = {
+ serverAliases = [ "d.example.test" ];
forceSSL = true;
- locations."/".root = pkgs.runCommand "docroot" {} ''
- mkdir -p "$out"
- echo hello world > "$out/index.html"
- '';
+ enableACME = true;
+ documentRoot = documentRoot pkgs;
+ };
+
+ # Used to determine if service reload was triggered
+ systemd.targets.test-renew-httpd = {
+ wants = [ "acme-c.example.test.service" ];
+ after = [ "acme-c.example.test.service" "httpd-config-reload.service" ];
};
};
- specialisation.dns-01.configuration = {pkgs, config, nodes, lib, ...}: {
+ # Validation via DNS-01 challenge
+ specialisation.dns-01.configuration = { pkgs, config, nodes, ... }: {
security.acme.certs."example.test" = {
domain = "*.example.test";
+ group = config.services.nginx.group;
dnsProvider = "exec";
dnsPropagationCheck = false;
- credentialsFile = with pkgs; writeText "wildcard.env" ''
- EXEC_PATH=${dnsScript { inherit writeScript bash curl; dnsAddress = nodes.dnsserver.config.networking.primaryIPAddress; }}
+ credentialsFile = pkgs.writeText "wildcard.env" ''
+ EXEC_PATH=${dnsScript { inherit pkgs nodes; }}
'';
- user = config.services.nginx.user;
- group = config.services.nginx.group;
};
- systemd.targets."acme-finished-example.test" = {
- after = [ "acme-example.test.service" ];
- wantedBy = [ "acme-example.test.service" ];
- };
- systemd.services."acme-example.test" = {
- before = [ "nginx.service" ];
- wantedBy = [ "nginx.service" ];
- };
- services.nginx.virtualHosts."c.example.test" = {
- forceSSL = true;
- sslCertificate = config.security.acme.certs."example.test".directory + "/cert.pem";
- sslTrustedCertificate = config.security.acme.certs."example.test".directory + "/full.pem";
- sslCertificateKey = config.security.acme.certs."example.test".directory + "/key.pem";
- locations."/".root = pkgs.runCommand "docroot" {} ''
- mkdir -p "$out"
- echo hello world > "$out/index.html"
- '';
+
+ services.nginx.virtualHosts."dns.example.test" = (vhostBase pkgs) // {
+ useACMEHost = "example.test";
};
};
- # When nginx depends on a service that is slow to start up, requesting used to fail
- # certificates fail. Reproducer for https://github.com/NixOS/nixpkgs/issues/81842
- specialisation.slow-startup.configuration = { pkgs, config, nodes, lib, ...}: {
+ # Validate service relationships by adding a slow start service to nginx' wants.
+ # Reproducer for https://github.com/NixOS/nixpkgs/issues/81842
+ specialisation.slow-startup.configuration = { pkgs, config, nodes, lib, ... }: {
systemd.services.my-slow-service = {
wantedBy = [ "multi-user.target" "nginx.service" ];
before = [ "nginx.service" ];
preStart = "sleep 5";
script = "${pkgs.python3}/bin/python -m http.server";
};
- systemd.targets."acme-finished-d.example.com" = {
- after = [ "acme-d.example.com.service" ];
- wantedBy = [ "acme-d.example.com.service" ];
- };
- services.nginx.virtualHosts."d.example.com" = {
+
+ services.nginx.virtualHosts."slow.example.com" = {
forceSSL = true;
enableACME = true;
locations."/".proxyPass = "http://localhost:8000";
@@ -152,11 +151,13 @@ in import ./make-test-python.nix ({ lib, ... }: {
};
};
- client = {nodes, lib, ...}: {
+ # The client will be used to curl the webserver to validate configuration
+ client = {nodes, lib, pkgs, ...}: {
imports = [ commonConfig ];
- networking.nameservers = lib.mkForce [
- nodes.dnsserver.config.networking.primaryIPAddress
- ];
+ networking.nameservers = lib.mkForce [ (dnsServerIP nodes) ];
+
+ # OpenSSL will be used for more thorough certificate validation
+ environment.systemPackages = [ pkgs.openssl ];
};
};
@@ -167,73 +168,168 @@ in import ./make-test-python.nix ({ lib, ... }: {
in
# Note, wait_for_unit does not work for oneshot services that do not have RemainAfterExit=true,
# this is because a oneshot goes from inactive => activating => inactive, and never
- # reaches the active state. To work around this, we create some mock target units which
- # get pulled in by the oneshot units. The target units linger after activation, and hence we
- # can use them to probe that a oneshot fired. It is a bit ugly, but it is the best we can do
+ # reaches the active state. Targets do not have this issue.
+
''
+ import time
+
+
+ has_switched = False
+
+
+ def switch_to(node, name):
+ global has_switched
+ if has_switched:
+ node.succeed(
+ "${switchToNewServer}"
+ )
+ has_switched = True
+ node.succeed(
+ f"/run/current-system/specialisation/{name}/bin/switch-to-configuration test"
+ )
+
+
+ # Ensures the issuer of our cert matches the chain
+ # and matches the issuer we expect it to be.
+ # It's a good validation to ensure the cert.pem and fullchain.pem
+ # are not still selfsigned afer verification
+ def check_issuer(node, cert_name, issuer):
+ for fname in ("cert.pem", "fullchain.pem"):
+ actual_issuer = node.succeed(
+ f"openssl x509 -noout -issuer -in /var/lib/acme/{cert_name}/{fname}"
+ ).partition("=")[2]
+ print(f"{fname} issuer: {actual_issuer}")
+ assert issuer.lower() in actual_issuer.lower()
+
+
+ # Ensure cert comes before chain in fullchain.pem
+ def check_fullchain(node, cert_name):
+ subject_data = node.succeed(
+ f"openssl crl2pkcs7 -nocrl -certfile /var/lib/acme/{cert_name}/fullchain.pem"
+ " | openssl pkcs7 -print_certs -noout"
+ )
+ for line in subject_data.lower().split("\n"):
+ if "subject" in line:
+ print(f"First subject in fullchain.pem: ", line)
+ assert cert_name.lower() in line
+ return
+
+ assert False
+
+
+ def check_connection(node, domain, retries=3):
+ assert retries >= 0
+
+ result = node.succeed(
+ "openssl s_client -brief -verify 2 -CAfile /tmp/ca.crt"
+ f" -servername {domain} -connect {domain}:443 < /dev/null 2>&1"
+ )
+
+ for line in result.lower().split("\n"):
+ if "verification" in line and "error" in line:
+ time.sleep(1)
+ return check_connection(node, domain, retries - 1)
+
+
+ def check_connection_key_bits(node, domain, bits, retries=3):
+ assert retries >= 0
+
+ result = node.succeed(
+ "openssl s_client -CAfile /tmp/ca.crt"
+ f" -servername {domain} -connect {domain}:443 < /dev/null"
+ " | openssl x509 -noout -text | grep -i Public-Key"
+ )
+ print("Key type:", result)
+
+ if bits not in result:
+ time.sleep(1)
+ return check_connection_key_bits(node, domain, bits, retries - 1)
+
+
client.start()
dnsserver.start()
- acme.wait_for_unit("default.target")
dnsserver.wait_for_unit("pebble-challtestsrv.service")
+ client.wait_for_unit("default.target")
+
client.succeed(
- 'curl --data \'{"host": "acme.test", "addresses": ["${nodes.acme.config.networking.primaryIPAddress}"]}\' http://${nodes.dnsserver.config.networking.primaryIPAddress}:8055/add-a'
- )
- client.succeed(
- 'curl --data \'{"host": "standalone.test", "addresses": ["${nodes.acmeStandalone.config.networking.primaryIPAddress}"]}\' http://${nodes.dnsserver.config.networking.primaryIPAddress}:8055/add-a'
+ 'curl --data \'{"host": "acme.test", "addresses": ["${nodes.acme.config.networking.primaryIPAddress}"]}\' http://${dnsServerIP nodes}:8055/add-a'
)
acme.start()
- acmeStandalone.start()
+ webserver.start()
acme.wait_for_unit("default.target")
acme.wait_for_unit("pebble.service")
- with subtest("can request certificate with HTTPS-01 challenge"):
- acmeStandalone.wait_for_unit("default.target")
- acmeStandalone.succeed("systemctl start acme-standalone.test.service")
- acmeStandalone.wait_for_unit("acme-finished-standalone.test.target")
-
- client.wait_for_unit("default.target")
-
client.succeed("curl https://acme.test:15000/roots/0 > /tmp/ca.crt")
client.succeed("curl https://acme.test:15000/intermediate-keys/0 >> /tmp/ca.crt")
- with subtest("Can request certificate for nginx service"):
+ with subtest("Can request certificate with HTTPS-01 challenge"):
webserver.wait_for_unit("acme-finished-a.example.test.target")
- client.succeed(
- "curl --cacert /tmp/ca.crt https://a.example.test/ | grep -qF 'hello world'"
- )
+ check_fullchain(webserver, "a.example.test")
+ check_issuer(webserver, "a.example.test", "pebble")
+ check_connection(client, "a.example.test")
- with subtest("Can add another certificate for nginx service"):
- webserver.succeed(
- "/run/current-system/specialisation/second-cert/bin/switch-to-configuration test"
- )
- webserver.wait_for_unit("acme-finished-b.example.test.target")
- client.succeed(
- "curl --cacert /tmp/ca.crt https://b.example.test/ | grep -qF 'hello world'"
- )
+ with subtest("Can generate valid selfsigned certs"):
+ webserver.succeed("systemctl clean acme-a.example.test.service --what=state")
+ webserver.succeed("systemctl start acme-selfsigned-a.example.test.service")
+ check_fullchain(webserver, "a.example.test")
+ check_issuer(webserver, "a.example.test", "minica")
+ # Will succeed if nginx can load the certs
+ webserver.succeed("systemctl start nginx-config-reload.service")
+
+ with subtest("Can reload nginx when timer triggers renewal"):
+ webserver.succeed("systemctl start test-renew-nginx.target")
+ check_issuer(webserver, "a.example.test", "pebble")
+ check_connection(client, "a.example.test")
+
+ with subtest("Can reload web server when cert configuration changes"):
+ switch_to(webserver, "cert-change")
+ webserver.wait_for_unit("acme-finished-a.example.test.target")
+ check_connection_key_bits(client, "a.example.test", "384")
+ webserver.succeed("grep testing /var/lib/acme/a.example.test/test")
+
+ with subtest("Can request certificate with HTTPS-01 when nginx startup is delayed"):
+ switch_to(webserver, "slow-startup")
+ webserver.wait_for_unit("acme-finished-slow.example.com.target")
+ check_issuer(webserver, "slow.example.com", "pebble")
+ check_connection(client, "slow.example.com")
+
+ with subtest("Can request certificate for vhost + aliases (nginx)"):
+ # Check the key hash before and after adding an alias. It should not change.
+ # The previous test reverts the ed384 change
+ webserver.wait_for_unit("acme-finished-a.example.test.target")
+ keyhash_old = webserver.succeed("md5sum /var/lib/acme/a.example.test/key.pem")
+ switch_to(webserver, "nginx-aliases")
+ webserver.wait_for_unit("acme-finished-a.example.test.target")
+ check_issuer(webserver, "a.example.test", "pebble")
+ check_connection(client, "a.example.test")
+ check_connection(client, "b.example.test")
+ keyhash_new = webserver.succeed("md5sum /var/lib/acme/a.example.test/key.pem")
+ assert keyhash_old == keyhash_new
+
+ with subtest("Can request certificates for vhost + aliases (apache-httpd)"):
+ switch_to(webserver, "httpd-aliases")
+ webserver.wait_for_unit("acme-finished-c.example.test.target")
+ check_issuer(webserver, "c.example.test", "pebble")
+ check_connection(client, "c.example.test")
+ check_connection(client, "d.example.test")
+
+ with subtest("Can reload httpd when timer triggers renewal"):
+ # Switch to selfsigned first
+ webserver.succeed("systemctl clean acme-c.example.test.service --what=state")
+ webserver.succeed("systemctl start acme-selfsigned-c.example.test.service")
+ check_issuer(webserver, "c.example.test", "minica")
+ webserver.succeed("systemctl start httpd-config-reload.service")
+ webserver.succeed("systemctl start test-renew-httpd.target")
+ check_issuer(webserver, "c.example.test", "pebble")
+ check_connection(client, "c.example.test")
with subtest("Can request wildcard certificates using DNS-01 challenge"):
- webserver.succeed(
- "${switchToNewServer}"
- )
- webserver.succeed(
- "/run/current-system/specialisation/dns-01/bin/switch-to-configuration test"
- )
+ switch_to(webserver, "dns-01")
webserver.wait_for_unit("acme-finished-example.test.target")
- client.succeed(
- "curl --cacert /tmp/ca.crt https://c.example.test/ | grep -qF 'hello world'"
- )
-
- with subtest("Can request certificate of nginx when startup is delayed"):
- webserver.succeed(
- "${switchToNewServer}"
- )
- webserver.succeed(
- "/run/current-system/specialisation/slow-startup/bin/switch-to-configuration test"
- )
- webserver.wait_for_unit("acme-finished-d.example.com.target")
- client.succeed("curl --cacert /tmp/ca.crt https://d.example.com/")
+ check_issuer(webserver, "example.test", "pebble")
+ check_connection(client, "dns.example.test")
'';
})
diff --git a/nixpkgs/nixos/tests/all-tests.nix b/nixpkgs/nixos/tests/all-tests.nix
index 31dad3be814..8048c885e15 100644
--- a/nixpkgs/nixos/tests/all-tests.nix
+++ b/nixpkgs/nixos/tests/all-tests.nix
@@ -34,6 +34,7 @@ in
bind = handleTest ./bind.nix {};
bitcoind = handleTest ./bitcoind.nix {};
bittorrent = handleTest ./bittorrent.nix {};
+ bitwarden = handleTest ./bitwarden.nix {};
blockbook-frontend = handleTest ./blockbook-frontend.nix {};
buildkite-agents = handleTest ./buildkite-agents.nix {};
boot = handleTestOn ["x86_64-linux"] ./boot.nix {}; # syslinux is unsupported on aarch64
@@ -48,6 +49,7 @@ in
ceph-multi-node = handleTestOn ["x86_64-linux"] ./ceph-multi-node.nix {};
certmgr = handleTest ./certmgr.nix {};
cfssl = handleTestOn ["x86_64-linux"] ./cfssl.nix {};
+ charliecloud = handleTest ./charliecloud.nix {};
chromium = (handleTestOn ["x86_64-linux"] ./chromium.nix {}).stable or {};
cjdns = handleTest ./cjdns.nix {};
clickhouse = handleTest ./clickhouse.nix {};
@@ -65,11 +67,13 @@ in
containers-macvlans = handleTest ./containers-macvlans.nix {};
containers-physical_interfaces = handleTest ./containers-physical_interfaces.nix {};
containers-portforward = handleTest ./containers-portforward.nix {};
+ containers-reloadable = handleTest ./containers-reloadable.nix {};
containers-restart_networking = handleTest ./containers-restart_networking.nix {};
containers-tmpfs = handleTest ./containers-tmpfs.nix {};
convos = handleTest ./convos.nix {};
corerad = handleTest ./corerad.nix {};
couchdb = handleTest ./couchdb.nix {};
+ cri-o = handleTestOn ["x86_64-linux"] ./cri-o.nix {};
deluge = handleTest ./deluge.nix {};
dhparams = handleTest ./dhparams.nix {};
dnscrypt-proxy2 = handleTestOn ["x86_64-linux"] ./dnscrypt-proxy2.nix {};
@@ -78,15 +82,13 @@ in
docker = handleTestOn ["x86_64-linux"] ./docker.nix {};
oci-containers = handleTestOn ["x86_64-linux"] ./oci-containers.nix {};
docker-edge = handleTestOn ["x86_64-linux"] ./docker-edge.nix {};
- docker-preloader = handleTestOn ["x86_64-linux"] ./docker-preloader.nix {};
docker-registry = handleTest ./docker-registry.nix {};
docker-tools = handleTestOn ["x86_64-linux"] ./docker-tools.nix {};
docker-tools-overlay = handleTestOn ["x86_64-linux"] ./docker-tools-overlay.nix {};
documize = handleTest ./documize.nix {};
dokuwiki = handleTest ./dokuwiki.nix {};
dovecot = handleTest ./dovecot.nix {};
- # ec2-config doesn't work in a sandbox as the simulated ec2 instance needs network access
- #ec2-config = (handleTestOn ["x86_64-linux"] ./ec2.nix {}).boot-ec2-config or {};
+ ec2-config = (handleTestOn ["x86_64-linux"] ./ec2.nix {}).boot-ec2-config or {};
ec2-nixops = (handleTestOn ["x86_64-linux"] ./ec2.nix {}).boot-ec2-nixops or {};
ecryptfs = handleTest ./ecryptfs.nix {};
ejabberd = handleTest ./xmpp/ejabberd.nix {};
@@ -101,6 +103,7 @@ in
ferm = handleTest ./ferm.nix {};
firefox = handleTest ./firefox.nix {};
firefox-esr = handleTest ./firefox.nix { esr = true; };
+ firejail = handleTest ./firejail.nix {};
firewall = handleTest ./firewall.nix {};
fish = handleTest ./fish.nix {};
flannel = handleTestOn ["x86_64-linux"] ./flannel.nix {};
@@ -194,12 +197,10 @@ in
mailcatcher = handleTest ./mailcatcher.nix {};
mariadb-galera-mariabackup = handleTest ./mysql/mariadb-galera-mariabackup.nix {};
mariadb-galera-rsync = handleTest ./mysql/mariadb-galera-rsync.nix {};
- mathics = handleTest ./mathics.nix {};
matomo = handleTest ./matomo.nix {};
matrix-synapse = handleTest ./matrix-synapse.nix {};
mediawiki = handleTest ./mediawiki.nix {};
memcached = handleTest ./memcached.nix {};
- mesos = handleTest ./mesos.nix {};
metabase = handleTest ./metabase.nix {};
miniflux = handleTest ./miniflux.nix {};
minio = handleTest ./minio.nix {};
@@ -268,6 +269,7 @@ in
pgjwt = handleTest ./pgjwt.nix {};
pgmanage = handleTest ./pgmanage.nix {};
php = handleTest ./php {};
+ pinnwand = handleTest ./pinnwand.nix {};
plasma5 = handleTest ./plasma5.nix {};
plotinus = handleTest ./plotinus.nix {};
podman = handleTestOn ["x86_64-linux"] ./podman.nix {};
@@ -296,6 +298,7 @@ in
redis = handleTest ./redis.nix {};
redmine = handleTest ./redmine.nix {};
restic = handleTest ./restic.nix {};
+ robustirc-bridge = handleTest ./robustirc-bridge.nix {};
roundcube = handleTest ./roundcube.nix {};
rspamd = handleTest ./rspamd.nix {};
rss2email = handleTest ./rss2email.nix {};
@@ -306,6 +309,8 @@ in
sanoid = handleTest ./sanoid.nix {};
sddm = handleTest ./sddm.nix {};
service-runner = handleTest ./service-runner.nix {};
+ shadowsocks = handleTest ./shadowsocks {};
+ shattered-pixel-dungeon = handleTest ./shattered-pixel-dungeon.nix {};
shiori = handleTest ./shiori.nix {};
signal-desktop = handleTest ./signal-desktop.nix {};
simple = handleTest ./simple.nix {};
@@ -319,6 +324,8 @@ in
spike = handleTest ./spike.nix {};
sonarr = handleTest ./sonarr.nix {};
sslh = handleTest ./sslh.nix {};
+ sssd = handleTestOn ["x86_64-linux"] ./sssd.nix {};
+ sssd-ldap = handleTestOn ["x86_64-linux"] ./sssd-ldap.nix {};
strongswan-swanctl = handleTest ./strongswan-swanctl.nix {};
sudo = handleTest ./sudo.nix {};
switchTest = handleTest ./switch-test.nix {};
@@ -356,6 +363,7 @@ in
unit-php = handleTest ./web-servers/unit-php.nix {};
upnp = handleTest ./upnp.nix {};
uwsgi = handleTest ./uwsgi.nix {};
+ v2ray = handleTest ./v2ray.nix {};
vault = handleTest ./vault.nix {};
victoriametrics = handleTest ./victoriametrics.nix {};
virtualbox = handleTestOn ["x86_64-linux"] ./virtualbox.nix {};
diff --git a/nixpkgs/nixos/tests/bitcoind.nix b/nixpkgs/nixos/tests/bitcoind.nix
index 95c6a5b91bc..09f3e4a6ec0 100644
--- a/nixpkgs/nixos/tests/bitcoind.nix
+++ b/nixpkgs/nixos/tests/bitcoind.nix
@@ -1,7 +1,7 @@
import ./make-test-python.nix ({ pkgs, ... }: {
name = "bitcoind";
meta = with pkgs.stdenv.lib; {
- maintainers = with maintainers; [ maintainers."1000101" ];
+ maintainers = with maintainers; [ _1000101 ];
};
machine = { ... }: {
diff --git a/nixpkgs/nixos/tests/bittorrent.nix b/nixpkgs/nixos/tests/bittorrent.nix
index 0a97d5556a2..c195b60cd56 100644
--- a/nixpkgs/nixos/tests/bittorrent.nix
+++ b/nixpkgs/nixos/tests/bittorrent.nix
@@ -19,6 +19,7 @@ let
externalClient2Address = "80.100.100.2";
externalTrackerAddress = "80.100.100.3";
+ download-dir = "/var/lib/transmission/Downloads";
transmissionConfig = { ... }: {
environment.systemPackages = [ pkgs.transmission ];
services.transmission = {
@@ -26,6 +27,7 @@ let
settings = {
dht-enabled = false;
message-level = 3;
+ inherit download-dir;
};
};
};
@@ -117,12 +119,12 @@ in
router.wait_for_unit("miniupnpd")
# Create the torrent.
- tracker.succeed("mkdir /tmp/data")
+ tracker.succeed("mkdir ${download-dir}/data")
tracker.succeed(
- "cp ${file} /tmp/data/test.tar.bz2"
+ "cp ${file} ${download-dir}/data/test.tar.bz2"
)
tracker.succeed(
- "transmission-create /tmp/data/test.tar.bz2 --private --tracker http://${externalTrackerAddress}:6969/announce --outfile /tmp/test.torrent"
+ "transmission-create ${download-dir}/data/test.tar.bz2 --private --tracker http://${externalTrackerAddress}:6969/announce --outfile /tmp/test.torrent"
)
tracker.succeed("chmod 644 /tmp/test.torrent")
@@ -133,18 +135,16 @@ in
# Start the initial seeder.
tracker.succeed(
- "transmission-remote --add /tmp/test.torrent --no-portmap --no-dht --download-dir /tmp/data"
+ "transmission-remote --add /tmp/test.torrent --no-portmap --no-dht --download-dir ${download-dir}/data"
)
# Now we should be able to download from the client behind the NAT.
tracker.wait_for_unit("httpd")
client1.wait_for_unit("network-online.target")
+ client1.succeed("transmission-remote --add http://${externalTrackerAddress}/test.torrent >&2 &")
+ client1.wait_for_file("${download-dir}/test.tar.bz2")
client1.succeed(
- "transmission-remote --add http://${externalTrackerAddress}/test.torrent --download-dir /tmp >&2 &"
- )
- client1.wait_for_file("/tmp/test.tar.bz2")
- client1.succeed(
- "cmp /tmp/test.tar.bz2 ${file}"
+ "cmp ${download-dir}/test.tar.bz2 ${file}"
)
# Bring down the initial seeder.
@@ -154,11 +154,11 @@ in
# the first client created a NAT hole in the router.
client2.wait_for_unit("network-online.target")
client2.succeed(
- "transmission-remote --add http://${externalTrackerAddress}/test.torrent --no-portmap --no-dht --download-dir /tmp >&2 &"
+ "transmission-remote --add http://${externalTrackerAddress}/test.torrent --no-portmap --no-dht >&2 &"
)
- client2.wait_for_file("/tmp/test.tar.bz2")
+ client2.wait_for_file("${download-dir}/test.tar.bz2")
client2.succeed(
- "cmp /tmp/test.tar.bz2 ${file}"
+ "cmp ${download-dir}/test.tar.bz2 ${file}"
)
'';
})
diff --git a/nixpkgs/nixos/tests/bitwarden.nix b/nixpkgs/nixos/tests/bitwarden.nix
new file mode 100644
index 00000000000..a47c77cec21
--- /dev/null
+++ b/nixpkgs/nixos/tests/bitwarden.nix
@@ -0,0 +1,188 @@
+{ system ? builtins.currentSystem
+, config ? { }
+, pkgs ? import ../.. { inherit system config; }
+}:
+
+# These tests will:
+# * Set up a bitwarden-rs server
+# * Have Firefox use the web vault to create an account, log in, and save a password to the valut
+# * Have the bw cli log in and read that password from the vault
+#
+# Note that Firefox must be on the same machine as the server for WebCrypto APIs to be available (or HTTPS must be configured)
+#
+# The same tests should work without modification on the official bitwarden server, if we ever package that.
+
+with import ../lib/testing-python.nix { inherit system pkgs; };
+with pkgs.lib;
+let
+ backends = [ "sqlite" "mysql" "postgresql" ];
+
+ dbPassword = "please_dont_hack";
+
+ userEmail = "meow@example.com";
+ userPassword = "also_super_secret_ZJWpBKZi668QGt"; # Must be complex to avoid interstitial warning on the signup page
+
+ storedPassword = "seeeecret";
+
+ makeBitwardenTest = backend: makeTest {
+ name = "bitwarden_rs-${backend}";
+ meta = {
+ maintainers = with pkgs.stdenv.lib.maintainers; [ jjjollyjim ];
+ };
+
+ nodes = {
+ server = { pkgs, ... }:
+ let backendConfig = {
+ mysql = {
+ services.mysql = {
+ enable = true;
+ initialScript = pkgs.writeText "mysql-init.sql" ''
+ CREATE DATABASE bitwarden;
+ CREATE USER 'bitwardenuser'@'localhost' IDENTIFIED BY '${dbPassword}';
+ GRANT ALL ON `bitwarden`.* TO 'bitwardenuser'@'localhost';
+ FLUSH PRIVILEGES;
+ '';
+ package = pkgs.mysql;
+ };
+
+ services.bitwarden_rs.config.databaseUrl = "mysql://bitwardenuser:${dbPassword}@localhost/bitwarden";
+
+ systemd.services.bitwarden_rs.after = [ "mysql.service" ];
+ };
+
+ postgresql = {
+ services.postgresql = {
+ enable = true;
+ initialScript = pkgs.writeText "postgresql-init.sql" ''
+ CREATE DATABASE bitwarden;
+ CREATE USER bitwardenuser WITH PASSWORD '${dbPassword}';
+ GRANT ALL PRIVILEGES ON DATABASE bitwarden TO bitwardenuser;
+ '';
+ };
+
+ services.bitwarden_rs.config.databaseUrl = "postgresql://bitwardenuser:${dbPassword}@localhost/bitwarden";
+
+ systemd.services.bitwarden_rs.after = [ "postgresql.service" ];
+ };
+
+ sqlite = { };
+ };
+ in
+ mkMerge [
+ backendConfig.${backend}
+ {
+ services.bitwarden_rs = {
+ enable = true;
+ dbBackend = backend;
+ config.rocketPort = 80;
+ };
+
+ networking.firewall.allowedTCPPorts = [ 80 ];
+
+ environment.systemPackages =
+ let
+ testRunner = pkgs.writers.writePython3Bin "test-runner"
+ {
+ libraries = [ pkgs.python3Packages.selenium ];
+ } ''
+ from selenium.webdriver import Firefox
+ from selenium.webdriver.firefox.options import Options
+ from selenium.webdriver.support.ui import WebDriverWait
+ from selenium.webdriver.support import expected_conditions as EC
+
+ options = Options()
+ options.add_argument('--headless')
+ driver = Firefox(options=options)
+
+ driver.implicitly_wait(20)
+ driver.get('http://localhost/#/register')
+
+ wait = WebDriverWait(driver, 10)
+
+ wait.until(EC.title_contains("Create Account"))
+
+ driver.find_element_by_css_selector('input#email').send_keys(
+ '${userEmail}'
+ )
+ driver.find_element_by_css_selector('input#name').send_keys(
+ 'A Cat'
+ )
+ driver.find_element_by_css_selector('input#masterPassword').send_keys(
+ '${userPassword}'
+ )
+ driver.find_element_by_css_selector('input#masterPasswordRetype').send_keys(
+ '${userPassword}'
+ )
+
+ driver.find_element_by_xpath("//button[contains(., 'Submit')]").click()
+
+ wait.until_not(EC.title_contains("Create Account"))
+
+ driver.find_element_by_css_selector('input#masterPassword').send_keys(
+ '${userPassword}'
+ )
+ driver.find_element_by_xpath("//button[contains(., 'Log In')]").click()
+
+ wait.until(EC.title_contains("My Vault"))
+
+ driver.find_element_by_xpath("//button[contains(., 'Add Item')]").click()
+
+ driver.find_element_by_css_selector('input#name').send_keys(
+ 'secrets'
+ )
+ driver.find_element_by_css_selector('input#loginPassword').send_keys(
+ '${storedPassword}'
+ )
+
+ driver.find_element_by_xpath("//button[contains(., 'Save')]").click()
+ '';
+ in
+ [ pkgs.firefox-unwrapped pkgs.geckodriver testRunner ];
+
+ virtualisation.memorySize = 768;
+ }
+ ];
+
+ client = { pkgs, ... }:
+ {
+ environment.systemPackages = [ pkgs.bitwarden-cli ];
+ };
+ };
+
+ testScript = ''
+ start_all()
+ server.wait_for_unit("bitwarden_rs.service")
+ server.wait_for_open_port(80)
+
+ with subtest("configure the cli"):
+ client.succeed("bw --nointeraction config server http://server")
+
+ with subtest("can't login to nonexistant account"):
+ client.fail(
+ "bw --nointeraction --raw login ${userEmail} ${userPassword}"
+ )
+
+ with subtest("use the web interface to sign up, log in, and save a password"):
+ server.succeed("PYTHONUNBUFFERED=1 test-runner | systemd-cat -t test-runner")
+
+ with subtest("log in with the cli"):
+ key = client.succeed(
+ "bw --nointeraction --raw login ${userEmail} ${userPassword}"
+ ).strip()
+
+ with subtest("sync with the cli"):
+ client.succeed(f"bw --nointeraction --raw --session {key} sync -f")
+
+ with subtest("get the password with the cli"):
+ password = client.succeed(
+ f"bw --nointeraction --raw --session {key} list items | ${pkgs.jq}/bin/jq -r .[].login.password"
+ )
+ assert password.strip() == "${storedPassword}"
+ '';
+ };
+in
+builtins.listToAttrs (
+ map
+ (backend: { name = backend; value = makeBitwardenTest backend; })
+ backends
+)
diff --git a/nixpkgs/nixos/tests/blockbook-frontend.nix b/nixpkgs/nixos/tests/blockbook-frontend.nix
index 5fbfc6c30c1..742a02999e7 100644
--- a/nixpkgs/nixos/tests/blockbook-frontend.nix
+++ b/nixpkgs/nixos/tests/blockbook-frontend.nix
@@ -1,7 +1,7 @@
import ./make-test-python.nix ({ pkgs, ... }: {
name = "blockbook-frontend";
meta = with pkgs.stdenv.lib; {
- maintainers = with maintainers; [ maintainers."1000101" ];
+ maintainers = with maintainers; [ _1000101 ];
};
machine = { ... }: {
diff --git a/nixpkgs/nixos/tests/caddy.nix b/nixpkgs/nixos/tests/caddy.nix
index 144d83179a1..445a7fa6b0b 100644
--- a/nixpkgs/nixos/tests/caddy.nix
+++ b/nixpkgs/nixos/tests/caddy.nix
@@ -1,7 +1,7 @@
import ./make-test-python.nix ({ pkgs, ... }: {
name = "caddy";
meta = with pkgs.stdenv.lib.maintainers; {
- maintainers = [ xfix ];
+ maintainers = [ xfix filalex77 ];
};
nodes = {
@@ -9,9 +9,10 @@ import ./make-test-python.nix ({ pkgs, ... }: {
services.caddy.enable = true;
services.caddy.config = ''
http://localhost {
- gzip
+ encode gzip
- root ${
+ file_server
+ root * ${
pkgs.runCommand "testdir" {} ''
mkdir "$out"
echo hello world > "$out/example.html"
@@ -23,9 +24,10 @@ import ./make-test-python.nix ({ pkgs, ... }: {
specialisation.etag.configuration = {
services.caddy.config = lib.mkForce ''
http://localhost {
- gzip
+ encode gzip
- root ${
+ file_server
+ root * ${
pkgs.runCommand "testdir2" {} ''
mkdir "$out"
echo changed > "$out/example.html"
@@ -59,9 +61,11 @@ import ./make-test-python.nix ({ pkgs, ... }: {
)
etag = etag.replace("\r\n", " ")
http_code = webserver.succeed(
- "curl -w \"%{{http_code}}\" -X HEAD -H 'If-None-Match: {}' {}".format(etag, url)
+ "curl --silent --show-error -o /dev/null -w \"%{{http_code}}\" --head -H 'If-None-Match: {}' {}".format(
+ etag, url
+ )
)
- assert int(http_code) == 304, "HTTP code is not 304"
+ assert int(http_code) == 304, "HTTP code is {}, expected 304".format(http_code)
return etag
diff --git a/nixpkgs/nixos/tests/charliecloud.nix b/nixpkgs/nixos/tests/charliecloud.nix
new file mode 100644
index 00000000000..acba41e228a
--- /dev/null
+++ b/nixpkgs/nixos/tests/charliecloud.nix
@@ -0,0 +1,43 @@
+# This test checks charliecloud image construction and run
+
+import ./make-test-python.nix ({ pkgs, ...} : let
+
+ dockerfile = pkgs.writeText "Dockerfile" ''
+ FROM nix
+ RUN mkdir /home /tmp
+ RUN touch /etc/passwd /etc/group
+ CMD ["true"]
+ '';
+
+in {
+ name = "charliecloud";
+ meta = with pkgs.stdenv.lib.maintainers; {
+ maintainers = [ bzizou ];
+ };
+
+ nodes = {
+ host = { ... }: {
+ environment.systemPackages = [ pkgs.charliecloud ];
+ virtualisation.docker.enable = true;
+ users.users.alice = {
+ isNormalUser = true;
+ extraGroups = [ "docker" ];
+ };
+ };
+ };
+
+ testScript = ''
+ host.start()
+ host.wait_for_unit("docker.service")
+ host.succeed(
+ 'su - alice -c "docker load --input=${pkgs.dockerTools.examples.nix}"'
+ )
+ host.succeed(
+ "cp ${dockerfile} /home/alice/Dockerfile"
+ )
+ host.succeed('su - alice -c "ch-build -t hello ."')
+ host.succeed('su - alice -c "ch-builder2tar hello /var/tmp"')
+ host.succeed('su - alice -c "ch-tar2dir /var/tmp/hello.tar.gz /var/tmp"')
+ host.succeed('su - alice -c "ch-run /var/tmp/hello -- echo Running_From_Container_OK"')
+ '';
+})
diff --git a/nixpkgs/nixos/tests/common/acme/client/default.nix b/nixpkgs/nixos/tests/common/acme/client/default.nix
index 80893da0252..1e9885e375c 100644
--- a/nixpkgs/nixos/tests/common/acme/client/default.nix
+++ b/nixpkgs/nixos/tests/common/acme/client/default.nix
@@ -1,15 +1,14 @@
{ lib, nodes, pkgs, ... }:
-
let
- acme-ca = nodes.acme.config.test-support.acme.caCert;
-in
+ caCert = nodes.acme.config.test-support.acme.caCert;
+ caDomain = nodes.acme.config.test-support.acme.caDomain;
-{
+in {
security.acme = {
- server = "https://acme.test/dir";
+ server = "https://${caDomain}/dir";
email = "hostmaster@example.test";
acceptTerms = true;
};
- security.pki.certificateFiles = [ acme-ca ];
+ security.pki.certificateFiles = [ caCert ];
}
diff --git a/nixpkgs/nixos/tests/common/acme/server/default.nix b/nixpkgs/nixos/tests/common/acme/server/default.nix
index 1a0ee882572..4d8e664c4e1 100644
--- a/nixpkgs/nixos/tests/common/acme/server/default.nix
+++ b/nixpkgs/nixos/tests/common/acme/server/default.nix
@@ -3,7 +3,7 @@
# config.test-support.acme.caCert
#
# This value can be used inside the configuration of other test nodes to inject
-# the snakeoil certificate into security.pki.certificateFiles or into package
+# the test certificate into security.pki.certificateFiles or into package
# overlays.
#
# Another value that's needed if you don't use a custom resolver (see below for
@@ -50,19 +50,13 @@
# Also make sure that whenever you use a resolver from a different test node
# that it has to be started _before_ the ACME service.
{ config, pkgs, lib, ... }:
-
-
let
- snakeOilCerts = import ./snakeoil-certs.nix;
-
- wfeDomain = "acme.test";
- wfeCertFile = snakeOilCerts.${wfeDomain}.cert;
- wfeKeyFile = snakeOilCerts.${wfeDomain}.key;
+ testCerts = import ./snakeoil-certs.nix {
+ minica = pkgs.minica;
+ mkDerivation = pkgs.stdenv.mkDerivation;
+ };
+ domain = testCerts.domain;
- siteDomain = "acme.test";
- siteCertFile = snakeOilCerts.${siteDomain}.cert;
- siteKeyFile = snakeOilCerts.${siteDomain}.key;
- pebble = pkgs.pebble;
resolver = let
message = "You need to define a resolver for the acme test module.";
firstNS = lib.head config.networking.nameservers;
@@ -71,8 +65,9 @@ let
pebbleConf.pebble = {
listenAddress = "0.0.0.0:443";
managementListenAddress = "0.0.0.0:15000";
- certificate = snakeOilCerts.${wfeDomain}.cert;
- privateKey = snakeOilCerts.${wfeDomain}.key;
+ # These certs and keys are used for the Web Front End (WFE)
+ certificate = testCerts.${domain}.cert;
+ privateKey = testCerts.${domain}.key;
httpPort = 80;
tlsPort = 443;
ocspResponderURL = "http://0.0.0.0:4002";
@@ -80,18 +75,30 @@ let
};
pebbleConfFile = pkgs.writeText "pebble.conf" (builtins.toJSON pebbleConf);
- pebbleDataDir = "/root/pebble";
in {
imports = [ ../../resolver.nix ];
- options.test-support.acme.caCert = lib.mkOption {
- type = lib.types.path;
- description = ''
- A certificate file to use with the <literal>nodes</literal> attribute to
- inject the snakeoil CA certificate used in the ACME server into
- <option>security.pki.certificateFiles</option>.
- '';
+ options.test-support.acme = with lib; {
+ caDomain = mkOption {
+ type = types.str;
+ readOnly = true;
+ default = domain;
+ description = ''
+ A domain name to use with the <literal>nodes</literal> attribute to
+ identify the CA server.
+ '';
+ };
+ caCert = mkOption {
+ type = types.path;
+ readOnly = true;
+ default = testCerts.ca.cert;
+ description = ''
+ A certificate file to use with the <literal>nodes</literal> attribute to
+ inject the test CA certificate used in the ACME server into
+ <option>security.pki.certificateFiles</option>.
+ '';
+ };
};
config = {
@@ -99,35 +106,32 @@ in {
resolver.enable = let
isLocalResolver = config.networking.nameservers == [ "127.0.0.1" ];
in lib.mkOverride 900 isLocalResolver;
- acme.caCert = snakeOilCerts.ca.cert;
};
# This has priority 140, because modules/testing/test-instrumentation.nix
# already overrides this with priority 150.
networking.nameservers = lib.mkOverride 140 [ "127.0.0.1" ];
- networking.firewall.enable = false;
+ networking.firewall.allowedTCPPorts = [ 80 443 15000 4002 ];
networking.extraHosts = ''
- 127.0.0.1 ${wfeDomain}
- ${config.networking.primaryIPAddress} ${wfeDomain} ${siteDomain}
+ 127.0.0.1 ${domain}
+ ${config.networking.primaryIPAddress} ${domain}
'';
systemd.services = {
pebble = {
enable = true;
description = "Pebble ACME server";
- requires = [ ];
wantedBy = [ "network.target" ];
- preStart = ''
- mkdir ${pebbleDataDir}
- '';
- script = ''
- cd ${pebbleDataDir}
- ${pebble}/bin/pebble -config ${pebbleConfFile}
- '';
+
serviceConfig = {
+ RuntimeDirectory = "pebble";
+ WorkingDirectory = "/run/pebble";
+
# Required to bind on privileged ports.
AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ];
+
+ ExecStart = "${pkgs.pebble}/bin/pebble -config ${pebbleConfFile}";
};
};
};
diff --git a/nixpkgs/nixos/tests/common/acme/server/mkcerts.nix b/nixpkgs/nixos/tests/common/acme/server/mkcerts.nix
deleted file mode 100644
index 2474019cbac..00000000000
--- a/nixpkgs/nixos/tests/common/acme/server/mkcerts.nix
+++ /dev/null
@@ -1,68 +0,0 @@
-{ pkgs ? import <nixpkgs> {}
-, lib ? pkgs.lib
-, domains ? [ "acme.test" ]
-}:
-
-pkgs.runCommand "acme-snakeoil-ca" {
- nativeBuildInputs = [ pkgs.openssl ];
-} ''
- addpem() {
- local file="$1"; shift
- local storeFileName="$(IFS=.; echo "$*")"
-
- echo -n " " >> "$out"
-
- # Every following argument is an attribute, so let's recurse and check
- # every attribute whether it must be quoted and write it into $out.
- while [ -n "$1" ]; do
- if expr match "$1" '^[a-zA-Z][a-zA-Z0-9]*$' > /dev/null; then
- echo -n "$1" >> "$out"
- else
- echo -n '"' >> "$out"
- echo -n "$1" | sed -e 's/["$]/\\&/g' >> "$out"
- echo -n '"' >> "$out"
- fi
- shift
- [ -z "$1" ] || echo -n . >> "$out"
- done
-
- echo " = builtins.toFile \"$storeFileName\" '''" >> "$out"
- sed -e 's/^/ /' "$file" >> "$out"
-
- echo " ''';" >> "$out"
- }
-
- echo '# Generated via mkcert.sh in the same directory.' > "$out"
- echo '{' >> "$out"
-
- openssl req -newkey rsa:4096 -x509 -sha256 -days 36500 \
- -subj '/CN=Snakeoil CA' -nodes -out ca.pem -keyout ca.key
-
- addpem ca.key ca key
- addpem ca.pem ca cert
-
- ${lib.concatMapStrings (fqdn: let
- opensslConfig = pkgs.writeText "snakeoil.cnf" ''
- [req]
- default_bits = 4096
- prompt = no
- default_md = sha256
- req_extensions = req_ext
- distinguished_name = dn
- [dn]
- CN = ${fqdn}
- [req_ext]
- subjectAltName = DNS:${fqdn}
- '';
- in ''
- export OPENSSL_CONF=${lib.escapeShellArg opensslConfig}
- openssl genrsa -out snakeoil.key 4096
- openssl req -new -key snakeoil.key -out snakeoil.csr
- openssl x509 -req -in snakeoil.csr -sha256 -set_serial 666 \
- -CA ca.pem -CAkey ca.key -out snakeoil.pem -days 36500
- addpem snakeoil.key ${lib.escapeShellArg fqdn} key
- addpem snakeoil.pem ${lib.escapeShellArg fqdn} cert
- '') domains}
-
- echo '}' >> "$out"
-''
diff --git a/nixpkgs/nixos/tests/common/acme/server/mkcerts.sh b/nixpkgs/nixos/tests/common/acme/server/mkcerts.sh
deleted file mode 100755
index cc7f8ca650d..00000000000
--- a/nixpkgs/nixos/tests/common/acme/server/mkcerts.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/usr/bin/env nix-shell
-#!nix-shell -p nix bash -i bash
-set -e
-cd "$(dirname "$0")"
-storepath="$(nix-build --no-out-link mkcerts.nix)"
-cat "$storepath" > snakeoil-certs.nix
diff --git a/nixpkgs/nixos/tests/common/acme/server/snakeoil-certs.nix b/nixpkgs/nixos/tests/common/acme/server/snakeoil-certs.nix
index fd537c3260f..4b6a38b8fa3 100644
--- a/nixpkgs/nixos/tests/common/acme/server/snakeoil-certs.nix
+++ b/nixpkgs/nixos/tests/common/acme/server/snakeoil-certs.nix
@@ -1,171 +1,37 @@
-# Generated via mkcert.sh in the same directory.
-{
- ca.key = builtins.toFile "ca.key" ''
- -----BEGIN PRIVATE KEY-----
- MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQDCnVZGEn68ezXl
- DWE5gjsCPqutR4nxw/wvIbAxB2Vk2WeQ6HGvt2Jdrz5qer2IXd76YtpQeqd+ffet
- aLtMeFTr+Xy9yqEpx2AfvmEEcLnuiWbsUGZzsHwW7/4kPgAFBy9TwJn/k892lR6u
- QYa0QS39CX85kLMZ/LZXUyClIBa+IxT1OovmGqMOr4nGASRQP6d/nnyn41Knat/d
- tpyaa5zgfYwA6YW6UxcywvBSpMOXM0/82BFZGyALt3nQ+ffmrtKcvMjsNLBFaslV
- +zYO1PMbLbTCW8SmJTjhzuapXtBHruvoe24133XWlvcP1ylaTx0alwiQWJr1XEOU
- WLEFTgOTeRyiVDxDunpz+7oGcwzcdOG8nCgd6w0aYaECz1zvS3FYTQz+MiqmEkx6
- s4bj1U90I0kwUJbeWjjrGO7Y9Qq4i19GafDg7cAMn9eHCiNbNrPj6t/gfaVbCrbk
- m3ZVjkvLTQ2mb2lv7+tVii45227iNPuNS6lx2FVlr/DXiRrOVfghPvoOxUfXzogJ
- hZLV4Zki+ycbGQa5w8YMDYCv4c08dKA7AatVhNS60c1zgQNjuWF3BvocSySyGUon
- VT6h1DYlJ9YAqgqNpedgNR9kpp034SMhB7dj9leB6LRMA+c1fG/T+1lDbkA+vope
- pt4+30oDcCTYfEifl1HwqNw/bXDm1wIDAQABAoICABPbd/UYaAQVUk93yQbUKe81
- s9CvbvzTMYUhm9e02Hyszitz/D2gqZHDksvMkFA8u8aylXIGwdZfRglUmV/ZG1kk
- kLzQ0xbvN/ilNUL9uYsETBMqtPly9YZloHnUNa5NqF+UVGJGk7GWz5WaLANybx3V
- fTzDbfLl3TkVy0vt9UQbUkUfXyzwZNjXwmgIr8rcY9vasP90a3eXqRX3Tw1Wk6A4
- TzO8oB994O0WBO150Fc6Lhwvc72yzddENlLDXq8UAXtqq9mmGqJKnhZ+1mo3AkMw
- q7P1JyCIxcAMm26GtRvLVljXV0x5640kxDrCin6jeeW/qWkJEW6dpmuZjR5scmLI
- /9n8H+fGzdZH8bOPPotMy12doj3vJqvew3p0eIkmVctYMJKD0j/CWjvKJNE3Yx4O
- Ls47X/dEypX6anR1HQUXcpd6JfRWdIJANo2Duaz+HYbyA88bHcJL9shFYcjLs3sX
- R/TvnnKHvw/ud7XBgvLGwGAf/cDEuLI2tv+V7tkMGrMUv+gUJNZaJaCpdt+1iUwO
- QFq8APyBNn6FFw54TwXWfSjfSNh3geIMLHuErYVu9MIXvB7Yhh+ZvLcfLbmckhAX
- wb39RRHnCWvnw5Bm9hnsDhqfDsIoP+2wvUkViyHOmrKi8nSJhSk19C8AuQtSVcJg
- 5op+epEmjt70GHt52nuBAoIBAQD2a4Ftp4QxWE2d6oAFI6WPrX7nAwI5/ezCbO/h
- yoYAn6ucTVnn5/5ITJ8V4WTWZ4lkoZP3YSJiCyBhs8fN63J+RaJ/bFRblHDns1HA
- 2nlMVdNLg6uOfjgUJ8Y6xVM0J2dcFtwIFyK5pfZ7loxMZfvuovg74vDOi2vnO3dO
- 16DP3zUx6B/yIt57CYn8NWTq+MO2bzKUnczUQRx0yEzPOfOmVbcqGP8f7WEdDWXm
- 7scjjN53OPyKzLOVEhOMsUhIMBMO25I9ZpcVkyj3/nj+fFLf/XjOTM00M/S/KnOj
- RwaWffx6mSYS66qNc5JSsojhIiYyiGVEWIznBpNWDU35y/uXAoIBAQDKLj0dyig2
- kj1r3HvdgK4sRULqBQFMqE9ylxDmpJxAj6/A8hJ0RCBR57vnIIZMzK4+6K0l3VBJ
- ukzXJHJLPkZ0Uuo2zLuRLkyjBECH6KYznyTkUVRn50Oq6IoP6WTCfd3Eg+7AKYY1
- VFo2iR8sxeSQQ+AylFy6QcQ1xPIW30Jj1/LFjrRdRggapPEekpJec0pEqhasT8rR
- UFhRL2NdZnL5b7ZlsJc7gZKEJgNfxgzaCzloqLcjCgGpOhLKx0fFsNOqHcbIGMwG
- 6wQCOyNghQJ6AZtRD5TYCJow92FchWjoTIaMJ8RjMKQmxpiwM6wQG4J78Hd3mbhf
- q0hiQhPHaNbBAoIBAFeIeMFq8BpXM7sUwcURlI4lIx8Mgo33FVM7PzsFpfQyw9MR
- 5w3p6vnjvd8X4aoHvVZxzw3hA0WwjiAmrKMJL/KK6d45rP2bDUBBAplvAgeLtTLt
- 4tMLIwCF4HSgA55TIPQlaqO1FDC+M4BTSiMZVxS970/WnZPBEuNgzFDFZ+pvb4X6
- 3t40ZLNwAAQHM4IEPAFiHqWMKGZ9eo5BWIeEHnjHmfjqSDYfLJAVYk1WJIcMUzom
- lA76CBC8CxW/I94AtcRhWuFUv/Z5/+OYEYLUxtuqPm+J+JrCmf4OJmWppT1wI2+p
- V00BSeRVWXTm1piieM8ahF5y1hp6y3uV3k0NmKECggEBAMC42Ms3s6NpPSE+99eJ
- 3P0YPJOkl7uByNGbTKH+kW89SDRsy8iGVCSe9892gm5cwU/4LWyljO3qp2qBNG2i
- /DfP/bCk8bqPXsAZwoWK8DrO3bTCDepJWYhlx40pVkHLBwVXGdOVAXh+YswPY2cj
- cB9QhDrSj52AKU9z36yLvtY7uBA3Wph6tCjpx2n0H4/m6AmR9LDmEpf5tWYV/OrA
- SKKaqUw/y7kOZyKOtbKqr/98qYmpIYFF/ZVZZSZkVXcNeoZzgdOlR37ksVqLEsrj
- nxu7wli/uItBj/FTLjyqcvjUUYDyO1KtwBuyPUPgzYhBIN2Rt9+K6WRQelwnToFL
- 30ECggEBALzozykZj2sr3z8tQQRZuXLGotUFGsQCB8ikeqoeB8FbNNkC+qgflQGv
- zLRB2KWOvnboc94wVgBJH43xG0HBibZnBhUO8/HBI/WlmyEj9KQ/ZskUK4GVZkB6
- r/81ASLwH+P/rqrLEjcp1SIPPevjzCWD9VYR5m/qPHLNxStwGSrPjtPzgaFxhq84
- Jl+YVmNqVlrOKYYfIPh8exPLiTti3wfM61pVYFv56PI2gd5ysMWYnuN+vK0sbmZh
- cIWwykcKlODIngI7IzYqt8NuIJI0jrYyHgtUw4jaJzdF4mEOplGONxdz15jAGHtg
- JUsBXFNz132nP4iIr3UKrPedQZijSi4=
- -----END PRIVATE KEY-----
- '';
- ca.cert = builtins.toFile "ca.cert" ''
- -----BEGIN CERTIFICATE-----
- MIIFDzCCAvegAwIBAgIUTRDYSWJvmlhwIR3pzVrIQfnboLEwDQYJKoZIhvcNAQEL
- BQAwFjEUMBIGA1UEAwwLU25ha2VvaWwgQ0EwIBcNMjAwMzIyMjI1NjE3WhgPMjEy
- MDAyMjcyMjU2MTdaMBYxFDASBgNVBAMMC1NuYWtlb2lsIENBMIICIjANBgkqhkiG
- 9w0BAQEFAAOCAg8AMIICCgKCAgEAwp1WRhJ+vHs15Q1hOYI7Aj6rrUeJ8cP8LyGw
- MQdlZNlnkOhxr7diXa8+anq9iF3e+mLaUHqnfn33rWi7THhU6/l8vcqhKcdgH75h
- BHC57olm7FBmc7B8Fu/+JD4ABQcvU8CZ/5PPdpUerkGGtEEt/Ql/OZCzGfy2V1Mg
- pSAWviMU9TqL5hqjDq+JxgEkUD+nf558p+NSp2rf3bacmmuc4H2MAOmFulMXMsLw
- UqTDlzNP/NgRWRsgC7d50Pn35q7SnLzI7DSwRWrJVfs2DtTzGy20wlvEpiU44c7m
- qV7QR67r6HtuNd911pb3D9cpWk8dGpcIkFia9VxDlFixBU4Dk3kcolQ8Q7p6c/u6
- BnMM3HThvJwoHesNGmGhAs9c70txWE0M/jIqphJMerOG49VPdCNJMFCW3lo46xju
- 2PUKuItfRmnw4O3ADJ/XhwojWzaz4+rf4H2lWwq25Jt2VY5Ly00Npm9pb+/rVYou
- Odtu4jT7jUupcdhVZa/w14kazlX4IT76DsVH186ICYWS1eGZIvsnGxkGucPGDA2A
- r+HNPHSgOwGrVYTUutHNc4EDY7lhdwb6HEskshlKJ1U+odQ2JSfWAKoKjaXnYDUf
- ZKadN+EjIQe3Y/ZXgei0TAPnNXxv0/tZQ25APr6KXqbePt9KA3Ak2HxIn5dR8Kjc
- P21w5tcCAwEAAaNTMFEwHQYDVR0OBBYEFCIoeYSYjtMiPrmxfHmcrsZkyTpvMB8G
- A1UdIwQYMBaAFCIoeYSYjtMiPrmxfHmcrsZkyTpvMA8GA1UdEwEB/wQFMAMBAf8w
- DQYJKoZIhvcNAQELBQADggIBAHPdwOgAxyhIhbqFObNftW8K3sptorB/Fj6jwYCm
- mHleFueqQnjTHMWsflOjREvQp1M307FWooGj+KQkjwvAyDc/Hmy7WgJxBg9p3vc+
- /Xf/e7ZfBl8rv7vH8VXW/BC1vVsILdFncrgTrP8/4psV50/cl1F4+nPBiekvvxwZ
- k+R7SgeSvcWT7YlOG8tm1M3al4F4mWzSRkYjkrXmwRCKAiya9xcGSt0Bob+LoM/O
- mpDGV/PMC1WAoDc1mMuXN2hSc0n68xMcuFs+dj/nQYn8uL5pzOxpX9560ynKyLDv
- yOzQlM2VuZ7H2hSIeYOFgrtHJJwhDtzjmUNDQpQdp9Fx+LONQTS1VLCTXND2i/3F
- 10X6PkdnLEn09RiPt5qy20pQkICxoEydmlwpFs32musYfJPdBPkZqZWrwINBv2Wb
- HfOmEB4xUvXufZ5Ju5icgggBkyNA3PCLo0GZFRrMtvA7i9IXOcXNR+njhKa9246V
- QQfeWiz05RmIvgShJYVsnZWtael8ni366d+UXypBYncohimyNlAD1n+Bh3z0PvBB
- +FK4JgOSeouM4SuBHdwmlZ/H0mvfUG81Y8Jbrw0yuRHtuCtX5HpN5GKpZPHDE7aQ
- fEShVB/GElC3n3DvgK9OJBeVVhYQgUEfJi4rsSxt3cdEI0NrdckUoZbApWVJ3CBc
- F8Y7
- -----END CERTIFICATE-----
- '';
- "acme.test".key = builtins.toFile "acme.test.key" ''
- -----BEGIN RSA PRIVATE KEY-----
- MIIJKAIBAAKCAgEAlgQTZjKfs3aHw0J993k7jFAs+hVRPf//zHMAiUkPKUYPTSl1
- TxS/bPbhWzSoom00j4SLhGGGhbd+lnvTg0uvKbxskgATfw5clbm1ZN+gx4DuxwjL
- V3xIxpeSY+PKzs5z8w/k+AJh+zOPyXwH3ut3C+ogp1S/5IhmzV3a/yU/6k0zpGxj
- N6ZPRTXFrz93I1pPeCkJz90l7tj+2uFc9xtM20NQX52f0Y2oShcG8fKdNZVzuHHk
- ZXkrZIhou55/nRy2jKgFeD3GQQfa9rwPWrVybQ6tKMMkoazB/Unky9xcTI2LJarf
- xgHDO9v9yFBvmR4UM8B3kM82NHoENtHaZ2mmiMGZzTEQlf8xwYyHFrqBFIVRWEUr
- 7rr/O5Qr9gIN0T4u367HCexVYAKzbO2P9h75czzjMMoGkbXze9SMQ/ikrxEmwAHg
- r1Xxh6iQYmgPNk8AR3d9+o2I7WJZMUYZARLnuhVr9BNXv510iqZTqX8lcyL5fEj3
- ST4Ab+H7rfevZt6NU26iJLBYAjrA2mSvH+wvkboxrgSS8xYPkOW8NLNEbbodzofI
- pB+SaK53OIk0bj9c1YAgrSNER/TDTgDXrWUNrlfVZ/M7+AEdeU06wi7sVhVif6OB
- D3OpgKSNjeE6TuJH80Pi5MWugSFBr792Xb6uhVoPiVOFN+qiGB6UkwBgSKkCAwEA
- AQKCAgAmN7OZfZwh5DiCDhZ5TXFWNba/n16rJOTN+R5R20L5iNetGLrCAs8hu2N+
- ENRFTPzu8x14BEB5IF4niDRCZq2hPFeMemh9HfOIUV9c63vSV459NkhXaVpA/axV
- tlqchQwVCB+U70Z28JPZCLgYmnQhnOvktTqNxhIqj5aTGbJGxpQ5d0Nvkfbv8tsB
- 4nE/mGpWel39jqFzT+Tdbjx414Ok+GkpcsacZDJTbbpfOSfD1uc8PgepskzTt8y2
- v5JTPFVlUAjUsSgouQ+XfCGNQlx8XBjRIaXbal+hX4niRald91FTr0yC7UAHp+vn
- dFZ586fB526OfbuZctxP+vZhEhFSseQKxHQ0tB8me81xH44daVNr9PPUM69FDT3j
- ygJaUJjNEG3vVzePCDzhmxTmz2/rAClp77WTWziBWDoA6YWDDzhgNPrXWzLIbZIx
- ue9ZbGEOh/u5ZzrEXxKCz9FjDe9wQu3TeYUe0M+ejzwWgn7zdWDvjjmtLUUuun2Y
- wW7WANpu32qvB/V+qssw4O63tbRiwneRCnb8AF2ixgyWr6xyZwch4kacv1KMiixf
- gO/5GTj7ba5GcdGoktJb29cUEgz13yPd106RsHK4vcggFxfMbOVauNRIo6ddLwyS
- 8UMxLf2i2cToOLkHZrIb8FgimmzRoBd3yYzwVJBydiVcsrHQAQKCAQEAxlzFYCiQ
- hjEtblGnrkOC7Hx6HvqMelViOkGN8Y9VczG4GhwntmSE2nbpaAKhFBGdLfuSI3tJ
- Lf24f0IGgAhzPmpo2TjbxPO3YSKFTH71fznVBhtQ1iSxwZ1InXktnuhot6VSDx6A
- sbHSy1hMFy3nj+Zj5+fQ89tclzBzG9bCShaauO39KrPMwKi6CYoYdGhXBC3+OpHY
- zBNvmDTxG2kW8L42rlf14EH4pAlgKs4eeZbpcbZ6fXURP2hToHJ8swyKw/1p12WA
- cc19BKFJXL8nNP4uCf/fI0mVYpytz5KwUzG+z+umDqk+RRCH4mNB28xvEEuEyp/e
- /C5Is+WrlDAA6QKCAQEAwZsK4AJ/w4Xf4Q/SsnZJO9bfP1ejJjzKElt8rG28JXeb
- +FjykZZ6vw2gt2Boest2n9N4fBwaRkaHVtVS4iAmaDXozTlcvCLs2rVjPSguuQtW
- 80CKg6+dux+6gFN8IGzDCiX3pWUnhhiXvCcRYEcvgpH6GA5vuCNrXrjH0JFC0kef
- aaDMGMTbzhc2IIRztmWU4v8YJSSy5KOkIQLWO+7u9aGx9IqT5/z3gx3XrItyl0Bk
- aQmZEh7JOSyhmGhhf5LdeTLu2YgRw3/tzS+lPMX3+UPw99k9MdTOFn2pww5AdRmg
- aBIzV+/LBYG0pPRl0D8/6yzGVBPuUDQpmK9Z3gsxwQKCAQEAnNkMZN2Ocd1+6+V7
- LmtJog9HTSmWXMEZG7FsOJ661Yxx44txx2IyPsCaDNlPXxwSaiKrSo0Yr1oZQd8G
- XsTPw4HGiETSWijQTulJ99PH8SLck6iTwdBgEhV5LrN75FQnQVdizHu1DUzrvkiC
- Wi29FWb6howiCEDjNNVln5SwKn83NpVQgyyK8ag4+oQMlDdQ3wgzJ0Ld53hS3Eq4
- f5EYR6JQgIki7YGcxrB3L0GujTxMONMuhfdEfRvUTGFawwVe0FyYDW7AIrx2Z2vV
- I5YuvVNjOhrt6OwtSD1VnnWCITaLh8LwmlUu3NOWbudHUzKSe5MLXGEPo95BNKad
- hl5yyQKCAQBNo0gMJtRnawMpdLfwewDJL1SdSR6S0ePS0r8/Qk4l1D5GrByyB183
- yFY/0zhyra7nTt1NH9PlhJj3WFqBdZURSzUNP0iR5YuH9R9Twg5ihEqdB6/EOSOO
- i521okTvl83q/ui9ecAMxUXr3NrZ+hHyUWmyRe/FLub6uCzg1a+vNauWpzXRZPgk
- QCijh5oDdd7r3JIpKvtWNs01s7aHmDxZYjtDrmK7sDTtboUzm0QbpWXevUuV+aSF
- +gDfZlRa3WFVHfisYSWGeYG6O7YOlfDoE7fJHGOu3QC8Ai6Wmtt8Wgd6VHokdHO8
- xJPVZnCBvyt5up3Zz5hMr25S3VazdVfBAoIBAHVteqTGqWpKFxekGwR0RqE30wmN
- iIEwFhgOZ8sQ+6ViZJZUR4Nn2fchn2jVwF8V8J1GrJbTknqzAwdXtO3FbgfmmyF2
- 9VbS/GgomXhA9vJkM4KK3Iwo/y/nE9hRhtzuVE0QPudz2fyfaDgnWjcNM59064tH
- 88361LVJm3ixyWSBD41UZ7NgWWJX1y2f073vErsfcPpavF5lhn1oSkQnOlgMJsnl
- 24qeuzAgTWu/2rFpIA2EK30Bgvsl3pjJxHwyNDAgklV7C783LIoAHi7VO7tzZ6iF
- dmD5XLfcUZc3eaB7XehNQKBXDGLJeI5AFmjsHka5GUoitkU2PFrg/3+nJmg=
- -----END RSA PRIVATE KEY-----
- '';
- "acme.test".cert = builtins.toFile "acme.test.cert" ''
- -----BEGIN CERTIFICATE-----
- MIIEoTCCAokCAgKaMA0GCSqGSIb3DQEBCwUAMBYxFDASBgNVBAMMC1NuYWtlb2ls
- IENBMCAXDTIwMDMyMjIyNTYxOFoYDzIxMjAwMjI3MjI1NjE4WjAUMRIwEAYDVQQD
- DAlhY21lLnRlc3QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCWBBNm
- Mp+zdofDQn33eTuMUCz6FVE9///McwCJSQ8pRg9NKXVPFL9s9uFbNKiibTSPhIuE
- YYaFt36We9ODS68pvGySABN/DlyVubVk36DHgO7HCMtXfEjGl5Jj48rOznPzD+T4
- AmH7M4/JfAfe63cL6iCnVL/kiGbNXdr/JT/qTTOkbGM3pk9FNcWvP3cjWk94KQnP
- 3SXu2P7a4Vz3G0zbQ1BfnZ/RjahKFwbx8p01lXO4ceRleStkiGi7nn+dHLaMqAV4
- PcZBB9r2vA9atXJtDq0owyShrMH9SeTL3FxMjYslqt/GAcM72/3IUG+ZHhQzwHeQ
- zzY0egQ20dpnaaaIwZnNMRCV/zHBjIcWuoEUhVFYRSvuuv87lCv2Ag3RPi7frscJ
- 7FVgArNs7Y/2HvlzPOMwygaRtfN71IxD+KSvESbAAeCvVfGHqJBiaA82TwBHd336
- jYjtYlkxRhkBEue6FWv0E1e/nXSKplOpfyVzIvl8SPdJPgBv4fut969m3o1TbqIk
- sFgCOsDaZK8f7C+RujGuBJLzFg+Q5bw0s0Rtuh3Oh8ikH5Jornc4iTRuP1zVgCCt
- I0RH9MNOANetZQ2uV9Vn8zv4AR15TTrCLuxWFWJ/o4EPc6mApI2N4TpO4kfzQ+Lk
- xa6BIUGvv3Zdvq6FWg+JU4U36qIYHpSTAGBIqQIDAQABMA0GCSqGSIb3DQEBCwUA
- A4ICAQBCDs0V4z00Ze6Ask3qDOLAPo4k85QCfItlRZmwl2XbPZq7kbe13MqF2wxx
- yiLalm6veK+ehU9MYN104hJZnuce5iEcZurk+8A+Pwn1Ifz+oWKVbUtUP3uV8Sm3
- chktJ2H1bebXtNJE5TwvdHiUkXU9ywQt2FkxiTSl6+eac7JKEQ8lVN/o6uYxF5ds
- +oIZplb7bv2XxsRCzq55F2tJX7fIzqXrSa+lQTnfLGmDVMAQX4TRB/lx0Gqd1a9y
- qGfFnZ7xVyW97f6PiL8MoxPfd2I2JzrzGyP/igNbFOW0ho1OwfxVmvZeS7fQSc5e
- +qu+nwnFfl0S4cHRif3G3zmz8Ryx9LM5TYkH41qePIHxoEO2sV0DgWJvbSjysV2S
- EU2a31dJ0aZ+z6YtZVpHlujKMVzxVTrqj74trS4LvU5h/9hv7e1gjYdox1TO0HMK
- mtDfgBevB21Tvxpz67Ijf31HvfTmCerKJEOjGnbYmyYpMeMNSONRDcToWk8sUwvi
- OWa5jlUFRAxgXNM09vCTPi9aRUhcFqACqfAd6I1NqGVlfplLWrc7SWaSa+PsLfBf
- 4EOZfk8iEKBVeYXNjg+CcD8j8yk/oEs816/jpihIk8haCDRWYWGKyyGnwn6OQb8d
- MdRO2b7Oi/AAmEF3jMlICqv286GIYK5qTKk2/CKHlOLPnsWEuA==
- -----END CERTIFICATE-----
- '';
+# Minica can provide a CA key and cert, plus a key
+# and cert for our fake CA server's Web Front End (WFE).
+{ minica, mkDerivation }:
+let
+ domain = "acme.test";
+
+ selfSignedCertData = mkDerivation {
+ name = "test-certs";
+ buildInputs = [ minica ];
+ phases = [ "buildPhase" "installPhase" ];
+
+ buildPhase = ''
+ mkdir ca
+ minica \
+ --ca-key ca/key.pem \
+ --ca-cert ca/cert.pem \
+ --domains ${domain}
+ chmod 600 ca/*
+ chmod 640 ${domain}/*.pem
+ '';
+
+ installPhase = ''
+ mkdir -p $out
+ mv ${domain} ca $out/
+ '';
+ };
+in {
+ inherit domain;
+ ca = {
+ cert = "${selfSignedCertData}/ca/cert.pem";
+ key = "${selfSignedCertData}/ca/key.pem";
+ };
+ "${domain}" = {
+ cert = "${selfSignedCertData}/${domain}/cert.pem";
+ key = "${selfSignedCertData}/${domain}/key.pem";
+ };
}
diff --git a/nixpkgs/nixos/tests/common/ec2.nix b/nixpkgs/nixos/tests/common/ec2.nix
index ba087bb6009..502fe96231f 100644
--- a/nixpkgs/nixos/tests/common/ec2.nix
+++ b/nixpkgs/nixos/tests/common/ec2.nix
@@ -20,30 +20,44 @@ with pkgs.lib;
in makeTest {
name = "ec2-" + name;
nodes = {};
- testScript =
- ''
- my $imageDir = ($ENV{'TMPDIR'} // "/tmp") . "/vm-state-machine";
- mkdir $imageDir, 0700;
- my $diskImage = "$imageDir/machine.qcow2";
- system("qemu-img create -f qcow2 -o backing_file=${image} $diskImage") == 0 or die;
- system("qemu-img resize $diskImage 10G") == 0 or die;
+ testScript = ''
+ import os
+ import subprocess
- # Note: we use net=169.0.0.0/8 rather than
- # net=169.254.0.0/16 to prevent dhcpcd from getting horribly
- # confused. (It would get a DHCP lease in the 169.254.*
- # range, which it would then configure and prompty delete
- # again when it deletes link-local addresses.) Ideally we'd
- # turn off the DHCP server, but qemu does not have an option
- # to do that.
- my $startCommand = "qemu-kvm -m 1024";
- $startCommand .= " -device virtio-net-pci,netdev=vlan0";
- $startCommand .= " -netdev 'user,id=vlan0,net=169.0.0.0/8,guestfwd=tcp:169.254.169.254:80-cmd:${pkgs.micro-httpd}/bin/micro_httpd ${metaData}'";
- $startCommand .= " -drive file=$diskImage,if=virtio,werror=report";
- $startCommand .= " \$QEMU_OPTS";
+ image_dir = os.path.join(
+ os.environ.get("TMPDIR", tempfile.gettempdir()), "tmp", "vm-state-machine"
+ )
+ os.makedirs(image_dir, mode=0o700, exist_ok=True)
+ disk_image = os.path.join(image_dir, "machine.qcow2")
+ subprocess.check_call(
+ [
+ "qemu-img",
+ "create",
+ "-f",
+ "qcow2",
+ "-o",
+ "backing_file=${image}",
+ disk_image,
+ ]
+ )
+ subprocess.check_call(["qemu-img", "resize", disk_image, "10G"])
- my $machine = createMachine({ startCommand => $startCommand });
+ # Note: we use net=169.0.0.0/8 rather than
+ # net=169.254.0.0/16 to prevent dhcpcd from getting horribly
+ # confused. (It would get a DHCP lease in the 169.254.*
+ # range, which it would then configure and prompty delete
+ # again when it deletes link-local addresses.) Ideally we'd
+ # turn off the DHCP server, but qemu does not have an option
+ # to do that.
+ start_command = (
+ "qemu-kvm -m 1024"
+ + " -device virtio-net-pci,netdev=vlan0"
+ + " -netdev 'user,id=vlan0,net=169.0.0.0/8,guestfwd=tcp:169.254.169.254:80-cmd:${pkgs.micro-httpd}/bin/micro_httpd ${metaData}'"
+ + f" -drive file={disk_image},if=virtio,werror=report"
+ + " $QEMU_OPTS"
+ )
- ${script}
- '';
+ machine = create_machine({"startCommand": start_command})
+ '' + script;
};
}
diff --git a/nixpkgs/nixos/tests/containers-reloadable.nix b/nixpkgs/nixos/tests/containers-reloadable.nix
index 35aff91e85b..2d81f163938 100644
--- a/nixpkgs/nixos/tests/containers-reloadable.nix
+++ b/nixpkgs/nixos/tests/containers-reloadable.nix
@@ -9,13 +9,13 @@ let
};
};
- # prevent make-test.nix to change IP
+ # prevent make-test-python.nix to change IP
networking.interfaces = {
eth1.ipv4.addresses = lib.mkOverride 0 [ ];
};
};
in {
- name = "cotnainers-reloadable";
+ name = "containers-reloadable";
meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ danbst ];
};
diff --git a/nixpkgs/nixos/tests/couchdb.nix b/nixpkgs/nixos/tests/couchdb.nix
index 10e95701acd..57b79e29b43 100644
--- a/nixpkgs/nixos/tests/couchdb.nix
+++ b/nixpkgs/nixos/tests/couchdb.nix
@@ -1,4 +1,19 @@
-import ./make-test-python.nix ({ pkgs, lib, ...}:
+let
+
+ makeNode = couchpkg: user: passwd:
+ { pkgs, ... } :
+
+ { environment.systemPackages = with pkgs; [ jq ];
+ services.couchdb.enable = true;
+ services.couchdb.package = couchpkg;
+ services.couchdb.adminUser = user;
+ services.couchdb.adminPass = passwd;
+ };
+ testuser = "testadmin";
+ testpass = "cowabunga";
+ testlogin = "${testuser}:${testpass}@";
+
+in import ./make-test-python.nix ({ pkgs, lib, ...}:
with lib;
@@ -9,26 +24,15 @@ with lib;
};
nodes = {
- couchdb1 =
- { pkgs, ... }:
-
- { environment.systemPackages = with pkgs; [ jq ];
- services.couchdb.enable = true;
- };
-
- couchdb2 =
- { pkgs, ... }:
-
- { environment.systemPackages = with pkgs; [ jq ];
- services.couchdb.enable = true;
- services.couchdb.package = pkgs.couchdb2;
- };
+ couchdb1 = makeNode pkgs.couchdb testuser testpass;
+ couchdb2 = makeNode pkgs.couchdb2 testuser testpass;
+ couchdb3 = makeNode pkgs.couchdb3 testuser testpass;
};
testScript = let
- curlJqCheck = action: path: jqexpr: result:
+ curlJqCheck = login: action: path: jqexpr: result:
pkgs.writeScript "curl-jq-check-${action}-${path}.sh" ''
- RESULT=$(curl -X ${action} http://127.0.0.1:5984/${path} | jq -r '${jqexpr}')
+ RESULT=$(curl -X ${action} http://${login}127.0.0.1:5984/${path} | jq -r '${jqexpr}')
echo $RESULT >&2
if [ "$RESULT" != "${result}" ]; then
exit 1
@@ -39,38 +43,56 @@ with lib;
couchdb1.wait_for_unit("couchdb.service")
couchdb1.wait_until_succeeds(
- "${curlJqCheck "GET" "" ".couchdb" "Welcome"}"
+ "${curlJqCheck "" "GET" "" ".couchdb" "Welcome"}"
)
couchdb1.wait_until_succeeds(
- "${curlJqCheck "GET" "_all_dbs" ". | length" "2"}"
+ "${curlJqCheck "" "GET" "_all_dbs" ". | length" "2"}"
)
- couchdb1.succeed("${curlJqCheck "PUT" "foo" ".ok" "true"}")
+ couchdb1.succeed("${curlJqCheck testlogin "PUT" "foo" ".ok" "true"}")
couchdb1.succeed(
- "${curlJqCheck "GET" "_all_dbs" ". | length" "3"}"
+ "${curlJqCheck "" "GET" "_all_dbs" ". | length" "3"}"
)
couchdb1.succeed(
- "${curlJqCheck "DELETE" "foo" ".ok" "true"}"
+ "${curlJqCheck testlogin "DELETE" "foo" ".ok" "true"}"
)
couchdb1.succeed(
- "${curlJqCheck "GET" "_all_dbs" ". | length" "2"}"
+ "${curlJqCheck "" "GET" "_all_dbs" ". | length" "2"}"
)
couchdb2.wait_for_unit("couchdb.service")
couchdb2.wait_until_succeeds(
- "${curlJqCheck "GET" "" ".couchdb" "Welcome"}"
+ "${curlJqCheck "" "GET" "" ".couchdb" "Welcome"}"
)
couchdb2.wait_until_succeeds(
- "${curlJqCheck "GET" "_all_dbs" ". | length" "0"}"
+ "${curlJqCheck "" "GET" "_all_dbs" ". | length" "0"}"
)
- couchdb2.succeed("${curlJqCheck "PUT" "foo" ".ok" "true"}")
+ couchdb2.succeed("${curlJqCheck testlogin "PUT" "foo" ".ok" "true"}")
couchdb2.succeed(
- "${curlJqCheck "GET" "_all_dbs" ". | length" "1"}"
+ "${curlJqCheck "" "GET" "_all_dbs" ". | length" "1"}"
)
couchdb2.succeed(
- "${curlJqCheck "DELETE" "foo" ".ok" "true"}"
+ "${curlJqCheck testlogin "DELETE" "foo" ".ok" "true"}"
)
couchdb2.succeed(
- "${curlJqCheck "GET" "_all_dbs" ". | length" "0"}"
+ "${curlJqCheck "" "GET" "_all_dbs" ". | length" "0"}"
+ )
+
+ couchdb3.wait_for_unit("couchdb.service")
+ couchdb3.wait_until_succeeds(
+ "${curlJqCheck testlogin "GET" "" ".couchdb" "Welcome"}"
+ )
+ couchdb3.wait_until_succeeds(
+ "${curlJqCheck testlogin "GET" "_all_dbs" ". | length" "0"}"
+ )
+ couchdb3.succeed("${curlJqCheck testlogin "PUT" "foo" ".ok" "true"}")
+ couchdb3.succeed(
+ "${curlJqCheck testlogin "GET" "_all_dbs" ". | length" "1"}"
+ )
+ couchdb3.succeed(
+ "${curlJqCheck testlogin "DELETE" "foo" ".ok" "true"}"
+ )
+ couchdb3.succeed(
+ "${curlJqCheck testlogin "GET" "_all_dbs" ". | length" "0"}"
)
'';
})
diff --git a/nixpkgs/nixos/tests/cri-o.nix b/nixpkgs/nixos/tests/cri-o.nix
new file mode 100644
index 00000000000..f13f1bdacb6
--- /dev/null
+++ b/nixpkgs/nixos/tests/cri-o.nix
@@ -0,0 +1,19 @@
+# This test runs CRI-O and verifies via critest
+import ./make-test-python.nix ({ pkgs, ... }: {
+ name = "cri-o";
+ maintainers = with pkgs.stdenv.lib.maintainers; teams.podman.members;
+
+ nodes = {
+ crio = {
+ virtualisation.cri-o.enable = true;
+ };
+ };
+
+ testScript = ''
+ start_all()
+ crio.wait_for_unit("crio.service")
+ crio.succeed(
+ "critest --ginkgo.focus='Runtime info' --runtime-endpoint unix:///var/run/crio/crio.sock"
+ )
+ '';
+})
diff --git a/nixpkgs/nixos/tests/docker-preloader.nix b/nixpkgs/nixos/tests/docker-preloader.nix
deleted file mode 100644
index c3e8aced351..00000000000
--- a/nixpkgs/nixos/tests/docker-preloader.nix
+++ /dev/null
@@ -1,27 +0,0 @@
-import ./make-test.nix ({ pkgs, ...} : {
- name = "docker-preloader";
- meta = with pkgs.stdenv.lib.maintainers; {
- maintainers = [ lewo ];
- };
-
- nodes = {
- docker =
- { pkgs, ... }:
- {
- virtualisation.docker.enable = true;
- virtualisation.dockerPreloader.images = [ pkgs.dockerTools.examples.nix pkgs.dockerTools.examples.bash ];
-
- services.openssh.enable = true;
- services.openssh.permitRootLogin = "yes";
- services.openssh.extraConfig = "PermitEmptyPasswords yes";
- users.extraUsers.root.password = "";
- };
- };
- testScript = ''
- startAll;
-
- $docker->waitForUnit("sockets.target");
- $docker->succeed("docker run nix nix-store --version");
- $docker->succeed("docker run bash bash --version");
- '';
-})
diff --git a/nixpkgs/nixos/tests/docker-tools.nix b/nixpkgs/nixos/tests/docker-tools.nix
index 2543801ae8b..edb9aec62db 100644
--- a/nixpkgs/nixos/tests/docker-tools.nix
+++ b/nixpkgs/nixos/tests/docker-tools.nix
@@ -219,18 +219,11 @@ import ./make-test-python.nix ({ pkgs, ... }: {
)
with subtest("Ensure correct behavior when no store is needed"):
- # This check tests two requirements simultaneously
- # 1. buildLayeredImage can build images that don't need a store.
- # 2. Layers of symlinks are eliminated by the customization layer.
- #
+ # This check tests that buildLayeredImage can build images that don't need a store.
docker.succeed(
"docker load --input='${pkgs.dockerTools.examples.no-store-paths}'"
)
- # Busybox will not recognize argv[0] and print an error message with argv[0],
- # but it confirms that the custom-true symlink is present.
- docker.succeed("docker run --rm no-store-paths custom-true |& grep custom-true")
-
# This check may be loosened to allow an *empty* store rather than *no* store.
docker.succeed("docker run --rm no-store-paths ls /")
docker.fail("docker run --rm no-store-paths ls /nix/store")
diff --git a/nixpkgs/nixos/tests/dokuwiki.nix b/nixpkgs/nixos/tests/dokuwiki.nix
index 4f00521c202..58069366ca3 100644
--- a/nixpkgs/nixos/tests/dokuwiki.nix
+++ b/nixpkgs/nixos/tests/dokuwiki.nix
@@ -33,24 +33,16 @@ let
in {
name = "dokuwiki";
meta = with pkgs.stdenv.lib; {
- maintainers = with maintainers; [ maintainers."1000101" ];
+ maintainers = with maintainers; [ _1000101 ];
};
machine = { ... }: {
services.dokuwiki."site1.local" = {
aclUse = false;
superUser = "admin";
- nginx = {
- forceSSL = false;
- enableACME = false;
- };
};
services.dokuwiki."site2.local" = {
- aclUse = true;
+ usersFile = "/var/lib/dokuwiki/site2.local/users.auth.php";
superUser = "admin";
- nginx = {
- forceSSL = false;
- enableACME = false;
- };
templates = [ template-bootstrap3 ];
plugins = [ plugin-icalevents ];
};
@@ -70,6 +62,15 @@ in {
machine.wait_for_open_port(80)
machine.succeed("curl -sSfL http://site1.local/ | grep 'DokuWiki'")
+ machine.fail("curl -sSfL 'http://site1.local/doku.php?do=login' | grep 'Login'")
+
machine.succeed("curl -sSfL http://site2.local/ | grep 'DokuWiki'")
+ machine.succeed("curl -sSfL 'http://site2.local/doku.php?do=login' | grep 'Login'")
+
+ machine.succeed(
+ "echo 'admin:$2y$10$ijdBQMzSVV20SrKtCna8gue36vnsbVm2wItAXvdm876sshI4uwy6S:Admin:admin@example.test:user' >> /var/lib/dokuwiki/site2.local/users.auth.php",
+ "curl -sSfL -d 'u=admin&p=password' --cookie-jar cjar 'http://site2.local/doku.php?do=login'",
+ "curl -sSfL --cookie cjar --cookie-jar cjar 'http://site2.local/doku.php?do=login' | grep 'Logged in as: <bdi>Admin</bdi>'",
+ )
'';
})
diff --git a/nixpkgs/nixos/tests/ec2.nix b/nixpkgs/nixos/tests/ec2.nix
index 5a59d65e602..df067248016 100644
--- a/nixpkgs/nixos/tests/ec2.nix
+++ b/nixpkgs/nixos/tests/ec2.nix
@@ -3,58 +3,58 @@
pkgs ? import ../.. { inherit system config; }
}:
-with import ../lib/testing.nix { inherit system pkgs; };
+with import ../lib/testing-python.nix { inherit system pkgs; };
with pkgs.lib;
with import common/ec2.nix { inherit makeTest pkgs; };
let
- imageCfg =
- (import ../lib/eval-config.nix {
- inherit system;
- modules = [
- ../maintainers/scripts/ec2/amazon-image.nix
- ../modules/testing/test-instrumentation.nix
- ../modules/profiles/qemu-guest.nix
- { ec2.hvm = true;
-
- # Hack to make the partition resizing work in QEMU.
- boot.initrd.postDeviceCommands = mkBefore
- ''
- ln -s vda /dev/xvda
- ln -s vda1 /dev/xvda1
- '';
-
- # Needed by nixos-rebuild due to the lack of network
- # access. Determined by trial and error.
- system.extraDependencies =
- with pkgs; (
- [
- # Needed for a nixos-rebuild.
- busybox
- stdenv
- stdenvNoCC
- mkinitcpio-nfs-utils
- unionfs-fuse
- cloud-utils
- desktop-file-utils
- texinfo
- libxslt.bin
- xorg.lndir
-
- # These are used in the configure-from-userdata tests
- # for EC2. Httpd and valgrind are requested by the
- # configuration.
- apacheHttpd apacheHttpd.doc apacheHttpd.man valgrind.doc
- ]
- );
- }
- ];
- }).config;
+ imageCfg = (import ../lib/eval-config.nix {
+ inherit system;
+ modules = [
+ ../maintainers/scripts/ec2/amazon-image.nix
+ ../modules/testing/test-instrumentation.nix
+ ../modules/profiles/qemu-guest.nix
+ {
+ ec2.hvm = true;
+
+ # Hack to make the partition resizing work in QEMU.
+ boot.initrd.postDeviceCommands = mkBefore ''
+ ln -s vda /dev/xvda
+ ln -s vda1 /dev/xvda1
+ '';
+
+ # Needed by nixos-rebuild due to the lack of network
+ # access. Determined by trial and error.
+ system.extraDependencies = with pkgs; ( [
+ # Needed for a nixos-rebuild.
+ busybox
+ cloud-utils
+ desktop-file-utils
+ libxslt.bin
+ mkinitcpio-nfs-utils
+ stdenv
+ stdenvNoCC
+ texinfo
+ unionfs-fuse
+ xorg.lndir
+
+ # These are used in the configure-from-userdata tests
+ # for EC2. Httpd and valgrind are requested by the
+ # configuration.
+ apacheHttpd
+ apacheHttpd.doc
+ apacheHttpd.man
+ valgrind.doc
+ ]);
+ }
+ ];
+ }).config;
image = "${imageCfg.system.build.amazonImage}/${imageCfg.amazonImage.name}.vhd";
sshKeys = import ./ssh-keys.nix pkgs;
snakeOilPrivateKey = sshKeys.snakeOilPrivateKey.text;
+ snakeOilPrivateKeyFile = pkgs.writeText "private-key" snakeOilPrivateKey;
snakeOilPublicKey = sshKeys.snakeOilPublicKey;
in {
@@ -68,43 +68,47 @@ in {
SSH_HOST_ED25519_KEY:${replaceStrings ["\n"] ["|"] snakeOilPrivateKey}
'';
script = ''
- $machine->start;
- $machine->waitForFile("/etc/ec2-metadata/user-data");
- $machine->waitForUnit("sshd.service");
+ machine.start()
+ machine.wait_for_file("/etc/ec2-metadata/user-data")
+ machine.wait_for_unit("sshd.service")
- $machine->succeed("grep unknown /etc/ec2-metadata/ami-manifest-path");
+ machine.succeed("grep unknown /etc/ec2-metadata/ami-manifest-path")
# We have no keys configured on the client side yet, so this should fail
- $machine->fail("ssh -o BatchMode=yes localhost exit");
+ machine.fail("ssh -o BatchMode=yes localhost exit")
# Let's install our client private key
- $machine->succeed("mkdir -p ~/.ssh");
+ machine.succeed("mkdir -p ~/.ssh")
- $machine->succeed("echo '${snakeOilPrivateKey}' > ~/.ssh/id_ed25519");
- $machine->succeed("chmod 600 ~/.ssh/id_ed25519");
+ machine.copy_from_host_via_shell(
+ "${snakeOilPrivateKeyFile}", "~/.ssh/id_ed25519"
+ )
+ machine.succeed("chmod 600 ~/.ssh/id_ed25519")
# We haven't configured the host key yet, so this should still fail
- $machine->fail("ssh -o BatchMode=yes localhost exit");
+ machine.fail("ssh -o BatchMode=yes localhost exit")
# Add the host key; ssh should finally succeed
- $machine->succeed("echo localhost,127.0.0.1 ${snakeOilPublicKey} > ~/.ssh/known_hosts");
- $machine->succeed("ssh -o BatchMode=yes localhost exit");
+ machine.succeed(
+ "echo localhost,127.0.0.1 ${snakeOilPublicKey} > ~/.ssh/known_hosts"
+ )
+ machine.succeed("ssh -o BatchMode=yes localhost exit")
# Test whether the root disk was resized.
- my $blocks = $machine->succeed("stat -c %b -f /");
- my $bsize = $machine->succeed("stat -c %S -f /");
- my $size = $blocks * $bsize;
- die "wrong free space $size" if $size < 9.7 * 1024 * 1024 * 1024 || $size > 10 * 1024 * 1024 * 1024;
+ blocks, block_size = map(int, machine.succeed("stat -c %b:%S -f /").split(":"))
+ GB = 1024 ** 3
+ assert 9.7 * GB <= blocks * block_size <= 10 * GB
# Just to make sure resizing is idempotent.
- $machine->shutdown;
- $machine->start;
- $machine->waitForFile("/etc/ec2-metadata/user-data");
+ machine.shutdown()
+ machine.start()
+ machine.wait_for_file("/etc/ec2-metadata/user-data")
'';
};
boot-ec2-config = makeEc2Test {
name = "config-userdata";
+ meta.broken = true; # amazon-init wants to download from the internet while building the system
inherit image;
sshPublicKey = snakeOilPublicKey;
@@ -133,17 +137,17 @@ in {
}
'';
script = ''
- $machine->start;
+ machine.start()
# amazon-init must succeed. if it fails, make the test fail
- # immediately instead of timing out in waitForFile.
- $machine->waitForUnit('amazon-init.service');
+ # immediately instead of timing out in wait_for_file.
+ machine.wait_for_unit("amazon-init.service")
- $machine->waitForFile("/etc/testFile");
- $machine->succeed("cat /etc/testFile | grep -q 'whoa'");
+ machine.wait_for_file("/etc/testFile")
+ assert "whoa" in machine.succeed("cat /etc/testFile")
- $machine->waitForUnit("httpd.service");
- $machine->succeed("curl http://localhost | grep Valgrind");
+ machine.wait_for_unit("httpd.service")
+ assert "Valgrind" in machine.succeed("curl http://localhost")
'';
};
}
diff --git a/nixpkgs/nixos/tests/firejail.nix b/nixpkgs/nixos/tests/firejail.nix
new file mode 100644
index 00000000000..a723cb01664
--- /dev/null
+++ b/nixpkgs/nixos/tests/firejail.nix
@@ -0,0 +1,82 @@
+import ./make-test-python.nix ({ pkgs, ...} : {
+ name = "firejail";
+ meta = with pkgs.stdenv.lib.maintainers; {
+ maintainers = [ sgo ];
+ };
+
+ nodes.machine = { ... }: {
+ imports = [ ./common/user-account.nix ];
+
+ programs.firejail = {
+ enable = true;
+ wrappedBinaries = {
+ bash-jailed = "${pkgs.bash}/bin/bash";
+ };
+ };
+
+ systemd.services.setupFirejailTest = {
+ wantedBy = [ "multi-user.target" ];
+ before = [ "multi-user.target" ];
+
+ environment = {
+ HOME = "/home/alice";
+ };
+
+ unitConfig = {
+ type = "oneshot";
+ RemainAfterExit = true;
+ user = "alice";
+ };
+
+ script = ''
+ cd $HOME
+
+ mkdir .password-store && echo s3cret > .password-store/secret
+ mkdir my-secrets && echo s3cret > my-secrets/secret
+
+ echo publ1c > public
+
+ mkdir -p .config/firejail
+ echo 'blacklist ''${HOME}/my-secrets' > .config/firejail/globals.local
+ '';
+ };
+ };
+
+ testScript = ''
+ start_all()
+ machine.wait_for_unit("multi-user.target")
+
+ # Test path acl with wrapper
+ machine.succeed("sudo -u alice bash-jailed -c 'cat ~/public' | grep -q publ1c")
+ machine.fail(
+ "sudo -u alice bash-jailed -c 'cat ~/.password-store/secret' | grep -q s3cret"
+ )
+ machine.fail("sudo -u alice bash-jailed -c 'cat ~/my-secrets/secret' | grep -q s3cret")
+
+
+ # Test path acl with firejail executable
+ machine.succeed("sudo -u alice firejail -- bash -c 'cat ~/public' | grep -q publ1c")
+ machine.fail(
+ "sudo -u alice firejail -- bash -c 'cat ~/.password-store/secret' | grep -q s3cret"
+ )
+ machine.fail(
+ "sudo -u alice firejail -- bash -c 'cat ~/my-secrets/secret' | grep -q s3cret"
+ )
+
+ # Disabling profiles
+ machine.succeed(
+ "sudo -u alice bash -c 'firejail --noprofile -- cat ~/.password-store/secret' | grep -q s3cret"
+ )
+
+ # CVE-2020-17367
+ machine.fail(
+ "sudo -u alice firejail --private-tmp id --output=/tmp/vuln1 && cat /tmp/vuln1"
+ )
+
+ # CVE-2020-17368
+ machine.fail(
+ "sudo -u alice firejail --private-tmp --output=/tmp/foo 'bash -c $(id>/tmp/vuln2;echo id)' && cat /tmp/vuln2"
+ )
+ '';
+})
+
diff --git a/nixpkgs/nixos/tests/gnome3.nix b/nixpkgs/nixos/tests/gnome3.nix
index b3d7aff8bd7..7e301be49d1 100644
--- a/nixpkgs/nixos/tests/gnome3.nix
+++ b/nixpkgs/nixos/tests/gnome3.nix
@@ -23,6 +23,13 @@ import ./make-test-python.nix ({ pkgs, lib, ...} : {
services.xserver.desktopManager.gnome3.enable = true;
services.xserver.desktopManager.gnome3.debug = true;
+ environment.systemPackages = [
+ (pkgs.makeAutostartItem {
+ name = "org.gnome.Terminal";
+ package = pkgs.gnome3.gnome-terminal;
+ })
+ ];
+
virtualisation.memorySize = 1024;
};
@@ -65,9 +72,6 @@ import ./make-test-python.nix ({ pkgs, lib, ...} : {
)
with subtest("Open Gnome Terminal"):
- machine.succeed(
- "${gnomeTerminalCommand}"
- )
# correct output should be (true, '"gnome-terminal-server"')
machine.wait_until_succeeds(
"${wmClass} | grep -q 'gnome-terminal-server'"
diff --git a/nixpkgs/nixos/tests/gotify-server.nix b/nixpkgs/nixos/tests/gotify-server.nix
index c6e00686aed..c0b8ba43548 100644
--- a/nixpkgs/nixos/tests/gotify-server.nix
+++ b/nixpkgs/nixos/tests/gotify-server.nix
@@ -41,5 +41,10 @@ import ./make-test-python.nix ({ pkgs, lib, ...} : {
)
assert title == "Gotify"
+
+ # Ensure that the UI responds with a successfuly code and that the
+ # response is not empty
+ result = machine.succeed("curl -fsS localhost:3000")
+ assert result, "HTTP response from localhost:3000 must not be empty!"
'';
})
diff --git a/nixpkgs/nixos/tests/hardened.nix b/nixpkgs/nixos/tests/hardened.nix
index 5ed0dfcf9ab..8d845de70e2 100644
--- a/nixpkgs/nixos/tests/hardened.nix
+++ b/nixpkgs/nixos/tests/hardened.nix
@@ -1,4 +1,4 @@
-import ./make-test.nix ({ pkgs, latestKernel ? false, ... } : {
+import ./make-test-python.nix ({ pkgs, latestKernel ? false, ... } : {
name = "hardened";
meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ joachifm ];
@@ -47,84 +47,88 @@ import ./make-test.nix ({ pkgs, latestKernel ? false, ... } : {
};
in
''
- $machine->waitForUnit("multi-user.target");
+ machine.wait_for_unit("multi-user.target")
+
+
+ with subtest("AppArmor profiles are loaded"):
+ machine.succeed("systemctl status apparmor.service")
- subtest "apparmor-loaded", sub {
- $machine->succeed("systemctl status apparmor.service");
- };
# AppArmor securityfs
- subtest "apparmor-securityfs", sub {
- $machine->succeed("mountpoint -q /sys/kernel/security");
- $machine->succeed("cat /sys/kernel/security/apparmor/profiles");
- };
+ with subtest("AppArmor securityfs is mounted"):
+ machine.succeed("mountpoint -q /sys/kernel/security")
+ machine.succeed("cat /sys/kernel/security/apparmor/profiles")
+
# Test loading out-of-tree modules
- subtest "extra-module-packages", sub {
- $machine->succeed("grep -Fq wireguard /proc/modules");
- };
+ with subtest("Out-of-tree modules can be loaded"):
+ machine.succeed("grep -Fq wireguard /proc/modules")
+
# Test hidepid
- subtest "hidepid", sub {
- $machine->succeed("grep -Fq hidepid=2 /proc/mounts");
+ with subtest("hidepid=2 option is applied and works"):
+ machine.succeed("grep -Fq hidepid=2 /proc/mounts")
# cannot use pgrep -u here, it segfaults when access to process info is denied
- $machine->succeed("[ `su - sybil -c 'ps --no-headers --user root | wc -l'` = 0 ]");
- $machine->succeed("[ `su - alice -c 'ps --no-headers --user root | wc -l'` != 0 ]");
- };
+ machine.succeed("[ `su - sybil -c 'ps --no-headers --user root | wc -l'` = 0 ]")
+ machine.succeed("[ `su - alice -c 'ps --no-headers --user root | wc -l'` != 0 ]")
+
# Test kernel module hardening
- subtest "lock-modules", sub {
+ with subtest("No more kernel modules can be loaded"):
# note: this better a be module we normally wouldn't load ...
- $machine->fail("modprobe dccp");
- };
+ machine.fail("modprobe dccp")
+
# Test userns
- subtest "userns", sub {
- $machine->succeed("unshare --user true");
- $machine->fail("su -l alice -c 'unshare --user true'");
- };
+ with subtest("User namespaces are restricted"):
+ machine.succeed("unshare --user true")
+ machine.fail("su -l alice -c 'unshare --user true'")
+
# Test dmesg restriction
- subtest "dmesg", sub {
- $machine->fail("su -l alice -c dmesg");
- };
+ with subtest("Regular users cannot access dmesg"):
+ machine.fail("su -l alice -c dmesg")
+
# Test access to kcore
- subtest "kcore", sub {
- $machine->fail("cat /proc/kcore");
- };
+ with subtest("Kcore is inaccessible as root"):
+ machine.fail("cat /proc/kcore")
+
# Test deferred mount
- subtest "mount", sub {
- $machine->fail("mountpoint -q /efi"); # was deferred
- $machine->execute("mkdir -p /efi");
- $machine->succeed("mount /dev/disk/by-label/EFISYS /efi");
- $machine->succeed("mountpoint -q /efi"); # now mounted
- };
+ with subtest("Deferred mounts work"):
+ machine.fail("mountpoint -q /efi") # was deferred
+ machine.execute("mkdir -p /efi")
+ machine.succeed("mount /dev/disk/by-label/EFISYS /efi")
+ machine.succeed("mountpoint -q /efi") # now mounted
+
# Test Nix dæmon usage
- subtest "nix-daemon", sub {
- $machine->fail("su -l nobody -s /bin/sh -c 'nix ping-store'");
- $machine->succeed("su -l alice -c 'nix ping-store'") =~ "OK";
- };
+ with subtest("nix-daemon cannot be used by all users"):
+ machine.fail("su -l nobody -s /bin/sh -c 'nix ping-store'")
+ machine.succeed("su -l alice -c 'nix ping-store'")
+
# Test kernel image protection
- subtest "kernelimage", sub {
- $machine->fail("systemctl hibernate");
- $machine->fail("systemctl kexec");
- };
+ with subtest("The kernel image is protected"):
+ machine.fail("systemctl hibernate")
+ machine.fail("systemctl kexec")
- # Test hardened memory allocator
- sub runMallocTestProg {
- my ($progName, $errorText) = @_;
- my $text = "fatal allocator error: " . $errorText;
- $machine->fail("${hardened-malloc-tests}/bin/" . $progName) =~ $text;
- };
- subtest "hardenedmalloc", sub {
- runMallocTestProg("double_free_large", "invalid free");
- runMallocTestProg("unaligned_free_small", "invalid unaligned free");
- runMallocTestProg("write_after_free_small", "detected write after free");
- };
+ # Test hardened memory allocator
+ def runMallocTestProg(prog_name, error_text):
+ text = "fatal allocator error: " + error_text
+ if not text in machine.fail(
+ "${hardened-malloc-tests}/bin/"
+ + prog_name
+ + " 2>&1"
+ ):
+ raise Exception("Hardened malloc does not work for {}".format(error_text))
+
+
+ with subtest("The hardened memory allocator works"):
+ runMallocTestProg("double_free_large", "invalid free")
+ runMallocTestProg("unaligned_free_small", "invalid unaligned free")
+ runMallocTestProg("write_after_free_small", "detected write after free")
'';
})
diff --git a/nixpkgs/nixos/tests/hocker-fetchdocker/default.nix b/nixpkgs/nixos/tests/hocker-fetchdocker/default.nix
index 4f30f01e403..978dbf310b1 100644
--- a/nixpkgs/nixos/tests/hocker-fetchdocker/default.nix
+++ b/nixpkgs/nixos/tests/hocker-fetchdocker/default.nix
@@ -1,15 +1,16 @@
-import ../make-test.nix ({ pkgs, ...} : {
+import ../make-test-python.nix ({ pkgs, ...} : {
name = "test-hocker-fetchdocker";
meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ ixmatus ];
+ broken = true; # tries to download from registry-1.docker.io - how did this ever work?
};
machine = import ./machine.nix;
testScript = ''
- startAll;
+ start_all()
- $machine->waitForUnit("sockets.target");
- $machine->waitUntilSucceeds("docker run registry-1.docker.io/v2/library/hello-world:latest");
+ machine.wait_for_unit("sockets.target")
+ machine.wait_until_succeeds("docker run registry-1.docker.io/v2/library/hello-world:latest")
'';
})
diff --git a/nixpkgs/nixos/tests/installer.nix b/nixpkgs/nixos/tests/installer.nix
index 02b839fee3f..d80cfb4bd83 100644
--- a/nixpkgs/nixos/tests/installer.nix
+++ b/nixpkgs/nixos/tests/installer.nix
@@ -74,7 +74,7 @@ let
throw "Non-EFI boot methods are only supported on i686 / x86_64"
else ''
def assemble_qemu_flags():
- flags = "-cpu host"
+ flags = "-cpu max"
${if system == "x86_64-linux"
then ''flags += " -m 768"''
else ''flags += " -m 512 -enable-kvm -machine virt,gic-version=host"''
@@ -285,7 +285,7 @@ let
];
virtualisation.diskSize = 8 * 1024;
- virtualisation.memorySize = 1024;
+ virtualisation.memorySize = 1536;
# Use a small /dev/vdb as the root disk for the
# installer. This ensures the target disk (/dev/vda) is
@@ -633,10 +633,10 @@ in {
+ " mklabel msdos"
+ " mkpart primary ext2 1M 100MB" # /boot
+ " mkpart extended 100M -1s"
- + " mkpart logical 102M 2102M" # md0 (root), first device
- + " mkpart logical 2103M 4103M" # md0 (root), second device
- + " mkpart logical 4104M 4360M" # md1 (swap), first device
- + " mkpart logical 4361M 4617M", # md1 (swap), second device
+ + " mkpart logical 102M 3102M" # md0 (root), first device
+ + " mkpart logical 3103M 6103M" # md0 (root), second device
+ + " mkpart logical 6104M 6360M" # md1 (swap), first device
+ + " mkpart logical 6361M 6617M", # md1 (swap), second device
"udevadm settle",
"ls -l /dev/vda* >&2",
"cat /proc/partitions >&2",
@@ -799,7 +799,7 @@ in {
"btrfs subvol create /mnt/badpath/boot",
"btrfs subvol create /mnt/nixos",
"btrfs subvol set-default "
- + "$(btrfs subvol list /mnt | grep 'nixos' | awk '{print \$2}') /mnt",
+ + "$(btrfs subvol list /mnt | grep 'nixos' | awk '{print $2}') /mnt",
"umount /mnt",
"mount -o defaults LABEL=root /mnt",
"mkdir -p /mnt/badpath/boot", # Help ensure the detection mechanism
diff --git a/nixpkgs/nixos/tests/krb5/example-config.nix b/nixpkgs/nixos/tests/krb5/example-config.nix
index be195b51393..e2e10a9fda8 100644
--- a/nixpkgs/nixos/tests/krb5/example-config.nix
+++ b/nixpkgs/nixos/tests/krb5/example-config.nix
@@ -18,7 +18,10 @@ import ../make-test-python.nix ({ pkgs, ...} : {
realms = {
"ATHENA.MIT.EDU" = {
admin_server = "athena.mit.edu";
- kdc = "athena.mit.edu";
+ kdc = [
+ "athena01.mit.edu"
+ "athena02.mit.edu"
+ ];
};
};
domain_realm = {
@@ -65,7 +68,8 @@ import ../make-test-python.nix ({ pkgs, ...} : {
[realms]
ATHENA.MIT.EDU = {
admin_server = athena.mit.edu
- kdc = athena.mit.edu
+ kdc = athena01.mit.edu
+ kdc = athena02.mit.edu
}
[domain_realm]
diff --git a/nixpkgs/nixos/tests/lxd-nftables.nix b/nixpkgs/nixos/tests/lxd-nftables.nix
index 25517914db8..4ca02067a0a 100644
--- a/nixpkgs/nixos/tests/lxd-nftables.nix
+++ b/nixpkgs/nixos/tests/lxd-nftables.nix
@@ -7,6 +7,7 @@
import ./make-test-python.nix ({ pkgs, ...} : {
name = "lxd-nftables";
+
meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ patryk27 ];
};
diff --git a/nixpkgs/nixos/tests/lxd.nix b/nixpkgs/nixos/tests/lxd.nix
index db2d44dff55..d1e642383cf 100644
--- a/nixpkgs/nixos/tests/lxd.nix
+++ b/nixpkgs/nixos/tests/lxd.nix
@@ -6,15 +6,14 @@ let
#
# I've chosen to import Alpine Linux, because its image is turbo-tiny and,
# generally, sufficient for our tests.
-
alpine-meta = pkgs.fetchurl {
- url = "https://uk.images.linuxcontainers.org/images/alpine/3.11/i386/default/20200608_13:00/lxd.tar.xz";
- sha256 = "1hkvaj3rr333zmx1759njy435lps33gl4ks8zfm7m4nqvipm26a0";
+ url = "https://tarballs.nixos.org/alpine/3.12/lxd.tar.xz";
+ hash = "sha256-1tcKaO9lOkvqfmG/7FMbfAEToAuFy2YMewS8ysBKuLA=";
};
alpine-rootfs = pkgs.fetchurl {
- url = "https://uk.images.linuxcontainers.org/images/alpine/3.11/i386/default/20200608_13:00/rootfs.tar.xz";
- sha256 = "1v82zdra4j5xwsff09qlp7h5vbsg54s0j7rdg4rynichfid3r347";
+ url = "https://tarballs.nixos.org/alpine/3.12/rootfs.tar.xz";
+ hash = "sha256-Tba9sSoaiMtQLY45u7p5DMqXTSDgs/763L/SQp0bkCA=";
};
lxd-config = pkgs.writeText "config.yaml" ''
@@ -44,8 +43,10 @@ let
type: disk
'';
+
in {
name = "lxd";
+
meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ patryk27 ];
};
@@ -53,7 +54,7 @@ in {
machine = { lib, ... }: {
virtualisation = {
# Since we're testing `limits.cpu`, we've gotta have a known number of
- # cores to lay on
+ # cores to lean on
cores = 2;
# Ditto, for `limits.memory`
@@ -67,6 +68,7 @@ in {
testScript = ''
machine.wait_for_unit("sockets.target")
machine.wait_for_unit("lxd.service")
+ machine.wait_for_file("/var/lib/lxd/unix.socket")
# It takes additional second for lxd to settle
machine.sleep(1)
diff --git a/nixpkgs/nixos/tests/make-test.nix b/nixpkgs/nixos/tests/make-test.nix
deleted file mode 100644
index cee5da93454..00000000000
--- a/nixpkgs/nixos/tests/make-test.nix
+++ /dev/null
@@ -1,9 +0,0 @@
-f: {
- system ? builtins.currentSystem,
- pkgs ? import ../.. { inherit system; config = {}; },
- ...
-} @ args:
-
-with import ../lib/testing.nix { inherit system pkgs; };
-
-makeTest (if pkgs.lib.isFunction f then f (args // { inherit pkgs; inherit (pkgs) lib; }) else f)
diff --git a/nixpkgs/nixos/tests/mathics.nix b/nixpkgs/nixos/tests/mathics.nix
deleted file mode 100644
index fcbeeb18a72..00000000000
--- a/nixpkgs/nixos/tests/mathics.nix
+++ /dev/null
@@ -1,20 +0,0 @@
-import ./make-test.nix ({ pkgs, ... }: {
- name = "mathics";
- meta = with pkgs.stdenv.lib.maintainers; {
- maintainers = [ benley ];
- };
-
- nodes = {
- machine = { ... }: {
- services.mathics.enable = true;
- services.mathics.port = 8888;
- };
- };
-
- testScript = ''
- startAll;
- $machine->waitForUnit("mathics.service");
- $machine->waitForOpenPort(8888);
- $machine->succeed("curl http://localhost:8888/");
- '';
-})
diff --git a/nixpkgs/nixos/tests/mesos.nix b/nixpkgs/nixos/tests/mesos.nix
deleted file mode 100644
index 2e6dc0eda06..00000000000
--- a/nixpkgs/nixos/tests/mesos.nix
+++ /dev/null
@@ -1,92 +0,0 @@
-import ./make-test.nix ({ pkgs, ...} : rec {
- name = "mesos";
- meta = with pkgs.stdenv.lib.maintainers; {
- maintainers = [ offline kamilchm cstrahan ];
- };
-
- nodes = {
- master = { ... }: {
- networking.firewall.enable = false;
- services.zookeeper.enable = true;
- services.mesos.master = {
- enable = true;
- zk = "zk://master:2181/mesos";
- };
- };
-
- slave = { ... }: {
- networking.firewall.enable = false;
- networking.nat.enable = true;
- virtualisation.docker.enable = true;
- services.mesos = {
- slave = {
- enable = true;
- master = "master:5050";
- dockerRegistry = registry;
- executorEnvironmentVariables = {
- PATH = "/run/current-system/sw/bin";
- };
- };
- };
- };
- };
-
- simpleDocker = pkgs.dockerTools.buildImage {
- name = "echo";
- tag = "latest";
- contents = [ pkgs.stdenv.shellPackage pkgs.coreutils ];
- config = {
- Env = [
- # When shell=true, mesos invokes "sh -c '<cmd>'", so make sure "sh" is
- # on the PATH.
- "PATH=${pkgs.stdenv.shellPackage}/bin:${pkgs.coreutils}/bin"
- ];
- Entrypoint = [ "echo" ];
- };
- };
-
- registry = pkgs.runCommand "registry" { } ''
- mkdir -p $out
- cp ${simpleDocker} $out/echo:latest.tar
- '';
-
- testFramework = pkgs.pythonPackages.buildPythonPackage {
- name = "mesos-tests";
- propagatedBuildInputs = [ pkgs.mesos ];
- catchConflicts = false;
- src = ./mesos_test.py;
- phases = [ "installPhase" "fixupPhase" ];
- installPhase = ''
- install -Dvm 0755 $src $out/bin/mesos_test.py
-
- echo "done" > test.result
- tar czf $out/test.tar.gz test.result
- '';
- };
-
- testScript =
- ''
- startAll;
- $master->waitForUnit("zookeeper.service");
- $master->waitForUnit("mesos-master.service");
- $slave->waitForUnit("docker.service");
- $slave->waitForUnit("mesos-slave.service");
- $master->waitForOpenPort(2181);
- $master->waitForOpenPort(5050);
- $slave->waitForOpenPort(5051);
-
- # is slave registered?
- $master->waitUntilSucceeds("curl -s --fail http://master:5050/master/slaves".
- " | grep -q \"\\\"hostname\\\":\\\"slave\\\"\"");
-
- # try to run docker image
- $master->succeed("${pkgs.mesos}/bin/mesos-execute --master=master:5050".
- " --resources=\"cpus:0.1;mem:32\" --name=simple-docker".
- " --containerizer=mesos --docker_image=echo:latest".
- " --shell=true --command=\"echo done\" | grep -q TASK_FINISHED");
-
- # simple command with .tar.gz uri
- $master->succeed("${testFramework}/bin/mesos_test.py master ".
- "${testFramework}/test.tar.gz");
- '';
-})
diff --git a/nixpkgs/nixos/tests/mesos_test.py b/nixpkgs/nixos/tests/mesos_test.py
deleted file mode 100644
index be8bb32e49a..00000000000
--- a/nixpkgs/nixos/tests/mesos_test.py
+++ /dev/null
@@ -1,72 +0,0 @@
-#!/usr/bin/env python
-import uuid
-import time
-import subprocess
-import os
-
-import sys
-
-from mesos.interface import Scheduler
-from mesos.native import MesosSchedulerDriver
-from mesos.interface import mesos_pb2
-
-def log(msg):
- process = subprocess.Popen("systemd-cat", stdin=subprocess.PIPE)
- (out,err) = process.communicate(msg)
-
-class NixosTestScheduler(Scheduler):
- def __init__(self):
- self.master_ip = sys.argv[1]
- self.download_uri = sys.argv[2]
-
- def resourceOffers(self, driver, offers):
- log("XXX got resource offer")
-
- offer = offers[0]
- task = self.new_task(offer)
- uri = task.command.uris.add()
- uri.value = self.download_uri
- task.command.value = "cat test.result"
- driver.launchTasks(offer.id, [task])
-
- def statusUpdate(self, driver, update):
- log("XXX status update")
- if update.state == mesos_pb2.TASK_FAILED:
- log("XXX test task failed with message: " + update.message)
- driver.stop()
- sys.exit(1)
- elif update.state == mesos_pb2.TASK_FINISHED:
- driver.stop()
- sys.exit(0)
-
- def new_task(self, offer):
- task = mesos_pb2.TaskInfo()
- id = uuid.uuid4()
- task.task_id.value = str(id)
- task.slave_id.value = offer.slave_id.value
- task.name = "task {}".format(str(id))
-
- cpus = task.resources.add()
- cpus.name = "cpus"
- cpus.type = mesos_pb2.Value.SCALAR
- cpus.scalar.value = 0.1
-
- mem = task.resources.add()
- mem.name = "mem"
- mem.type = mesos_pb2.Value.SCALAR
- mem.scalar.value = 32
-
- return task
-
-if __name__ == '__main__':
- log("XXX framework started")
-
- framework = mesos_pb2.FrameworkInfo()
- framework.user = "root"
- framework.name = "nixos-test-framework"
- driver = MesosSchedulerDriver(
- NixosTestScheduler(),
- framework,
- sys.argv[1] + ":5050"
- )
- driver.run()
diff --git a/nixpkgs/nixos/tests/misc.nix b/nixpkgs/nixos/tests/misc.nix
index 17260ce6406..ae150553273 100644
--- a/nixpkgs/nixos/tests/misc.nix
+++ b/nixpkgs/nixos/tests/misc.nix
@@ -20,12 +20,24 @@ import ./make-test-python.nix ({ pkgs, ...} : rec {
{ fsType = "tmpfs";
options = [ "mode=1777" "noauto" ];
};
+ # Tests https://discourse.nixos.org/t/how-to-make-a-derivations-executables-have-the-s-permission/8555
+ "/user-mount/point" = {
+ device = "/user-mount/source";
+ fsType = "none";
+ options = [ "bind" "rw" "user" "noauto" ];
+ };
+ "/user-mount/denied-point" = {
+ device = "/user-mount/denied-source";
+ fsType = "none";
+ options = [ "bind" "rw" "noauto" ];
+ };
};
systemd.automounts = singleton
{ wantedBy = [ "multi-user.target" ];
where = "/tmp2";
};
users.users.sybil = { isNormalUser = true; group = "wheel"; };
+ users.users.alice = { isNormalUser = true; };
security.sudo = { enable = true; wheelNeedsPassword = false; };
boot.kernel.sysctl."vm.swappiness" = 1;
boot.kernelParams = [ "vsyscall=emulate" ];
@@ -112,6 +124,26 @@ import ./make-test-python.nix ({ pkgs, ...} : rec {
machine.succeed("touch /tmp2/x")
machine.succeed("grep '/tmp2 tmpfs' /proc/mounts")
+ with subtest(
+ "Whether mounting by a user is possible with the `user` option in fstab (#95444)"
+ ):
+ machine.succeed("mkdir -p /user-mount/source")
+ machine.succeed("touch /user-mount/source/file")
+ machine.succeed("chmod -R a+Xr /user-mount/source")
+ machine.succeed("mkdir /user-mount/point")
+ machine.succeed("chown alice:users /user-mount/point")
+ machine.succeed("su - alice -c 'mount /user-mount/point'")
+ machine.succeed("su - alice -c 'ls /user-mount/point/file'")
+ with subtest(
+ "Whether mounting by a user is denied without the `user` option in fstab"
+ ):
+ machine.succeed("mkdir -p /user-mount/denied-source")
+ machine.succeed("touch /user-mount/denied-source/file")
+ machine.succeed("chmod -R a+Xr /user-mount/denied-source")
+ machine.succeed("mkdir /user-mount/denied-point")
+ machine.succeed("chown alice:users /user-mount/denied-point")
+ machine.fail("su - alice -c 'mount /user-mount/denied-point'")
+
with subtest("shell-vars"):
machine.succeed('[ -n "$NIX_PATH" ]')
diff --git a/nixpkgs/nixos/tests/mysql/mysql.nix b/nixpkgs/nixos/tests/mysql/mysql.nix
index 50e1c76e9fd..5437a286043 100644
--- a/nixpkgs/nixos/tests/mysql/mysql.nix
+++ b/nixpkgs/nixos/tests/mysql/mysql.nix
@@ -172,32 +172,32 @@ import ./../make-test-python.nix ({ pkgs, ...} : {
"echo 'use testdb; select test_id from tests;' | sudo -u testuser mysql -u testuser -N | grep 42"
)
- # Check if TokuDB plugin works
+ # Check if RocksDB plugin works
mariadb.succeed(
- "echo 'use testdb; create table tokudb (test_id INT, PRIMARY KEY (test_id)) ENGINE = TokuDB;' | sudo -u testuser mysql -u testuser"
+ "echo 'use testdb; create table rocksdb (test_id INT, PRIMARY KEY (test_id)) ENGINE = RocksDB;' | sudo -u testuser mysql -u testuser"
)
mariadb.succeed(
- "echo 'use testdb; insert into tokudb values (25);' | sudo -u testuser mysql -u testuser"
+ "echo 'use testdb; insert into rocksdb values (28);' | sudo -u testuser mysql -u testuser"
)
mariadb.succeed(
- "echo 'use testdb; select test_id from tokudb;' | sudo -u testuser mysql -u testuser -N | grep 25"
+ "echo 'use testdb; select test_id from rocksdb;' | sudo -u testuser mysql -u testuser -N | grep 28"
)
mariadb.succeed(
- "echo 'use testdb; drop table tokudb;' | sudo -u testuser mysql -u testuser"
+ "echo 'use testdb; drop table rocksdb;' | sudo -u testuser mysql -u testuser"
)
-
- # Check if RocksDB plugin works
+ '' + pkgs.stdenv.lib.optionalString pkgs.stdenv.isx86_64 ''
+ # Check if TokuDB plugin works
mariadb.succeed(
- "echo 'use testdb; create table rocksdb (test_id INT, PRIMARY KEY (test_id)) ENGINE = RocksDB;' | sudo -u testuser mysql -u testuser"
+ "echo 'use testdb; create table tokudb (test_id INT, PRIMARY KEY (test_id)) ENGINE = TokuDB;' | sudo -u testuser mysql -u testuser"
)
mariadb.succeed(
- "echo 'use testdb; insert into rocksdb values (28);' | sudo -u testuser mysql -u testuser"
+ "echo 'use testdb; insert into tokudb values (25);' | sudo -u testuser mysql -u testuser"
)
mariadb.succeed(
- "echo 'use testdb; select test_id from rocksdb;' | sudo -u testuser mysql -u testuser -N | grep 28"
+ "echo 'use testdb; select test_id from tokudb;' | sudo -u testuser mysql -u testuser -N | grep 25"
)
mariadb.succeed(
- "echo 'use testdb; drop table rocksdb;' | sudo -u testuser mysql -u testuser"
+ "echo 'use testdb; drop table tokudb;' | sudo -u testuser mysql -u testuser"
)
'';
})
diff --git a/nixpkgs/nixos/tests/nextcloud/basic.nix b/nixpkgs/nixos/tests/nextcloud/basic.nix
index a8fa0cae6f0..72fb020dca7 100644
--- a/nixpkgs/nixos/tests/nextcloud/basic.nix
+++ b/nixpkgs/nixos/tests/nextcloud/basic.nix
@@ -33,7 +33,6 @@ in {
services.nextcloud = {
enable = true;
- nginx.enable = true;
hostName = "nextcloud";
config = {
# Don't inherit adminuser since "root" is supposed to be the default
diff --git a/nixpkgs/nixos/tests/nextcloud/with-mysql-and-memcached.nix b/nixpkgs/nixos/tests/nextcloud/with-mysql-and-memcached.nix
index 8db630be893..bec3815a3e1 100644
--- a/nixpkgs/nixos/tests/nextcloud/with-mysql-and-memcached.nix
+++ b/nixpkgs/nixos/tests/nextcloud/with-mysql-and-memcached.nix
@@ -17,7 +17,6 @@ in {
services.nextcloud = {
enable = true;
hostName = "nextcloud";
- nginx.enable = true;
https = true;
caching = {
apcu = true;
diff --git a/nixpkgs/nixos/tests/nextcloud/with-postgresql-and-redis.nix b/nixpkgs/nixos/tests/nextcloud/with-postgresql-and-redis.nix
index 95219cac9be..40a208115c3 100644
--- a/nixpkgs/nixos/tests/nextcloud/with-postgresql-and-redis.nix
+++ b/nixpkgs/nixos/tests/nextcloud/with-postgresql-and-redis.nix
@@ -17,7 +17,6 @@ in {
services.nextcloud = {
enable = true;
hostName = "nextcloud";
- nginx.enable = true;
caching = {
apcu = false;
redis = true;
diff --git a/nixpkgs/nixos/tests/nginx-sandbox.nix b/nixpkgs/nixos/tests/nginx-sandbox.nix
index bc9d3ba8add..514318c9456 100644
--- a/nixpkgs/nixos/tests/nginx-sandbox.nix
+++ b/nixpkgs/nixos/tests/nginx-sandbox.nix
@@ -18,7 +18,6 @@ import ./make-test-python.nix ({ pkgs, ... }: {
];
services.nginx.enable = true;
services.nginx.package = pkgs.nginx-lua;
- services.nginx.enableSandbox = true;
services.nginx.virtualHosts.localhost = {
extraConfig = ''
location /test1-write {
diff --git a/nixpkgs/nixos/tests/openstack-image.nix b/nixpkgs/nixos/tests/openstack-image.nix
index 97c9137fe1d..0b57dfb8e7e 100644
--- a/nixpkgs/nixos/tests/openstack-image.nix
+++ b/nixpkgs/nixos/tests/openstack-image.nix
@@ -3,30 +3,30 @@
pkgs ? import ../.. { inherit system config; }
}:
-with import ../lib/testing.nix { inherit system pkgs; };
+with import ../lib/testing-python.nix { inherit system pkgs; };
with pkgs.lib;
with import common/ec2.nix { inherit makeTest pkgs; };
let
- image =
- (import ../lib/eval-config.nix {
- inherit system;
- modules = [
- ../maintainers/scripts/openstack/openstack-image.nix
- ../modules/testing/test-instrumentation.nix
- ../modules/profiles/qemu-guest.nix
- {
- # Needed by nixos-rebuild due to lack of network access.
- system.extraDependencies = with pkgs; [
- stdenv
- ];
- }
- ];
- }).config.system.build.openstackImage + "/nixos.qcow2";
+ image = (import ../lib/eval-config.nix {
+ inherit system;
+ modules = [
+ ../maintainers/scripts/openstack/openstack-image.nix
+ ../modules/testing/test-instrumentation.nix
+ ../modules/profiles/qemu-guest.nix
+ {
+ # Needed by nixos-rebuild due to lack of network access.
+ system.extraDependencies = with pkgs; [
+ stdenv
+ ];
+ }
+ ];
+ }).config.system.build.openstackImage + "/nixos.qcow2";
sshKeys = import ./ssh-keys.nix pkgs;
snakeOilPrivateKey = sshKeys.snakeOilPrivateKey.text;
+ snakeOilPrivateKeyFile = pkgs.writeText "private-key" snakeOilPrivateKey;
snakeOilPublicKey = sshKeys.snakeOilPublicKey;
in {
@@ -39,32 +39,36 @@ in {
SSH_HOST_ED25519_KEY:${replaceStrings ["\n"] ["|"] snakeOilPrivateKey}
'';
script = ''
- $machine->start;
- $machine->waitForFile("/etc/ec2-metadata/user-data");
- $machine->waitForUnit("sshd.service");
+ machine.start()
+ machine.wait_for_file("/etc/ec2-metadata/user-data")
+ machine.wait_for_unit("sshd.service")
- $machine->succeed("grep unknown /etc/ec2-metadata/ami-manifest-path");
+ machine.succeed("grep unknown /etc/ec2-metadata/ami-manifest-path")
# We have no keys configured on the client side yet, so this should fail
- $machine->fail("ssh -o BatchMode=yes localhost exit");
+ machine.fail("ssh -o BatchMode=yes localhost exit")
# Let's install our client private key
- $machine->succeed("mkdir -p ~/.ssh");
+ machine.succeed("mkdir -p ~/.ssh")
- $machine->succeed("echo '${snakeOilPrivateKey}' > ~/.ssh/id_ed25519");
- $machine->succeed("chmod 600 ~/.ssh/id_ed25519");
+ machine.copy_from_host_via_shell(
+ "${snakeOilPrivateKeyFile}", "~/.ssh/id_ed25519"
+ )
+ machine.succeed("chmod 600 ~/.ssh/id_ed25519")
# We haven't configured the host key yet, so this should still fail
- $machine->fail("ssh -o BatchMode=yes localhost exit");
+ machine.fail("ssh -o BatchMode=yes localhost exit")
# Add the host key; ssh should finally succeed
- $machine->succeed("echo localhost,127.0.0.1 ${snakeOilPublicKey} > ~/.ssh/known_hosts");
- $machine->succeed("ssh -o BatchMode=yes localhost exit");
+ machine.succeed(
+ "echo localhost,127.0.0.1 ${snakeOilPublicKey} > ~/.ssh/known_hosts"
+ )
+ machine.succeed("ssh -o BatchMode=yes localhost exit")
# Just to make sure resizing is idempotent.
- $machine->shutdown;
- $machine->start;
- $machine->waitForFile("/etc/ec2-metadata/user-data");
+ machine.shutdown()
+ machine.start()
+ machine.wait_for_file("/etc/ec2-metadata/user-data")
'';
};
@@ -86,9 +90,9 @@ in {
}
'';
script = ''
- $machine->start;
- $machine->waitForFile("/etc/testFile");
- $machine->succeed("cat /etc/testFile | grep -q 'whoa'");
+ machine.start()
+ machine.wait_for_file("/etc/testFile")
+ assert "whoa" in machine.succeed("cat /etc/testFile")
'';
};
}
diff --git a/nixpkgs/nixos/tests/os-prober.nix b/nixpkgs/nixos/tests/os-prober.nix
index 6a38f5ca531..be0235a4175 100644
--- a/nixpkgs/nixos/tests/os-prober.nix
+++ b/nixpkgs/nixos/tests/os-prober.nix
@@ -1,4 +1,4 @@
-import ./make-test.nix ({pkgs, lib, ...}:
+import ./make-test-python.nix ({pkgs, lib, ...}:
let
# A filesystem image with a (presumably) bootable debian
debianImage = pkgs.vmTools.diskImageFuns.debian9i386 {
@@ -34,9 +34,6 @@ let
'';
};
- # options to add the disk to the test vm
- QEMU_OPTS = "-drive index=2,file=${debianImage}/disk-image.qcow2,read-only,if=virtio";
-
# a part of the configuration of the test vm
simpleConfig = {
boot.loader.grub = {
@@ -71,7 +68,7 @@ in {
machine = { config, pkgs, ... }: (simpleConfig // {
imports = [ ../modules/profiles/installation-device.nix
../modules/profiles/base.nix ];
- virtualisation.memorySize = 1024;
+ virtualisation.memorySize = 1300;
# The test cannot access the network, so any packages
# nixos-rebuild needs must be included in the VM.
system.extraDependencies = with pkgs;
@@ -99,22 +96,28 @@ in {
testScript = ''
# hack to add the secondary disk
- $machine->{startCommand} = "QEMU_OPTS=\"\$QEMU_OPTS \"${lib.escapeShellArg QEMU_OPTS} ".$machine->{startCommand};
+ os.environ[
+ "QEMU_OPTS"
+ ] = "-drive index=2,file=${debianImage}/disk-image.qcow2,read-only,if=virtio"
- $machine->start;
- $machine->succeed("udevadm settle");
- $machine->waitForUnit("multi-user.target");
+ machine.start()
+ machine.succeed("udevadm settle")
+ machine.wait_for_unit("multi-user.target")
+ print(machine.succeed("lsblk"))
# check that os-prober works standalone
- $machine->succeed("${pkgs.os-prober}/bin/os-prober | grep /dev/vdb1");
+ machine.succeed(
+ "${pkgs.os-prober}/bin/os-prober | grep /dev/vdb1"
+ )
# rebuild and test that debian is available in the grub menu
- $machine->succeed("nixos-generate-config");
- $machine->copyFileFromHost(
+ machine.succeed("nixos-generate-config")
+ machine.copy_from_host(
"${configFile}",
- "/etc/nixos/configuration.nix");
- $machine->succeed("nixos-rebuild boot >&2");
+ "/etc/nixos/configuration.nix",
+ )
+ machine.succeed("nixos-rebuild boot >&2")
- $machine->succeed("egrep 'menuentry.*debian' /boot/grub/grub.cfg");
+ machine.succeed("egrep 'menuentry.*debian' /boot/grub/grub.cfg")
'';
})
diff --git a/nixpkgs/nixos/tests/pinnwand.nix b/nixpkgs/nixos/tests/pinnwand.nix
new file mode 100644
index 00000000000..2204e74b2c2
--- /dev/null
+++ b/nixpkgs/nixos/tests/pinnwand.nix
@@ -0,0 +1,86 @@
+import ./make-test-python.nix ({ pkgs, ...}:
+let
+ pythonEnv = pkgs.python3.withPackages (py: with py; [ appdirs toml ]);
+
+ port = 8000;
+ baseUrl = "http://server:${toString port}";
+
+ configureSteck = pkgs.writeScript "configure.py" ''
+ #!${pythonEnv.interpreter}
+ import appdirs
+ import toml
+ import os
+
+ CONFIG = {
+ "base": "${baseUrl}/",
+ "confirm": False,
+ "magic": True,
+ "ignore": True
+ }
+
+ os.makedirs(appdirs.user_config_dir('steck'))
+ with open(os.path.join(appdirs.user_config_dir('steck'), 'steck.toml'), "w") as fd:
+ toml.dump(CONFIG, fd)
+ '';
+in
+{
+ name = "pinnwand";
+ meta = with pkgs.stdenv.lib.maintainers; {
+ maintainers =[ hexa ];
+ };
+
+ nodes = {
+ server = { config, ... }:
+ {
+ networking.firewall.allowedTCPPorts = [
+ port
+ ];
+
+ services.pinnwand = {
+ enable = true;
+ port = port;
+ };
+ };
+
+ client = { pkgs, ... }:
+ {
+ environment.systemPackages = [ pkgs.steck ];
+ };
+ };
+
+ testScript = ''
+ start_all()
+
+ server.wait_for_unit("pinnwand.service")
+ client.wait_for_unit("network.target")
+
+ # create steck.toml config file
+ client.succeed("${configureSteck}")
+
+ # wait until the server running pinnwand is reachable
+ client.wait_until_succeeds("ping -c1 server")
+
+ # make sure pinnwand is listening
+ server.wait_until_succeeds("ss -lnp | grep ${toString port}")
+
+ # send the contents of /etc/machine-id
+ response = client.succeed("steck paste /etc/machine-id")
+
+ # parse the steck response
+ raw_url = None
+ removal_link = None
+ for line in response.split("\n"):
+ if line.startswith("View link:"):
+ raw_url = f"${baseUrl}/raw/{line.split('/')[-1]}"
+ if line.startswith("Removal link:"):
+ removal_link = line.split(":", 1)[1]
+
+ # check whether paste matches what we sent
+ client.succeed(f"curl {raw_url} > /tmp/machine-id")
+ client.succeed("diff /tmp/machine-id /etc/machine-id")
+
+ # remove paste and check that it's not available any more
+ client.succeed(f"curl {removal_link}")
+ client.fail(f"curl --fail {raw_url}")
+ '';
+})
diff --git a/nixpkgs/nixos/tests/postfix-raise-smtpd-tls-security-level.nix b/nixpkgs/nixos/tests/postfix-raise-smtpd-tls-security-level.nix
index b3c2156122d..5fad1fed75b 100644
--- a/nixpkgs/nixos/tests/postfix-raise-smtpd-tls-security-level.nix
+++ b/nixpkgs/nixos/tests/postfix-raise-smtpd-tls-security-level.nix
@@ -1,6 +1,3 @@
-let
- certs = import ./common/acme/server/snakeoil-certs.nix;
-in
import ./make-test-python.nix {
name = "postfix";
diff --git a/nixpkgs/nixos/tests/postfix.nix b/nixpkgs/nixos/tests/postfix.nix
index b0674ca3a0d..37ae76afec1 100644
--- a/nixpkgs/nixos/tests/postfix.nix
+++ b/nixpkgs/nixos/tests/postfix.nix
@@ -1,5 +1,6 @@
let
certs = import ./common/acme/server/snakeoil-certs.nix;
+ domain = certs.domain;
in
import ./make-test-python.nix {
name = "postfix";
@@ -11,8 +12,8 @@ import ./make-test-python.nix {
enableSubmission = true;
enableSubmissions = true;
sslCACert = certs.ca.cert;
- sslCert = certs."acme.test".cert;
- sslKey = certs."acme.test".key;
+ sslCert = certs.${domain}.cert;
+ sslKey = certs.${domain}.key;
submissionsOptions = {
smtpd_sasl_auth_enable = "yes";
smtpd_client_restrictions = "permit";
@@ -25,7 +26,7 @@ import ./make-test-python.nix {
];
networking.extraHosts = ''
- 127.0.0.1 acme.test
+ 127.0.0.1 ${domain}
'';
environment.systemPackages = let
@@ -33,7 +34,7 @@ import ./make-test-python.nix {
#!${pkgs.python3.interpreter}
import smtplib
- with smtplib.SMTP('acme.test') as smtp:
+ with smtplib.SMTP('${domain}') as smtp:
smtp.sendmail('root@localhost', 'alice@localhost', 'Subject: Test\n\nTest data.')
smtp.quit()
'';
@@ -45,7 +46,7 @@ import ./make-test-python.nix {
ctx = ssl.create_default_context()
- with smtplib.SMTP('acme.test') as smtp:
+ with smtplib.SMTP('${domain}') as smtp:
smtp.ehlo()
smtp.starttls(context=ctx)
smtp.ehlo()
@@ -60,7 +61,7 @@ import ./make-test-python.nix {
ctx = ssl.create_default_context()
- with smtplib.SMTP_SSL(host='acme.test', context=ctx) as smtp:
+ with smtplib.SMTP_SSL(host='${domain}', context=ctx) as smtp:
smtp.sendmail('root@localhost', 'alice@localhost', 'Subject: Test SMTPS\n\nTest data.')
smtp.quit()
'';
diff --git a/nixpkgs/nixos/tests/postgresql-wal-receiver.nix b/nixpkgs/nixos/tests/postgresql-wal-receiver.nix
index 372dd9d8c1c..432b46234f9 100644
--- a/nixpkgs/nixos/tests/postgresql-wal-receiver.nix
+++ b/nixpkgs/nixos/tests/postgresql-wal-receiver.nix
@@ -1,99 +1,111 @@
-{ system ? builtins.currentSystem
-, config ? { }
-, pkgs ? import ../.. { inherit system config; } }:
-
-with import ../lib/testing.nix { inherit system pkgs; };
-with pkgs.lib;
-
let
- makePostgresqlWalReceiverTest = subTestName: postgresqlPackage: let
+ # Makes a test for a PostgreSQL package, given by name and looked up from `pkgs`.
+ makePostgresqlWalReceiverTest = postgresqlPackage:
+ {
+ name = postgresqlPackage;
+ value =
+ import ./make-test-python.nix ({ pkgs, lib, ... }: let
- postgresqlDataDir = "/var/db/postgresql/test";
- replicationUser = "wal_receiver_user";
- replicationSlot = "wal_receiver_slot";
- replicationConn = "postgresql://${replicationUser}@localhost";
- baseBackupDir = "/tmp/pg_basebackup";
- walBackupDir = "/tmp/pg_wal";
- atLeast12 = versionAtLeast postgresqlPackage.version "12.0";
- restoreCommand = ''
- restore_command = 'cp ${walBackupDir}/%f %p'
- '';
+ pkg = pkgs."${postgresqlPackage}";
+ postgresqlDataDir = "/var/lib/postgresql/${pkg.psqlSchema}";
+ replicationUser = "wal_receiver_user";
+ replicationSlot = "wal_receiver_slot";
+ replicationConn = "postgresql://${replicationUser}@localhost";
+ baseBackupDir = "/tmp/pg_basebackup";
+ walBackupDir = "/tmp/pg_wal";
+ atLeast12 = lib.versionAtLeast pkg.version "12.0";
- recoveryFile = if atLeast12
- then pkgs.writeTextDir "recovery.signal" ""
- else pkgs.writeTextDir "recovery.conf" "${restoreCommand}";
+ recoveryFile = if atLeast12
+ then pkgs.writeTextDir "recovery.signal" ""
+ else pkgs.writeTextDir "recovery.conf" "restore_command = 'cp ${walBackupDir}/%f %p'";
- in makeTest {
- name = "postgresql-wal-receiver-${subTestName}";
- meta.maintainers = with maintainers; [ pacien ];
+ in {
+ name = "postgresql-wal-receiver-${postgresqlPackage}";
+ meta.maintainers = with lib.maintainers; [ pacien ];
- machine = { ... }: {
- services.postgresql = {
- package = postgresqlPackage;
- enable = true;
- dataDir = postgresqlDataDir;
- extraConfig = ''
- wal_level = archive # alias for replica on pg >= 9.6
- max_wal_senders = 10
- max_replication_slots = 10
- '' + optionalString atLeast12 ''
- ${restoreCommand}
- recovery_end_command = 'touch recovery.done'
- '';
- authentication = ''
- host replication ${replicationUser} all trust
- '';
- initialScript = pkgs.writeText "init.sql" ''
- create user ${replicationUser} replication;
- select * from pg_create_physical_replication_slot('${replicationSlot}');
- '';
- };
+ machine = { ... }: {
+ services.postgresql = {
+ package = pkg;
+ enable = true;
+ settings = lib.mkMerge [
+ {
+ wal_level = "archive"; # alias for replica on pg >= 9.6
+ max_wal_senders = 10;
+ max_replication_slots = 10;
+ }
+ (lib.mkIf atLeast12 {
+ restore_command = "cp ${walBackupDir}/%f %p";
+ recovery_end_command = "touch recovery.done";
+ })
+ ];
+ authentication = ''
+ host replication ${replicationUser} all trust
+ '';
+ initialScript = pkgs.writeText "init.sql" ''
+ create user ${replicationUser} replication;
+ select * from pg_create_physical_replication_slot('${replicationSlot}');
+ '';
+ };
- services.postgresqlWalReceiver.receivers.main = {
- inherit postgresqlPackage;
- connection = replicationConn;
- slot = replicationSlot;
- directory = walBackupDir;
- };
- # This is only to speedup test, it isn't time racing. Service is set to autorestart always,
- # default 60sec is fine for real system, but is too much for a test
- systemd.services.postgresql-wal-receiver-main.serviceConfig.RestartSec = mkForce 5;
- };
+ services.postgresqlWalReceiver.receivers.main = {
+ postgresqlPackage = pkg;
+ connection = replicationConn;
+ slot = replicationSlot;
+ directory = walBackupDir;
+ };
+ # This is only to speedup test, it isn't time racing. Service is set to autorestart always,
+ # default 60sec is fine for real system, but is too much for a test
+ systemd.services.postgresql-wal-receiver-main.serviceConfig.RestartSec = lib.mkForce 5;
+ };
- testScript = ''
- # make an initial base backup
- $machine->waitForUnit('postgresql');
- $machine->waitForUnit('postgresql-wal-receiver-main');
- # WAL receiver healthchecks PG every 5 seconds, so let's be sure they have connected each other
- # required only for 9.4
- $machine->sleep(5);
- $machine->succeed('${postgresqlPackage}/bin/pg_basebackup --dbname=${replicationConn} --pgdata=${baseBackupDir}');
+ testScript = ''
+ # make an initial base backup
+ machine.wait_for_unit("postgresql")
+ machine.wait_for_unit("postgresql-wal-receiver-main")
+ # WAL receiver healthchecks PG every 5 seconds, so let's be sure they have connected each other
+ # required only for 9.4
+ machine.sleep(5)
+ machine.succeed(
+ "${pkg}/bin/pg_basebackup --dbname=${replicationConn} --pgdata=${baseBackupDir}"
+ )
- # create a dummy table with 100 records
- $machine->succeed('sudo -u postgres psql --command="create table dummy as select * from generate_series(1, 100) as val;"');
+ # create a dummy table with 100 records
+ machine.succeed(
+ "sudo -u postgres psql --command='create table dummy as select * from generate_series(1, 100) as val;'"
+ )
- # stop postgres and destroy data
- $machine->systemctl('stop postgresql');
- $machine->systemctl('stop postgresql-wal-receiver-main');
- $machine->succeed('rm -r ${postgresqlDataDir}/{base,global,pg_*}');
+ # stop postgres and destroy data
+ machine.systemctl("stop postgresql")
+ machine.systemctl("stop postgresql-wal-receiver-main")
+ machine.succeed("rm -r ${postgresqlDataDir}/{base,global,pg_*}")
- # restore the base backup
- $machine->succeed('cp -r ${baseBackupDir}/* ${postgresqlDataDir} && chown postgres:postgres -R ${postgresqlDataDir}');
+ # restore the base backup
+ machine.succeed(
+ "cp -r ${baseBackupDir}/* ${postgresqlDataDir} && chown postgres:postgres -R ${postgresqlDataDir}"
+ )
- # prepare WAL and recovery
- $machine->succeed('chmod a+rX -R ${walBackupDir}');
- $machine->execute('for part in ${walBackupDir}/*.partial; do mv $part ''${part%%.*}; done'); # make use of partial segments too
- $machine->succeed('cp ${recoveryFile}/* ${postgresqlDataDir}/ && chmod 666 ${postgresqlDataDir}/recovery*');
+ # prepare WAL and recovery
+ machine.succeed("chmod a+rX -R ${walBackupDir}")
+ machine.execute(
+ "for part in ${walBackupDir}/*.partial; do mv $part ''${part%%.*}; done"
+ ) # make use of partial segments too
+ machine.succeed(
+ "cp ${recoveryFile}/* ${postgresqlDataDir}/ && chmod 666 ${postgresqlDataDir}/recovery*"
+ )
- # replay WAL
- $machine->systemctl('start postgresql');
- $machine->waitForFile('${postgresqlDataDir}/recovery.done');
- $machine->systemctl('restart postgresql');
- $machine->waitForUnit('postgresql');
+ # replay WAL
+ machine.systemctl("start postgresql")
+ machine.wait_for_file("${postgresqlDataDir}/recovery.done")
+ machine.systemctl("restart postgresql")
+ machine.wait_for_unit("postgresql")
- # check that our records have been restored
- $machine->succeed('test $(sudo -u postgres psql --pset="pager=off" --tuples-only --command="select count(distinct val) from dummy;") -eq 100');
- '';
- };
+ # check that our records have been restored
+ machine.succeed(
+ "test $(sudo -u postgres psql --pset='pager=off' --tuples-only --command='select count(distinct val) from dummy;') -eq 100"
+ )
+ '';
+ });
+ };
-in mapAttrs makePostgresqlWalReceiverTest (import ../../pkgs/servers/sql/postgresql pkgs)
+# Maps the generic function over all attributes of PostgreSQL packages
+in builtins.listToAttrs (map makePostgresqlWalReceiverTest (builtins.attrNames (import ../../pkgs/servers/sql/postgresql { })))
diff --git a/nixpkgs/nixos/tests/prometheus-exporters.nix b/nixpkgs/nixos/tests/prometheus-exporters.nix
index b912e3425e0..fdcc4072132 100644
--- a/nixpkgs/nixos/tests/prometheus-exporters.nix
+++ b/nixpkgs/nixos/tests/prometheus-exporters.nix
@@ -22,6 +22,9 @@ let
* `metricProvider` (optional)
* this attribute contains additional machine config
*
+ * `nodeName` (optional)
+ * override an incompatible testnode name
+ *
* Example:
* exporterTests.<exporterName> = {
* exporterConfig = {
@@ -590,6 +593,19 @@ let
'';
};
+ unifi-poller = {
+ nodeName = "unifi_poller";
+ exporterConfig.enable = true;
+ exporterConfig.controllers = [ { } ];
+ exporterTest = ''
+ wait_for_unit("prometheus-unifi-poller-exporter.service")
+ wait_for_open_port(9130)
+ succeed(
+ "curl -sSf localhost:9130/metrics | grep -q 'unifipoller_build_info{.\\+} 1'"
+ )
+ '';
+ };
+
varnish = {
exporterConfig = {
enable = true;
@@ -646,24 +662,27 @@ let
};
};
in
-mapAttrs (exporter: testConfig: (makeTest {
+mapAttrs (exporter: testConfig: (makeTest (let
+ nodeName = testConfig.nodeName or exporter;
+
+in {
name = "prometheus-${exporter}-exporter";
- nodes.${exporter} = mkMerge [{
+ nodes.${nodeName} = mkMerge [{
services.prometheus.exporters.${exporter} = testConfig.exporterConfig;
} testConfig.metricProvider or {}];
testScript = ''
- ${exporter}.start()
+ ${nodeName}.start()
${concatStringsSep "\n" (map (line:
if (builtins.substring 0 1 line == " " || builtins.substring 0 1 line == ")")
then line
- else "${exporter}.${line}"
+ else "${nodeName}.${line}"
) (splitString "\n" (removeSuffix "\n" testConfig.exporterTest)))}
- ${exporter}.shutdown()
+ ${nodeName}.shutdown()
'';
meta = with maintainers; {
- maintainers = [ willibutz ];
+ maintainers = [ willibutz elseym ];
};
-})) exporterTests
+}))) exporterTests
diff --git a/nixpkgs/nixos/tests/prometheus.nix b/nixpkgs/nixos/tests/prometheus.nix
index bce489168f9..af2aa66a552 100644
--- a/nixpkgs/nixos/tests/prometheus.nix
+++ b/nixpkgs/nixos/tests/prometheus.nix
@@ -158,7 +158,10 @@ in import ./make-test-python.nix {
s3 = { pkgs, ... } : {
# Minio requires at least 1GiB of free disk space to run.
- virtualisation.diskSize = 2 * 1024;
+ virtualisation = {
+ diskSize = 2 * 1024;
+ memorySize = 1024;
+ };
networking.firewall.allowedTCPPorts = [ minioPort ];
services.minio = {
@@ -235,7 +238,7 @@ in import ./make-test-python.nix {
# Test if the Thanos bucket command is able to retrieve blocks from the S3 bucket
# and check if the blocks have the correct labels:
store.succeed(
- "thanos bucket ls "
+ "thanos tools bucket ls "
+ "--objstore.config-file=${nodes.store.config.services.thanos.store.objstore.config-file} "
+ "--output=json | "
+ "jq .thanos.labels.some_label | "
diff --git a/nixpkgs/nixos/tests/robustirc-bridge.nix b/nixpkgs/nixos/tests/robustirc-bridge.nix
new file mode 100644
index 00000000000..a5c22d73a34
--- /dev/null
+++ b/nixpkgs/nixos/tests/robustirc-bridge.nix
@@ -0,0 +1,29 @@
+import ./make-test-python.nix ({ pkgs, ... }:
+
+{
+ name = "robustirc-bridge";
+ meta = with pkgs.stdenv.lib.maintainers; {
+ maintainers = [ hax404 ];
+ };
+
+ nodes =
+ { bridge =
+ { services.robustirc-bridge = {
+ enable = true;
+ extraFlags = [
+ "-listen localhost:6667"
+ "-network example.com"
+ ];
+ };
+ };
+ };
+
+ testScript =
+ ''
+ start_all()
+
+ bridge.wait_for_unit("robustirc-bridge.service")
+ bridge.wait_for_open_port(1080)
+ bridge.wait_for_open_port(6667)
+ '';
+})
diff --git a/nixpkgs/nixos/tests/shadowsocks/common.nix b/nixpkgs/nixos/tests/shadowsocks/common.nix
new file mode 100644
index 00000000000..8cbbc3f2068
--- /dev/null
+++ b/nixpkgs/nixos/tests/shadowsocks/common.nix
@@ -0,0 +1,84 @@
+{ name
+, plugin ? null
+, pluginOpts ? ""
+}:
+
+import ../make-test-python.nix ({ pkgs, lib, ... }: {
+ inherit name;
+ meta = {
+ maintainers = with lib.maintainers; [ hmenke ];
+ };
+
+ nodes = {
+ server = {
+ boot.kernel.sysctl."net.ipv4.ip_forward" = "1";
+ networking.useDHCP = false;
+ networking.interfaces.eth1.ipv4.addresses = [
+ { address = "192.168.0.1"; prefixLength = 24; }
+ ];
+ networking.firewall.rejectPackets = true;
+ networking.firewall.allowedTCPPorts = [ 8488 ];
+ networking.firewall.allowedUDPPorts = [ 8488 ];
+ services.shadowsocks = {
+ enable = true;
+ encryptionMethod = "chacha20-ietf-poly1305";
+ password = "pa$$w0rd";
+ localAddress = [ "0.0.0.0" ];
+ port = 8488;
+ fastOpen = false;
+ mode = "tcp_and_udp";
+ } // lib.optionalAttrs (plugin != null) {
+ inherit plugin;
+ pluginOpts = "server;${pluginOpts}";
+ };
+ services.nginx = {
+ enable = true;
+ virtualHosts.server = {
+ locations."/".root = pkgs.writeTextDir "index.html" "It works!";
+ };
+ };
+ };
+
+ client = {
+ networking.useDHCP = false;
+ networking.interfaces.eth1.ipv4.addresses = [
+ { address = "192.168.0.2"; prefixLength = 24; }
+ ];
+ systemd.services.shadowsocks-client = {
+ description = "connect to shadowsocks";
+ after = [ "network.target" ];
+ wantedBy = [ "multi-user.target" ];
+ path = with pkgs; [ shadowsocks-libev ];
+ script = ''
+ exec ss-local \
+ -s 192.168.0.1 \
+ -p 8488 \
+ -l 1080 \
+ -k 'pa$$w0rd' \
+ -m chacha20-ietf-poly1305 \
+ -a nobody \
+ ${lib.optionalString (plugin != null) ''
+ --plugin "${plugin}" --plugin-opts "${pluginOpts}"
+ ''}
+ '';
+ };
+ };
+ };
+
+ testScript = ''
+ start_all()
+
+ server.wait_for_unit("shadowsocks-libev.service")
+ client.wait_for_unit("shadowsocks-client.service")
+
+ client.fail(
+ "${pkgs.curl}/bin/curl 192.168.0.1:80"
+ )
+
+ msg = client.succeed(
+ "${pkgs.curl}/bin/curl --socks5 localhost:1080 192.168.0.1:80"
+ )
+ assert msg == "It works!", "Could not connect through shadowsocks"
+ '';
+ }
+)
diff --git a/nixpkgs/nixos/tests/shadowsocks/default.nix b/nixpkgs/nixos/tests/shadowsocks/default.nix
new file mode 100644
index 00000000000..37a8c3c9d0d
--- /dev/null
+++ b/nixpkgs/nixos/tests/shadowsocks/default.nix
@@ -0,0 +1,16 @@
+{ system ? builtins.currentSystem
+, config ? { }
+, pkgs ? import ../../.. { inherit system config; }
+}:
+
+{
+ "basic" = import ./common.nix {
+ name = "basic";
+ };
+
+ "v2ray-plugin" = import ./common.nix {
+ name = "v2ray-plugin";
+ plugin = "${pkgs.shadowsocks-v2ray-plugin}/bin/v2ray-plugin";
+ pluginOpts = "host=nixos.org";
+ };
+}
diff --git a/nixpkgs/nixos/tests/shattered-pixel-dungeon.nix b/nixpkgs/nixos/tests/shattered-pixel-dungeon.nix
new file mode 100644
index 00000000000..cf6ee8db80b
--- /dev/null
+++ b/nixpkgs/nixos/tests/shattered-pixel-dungeon.nix
@@ -0,0 +1,29 @@
+import ./make-test-python.nix ({ pkgs, ... }: {
+ name = "shattered-pixel-dungeon";
+ meta = with pkgs.lib.maintainers; {
+ maintainers = [ fgaz ];
+ };
+
+ machine = { config, pkgs, ... }: {
+ imports = [
+ ./common/x11.nix
+ ];
+
+ services.xserver.enable = true;
+ environment.systemPackages = [ pkgs.shattered-pixel-dungeon ];
+ };
+
+ enableOCR = true;
+
+ testScript =
+ ''
+ machine.wait_for_x()
+ machine.execute("shattered-pixel-dungeon &")
+ machine.wait_for_window(r"Shattered Pixel Dungeon")
+ machine.sleep(5)
+ if "Enter" not in machine.get_screen_text():
+ raise Exception("Program did not start successfully")
+ machine.screenshot("screen")
+ '';
+})
+
diff --git a/nixpkgs/nixos/tests/sssd-ldap.nix b/nixpkgs/nixos/tests/sssd-ldap.nix
new file mode 100644
index 00000000000..b68403a0102
--- /dev/null
+++ b/nixpkgs/nixos/tests/sssd-ldap.nix
@@ -0,0 +1,78 @@
+import ./make-test-python.nix ({ pkgs, ... }:
+ let
+ dbDomain = "example.org";
+ dbSuffix = "dc=example,dc=org";
+
+ ldapRootUser = "admin";
+ ldapRootPassword = "foobar";
+
+ testUser = "alice";
+ in
+ {
+ name = "sssd-ldap";
+
+ meta = with pkgs.stdenv.lib.maintainers; {
+ maintainers = [ bbigras ];
+ };
+
+ machine = { pkgs, ... }: {
+ services.openldap = {
+ enable = true;
+ rootdn = "cn=${ldapRootUser},${dbSuffix}";
+ rootpw = ldapRootPassword;
+ suffix = dbSuffix;
+ declarativeContents = ''
+ dn: ${dbSuffix}
+ objectClass: top
+ objectClass: dcObject
+ objectClass: organization
+ o: ${dbDomain}
+
+ dn: ou=posix,${dbSuffix}
+ objectClass: top
+ objectClass: organizationalUnit
+
+ dn: ou=accounts,ou=posix,${dbSuffix}
+ objectClass: top
+ objectClass: organizationalUnit
+
+ dn: uid=${testUser},ou=accounts,ou=posix,${dbSuffix}
+ objectClass: person
+ objectClass: posixAccount
+ # userPassword: somePasswordHash
+ homeDirectory: /home/${testUser}
+ uidNumber: 1234
+ gidNumber: 1234
+ cn: ""
+ sn: ""
+ '';
+ };
+
+ services.sssd = {
+ enable = true;
+ config = ''
+ [sssd]
+ config_file_version = 2
+ services = nss, pam, sudo
+ domains = ${dbDomain}
+
+ [domain/${dbDomain}]
+ auth_provider = ldap
+ id_provider = ldap
+ ldap_uri = ldap://127.0.0.1:389
+ ldap_search_base = ${dbSuffix}
+ ldap_default_bind_dn = cn=${ldapRootUser},${dbSuffix}
+ ldap_default_authtok_type = password
+ ldap_default_authtok = ${ldapRootPassword}
+ '';
+ };
+ };
+
+ testScript = ''
+ machine.start()
+ machine.wait_for_unit("openldap.service")
+ machine.wait_for_unit("sssd.service")
+ machine.succeed("getent passwd ${testUser}")
+ '';
+ }
+)
diff --git a/nixpkgs/nixos/tests/sssd.nix b/nixpkgs/nixos/tests/sssd.nix
new file mode 100644
index 00000000000..4c6ca86c74c
--- /dev/null
+++ b/nixpkgs/nixos/tests/sssd.nix
@@ -0,0 +1,17 @@
+import ./make-test-python.nix ({ pkgs, ... }:
+
+{
+ name = "sssd";
+ meta = with pkgs.stdenv.lib.maintainers; {
+ maintainers = [ bbigras ];
+ };
+ machine = { pkgs, ... }: {
+ services.sssd.enable = true;
+ };
+
+ testScript = ''
+ start_all()
+ machine.wait_for_unit("multi-user.target")
+ machine.wait_for_unit("sssd.service")
+ '';
+})
diff --git a/nixpkgs/nixos/tests/systemd-networkd-ipv6-prefix-delegation.nix b/nixpkgs/nixos/tests/systemd-networkd-ipv6-prefix-delegation.nix
index 99cd341eec1..99395fe3023 100644
--- a/nixpkgs/nixos/tests/systemd-networkd-ipv6-prefix-delegation.nix
+++ b/nixpkgs/nixos/tests/systemd-networkd-ipv6-prefix-delegation.nix
@@ -31,7 +31,7 @@ import ./make-test-python.nix ({pkgs, ...}: {
firewall.enable = false;
interfaces.eth1.ipv4.addresses = lib.mkForce []; # no need for legacy IP
interfaces.eth1.ipv6.addresses = lib.mkForce [
- { address = "2001:DB8::"; prefixLength = 64; }
+ { address = "2001:DB8::1"; prefixLength = 64; }
];
};
@@ -260,7 +260,7 @@ import ./make-test-python.nix ({pkgs, ...}: {
client.wait_until_succeeds("ping -6 -c 1 FD42::1")
# the global IP of the ISP router should still not be a reachable
- router.fail("ping -6 -c 1 2001:DB8::")
+ router.fail("ping -6 -c 1 2001:DB8::1")
# Once we have internal connectivity boot up the ISP
isp.start()
@@ -273,11 +273,11 @@ import ./make-test-python.nix ({pkgs, ...}: {
# wait until the uplink interface has a good status
router.wait_for_unit("network-online.target")
- router.wait_until_succeeds("ping -6 -c1 2001:DB8::")
+ router.wait_until_succeeds("ping -6 -c1 2001:DB8::1")
# shortly after that the client should have received it's global IPv6
# address and thus be able to ping the ISP
- client.wait_until_succeeds("ping -6 -c1 2001:DB8::")
+ client.wait_until_succeeds("ping -6 -c1 2001:DB8::1")
# verify that we got a globally scoped address in eth1 from the
# documentation prefix
diff --git a/nixpkgs/nixos/tests/systemd-networkd.nix b/nixpkgs/nixos/tests/systemd-networkd.nix
index 319e5e94ece..d5fb2431dba 100644
--- a/nixpkgs/nixos/tests/systemd-networkd.nix
+++ b/nixpkgs/nixos/tests/systemd-networkd.nix
@@ -7,18 +7,19 @@ let generateNodeConf = { lib, pkgs, config, privk, pubk, peerId, nodeId, ...}: {
virtualisation.vlans = [ 1 ];
environment.systemPackages = with pkgs; [ wireguard-tools ];
boot.extraModulePackages = [ config.boot.kernelPackages.wireguard ];
- systemd.tmpfiles.rules = [
- "f /run/wg_priv 0640 root systemd-network - ${privk}"
- ];
systemd.network = {
enable = true;
netdevs = {
"90-wg0" = {
netdevConfig = { Kind = "wireguard"; Name = "wg0"; };
wireguardConfig = {
- PrivateKeyFile = "/run/wg_priv";
+ # NOTE: we're storing the wireguard private key in the
+ # store for this test. Do not do this in the real
+ # world. Keep in mind the nix store is
+ # world-readable.
+ PrivateKeyFile = pkgs.writeText "wg0-priv" privk;
ListenPort = 51820;
- FwMark = 42;
+ FirewallMark = 42;
};
wireguardPeers = [ {wireguardPeerConfig={
Endpoint = "192.168.1.${peerId}:51820";
diff --git a/nixpkgs/nixos/tests/systemd.nix b/nixpkgs/nixos/tests/systemd.nix
index a653932fb37..dfa16eecfad 100644
--- a/nixpkgs/nixos/tests/systemd.nix
+++ b/nixpkgs/nixos/tests/systemd.nix
@@ -4,7 +4,10 @@ import ./make-test-python.nix ({ pkgs, ... }: {
machine = { lib, ... }: {
imports = [ common/user-account.nix common/x11.nix ];
- virtualisation.emptyDiskImages = [ 512 ];
+ virtualisation.emptyDiskImages = [ 512 512 ];
+ virtualisation.memorySize = 1024;
+
+ environment.systemPackages = [ pkgs.cryptsetup ];
fileSystems = lib.mkVMOverride {
"/test-x-initrd-mount" = {
@@ -141,8 +144,29 @@ import ./make-test-python.nix ({ pkgs, ... }: {
)
output = machine.succeed("systemctl show | grep Watchdog")
- assert "RuntimeWatchdogUSec=30s" in output
- assert "RebootWatchdogUSec=10m" in output
- assert "KExecWatchdogUSec=5m" in output
+ # assert "RuntimeWatchdogUSec=30s" in output
+ # for some reason RuntimeWatchdogUSec, doesn't seem to be updated in here.
+ assert "RebootWatchdogUSec=10min" in output
+ assert "KExecWatchdogUSec=5min" in output
+
+ # Test systemd cryptsetup support
+ with subtest("systemd successfully reads /etc/crypttab and unlocks volumes"):
+ # create a luks volume and put a filesystem on it
+ machine.succeed(
+ "echo -n supersecret | cryptsetup luksFormat -q /dev/vdc -",
+ "echo -n supersecret | cryptsetup luksOpen --key-file - /dev/vdc foo",
+ "mkfs.ext3 /dev/mapper/foo",
+ )
+
+ # create a keyfile and /etc/crypttab
+ machine.succeed("echo -n supersecret > /var/lib/luks-keyfile")
+ machine.succeed("chmod 600 /var/lib/luks-keyfile")
+ machine.succeed("echo 'luks1 /dev/vdc /var/lib/luks-keyfile luks' > /etc/crypttab")
+
+ # after a reboot, systemd should unlock the volume and we should be able to mount it
+ machine.shutdown()
+ machine.succeed("systemctl status systemd-cryptsetup@luks1.service")
+ machine.succeed("mkdir -p /tmp/luks1")
+ machine.succeed("mount /dev/mapper/luks1 /tmp/luks1")
'';
})
diff --git a/nixpkgs/nixos/tests/transmission.nix b/nixpkgs/nixos/tests/transmission.nix
index f4f2186be1f..37c0352dcfb 100644
--- a/nixpkgs/nixos/tests/transmission.nix
+++ b/nixpkgs/nixos/tests/transmission.nix
@@ -9,6 +9,8 @@ import ./make-test-python.nix ({ pkgs, ...} : {
networking.firewall.allowedTCPPorts = [ 9091 ];
+ security.apparmor.enable = true;
+
services.transmission.enable = true;
};
diff --git a/nixpkgs/nixos/tests/trezord.nix b/nixpkgs/nixos/tests/trezord.nix
index 67646496ff9..b7b3dd31942 100644
--- a/nixpkgs/nixos/tests/trezord.nix
+++ b/nixpkgs/nixos/tests/trezord.nix
@@ -1,7 +1,7 @@
import ./make-test-python.nix ({ pkgs, ... }: {
name = "trezord";
meta = with pkgs.stdenv.lib; {
- maintainers = with maintainers; [ mmahut maintainers."1000101" ];
+ maintainers = with maintainers; [ mmahut _1000101 ];
};
nodes = {
machine = { ... }: {
diff --git a/nixpkgs/nixos/tests/trickster.nix b/nixpkgs/nixos/tests/trickster.nix
index c65160f81e3..713ac8f0b2f 100644
--- a/nixpkgs/nixos/tests/trickster.nix
+++ b/nixpkgs/nixos/tests/trickster.nix
@@ -1,7 +1,7 @@
import ./make-test-python.nix ({ pkgs, ... }: {
name = "trickster";
meta = with pkgs.stdenv.lib; {
- maintainers = with maintainers; [ maintainers."1000101" ];
+ maintainers = with maintainers; [ _1000101 ];
};
nodes = {
diff --git a/nixpkgs/nixos/tests/v2ray.nix b/nixpkgs/nixos/tests/v2ray.nix
new file mode 100644
index 00000000000..f1b2570cc86
--- /dev/null
+++ b/nixpkgs/nixos/tests/v2ray.nix
@@ -0,0 +1,83 @@
+import ./make-test-python.nix ({ lib, pkgs, ... }: let
+
+ v2rayUser = {
+ # A random UUID.
+ id = "a6a46834-2150-45f8-8364-0f6f6ab32384";
+ alterId = 4;
+ };
+
+ # 1080 [http proxy] -> 1081 [vmess] -> direct
+ v2rayConfig = {
+ inbounds = [
+ {
+ tag = "http_in";
+ port = 1080;
+ listen = "127.0.0.1";
+ protocol = "http";
+ }
+ {
+ tag = "vmess_in";
+ port = 1081;
+ listen = "127.0.0.1";
+ protocol = "vmess";
+ settings.clients = [v2rayUser];
+ }
+ ];
+ outbounds = [
+ {
+ tag = "vmess_out";
+ protocol = "vmess";
+ settings.vnext = [{
+ address = "127.0.0.1";
+ port = 1081;
+ users = [v2rayUser];
+ }];
+ }
+ {
+ tag = "direct";
+ protocol = "freedom";
+ }
+ ];
+ routing.rules = [
+ {
+ type = "field";
+ inboundTag = "http_in";
+ outboundTag = "vmess_out";
+ }
+ {
+ type = "field";
+ inboundTag = "vmess_in";
+ outboundTag = "direct";
+ }
+ ];
+ };
+
+in {
+ name = "v2ray";
+ meta = with lib.maintainers; {
+ maintainers = [ servalcatty ];
+ };
+ machine = { pkgs, ... }: {
+ environment.systemPackages = [ pkgs.curl ];
+ services.v2ray = {
+ enable = true;
+ config = v2rayConfig;
+ };
+ services.httpd = {
+ enable = true;
+ adminAddr = "foo@example.org";
+ };
+ };
+
+ testScript = ''
+ start_all()
+
+ machine.wait_for_unit("httpd.service")
+ machine.wait_for_unit("v2ray.service")
+ machine.wait_for_open_port(80)
+ machine.wait_for_open_port(1080)
+ machine.succeed(
+ "curl --fail --max-time 10 --proxy http://localhost:1080 http://localhost"
+ )
+ '';
+})
diff --git a/nixpkgs/nixos/tests/virtualbox.nix b/nixpkgs/nixos/tests/virtualbox.nix
index aec8da6a2af..0d9eafa4a20 100644
--- a/nixpkgs/nixos/tests/virtualbox.nix
+++ b/nixpkgs/nixos/tests/virtualbox.nix
@@ -15,7 +15,7 @@
assert use64bitGuest -> useKvmNestedVirt;
-with import ../lib/testing.nix { inherit system pkgs; };
+with import ../lib/testing-python.nix { inherit system pkgs; };
with pkgs.lib;
let
@@ -91,13 +91,15 @@ let
(isYes "SERIAL_8250_CONSOLE")
(isYes "SERIAL_8250")
];
+
+ networking.usePredictableInterfaceNames = false;
};
mkLog = logfile: tag: let
rotated = map (i: "${logfile}.${toString i}") (range 1 9);
all = concatMapStringsSep " " (f: "\"${f}\"") ([logfile] ++ rotated);
logcmd = "tail -F ${all} 2> /dev/null | logger -t \"${tag}\"";
- in optionalString debug "$machine->execute(ru '${logcmd} & disown');";
+ in if debug then "machine.execute(ru('${logcmd} & disown'))" else "pass";
testVM = vmName: vmScript: let
cfg = (import ../lib/eval-config.nix {
@@ -198,103 +200,111 @@ let
systemd.services."vboxtestlog-${name}@" = {
description = "VirtualBox Test Machine Log For ${name}";
serviceConfig.StandardInput = "socket";
- serviceConfig.StandardOutput = "syslog";
serviceConfig.SyslogIdentifier = "GUEST-${name}";
serviceConfig.ExecStart = "${pkgs.coreutils}/bin/cat";
};
};
testSubs = ''
- my ${"$" + name}_sharepath = '${sharePath}';
-
- sub checkRunning_${name} {
- my $cmd = 'VBoxManage list runningvms | grep -q "^\"${name}\""';
- my ($status, $out) = $machine->execute(ru $cmd);
- return $status == 0;
- }
-
- sub cleanup_${name} {
- $machine->execute(ru "VBoxManage controlvm ${name} poweroff")
- if checkRunning_${name};
- $machine->succeed("rm -rf ${sharePath}");
- $machine->succeed("mkdir -p ${sharePath}");
- $machine->succeed("chown alice.users ${sharePath}");
- }
-
- sub createVM_${name} {
- vbm("createvm --name ${name} ${createFlags}");
- vbm("modifyvm ${name} ${vmFlags}");
- vbm("setextradata ${name} VBoxInternal/PDM/HaltOnReset 1");
- vbm("storagectl ${name} ${controllerFlags}");
- vbm("storageattach ${name} ${diskFlags}");
- vbm("sharedfolder add ${name} ${sharedFlags}");
- vbm("sharedfolder add ${name} ${nixstoreFlags}");
- cleanup_${name};
-
- ${mkLog "$HOME/VirtualBox VMs/${name}/Logs/VBox.log" "HOST-${name}"}
- }
-
- sub destroyVM_${name} {
- cleanup_${name};
- vbm("unregistervm ${name} --delete");
- }
-
- sub waitForVMBoot_${name} {
- $machine->execute(ru(
- 'set -e; i=0; '.
- 'while ! test -e ${sharePath}/boot-done; do '.
- 'sleep 10; i=$(($i + 10)); [ $i -le 3600 ]; '.
- 'VBoxManage list runningvms | grep -q "^\"${name}\""; '.
- 'done'
- ));
- }
-
- sub waitForIP_${name} ($) {
- my $property = "/VirtualBox/GuestInfo/Net/$_[0]/V4/IP";
- my $getip = "VBoxManage guestproperty get ${name} $property | ".
- "sed -n -e 's/^Value: //p'";
- my $ip = $machine->succeed(ru(
- 'for i in $(seq 1000); do '.
- 'if ipaddr="$('.$getip.')" && [ -n "$ipaddr" ]; then '.
- 'echo "$ipaddr"; exit 0; '.
- 'fi; '.
- 'sleep 1; '.
- 'done; '.
- 'echo "Could not get IPv4 address for ${name}!" >&2; '.
- 'exit 1'
- ));
- chomp $ip;
- return $ip;
- }
-
- sub waitForStartup_${name} {
- for (my $i = 0; $i <= 120; $i += 10) {
- $machine->sleep(10);
- return if checkRunning_${name};
- eval { $_[0]->() } if defined $_[0];
- }
- die "VirtualBox VM didn't start up within 2 minutes";
- }
-
- sub waitForShutdown_${name} {
- for (my $i = 0; $i <= 120; $i += 10) {
- $machine->sleep(10);
- return unless checkRunning_${name};
- }
- die "VirtualBox VM didn't shut down within 2 minutes";
- }
-
- sub shutdownVM_${name} {
- $machine->succeed(ru "touch ${sharePath}/shutdown");
- $machine->execute(
- 'set -e; i=0; '.
- 'while test -e ${sharePath}/shutdown '.
- ' -o -e ${sharePath}/boot-done; do '.
- 'sleep 1; i=$(($i + 1)); [ $i -le 3600 ]; '.
- 'done'
- );
- waitForShutdown_${name};
- }
+
+
+ ${name}_sharepath = "${sharePath}"
+
+
+ def check_running_${name}():
+ cmd = "VBoxManage list runningvms | grep -q '^\"${name}\"'"
+ (status, _) = machine.execute(ru(cmd))
+ return status == 0
+
+
+ def cleanup_${name}():
+ if check_running_${name}():
+ machine.execute(ru("VBoxManage controlvm ${name} poweroff"))
+ machine.succeed("rm -rf ${sharePath}")
+ machine.succeed("mkdir -p ${sharePath}")
+ machine.succeed("chown alice.users ${sharePath}")
+
+
+ def create_vm_${name}():
+ # fmt: off
+ vbm(f"createvm --name ${name} ${createFlags}")
+ vbm(f"modifyvm ${name} ${vmFlags}")
+ vbm(f"setextradata ${name} VBoxInternal/PDM/HaltOnReset 1")
+ vbm(f"storagectl ${name} ${controllerFlags}")
+ vbm(f"storageattach ${name} ${diskFlags}")
+ vbm(f"sharedfolder add ${name} ${sharedFlags}")
+ vbm(f"sharedfolder add ${name} ${nixstoreFlags}")
+ cleanup_${name}()
+
+ ${mkLog "$HOME/VirtualBox VMs/${name}/Logs/VBox.log" "HOST-${name}"}
+ # fmt: on
+
+
+ def destroy_vm_${name}():
+ cleanup_${name}()
+ vbm("unregistervm ${name} --delete")
+
+
+ def wait_for_vm_boot_${name}():
+ machine.execute(
+ ru(
+ "set -e; i=0; "
+ "while ! test -e ${sharePath}/boot-done; do "
+ "sleep 10; i=$(($i + 10)); [ $i -le 3600 ]; "
+ "VBoxManage list runningvms | grep -q '^\"${name}\"'; "
+ "done"
+ )
+ )
+
+
+ def wait_for_ip_${name}(interface):
+ property = f"/VirtualBox/GuestInfo/Net/{interface}/V4/IP"
+ # fmt: off
+ getip = f"VBoxManage guestproperty get ${name} {property} | sed -n -e 's/^Value: //p'"
+ # fmt: on
+
+ ip = machine.succeed(
+ ru(
+ "for i in $(seq 1000); do "
+ f'if ipaddr="$({getip})" && [ -n "$ipaddr" ]; then '
+ 'echo "$ipaddr"; exit 0; '
+ "fi; "
+ "sleep 1; "
+ "done; "
+ "echo 'Could not get IPv4 address for ${name}!' >&2; "
+ "exit 1"
+ )
+ ).strip()
+ return ip
+
+
+ def wait_for_startup_${name}(nudge=lambda: None):
+ for _ in range(0, 130, 10):
+ machine.sleep(10)
+ if check_running_${name}():
+ return
+ nudge()
+ raise Exception("VirtualBox VM didn't start up within 2 minutes")
+
+
+ def wait_for_shutdown_${name}():
+ for _ in range(0, 130, 10):
+ machine.sleep(10)
+ if not check_running_${name}():
+ return
+ raise Exception("VirtualBox VM didn't shut down within 2 minutes")
+
+
+ def shutdown_vm_${name}():
+ machine.succeed(ru("touch ${sharePath}/shutdown"))
+ machine.execute(
+ "set -e; i=0; "
+ "while test -e ${sharePath}/shutdown "
+ " -o -e ${sharePath}/boot-done; do "
+ "sleep 1; i=$(($i + 1)); [ $i -le 3600 ]; "
+ "done"
+ )
+ wait_for_shutdown_${name}()
'';
};
@@ -365,26 +375,31 @@ let
};
testScript = ''
- sub ru ($) {
- my $esc = $_[0] =~ s/'/'\\${"'"}'/gr;
- return "su - alice -c '$esc'";
- }
+ from shlex import quote
+ ${concatStrings (mapAttrsToList (_: getAttr "testSubs") vms)}
- sub vbm {
- $machine->succeed(ru("VBoxManage ".$_[0]));
- };
+ def ru(cmd: str) -> str:
+ return f"su - alice -c {quote(cmd)}"
- sub removeUUIDs {
- return join("\n", grep { $_ !~ /^UUID:/ } split(/\n/, $_[0]))."\n";
- }
- ${concatStrings (mapAttrsToList (_: getAttr "testSubs") vms)}
+ def vbm(cmd: str) -> str:
+ return machine.succeed(ru(f"VBoxManage {cmd}"))
+
+
+ def remove_uuids(output: str) -> str:
+ return "\n".join(
+ [line for line in (output or "").splitlines() if not line.startswith("UUID:")]
+ )
+
- $machine->waitForX;
+ machine.wait_for_x()
+ # fmt: off
${mkLog "$HOME/.config/VirtualBox/VBoxSVC.log" "HOST-SVC"}
+ # fmt: on
${testScript}
+ # (keep black happy)
'';
meta = with pkgs.stdenv.lib.maintainers; {
@@ -394,133 +409,129 @@ let
unfreeTests = mapAttrs (mkVBoxTest true vboxVMsWithExtpack) {
enable-extension-pack = ''
- createVM_testExtensionPack;
- vbm("startvm testExtensionPack");
- waitForStartup_testExtensionPack;
- $machine->screenshot("cli_started");
- waitForVMBoot_testExtensionPack;
- $machine->screenshot("cli_booted");
-
- $machine->nest("Checking for privilege escalation", sub {
- $machine->fail("test -e '/root/VirtualBox VMs'");
- $machine->fail("test -e '/root/.config/VirtualBox'");
- $machine->succeed("test -e '/home/alice/VirtualBox VMs'");
- });
-
- shutdownVM_testExtensionPack;
- destroyVM_testExtensionPack;
+ create_vm_testExtensionPack()
+ vbm("startvm testExtensionPack")
+ wait_for_startup_testExtensionPack()
+ machine.screenshot("cli_started")
+ wait_for_vm_boot_testExtensionPack()
+ machine.screenshot("cli_booted")
+
+ with machine.nested("Checking for privilege escalation"):
+ machine.fail("test -e '/root/VirtualBox VMs'")
+ machine.fail("test -e '/root/.config/VirtualBox'")
+ machine.succeed("test -e '/home/alice/VirtualBox VMs'")
+
+ shutdown_vm_testExtensionPack()
+ destroy_vm_testExtensionPack()
'';
};
in mapAttrs (mkVBoxTest false vboxVMs) {
simple-gui = ''
- createVM_simple;
- $machine->succeed(ru "VirtualBox &");
- $machine->waitUntilSucceeds(
- ru "xprop -name 'Oracle VM VirtualBox Manager'"
- );
- $machine->sleep(5);
- $machine->screenshot("gui_manager_started");
# Home to select Tools, down to move to the VM, enter to start it.
- $machine->sendKeys("home");
- $machine->sendKeys("down");
- $machine->sendKeys("ret");
- $machine->screenshot("gui_manager_sent_startup");
- waitForStartup_simple (sub {
- $machine->sendKeys("home");
- $machine->sendKeys("down");
- $machine->sendKeys("ret");
- });
- $machine->screenshot("gui_started");
- waitForVMBoot_simple;
- $machine->screenshot("gui_booted");
- shutdownVM_simple;
- $machine->sleep(5);
- $machine->screenshot("gui_stopped");
- $machine->sendKeys("ctrl-q");
- $machine->sleep(5);
- $machine->screenshot("gui_manager_stopped");
- destroyVM_simple;
+ def send_vm_startup():
+ machine.send_key("home")
+ machine.send_key("down")
+ machine.send_key("ret")
+
+
+ create_vm_simple()
+ machine.succeed(ru("VirtualBox &"))
+ machine.wait_until_succeeds(ru("xprop -name 'Oracle VM VirtualBox Manager'"))
+ machine.sleep(5)
+ machine.screenshot("gui_manager_started")
+ send_vm_startup()
+ machine.screenshot("gui_manager_sent_startup")
+ wait_for_startup_simple(send_vm_startup)
+ machine.screenshot("gui_started")
+ wait_for_vm_boot_simple()
+ machine.screenshot("gui_booted")
+ shutdown_vm_simple()
+ machine.sleep(5)
+ machine.screenshot("gui_stopped")
+ machine.send_key("ctrl-q")
+ machine.sleep(5)
+ machine.screenshot("gui_manager_stopped")
+ destroy_vm_simple()
'';
simple-cli = ''
- createVM_simple;
- vbm("startvm simple");
- waitForStartup_simple;
- $machine->screenshot("cli_started");
- waitForVMBoot_simple;
- $machine->screenshot("cli_booted");
-
- $machine->nest("Checking for privilege escalation", sub {
- $machine->fail("test -e '/root/VirtualBox VMs'");
- $machine->fail("test -e '/root/.config/VirtualBox'");
- $machine->succeed("test -e '/home/alice/VirtualBox VMs'");
- });
-
- shutdownVM_simple;
- destroyVM_simple;
+ create_vm_simple()
+ vbm("startvm simple")
+ wait_for_startup_simple()
+ machine.screenshot("cli_started")
+ wait_for_vm_boot_simple()
+ machine.screenshot("cli_booted")
+
+ with machine.nested("Checking for privilege escalation"):
+ machine.fail("test -e '/root/VirtualBox VMs'")
+ machine.fail("test -e '/root/.config/VirtualBox'")
+ machine.succeed("test -e '/home/alice/VirtualBox VMs'")
+
+ shutdown_vm_simple()
+ destroy_vm_simple()
'';
headless = ''
- createVM_headless;
- $machine->succeed(ru("VBoxHeadless --startvm headless & disown %1"));
- waitForStartup_headless;
- waitForVMBoot_headless;
- shutdownVM_headless;
- destroyVM_headless;
+ create_vm_headless()
+ machine.succeed(ru("VBoxHeadless --startvm headless & disown %1"))
+ wait_for_startup_headless()
+ wait_for_vm_boot_headless()
+ shutdown_vm_headless()
+ destroy_vm_headless()
'';
host-usb-permissions = ''
- my $userUSB = removeUUIDs vbm("list usbhost");
- print STDERR $userUSB;
- my $rootUSB = removeUUIDs $machine->succeed("VBoxManage list usbhost");
- print STDERR $rootUSB;
-
- die "USB host devices differ for root and normal user"
- if $userUSB ne $rootUSB;
- die "No USB host devices found" if $userUSB =~ /<none>/;
+ user_usb = remove_uuids(vbm("list usbhost"))
+ print(user_usb, file=sys.stderr)
+ root_usb = remove_uuids(machine.succeed("VBoxManage list usbhost"))
+ print(root_usb, file=sys.stderr)
+
+ if user_usb != root_usb:
+ raise Exception("USB host devices differ for root and normal user")
+ if "<none>" in user_usb:
+ raise Exception("No USB host devices found")
'';
systemd-detect-virt = ''
- createVM_detectvirt;
- vbm("startvm detectvirt");
- waitForStartup_detectvirt;
- waitForVMBoot_detectvirt;
- shutdownVM_detectvirt;
- my $result = $machine->succeed("cat '$detectvirt_sharepath/result'");
- chomp $result;
- destroyVM_detectvirt;
- die "systemd-detect-virt returned \"$result\" instead of \"oracle\""
- if $result ne "oracle";
+ create_vm_detectvirt()
+ vbm("startvm detectvirt")
+ wait_for_startup_detectvirt()
+ wait_for_vm_boot_detectvirt()
+ shutdown_vm_detectvirt()
+ result = machine.succeed(f"cat '{detectvirt_sharepath}/result'").strip()
+ destroy_vm_detectvirt()
+ if result != "oracle":
+ raise Exception(f'systemd-detect-virt returned "{result}" instead of "oracle"')
'';
net-hostonlyif = ''
- createVM_test1;
- createVM_test2;
+ create_vm_test1()
+ create_vm_test2()
- vbm("startvm test1");
- waitForStartup_test1;
- waitForVMBoot_test1;
+ vbm("startvm test1")
+ wait_for_startup_test1()
+ wait_for_vm_boot_test1()
- vbm("startvm test2");
- waitForStartup_test2;
- waitForVMBoot_test2;
+ vbm("startvm test2")
+ wait_for_startup_test2()
+ wait_for_vm_boot_test2()
- $machine->screenshot("net_booted");
+ machine.screenshot("net_booted")
- my $test1IP = waitForIP_test1 1;
- my $test2IP = waitForIP_test2 1;
+ test1_ip = wait_for_ip_test1(1)
+ test2_ip = wait_for_ip_test2(1)
- $machine->succeed("echo '$test2IP' | nc -N '$test1IP' 1234");
- $machine->succeed("echo '$test1IP' | nc -N '$test2IP' 1234");
+ machine.succeed(f"echo '{test2_ip}' | nc -N '{test1_ip}' 1234")
+ machine.succeed(f"echo '{test1_ip}' | nc -N '{test2_ip}' 1234")
- $machine->waitUntilSucceeds("nc -N '$test1IP' 5678 < /dev/null >&2");
- $machine->waitUntilSucceeds("nc -N '$test2IP' 5678 < /dev/null >&2");
+ machine.wait_until_succeeds(f"nc -N '{test1_ip}' 5678 < /dev/null >&2")
+ machine.wait_until_succeeds(f"nc -N '{test2_ip}' 5678 < /dev/null >&2")
- shutdownVM_test1;
- shutdownVM_test2;
+ shutdown_vm_test1()
+ shutdown_vm_test2()
- destroyVM_test1;
- destroyVM_test2;
+ destroy_vm_test1()
+ destroy_vm_test2()
'';
} // (if enableUnfree then unfreeTests else {})
diff --git a/nixpkgs/nixos/tests/xandikos.nix b/nixpkgs/nixos/tests/xandikos.nix
index 886c3e0082f..48c770a3d16 100644
--- a/nixpkgs/nixos/tests/xandikos.nix
+++ b/nixpkgs/nixos/tests/xandikos.nix
@@ -4,7 +4,7 @@ import ./make-test-python.nix (
{
name = "xandikos";
- meta.maintainers = [ lib.maintainers."0x4A6F" ];
+ meta.maintainers = with lib.maintainers; [ _0x4A6F ];
nodes = {
xandikos_client = {};
diff --git a/nixpkgs/nixos/tests/xmpp/ejabberd.nix b/nixpkgs/nixos/tests/xmpp/ejabberd.nix
index 1518aaacc8a..2b09f99f5fd 100644
--- a/nixpkgs/nixos/tests/xmpp/ejabberd.nix
+++ b/nixpkgs/nixos/tests/xmpp/ejabberd.nix
@@ -5,6 +5,10 @@ import ../make-test-python.nix ({ pkgs, ... }: {
};
nodes = {
client = { nodes, pkgs, ... }: {
+ networking.extraHosts = ''
+ ${nodes.server.config.networking.primaryIPAddress} example.com
+ '';
+
environment.systemPackages = [
(pkgs.callPackage ./xmpp-sendmessage.nix { connectTo = nodes.server.config.networking.primaryIPAddress; })
];
@@ -46,6 +50,11 @@ import ../make-test-python.nix ({ pkgs, ... }: {
module: ejabberd_service
access: local
shaper: fast
+ -
+ port: 5444
+ module: ejabberd_http
+ request_handlers:
+ "/upload": mod_http_upload
## Disabling digest-md5 SASL authentication. digest-md5 requires plain-text
## password storage (see auth_password_format option).
@@ -180,6 +189,7 @@ import ../make-test-python.nix ({ pkgs, ... }: {
mod_client_state: {}
mod_configure: {} # requires mod_adhoc
## mod_delegation: {} # for xep0356
+ mod_disco: {}
#mod_irc:
# host: "irc.@HOST@"
# default_encoding: "utf-8"
@@ -187,9 +197,9 @@ import ../make-test-python.nix ({ pkgs, ... }: {
## mod_http_fileserver:
## docroot: "/var/www"
## accesslog: "/var/log/ejabberd/access.log"
- #mod_http_upload:
- # thumbnail: false # otherwise needs the identify command from ImageMagick installed
- # put_url: "https://@HOST@:5444"
+ mod_http_upload:
+ thumbnail: false # otherwise needs the identify command from ImageMagick installed
+ put_url: "http://@HOST@:5444/upload"
## # docroot: "@HOME@/upload"
#mod_http_upload_quota:
# max_days: 14
diff --git a/nixpkgs/nixos/tests/xmpp/xmpp-sendmessage.nix b/nixpkgs/nixos/tests/xmpp/xmpp-sendmessage.nix
index 349b9c6f38e..30945e68300 100644
--- a/nixpkgs/nixos/tests/xmpp/xmpp-sendmessage.nix
+++ b/nixpkgs/nixos/tests/xmpp/xmpp-sendmessage.nix
@@ -36,7 +36,11 @@ class CthonTest(ClientXMPP):
def timeout_callback(arg):
log.error("ERROR: Cannot upload file. XEP_0363 seems broken")
sys.exit(1)
- url = await self['xep_0363'].upload_file("${dummyFile}",timeout=10, timeout_callback=timeout_callback)
+ try:
+ url = await self['xep_0363'].upload_file("${dummyFile}",timeout=10, timeout_callback=timeout_callback)
+ except:
+ log.error("ERROR: Cannot run upload command. XEP_0363 seems broken")
+ sys.exit(1)
log.info('Upload success!')
# Test MUC
self.plugin['xep_0045'].join_muc('testMucRoom', 'cthon98', wait=True)
diff --git a/nixpkgs/nixos/tests/zfs.nix b/nixpkgs/nixos/tests/zfs.nix
index 7ba60ee9806..87e6c900c98 100644
--- a/nixpkgs/nixos/tests/zfs.nix
+++ b/nixpkgs/nixos/tests/zfs.nix
@@ -46,6 +46,17 @@ let
"zpool destroy rpool",
"udevadm settle",
)
+
+ machine.succeed(
+ 'echo password | zpool create -o altroot="/tmp/mnt" '
+ + "-O encryption=aes-256-gcm -O keyformat=passphrase rpool /dev/vdb1",
+ "zfs create -o mountpoint=legacy rpool/root",
+ "mount -t zfs rpool/root /tmp/mnt",
+ "udevadm settle",
+ "umount /tmp/mnt",
+ "zpool destroy rpool",
+ "udevadm settle",
+ )
'' + extraTest;
};
@@ -57,18 +68,6 @@ in {
unstable = makeZfsTest "unstable" {
enableUnstable = true;
- extraTest = ''
- machine.succeed(
- 'echo password | zpool create -o altroot="/tmp/mnt" '
- + "-O encryption=aes-256-gcm -O keyformat=passphrase rpool /dev/vdb1",
- "zfs create -o mountpoint=legacy rpool/root",
- "mount -t zfs rpool/root /tmp/mnt",
- "udevadm settle",
- "umount /tmp/mnt",
- "zpool destroy rpool",
- "udevadm settle",
- )
- '';
};
installer = (import ./installer.nix { }).zfsroot;