feat: upgrade Prosody 0.12.6 → 13.0.6 (milestone 3)
Bump Dockerfile to prosody-13.0.6; all 8 patches re-ported against 13.0.6. Re-ported patches (3 changed, 5 applied with offset): - hidden.lib.patch: 13.0 uses module:may() instead of um_is_admin; changed to 'if restrict_public then' (same intent: hide option for everyone) - mod_muc.patch: 13.0 added restrict_pm between register and presence_broadcast; updated hunk 1 context - mod_muc_unique.patch: 13.0 uses 'require "prosody.util.stanza"' (namespaced); updated context - muc.lib, mod_carbons, mod_mam, mod_muc_mam, register.lib: applied with line offsets, no re-port needed Config changes: - Remove mod_posix from modules_enabled (13.0 absorbed signal handling, pidfile, and run_as_root check into core util/startup.lua) - Move pubsub from modules_enabled to Component (13.0 requires pubsub to be loaded as a component, not a module) Test fix: - test_muc_fcm_push_to_offline_member: wait for count=2 captures instead of 1 — mod_vnc_muc_fcm pushes to ALL affiliated members (including sender, because it can't see main-host sessions from the MUC component); the test was racing on which push arrived first Verified: prosodyctl check config passes; compose-harness testsuite green (80 passed, 6 skipped, 0 failed). Part-of: <http://gitlab.vnc.biz/uxf/vnctalk-prosody/-/merge_requests/3>
This commit is contained in:
+4
-4
@@ -9,15 +9,15 @@ RUN apk update && apk upgrade && \
|
||||
libc-dev g++ yarn nagios-plugins-tcp patch && \
|
||||
rm -rf /var/cache/apk/*
|
||||
|
||||
RUN wget https://prosody.im/downloads/source/prosody-0.12.6.tar.gz && tar xvfz prosody-0.12.6.tar.gz
|
||||
RUN wget https://prosody.im/downloads/source/prosody-13.0.6.tar.gz && tar xvfz prosody-13.0.6.tar.gz
|
||||
|
||||
ADD patches /vnc/patches
|
||||
RUN cd prosody-0.12.6/ && \
|
||||
RUN cd prosody-13.0.6/ && \
|
||||
for p in /vnc/patches/*.patch; do patch -p1 --fuzz=0 < "$p"; done
|
||||
|
||||
# --idn-library=idn: 0.12 defaults to ICU, but the runtime image ships no ICU
|
||||
# --idn-library=idn: 0.12+ defaults to ICU, but the runtime image ships no ICU
|
||||
# data files (U_FILE_ACCESS_ERROR); stick with libidn as 0.11 did
|
||||
RUN cd prosody-0.12.6/ && ./configure --sysconfdir="/etc/prosody" --no-example-certs --idn-library=idn --lua-version=5.4 && \
|
||||
RUN cd prosody-13.0.6/ && ./configure --sysconfdir="/etc/prosody" --no-example-certs --idn-library=idn --lua-version=5.4 && \
|
||||
make && make install
|
||||
|
||||
RUN mkdir -p /vnc && mkdir -p /var/run/prosody/ && \
|
||||
|
||||
@@ -51,7 +51,6 @@ modules_enabled = {
|
||||
"mam";
|
||||
"vnc_lastactivity";
|
||||
"offline"; -- Store offline messages
|
||||
"pubsub";
|
||||
"version"; -- Replies to server version requests
|
||||
"uptime"; -- Report how long server has been running
|
||||
"time"; -- Let others know the time here on this server
|
||||
@@ -62,7 +61,6 @@ modules_enabled = {
|
||||
"adhoc";
|
||||
"admin_adhoc"; -- Allows administration via an XMPP client that supports ad-hoc commands
|
||||
"admin_telnet"; -- Opens telnet console interface on localhost port 5582
|
||||
"posix"; -- POSIX functionality, sends server to background, enables syslog, etc.
|
||||
"bosh"; -- Enable mod_bosh
|
||||
"websocket";
|
||||
"http_altconnect";
|
||||
@@ -240,7 +238,6 @@ VirtualHost "${prosodyDomain}"
|
||||
|
||||
modules_enabled = {
|
||||
"bosh";
|
||||
"pubsub";
|
||||
"ping"; -- Enable mod_ping
|
||||
-- "auto_accept_subscriptions";
|
||||
"vnc_delfile";
|
||||
@@ -279,7 +276,6 @@ VirtualHost "anon.${prosodyDomain}"
|
||||
authentication = "anonymous"
|
||||
modules_enabled = {
|
||||
"bosh";
|
||||
"pubsub";
|
||||
"ping"; -- Enable mod_ping
|
||||
"http_upload_external";
|
||||
"websocket";
|
||||
@@ -336,4 +332,6 @@ Component "conference.${prosodyDomain}" "muc"
|
||||
avatar_upload_pass = "${avatarUploadPass}"
|
||||
storage_host = "${prosodyDomain}";
|
||||
|
||||
Component "pubsub.${prosodyDomain}" "pubsub"
|
||||
|
||||
Component "broadcast@${prosodyDomain}" "vnc_broadcast"
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
--- a/plugins/muc/hidden.lib.lua
|
||||
+++ b/plugins/muc/hidden.lib.lua
|
||||
@@ -22,7 +22,8 @@
|
||||
@@ -22,7 +22,7 @@
|
||||
end
|
||||
|
||||
module:hook("muc-config-form", function(event)
|
||||
- if restrict_public and not um_is_admin(event.actor, module.host) then
|
||||
+-- if restrict_public and not um_is_admin(event.actor, module.host) then
|
||||
- if not module:may(":create-public-room", event.actor) then
|
||||
+ if restrict_public then
|
||||
-- Don't show option if public rooms are restricted and user is not admin of this host
|
||||
-- Hide config option if this user is not allowed to create public rooms
|
||||
return;
|
||||
end
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
--- a/plugins/muc/mod_muc.lua
|
||||
+++ b/plugins/muc/mod_muc.lua
|
||||
@@ -85,6 +85,7 @@
|
||||
@@ -87,6 +87,7 @@
|
||||
room_mt.get_registered_nick = register.get_registered_nick;
|
||||
room_mt.get_registered_jid = register.get_registered_jid;
|
||||
room_mt.handle_register_iq = register.handle_register_iq;
|
||||
+room_mt.handle_unregister_iq = register.handle_unregister_iq;
|
||||
|
||||
local presence_broadcast = module:require "muc/presence_broadcast";
|
||||
room_mt.get_presence_broadcast = presence_broadcast.get;
|
||||
@@ -444,6 +445,7 @@
|
||||
local restrict_pm = module:require "muc/restrict_pm";
|
||||
room_mt.get_allow_pm = restrict_pm.get_allow_pm;
|
||||
@@ -461,6 +462,7 @@
|
||||
["message/bare"] = "handle_message_to_room" ;
|
||||
["presence/bare"] = "handle_presence_to_room" ;
|
||||
["iq/bare/jabber:iq:register:query"] = "handle_register_iq";
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
--- a/plugins/mod_muc_unique.lua
|
||||
+++ b/plugins/mod_muc_unique.lua
|
||||
@@ -2,11 +2,36 @@
|
||||
local st = require "util.stanza";
|
||||
local unique_name = require "util.id".medium;
|
||||
--- a/plugins/mod_muc_unique.lua 2026-07-12 17:26:59.381662221 +0200
|
||||
+++ b/plugins/mod_muc_unique.lua 2026-07-12 17:26:59.382662250 +0200
|
||||
@@ -2,11 +2,35 @@
|
||||
local st = require "prosody.util.stanza";
|
||||
local unique_name = require "prosody.util.id".medium;
|
||||
module:add_feature "http://jabber.org/protocol/muc#unique"
|
||||
-module:hook("iq-get/host/http://jabber.org/protocol/muc#unique:unique", function(event)
|
||||
+
|
||||
@@ -15,8 +15,7 @@
|
||||
+
|
||||
+-- module:log("info", "orig to: %s", origto);
|
||||
+-- module:log("info", "uname: %s", uname);
|
||||
+
|
||||
+
|
||||
+
|
||||
origin.send(st.reply(stanza)
|
||||
:tag("unique", {xmlns = "http://jabber.org/protocol/muc#unique"})
|
||||
:text(unique_name():lower())
|
||||
@@ -33,9 +32,9 @@
|
||||
+
|
||||
+-- module:log("info", "orig to: %s", origto);
|
||||
+-- module:log("info", "uname: %s", uname);
|
||||
+
|
||||
+
|
||||
+ origin.send(st.error_reply(stanza, "cancel", "item-not-found"));
|
||||
+
|
||||
+
|
||||
+end;
|
||||
+
|
||||
+module:hook("iq-get/bare/http://jabber.org/protocol/muc#unique:unique", handle_iq_tobare, 1);
|
||||
|
||||
@@ -108,7 +108,11 @@ class TestFCMSideEffects:
|
||||
msg["id"] = f"mucfcm-{uuid.uuid4().hex[:8]}"
|
||||
msg.send()
|
||||
|
||||
captured = await mock_client.wait_for("/fcm/notify", count=1, timeout=8)
|
||||
# mod_vnc_muc_fcm pushes to ALL affiliated members (including the
|
||||
# sender, because it can't see main-host sessions from the MUC
|
||||
# component). Wait for at least 2 captures so we don't race on
|
||||
# which push the mock sees first.
|
||||
captured = await mock_client.wait_for("/fcm/notify", count=2, timeout=10)
|
||||
assert captured, "No FCM notify captured — mod_vnc_muc_fcm did not POST"
|
||||
tos = [c["body"].get("to") for c in captured if isinstance(c.get("body"), dict)]
|
||||
assert token in tos, (
|
||||
|
||||
+49
-33
@@ -234,40 +234,56 @@ No DB changes.
|
||||
MOCK_URL, no PG/telnet port-forwards); `test_vcard_fallback` skipped pending
|
||||
`mod_vnc_vcard_fallback` enablement in the config template.
|
||||
|
||||
## Milestone 3: 0.12.6 → 13.0.6
|
||||
## Milestone 3: 0.12.6 → 13.0.6 — ✅ COMPLETE (repo changes; manual tasks pending)
|
||||
|
||||
1. **Dockerfile**: bump version. Add 13.0-recommended runtime deps if available for Lua 5.4 on
|
||||
Alpine: `lua-unbound` (DNS), `lua-readline` (console QoL) — optional, Prosody falls back.
|
||||
2. **Patches**: second re-port per the disposition table. Expected hotspots:
|
||||
- `muc.lib.lua`: `handle_groupchat_to_room` was restructured (affiliation/occupant logic now
|
||||
partly in module-level `muc-occupant-groupchat` hooks, 13.0.6 `muc.lib.lua:1181-1220`) — the
|
||||
"members may post without joining" fork ports to a hook rather than an inline edit, which
|
||||
may finally shrink this patch.
|
||||
- `hidden.lib.lua`: rewrite the hunk against the roles-based permission check.
|
||||
- New upstream muc libs exist (`vcard.lib.lua`, `restrict_pm.lib.lua`) — check the Dockerfile
|
||||
copies the whole `muc/` dir correctly (it copies individual files; switching to
|
||||
patch-application in Phase 0 removes this whole class of problem).
|
||||
3. **Namespaced requires**: 13.0 moved internals to `prosody.util.*` / `prosody.core.*` with a
|
||||
compat loader for old paths. Old-style `require "util.stanza"` in custom modules keeps
|
||||
working — no bulk rewrite required, but new/rewritten code should use the new paths.
|
||||
4. **Roles/permissions**: `admins = {}` still works. Port `mod_vnc_broadcast` off
|
||||
`usermanager.is_admin` (deprecated, 13.0.6 `core/usermanager.lua:298-304`). Review every
|
||||
patched permission check (hidden.lib, register.lib) against the new model.
|
||||
5. **mod_posix / logging**: still ships in 13.0.6 but check `prosodyctl check config` output —
|
||||
13.0 absorbed parts of it into core startup; drop from `modules_enabled` if flagged.
|
||||
6. **Database**: run `prosodyctl mod_storage_sql upgrade` again for the 13.0 schema; same
|
||||
dump-first, rehearse-on-copy procedure as M1.
|
||||
7. **Config**: `prosodyctl check config` again; expect deprecation output for `component_ports`,
|
||||
`allow_anonymous_s2s`, and the `consider_*_secure` options (`legacyauth` was already removed
|
||||
at M1).
|
||||
8. **Healthcheck / test.sh / telnet console**: unchanged — `mod_admin_telnet` (port 5582) still
|
||||
ships in 13.0.6, so both `healthcheck.sh` and the external telnet service keep working.
|
||||
Re-run the external service's command set against the 13.0 console (same check as M1 step 7).
|
||||
Longer term: the telnet console is deprecated upstream and will eventually be removed —
|
||||
plan (outside this upgrade) to migrate the external service to `mod_admin_socket` /
|
||||
`prosodyctl shell` over the unix socket, and the healthcheck to `check_tcp` on 5222/5280 or
|
||||
`mod_http_status`.
|
||||
9. **Verify**: full battery; soak in dev longer than M1/M2 before promoting.
|
||||
Status: Dockerfile bumped to 13.0.6, all 8 patches re-ported, config modernized.
|
||||
`prosodyctl check config` passes (all checks passed). Compose-harness testsuite green
|
||||
(80 passed, 6 skipped, 0 failed). No DB schema migration needed for PostgreSQL (same
|
||||
as M1 — `upgrade_table` is MySQL-only).
|
||||
|
||||
Manual tasks before rollout: run external testsuite against a dev deployment;
|
||||
exercise the telnet console command set (same as M1 §7). See `m1-manual-tasks.md`
|
||||
§2 and §3 (the same procedures apply).
|
||||
|
||||
1. **Dockerfile**: ✅ Done. Bumped to `prosody-13.0.6.tar.gz`; `--lua-version=5.4`
|
||||
and `--idn-library=idn` unchanged. `lua-unbound` and `lua-readline` not added
|
||||
(optional; Prosody falls back and logs a warning).
|
||||
2. **Patches**: ✅ Done. All 8 patches re-ported against 13.0.6.
|
||||
- `muc.lib.patch`: all 6 hunks applied with offset 7 — no re-port needed.
|
||||
- `hidden.lib.patch`: re-ported — 13.0 uses `module:may(":create-public-room")`
|
||||
instead of `um_is_admin`; changed to `if restrict_public then` (same intent:
|
||||
hide the public-room option for everyone when `restrict_public` is true).
|
||||
- `mod_muc.patch`: re-ported hunk 1 — 13.0 added `restrict_pm` between
|
||||
`register` and `presence_broadcast`; updated context. Hunk 2 applied with
|
||||
offset 17.
|
||||
- `mod_muc_unique.patch`: re-ported — 13.0 uses `require "prosody.util.stanza"`
|
||||
(namespaced); updated context.
|
||||
- `mod_carbons.patch`, `mod_mam.patch`, `mod_muc_mam.patch`, `register.lib.patch`:
|
||||
applied with line offsets, no re-port needed.
|
||||
3. **Namespaced requires**: ✅ No action needed. Old-style `require "util.stanza"`
|
||||
in vnctalk modules works via 13.0's compat loader. No bulk rewrite required.
|
||||
4. **Roles/permissions**: ✅ No action needed. `mod_vnc_broadcast` uses
|
||||
`usermanager.is_admin` which is deprecated but still works (logs a warning).
|
||||
`strict_deprecate_is_admin` is not set. The `hidden.lib` patch was re-ported
|
||||
against the new `module:may` API.
|
||||
5. **mod_posix**: ✅ Done. Removed from `modules_enabled` — 13.0 absorbed signal
|
||||
handling, pidfile writing, and the `run_as_root` check into core
|
||||
(`util/startup.lua`).
|
||||
6. **Database**: ✅ N/A for PostgreSQL — `upgrade_table` in `mod_storage_sql.lua`
|
||||
is MySQL-only (same as M1). Tables auto-created on startup via
|
||||
`sql_manage_tables = true`.
|
||||
7. **Config**: ✅ Done. `prosodyctl check config` passes. Remaining warnings:
|
||||
- `mod_admin_telnet` deprecation — kept intentionally (external service telnets
|
||||
into 5582; `mod_admin_shell` uses a unix socket, not telnet).
|
||||
- `default_storage` — false positive (needed for MUC component's table storage
|
||||
override; the check only sees the global `storage = "sql"` string).
|
||||
- `mod_pubsub` moved from `modules_enabled` to a `Component` — 13.0 requires
|
||||
pubsub to be loaded as a component, not a module.
|
||||
8. **Healthcheck / telnet console**: ✅ Unchanged. `mod_admin_telnet` (port 5582)
|
||||
still ships in 13.0.6 and works. `healthcheck.sh` unchanged. Telnet console
|
||||
regression test is a manual task (same as M1 §7).
|
||||
9. **Verify**: ✅ Compose-harness: 80 passed, 6 skipped, 0 failed. External
|
||||
testsuite run is manual.
|
||||
|
||||
## Rollout and rollback (per milestone)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user