Ubuntu – the right way to restart dependent services while package installation

14.04packagingservicessystemdupstart

I am creating a configuration package, and would like to stop and restart services whose configuration is affected. Right now I am using the service [stop|restart] in {pre,post}{inst,rm} way. I read in a question somewhere that invoke-rc.d is the right way, because it honours user preferences about a service. However, I couldn't find any guidelines about this. Does anyone know of such guidelines? Or have any advice as to which way I should pick? The package is of internal use, and will likely only be for 14.04 for the next two years. However, I'd like to leave as clean a state as possible for my successor, so systemd is in my mind as well.

From the invoke-rc.d man page:

All access to the init scripts by Debian packages' maintainer scripts
should be done through invoke-rc.d.

From the Debian Policy Manual, Chapter 9, Section 3.3:

Maintainers should use the abstraction layer provided by the update-rc.d and invoke-rc.d programs to deal with initscripts in their packages' scripts such as postinst, prerm and postrm.

The package maintainer scripts must use invoke-rc.d to invoke the /etc/init.d/* initscripts, instead of calling them directly.

Debian has been using sysv-init and will shift directly to systemd, and I suppose the policy manual will be updated in due time to refer to systemctl. However, what I am uncertain about is this: Should I use invoke-rc.d instead of service? I can tell dpkg that I am interested in some files (via triggers), so is there a way to tell dpkg that I am interested in some services as well and get dpkg to do the restarting/reloading?

To clarify: I am not writing init scripts. I am providing a package with configuration for other applications, like Puppet, NTP, etc., so I stop and restart the corresponding services in the scripts.

Here, for example, is a Docker issue about invoke-rc.d vs service. The issue is still open, with one person, probably a maintainer, commenting that they are definitely interested in doing this the right way – clearly neither of us are sure what that is. (My question is independent of that issue.)

Best Answer

I would continue to use the pre/post inst scripts,

preinst - This script executes before that package will be unpacked from its Debian archive (".deb") file. Many 'preinst' scripts stop services for packages which are being upgraded until their installation or upgrade is completed (following the successful execution of the 'postinst' script).

postinst - This script typically completes any required configuration of the package foo once foo has been unpacked from its Debian archive (".deb") file. Often, 'postinst' scripts ask the user for input, and/or warn the user that if he accepts default values, he should remember to go back and re-configure that package as the situation warrants. Many 'postinst' scripts then execute any commands necessary to start or restart a service once a new package has been installed or upgraded.

see - https://www.debian.org/doc/manuals/debian-faq/ch-pkg_basics.en.html

The syntax of invoking start|stop|restart is written as a conditional, see https://www.debian.org/doc/debian-policy/ch-opersys.html section 9.3.3.2 Running initscripts

if which invoke-rc.d >/dev/null 2>&1; then

invoke-rc.d package

else

/etc/init.d/package

fi

so ...

if which service >/dev/null 2>&1; then
        service package <action>
elif which invoke-rc.d >/dev/null 2>&1; then
        invoke-rc.d package <action>
else
        /etc/init.d/package <action>
fi

and add another conditional for systemd when needed ;)

So yes, the proper way to start|stop|restart a service is with the appropriate wrapper script (invoke-rc.d / system), when possible, rather then calling the init script (/etc/init.d/package) and falling back to the /etc/init.d script when no wrapper is available.

Related Question