Skip to content

Commit

Permalink
batou_ext.oci: Add support for podman
Browse files Browse the repository at this point in the history
FC-37959

We mostly want this for healthchecks that must pass before the unit is
actually active.
  • Loading branch information
Ma27 committed Nov 29, 2024
1 parent 1679d98 commit d83ac63
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 6 deletions.
13 changes: 13 additions & 0 deletions CHANGES.d/20241129_131748_mb_FC_37959_podman.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
- `batou_ext.oci.Container`: allow to use `podman` as backend instead of `docker`.
This also enables the following features:

* Rootless containers: by setting the `user` option to a different user. By default,
the service user of the deployment is used.

* Only mark services as `active` if the container is up. Which metric is used
for that can be configured using the `sd_notify` option:

* `container`: the `sd_notify(3)` call must be sent from inside the container.
* `healthy`: if the container's health check(s) are green.
* `conmon`: if the container is up (but not necessarily the service in it).
* `ignore`: just mark the unit as `active`.
30 changes: 29 additions & 1 deletion src/batou_ext/oci.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ class Container(Component):
image = Attribute(str)
version: str = "latest"
container_name = Attribute(str)
backend = Attribute(str, "docker")

sd_notify = Attribute(str, None)
user = Attribute(str, None)

# Set up monitoring
monitor: bool = True
Expand All @@ -95,7 +99,7 @@ class Container(Component):
ports: dict = {}
env: dict = {}
depends_on: list = None
extra_options: list = None
extra_options: list = []

# secrets
registry_address = Attribute(Optional[str], None)
Expand All @@ -108,6 +112,11 @@ class Container(Component):
}

def configure(self):
if self.backend not in ["docker", "podman"]:
raise ValueError(
f"Unsupported backend '{self.backend}' for container '{self.container_name}' (allowed: docker, podman)!"
)

if (
self.registry_user or self.registry_password
) and not self.registry_address:
Expand Down Expand Up @@ -145,6 +154,25 @@ def configure(self):
if self.docker_cmd:
self._docker_cmd_list = shlex.split(self.docker_cmd)

if self.backend != "podman":
assert (
self.sd_notify is None
), f"Container '{self.container_name}' runs with Docker, so the sd_notify option is not supported!"
assert (
self.user is None
), f"Container '{self.container_name}' runs with Docker, so the user option is not supported!"
elif self.sd_notify is not None:
assert self.sd_notify in [
"container",
"conmon",
"healthy",
"ignore",
], f"Container '{self.container_name}' set invalid value for 'sd_notify'. Allowed values: container, conmon, healthy, ignore!"
self.extra_options.append(f"--sdnotify={self.sd_notify}")

if self.backend == "podman" and self.user is None:
self.user = self.host.service_user

if not self.depends_on:
self.depends_on = []

Expand Down
26 changes: 21 additions & 5 deletions src/batou_ext/resources/oci-template.nix
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,26 @@
{
# {% if component.monitor %}
flyingcircus = {
services.sensu-client.checks."docker-{{component.container_name}}" = {
services.sensu-client.checks."{{ component.backend }}-{{component.container_name}}" = {
notification = "Status of container {{component.container_name}}";
command = ''
if $(systemctl is-active --quiet docker-{{component.container_name}}); then
echo "docker container {{component.container_name}} is ok"
if $(systemctl is-active --quiet {{ component.backend }}-{{component.container_name}}); then
echo "{{ component.backend }} container {{component.container_name}} is ok"
else
echo "docker container {{component.container_name}} is inactive"
echo "{{ component.backend }} container {{component.container_name}} is inactive"
exit 2
fi
'';
};
};
# {% endif %}

# {% if component.backend == "podman" %}
virtualisation.podman.enable = true;
# {% endif %}

virtualisation.oci-containers = {
backend = "docker";
backend = "{{ component.backend }}";
containers."{{component.container_name}}" = {
# {% if component.entrypoint %}
entrypoint = "{{component.entrypoint}}";
Expand All @@ -40,6 +44,9 @@

extraOptions = [
"--pull=always"
# {% if component.backend == "podman" %}
"--cidfile=/run/{{component.container_name}}/ctr-id"
# {% endif %}
# {% for option in (component.extra_options or []) %}
"{{option}}"
# {% endfor %}
Expand Down Expand Up @@ -68,4 +75,13 @@
];
};
};

# {% if component.backend == "podman" %}
systemd.services.podman-lalala.serviceConfig = {
User = "{{ component.user }}";
RuntimeDirectory = "{{component.container_name}}";
Delegate = true;
NotifyAccess = "all";
};
# {% endif %}
}

0 comments on commit d83ac63

Please sign in to comment.