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 <noreply@anthropic.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
- 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 <noreply@anthropic.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
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@<inst>.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@<inst>.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@<name>.target
itself.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
- 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 <noreply@anthropic.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
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 <noreply@anthropic.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
- Order services Before= their instance target instead of After=. With
After=, koha@<inst>.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-<service> 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 <listen> entries
get the same stale-socket protection.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
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 <noreply@anthropic.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
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 <noreply@anthropic.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
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 <noreply@anthropic.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
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 <noreply@anthropic.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
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 <noreply@anthropic.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
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 <noreply@anthropic.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
debhelper treats debian/<package>.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 <noreply@anthropic.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
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 <noreply@anthropic.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
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 <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
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 <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
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 <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
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 <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
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 <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
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 <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
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 <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
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 <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
- 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>