API-Docker

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

    malformed status line, a bad `Content-Length` or a stray 1xx all croak
    `API::Docker::Error::Truncated` instead of being handed back as a whole
    response.
  - A status of 400 or above croaks `API::Docker::Error::HTTP` instead of a
    plain string, carrying `status`, `reason`, `body` and decoded `data`. It
    stringifies exactly as the old string croak did, so text-matching
    callers are unaffected.
  - `tls => 1` now speaks real TLS over `tcp://`. `cert_path` names the
    `docker` CLI's `ca.pem`/`cert.pem`/`key.pem` layout, `tls_insecure`
    turns verification off, and `tls` defaults from
    `$ENV{DOCKER_TLS_VERIFY}`. `IO::Socket::SSL` is a recommended
    dependency, loaded on the first TLS connection.
  - New `response => \%h` option fills `status`, `reason` and `headers`,
    including for a request that croaked. New `head` verb beside
    `get`/`post`/`put`/`delete_request`, which never waits for a body.
  - `negotiate_version` croaks, naming `GET /version` and the expected
    shape, when the body is not a JSON object carrying an `ApiVersion` of the
    form `N.N`.
  - New `API::Docker::Role::Filters`, consumed by all eight resource classes
    and applied at every `filters` call site: a bare value, a boolean or a
    mis-shaped filter is normalised to the engine's JSON map-of-arrays
    instead of silently matching nothing.
  - JSON request bodies send booleans as real `true`/`false`; a caller may
    pass `1`/`0` or a JSON boolean interchangeably.
  - `_uri_encode` UTF-8-encodes a decoded character string before
    percent-escaping, so a name or tag typed as characters (`ü`, `中`) goes
    out as valid UTF-8.
  - A request path outside the RFC 3986 origin-form character set is refused
    before it reaches the daemon, closing a request-line injection through a
    container name or image reference.
  - An ArrayRef query parameter expands into one repeated `k=v` pair per
    element (`names=a&names=b`), which some endpoints require.
  - A bare JSON scalar body (`null`, `true`, a number, a quoted string) is
    decoded rather than handed back as raw bytes; `raw` and `ndjson` return
    `''` and `[]` for a zero-byte body instead of `undef`.
  - Registry credentials reach `images->pull` (`auth`, sent as
    `X-Registry-Auth`) and `images->build` (`registry_config`, sent as
    `X-Registry-Config`), sent only when given. An already-base64 auth value
    in the standard alphabet is respelled URL-safe, which the engine
    requires.
  - `images->pull` no longer appends a default `tag` onto a reference that
    already carries a `:tag` or `@digest`.
  - New `images->get`, `->get_all` and `->load`: the image tar roundtrip in
    and out of a daemon without a registry. New `images->commit`
    (POST /commit) and `images->build_prune` (POST /build/prune, the
    BuildKit cache, a different store from the dangling images
    `images->prune` deletes).
  - New container endpoints: `get_archive`, `put_archive`, `stat_archive`
    (the `docker cp` primitives), `changes`, `export`, `resize` and the
    one-way half of `attach`. `attach` defaults to `stream => 0, logs => 1`
    (replay and return) and refuses a container that is not running unless
    `require_running => 0`.
  - `containers->start`/`stop`/`restart`/`pause`/`unpause` return 1 when the
    call changed the container's state and 0 when it was already in it (the
    engine answers a no-op with 304), instead of always undef.
  - `containers->stats` croaks `API::Docker::Error::HTTP` when Podman reports
    a failure inside a 200 response, instead of handing the error object back
    as a reading.
  - New `API::Docker::API::Plugins` (`$docker->plugins`): `list`,
    `privileges`, `install`, `inspect`, `remove`, `enable`, `disable`,
    `upgrade`, `push` and `configure`. Needs a real Docker daemon; Podman
    serves no `/plugins`.
  - New `API::Docker::API::Secrets` and `API::Docker::API::Configs`: `list`,
    `create`, `inspect`, `update` and `remove`. `Data` is base64-encoded for
    the caller; `update` takes the current `Version.Index` as a mandatory
    concurrency token.
  - New `API::Docker::API::System::auth` (POST /auth): check registry
    credentials without pulling or pushing. A rejected credential croaks.
  - New `API::Docker::API::Distribution` (`inspect`/`exists`,
    GET /distribution/{name}/json): ask a registry for a manifest without
    pulling. `exists` answers `1`/`0` and tells a registry's own 404 apart
    from an engine that serves no such route.
  - Declare a minimum Perl of 5.014 (`s///r` in `Role::HTTP`) and add the
    core modules `Errno`, `IO::Handle`, `Scalar::Util` and `Socket` to
    `cpanfile`. Stop shipping `spec/` and `maint/` in the built dist.
  - Swarm (`/swarm`, `/nodes`, `/services`, `/tasks`) is documented as a
    permanent scope decision, not a gap: Podman implements none of it and no
    consumer needs it. `secrets` and `configs` stand on their own and stay
    covered.

0.003     2026-08-27 03:37:00Z
  - t/containers.t: the registered cleanup tolerates the container the
    happy path already removed, so a live run no longer warns "Cleanup
    failed: ... no such container" on every pass. The safety net still
    warns on any other failure.
  - The `>= 400` croak now falls back to `errorDetail.message` and then to
    the flat `error` key when the JSON error body carries no `message`.
    Docker answers `{"message":...}`; Podman answers a failed push with
    the stream shape instead -- `{"errorDetail":{"message":...},"error":
    ...}` and no `message` at all -- so the whole JSON object used to be
    the croak text and the reason had to be dug out of it by eye. A body
    that is not an object still surfaces verbatim.
  - `images->build`, `->pull` and `->push` now croak when the engine
    reports a failure inside the event stream, instead of returning the
    stream and leaving the check to the caller. A failed build, pull or
    push is answered with HTTP 200 -- the status line is committed
    before the operation is attempted -- and the failure arrives as an
    `errorDetail` object among the progress events, so nothing about the
    response says the operation broke. Measured against the rootless
    Podman socket (5.4.2, API 1.41): a Dockerfile of `FROM alpine:3` /
    `RUN exit 7` answers `200 OK` and ends the stream with
    `{"errorDetail":{"message":"building at STEP \"RUN exit 7\": while
    running runtime: exit status 7\n"},"error":"..."}`, the flat `error`
    key carrying the same text. Callers that never scanned for it -- the
    documented shape until now -- reported a broken build as a success.
    The exception is an `API::Docker::Error::Stream`, a new class whose
    whole purpose is that the progress output is not lost with the
    return value: `$err->events` is the complete event list, error event
    included. It overloads stringification and produces exactly what the
    plain croak it replaces produced, reason plus Carp's ` at FILE line
    N.` suffix, so existing eval-and-inspect-$@ code needs no change;
    `$@ =~ s/...//` on it yields a plain string as it would for any
    overloaded object. The trigger is the `errorDetail` key alone, never
    the word "error" in payload text.
    Which of the three actually takes that route depends on the engine,
    and Podman is not Docker here -- measured on the same socket, all
    three cases: only `build` answers 200 with the failure in the
    stream. A pull of a missing repository answers `403 Forbidden` with
    `{"message":"denied: requested access to the resource is denied"}`,
    a missing tag answers `404 Not Found` with `{"message":"manifest
    unknown: manifest unknown"}`, and a push to an unreachable registry



( run in 0.859 second using v1.01-cache-2.11-cpan-aadc1410aed )