Skip to content

info

info

Podman version and capability detection.

Parses podman info -f json into a structured PodmanInfo dataclass, with just enough metadata for shield to choose a network mode and decide whether per-container --hooks-dir will survive a restart.

This module is stateless — callers cache the result.

HOOKS_DIR_PERSIST_VERSION = (99, 0, 0) module-attribute

PodmanInfo(version, rootless_network_cmd, pasta_executable, slirp4netns_executable) dataclass

Parsed podman environment information.

Constructed from podman info -f json output. Stateless — the caller manages caching.

version instance-attribute

rootless_network_cmd instance-attribute

pasta_executable instance-attribute

slirp4netns_executable instance-attribute

hooks_dir_persists property

Return True if --hooks-dir survives container restart.

Currently always False — podman drops per-container hooks-dir on stop/start even on 5.8.0 (issues #121, #122). The version gate will be lowered when podman fixes this upstream.

network_mode property

Determine the rootless network mode.

Uses rootlessNetworkCmd when available (podman 5+). When absent (podman 4.x), defaults to slirp4netns if its executable is available — podman 4.x defaults to slirp4netns.

parse_podman_info(json_str)

Parse podman info -f json output into a PodmanInfo.

Returns a zero-version fallback on invalid or partially-malformed input — every nested section is coerced through an isinstance(..., dict) guard so a scalar/list where a table is expected can never produce an AttributeError.

Source code in src/terok_shield/podman_info/info.py
def parse_podman_info(json_str: str) -> PodmanInfo:
    """Parse ``podman info -f json`` output into a [`PodmanInfo`][terok_shield.podman_info.info.PodmanInfo].

    Returns a zero-version fallback on invalid or partially-malformed input —
    every nested section is coerced through an ``isinstance(..., dict)``
    guard so a scalar/list where a table is expected can never produce
    an ``AttributeError``.
    """
    try:
        info = json.loads(json_str)
    except (json.JSONDecodeError, TypeError):
        info = None

    if not isinstance(info, dict):
        return PodmanInfo(
            version=(0,),
            rootless_network_cmd="",
            pasta_executable="",
            slirp4netns_executable="",
        )

    host = _as_dict(info.get("host"))
    version_section = _as_dict(info.get("version"))
    pasta = _as_dict(host.get("pasta"))
    slirp = _as_dict(host.get("slirp4netns"))

    return PodmanInfo(
        version=_parse_version(_as_str(version_section.get("Version"), "0")),
        rootless_network_cmd=_as_str(host.get("rootlessNetworkCmd")),
        pasta_executable=_as_str(pasta.get("executable")),
        slirp4netns_executable=_as_str(slirp.get("executable")),
    )