#804018 dpkg: provide options to avoid service startup on package installation

#804018#5
Date:
2015-11-04 09:59:19 UTC
From:
To:
Hi,

as of today services a started once they are installed. This is a problem
in some cases, e.g. when installing and configuring a service via puppet
and/or in preparation for a HA setup.

We had a lot of discussions around this design decision in the past and I
do not want to restart that. Instead I'd like to propose a feature to
opt-out from automatic service startup by introdocution of a new dpkg
option, e.g. Dpkg::StartServices with a truthy default.

RATIONALE:
By adding a configuration option for this, we allow the administrator of a
Debian system to decide if services are started after installation or not.

It is superior to adding a command line switch only, since it allows the
admin to set this permanent and system-wide (with all its disadvantages) or
on a per-installation base (which would be suitable to be used by
configuration management systems).

Possible implementation:
Per policy 9.3.3.2 have to interface with init via invoke-rc.d for service
startup. A possible (and admittedly naive) implementation which does not
involve changes in each and every package, could possibly just let dpkg
install a policy.d layer and ensure its absence on process end. Though some
sort of IPC between invoke-rc.d and dpkg that does not involve filesystem
modifications would probably be better.

Best Regards,
Patrick

#804018#10
Date:
2015-11-04 12:19:20 UTC
From:
To:
Hi Patrick,

you are aware of

echo -e '#!/bin/sh\nexit 101' > /usr/sbin/policy-rc.d

to implement exactly this?


cheers,
	Holger

#804018#15
Date:
2015-11-04 13:08:52 UTC
From:
To:
Hi!

This all feels very out of scope for dpkg. More so when policy-rc.d
already supports what you seem to be asking for (as Holger also
pointed out)?

Something like this would mean encoding extremely system specific
policy into the dpkg C codebase, when dpkg has no knowledge whatsoever
on what is happening on maintainer scripts or how init scripts are
invoked or managed etc. It does not feel right.

But perhaps I'm not fully understanding your proposal?

Thanks,
Guillem

#804018#20
Date:
2015-11-04 17:31:28 UTC
From:
To:
Hi,

thanks for thinking about my proposal and commenting on it.

2015-11-04 13:19 GMT+01:00 Holger Levsen <holger@layer-acht.org>:
proposal (it's what I meant with policy.d layer - a misnomer of mine).
However, that would effect all service starts, not only the start after the
package installation, which my proposal aims at.

Of course I could write some policy-rc.d script checking an environment
variable, blacklist or a like and set it before the package installation,
but that somehow feels like a hack, considering that this is just a
distribution decision I want to overrule as an admin (on a case-by-case
basis).

Maybe it helps understanding my proposal, if I describe a use case:
Let's say I'd like to install serviceX, which shall be managed by
pacemaker. Since pacemaker will manage the runtime status of the service
this means to install, disable (and currently) stop the service (which is a
hack in declarative configuration management systems since there is no
state to describe "install package with service disabled").

Providing a standard way to not start a certain service after package
installation seems a lot of cleaner. And that is what my proposal aims at.
Apart from that our distribution decision to start services after
installation is quiet controversial to some people anyway and my proposal
would provide a standard way for those people to opt-out from this choice.


2015-11-04 14:08 GMT+01:00 Guillem Jover <guillem@debian.org>:


I don't think so, because after all its the package manager which starts
the maintainer scripts which in turn starts the service. Apart from that
it's _the_ place where I consciously choose to install a package and if I
want it to be running afterwards. And in case of configuration management
systems: the interface it communicates with.

Yeah, I admit that the implementation idea has all sorts of problems (which
is why I called it naive in the first place).
But I really think dpkg is the right place for the flag (to start services
or not), while invoke-rc.d is the tool called by the maintainer scripts and
therefore responsible for the actual doing. What's missing is the glue
between these components.

Maybe a better implementation would be an environment variable respected by
invoke-rc.d and passed-thru by dpkg?

Best Regards,

Patrick Schönfeld

#804018#25
Date:
2015-11-05 01:38:51 UTC
From:
To:
Hi!

invoke-rc.d and policy-rc.d are precisely interfaces expected to be used
only by maintainer scripts. Anything else done during run-time should
be using some other interface, such as service(8) for example or an init
specific one, otherwise that should be considered a bug.

In case this is a local problem where you have deployed non-maintainer
scripts using invoke-rc.d, then while you fix those, you could check in
policy-rc.d if you are running inside dpkg by checking if the environment
variable DPKG_RUNNING_VERSION is defined (documented in dpkg(1)).

That's really what policy-rc.d is for.

dpkg has no idea nor control over what happens inside maintainer scripts,
those are exclusively under the package domain. Starting services is
just one of the actions that can be done there, if any other policy
would require making dpkg aware of it, then dpkg would suddenly have
to know about tons of things it has no control over. But that place
already exists anyway, per above. :)

As mentioned before and above, I still think this is the wrong way to
look at this. And in principle I'm going to close this bug in a bit,
if no other compelling arguments are put forward.

Thanks,
Guillem

#804018#30
Date:
2015-11-05 07:36:38 UTC
From:
To:
Hi,

2015-11-05 2:38 GMT+01:00 Guillem Jover <guillem@debian.org>:
not the best interface we can can provide for such cases. It's certainly
good enough for the admin who wants to overrule our policy permanently,
although letting the admin write a script for such a simple decision still
feels kind of clumsy. IMHO it has probably been designed for build chroots
and that's absolutely the purpose it fits best.

But let's have a deeper look at the configuration management case. If they
wanted to provide a way to say "install that package, but make sure that
the service is not started afterwards", they could either

a) Permanently install a policy-rc.d layer, letting it interface with the
package install (e.g. by the env variable you said and another one set by
the configuration management to tell the policy-layer which service the
policy applies to)

b) Install a policy-rc.d layer before each package installation, removing
it afterwards

c) Let each user handle installing a policy-rc.d layer either permanently
or before each package installation

Each of this option has several disadvantages:
With a) the admin is no longer able to install another policy-rc.d script,
apart from that it's a quiet invasive from a configuration management
system to put a script in place that is permanently interfered with for
every service that is ever started.

With b) the door is widely opened for all kind of trouble, e.g. leaving
mess around after package installation. Sure there can be put safety
measures into place to avoid that, but overall it increases complexicity -
for a Debian specific solution, since other distributions just don't start
services after installation.

With c) everything applies which applies to b), additionally each user has
to implement this himselves and need to workaround the fact, that the
configuration management system is not aware of his implementation. Thats
where we are today: Some people employ exec-handlers to kill the service
after install, some put a policy-rc.d layer in place.

All of these solutions have in common that they workaround a decision that
we as a project have made (to provide "default" configurations for services
and start them after package installations), which is fine in some cases
(e.g. software I *want* to be running after installation like sshd) and not
so fine in others (installing services I want to manage via a clusterstack
for example). Feels somewhat like giving the user some nails, but expect
him to build the hammer on his own.
And it does not have to have an idea what happens inside maintainer
scripts.

But since it's responsible for installation of those packages, it is also
responsible for providing the environment in which the maintainer scripts
run. Seems absolutely legit to restrict what the maintainer scripts are
allowed to do, even if that restriction is soft, in a way that could be
ignored by the maintainer scripts.

In that specific case, however, we absolutely do have control over what
happens. We have a policy in place that maintainer scripts have to
interface with invoke-rc.d, so if we'd decide on a flag, we could very well
set it in dpkg and let invoke-rc.d respect it. It would be cheap and
solving a problem in a way that other tools (like configuration management)
can rely on. And if the maintainer script does not run an init script at
all, this flag does no harm either.

Best Regards,
Patrick

#804018#35
Date:
2015-11-09 17:07:24 UTC
From:
To:
Hi,

thanks for keeping up the discussion! While I did suggest to file this
against dpkg initially, after reading this bug I do agree with Guillem
that src:dpkg is the wrong place to implement this. Dpkg should care
about .deb files and .deb files only (and whatever is needed around
this). I therefor propose to reassign this discussion to either
"general" or "debian-policy" for now.

That said, back to the original topic. I agree with Patrick that we need
a flexble way to tell "the system" whether we want to start a specific
service on installation or not. The mentioned policy-rc.d system may
help here, but is not in the current state of documentation and
implementation.

As far as I can find (according to [1]), our own documentation mentions
policy-rc.d only twice: [2] and [3]. Especially it is not mentioned in
Policy 9.3.3 [7]! The best documentation I could find is on people.d.o
and in the sysv-rc package: [4], which could make one think this is not
an official interface and only applies to SysV init (it does not: [8]).
So the first step to fixing the issue should be promoting parts of [4]
to the Debian Policy, making policy-rc.d an actual interface definition.

After this is defined, we should have a look at the archive and the
present mis-implementations of [4]. A quick search reveals three
"correct" uses: [5] and various "maybe-not-so-correct" (I did not read
the whole code of the packages) ones: [6]. [ "correct" means here the
package installs an own policy script using the alternatives system ].

With a policy in place and a policy-conform archive, we then can provide
a default implementation of the interface to the users (as a
high-priority alternative inside of pkg:init-system-helpers?) in which
they can decide whether they do want the default debian policy or
whether they want all or some services to be skipped during the
installation. A naïve implementation can be found in __DATA__. With this
implementation, Patrick will just have to drop an
/etc/policy-rc.d/<clusterservice> with a content of
"DEBIAN_NO_START_SERVICES=1" and then his specific service will not be
started during installation. Neither it will be restarted during
upgrade, which is the right thing to do in Patrick's setup. Also, this
should be the real interface Patrick is looking for.

Thanks for reading thus far
o/
Evgeni

[1] https://www.google.com/search?q=policy-rc.d+site%3Adebian.org
[2] https://www.debian.org/doc/manuals/securing-debian-howto/ch3.en.html#s3.5
[3] https://www.debian.org/doc/manuals/debian-reference/ch09.en.html#_chroot_system
[4] https://people.debian.org/~hmh/invokerc.d-policyrc.d-specification.txt
installed on Debian systems as
/usr/share/doc/sysv-rc/README.policy-rc.d.gz from pkg:sysv-rc
[5] https://codesearch.debian.net/results/install%20%2Fusr%2Fsbin%2Fpolicy-rc.d/
[6] https://codesearch.debian.net/perpackage-results/exit.*policy-rc.d/
[7] https://www.debian.org/doc/debian-policy/ch-opersys.html
[8] http://sources.debian.net/src/init-system-helpers/1.24/script/deb-systemd-invoke/#L63

#804018#40
Date:
2015-11-09 19:58:59 UTC
From:
To:
reassign -1 debian-policy
thanks

#804018#47
Date:
2015-11-19 11:51:25 UTC
From:
To:
Hi,

just talking into the wild here.

The policyrcd-script-zg2 package shows how this could be addressed. My
script just looks into /usr/local/sbin/policy-rc.d or
/etc/policy-rc.d and executes the files if they exist. This just moves
the place where the local admin places his local script into a
directory which is in her local domain, a rather trivial task.

For the task at hand, I would think that it would probably be a good
idea to have /etc/policy-rc.d as a directory which holds files called
like services. For example, to stop apache from being started on
package installation and upgrades, one would drop a file into
/etc/policy-rc.d/apache. That file could either contain configuration
data like a single line of "allowed", "undefined", "unknown",
"forbidden", "error" (see other values in
/usr/share/doc/sysv-rc/README.policy-rc.d.gz) or have there a simple
shellscript with the appropriate exit code.

That way would allow a per-service configuration of process start
behavior. The script handling the /etc/policy-rc.d/* file/scripts
could even be in a package (and I could finally retire the rather
trivial policyrcd-script-zg2).

Disclaimer: I do not know whether the new nice systemd world still
honors invoke-rc.d mechanisms. The scripts and documentation originate
from sysv-rc which is at least still present on my systemd-pid1-sid
systems, so there is hope.

Greetings
Marc

#804018#50
Date:
2015-11-19 11:51:25 UTC
From:
To:
Hi,

just talking into the wild here.

The policyrcd-script-zg2 package shows how this could be addressed. My
script just looks into /usr/local/sbin/policy-rc.d or
/etc/policy-rc.d and executes the files if they exist. This just moves
the place where the local admin places his local script into a
directory which is in her local domain, a rather trivial task.

For the task at hand, I would think that it would probably be a good
idea to have /etc/policy-rc.d as a directory which holds files called
like services. For example, to stop apache from being started on
package installation and upgrades, one would drop a file into
/etc/policy-rc.d/apache. That file could either contain configuration
data like a single line of "allowed", "undefined", "unknown",
"forbidden", "error" (see other values in
/usr/share/doc/sysv-rc/README.policy-rc.d.gz) or have there a simple
shellscript with the appropriate exit code.

That way would allow a per-service configuration of process start
behavior. The script handling the /etc/policy-rc.d/* file/scripts
could even be in a package (and I could finally retire the rather
trivial policyrcd-script-zg2).

Disclaimer: I do not know whether the new nice systemd world still
honors invoke-rc.d mechanisms. The scripts and documentation originate
from sysv-rc which is at least still present on my systemd-pid1-sid
systems, so there is hope.

Greetings
Marc

#804018#55
Date:
2015-11-19 12:43:04 UTC
From:
To:
Will this also work if a package does not come with a sysvinit init
script, or the sysvinit init script is overridden by a native systemd
unit?

Can a unit be masked before the corresponding package is installed?

That being said, this bug is only about preventing a service from
being started when the package is installed or updated. keepalived etc
do need to be able to start the service manually, which is also
prevented by systemd's mask mechanism.

I didn't think about that. One would need a mechanism to prevent this
as well since one probably doesn't want a keepalived-managed service
to be started on system boot.

Greetings
Marc

#804018#60
Date:
2015-11-19 19:02:01 UTC
From:
To:
Not in the same way. That's the deb-systemd-invoke code path, which
still respects policy-rc.d, but does not actually use invoke-rc.d to do it.

This case does use invoke-rc.d, which knows how to invoke the systemd
and/or Upstart bits that come with a sysvinit script.
/etc/systemd/system/whatever.service

This sounds as though in addition to policy-rc.d, you also want a way to
avoid enabling the init script (update-rc.d whatever disable, but
preferably something you can set up in advance like you can for masking).

For systemd-only services, a package maintainer can use
dh_enable_systemd --no-enable whatever.service (which will not enable it
on install, but will still disable it on purge), but I don't think
there's an API for sysadmins to make this happen.

For services with a sysvinit script, I don't think dh_installinit has an
equivalent of --no-enable for maintainers' use either.

    S

#804018#67
Date:
2018-02-15 09:24:31 UTC
From:
To:
Laba diena,


Noriu Jus informuoti apie šių metų pasikeitimą dėl atnaujintos visos Lietuvos įmonių bazės 2018 metų sausio vidurio.
Visi juridiniai asmenys pateikti bazėje yra veikiantys, realiai vykdantys veiklą, turintys įdarbintų darbuotojų. Duomenys pagal Sodrą, Registrų centrą.

Bazėje nurodoma ir apyvarta, darbuotojų atlyginimai, darbuotojų skaičius, transporto skaičius ir daug kitų duomenų, kuriuos matysite pavyzdyje.

Duomenis galima filtruoti pagal veiklas, miestus ir kitus duomenis.


Šią bazę verta turėti visoms įmonėms. Pateiksiu priežastis:

1) Kontaktai pateikti bazėje direktorių ir kitų atsakingų asmenų, didelė tikimybė Jums surasti naujų klientų, partnerių, tiekėjų, kai tiesiogiai bendrausite su direktoriais, komercijos vadovais.

2) Konkurentų analizavimas, tiekėjų atsirinkimas pagal Jums reikalingus kriterijus, galite atsifiltruoti pagal įmonės dydį, bazėje nurodoma kiek įmonės skolingos Sodrai.

3) Lengva, greita ir patogu dirbti su šia baze, elektroninius pašto adresus galite importuoti į elektroninių laiškų siuntimo programas ar sistemas iš kurių siunčiate elektroninius laiškus.
Taip pat galite importuoti mobiliųjų telefonų numerius į SMS siuntimo programas.


Išsirinkite iš "Veiklų sąrašo" veiklas kurių Jums reikia.
( Sąrašas prisegtas laiške excel faile )

Parašykite, kurias veiklas išsirinkote
ir atsiųsime pavyzdį ir pasiūlymą su sąlygomis įmonių bazei įsigyti



Pagarbiai,
Tadas Giedraitis
Tel. nr. +37067881041

#804018#70
Date:
2018-02-15 09:24:31 UTC
From:
To:
Laba diena,


Noriu Jus informuoti apie šių metų pasikeitimą dėl atnaujintos visos Lietuvos įmonių bazės 2018 metų sausio vidurio.
Visi juridiniai asmenys pateikti bazėje yra veikiantys, realiai vykdantys veiklą, turintys įdarbintų darbuotojų. Duomenys pagal Sodrą, Registrų centrą.

Bazėje nurodoma ir apyvarta, darbuotojų atlyginimai, darbuotojų skaičius, transporto skaičius ir daug kitų duomenų, kuriuos matysite pavyzdyje.

Duomenis galima filtruoti pagal veiklas, miestus ir kitus duomenis.


Šią bazę verta turėti visoms įmonėms. Pateiksiu priežastis:

1) Kontaktai pateikti bazėje direktorių ir kitų atsakingų asmenų, didelė tikimybė Jums surasti naujų klientų, partnerių, tiekėjų, kai tiesiogiai bendrausite su direktoriais, komercijos vadovais.

2) Konkurentų analizavimas, tiekėjų atsirinkimas pagal Jums reikalingus kriterijus, galite atsifiltruoti pagal įmonės dydį, bazėje nurodoma kiek įmonės skolingos Sodrai.

3) Lengva, greita ir patogu dirbti su šia baze, elektroninius pašto adresus galite importuoti į elektroninių laiškų siuntimo programas ar sistemas iš kurių siunčiate elektroninius laiškus.
Taip pat galite importuoti mobiliųjų telefonų numerius į SMS siuntimo programas.


Išsirinkite iš "Veiklų sąrašo" veiklas kurių Jums reikia.
( Sąrašas prisegtas laiške excel faile )

Parašykite, kurias veiklas išsirinkote
ir atsiųsime pavyzdį ir pasiūlymą su sąlygomis įmonių bazei įsigyti



Pagarbiai,
Tadas Giedraitis
Tel. nr. +37067881041

#804018#77
Date:
2018-07-25 04:11:15 UTC
From:
To:
This bug came up in the DC18 rolling policy sprint (ie, I overheard
Sean mentioning it).

ISTM that in days gone by this would have been (should have been) a
wishlist item for invoke-rc.d.  The interface was defined in
invoke-rc.d(8) and README.policy-rc.d.gz.  I am happy to fold
policyrcd-script-zg2 into init-system-helpers, if some would care to
submit a patch to do that.  Please do that as a separate bug.
Alternatively we could just let policyrcd-script-zg2 continue to
exist.

Nowadays, there is systemd too.  I have no idea whether
policyrcd-script-zg2 works with systemd.  If it doesn't then I guess a
more general interface ought to be defined.  That might plausibly be a
policy bug although it would probably be more sensible for people who
want this feature across different init systems to try to design that.

If systemd has a different way of achieving the same overall objective
then maybe the answer is just that the admin must configure this
differently depending on what init system they have.

I hope this analysis is helpful.

Thanks,
Ian.

#804018#82
Date:
2018-07-25 09:18:22 UTC
From:
To:
...
parallel systemd unit) run update-rc.d and invoke-rc.d in their postinst,
as they did before systemd. Packages that have only a systemd unit run
deb-systemd-helper and deb-systemd-invoke instead. Both invoke-rc.d and
deb-systemd-invoke run policy-rc.d to decide whether they should continue.
All of this now lives in the Essential init-system-helpers package, which
took over the init-agnostic scripts from sysvinit.

Some examples:
* LSB init script only: cpufrequtils, ikiwiki-hosting-web, sysfsutils
* Both: apt-cacher-ng, avahi-daemon, uuid-runtime, many more
* systemd only: quake4-server, systemd-cron

policyrcd-script-zg2 is an adapter between the invoke-rc.d-defined API
(which says the policy-rc.d script must be in /usr/sbin) and what that
API should maybe have been all along (additionally looking for the script
in a configurable location, /usr/local/sbin, and /etc).

The policy-rc.d interface seems to have at least two overall objectives,
which shouldn't necessarily be conflated.

Some sysadmins want to stick to the usual Debian setup in general
(services that are installed get started), but disable individual
services: for instance I have various game dedicated servers like
openarena-server installed, but I don't want them to run when my laptop
boots, only on-demand. policy-rc.d is inconvenient for this use-case
because there is only one policy-rc.d script, so the list of services to
run is centralized and written in an imperative rather than declarative
language (unless you write a local policy-rc.d implementation that reads
a ".d"-style configuration directory, but you're still responsible for
writing the script that pulls it all together, because no such script
is packaged).

Other sysadmins (particularly those working with chroots) want a more
Red-Hat-like setup where services are not, in general, started just
because they are installed (possibly with a whitelist of exceptions to
that general policy, which is what happens in Red Hat). policy-rc.d is
fine for this, although somewhat over-engineered for the common trivial
cases "start everything" and "start nothing". sbuild-createchroot is one
example of a tool that provides a policy-rc.d that doesn't start anything,
although this is somewhat obsoleted by the recent change that /sbin/init
is non-Essential and invoke-rc.d doesn't start services when there is
no /sbin/init.

systemd does have an equivalent of policy-rc.d ("presets",
systemd.preset(5)) with what I personally think is a better configuration
language (declarative files in a .d-style directory instead of a single
imperative script), but it isn't fully supported by Debian packages:
it looks as though deb-systemd-helper (the equivalent of update-rc.d
for systemd units with no LSB equivalent) does respect presets, but
update-rc.d itself does not.

The problem with systemd-specific interfaces (and sysv-rc-specific
interfaces, and other-init-specific interfaces) is that it's hard to
make them meet the goal that switching between init systems preserves
"enabledness". I suspect policy-rc.d is going to be the only "official
Debian" interface to this as long as that goal exists.

An implementation of policy-rc.d that reads systemd presets and applies
them to any Debian-supported init system might be an interesting way to
get declarative configuration for this, if full support for sysvinit
and init-system-switching continues to be a goal.

    smcv

#804018#87
Date:
2018-07-25 09:33:54 UTC
From:
To:
And I still think that the adapter should be superfluous and the
original API should be expanded.

Greetings
Marc

#804018#92
Date:
2018-07-25 15:09:35 UTC
From:
To:
Marc Haber writes ("Re: Bug#804018: options to avoid service startup on package installation"):

Right.

AIUI from what Simon says, there are two callers of
/usr/sbin/policy-rc.d.

There should be one implementation of the expanded interface.

I suggest a new script which implements it, in init-system-helpers,
called something like /usr/lib/policy-rc.d-invoke, and containing
something like the contentse of policyrcd-script-zg2.

We would then change invoke-rc.d and deb-systemd-* to run that script,
instead of /usr/sbin/policy-rc.d.  As an additional bonus, the new
script can run policy-rc.d from $PATH which would be more compliant
with Debian policy.

Does that sound sensible ?

Ian.

#804018#97
Date:
2018-07-27 08:13:52 UTC
From:
To:
control: reassign -1 init-system-helpers

Hello,

AFAICT the work to be done here is to expand a spec which already lives
in init-system-helpers, and improve some tooling which will live in
init-system-helpers.  So this bug should be reassigned to
init-system-helpers.

Thanks Ian for unsticking this bug.

#804018#104
Date:
2021-07-15 12:32:24 UTC
From:
To:
Am Fri, Jul 27, 2018 at 04:13:52PM +0800 schrieb Sean Whitton:

JFTR, this feature already exists natively in systemd in combination
with init-system-helpers. It's working fine in Bullseye, but doesn't in
Buster (not sure if there was an explicit bug fix which made it work):

Adding a /etc/systemd/system-preset/apache2.preset file with the content
"disable apache2.service" will correctly prevent the service from starting
upon installation. This works both for services with a native systemd unit
(like apache2), but also for services which ship a sysvinit script which
gets auto-translated to a systemd unit (e.g. nginx).

Cheers,
	 Moritz