I have a snap with a service that will fail to start when initially installed due to needing credentials the user will supply via a config hook (invoked as
snap set snap-name certs=...) after being installed. Thus, I want to have the daemon not attempt to be started at all upon install, as the service will immediately fail and then prevent installation of the snap.
I was told a trick to handle this was to disable the service in the
install hook using
snapctl stop --disable SERVICE, but trying this out it doesn’t seem to work as intended, and looking at the code, I’m not sure if that’s by design or not. My understanding of the flow is this:
- snap gets mounted, setup
- install hook is run; snapctl stops service via calling systemd and puts the service into disabled state so that it’s not autostarted
- snap services are started,
systemctl start SERVICE_NAMEis called, which ignores the fact that the service was disabled.
Specifically, I’m looking at the code for snapd and see that when installing a snap the following tasks are run:
The install hook is run here: https://github.com/snapcore/snapd/blob/master/overlord/snapstate/snapstate.go#L223
Then the snap services are unconditionally started here: https://github.com/snapcore/snapd/blob/master/overlord/snapstate/snapstate.go#L231, which in effect calls
systemd start here: https://github.com/snapcore/snapd/blob/master/wrappers/services.go#L163
I would propose that we have a check in the
start-snap-services task that checks if the service is disabled (i.e. by the install hook), and if it is not to start it. It seems unintuitive for a service that was disabled to be “auto-started” by snapd during installation.
I could attempt to fix this, probably using the
Status method to check if it’s enabled or not during the
StartServices function during the loop, skipping services that are disabled: https://github.com/snapcore/snapd/blob/master/wrappers/services.go#L105.