You are not logged in.
So I have .deb install scripts on a package (zoneminder) that I'm looking to get changed. They are built for systemd, and look something like this:
#! /bin/sh
set +e
if [ "$1" = "configure" ]; then
. /etc/zm/zm.conf
for CONFFILE in /etc/zm/conf.d/*.conf; do
. "$CONFFILE"
done
# The logs can contain passwords, etc... so by setting group root, only www-data can read them, not people in the www-data group
chown www-data:root /var/log/zm
chown www-data:www-data /var/lib/zm
if [ -z "$2" ]; then
chown www-data:www-data /var/cache/zoneminder /var/cache/zoneminder/*
fi
if [ ! -e "/etc/apache2/mods-enabled/cgi.load" ] && [ "$(command -v a2enmod)" != "" ]; then
echo "The cgi module is not enabled in apache2. I am enabling it using a2enmod cgi."
a2enmod cgi
fi
if [ ! -e "/etc/apache2/mods-enabled/rewrite.load" ] && [ "$(command -v a2enmod)" != "" ]; then
echo "The rewrite module is not enabled in apache2. I am enabling it using a2enmod rewrite."
a2enmod rewrite
fi
if [ "$ZM_DB_HOST" = "localhost" ]; then
if [ -e "/lib/systemd/system/mysql.service" ] || [ -e "/lib/systemd/system/mariadb.service" ] || [ -e "/etc/init.d/mysql" ]; then
# Ensure zoneminder is stopped
deb-systemd-invoke stop zoneminder.service || exit $?
#
# Get mysql started if it isn't running
#
if [ -e "/lib/systemd/system/mariadb.service" ]; then
DBSERVICE="mariadb.service"
else
DBSERVICE="mysql.service"
fi
echo "Detected db service is $DBSERVICE"
if systemctl is-failed --quiet $DBSERVICE; then
echo "$DBSERVICE is in a failed state; it will not be started."
echo "If you have already resolved the problem preventing $DBSERVICE from running,"
echo "run sudo systemctl restart $DBSERVICE then run sudo dpkg-reconfigure zoneminder."
exit 1
fi
if ! systemctl is-active --quiet mysql.service mariadb.service; then
# Due to /etc/init.d service autogeneration, mysql.service always returns the status of mariadb.service
# However, mariadb.service will not return the status of mysql.service.
deb-systemd-invoke start $DBSERVICE
fi
# Make sure systemctl status exit code is 0; i.e. the DB is running
if systemctl is-active --quiet "$DBSERVICE"; then
mysqladmin --defaults-file=/etc/mysql/debian.cnf -f reload
# test if database if already present...
if ! $(echo quit | mysql --defaults-file=/etc/mysql/debian.cnf zm > /dev/null 2> /dev/null) ; then
echo "Creating zm db"
cat /usr/share/zoneminder/db/zm_create.sql | mysql --defaults-file=/etc/mysql/debian.cnf
if [ $? -ne 0 ]; then
echo "Error creating db."
exit 1;
fi
# This creates the user.
echo "CREATE USER '${ZM_DB_USER}'@localhost IDENTIFIED BY '${ZM_DB_PASS}';" | mysql --defaults-file=/etc/mysql/debian.cnf mysql
fi
echo "Updating permissions"
echo "grant lock tables,alter,drop,select,insert,update,delete,create,index,alter routine,create routine, trigger,execute on ${ZM_DB_NAME}.* to '${ZM_DB_USER}'@localhost;" | mysql --defaults-file=/etc/mysql/debian.cnf mysql
zmupdate.pl --nointeractive
zmupdate.pl --nointeractive -f
# Add any new PTZ control configurations to the database (will not overwrite)
zmcamtool.pl --import >/dev/null 2>&1
echo "Done Updating; starting ZoneMinder."
else
echo 'NOTE: MySQL/MariaDB not running; please start mysql and run dpkg-reconfigure zoneminder when it is running.'
fi
else
echo 'MySQL/MariaDB not found; assuming remote server.'
fi
else
echo "Not doing database upgrade due to remote db server ($ZM_DB_HOST)."
fi
deb-systemd-invoke restart zoneminder.service
fi
# Automatically added by dh_systemd_enable/12.1.1
if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ] || [ "$1" = "abort-deconfigure" ] || [ "$1" = "abort-remove" ] ; then
if deb-systemd-helper debian-installed 'zoneminder.service'; then
# This will only remove masks created by d-s-h on package removal.
deb-systemd-helper unmask 'zoneminder.service' >/dev/null || true
if deb-systemd-helper --quiet was-enabled 'zoneminder.service'; then
# Create new symlinks, if any.
deb-systemd-helper enable 'zoneminder.service' >/dev/null || true
fi
fi
# Update the statefile to add new symlinks (if any), which need to be cleaned
# up on purge. Also remove old symlinks.
deb-systemd-helper update-state 'zoneminder.service' >/dev/null || true
fi
# End automatically added section
# Automatically added by dh_installinit/12.1.1
if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ] || [ "$1" = "abort-deconfigure" ] || [ "$1" = "abort-remove" ] ; then
# In case this system is running systemd, we need to ensure that all
# necessary tmpfiles (if any) are created before starting.
if [ -d /run/systemd/system ] ; then
systemd-tmpfiles --create zoneminder.conf >/dev/null || true
fi
fi
# End automatically added section
# Automatically added by dh_installdeb/12.1.1
dpkg-maintscript-helper rm_conffile /etc/zm/apache.conf 1.28.1-5~ -- "$@"
# End automatically added section
# Automatically added by dh_installinit/12.1.1
if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ] || [ "$1" = "abort-deconfigure" ] || [ "$1" = "abort-remove" ] ; then
if [ -x "/etc/init.d/zoneminder" ]; then
update-rc.d zoneminder defaults >/dev/null
invoke-rc.d zoneminder start || exit 1
fi
fi
# End automatically added section
What breaks compatibility is the specific commands such as deb-systemd-helper or deb-systemd-invoke restart zoneminder.service for example.
What's the best practice for adding support for sysvinit or devuan as well? Should I search - if exists - /etc/devuan_version then do devuan section... or is there a better way that is not limited to devuan (i.e. would also support any distro with sysvinit).
I should mention that, in terms of simplicity, I would not want to just add on something like
else
echo "Not doing database upgrade due to remote db server ($ZM_DB_HOST)."
fi
<added section>
if (init is detected as sysvinit)
then
service restart zoneminder
else
</added section>
deb-systemd-invoke restart zoneminder.service
And layer more commands in each section, as that would make maintenance difficult.
I would instinctively want to separate out the configs, so that the sysvinit is in its own section to make everything less entangled and more modular. My thought was to have it be
if sysvinit detected then
sysvinitsection with break to end script
else
systemd section
give a man an init, he takes an os
Offline
What's the best practice for adding support for sysvinit or devuan as well?
The posted script seems to already support sysvinit:
if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ] || [ "$1" = "abort-deconfigure" ] || [ "$1" = "abort-remove" ] ; then if [ -x "/etc/init.d/zoneminder" ]; then update-rc.d zoneminder defaults >/dev/null invoke-rc.d zoneminder start || exit 1 fi fi
Brianna Ghey — Rest In Power
Offline
As I understand it the correct way is to re-build the .deb package from the source using deb_helper.
There a tutorial on the overall process here: https://wiki.debian.org/BuildingTutorial.
Though the tutorial uses an example where you want to change the source code (and recompile) not just the packaging.
Essentially to create a Devuan compatible .deb you need to:
1) add a suitable init script to the files tree (your /etc/init.d/zoneminder). As has been pointed out by Head_on_a_Stick you can generate one from the systemd service file using the sysv2d.sh script.
2) Adding a Debian rule to generate the sysvinit additions to the postinst and postrm scripts.
The rule will be a parametrisation of the deb helper program dh_installinit.
3) Change the version number and annotate the change.
4) If you then want to submit as a bug to Debian create a diff on the original and submit it with the bug report.
When you've recreated your .deb you might see in your postinst file something like this :
# Automatically added by dh_installinit/12.1.1
if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ] || [ "$1" = "abort-deconfigure" ] || [ "$1" = "abort-remove" ] ; then
if [ -x "/etc/init.d/chrony" ]; then
update-rc.d chrony defaults >/dev/null
if [ -n "$2" ]; then
_dh_action=restart
else
_dh_action=start
fi
invoke-rc.d --skip-systemd-native chrony $_dh_action || exit 1
fi
fi
# End automatically added section
This example (for chrony) enables (using update-rc.d) and starts (using invoke-rc.d) the init.
The corresponding addition to postrm is:
# Automatically added by dh_installinit/12.1.1
if [ "$1" = "purge" ] ; then
update-rc.d chrony remove >/dev/null
fi
# End automatically added section
However some maintainers don't provide an init file and don't run dh_installinit, which is where we get problems.
Here is an example of the rules for another deb (nftables) that doesn't. As you can see, dh_installinit is called but just with the -n parameter and so doesn'r run. Run without any parameters it will create the postinst code to enable and start the init and the postrm code to remove it. For some programs you might not want to have enable or start (in this case for dh_installsystemd they are turned off by parameters --no-enable- -no-start).
#!/usr/bin/make -f
ifeq (,$(filter terse,$(DEB_BUILD_OPTIONS)))
export DH_VERBOSE=1
endif
export PYBUILD_NAME = nftables
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
configure_opts := --with-xtables --with-json --with-python-bin=/usr/bin/python3
override_dh_auto_configure:
dh_auto_configure -- $(configure_opts) --
%:
dh $@ --with python3
override_dh_fixperms:
dh_fixperms
chmod a+x debian/nftables/etc/nftables.conf
override_dh_installsystemd:
dh_installsystemd --no-enable --no-start
override_dh_installinit:
# dh_installinit will try to mess with /etc/init.d/nftables in
# the maintainer scripts, but we don't ship it
dh_installinit -n
override_dh_installexamples:
dh_installexamples -XMakefile
# upstream examples are installed in by the 'install' target to '/etc/nftables'
mv debian/tmp/etc/nftables/*.nft debian/nftables/usr/share/doc/nftables/examples/
rm -rf debian/nftables/etc/nftables
Last edited by Marjorie (2020-07-30 21:10:28)
Offline
Per Headonastick: There's other commands in the script that fail to run on devuan, and that snippet is only for the startup defaults. If you read the remaining parts of the script, you will see what I mean.
I should probably get around to reading one of the dpkg books, so I apologize if this information is obvious to package maintainers.
Per Marjorie, thanks, that seems to point me in the right direction. I'll look into the rules, along with the commands you listed and should be able to figure it out.
Last edited by little (2020-07-30 20:49:33)
give a man an init, he takes an os
Offline