Improved handling of restarts ("run this on changes") #129

Closed
opened 2021-11-20 13:24:24 +00:00 by ungleich-gitea · 1 comment

Created by: matthijskooijman

In my manifest, I'm running into problems handling restarts of services after config files or installed binaries are changed. There's a few sides to this.

__config_file supports an --onchange option, which runs arbitrary commands when a config file changes. However, when multiple config files are involved in the same service, this has a number of problems:

  • The service is restarted once for every changed config file, which is suboptimal.
  • The service might not restart cleanly if not all the config files are installed / updated together.

No other types seem to have such an --onchange option. A lot of them do emit messages when they run / change things, but you cannot currently configure any handlers for them in the manifest directly AFAUI. Instead, you must define a new type "__restart_my_service" that checks the message list for any changed files or other relevant messages and restarts the service if any are found. Having such a specific type does not seem useful to me, and this also implies hardcoding the list of relevant messages, which you'd rather control from the manifest AFAICS.

Ideally, I could do something like:

__config_file /etc/foo.conf --on-change-message 'foo-restart'
__config_file /etc/foo-bar.conf --on-change-message 'foo-restart'
__systemd_restart_unit foo.service --on-message 'foo-restart'

This invented a __systemd_restart_unit to actually do the restart, something more generic could also work. There's two parts to such a solution:

  • Making sure that the restart only happens if needed. Above, --on-change-message is used to make the type emit a custom message, which is checked by __system_restart_unit to decide whether to run or not.
  • Making sure that the restart happens after all other types that could emit the foo-restart message. In the above example, this would either need CDIST_ORDER_DEPENDENCY, or explicitly naming all of them (or cdist must be extended to recognize this particular pattern).

If all dependencies are listed, you might consider introducing another dependency type in addition to the current require, which could handle both ordering and running only if neeed. E.g.:

__config_file /etc/foo.conf
__config_file /etc/foo-bar.conf
onlyif="__config_file/etc/foo.conf __config_file/etc/foo-bar.conf" __systemd_restart_unit foo.service

Here, the onlyif dependency says to only run if any of the mentioned dependencies ran, and implicitly to also run after all of the mentioned dependencies.

Perhaps you could reverse this:

activates="__systemd_restart_unit/foo.service" __config_file /etc/foo.conf
activates="__systemd_restart_unit/foo.service" __config_file /etc/foo-bar.conf
onlyifactivated=1 __systemd_restart_unit foo.service

Which is a bit more elegant, but might also be more complex to implement?

A message-based approach is probably more flexible than these dependency-based approaches, but also a bit more verbose...

I'm not quite sure what implementation would be best (I'm just guessing, the best approach is probably not listed here), but I'd like to see something to implement this usecase (unless something exists that I'm missing?).

I suspect this might tie in with #624 a little.

*Created by: matthijskooijman* In my manifest, I'm running into problems handling restarts of services after config files or installed binaries are changed. There's a few sides to this. `__config_file` supports an `--onchange` option, which runs arbitrary commands when a config file changes. However, when multiple config files are involved in the same service, this has a number of problems: - The service is restarted once for every changed config file, which is suboptimal. - The service might not restart cleanly if not all the config files are installed / updated together. No other types seem to have such an `--onchange` option. A lot of them do emit messages when they run / change things, but you cannot currently configure any handlers for them in the manifest directly AFAUI. Instead, you must define a new type "__restart_my_service" that checks the message list for any changed files or other relevant messages and restarts the service if any are found. Having such a specific type does not seem useful to me, and this also implies hardcoding the list of relevant messages, which you'd rather control from the manifest AFAICS. Ideally, I could do something like: ``` __config_file /etc/foo.conf --on-change-message 'foo-restart' __config_file /etc/foo-bar.conf --on-change-message 'foo-restart' __systemd_restart_unit foo.service --on-message 'foo-restart' ``` This invented a `__systemd_restart_unit` to actually do the restart, something more generic could also work. There's two parts to such a solution: - Making sure that the restart only happens if needed. Above, `--on-change-message` is used to make the type emit a custom message, which is checked by `__system_restart_unit` to decide whether to run or not. - Making sure that the restart happens *after* all other types that could emit the `foo-restart` message. In the above example, this would either need `CDIST_ORDER_DEPENDENCY`, or explicitly naming all of them (or cdist must be extended to recognize this particular pattern). If all dependencies are listed, you might consider introducing another dependency type in addition to the current `require`, which could handle both ordering and running only if neeed. E.g.: ``` __config_file /etc/foo.conf __config_file /etc/foo-bar.conf onlyif="__config_file/etc/foo.conf __config_file/etc/foo-bar.conf" __systemd_restart_unit foo.service ``` Here, the `onlyif` dependency says to only run if any of the mentioned dependencies ran, and implicitly to also run after all of the mentioned dependencies. Perhaps you could reverse this: ``` activates="__systemd_restart_unit/foo.service" __config_file /etc/foo.conf activates="__systemd_restart_unit/foo.service" __config_file /etc/foo-bar.conf onlyifactivated=1 __systemd_restart_unit foo.service ``` Which is a bit more elegant, but might also be more complex to implement? A message-based approach is probably more flexible than these dependency-based approaches, but also a bit more verbose... I'm not quite sure what implementation would be best (I'm just guessing, the best approach is probably not listed here), but I'd like to see something to implement this usecase (unless something exists that I'm missing?). I suspect this might tie in with #624 a little.
ungleich-gitea added the
Stale
label 2021-11-20 13:24:24 +00:00
Author
Owner

closed

closed
Sign in to join this conversation.
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: ungleich-public/cdist#129
No description provided.