Commit Graph

62793 Commits

Author SHA1 Message Date
Martin Renvoize 445b955b78
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 <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:02:08 +00:00
Martin Renvoize 6b54ee976b
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 <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:02:07 +00:00
Martin Renvoize 3eb65c1041
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 <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:02:05 +00:00
Martin Renvoize 868947cb55
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 <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:02:04 +00:00
Martin Renvoize 6d3b026d91
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 <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:02:03 +00:00
Martin Renvoize 53ebfcb8c5
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 <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:02:01 +00:00
Martin Renvoize 3644a8407f
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 <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:02:00 +00:00
Kyle M Hall b5000b8869
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 <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:01:59 +00:00
Kyle M Hall 05228589ed
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 <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:01:58 +00:00
Kyle M Hall 88926c5032
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 <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:01:57 +00:00
Kyle M Hall a84dbc3d29
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 <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:01:56 +00:00
Kyle M Hall a6226588f6
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 <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:01:55 +00:00
Kyle M Hall 0f2f88371d
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 <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:01:53 +00:00
Kyle M Hall 1425743c10
Bug 40901: (follow-up) koha-remove leaves koha@<inst>.target enabled
Disable koha@<inst>.target and koha-create-dirs@<inst>.service so
their koha.target.wants/ symlinks don't outlive the instance.

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:01:52 +00:00
Kyle M Hall d0d193ea7e
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 <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:01:51 +00:00
Kyle M Hall 5e37c3e412
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 <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:01:50 +00:00
Kyle M Hall 8023b38202
Bug 40901: (follow-up) koha-create enables koha@<inst>.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 <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:01:49 +00:00
Kyle M Hall 9ce9a07460
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 <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:01:48 +00:00
Kyle M Hall 8dccb4cc37
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 <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:01:47 +00:00
Kyle M Hall c82e55a5a5
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/<inst>/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@<inst>.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 <inst>. Use: koha-sip --enable <inst>

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 <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:01:45 +00:00
Tomás Cohen Arazi d67d319b89
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 <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:01:44 +00:00
Tomás Cohen Arazi bf8529fbd4
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 <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:01:42 +00:00
Tomás Cohen Arazi d8b3d46634
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 <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:01:41 +00:00
Tomás Cohen Arazi 6763a3048b
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 <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:01:40 +00:00
Tomás Cohen Arazi af44d814af
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 <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:01:38 +00:00
Tomás Cohen Arazi bde94861c4
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 <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:01:37 +00:00
Tomás Cohen Arazi 439be05aef
Bug 40901: (follow-up) Extract koha-create-dirs into a oneshot unit
Replace per-service ExecStartPre=+koha-create-dirs (running as root
on every start of every service) with a single oneshot unit per
instance. Services declare Requires= on it, and the oneshot's Before=
ensures directories exist before any service starts.

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:01:35 +00:00
Tomás Cohen Arazi 90825d3292
Bug 40901: (follow-up) Fix incomplete systemd wiring in helpers
- koha-z3950-responder: add systemd enable/disable to enable_z3950/disable_z3950
- koha-disable: add plack and es-indexer stop/disable
- koha-remove: add worker --disable after --stop
- koha-systemd-ctl: fix service name worker-long to worker-long_tasks

Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:01:34 +00:00
Tomás Cohen Arazi 630b1c377d
Bug 40901: (follow-up) Fix critical bugs in systemd integration
- koha-sip: disable_sip() was calling 'enable' instead of 'disable'
- koha-indexer: enable/disable dispatch was calling start/stop functions
- koha-systemd.postinst: upgrade try-restart was outside the case block

Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:01:33 +00:00
Jake Bateman 142ab7320f
Bug 40901: Add systemd try-restart to koha-systemd postinst
In order for apt upgrades to trigger a service restart for all koha-systemd subservices and all instances, this adds a wildcard try-restart for those in addition to the daemon-reload. Only services which are already present and running will be restarted at postinst time

Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:01:32 +00:00
Jake Deery d998990d77
Bug 40901: (testing follow-up) Add koha-create-dirs to units
This patch adds an elevated koha-create-dirs to the systemd units, so
that when the units (re)start, the directories are definitely present.
We found that PID files were missing and couldn't be created without
this patch.

Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:01:30 +00:00
Jake Deery 3073a347cc
Bug 40901: (testing follow-up) Added enable / disable to more helpers
This patch adds more enable / disable flags to the koha daemon helper
scripts. This is essential as systemd does not enable units by default,
especially when using instantiation variables.

Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:01:29 +00:00
Jake Deery d28ded7538
Bug 40901: (testing follow-up) Move koha-worker-long@ unit to koha-worker-long_tasks@
We found a bug when running koha-create. The systemd unit name didn't
match expected, so we've moved the unit to match the koha functions
computed value.

Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:01:28 +00:00
Jake Deery 0af4e80aa0
Bug 40901: (testing follow-up) Moved legacy code to koha-sysv.postinst
This patch moves the update-rc.d lines from koha-core to koha-sysv, so
it only fires if systemd is not in use

Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:01:27 +00:00
Jake Deery 80e6ddaa90
Bug 40901: (testing follow-up) Remove / rename koha-common to koha-core
This patch removes or renames some of the debian files from koha-common
to koha-core, to avoid file clash during install

Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:01:25 +00:00
Tomás Cohen Arazi a0f36621ad
Bug 40901: Add support for 'systemctl' in `koha-*` scripts
Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:01:24 +00:00
Tomás Cohen Arazi be89db235c
Bug 40901: Restructure packages - koha-common becomes metapackage
This patch restructures the Koha packaging to support both systemd and
SysV init systems through a clean separation of concerns.

Package hierarchy:
- koha-core: Core application files (no init system)
- koha-systemd: Native systemd units (Provides: koha-init)
- koha-sysv: SysV init scripts (Provides: koha-init, Conflicts: koha-systemd)
- koha-common: Metapackage (Depends: koha-core, koha-systemd | koha-sysv)

Changes:
- koha-core: Removed 'daemon' dependency, updated description to clarify
  it provides core files without init system
- koha-systemd: Now depends on koha-core instead of koha-common, provides
  koha-init virtual package
- koha-sysv: Now depends on koha-core instead of koha-common, provides
  koha-init virtual package
- koha-common: Converted to metapackage that depends on koha-core and
  prefers koha-systemd on systemd-based systems
- Removed koha-common.install (files now installed by koha-core)
- Simplified koha-common.postinst (metapackage has minimal logic)

Benefits:
- Clean separation between core application and init system
- Users can explicitly choose their init system
- KTD can use koha-sysv without systemd
- Modern systems get native systemd by default
- Conflicts prevent both init systems being active simultaneously

Test plan:
1. Build packages
2. Install koha-common on a systemd system, verify koha-systemd is pulled in
3. Try installing both koha-systemd and koha-sysv, verify conflict
4. Install koha-core + koha-sysv explicitly, verify it works

Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:01:23 +00:00
Tomás Cohen Arazi 34ad12360f
Bug 40901: Add koha-sysv package for SysV init support
This patch introduces the koha-sysv package, which provides traditional
SysV init.d scripts for managing Koha instances. All services (Plack,
Zebra, SIP, Z3950, workers, indexers) are managed through a single init
script using the daemon wrapper.

The package includes:
- /etc/init.d/koha-common (SysV init script)
- /lib/systemd/system/koha-common.service (systemd wrapper for init.d)

This package is intended for legacy systems, containers without systemd
(like KTD), or environments where SysV init is preferred.

The package provides 'koha-init' and conflicts with koha-systemd to
ensure only one init system is active at a time.

Test plan:
1. Build and install the package
2. Start services with /etc/init.d/koha-common start
3. Verify all services start correctly
4. Check that koha-systemd cannot be installed alongside

Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:01:22 +00:00
Tomás Cohen Arazi dc8cced6be
Bug 40901: Add koha-systemd package with native systemd units
This patch introduces the koha-systemd package, which provides native
systemd service units for managing Koha instances. Each service type
(Plack, Zebra, SIP, Z3950, workers, indexers) is managed as a separate
systemd unit using instance templates.

The package includes:
- 8 service templates (plack, zebra, sip, z3950, worker, worker-long,
  indexer, es-indexer)
- 2 target units (koha@.target for per-instance, koha.target for global)
- Helper script (koha-systemd-ctl) for managing services

All service units include:
- KOHA_HOME environment variable pointing to /usr/share/koha
- WorkingDirectory set to /var/lib/koha/%i
- Proper user/group permissions (%i-koha)

This allows granular control over individual services per instance and
leverages systemd features like dependency management, resource limits,
and journald logging.

Test plan:
1. Build and install the package
2. Enable services for an instance
3. Verify all services start correctly
4. Check journalctl logs show no errors

Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-29 09:01:21 +00:00
Pedro Amorim 02e0b4dc9e
Bug 42490: DBRev 26.06.00.030
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-28 15:36:08 +00:00
Andrew Fuerste Henry 20223a3e16
Bug 42490: (QA follow-up) Reword syspref description and options
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-28 15:29:59 +00:00
Martin Renvoize d8c245b505
Bug 42490: (QA follow-up) Address QA review comments
- Remove leftover skeleton boilerplate comments in the atomicupdate
  ("Do you stuffs here", "# sysprefs")
- Fix typo in atomicupdate description ("preferene" -> "preference")
- Update POD on MapItemsToHoldRequests to mention the new
  LocalHoldsPriorityScope gate
- Explicitly mock LocalHoldsPriorityScope in the existing Local Holds
  Priority subtests that exercise CreateQueue/MapItemsToHoldRequests,
  instead of relying on it falling through to the real DB default

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-28 15:29:58 +00:00
Andrew Fuerste Henry fa3aacffd8
Bug 42490: Update unit tests
Prove t/db_dependent/HoldsQueue.t

Sponsored-by: The Main Library Alliance <https://www.mainlib.org/>
Signed-off-by: Trevor Diamond <trevor.diamond@mainlib.org>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-28 15:29:57 +00:00
Andrew Fuerste Henry 662de2a955
Bug 42490: Implement LocalHoldsPriorityScope
To test:
1 - Set LocalHoldsPriority to "Don't give", set HoldsQueuePrioritizeBranch to "home library"
2 - have a bib with two items: both items available, Item 1 home and holdingbranch Centerville, Item 2 home and holdingbranch Fairfield
3 - place a hold (Hold 1) on the bib for a patron from Centerville , for pickup at Fairfield
4 - place a hold (Hold 2) on the bib for a patron from Fairfield, for pickup at Centerville

Establish behavior without LocalHoldsPriority
5 - build holds queue
6 - confirm the queue targets the FPL item for Hold 1 and the CPL item for Hold 2
7 - check both items out to a third patron (not one of your patrons with holds)
8 - check in Item 2, confirm it tries to fill Hold 1, click Ignore
9 - check in Item 1, confirm it also tries to fill Holds 1, click Ignore
10 - reset item locations: UPDATE items SET holdingbranch=homebranch;

Establish behavior with LocalHoldsPriority
11 - Set LocalHoldsPriority to "Give library", LocalHoldsPriorityPatronControl to "home library", LocalHoldsPriorityItemControl to "home library"
12 - build holds queue
13 - confirm the queue targets the CPL item for Hold 1 and the FPL item for Hold 2
14 - check both items out to a third patron (not one of your patrons with holds)
15 - build holds queue, confirm it has no targets
16 - check in Item 2, confirm it tries to fill Hold 2, click Ignore
17 - check in Item 1, confirm it tries to fill Holds 1, click Ignore
18 - reset item locations: UPDATE items SET holdingbranch=homebranch;

Apply patch, updatedatabase, restart_all
19 - confirm new system preference LocalHoldsPriorityScope, set to "checking items in and building the holds queue"
20 - repeat steps 11 - 18, no change in behavior
21 - set LocalHoldsPriorityScope to "checking items in"
22 - build holds queue
23 - confirm the queue targets the FPL item for Hold 1 and the CPL item for Hold 2
24 - check both items out to a third patron (not one of your patrons with holds)
25 - build holds queue, confirm it has no targets
26 - check in Item 2, confirm it tries to fill Hold 2
27 - check in Item 1, confirm it tries to fill Holds 1

Sponsored-by: The Main Library Alliance <https://www.mainlib.org/>
Signed-off-by: Trevor Diamond <trevor.diamond@mainlib.org>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-28 15:29:56 +00:00
Andrew Fuerste Henry 5434465a35
Bug 42490: Add system preference LocalHoldsPriorityScope
Sponsored-by: The Main Library Alliance <https://www.mainlib.org/>
Signed-off-by: Trevor Diamond <trevor.diamond@mainlib.org>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-28 15:29:54 +00:00
Slava Shishkin 08333dc996
Bug 42505: (follow-up) Generate hold slip after confirming hold
The previous follow-up passed the checked-in itemnumber to the slip, but
the slip was still rendered before ModReserveAffect() confirmed the
hold. Fields updated during confirmation, such as waitingdate and
expirationdate, were therefore missing or stale on the first print.

Open a blank named popup during the user gesture, then submit the
confirmation form with print_slip set. The response page reuses that
popup after the hold has been updated.

This preserves the popup blocker fix and allows ReserveSlip() to use
the persisted hold and item data without passing individual fields as
workarounds.

To test:
1. Set HoldsAutoFill to "Don't".
2. Add the following to the HOLD_SLIP notice:
   Waiting since: [% hold.waitingdate | $KohaDates %]
   Barcode: <<items.barcode>>
3. Place a title-level "Next available" hold with pickup at the
   check-in library.
4. Check in a matching item.
5. Click "Print slip and confirm".
6. Confirm the popup is not blocked.
7. Confirm the first slip contains the item's barcode and today's
   waiting date.
8. Reload the slip and confirm the values are unchanged.

Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-28 15:29:53 +00:00
Martin Renvoize 3ce02836d0
Bug 42505: Open hold transfer slip in user gesture to bypass popup blocker
When returning an item required to fulfil a hold at another branch with
HoldsAutoFill set to "Don't", the librarian is shown a "Hold found"
modal and chooses "Print slip, transfer, and confirm". The previous
implementation set a hidden 'print_slip' input to 1, submitted the
form, and relied on $(document).ready on the response page to call
Dopop() / window.open() to open the slip. Because that window.open()
is no longer associated with a user gesture (the gesture chain is
broken by the form submission and page navigation), modern browsers
block it as an unsolicited popup. The hold is confirmed but the slip
never appears, and the librarian may not realise it was attempted.

This patch opens the slip synchronously inside the .print click
handler instead, while the user gesture is still active, so the
browser allows the window.open() through. The form is then submitted
as before to confirm the hold. The reserve_id is taken from the
hidden input already present in the modal form; hold-transfer-slip.pl
needs only the reserve_id and does not require the hold to have been
moved to "Waiting" state first, so the slip content is correct.

To test:
1. Set syspref HoldsAutoFill = "Don't".
2. Place a hold for a patron whose pickup branch is different from
   your logged-in branch.
3. Check in the item at your logged-in branch.
4. The "Hold found" modal appears.
5. Click "Print slip, transfer, and confirm".
6. Confirm the hold transfer slip opens in a new window and is not
   blocked by the browser's popup blocker.
7. Confirm the hold is still correctly confirmed and the item placed
   in transit.
8. Repeat with HoldsAutoFill = "Don't" and a same-branch hold,
   clicking "Print slip and confirm" instead, and confirm the slip
   opens for that path too.

Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-28 15:29:52 +00:00
Pedro Amorim f1955d23f0
Bug 41253: DBRev 26.06.00.029
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-28 15:29:51 +00:00
Alex Carver [Acerock7] 03a817759c
Bug 41253: Fix Cataloging Side Nav
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-28 15:29:50 +00:00
Jonathan Druart 1d0e6f0930
Bug 41253: Grant permission only when the permission is created
In case it got backported, we don't want to grant permissions again,
only when the db rev is run for the first time.

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-09-28 15:29:48 +00:00