commit 103f60a4ff6dd5ef07316c154b0ec5430c1c08a4 Author: Alex Carver [Acerock7] Date: Thu Oct 1 13:06:46 2026 +0000 Bug 41253: Add new permission to superlibrarian test Adds items_modification_by_age to the superlibrarian subtest in t/Koha/Auth/Permissions.t Signed-off-by: Pedro Amorim commit d1f8d5bbd2d221457787262b6724049294d1ec56 Author: Tomás Cohen Arazi Date: Wed Sep 30 11:41:21 2026 -0300 Bug 42719: (QA follow-up) Adjust tests This patch makes the tests reflect the design decision made on the bug report. The author for the original 'No CGISESSID then error' patch signed off on this so I'm confident this is the right thing to do. Signed-off-by: Tomás Cohen Arazi Signed-off-by: Pedro Amorim commit 9f50aa986275d559be3d69bf94d3fe075de36558 Author: Lucas Gass Date: Wed Sep 30 14:06:29 2026 +0000 Bug 42667: (follow-up) Fix POD coverage Signed-off-by: Pedro Amorim commit 541cbd84a5323be81f3047aa648ef8086e84b31c Author: Jonathan Druart Date: Tue Sep 22 13:50:51 2026 +0200 Bug 42685: Fix Cypress test AssertionError: Timed out retrying after 10000ms: Expected to find content: 'Requesting Agencies' within the element: but never did. Signed-off-by: Pedro Amorim commit 36606ea9d600ed16cda05c2ee03e76e824706dab Author: Jonathan Druart Date: Tue Aug 25 11:26:00 2026 +0200 Bug 41674: Fix review issues - remove unused import, fix POD synopsis, remove unused variable Signed-off-by: Pedro Amorim commit 8526f2ac3ba1860ad8f0c79c0925c2612be6e183 Author: Jonathan Druart Date: Fri Jun 19 13:59:18 2026 +0200 Bug 41674: Use LinkPref for CurbsidePickup Signed-off-by: Jonathan Druart Signed-off-by: Pedro Amorim commit a746db644c5b94d0fd064303928040f65ba8003a Author: Jonathan Druart Date: Fri Jun 19 13:56:44 2026 +0200 Bug 41674: Add a test Signed-off-by: Jonathan Druart Signed-off-by: Pedro Amorim commit e7aee90141a908ff6eff0b7063adbab0f062a226 Author: Owen Leonard Date: Wed Jan 21 10:15:13 2026 -0500 Bug 41674: (follow-up) Proof of concept: branches.pl This patch implements the new template plugin on Administration -> Libraries. - When viewed as a user with permission to manage system preferences, the system preference names under "Reply-To", "Return-Path", and "MARC organization code" should be linked to system preferences, and the link should take you to the correct preference search. - When viewed as a user without permission the system preference names should not be linked. Sponsored-by: Athens County Public Libraries Signed-off-by: David Nind Signed-off-by: Jonathan Druart Signed-off-by: Pedro Amorim commit 797c1b352ebef08cd4f99ac42842996bde56b731 Author: Owen Leonard Date: Wed Jan 21 09:19:08 2026 -0500 Bug 41674: Add template plugin for linking to system preferences based on user permission This patch adds a new template plugin, LinkPref, for displaying system preference names as links depending on the logged-in user's permission. Syntax: [% "SYSTEM_PREFERENCE_NAME" | html | $LinkPref %] For a user with 'CAN_user_parameters_manage_sysprefs' permission it outputs: SYSTEM_PREFERENCE_NAME For a user without permission it outputs: SYSTEM_PREFERENCE_NAME Sponsored-by: Athens County Public Libraries Signed-off-by: David Nind Signed-off-by: Jonathan Druart Signed-off-by: Pedro Amorim commit 106fabbf9a61cea7199eb62a984ab9cf4030c845 Author: Martin Renvoize Date: Tue Sep 29 15:21:00 2026 +0100 Bug 43669: Make t::lib::Selenium wait for the server to be ready This patch adds a wait_for_server_ready check to t::lib::Selenium, so Selenium-based tests poll the server until it responds successfully before driving it, instead of assuming it is already up. This guards against a race we saw on Jenkins CI: t/db_dependent/selenium/00-onboarding.t and t/db_dependent/selenium/01-installation.t both failed with 'no such element: //div[@class="alert alert-success"]' right after the DB connection check step, immediately after run_tests.pl's get_commands_to_reset_db() restarted Apache/Plack. That helper restarts services and moves straight to running the tests with no readiness wait, so the very first requests can hit workers that are still warming up. The test then fails on a missing page element even though there is no bug in the installer flow itself. A companion issue has been filed against koha-misc4dev to add a readiness wait to run_tests.pl itself: https://gitlab.com/koha-community/koha-misc4dev/-/work_items/108 Test plan: 1. Apply the patch 2. Run t/db_dependent/selenium/01-installation.t (or 00-onboarding.t) against a fresh empty database with KOHA_TESTING=1, as usual 3. Confirm it still passes normally 4. To exercise the new wait: drop/recreate the database, then run "sudo service apache2 restart" and "sudo service koha-common restart", then immediately run the selenium test with no delay. Confirm it either passes (server came up in time) or fails fast with a clear "Cannot wait more for the server to be ready" message rather than a confusing missing-element error deep in the install wizard Co-Authored-By: Claude Sonnet 5 Signed-off-by: Lucas Gass Signed-off-by: Pedro Amorim commit a86b7a063d21bf5a3b4537d4fd7219358befe1af Author: nela Date: Sat Sep 26 18:25:30 2026 +0100 Bug 43650: incremental EAN-13 barcodes produce unexpected sequence When incremental EAN-13 barcodes are selected for autoBarcode and new item records are created an unexpected sequence of barcode numbers is produced instead of a sequence where the barcode is incremented by 1 between each item. This patch fixes that by adding quote marks in the inline JS, thus treating the barcode as a string rather than an integer :+) Test plan: 1. have records imported from somewhere but with no items 2. autoBarcode set to incremental EAN-13 barcodes 3. create a number of new items 4. observe that the item barcodes don't follow the expected sequence 5. apply patch 6. delete item records 7. repeat step 3 8. observe that the item barcodes follow the expected sequence Signed-off-by: David Cook Signed-off-by: Pedro Amorim commit e1e08a7f5d0f199c16a732f54bd70620c1034bc7 Author: Martin Renvoize Date: Tue Sep 15 18:17:57 2026 +0100 Bug 40901: (QA follow-up) Keep daemon output in the traditional log files under systemd Under koha-sysv the daemon(1) wrapper captures each daemon's stdout and stderr to /var/log/koha/INSTANCE/NAME-output.log and NAME-error.log. The systemd units sent that output to the journal instead, so zebra-*.log, indexer-*.log, es-indexer-*.log, worker-*.log and sip-error.log silently stopped being written on migrated hosts, and log locations differed between the two init packages. Use StandardOutput=append: and StandardError=append: on those six units so the files are identical whichever package supervises the daemons. The shipped logrotate stanza uses copytruncate, which is safe with append-mode descriptors. The journal still records systemd's own messages about each unit, which is what matters when one fails to start, and README.Debian shows the drop-in for sites that prefer the journal. Plack and the Z39.50 responder already wrote their own files. The README, NEWS.Debian entry and koha-common(8) text that described the journal-only behaviour are updated accordingly. Co-Authored-By: Claude Fable 5.1 Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 0aa04d9ddc0d8bd9936be8f58cef90f9062463df Author: Martin Renvoize Date: Tue Sep 15 17:40:49 2026 +0100 Bug 40901: (QA follow-up) Document the two init packages, the new options and the logging change - koha-systemd.README.Debian was written for the first prototype: it named koha-worker-long@.service (now koha-worker-long_tasks@), said SIP needs the sip.enabled flag file (no longer read on systemd hosts), described coexisting with koha-common and a manual migration that the postinst now performs. Rewrite it to describe the actual units, how the koha-* helpers map onto them, where each configuration value is read from, how to relax the sandboxing with a drop-in, and the migration. - Logging is the one visible behavioural change and was undocumented: with koha-sysv the daemon(1) wrapper captured stdout/stderr to /var/log/koha/INSTANCE/NAME-output.log and NAME-error.log; with koha-systemd that output is in the journal, so zebra-*, indexer-*, es-indexer-*, worker-* and sip-error.log are no longer written, while everything Koha writes itself (Starman's plack.log/plack-error.log, the log4perl files, z3950.log, the Apache vhost logs) is unchanged. Spell that out in README.Debian, in a new koha-systemd NEWS.Debian entry shown by apt-listchanges on upgrade, and in a "Service management" section of the koha-common(8) man page. - Add --enable/--disable to the koha-zebra, koha-worker, koha-indexer and koha-es-indexer man pages. - z3950_responder.pl's synopsis listed --config-dir twice and had lost -c, which is still a YAZ pass-through option; put -c back. - t/00-valid-systemd-units.t: give it the usual shebang, and ignore every "Command ... is not executable" line from systemd-analyze rather than only the ones for scripts in this repository. Whether starman or /usr/share/koha/bin/... is installed on the host running the test says nothing about the unit files, and the old filter made the test fail on any development machine without the Koha packages. Co-Authored-By: Claude Fable 5.1 Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit ffe8b55b57ce4a5a0bfbb6db5c9a3151438acd67 Author: Martin Renvoize Date: Tue Sep 15 17:38:29 2026 +0100 Bug 40901: (QA follow-up) Make koha-disable/koha-enable symmetric and fix koha-remove/koha-create koha-disable had gained "koha-sip --disable" and an unconditional "koha-plack --disable". On both backends those are not just systemd bookkeeping: on SysV the former deletes the sip.enabled flag and the latter comments the Plack includes out of the Apache vhost (which koha-disable then restarts Apache to apply). koha-enable was unchanged, so "koha-disable x && koha-enable x" left the instance on CGI with SIP off. Go back to stopping the daemons only (the new Plack and ES indexer stops are kept), and under systemd stop and disable the per-instance koha@.target so the instance stays down across reboots while the individual units keep their enablement. koha-enable re-enables and starts that target, so an enabled instance comes back exactly as it was. koha-remove nested every --disable inside "if is_*_running", so a unit that was enabled but stopped kept its symlink in koha@.target.wants/ after the instance was gone, which is the very thing the block below it says it prevents. Disable unconditionally. koha-create aborted after the database and vhost existed if a systemd-only --enable failed, because the helpers run under set -e; guard them like the systemctl calls already were. It also only started koha.target, which is a no-op when the target is already active, so the new instance's units were not started; start koha@.target itself. Co-Authored-By: Claude Fable 5.1 Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 0bdb94bfbb204b95d75d759a5104fdd507d889c4 Author: Martin Renvoize Date: Tue Sep 15 17:38:29 2026 +0100 Bug 40901: (QA follow-up) Harden the service abstraction in koha-functions.sh - koha_init_backend relied on "systemctl list-unit-files" exiting non-zero when nothing matches. That behaviour is version dependent, and on a systemd host running koha-sysv a false positive would send every koha-* helper to units that do not exist. Test for the koha-plack@.service unit file instead: unambiguous, and no systemctl fork per call. The _KOHA_INIT_BACKEND cache is dropped; every caller ran the function in a $(...) subshell so it never took effect anyway. - The _sysv_worker and _sysv_z3950 code moved here from bash-only scripts brought "((error_count++))" and "[[ ! $VAR ]]" into a #!/bin/sh library that koha-disable, koha-enable, koha-remove, koha-list and the init script source under dash. Use POSIX equivalents. - _sysv_restart_zebra and _sysv_restart_sip lost the explicit "return 0" of the original quiet not-running branch, so a start failure now aborted the caller's whole instance loop under set -e (including the init script's restart across all instances). Restore it. - systemctl status is run with --no-pager from koha_service_ctl and koha-systemd-ctl so the helpers never block on a pager. - koha-plack --enable/--disable ran systemctl before editing the Apache configuration, so a systemctl failure under set -e left the vhost untouched. Do the systemd half after the Apache edits and warn instead of aborting. Co-Authored-By: Claude Fable 5.1 Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 606fc6bcd6a589738a3c584e98fb410f56cdbde9 Author: Martin Renvoize Date: Tue Sep 15 17:35:25 2026 +0100 Bug 40901: (QA follow-up) Fix the koha-systemd migration, upgrade and removal paths First install (migration from the SysV layout): - The postinst ran daemon-reload before stopping koha-common.service, so the name already resolved to the new native unit and the stop was a no-op; the daemon(1)-supervised starman/zebrasrv/workers survived and kept plack.sock and the Zebra sockets. The init script itself is gone by then (koha-common's rm_conffile) and the koha-* helpers already dispatch to systemd, so neither can be used either. Kill the legacy koha-common.service cgroup (the generated unit has KillMode=process, a plain stop leaves the supervisors alive), sweep remaining pid files, and wait for them to exit, all before daemon-reload. - Nothing ever started the new units, and koha-common.service was never enabled, so a migrated host came back with every instance stopped and "systemctl restart koha-common" doing nothing. Enable both koha.target and koha-common.service and start them through deb-systemd-invoke. - koha-plack@ was enabled for every instance including CGI-only ones, and koha-indexer@ regardless of USE_INDEXER_DAEMON. Use "koha-list --enabled --plack" and /etc/default/koha-common like the init script did. - Drop the "systemctl disable koha-common.service" that targeted our own compat unit. Upgrade: deb-systemd-invoke takes unit names, not glob patterns, so enumerate the active koha-*@*.service units before try-restarting them. Removal: the prerm only did a daemon-reload, leaving every daemon running with its unit file deleted, so swapping to koha-sysv started a second copy of each. Stop koha-common.service and koha.target on remove; a new postrm removes the enablement symlinks on purge and reloads the manager. Co-Authored-By: Claude Fable 5.1 Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 1a81cf9bc7d555a0c8061997b3898b5ab81bdd35 Author: Martin Renvoize Date: Tue Sep 15 17:34:02 2026 +0100 Bug 40901: (QA follow-up) Polish the per-component units - Order services Before= their instance target instead of After=. With After=, koha@.target (and therefore koha.target) reported active before a single daemon had started, so its state meant nothing to anything ordered after Koha. koha@.target is likewise Before=koha.target. - Add SyslogIdentifier=%i-koha- to every unit so journal lines can be filtered per instance and component (the template this series removed already did this) and Documentation= pointing at each helper's man page. - koha-plack@: stop with SIGQUIT and a 30s timeout. Starman treats QUIT as graceful shutdown and TERM as immediate; the SysV path used QUIT/30/KILL/5, so the default SIGTERM cut in-flight requests on every restart. Drop the redundant --user/--group starman flags, User=/Group= already apply. - koha-worker@, koha-worker-long_tasks@: KillMode=mixed with a 120s timeout so the parent is signalled but a running forked job gets a chance to finish before it is killed. - koha-zebra@: remove every *socket file in the run directory rather than the two default names, so sites with customised entries get the same stale-socket protection. Co-Authored-By: Claude Fable 5.1 Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 5562b26bb023b4f37dbef806cc34038ebcb65bef Author: Martin Renvoize Date: Tue Sep 15 17:32:52 2026 +0100 Bug 40901: (QA follow-up) Fix Z39.50 option expansion and honour the indexer defaults Two problems in how the units consume koha-generate-env's output: 1. koha-z3950@.service passed ${Z3950_ADDITIONAL_OPTS}. In systemd unit files "${VAR}" always expands to exactly one argument, and to a single empty argument when the variable is empty; only unbraced "$VAR" is word-split. So a configured value like "--add-item-status k -t 5" reached z3950_responder.pl as one unknown option, and the default empty value reached it as a "" listener address. Verified with systemd-run: ${X}="--a --b" gives ["--a --b"], ${Y}="" gives [""], $X gives ["--a"] ["--b"]. Use the unbraced form. 2. koha-indexer@.service hardcoded rebuild_zebra.pl -daemon -sleep, ignoring ALTERNATE_INDEXER_DAEMON and INDEXER_PARAMS from /etc/default/koha-common that the SysV path honours. koha-generate-env now resolves INDEXER_DAEMON and INDEXER_PARAMS exactly like koha-indexer and the unit runs them through /usr/bin/env, so any configured indexer works. koha-generate-env is also tightened up: numeric values are validated and fall back to their defaults, every value is forced onto one line without quote characters so the EnvironmentFile always parses, the debug_mode test matches is_debug_mode, Z3950_ADDITIONAL_OPTS is read from /etc/default/koha-common first (as before this patchset), the Z39.50 config dir uses the same config.xml test as is_z3950_enabled, the env dir is created with the instance's ownership if it does not exist yet, and unknown services get an empty env file instead of a chmod failure. The responder is invoked through /usr/bin/perl like the other Perl daemons. Co-Authored-By: Claude Fable 5.1 Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 3fb9421561bcc03cf99a13e2a266de2b8ac383f5 Author: Martin Renvoize Date: Tue Sep 15 17:32:34 2026 +0100 Bug 40901: (QA follow-up) Make koha-common.service a dependency-free shim The compat unit declared BindsTo=koha.target and After=koha.target while its ExecStop ran "systemctl stop koha.target". After= orders this unit's stop before the target's, so the ExecStop waited on a job that could not run until the ExecStop itself finished. Every "systemctl stop koha-common" and every "systemctl restart koha-common" hung for TimeoutStopSec (90s by default) and left the unit in failed state. An async --no-block stop does not help either: the queued target stop replaces the start job the restart transaction needs, and everything ends up stopped. Drop the dependencies. The unit is now a plain oneshot with RemainAfterExit that starts koha.target in ExecStart and stops it in ExecStop, which is all the old "service koha-common" UX requires. Verified with a replica set of user units: start, stop and restart of the shim each complete in well under a second, restart gives every service a new PID, and managing koha.target directly is unaffected. The one cosmetic consequence is that the shim stays "active (exited)" if koha.target is stopped behind its back; README.Debian says to look at koha.target for real status. Also sets SyslogIdentifier so its journal lines are identifiable. Co-Authored-By: Claude Fable 5.1 Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 529df17b4291ea99a91aae34b4e8ff0cc98311ae Author: Martin Renvoize Date: Tue Sep 15 17:30:32 2026 +0100 Bug 40901: (QA follow-up) Install units to /lib/systemd/system and tidy control The old koha-common package shipped /lib/systemd/system/koha-common.service while koha-systemd installs to /usr/lib/systemd/system. On a merged-/usr Debian 12 host these are the same file through the /lib symlink, but dpkg compares path strings, so Replaces does not apply and removing the old package's copy can delete the file koha-systemd just unpacked (the DEP-17 aliasing problem). Keep the units under lib/systemd/system, the path the previous package used, so this is an ordinary takeover. While here: - koha-core gains Recommends: koha-systemd | koha-sysv. Installing it alone previously gave helpers that fell back to the daemon(1) wrapper that no longer gets installed. - drop a stray comment from the Source stanza of control.in - stop appending Perl dependencies to koha-common.substvars: the metapackage no longer uses ${koha:Depends} Co-Authored-By: Claude Fable 5.1 Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 2992ea058b32aec096d4159a186dbd44dc1bad0c Author: Martin Renvoize Date: Tue Sep 15 17:30:20 2026 +0100 Bug 40901: (QA follow-up) Migrate debconf answers from koha-common to koha-core The debconf questions moved from the koha-common/* to the koha-core/* namespace, but nothing carried the existing answers across, so a site that had opted out of automatic translation updates was asked again and defaulted back to "yes". koha-core.config now seeds the new question, including its "seen" flag, from the old one when it exists. debian/koha-common.templates was left behind after koha-common.config was deleted; the metapackage registered three questions that no config script ever asks, so remove it. Co-Authored-By: Claude Fable 5.1 Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 67d9b903d66c929e2f04be8a22610ecab20504bf Author: Martin Renvoize Date: Tue Sep 15 17:30:13 2026 +0100 Bug 40901: (QA follow-up) Restore the RabbitMQ and memcached steps in koha-common.postinst The monolithic koha-common.postinst ended by enabling the rabbitmq_stomp plugin, restarting RabbitMQ and restarting memcached (Bug 35242). None of that survived the split: koha-core.postinst never had it and the new koha-common.postinst was an empty stub. A fresh "apt install koha-common" therefore left the STOMP plugin disabled, and upgrades stopped flushing memcached, which is exactly the stale-cache class of bug 35242 fixed. koha-common is the package that depends on rabbitmq-server and memcached, so the steps belong in its postinst. The copy in koha-full.postinst is dropped now that koha-full depends on koha-common. Co-Authored-By: Claude Fable 5.1 Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 9485938333efb0e19ae8654d4654b4f92b30be0a Author: Martin Renvoize Date: Tue Sep 15 17:29:28 2026 +0100 Bug 40901: (QA follow-up) Keep /etc conffiles under their koha-common names The cron, logrotate and defaults files were renamed from koha-common.* to koha-core.*, so debhelper installed them as /etc/cron.d/koha-core, /etc/logrotate.d/koha-core and /etc/default/koha-core. dpkg never deletes a conffile that a package stops shipping, so after an upgrade both the old and the new files exist side by side: - every cron job (process_message_queue.pl every 15 minutes, overdue_notices.pl, fines.pl, backups...) runs twice - logrotate complains about duplicate log entries every night - the admin's /etc/default/koha-common (USE_INDEXER_DAEMON, INDEXER_PARAMS, ES_* tuning) is replaced by a symlink to a fresh copy of the packaged defaults, silently losing every customisation Keep the on-disk names instead: koha-core now ships the files as debian/koha-core.koha-common.* and debian/rules passes --name=koha-common to dh_installinit, dh_installcron and dh_installlogrotate. Because koha-core Replaces the old koha-common, dpkg hands each conffile over with the admin's content intact and no duplicates are left behind. The defaults file content is byte-identical to the old koha-common.default so nobody gets a spurious conffile prompt, and koha-generate-env reads the single canonical name again. The experimental pre-split koha-core (used by koha-full) had its own /etc/default/koha-core and /etc/init.d/koha-core; a new koha-core.maintscript migrates the former with mv_conffile and removes the latter, with the matching rc.d links dropped in the postinst. /etc/koha/koha-worker@.service, whose template was deleted, is removed from upgrading systems too. koha-core.preinst gains the #DEBHELPER# token the maintscript machinery needs. Co-Authored-By: Claude Fable 5.1 Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 760641c550836f22fa7d2d334eb4a8013579540b Author: Martin Renvoize Date: Tue Sep 15 17:28:42 2026 +0100 Bug 40901: (QA follow-up) Install the SysV init script through dh_installinit debhelper treats debian/.init as that package's init script, so koha-sysv would have shipped /etc/init.d/koha-sysv (with generated update-rc.d and invoke-rc.d handling) as well as the .install-copied /etc/init.d/koha-common (with none). That meant two identical init scripts, two generated units on systemd hosts, and on a fresh non-systemd install the "update-rc.d koha-common disable" call in the postinst aborting with "no runlevel symlinks to modify" because nothing had ever created them. Rename the script to debian/koha-sysv.koha-common.init and run dh_installinit --name=koha-common for koha-sysv. debhelper now installs it as /etc/init.d/koha-common, registers the rc.d links, starts it on install, restarts it on upgrade, stops it on removal and removes the links on purge, which is exactly what the old koha-common package did. The hand-written prerm/postrm and the Bug 18250 disable/enable dance (a one-off link reshuffle from 2017 that is a no-op under dependency-based boot) are dropped in favour of the generated code. Co-Authored-By: Claude Fable 5.1 Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit b8b064bf404fbd10c4a84d1d861232005590bd63 Author: Martin Renvoize Date: Tue Sep 15 17:27:57 2026 +0100 Bug 40901: (QA follow-up) Fix Replaces/Breaks version bound for the package split The split lands in the 26.06 development cycle (Koha.pm is at 26.06.00.xxx), but the Replaces/Breaks on the old monolithic koha-common were written as (<< 25.11). Released 25.11.x and 26.05.x koha-common packages therefore don't match, and upgrading from them aborts with dpkg's "trying to overwrite '/usr/sbin/koha-list', which is also in package koha-common". Use (<< 26.06~) everywhere, including the rm_conffile version in koha-common.maintscript, so every pre-split release is covered. Co-Authored-By: Claude Fable 5.1 Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 699a7a3c0cb8c1979af1bb5857706ad41e4ec619 Author: Kyle M Hall Date: Fri Jul 24 12:12:04 2026 -0400 Bug 40901: (QA follow-up) Use /run instead of legacy /var/run in unit files systemd 257 warns that these units point PIDFile at the legacy /var/run directory. This patch updates the remaining /var/run/koha paths to /run/koha to match the EnvironmentFile lines; /var/run is a symlink to /run on Debian, so nothing changes at runtime. Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 29e31a22573f867966bd7c2d8f441e9007f88a0a Author: Kyle M Hall Date: Fri Jul 24 12:12:04 2026 -0400 Bug 40901: (QA follow-up) Make the systemd unit validation test run in KTD The test failed in KTD instead of skipping, and the systemd-analyze option it relied on doesn't exist in any systemd QA will meet, so the unit files were never actually checked anywhere. Load Test::NoWarnings after the plan, use the SYSTEMD_UNIT_PATH environment variable instead, and ignore noise from helper scripts the packages haven't installed yet. Test Plan: 1) Apply this patch 2) prove t/00-valid-systemd-units.t 3) Note all units are now verified instead of the file failing! Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 7169ea9e2d749ecbc7e63f78d4180df9b0951e9a Author: Kyle M Hall Date: Fri Jul 24 12:12:04 2026 -0400 Bug 40901: (QA follow-up) Move ES indexer re-discovery into koha-systemd-ctl koha-common.service had an unexplained one-line shell loop in ExecStartPre. It's now a documented sync-es-indexers command in koha-systemd-ctl that does the same thing: notice instances that switched to Elasticsearch and start their indexers, like the SysV init script did on every start. https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=40901#c132 Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit a46f1aa4ca27f0765338f610d5ced782aa2b1282 Author: Kyle M Hall Date: Fri Jul 24 12:12:04 2026 -0400 Bug 40901: (QA follow-up) Don't stop all Koha services on every koha-systemd upgrade The postinst stopped and disabled koha-common.service on every configure, which after migration means every upgrade of this package shuts down every Koha instance. Now it only happens on first install, where it exists to stop the old SysV-started services. The hand-rolled deletion of the old init script is replaced with dpkg's standard rm_conffile mechanism. https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=40901#c130 Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 67ec61a60fe489c3d66af6b4d0db31e08ca9fb3f Author: Kyle M Hall Date: Fri Jul 24 12:12:04 2026 -0400 Bug 40901: (QA follow-up) Add Replaces/Breaks on old koha-common to koha-systemd The old koha-common package shipped the same koha-common.service file that koha-systemd now ships. Declaring Replaces/Breaks lets upgrades hand the file over cleanly, matching what koha-sysv and koha-core already declare. https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=40901#c129 Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit de946eac7fa4279bb6a3614997c9164e9af28863 Author: Kyle M Hall Date: Fri Jul 24 12:12:04 2026 -0400 Bug 40901: (QA follow-up) Remove redundant unit files ( koha-sysv.service, koha-worker@.service ) Nothing ever used either of these files. On systemd hosts koha-sysv already gets a generated koha-common.service, so shipping its own unit meant two units driving the same init script. The koha-worker@.service sample in /etc/koha was a copy-by-hand template that koha-systemd's real worker unit replaces. https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=40901#c129 Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 653d6092b5bf2920a6056546fbe07c3e7be9d0ab Author: Kyle M Hall Date: Fri Jul 24 12:12:04 2026 -0400 Bug 40901: (QA follow-up) Make koha-full depend on koha-common so it gets an init system After the package split, installing koha-full got you Koha with no way to start its services. Depending on koha-common brings in an init system and the other services, leaving only the database server to add. https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=40901#c128 Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 71f9a686795303efb8cf08b3a12d544dd4e04a50 Author: Martin Renvoize Date: Fri May 22 10:46:10 2026 +0100 Bug 40901: (QA follow-up) Fix systemd unit test for Test::NoWarnings and older systemd Add Test::NoWarnings and probe for --unit-path support, skipping on systemd versions that don't recognise the flag (e.g. KTD's Debian image). Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 445b955b787807ff7aaa26533bd929b02bfcd82d Author: Martin Renvoize Date: Fri May 22 09:23:02 2026 +0100 Bug 40901: (QA follow-up) Fix koha-disable --disable idempotency under set -e koha-plack, koha-zebra, koha-indexer and koha-es-indexer all return exit code 1 when asked to disable a service that is already disabled. koha-disable has set -e, so this propagated as a fatal error when koha-create called koha-disable on a freshly-created instance (where none of the per-service configs are enabled yet). Apply the same || true guard that koha-worker already had to the four unconditional --disable calls. The desired postcondition (service disabled) is achieved either way; the exit code from the sub-script is not meaningful here. Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 6b54ee976b2703ee1e15b24414a6b62c7c21b90c Author: Martin Renvoize Date: Fri May 22 07:53:54 2026 +0100 Bug 40901: Add systemd unit file validation test Adds t/00-valid-systemd-units.t which runs systemd-analyze verify against every unit file in debian/systemd/. Skips gracefully if systemd-analyze is not installed (requires the systemd package). To enable this test in KTD-based CI, add 'systemd' to the KTD container's package list. systemd-analyze verify does not require systemd to be running as PID 1 — it is pure static analysis and works correctly in a standard Docker container. Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 3eb65c1041a3dcef3b7aaf53d3670c55d1a1e1f1 Author: Martin Renvoize Date: Fri May 22 07:29:55 2026 +0100 Bug 40901: (QA follow-up) Drop redundant ExecStart systemctl call in koha-common.service koha-common.service already declares BindsTo=koha.target and After=koha.target. BindsTo= implies Requires=, so systemd will start koha.target automatically when this compat unit starts and will wait for it to be active before proceeding. The explicit ExecStart=/bin/systemctl start koha.target was therefore redundant, and calling systemctl from within a service body is an anti-pattern (it makes an extra D-Bus round-trip back to PID 1 and can deadlock in edge cases during early boot). Replace with /bin/true so the oneshot succeeds immediately after the ExecStartPre ES-indexer discovery step. ExecStop is kept as-is because there is no declarative equivalent for "stopping this unit should stop koha.target" — BindsTo= only propagates stops in the other direction. Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 868947cb55448eefd7e3898fdde3083f4efbbd5b Author: Martin Renvoize Date: Fri May 22 07:26:12 2026 +0100 Bug 40901: (QA follow-up) Quote path/option values in koha-generate-env env files systemd EnvironmentFile parsing treats unquoted values as ending at the first whitespace. PLACK_PSGIFILE and Z3950_CONFIGDIR are paths that could in principle contain spaces; Z3950_ADDITIONAL_OPTS routinely holds multiple flags separated by spaces (e.g. "--port 9999 --verbose"). Wrap these three values in double-quotes in the generated env file so systemd reads the full value even when it contains spaces. Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 6d3b026d916e0ccd6d12c1a446f49ba6e0fef74d Author: Martin Renvoize Date: Thu May 21 17:50:42 2026 +0100 Bug 40901: (QA follow-up) Fix koha-sysv.postinst configure guard and double-enable Two problems in the original koha-sysv.postinst: 1. #DEBHELPER# was placed at the top (line 5) before any case statement, so whatever dh_installsystemd expands it to ran for ALL postinst invocations (abort-upgrade, abort-remove, triggered…), not just configure. 2. The custom block manually called `deb-systemd-helper enable koha-common.service` on systemd hosts. Because koha-sysv also ships koha-sysv.service (which dh_installsystemd enables via #DEBHELPER#), both koha-sysv.service and the sysv-generator-created koha-common.service could end up enabled, resulting in a double-start of the init script at boot. Fix both by wrapping the custom code in `case "$1" in configure)`, moving manual enable: dh_installsystemd already enables and starts koha-sysv.service correctly. Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 53ebfcb8c52f06c3bda13ee5912290a3374b521b Author: Martin Renvoize Date: Thu May 21 17:48:33 2026 +0100 Bug 40901: (QA follow-up) koha-disable must disable units even when stopped On systemd, koha-disable gated both --stop and --disable behind is_*_running checks (systemctl is-active). A service that was enabled but not currently active (e.g. stopped for maintenance) was therefore never disabled, leaving its unit enabled and able to restart on the next boot — so the instance was never truly disabled. Separate the concerns: keep the is_*_running guard around --stop (so we don't try to stop an already-stopped service), but call --disable unconditionally for plack, zebra, indexer, and es-indexer. The disable call is idempotent on both systemd and SysV, so calling it on an already- disabled unit is safe. SIP was already handled correctly (using is_sip_enabled). Worker units already used || true so were unaffected. Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 3644a8407f67d33860fee2d163fbd58af6c93642 Author: Martin Renvoize Date: Thu May 21 17:44:18 2026 +0100 Bug 40901: (QA follow-up) Fix stale /etc/default/koha-common reference in koha-generate-env koha-generate-env sourced /etc/default/koha-common to read INDEXER_TIMEOUT, but the defaults file was renamed to /etc/default/koha-core in this patchset. On fresh installations no /etc/default/koha-common exists, so INDEXER_TIMEOUT was always silently fixed at the built-in default of 5, ignoring any admin customisation. Read /etc/default/koha-core first; fall back to /etc/default/koha-common so that systems upgrading from the pre-split packaging still pick up their existing settings. Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit b5000b88696306bb8a92615c883316b84f7ef43e Author: Kyle M Hall Date: Tue May 12 13:08:49 2026 -0400 Bug 40901: (follow-up) Systemd hardening I think the following systemd security measures are safe for Koha: ProtectSystem=full Sets /usr & /boot to read-only ProtectHome=yes Hides /home, /root and /run/user NOTE: The hiding of /run/user through me off, but google says it's only for interactive logins only. AFAIK the only thing that does that is koha-shell which isn't a systemd thing so it is unaffected PrivateTmp=yes Private /tmp & /var/tmp NOTE: AFACT nothing in Koha shares files via /tmp which feels like it would be a bad thing to do anyway NoNewPrivileges=yes setuid binaries can't re-elevate NOTE: This feels like the most important one! Signed-off-by: Kyle M Hall Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 05228589edde87e4e98a06d9c87b174833b164b6 Author: Kyle M Hall Date: Tue May 12 13:06:10 2026 -0400 Bug 40901: (follow-up) Drop redundant StopWhenUnneeded on koha@.target PartOf=koha.target already cascades stop to the per-instance target so StopWhenUnneeded is not needed and adds more complication that could trip us up later. Signed-off-by: Kyle M Hall Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 88926c50328da232e501367326aa8d28b053a868 Author: Kyle M Hall Date: Tue May 12 13:05:47 2026 -0400 Bug 40901: (follow-up) Tighten RestartSec on SIP, Z3950, es-indexer 30 seconds between restart attempts is a very long time especially for AIP. With StartLimitIntervalSec at 60, and RestartSec at 5 we get 6 retries and what is hopefully a less visible downtime window for the tcp services. For es-indexer it's not so big a deal but could be an issue for cataloguers. Signed-off-by: Kyle M Hall Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit a84dbc3d29bcbc6b31b0938de990697c7e4a6d21 Author: Kyle M Hall Date: Tue May 12 11:51:18 2026 -0400 Bug 40901: (follow-up) Order per-component units after koha-create-dirs Pair each Requires=koha-create-dirs@%i.service with a matching After=, and drop the now redundant Before= list from koha-create-dirs@.service. Signed-off-by: Kyle M Hall Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit a6226588f61fecad728e031dc952e982c5355c4e Author: Kyle M Hall Date: Tue May 12 11:49:57 2026 -0400 Bug 40901: (follow-up) Cap restart attempts on per-component units Add StartLimitIntervalSec=60 add StartLimitBurst=3 so a broken-at- startup daemon stops looping at after three attempts. Signed-off-by: Kyle M Hall Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 0f2f88371d3e20db53f06f212386742fb0f82c5d Author: Kyle M Hall Date: Tue May 12 11:44:54 2026 -0400 Bug 40901: (follow-up) Re-discover ES indexers on koha-common start The SysV init script runs `koha-list --enabled --elasticsearch` at every start. ExecStartPre on koha-common.service restores that. Signed-off-by: Kyle M Hall Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 1425743c10eef1cf6a2553293f099f409c3c0ffb Author: Kyle M Hall Date: Tue May 12 11:27:41 2026 -0400 Bug 40901: (follow-up) koha-remove leaves koha@.target enabled Disable koha@.target and koha-create-dirs@.service so their koha.target.wants/ symlinks don't outlive the instance. Signed-off-by: Kyle M Hall Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit d0d193ea7ed21736a0432eda5111ef0d98c30576 Author: Kyle M Hall Date: Fri May 8 12:45:41 2026 -0400 Bug 40901: (follow-up) Clean up stale Zebra Unix sockets on startup zebrasrv removes its Unix sockets on clean exit but leaves them behind on SIGKILL, OOM, or sysv to systemd swap, causing 'Address already in use' on the next start. ExecStartPre rm makes the unit auto-fix itself. Signed-off-by: Kyle M Hall Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 5e37c3e412168114fd61085f79a018a38e70f149 Author: Kyle M Hall Date: Thu May 7 14:31:32 2026 -0400 Bug 40901: (follow-up) Allow seamless swap between koha-systemd and koha-sysv koha-systemd and koha-sysv have always declared mutual Conflicts so you can't install both, but they don't declare Replaces which would make it so installing one autmatically removes the other Signed-off-by: Kyle M Hall Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 8023b38202502d08266f80f30b38d42c471c82c4 Author: Kyle M Hall Date: Fri May 8 12:44:48 2026 -0400 Bug 40901: (follow-up) koha-create enables koha@.target on systemd Without this, freshly-created instances on a koha-systemd host do not auto-start at next boot. Signed-off-by: Kyle M Hall Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim