0
0
Fork 0
mirror of https://github.com/NixOS/nixpkgs.git synced 2025-07-12 05:16:25 +03:00

Merge master into staging-next

This commit is contained in:
github-actions[bot] 2024-03-16 18:01:00 +00:00 committed by GitHub
commit 60fbf92c10
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
116 changed files with 2548 additions and 828 deletions

View file

@ -103,6 +103,8 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m
- [Monado](https://monado.freedesktop.org/), an open source XR runtime. Available as [services.monado](#opt-services.monado.enable).
- [Pretix](https://pretix.eu/about/en/), an open source ticketing software for events. Available as [services.pretix]($opt-services-pretix.enable).
- [Clevis](https://github.com/latchset/clevis), a pluggable framework for automated decryption, used to unlock encrypted devices in initrd. Available as [boot.initrd.clevis.enable](#opt-boot.initrd.clevis.enable).
- [armagetronad](https://wiki.armagetronad.org), a mid-2000s 3D lightcycle game widely played at iD Tech Camps. You can define multiple servers using `services.armagetronad.<server>.enable`.
@ -320,7 +322,12 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m
- `addDriverRunpath` has been added to facilitate the deprecation of the old `addOpenGLRunpath` setuphook. This change is motivated by the evolution of the setuphook to include all hardware acceleration.
- Cinnamon has been updated to 6.0. Please beware that the [Wayland session](https://blog.linuxmint.com/?p=4591) is still experimental in this release.
- Cinnamon has been updated to 6.0. Please beware that the [Wayland session](https://blog.linuxmint.com/?p=4591) is still experimental in this release and could potentially [affect Xorg sessions](https://blog.linuxmint.com/?p=4639). We suggest a reboot when switching between sessions.
- MATE has been updated to 1.28.
- To properly support panel plugins built with Wayland (in-process) support, we are introducing `services.xserver.desktopManager.mate.extraPanelApplets` option, please use that for installing panel applets.
- Similarly, please use `services.xserver.desktopManager.mate.extraCajaExtensions` option for installing Caja extensions.
- To use the Wayland session, enable `services.xserver.desktopManager.mate.enableWaylandSession`. This is opt-in for now as it is in early stage and introduces a new set of Wayfire closure. Due to [known issues with LightDM](https://github.com/canonical/lightdm/issues/63), we suggest using SDDM for display manager.
- New `boot.loader.systemd-boot.xbootldrMountPoint` allows setting up a separate [XBOOTLDR partition](https://uapi-group.org/specifications/specs/boot_loader_specification/) to store boot files. Useful on systems with a small EFI System partition that cannot be easily repartitioned.
@ -347,6 +354,8 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m
- [Lilypond](https://lilypond.org/index.html) and [Denemo](https://www.denemo.org) are now compiled with Guile 3.0.
- The EC2 image module now enables the [Amazon SSM Agent](https://docs.aws.amazon.com/systems-manager/latest/userguide/ssm-agent.html) by default.
- The following options of the Nextcloud module were moved into [`services.nextcloud.settings`](#opt-services.nextcloud.settings) and renamed to match the name from Nextcloud's `config.php`:
- `logLevel` -> [`loglevel`](#opt-services.nextcloud.settings.loglevel),
- `logType` -> [`log_type`](#opt-services.nextcloud.settings.log_type),

View file

@ -30,7 +30,10 @@ in
ipu6-drivers
];
hardware.firmware = [ pkgs.ipu6-camera-bins ];
hardware.firmware = with pkgs; [
ipu6-camera-bins
ivsc-firmware
];
services.udev.extraRules = ''
SUBSYSTEM=="intel-ipu6-psys", MODE="0660", GROUP="video"

View file

@ -1358,6 +1358,7 @@
./services/web-apps/plausible.nix
./services/web-apps/powerdns-admin.nix
./services/web-apps/pretalx.nix
./services/web-apps/pretix.nix
./services/web-apps/prosody-filer.nix
./services/web-apps/rimgo.nix
./services/web-apps/sftpgo.nix

View file

@ -600,6 +600,7 @@ in
description = "Ensure that NetworkManager declarative profiles are created";
wantedBy = [ "multi-user.target" ];
before = [ "network-online.target" ];
after = [ "NetworkManager.service" ];
script = let
path = id: "/run/NetworkManager/system-connections/${id}.nmconnection";
in ''
@ -609,9 +610,7 @@ in
${pkgs.envsubst}/bin/envsubst -i ${ini.generate (lib.escapeShellArg profile.n) profile.v} > ${path (lib.escapeShellArg profile.n)}
'') (lib.mapAttrsToList (n: v: { inherit n v; }) cfg.ensureProfiles.profiles)
+ ''
if systemctl is-active --quiet NetworkManager; then
${pkgs.networkmanager}/bin/nmcli connection reload
fi
${pkgs.networkmanager}/bin/nmcli connection reload
'';
serviceConfig = {
EnvironmentFile = cfg.ensureProfiles.environmentFiles;

View file

@ -1,99 +1,122 @@
{ config, pkgs, lib, ... }:
with lib;
{
config,
pkgs,
lib,
...
}:
let
cfg = config.services.komga;
in {
inherit (lib) mkOption mkEnableOption maintainers;
inherit (lib.types) port str bool;
in
{
options = {
services.komga = {
enable = mkEnableOption (lib.mdDoc "Komga, a free and open source comics/mangas media server");
enable = mkEnableOption "Komga, a free and open source comics/mangas media server";
port = mkOption {
type = types.port;
type = port;
default = 8080;
description = lib.mdDoc ''
The port that Komga will listen on.
'';
description = "The port that Komga will listen on.";
};
user = mkOption {
type = types.str;
type = str;
default = "komga";
description = lib.mdDoc ''
User account under which Komga runs.
'';
description = "User account under which Komga runs.";
};
group = mkOption {
type = types.str;
type = str;
default = "komga";
description = lib.mdDoc ''
Group under which Komga runs.
'';
description = "Group under which Komga runs.";
};
stateDir = mkOption {
type = types.str;
type = str;
default = "/var/lib/komga";
description = lib.mdDoc ''
State and configuration directory Komga will use.
'';
description = "State and configuration directory Komga will use.";
};
openFirewall = mkOption {
type = types.bool;
type = bool;
default = false;
description = lib.mdDoc ''
Whether to open the firewall for the port in {option}`services.komga.port`.
'';
description = "Whether to open the firewall for the port in {option}`services.komga.port`.";
};
};
};
config = mkIf cfg.enable {
config =
let
inherit (lib) mkIf getExe;
in
mkIf cfg.enable {
networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.port ];
networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.port ];
users.groups = mkIf (cfg.group == "komga") {
komga = {};
};
users.groups = mkIf (cfg.group == "komga") { komga = { }; };
users.users = mkIf (cfg.user == "komga") {
komga = {
group = cfg.group;
home = cfg.stateDir;
description = "Komga Daemon user";
isSystemUser = true;
};
};
systemd.services.komga = {
environment = {
SERVER_PORT = builtins.toString cfg.port;
KOMGA_CONFIGDIR = cfg.stateDir;
users.users = mkIf (cfg.user == "komga") {
komga = {
group = cfg.group;
home = cfg.stateDir;
description = "Komga Daemon user";
isSystemUser = true;
};
};
description = "Komga is a free and open source comics/mangas media server";
systemd.services.komga = {
environment = {
SERVER_PORT = builtins.toString cfg.port;
KOMGA_CONFIGDIR = cfg.stateDir;
};
wantedBy = [ "multi-user.target" ];
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
description = "Komga is a free and open source comics/mangas media server";
serviceConfig = {
User = cfg.user;
Group = cfg.group;
wantedBy = [ "multi-user.target" ];
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
Type = "simple";
Restart = "on-failure";
ExecStart = "${pkgs.komga}/bin/komga";
serviceConfig = {
User = cfg.user;
Group = cfg.group;
StateDirectory = mkIf (cfg.stateDir == "/var/lib/komga") "komga";
Type = "simple";
Restart = "on-failure";
ExecStart = getExe pkgs.komga;
StateDirectory = mkIf (cfg.stateDir == "/var/lib/komga") "komga";
RemoveIPC = true;
NoNewPrivileges = true;
CapabilityBoundingSet = "";
SystemCallFilter = [ "@system-service" ];
ProtectSystem = "full";
PrivateTmp = true;
ProtectProc = "invisible";
ProtectClock = true;
ProcSubset = "pid";
PrivateUsers = true;
PrivateDevices = true;
ProtectHostname = true;
ProtectKernelTunables = true;
RestrictAddressFamilies = [
"AF_INET"
"AF_INET6"
"AF_NETLINK"
];
LockPersonality = true;
RestrictNamespaces = true;
ProtectKernelLogs = true;
ProtectControlGroups = true;
ProtectKernelModules = true;
SystemCallArchitectures = "native";
RestrictSUIDSGID = true;
RestrictRealtime = true;
};
};
};
};
meta.maintainers = with maintainers; [ govanify ];
}

View file

@ -0,0 +1,579 @@
{ config
, lib
, pkgs
, utils
, ...
}:
let
inherit (lib)
concatMapStringsSep
escapeShellArgs
filter
filterAttrs
getExe
getExe'
isAttrs
isList
literalExpression
mapAttrs
mkDefault
mkEnableOption
mkIf
mkOption
mkPackageOption
optionals
optionalString
recursiveUpdate
types
;
filterRecursiveNull = o:
if isAttrs o then
mapAttrs (_: v: filterRecursiveNull v) (filterAttrs (_: v: v != null) o)
else if isList o then
map filterRecursiveNull (filter (v: v != null) o)
else
o;
cfg = config.services.pretix;
format = pkgs.formats.ini { };
configFile = format.generate "pretix.cfg" (filterRecursiveNull cfg.settings);
finalPackage = cfg.package.override {
inherit (cfg) plugins;
};
pythonEnv = cfg.package.python.buildEnv.override {
extraLibs = with cfg.package.python.pkgs; [
(toPythonModule finalPackage)
gunicorn
]
++ lib.optionals (cfg.settings.memcached.location != null)
cfg.package.optional-dependencies.memcached
;
};
withRedis = cfg.settings.redis.location != null;
in
{
meta = with lib; {
maintainers = with maintainers; [ hexa ];
};
options.services.pretix = {
enable = mkEnableOption "pretix";
package = mkPackageOption pkgs "pretix" { };
group = mkOption {
type = types.str;
default = "pretix";
description = ''
Group under which pretix should run.
'';
};
user = mkOption {
type = types.str;
default = "pretix";
description = ''
User under which pretix should run.
'';
};
environmentFile = mkOption {
type = types.nullOr types.path;
default = null;
example = "/run/keys/pretix-secrets.env";
description = ''
Environment file to pass secret configuration values.
Each line must follow the `PRETIX_SECTION_KEY=value` pattern.
'';
};
plugins = mkOption {
type = types.listOf types.package;
default = [];
example = literalExpression ''
with config.services.pretix.package.plugins; [
passbook
pages
];
'';
description = ''
Pretix plugins to install into the Python environment.
'';
};
gunicorn.extraArgs = mkOption {
type = with types; listOf str;
default = [
"--name=pretix"
];
example = [
"--name=pretix"
"--workers=4"
"--max-requests=1200"
"--max-requests-jitter=50"
"--log-level=info"
];
description = ''
Extra arguments to pass to gunicorn.
See <https://docs.pretix.eu/en/latest/admin/installation/manual_smallscale.html#start-pretix-as-a-service> for details.
'';
apply = escapeShellArgs;
};
celery = {
extraArgs = mkOption {
type = with types; listOf str;
default = [ ];
description = ''
Extra arguments to pass to celery.
See <https://docs.celeryq.dev/en/stable/reference/cli.html#celery-worker> for more info.
'';
apply = utils.escapeSystemdExecArgs;
};
};
nginx = {
enable = mkOption {
type = types.bool;
default = true;
example = false;
description = ''
Whether to set up an nginx virtual host.
'';
};
domain = mkOption {
type = types.str;
example = "talks.example.com";
description = ''
The domain name under which to set up the virtual host.
'';
};
};
database.createLocally = mkOption {
type = types.bool;
default = true;
example = false;
description = ''
Whether to automatically set up the database on the local DBMS instance.
Only supported for PostgreSQL. Not required for sqlite.
'';
};
settings = mkOption {
type = types.submodule {
freeformType = format.type;
options = {
pretix = {
instance_name = mkOption {
type = types.str;
example = "tickets.example.com";
description = ''
The name of this installation.
'';
};
url = mkOption {
type = types.str;
example = "https://tickets.example.com";
description = ''
The installations full URL, without a trailing slash.
'';
};
cachedir = mkOption {
type = types.path;
default = "/var/cache/pretix";
description = ''
Directory for storing temporary files.
'';
};
datadir = mkOption {
type = types.path;
default = "/var/lib/pretix";
description = ''
Directory for storing user uploads and similar data.
'';
};
logdir = mkOption {
type = types.path;
default = "/var/log/pretix";
description = ''
Directory for storing log files.
'';
};
currency = mkOption {
type = types.str;
default = "EUR";
example = "USD";
description = ''
Default currency for events in its ISO 4217 three-letter code.
'';
};
registration = mkOption {
type = types.bool;
default = false;
example = true;
description = ''
Whether to allow registration of new admin users.
'';
};
};
database = {
backend = mkOption {
type = types.enum [
"sqlite3"
"postgresql"
];
default = "postgresql";
description = ''
Database backend to use.
Only postgresql is recommended for production setups.
'';
};
host = mkOption {
type = with types; nullOr types.path;
default = if cfg.settings.database.backend == "postgresql" then "/run/postgresql" else null;
defaultText = literalExpression ''
if config.services.pretix.settings..database.backend == "postgresql" then "/run/postgresql"
else null
'';
description = ''
Database host or socket path.
'';
};
name = mkOption {
type = types.str;
default = "pretix";
description = ''
Database name.
'';
};
user = mkOption {
type = types.str;
default = "pretix";
description = ''
Database username.
'';
};
};
mail = {
from = mkOption {
type = types.str;
example = "tickets@example.com";
description = ''
E-Mail address used in the `FROM` header of outgoing mails.
'';
};
host = mkOption {
type = types.str;
default = "localhost";
example = "mail.example.com";
description = ''
Hostname of the SMTP server use for mail delivery.
'';
};
port = mkOption {
type = types.port;
default = 25;
example = 587;
description = ''
Port of the SMTP server to use for mail delivery.
'';
};
};
celery = {
backend = mkOption {
type = types.str;
default = "redis+socket://${config.services.redis.servers.pretix.unixSocket}?virtual_host=1";
defaultText = literalExpression ''
optionalString config.services.pretix.celery.enable "redis+socket://''${config.services.redis.servers.pretix.unixSocket}?virtual_host=1"
'';
description = ''
URI to the celery backend used for the asynchronous job queue.
'';
};
broker = mkOption {
type = types.str;
default = "redis+socket://${config.services.redis.servers.pretix.unixSocket}?virtual_host=2";
defaultText = literalExpression ''
optionalString config.services.pretix.celery.enable "redis+socket://''${config.services.redis.servers.pretix.unixSocket}?virtual_host=2"
'';
description = ''
URI to the celery broker used for the asynchronous job queue.
'';
};
};
redis = {
location = mkOption {
type = with types; nullOr str;
default = "unix://${config.services.redis.servers.pretix.unixSocket}?db=0";
defaultText = literalExpression ''
"unix://''${config.services.redis.servers.pretix.unixSocket}?db=0"
'';
description = ''
URI to the redis server, used to speed up locking, caching and session storage.
'';
};
sessions = mkOption {
type = types.bool;
default = true;
example = false;
description = ''
Whether to use redis as the session storage.
'';
};
};
memcached = {
location = mkOption {
type = with types; nullOr str;
default = null;
example = "127.0.0.1:11211";
description = ''
The `host:port` combination or the path to the UNIX socket of a memcached instance.
Can be used instead of Redis for caching.
'';
};
};
tools = {
pdftk = mkOption {
type = types.path;
default = getExe pkgs.pdftk;
defaultText = literalExpression ''
lib.getExe pkgs.pdftk
'';
description = ''
Path to the pdftk executable.
'';
};
};
};
};
default = { };
description = ''
pretix configuration as a Nix attribute set. All settings can also be passed
from the environment.
See <https://docs.pretix.eu/en/latest/admin/config.html> for possible options.
'';
};
};
config = mkIf cfg.enable {
# https://docs.pretix.eu/en/latest/admin/installation/index.html
environment.systemPackages = [
(pkgs.writeScriptBin "pretix-manage" ''
cd ${cfg.settings.pretix.datadir}
sudo=exec
if [[ "$USER" != ${cfg.user} ]]; then
sudo='exec /run/wrappers/bin/sudo -u ${cfg.user} ${optionalString withRedis "-g redis-pretix"} --preserve-env=PRETIX_CONFIG_FILE'
fi
export PRETIX_CONFIG_FILE=${configFile}
$sudo ${getExe' pythonEnv "pretix-manage"} "$@"
'')
];
services = {
nginx = mkIf cfg.nginx.enable {
enable = true;
recommendedGzipSettings = mkDefault true;
recommendedOptimisation = mkDefault true;
recommendedProxySettings = mkDefault true;
recommendedTlsSettings = mkDefault true;
upstreams.pretix.servers."unix:/run/pretix/pretix.sock" = { };
virtualHosts.${cfg.nginx.domain} = {
# https://docs.pretix.eu/en/latest/admin/installation/manual_smallscale.html#ssl
extraConfig = ''
more_set_headers Referrer-Policy same-origin;
more_set_headers X-Content-Type-Options nosniff;
'';
locations = {
"/".proxyPass = "http://pretix";
"/media/" = {
alias = "${cfg.settings.pretix.datadir}/media/";
extraConfig = ''
access_log off;
expires 7d;
'';
};
"^~ /media/(cachedfiles|invoices)" = {
extraConfig = ''
deny all;
return 404;
'';
};
"/static/" = {
alias = "${finalPackage}/${cfg.package.python.sitePackages}/pretix/static.dist/";
extraConfig = ''
access_log off;
more_set_headers Cache-Control "public";
expires 365d;
'';
};
};
};
};
postgresql = mkIf (cfg.database.createLocally && cfg.settings.database.backend == "postgresql") {
enable = true;
ensureUsers = [ {
name = cfg.settings.database.user;
ensureDBOwnership = true;
} ];
ensureDatabases = [ cfg.settings.database.name ];
};
redis.servers.pretix.enable = withRedis;
};
systemd.services = let
commonUnitConfig = {
environment.PRETIX_CONFIG_FILE = configFile;
serviceConfig = {
User = "pretix";
Group = "pretix";
EnvironmentFile = optionals (cfg.environmentFile != null) [
cfg.environmentFile
];
StateDirectory = [
"pretix"
];
CacheDirectory = "pretix";
LogsDirectory = "pretix";
WorkingDirectory = cfg.settings.pretix.datadir;
SupplementaryGroups = optionals withRedis [
"redis-pretix"
];
AmbientCapabilities = "";
CapabilityBoundingSet = [ "" ];
DevicePolicy = "closed";
LockPersonality = true;
MemoryDenyWriteExecute = true;
NoNewPrivileges = true;
PrivateDevices = true;
PrivateTmp = true;
ProcSubset = "pid";
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectProc = "invisible";
ProtectSystem = "strict";
RemoveIPC = true;
RestrictAddressFamilies = [
"AF_INET"
"AF_INET6"
"AF_UNIX"
];
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
SystemCallArchitectures = "native";
SystemCallFilter = [
"@system-service"
"~@privileged"
"@chown"
];
UMask = "0077";
};
};
in {
pretix-web = recursiveUpdate commonUnitConfig {
description = "pretix web service";
after = [
"network.target"
"redis-pretix.service"
"postgresql.service"
];
wantedBy = [ "multi-user.target" ];
preStart = ''
versionFile="${cfg.settings.pretix.datadir}/.version"
version=$(cat "$versionFile" 2>/dev/null || echo 0)
pluginsFile="${cfg.settings.pretix.datadir}/.plugins"
plugins=$(cat "$pluginsFile" 2>/dev/null || echo "")
configuredPlugins="${concatMapStringsSep "|" (package: package.name) cfg.plugins}"
if [[ $version != ${cfg.package.version} || $plugins != $configuredPlugins ]]; then
${getExe' pythonEnv "pretix-manage"} migrate
echo "${cfg.package.version}" > "$versionFile"
echo "$configuredPlugins" > "$pluginsFile"
fi
'';
serviceConfig = {
ExecStart = "${getExe' pythonEnv "gunicorn"} --bind unix:/run/pretix/pretix.sock ${cfg.gunicorn.extraArgs} pretix.wsgi";
RuntimeDirectory = "pretix";
};
};
pretix-periodic = recursiveUpdate commonUnitConfig {
description = "pretix periodic task runner";
# every 15 minutes
startAt = [ "*:3,18,33,48" ];
serviceConfig = {
Type = "oneshot";
ExecStart = "${getExe' pythonEnv "pretix-manage"} runperiodic";
};
};
pretix-worker = recursiveUpdate commonUnitConfig {
description = "pretix asynchronous job runner";
after = [
"network.target"
"redis-pretix.service"
"postgresql.service"
];
wantedBy = [ "multi-user.target" ];
serviceConfig.ExecStart = "${getExe' pythonEnv "celery"} -A pretix.celery_app worker ${cfg.celery.extraArgs}";
};
};
systemd.sockets.pretix-web.socketConfig = {
ListenStream = "/run/pretix/pretix.sock";
SocketUser = "nginx";
};
users = {
groups."${cfg.group}" = {};
users."${cfg.user}" = {
isSystemUser = true;
createHome = true;
home = cfg.settings.pretix.datadir;
inherit (cfg) group;
};
};
};
}

View file

@ -20,6 +20,22 @@ in
};
debug = mkEnableOption (lib.mdDoc "mate-session debug messages");
extraPanelApplets = mkOption {
default = [ ];
example = literalExpression "with pkgs.mate; [ mate-applets ]";
type = types.listOf types.package;
description = lib.mdDoc "Extra applets to add to mate-panel.";
};
extraCajaExtensions = mkOption {
default = [ ];
example = lib.literalExpression "with pkgs.mate; [ caja-extensions ]";
type = types.listOf types.package;
description = lib.mdDoc "Extra extensions to add to caja.";
};
enableWaylandSession = mkEnableOption (lib.mdDoc "MATE Wayland session");
};
environment.mate.excludePackages = mkOption {
@ -31,55 +47,63 @@ in
};
config = mkIf cfg.enable {
config = mkMerge [
(mkIf (cfg.enable || cfg.enableWaylandSession) {
services.xserver.displayManager.sessionPackages = [
pkgs.mate.mate-session-manager
];
services.xserver.displayManager.sessionPackages = [
pkgs.mate.mate-session-manager
];
# Debugging
environment.sessionVariables.MATE_SESSION_DEBUG = mkIf cfg.debug "1";
# Let caja find extensions
environment.sessionVariables.CAJA_EXTENSION_DIRS = [ "${config.system.path}/lib/caja/extensions-2.0" ];
environment.systemPackages = utils.removePackagesByName
(pkgs.mate.basePackages ++
pkgs.mate.extraPackages ++
[
(pkgs.mate.caja-with-extensions.override {
extensions = cfg.extraCajaExtensions;
})
(pkgs.mate.mate-panel-with-applets.override {
applets = cfg.extraPanelApplets;
})
pkgs.desktop-file-utils
pkgs.glib
pkgs.gtk3.out
pkgs.shared-mime-info
pkgs.xdg-user-dirs # Update user dirs as described in https://freedesktop.org/wiki/Software/xdg-user-dirs/
pkgs.yelp # for 'Contents' in 'Help' menus
])
config.environment.mate.excludePackages;
# Let mate-panel find applets
environment.sessionVariables."MATE_PANEL_APPLETS_DIR" = "${config.system.path}/share/mate-panel/applets";
environment.sessionVariables."MATE_PANEL_EXTRA_MODULES" = "${config.system.path}/lib/mate-panel/applets";
programs.dconf.enable = true;
# Shell integration for VTE terminals
programs.bash.vteIntegration = mkDefault true;
programs.zsh.vteIntegration = mkDefault true;
# Debugging
environment.sessionVariables.MATE_SESSION_DEBUG = mkIf cfg.debug "1";
# Mate uses this for printing
programs.system-config-printer.enable = (mkIf config.services.printing.enable (mkDefault true));
environment.systemPackages = utils.removePackagesByName
(pkgs.mate.basePackages ++
pkgs.mate.extraPackages ++
[
pkgs.desktop-file-utils
pkgs.glib
pkgs.gtk3.out
pkgs.shared-mime-info
pkgs.xdg-user-dirs # Update user dirs as described in https://freedesktop.org/wiki/Software/xdg-user-dirs/
pkgs.yelp # for 'Contents' in 'Help' menus
])
config.environment.mate.excludePackages;
services.gnome.at-spi2-core.enable = true;
services.gnome.gnome-keyring.enable = true;
services.udev.packages = [ pkgs.mate.mate-settings-daemon ];
services.gvfs.enable = true;
services.upower.enable = config.powerManagement.enable;
services.xserver.libinput.enable = mkDefault true;
programs.dconf.enable = true;
# Shell integration for VTE terminals
programs.bash.vteIntegration = mkDefault true;
programs.zsh.vteIntegration = mkDefault true;
security.pam.services.mate-screensaver.unixAuth = true;
# Mate uses this for printing
programs.system-config-printer.enable = (mkIf config.services.printing.enable (mkDefault true));
xdg.portal.configPackages = mkDefault [ pkgs.mate.mate-desktop ];
services.gnome.at-spi2-core.enable = true;
services.gnome.gnome-keyring.enable = true;
services.udev.packages = [ pkgs.mate.mate-settings-daemon ];
services.gvfs.enable = true;
services.upower.enable = config.powerManagement.enable;
services.xserver.libinput.enable = mkDefault true;
environment.pathsToLink = [ "/share" ];
})
(mkIf cfg.enableWaylandSession {
programs.wayfire.enable = true;
programs.wayfire.plugins = [ pkgs.wayfirePlugins.firedecor ];
security.pam.services.mate-screensaver.unixAuth = true;
xdg.portal.configPackages = mkDefault [ pkgs.mate.mate-desktop ];
environment.pathsToLink = [ "/share" ];
};
environment.sessionVariables.NIX_GSETTINGS_OVERRIDES_DIR = "${pkgs.mate.mate-gsettings-overrides}/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas";
environment.systemPackages = [ pkgs.mate.mate-wayland-session ];
services.xserver.displayManager.sessionPackages = [ pkgs.mate.mate-wayland-session ];
})
];
}

View file

@ -79,6 +79,10 @@ in
serviceConfig.StandardOutput = "journal+console";
};
# Amazon-issued AMIs include the SSM Agent by default, so we do the same.
# https://docs.aws.amazon.com/systems-manager/latest/userguide/ami-preinstalled-agent.html
services.amazon-ssm-agent.enable = true;
# Allow root logins only using the SSH key that the user specified
# at instance creation time.
services.openssh.enable = true;

View file

@ -513,6 +513,7 @@ in {
mastodon = discoverTests (import ./web-apps/mastodon { inherit handleTestOn; });
pixelfed = discoverTests (import ./web-apps/pixelfed { inherit handleTestOn; });
mate = handleTest ./mate.nix {};
mate-wayland = handleTest ./mate-wayland.nix {};
matter-server = handleTest ./matter-server.nix {};
matomo = handleTest ./matomo.nix {};
matrix-appservice-irc = handleTest ./matrix/appservice-irc.nix {};
@ -729,6 +730,7 @@ in {
pppd = handleTest ./pppd.nix {};
predictable-interface-names = handleTest ./predictable-interface-names.nix {};
pretalx = runTest ./web-apps/pretalx.nix;
pretix = runTest ./web-apps/pretix.nix;
printing-socket = handleTest ./printing.nix { socket = true; };
printing-service = handleTest ./printing.nix { socket = false; };
privoxy = handleTest ./privoxy.nix {};

View file

@ -0,0 +1,63 @@
import ./make-test-python.nix ({ pkgs, lib, ... }: {
name = "mate-wayland";
meta.maintainers = lib.teams.mate.members;
nodes.machine = { ... }: {
imports = [
./common/user-account.nix
];
services.xserver.enable = true;
services.xserver.displayManager = {
sddm.enable = true; # https://github.com/canonical/lightdm/issues/63
sddm.wayland.enable = true;
defaultSession = "MATE";
autoLogin = {
enable = true;
user = "alice";
};
};
services.xserver.desktopManager.mate.enableWaylandSession = true;
hardware.pulseaudio.enable = true;
# Need to switch to a different GPU driver than the default one (-vga std) so that wayfire can launch:
virtualisation.qemu.options = [ "-vga none -device virtio-gpu-pci" ];
};
enableOCR = true;
testScript = { nodes, ... }:
let
user = nodes.machine.users.users.alice;
in
''
machine.wait_for_unit("display-manager.service")
with subtest("Wait for Wayland server"):
machine.wait_for_file("/run/user/${toString user.uid}/wayland-1")
with subtest("Check if MATE session components actually start"):
for i in ["wayfire", "mate-panel", "mate-wayland.sh", "mate-wayland-components.sh"]:
machine.wait_until_succeeds(f"pgrep -f {i}")
machine.wait_for_text('(Applications|Places|System)')
# It is expected that this applet doesn't work in Wayland
machine.wait_for_text('WorkspaceSwitcherApplet')
with subtest("Check if various environment variables are set"):
cmd = "xargs --null --max-args=1 echo < /proc/$(pgrep -xf mate-panel)/environ"
machine.succeed(f"{cmd} | grep 'XDG_SESSION_TYPE' | grep 'wayland'")
machine.succeed(f"{cmd} | grep 'XDG_SESSION_DESKTOP' | grep 'MATE'")
machine.succeed(f"{cmd} | grep 'MATE_PANEL_APPLETS_DIR' | grep '${pkgs.mate.mate-panel-with-applets.pname}'")
with subtest("Check if Wayfire config is properly configured"):
for i in ["button_style = mate", "firedecor", "mate-wayland-components.sh"]:
machine.wait_until_succeeds(f"cat /home/${user.name}/.config/mate/wayfire.ini | grep '{i}'")
with subtest("Check if Wayfire has ever coredumped"):
machine.fail("coredumpctl --json=short | grep wayfire")
machine.sleep(10)
machine.screenshot("screen")
'';
})

View file

@ -54,6 +54,15 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: {
machine.wait_for_text('(Applications|Places|System)')
machine.wait_for_text('(Computer|Home|Trash)')
with subtest("Check if various environment variables are set"):
machine.succeed("xargs --null --max-args=1 echo < /proc/$(pgrep -xf marco)/environ | grep 'XDG_CURRENT_DESKTOP' | grep 'MATE'")
# From mate-panel-with-applets packaging
machine.succeed("xargs --null --max-args=1 echo < /proc/$(pgrep -xf mate-panel)/environ | grep 'MATE_PANEL_APPLETS_DIR' | grep '${pkgs.mate.mate-panel-with-applets.pname}'")
with subtest("Check if applets are built with in-process support"):
# This is needed for Wayland support
machine.fail("pgrep -fa clock-applet")
with subtest("Lock the screen"):
machine.wait_until_succeeds("su - ${user.name} -c '${env} mate-screensaver-command -q' | grep 'The screensaver is inactive'")
machine.succeed("su - ${user.name} -c '${env} mate-screensaver-command -l >&2 &'")

View file

@ -0,0 +1,47 @@
{
lib,
pkgs,
...
}:
{
name = "pretix";
meta.maintainers = with lib.maintainers; [ hexa ];
nodes = {
pretix = {
networking.extraHosts = ''
127.0.0.1 tickets.local
'';
services.pretix = {
enable = true;
nginx.domain = "tickets.local";
plugins = with pkgs.pretix.plugins; [
passbook
pages
];
settings = {
pretix = {
instance_name = "NixOS Test";
url = "http://tickets.local";
};
mail.from = "hello@tickets.local";
};
};
};
};
testScript = ''
start_all()
pretix.wait_for_unit("pretix-web.service")
pretix.wait_for_unit("pretix-worker.service")
pretix.wait_until_succeeds("curl -q --fail http://tickets.local")
pretix.succeed("pretix-manage --help")
pretix.log(pretix.succeed("systemd-analyze security pretix-web.service"))
'';
}