Skip to content

Port the compose-to-podman-pod converter into compose2pod#1

Merged
lesnik512 merged 8 commits into
mainfrom
port-converter
Jul 3, 2026
Merged

Port the compose-to-podman-pod converter into compose2pod#1
lesnik512 merged 8 commits into
mainfrom
port-converter

Conversation

@lesnik512

Copy link
Copy Markdown
Member

Extracts the CI-proven compose-to-podman-pod converter (from the chats service prototype) into compose2pod, a standalone, dependency-free public package.

What it does

Converts a Docker Compose document into a POSIX sh script that runs the services as a single Podman pod — for CI/test environments where docker compose and podman kube play can't run: unprivileged runners with a read-only /proc/sys (netavark can't create bridge networks) and no systemd (podman healthchecks aren't scheduled). A single pod shares one netns (no bridge, no netavark), services talk over 127.0.0.1 via --add-host, and startup is health-gated by polling podman healthcheck run. The core is stdlib-only so it installs and runs in minimal images; YAML input is an optional [yaml] extra.

Supported compose subset

image/build, command, environment/env_file, short-form bind volumes, healthcheck (CMD/CMD-SHELL), depends_on (all conditions), network aliases. Anything outside the subset raises a clear UnsupportedComposeError; ports/restart/stdin_open/tty are ignored with a warning.

Included review fixes vs the prototype

  1. Non-dict input guard in validate (a null/scalar document raises cleanly instead of an AttributeError).
  2. start_period/retries are now passed through to podman run as --health-start-period/--health-retries; the health-wait budget stays fixed (deliberately not shortened to retries × interval, which would break a long start_period).
  3. Merged a duplicate constant into a single _CMD_MIN_LENGTH.
  4. Extracted emit_script's target branch into _emit_target.

Quality

  • 78 tests, 100% line coverage (enforced; branch is a diagnostic run). __main__.py omitted from coverage.
  • ruff select=ALL / ty / eof-fixer clean. Python 3.10–3.14 matrix.
  • Root layout, uv_build, just recipes, tag-driven PyPI Trusted Publishing — mirrors the modern-di conventions.
  • Built task-by-task with per-task spec+quality review and a whole-branch final review (verdict: ready to merge). Plan: docs/superpowers/plans/2026-07-03-compose2pod-extraction.md.

Follow-ups (not in this PR)

  • Harden the pod-cleanup trap's nested quoting for the library API path (emit_script with an arbitrary pod name); it's unreachable via the CLI, which validates pod names. Deserves its own change with a library-API test.
  • Before the first release tag: register the PyPI Trusted Publisher (project compose2pod, workflow release.yml, environment pypi).

lesnik512 added 8 commits July 3, 2026 19:40
Adds parsing module that validates compose documents against the supported subset,
including a non-dict guard that raises UnsupportedComposeError for non-mapping inputs.
Add compose2pod.cli (main, POD_NAME_PATTERN, JSON/YAML auto-detect via
--format), the python -m compose2pod entrypoint, and populate the
package __init__ with the public API (validate, emit_script,
EmitOptions, UnsupportedComposeError).

Omit the trivial __main__.py shim from coverage (it is exercised only
via subprocess in tests, which the parent coverage process can't
measure); this keeps the enforced gate at 100% line coverage without
enabling branch measurement.
@lesnik512 lesnik512 merged commit 287bb86 into main Jul 3, 2026
6 checks passed
@lesnik512 lesnik512 deleted the port-converter branch July 3, 2026 19:44
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