Skip to main content
Welcome. This site supports keyboard navigation and screen readers. Press ? at any time for keyboard shortcuts. Press [ to focus the sidebar, ] to focus the content. High-contrast themes are available via the toolbar.
serard@dev00:~/cv

PodmanCompose: From Versioned Inputs to Typed Observations

Podman Compose is a Python orchestration layer around container commands. It does not provide a universal machine-event bus with the same semantics as Docker Compose.

The integration recognizes reviewed Python logging, orchestration shapes, version output and service lines while preserving arbitrary application text.

Acquisition and generated commands

The Design program discovers containers/podman-compose releases, builds version images for the Python package and uses an argparse help strategy. Its collection minimum defaults to 1.0.0.

The live pipeline uses version images and containers; replay uses cached help. Declared variables from PodmanComposeEnvironmentCatalog configure the runner.

Commands and environment records belong to Contracts. Builders/client and concrete output implementations remain in the implementation project. The executable name is podman-compose.

A complete service-output example

This offline example constructs a generated up command and feeds a service line plus a Python warning to the parser. It starts no services.

using FrenchExDev.Net.BinaryWrapper;
using FrenchExDev.Net.BinaryWrapper.Lib;
using FrenchExDev.Net.BinaryWrapper.Testing;
using FrenchExDev.Net.PodmanCompose;

var binding = new BinaryBinding
{
    Identifier = new BinaryIdentifier("podman-compose"),
    ExecutablePath = "unused",
    DetectedVersion = SemanticVersion.Parse("1.5.0"),
};
var command = await PodmanCompose.Create(binding).UpAsync(builder => builder
    .WithDetach(false)
    .WithEnvironment(new PodmanComposeEnvironment { ProjectName = "example" }));
var executor = new CommandExecutor(new DictionaryBinaryResolver(binding),
    new FakeProcessRunner([
        new OutputLine("[web] | listening", OutputSource.StdOut),
        new OutputLine(
            "WARNING:podman_compose:example diagnostic", OutputSource.StdErr),
    ]));
await foreach (var evt in executor.StreamAsync(
    binding.Identifier, command, PodmanComposeOutputStrategies.Default))
{
    if (evt is PodmanComposeServiceOutput service)
        Console.WriteLine($"{service.Service}: {service.Message}");
    if (evt.OutputLine is { } original)
        Console.WriteLine($"{original.Source}: {original.Text}");
    if (evt is PodmanComposeCommandExited exited)
        Console.WriteLine($"Compose CLI exit: {exited.ExitCode}");
}

The service message is retained as application output. “listening” is not promoted to a reviewed application-health fact. The actual exit arrives through the runner's terminal event.

Source-shaped Python observations

The reviewed source pin is 1.5.0 at f7eeda1a3db10952424af6a5b0501c269ebe3f0d. Its inventory identifies logging/print sites, including dynamic payloads that do not justify dedicated semantic events.

The parser can expose log level, logger identity and rendered message. Reviewed task/phase shapes describe scheduling, dependency waiting, skipped container work, missing services, unused networks and shutdown reports.

PodmanComposeContainerTaskStarted reports scheduling. It does not prove the container became ready. PodmanComposeSubprocessExited reports an internal child command; PodmanComposeCommandExited reports the overall Python CLI process.

Channel context and upstream information loss

Python diagnostics are recognized in their expected stderr context with reviewed logger names and levels. A familiar warning string on stdout is not necessarily a Python logger observation.

Service formatting removes ANSI color only from decoded fields. OutputLine preserves the original logical text and channel, including colors.

The upstream wrapper can route both guest stdout and guest stderr through its own stdout. BinaryWrapper cannot recover the original guest channel afterward. Document the observed boundary accurately rather than marking every service warning as stdout-originating application behavior.

Version output is command-specific

The default strategy enables tool-version decoding for the generated version command. A service printing {"version":"..."} during up does not become PodmanComposeVersionObserved.

This guard illustrates a general rule: syntax alone is insufficient. The invocation context establishes whether a JSON shape belongs to the tool or to arbitrary application output.

Environment and backend policy

The catalogue includes project name/directory, compose files, path separators, parallel limits and backend/configuration settings. Values are generated with explicit assignment state and tool-specific converters.

PodmanComposeEnvironment configures the Python process. It is distinct from environment declarations in a service's Compose model.

Backend versions can evolve independently of the Python package. Selecting a reviewed podman-compose profile does not select or certify every Podman executable invoked beneath it.

Profiles and limits

The built-in interval is [1.5.0, 1.5.1-0). Other versions preserve raw observations and terminal status.

The default Python log level is WARN. Task/debug observations usually require verbose mode, so absence of a debug milestone cannot prove the operation was skipped. Unknown logging calls and arbitrary service output remain available generically.

There is no inferred container-readiness guarantee from a “started” phase or dependency log. Container-state queries or application probes are separate sources of evidence.

Validation

Tests cover service formatting and colors, logger/channel guards, source-derived phase parameters, child versus parent exits, command-specific version JSON, profiles, fresh state and fallback.

These tests use recorded/source-shaped output rather than asserting that every Python logging site has a unique semantic interpretation. Compare Docker Compose for a different output model under a similar orchestration role.

Source snapshot

Source inspection: 2 October 2026. These implementation paths are relative to Net/FrenchExDev in the local ecosystem checkout. The v2 changes are largely uncommitted; these paths identify inspected code, without claiming that public branch links contain it.

  • PodmanCompose/src/FrenchExDev.Net.PodmanCompose.Design/Program.cs
  • PodmanCompose/src/FrenchExDev.Net.PodmanCompose.Contracts/FrenchExDev.Net.PodmanCompose.Contracts.csproj
  • PodmanCompose/src/FrenchExDev.Net.PodmanCompose/FrenchExDev.Net.PodmanCompose.csproj
  • PodmanCompose/doc/TYPED-OUTPUT.md
  • PodmanCompose/test/FrenchExDev.Net.PodmanCompose.Tests

Previous: Podman · Implementation index · Series index · Next: GitLab.Cli

⬇ Download