API-Docker

 view release on metacpan or  search on metacpan

lib/API/Docker/API/Images.pm  view on Meta::CPAN

=item * C<noprune> - Do not delete untagged parents

=back

=head2 search

    my $results = $images->search('nginx', limit => 25);

Search Docker Hub for images. Returns ArrayRef of search results.

Options:

=over

=item * C<limit> - Maximum number of results

=item * C<filters> - HashRef of filter name to ArrayRef of string values; the
engine accepts C<is-official>, C<is-automated> and C<stars> here. The boolean
ones want the string, C<< { 'is-official' => ['true'] } >>, and C<stars> a
number written as one -- L<API::Docker::Role::Filters> takes care of both and
croaks on a shape the daemon would refuse

=back

=head2 prune

    my $result = $images->prune(filters => { dangling => ['true'] });

Delete unused images. Returns hashref with C<ImagesDeleted> and C<SpaceReclaimed>.

Options:

=over

=item * C<filters> - HashRef of filter name to ArrayRef of string values; the
engine accepts C<dangling>, C<until> and C<label> here. Shape-checked and
normalised by L<API::Docker::Role::Filters>

=back

=head2 get

    use Path::Tiny;
    my $tar = $images->get('alpine:3');
    path('alpine.tar')->spew_raw($tar);

Export one image, and the history behind it, as a tar archive -- the endpoint
behind C<docker image save>. Together with L</load> it is the only way in or
out of a daemon that does not go through a registry.

B<The return value is raw bytes, not a decoded structure.> The engine answers
with the tar stream itself, and the transport is told to hand it back
untouched (C<< raw => 1 >>), so what arrives is byte for byte what the daemon
wrote. Write it with a binary-safe file handle -- C<< path(...)->spew_raw >>,
or C<binmode> on a handle of your own. Treating it as text corrupts it, and
nothing about the value announces that it is binary.

The archive holds one tarball per layer, a config JSON per image,
C<manifest.json> and C<repositories>. Measured against Podman 5.4.2 (API
1.41): the response is chunked with
C<< Content-Type: application/octet; charset=us-ascii >>, where Docker sends
C<application/x-tar> -- the transport looks at neither, so the difference does
not reach the caller. Exporting C<alpine:3> through this method produced bytes
md5-identical to what C<curl --unix-socket> wrote for the same request, all
8705536 of them, so the chunked reader is binary-clean.

An unknown image croaks. On the same engine that is C<404 Not Found> with
C<< {"message":"failed to find image ...: image not known"} >>.

=head2 Exporting without buffering the archive

The whole archive is buffered in memory before it is returned, so exporting a
large image costs its full size in RAM. Pass C<on_chunk> and the bytes are
handed over as they arrive instead, and nothing is kept:

    use Path::Tiny;
    my $out = path('alpine.tar')->openw_raw;
    my $summary = $images->get('alpine:3',
        on_chunk => sub { print {$out} $_[0] });
    close $out;

    $summary;   # { delivered => 266, stopped => 0 }

The units are whatever the transport read, not a fixed size: a chunk boundary
carries no meaning in a tar stream, and the only guarantee is that
concatenating them in order gives the same bytes the buffered call returns.
Write them to a binary-safe handle, exactly as for the buffered value.

Measured against Podman 5.4.2 (API 1.41): exporting C<alpine:3> this way
delivered its 8705536 bytes in 266 pieces, md5-identical to what the buffered
call returns for the same request, with no more than one piece held at a time.

With a callback the return value is the summary HashRef
C<< { delivered => N, stopped => 0|1 } >>, not the archive: C<delivered> is
how many pieces went to the callback, C<stopped> is 1 when the callback ended
the transfer. Stopping leaves a B<truncated> archive behind -- the export is
one tar stream, not a sequence of independent records -- so stop only to
abandon it. See
L<API::Docker::Role::HTTP/"Streaming a response as it arrives">.

Options:

=over

=item * C<on_chunk> - CodeRef called with each piece of the archive as it
arrives, instead of the whole thing being returned

=back

=head2 get_all

    my $tar = $images->get_all('alpine:3', 'registry:2');
    my $tar = $images->get_all([ 'alpine:3', 'registry:2' ]);

Export several images into one tar archive. Takes the names as a list or as a
single ArrayRef; at least one is required.

B<The return value is raw bytes>, exactly as for L</get> -- see there for what
that means for writing it out.

C<manifest.json> inside the archive carries one entry per image, so a single



( run in 1.709 second using v1.01-cache-2.11-cpan-5e09290becf )