How can I prevent snapd from automatically starting every daemon of my snap on installation?
I’m currently working on a snap, which requires the user to connect some non-auto-connecting interfaces first before the snap’s daemons can start. Without these interfaces, the daemons fail to start.
Then, the installation of the snap will fail, because snapd still tries to start the daemon during installation:
error: cannot perform the following tasks:
Start snap “mysnap” (unset) services ([start snap.mysnap.myservice.service] failed with exit status 1: Job for snap.mysnap.myservice.service failed because the control process exited with error code.
See “systemctl status snap.mysnap.myservice.service” and “journalctl -xe” for details.
)
However, if the specified command exits with exit code 0, and the forked process exits with exit code 1, the installation does succeed.
Another version of test.sh:
#!/bin/bash
exit 1 &
exit 0
When using daemon: simple and a command that exits with exit code 1, the installation is also successful.
This I think is part of the issue, the order of things during snap installation is always:
run the install hook
start all non-disabled daemons
run the configure hook
So if you are trying to disable services in your configure hook, you’re too late as they would already have been started in 2.
The reason for this is from systemd, in that systemd considers a “simple” daemon to be done “starting” immediately after systemd starts the process, regardless of what happens, but for “forking” daemons, systemd waits for the daemon to actually fork a child process then waits for the parent process (i.e. the one that systemd forked initially) to exit with non-zero code. This also explains your point:
So yes all this behavior is expected. I do think we could probably do a better job at documenting how to order daemons with an example and perhaps some other examples of how the different daemon types are used and what systemd expects of them. @degville do you think that would be useful and/or do you already have something like that queued up?
We should definitely cover this because it’s both a good insight into how snapd is working with systemd, and a help for snap devs managing services. I’m obviously more than happy to do this - have you got a good example we could use @ijohnson?
I have several fake service examples that don’t really do anything, but the best example I have IRL is the edgexfoundry snap which is quite complicated and I don’t think we really want to get into all the gory details there… Let me look through my tests/examples and I’ll get back to you with what could be used for such a doc.
All right, now I get it. Thanks!
I used the configure hook because I wanted to run the script when installing the snap for the first time and when refreshing. I now understand that the right way to do this is by using the install and post-refresh hooks, not the configure hook. This is for a private snap of mine. I know that in a regular snap, disabling services on each refresh does not sound like a good idea.
@degville I think adding some information about how to disable autostart for services to the Services and daemons documentation page would also be helpful.
The page could also mention that services always run as root. I’ve read this on a different page but repeating it couldn’t hurt.