Files
computer-playbook/plugins/lookup/compose_restart.py
T
kevinveenbirkenbachandClaude Opus 4.8 fc398084f9 fix(compose_restart): quote the restart policy scalar
Bare policies like no/off render as 'restart: no' which YAML parses as a boolean, so 'docker compose config' rejects the file. Quote the scalar ('restart: "no"') to keep it a string.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 04:35:15 +02:00

71 lines
2.4 KiB
Python

"""Lookup `compose_restart`: emit `restart: <policy>` only in compose mode.
In swarm mode the `restart:` top-level service key is silently ignored
because swarm replaces it with `deploy.restart_policy` (rendered by
`roles/sys-svc-container/templates/deploy.yml.j2`). Emitting `restart:`
under swarm produces an "Ignoring unsupported options" warning at
`docker stack deploy` time and double-declares the intent.
Default call site:
{{ lookup('compose_restart') }}
resolves to the global `DOCKER_RESTART_POLICY` from
`group_vars/all/00_general.yml`. That covers every caller whose intent
is "use the operator-wide default policy".
When a template needs a per-call override (either via Jinja-scope
``{% set docker_restart_policy = '...' %}`` or a hardcoded literal),
the caller passes the policy explicitly:
{{ lookup('compose_restart', docker_restart_policy | default(DOCKER_RESTART_POLICY)) }}
{{ lookup('compose_restart', 'on-failure') }}
The override path lives at the caller because Jinja-scope `{% set %}`
bindings are visible only in the rendering template, never in the
Ansible variable context that the lookup sees.
"""
from __future__ import annotations
import contextlib
from typing import Any
from ansible.errors import AnsibleError
from ansible.plugins.lookup import LookupBase
_DEFAULT_POLICY = "unless-stopped"
class LookupModule(LookupBase):
def run(
self,
terms: list[Any] | None,
variables: dict[str, Any] | None = None,
**kwargs: Any,
) -> list[str]:
if terms and len(terms) > 1:
raise AnsibleError(
"compose_restart lookup accepts at most one term: an explicit policy override"
)
vars_ = variables or getattr(self._templar, "available_variables", {}) or {}
raw_mode = vars_.get("DEPLOYMENT_MODE", "compose")
templar = getattr(self, "_templar", None)
if templar is not None:
with contextlib.suppress(Exception):
raw_mode = templar.template(raw_mode)
if str(raw_mode).strip() == "swarm":
return [""]
if terms:
policy = terms[0]
else:
policy = vars_.get("DOCKER_RESTART_POLICY", _DEFAULT_POLICY)
if templar is not None:
with contextlib.suppress(Exception):
policy = templar.template(policy)
return [f'restart: "{policy}"']