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 commit 9ce9a07460c36191380644e3de77de18d9854043 Author: Kyle M Hall Date: Thu May 7 12:37:36 2026 -0400 Bug 40901: (follow-up) sip.enabled is an anti-pattern for systemd Remove the use of sip.enabled for systemd, keep for sysv No other service using a .enabled file is controlled via systemd or sysv Signed-off-by: Kyle M Hall Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 8dccb4cc376b053dd87f610c7b00292e1e1e887f Author: Kyle M Hall Date: Wed May 6 13:53:42 2026 -0400 Bug 40901: (follow-up) Use --config-dir for z3950_responder.pl Documentation is wrong, -c doesn't work for z3950_responder.pl Signed-off-by: Kyle M Hall Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit c82e55a5a564ee4328202571b5ae21efbf096a4b Author: Kyle M Hall Date: Mon May 4 14:16:32 2026 -0400 Bug 40901: (follow-up) Fail loudly when koha-sip is enabled without flag file The koha-sip@.service unit gates startup on /var/lib/koha//sip.enabled, the per-instance "I want SIP on" flag file. `koha-sip --enable` creates that flag in the same call that runs `systemctl enable`; running a bare `systemctl enable koha-sip@.service` only flips the systemd half, so the unit ends up enabled-but-refusing-to-start. With ConditionPathExists the failure mode is silent and the unit ends up "enabled" at the systemd level but "Active: inactive" (dead) with "Condition: start condition failed" and the journal logs aren't a big help figuring out the problem. This patch replaces the silent skip with a loud failure with a helpful message: ERROR: SIP not enabled for instance . Use: koha-sip --enable SIPconfig.xml is gated by AssertPathExists if it's missing the unit fails. Either failure path lands the unit in failed state, surfaced by 'systemctl --failed' Signed-off-by: Kyle M Hall Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit d67d319b8984ea468afc4b2e82476c3c345f281c Author: Tomás Cohen Arazi Date: Wed Apr 29 10:32:31 2026 -0300 Bug 40901: (follow-up) Preserve 'service koha-common' UX with systemd Adds PartOf=koha.target to koha@.target so that stopping or restarting the global target propagates to all instance targets and their services. Ships a koha-common.service oneshot unit that delegates to koha.target, so 'systemctl restart koha-common' works as the drop-in replacement for the old 'service koha-common restart'. Signed-off-by: Kyle M Hall Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit bf8529fbd4fb7bd099943130657f0f52e6bdce6c Author: Tomás Cohen Arazi Date: Tue Apr 28 21:37:44 2026 -0300 Bug 40901: (follow-up) Read service config from koha-conf.xml in systemd units The systemd units were missing most of the parameters that the SysV init functions read from koha-conf.xml. This caused wrong worker counts, missing log files, ignored batch sizes, and other config being silently dropped. This patch adds koha-generate-env, a helper script that reads koha-conf.xml and writes an EnvironmentFile for each service. Each unit runs it as ExecStartPre and then uses the variables. Changes per unit: - koha-plack@: workers, max-requests, access/error logs, environment (development/deployment), per-instance psgi, -M FindBin - koha-zebra@: loglevels, max_record_size, timestamp format - koha-es-indexer@: batch_size - koha-indexer@: INDEXER_TIMEOUT from /etc/default/koha-common - koha-z3950@: config dir fallback to global, additional options Signed-off-by: Kyle M Hall Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit d8b3d46634ecead671bdcaca9b965101fd847e33 Author: Tomás Cohen Arazi Date: Tue Apr 28 21:25:07 2026 -0300 Bug 40901: (follow-up) Fix parallel execution of SysV and systemd services When upgrading from the old koha-common (pre-split) to the new koha-core + koha-systemd packages, the SysV init script /etc/init.d/koha-common is left behind as an orphan. The systemd-sysv-generator auto-creates koha-common.service from it, which runs in parallel with the native systemd units, causing double-starts of all Koha services. Changes: - koha-systemd.postinst now stops, disables, and removes the orphaned SysV init script when koha-sysv is not installed - koha-sysv gets Replaces/Breaks on koha-common (<< 25.11) so dpkg can cleanly take over the init script file Signed-off-by: Kyle M Hall Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 6763a3048b0fa815d69e11641abe056aa3e14a03 Author: Tomás Cohen Arazi Date: Tue Apr 28 11:34:23 2026 -0300 Bug 40901: (follow-up) Enable systemd units for existing instances on install On first install of koha-systemd (migration from SysV), enable units for all existing Koha instances. Core services (plack, zebra, workers) are always enabled. SIP, Z39.50, and indexers are enabled conditionally based on instance configuration. Signed-off-by: Kyle M Hall Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit af44d814af7f2ec4d6b494d4941d96bcbfd1629f Author: Tomás Cohen Arazi Date: Tue Apr 28 11:08:17 2026 -0300 Bug 40901: (follow-up) Add Replaces/Breaks for smooth upgrade from koha-common koha-core takes over files previously owned by koha-common (e.g. /etc/default/koha-common). Without Replaces/Breaks, dpkg refuses to overwrite them during upgrade. Signed-off-by: Kyle M Hall Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit bde94861c48424e04b0dcdd96fc5ea40323f2549 Author: Tomás Cohen Arazi Date: Mon Apr 27 15:11:08 2026 -0300 Bug 40901: (follow-up) Regenerate debian/control from control.in Run debian/update-control to include koha-systemd and koha-sysv package stanzas and refresh Perl autodependencies. Signed-off-by: Kyle M Hall Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim