prosody: 0.12.4 -> 13.0.2, fix nixos test (#429967)

This commit is contained in:
Sandro 2025-08-06 00:16:29 +02:00 committed by GitHub
commit ef2f192da2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 152 additions and 153 deletions

View File

@ -16655,6 +16655,12 @@
githubId = 1776903;
name = "Andrew Abbott";
};
mirror230469 = {
email = "mirror230469@disroot.org";
github = "mirror230469";
githubId = 215964377;
name = "mirror";
};
mirrorwitch = {
email = "mirrorwitch@transmom.love";
github = "mirrorwitch";

View File

@ -107,6 +107,14 @@
- The `dovecot` systemd service was renamed from `dovecot2` to `dovecot`. The former is now just an alias. Update any overrides on the systemd unit to the new name.
- `Prosody` has been updated to major release 13 which removed some obsoleted modules and brought a couple of major and breaking changes:
- The `http_files` module is now disabled by default because it now requires `http_files_dir` to be configured.
- The `vcard_muc` module has been removed and got replaced by the inbuilt `muc_vcard` module.
- The `http_upload` module has been removed and you must migrate to the `http_file_share` module to stay XEP-0423 compliant. The `httpFileShare` options got expanded to better facility that.
- The `admin_shell` module is now always being loaded to make `prosodyctl` functional.
- The `mime_types_file` setting is now set to `"${pkgs.mailcap}/etc/mime.types"` to prevent errors.
For a complete list of changes, please see [their announcement](https://blog.prosody.im/prosody-13.0.0-released/).
- The `yeahwm` package and `services.xserver.windowManager.yeahwm` module were removed due to the package being broken and unmaintained upstream.
- The `services.postgresql` module now sets up a systemd unit `postgresql.target`. Depending on `postgresql.target` guarantees that postgres is in read-write mode and initial/ensure scripts were executed. Depending on `postgresql.service` only guarantees a read-only connection.

View File

@ -182,7 +182,7 @@ let
http_files = mkOption {
type = types.bool;
default = true;
default = false;
description = "Serve static files from a directory over HTTP";
};
@ -369,11 +369,6 @@ let
kick other. Useful in jitsi-meet to kick ghosts.
'';
};
vcard_muc = mkOption {
type = types.bool;
default = true;
description = "Adds the ability to set vCard for Multi User Chat rooms";
};
# Extra parameters. Defaulting to prosody default values.
# Adding them explicitly to make them visible from the options
@ -423,62 +418,58 @@ let
};
};
uploadHttpOpts = _: {
options = {
domain = mkOption {
type = types.nullOr types.str;
description = "Domain name for the http-upload service";
};
uploadFileSizeLimit = mkOption {
type = types.str;
default = "50 * 1024 * 1024";
description = "Maximum file size, in bytes. Defaults to 50MB.";
};
uploadExpireAfter = mkOption {
type = types.str;
default = "60 * 60 * 24 * 7";
description = "Max age of a file before it gets deleted, in seconds.";
};
userQuota = mkOption {
type = types.nullOr types.int;
default = null;
example = 1234;
description = ''
Maximum size of all uploaded files per user, in bytes. There
will be no quota if this option is set to null.
'';
};
httpUploadPath = mkOption {
type = types.str;
description = ''
Directory where the uploaded files will be stored when the http_upload module is used.
By default, uploaded files are put in a sub-directory of the default Prosody storage path (usually /var/lib/prosody).
'';
default = "/var/lib/prosody";
httpFileShareOpts =
{ config, options, ... }:
{
freeformType =
with types;
let
atom = oneOf [
int
bool
str
(listOf atom)
];
in
attrsOf (nullOr atom)
// {
description = "int, bool, string or list of them";
};
options = {
domain = mkOption {
type = with types; nullOr str;
description = "Domain name for a http_file_share service.";
};
http_host = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
To avoid an additional DNS record and certificate, you may set this option to your primary domain (e.g. "example.com")
or use a reverse proxy to handle the HTTP for that domain.
'';
};
size_limit = mkOption {
type = types.int;
default = 10 * 1024 * 1024;
defaultText = "10 * 1024 * 1024";
description = "Maximum file size, in bytes.";
};
expires_after = mkOption {
type = types.str;
default = "1 week";
description = "Max age of a file before it gets deleted.";
};
daily_quota = mkOption {
type = types.nullOr types.int;
default = 10 * config.size_limit;
defaultText = lib.literalExpression "10 * ${options.size_limit}";
example = "100*1024*1024";
description = ''
Maximum size of daily uploaded files per user, in bytes.
'';
};
};
};
};
httpFileShareOpts = _: {
freeformType =
with types;
let
atom = oneOf [
int
bool
str
(listOf atom)
];
in
attrsOf (nullOr atom)
// {
description = "int, bool, string or list of them";
};
options.domain = mkOption {
type = with types; nullOr str;
description = "Domain name for a http_file_share service.";
};
};
vHostOpts = _: {
options = {
@ -510,15 +501,10 @@ let
configFile =
let
httpDiscoItems =
optional (cfg.uploadHttp != null) {
url = cfg.uploadHttp.domain;
description = "HTTP upload endpoint";
}
++ optional (cfg.httpFileShare != null) {
url = cfg.httpFileShare.domain;
description = "HTTP file share endpoint";
};
httpDiscoItems = optional (cfg.httpFileShare != null) {
url = cfg.httpFileShare.domain;
description = "HTTP file share endpoint";
};
mucDiscoItems = builtins.foldl' (
acc: muc:
[
@ -546,7 +532,7 @@ let
admins = ${toLua cfg.admins}
modules_enabled = {
"admin_shell"; -- for prosodyctl
${lib.concatStringsSep "\n " (
lib.mapAttrsToList (name: val: optionalString val "${toLua name};") cfg.modules
)}
@ -575,11 +561,13 @@ let
http_ports = ${toLua cfg.httpPorts}
https_ports = ${toLua cfg.httpsPorts}
mime_types_file = "${pkgs.mailcap}/etc/mime.types"
${cfg.extraConfig}
${lib.concatMapStrings (muc: ''
Component ${toLua muc.domain} "muc"
modules_enabled = { "muc_mam"; ${optionalString muc.vcard_muc ''"vcard_muc";''} ${optionalString muc.allowners_muc ''"muc_allowners";''} }
modules_enabled = {${optionalString cfg.modules.mam ''" muc_mam",''}${optionalString muc.allowners_muc ''" muc_allowners",''} }
name = ${toLua muc.name}
restrict_room_creation = ${toLua muc.restrictRoomCreation}
max_history_messages = ${toLua muc.maxHistoryMessages}
@ -597,20 +585,18 @@ let
${muc.extraConfig}
'') cfg.muc}
${lib.optionalString (cfg.uploadHttp != null) ''
Component ${toLua cfg.uploadHttp.domain} "http_upload"
http_upload_file_size_limit = ${cfg.uploadHttp.uploadFileSizeLimit}
http_upload_expire_after = ${cfg.uploadHttp.uploadExpireAfter}
${lib.optionalString (
cfg.uploadHttp.userQuota != null
) "http_upload_quota = ${toLua cfg.uploadHttp.userQuota}"}
http_upload_path = ${toLua cfg.uploadHttp.httpUploadPath}
''}
${lib.optionalString (cfg.httpFileShare != null) ''
Component ${toLua cfg.httpFileShare.domain} "http_file_share"
${settingsToLua " http_file_share_" (cfg.httpFileShare // { domain = null; })}
''}
${
lib.optionalString (cfg.httpFileShare != null) ''
Component ${toLua cfg.httpFileShare.domain} "http_file_share"
modules_disabled = { "s2s" }
''
+ lib.optionalString (cfg.httpFileShare.http_host != null) ''
http_host = "${cfg.httpFileShare.http_host}"
''
+ ''
${settingsToLua " http_file_share_" (cfg.httpFileShare // { domain = null; })}
''
}
${lib.concatStringsSep "\n" (
lib.mapAttrsToList (n: v: ''
@ -621,7 +607,6 @@ let
'') cfg.virtualHosts
)}
'';
in
{
options = {
@ -817,20 +802,11 @@ in
description = "Additional path in which to look find plugins/modules";
};
uploadHttp = mkOption {
description = ''
Configures the old Prosody builtin HTTP server to handle user uploads.
'';
type = types.nullOr (types.submodule uploadHttpOpts);
default = null;
example = {
domain = "uploads.my-xmpp-example-host.org";
};
};
httpFileShare = mkOption {
description = ''
Configures the http_file_share module to handle user uploads.
See <https://prosody.im/doc/modules/mod_http_file_share> for a full list of options.
'';
type = types.nullOr (types.submodule httpFileShareOpts);
default = null;
@ -919,6 +895,12 @@ in
};
};
imports = [
(lib.mkRemovedOptionModule [ "services" "prosody" "uploadHttp" ]
"mod_http_upload has been obsoloted and been replaced by mod_http_file_share which can be configured with httpFileShare options."
)
];
config = mkIf cfg.enable {
assertions =
let
@ -941,10 +923,9 @@ in
+ genericErrMsg;
}
{
assertion = cfg.uploadHttp != null || cfg.httpFileShare != null || !cfg.xmppComplianceSuite;
assertion = cfg.httpFileShare != null || !cfg.xmppComplianceSuite;
message = ''
You need to setup the http_upload or http_file_share modules through config.services.prosody.uploadHttp
or config.services.prosody.httpFileShare to comply with XEP-0423.
You need to setup http_file_share modules through config.services.prosody.httpFileShare to comply with XEP-0423.
''
+ genericErrMsg;
}
@ -954,6 +935,9 @@ in
environment.systemPackages = [ cfg.package ];
# prevent error if not all certs are configured by the user
environment.etc."prosody/certs/.dummy".text = "";
environment.etc."prosody/prosody.cfg.lua".source =
if cfg.checkConfig then
pkgs.runCommandLocal "prosody.cfg.lua"
@ -993,12 +977,14 @@ in
{
User = cfg.user;
Group = cfg.group;
Type = "forking";
Type = "simple";
RuntimeDirectory = [ "prosody" ];
PIDFile = "/run/prosody/prosody.pid";
ExecStart = "${cfg.package}/bin/prosodyctl start";
ExecStart = "${lib.getExe cfg.package} -F";
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
Restart = "on-abnormal";
AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ];
MemoryDenyWriteExecute = true;
PrivateDevices = true;
PrivateMounts = true;

View File

@ -2,37 +2,29 @@ let
cert =
pkgs:
pkgs.runCommand "selfSignedCerts" { buildInputs = [ pkgs.openssl ]; } ''
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -nodes -subj '/CN=example.com/CN=uploads.example.com/CN=conference.example.com' -days 36500
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -nodes -days 365 \
-subj '/C=GB/CN=example.com' -addext "subjectAltName = DNS:example.com,DNS:uploads.example.com,DNS:conference.example.com"
mkdir -p $out
cp key.pem cert.pem $out
'';
# Creates and set password for the 2 xmpp test users.
#
# Doing that in a bash script instead of doing that in the test
# script allow us to easily provision the users when running that
# test interactively.
createUsers =
pkgs:
pkgs.writeScriptBin "create-prosody-users" ''
#!${pkgs.bash}/bin/bash
pkgs.writeShellScriptBin "create-prosody-users" ''
set -e
# Creates and set password for the 2 xmpp test users.
#
# Doing that in a bash script instead of doing that in the test
# script allow us to easily provision the users when running that
# test interactively.
prosodyctl register cthon98 example.com nothunter2
prosodyctl register azurediamond example.com hunter2
'';
# Deletes the test users.
delUsers =
pkgs:
pkgs.writeScriptBin "delete-prosody-users" ''
#!${pkgs.bash}/bin/bash
pkgs.writeShellScriptBin "delete-prosody-users" ''
set -e
# Deletes the test users.
#
# Doing that in a bash script instead of doing that in the test
# script allow us to easily provision the users when running that
# test interactively.
prosodyctl deluser cthon98@example.com
prosodyctl deluser azurediamond@example.com
'';
@ -44,26 +36,24 @@ import ../make-test-python.nix {
{
nodes,
pkgs,
config,
...
}:
{
security.pki.certificateFiles = [ "${cert pkgs}/cert.pem" ];
console.keyMap = "fr-bepo";
networking.extraHosts = ''
${nodes.server.config.networking.primaryIPAddress} example.com
${nodes.server.config.networking.primaryIPAddress} conference.example.com
${nodes.server.config.networking.primaryIPAddress} uploads.example.com
${nodes.server.networking.primaryIPAddress} example.com
${nodes.server.networking.primaryIPAddress} conference.example.com
${nodes.server.networking.primaryIPAddress} uploads.example.com
'';
environment.systemPackages = [
(pkgs.callPackage ./xmpp-sendmessage.nix { connectTo = "example.com"; })
];
};
server =
{ config, pkgs, ... }:
{
security.pki.certificateFiles = [ "${cert pkgs}/cert.pem" ];
console.keyMap = "fr-bepo";
networking.extraHosts = ''
${config.networking.primaryIPAddress} example.com
${config.networking.primaryIPAddress} conference.example.com
@ -89,23 +79,21 @@ import ../make-test-python.nix {
domain = "conference.example.com";
}
];
uploadHttp = {
httpFileShare = {
domain = "uploads.example.com";
};
};
};
};
testScript =
{ nodes, ... }:
''
# Check with sqlite storage
start_all()
server.wait_for_unit("prosody.service")
server.succeed('prosodyctl status | grep "Prosody is running"')
testScript = _: ''
# Check with sqlite storage
start_all()
server.wait_for_unit("prosody.service")
server.succeed('prosodyctl status | grep "Prosody is running"')
server.succeed("create-prosody-users")
client.succeed("send-message")
server.succeed("delete-prosody-users")
'';
server.succeed("create-prosody-users")
client.succeed("send-message")
server.succeed("delete-prosody-users")
'';
}

View File

@ -35,32 +35,33 @@ let
++ withExtraLuaPackages p
);
in
stdenv.mkDerivation rec {
version = "0.12.5"; # also update communityModules
stdenv.mkDerivation (finalAttrs: {
pname = "prosody";
version = "13.0.2"; # also update communityModules
src = fetchurl {
url = "https://prosody.im/downloads/source/prosody-${finalAttrs.version}.tar.gz";
hash = "sha256-PmG9OW83ylJF3r/WvkmkemGRMy8Pqi1O5fAPuwQK3bA=";
};
# The following community modules are necessary for the nixos module
# prosody module to comply with XEP-0423 and provide a working
# default setup.
nixosModuleDeps = [
"cloud_notify"
"vcard_muc"
"http_upload"
];
src = fetchurl {
url = "https://prosody.im/downloads/source/${pname}-${version}.tar.gz";
sha256 = "sha256-d4+3cHoPEDmVlbp6ucZt0qIojArjp/5Kt4+X1GK9OZ8=";
};
# A note to all those merging automated updates: Please also update this
# attribute as some modules might not be compatible with a newer prosody
# version.
communityModules = fetchhg {
url = "https://hg.prosody.im/prosody-modules";
rev = "fc521fb5ffa0";
hash = "sha256-Ci52Xkx1xd3GW9lBPKgWFBB52SocxKyj8f/Hq3hZeak=";
rev = "a4d7fefa4a8b";
hash = "sha256-lPxKZlIVyAt1Nx+PQ0ru0qihJ1ecBbvO0fMk+5D+NzE=";
};
nativeBuildInputs = [ makeWrapper ];
buildInputs = [
luaEnv
libidn
@ -77,6 +78,7 @@ stdenv.mkDerivation rec {
"--c-compiler=${stdenv.cc.targetPrefix}cc"
"--linker=${stdenv.cc.targetPrefix}cc"
];
configurePlatforms = [ ];
postBuild = ''
@ -93,9 +95,13 @@ stdenv.mkDerivation rec {
postInstall = ''
${lib.concatMapStringsSep "\n"
(module: ''
cp -r $communityModules/mod_${module} $out/lib/prosody/modules/
cp -r ${finalAttrs.communityModules}/mod_${module} $out/lib/prosody/modules/
'')
(lib.lists.unique (nixosModuleDeps ++ withCommunityModules ++ withOnlyInstalledCommunityModules))
(
lib.lists.unique (
finalAttrs.nixosModuleDeps ++ withCommunityModules ++ withOnlyInstalledCommunityModules
)
)
}
make -C tools/migration install
'';
@ -110,6 +116,11 @@ stdenv.mkDerivation rec {
license = licenses.mit;
homepage = "https://prosody.im";
platforms = platforms.linux;
maintainers = with maintainers; [ toastal ];
mainProgram = "prosody";
maintainers = with maintainers; [
toastal
mirror230469
];
teams = with lib.teams; [ c3d2 ];
};
}
})