Using snapctl in install hook to disable services

Hi,

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:

  1. snap gets mounted, setup
  2. install hook is run; snapctl stops service via calling systemd and puts the service into disabled state so that it’s not autostarted
  3. snap services are started, systemctl start SERVICE_NAME is 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 Systemd interface’s 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.

Thanks,
Ian

1 Like

I will check if we have a test exercising this feature and if it works as designed or if I mis-interpreted how that in any way and get back to you

1 Like

I hit this issue as well when I tried using forking services-- if the service happened to run into issues firing up, the installation failed. Non-forking services don’t seem to effect the installation process in this way.

I took a crack at fixing this, it works for me locally: https://github.com/snapcore/snapd/pull/5777

1 Like