I ran into an interesting issue tonight, and was curious if this is something we’ve considered.
I’m using the configure hook for a port number on which my snap listens. It defaults to 80, but one can change it with e.g. snap set mysnap port=81.
The piece of software listening on port 80 must be restarted in order for that new configuration to take effect. Since snaps don’t have access to systemctl, my solution has been to set services to restart-condition: always and then simply kill the daemon itself, relying on systemd to bring it back up.
The problem is, doing this in the configure hook causes a race condition. When the daemon comes back up, it determines the port it’s supposed to use using snapctl get port. But if systemd happens to bring it back up before the configure hook has exited successfully, since the configuration change happens in a transaction, the change hasn’t actually taken place yet, and the daemon comes back up with the old port.
How should I be restarting services in the configure hook to account for this? As far as I’m aware, even the ability to restart services via snapctl won’t solve this issue. Thoughts? The solution I’m currently working on is implementing a lock that will be checked by my services, but that seems a bit heavy.
Taking a queue from ansible’s handlers, it could be slick to queue up service restarts and only run them after the hook has completed. I suppose that would be implemented in snapctl as part of the services work.