Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] systemd lifecycle integration + tests #9

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

cbranch
Copy link
Collaborator

@cbranch cbranch commented Oct 2, 2024

This allows shellflip to be used directly in systemd's process lifecycle, instead of forking a process.

The lifecycle handler is the same as with the forking model, with two significant differences because systemd must stop the process before starting a new one:

  • Your process cannot allow tasks to drain for a significant period of time, as you cannot serve new connnections or tasks until the process has terminated.
  • The process writes data to a file instead of to the child process's pipe. This means the new process cannot signal that the written data is incorrect, so it is not possible to abort a restart.

Mitigations for these two limitations will be presented later. If these are not significant limitations for your usecase, e.g. because you can shutdown a process cleanly within a few seconds, or you test serialisation between versions thoroughly, then you can use this new method as-is.

In addition, we add long-awaited tests to assert the behaviour of the current and new operating modes.

WIP due to needing a change in sd-notify to support the systemd file descriptor store.

The lifecycle is only relevant within the restart task returned by
`try_into_restart_task`. It is not actually required in the config (e.g.
for the shutdown coordination signal). This lets us defer creating the
object used to handle lifecycle events later within the code.
Instead of forking the process and communicating with the child,
shellflip can communicate with systemd to send data in the 'old' process
and receive it in the 'new' process.

The restart can either be initiated through a Unix socket - in which case
the process and systemd unit file should agree on the exit code used to
restart the process - or by `systemctl restart`.

The process lifecycle is different when using systemd and its file
descriptor store. Systemd stops the process completely then spawns a new
one; old code does not stay running, unless you use the deprecated and
hated `KillMode=none` option.
This ensures that various kinds of restart and handover work as
intended. The test binary does very little except to check that data and
errors are passed as needed, and error conditions can be detected
through the notification socket.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant