File Coverage

blib/lib/WWW/Docker/API/Images.pm
Criterion Covered Total %
statement 81 94 86.1
branch 39 94 41.4
condition 2 4 50.0
subroutine 14 16 87.5
pod 3 10 30.0
total 139 218 63.7


line stmt bran cond sub pod time code
1             package WWW::Docker::API::Images;
2             # ABSTRACT: Docker Engine Images API
3              
4 10     10   64 use Moo;
  10         23  
  10         65  
5 10     10   8934 use WWW::Docker::Image;
  10         37  
  10         453  
6 10     10   74 use Carp qw( croak );
  10         19  
  10         722  
7 10     10   58 use namespace::clean;
  10         21  
  10         76  
8              
9             our $VERSION = '0.101';
10              
11             =head1 SYNOPSIS
12              
13             my $docker = WWW::Docker->new;
14              
15             # Build an image from a tar context
16             use Path::Tiny;
17             my $tar = path('context.tar')->slurp_raw;
18             $docker->images->build(context => $tar, t => 'myapp:latest');
19              
20             # Pull an image
21             $docker->images->pull(fromImage => 'nginx', tag => 'latest');
22              
23             # List images
24             my $images = $docker->images->list;
25             for my $image (@$images) {
26             say $image->Id;
27             say join ', ', @{$image->RepoTags};
28             }
29              
30             # Inspect image details
31             my $image = $docker->images->inspect('nginx:latest');
32              
33             # Tag and push
34             $docker->images->tag('nginx:latest', repo => 'myrepo/nginx', tag => 'v1');
35             $docker->images->push('myrepo/nginx', tag => 'v1');
36              
37             # Remove image
38             $docker->images->remove('nginx:latest', force => 1);
39              
40             =head1 DESCRIPTION
41              
42             This module provides methods for managing Docker images including pulling,
43             listing, tagging, pushing to registries, and removal.
44              
45             All C and C methods return L objects.
46              
47             Accessed via C<< $docker->images >>.
48              
49             =cut
50              
51             has client => (
52             is => 'ro',
53             required => 1,
54             weak_ref => 1,
55             );
56              
57             =attr client
58              
59             Reference to L client. Weak reference to avoid circular dependencies.
60              
61             =cut
62              
63             sub _wrap {
64 3     3   6 my ($self, $data) = @_;
65 3         86 return WWW::Docker::Image->new(
66             client => $self->client,
67             %$data,
68             );
69             }
70              
71             sub _wrap_list {
72 1     1   4 my ($self, $list) = @_;
73 1         3 return [ map { $self->_wrap($_) } @$list ];
  2         2939  
74             }
75              
76             sub list {
77 1     1 0 1460 my ($self, %opts) = @_;
78 1         3 my %params;
79 1 0       7 $params{all} = $opts{all} ? 1 : 0 if defined $opts{all};
    50          
80 1 0       5 $params{digests} = $opts{digests} ? 1 : 0 if defined $opts{digests};
    50          
81 1 50       4 $params{filters} = $opts{filters} if defined $opts{filters};
82 1         15 my $result = $self->client->get('/images/json', params => \%params);
83 1   50     27 return $self->_wrap_list($result // []);
84             }
85              
86             =method list
87              
88             my $images = $images->list(all => 1);
89              
90             List images. Returns ArrayRef of L objects.
91              
92             Options:
93              
94             =over
95              
96             =item * C - Show all images (default hides intermediate images)
97              
98             =item * C - Include digest information
99              
100             =item * C - Hashref of filters
101              
102             =back
103              
104             =cut
105              
106             sub build {
107 2     2 1 76 my ($self, %opts) = @_;
108 2         10 my $context = delete $opts{context};
109 2 100       287 croak "Build context required (tar archive as scalar ref or raw bytes)" unless defined $context;
110              
111 1         3 my %params;
112 1 50       7 $params{dockerfile} = $opts{dockerfile} if defined $opts{dockerfile};
113 1 50       7 $params{t} = $opts{t} if defined $opts{t};
114 1 0       5 $params{q} = $opts{q} ? 1 : 0 if defined $opts{q};
    50          
115 1 0       4 $params{nocache} = $opts{nocache} ? 1 : 0 if defined $opts{nocache};
    50          
116 1 50       5 $params{pull} = $opts{pull} if defined $opts{pull};
117 1 0       5 $params{rm} = defined $opts{rm} ? ($opts{rm} ? 1 : 0) : 1;
    50          
118 1 0       5 $params{forcerm} = $opts{forcerm} ? 1 : 0 if defined $opts{forcerm};
    50          
119 1 50       5 $params{memory} = $opts{memory} if defined $opts{memory};
120 1 50       4 $params{memswap} = $opts{memswap} if defined $opts{memswap};
121 1 50       3 $params{cpushares} = $opts{cpushares} if defined $opts{cpushares};
122 1 50       4 $params{cpusetcpus} = $opts{cpusetcpus} if defined $opts{cpusetcpus};
123 1 50       4 $params{cpuperiod} = $opts{cpuperiod} if defined $opts{cpuperiod};
124 1 50       4 $params{cpuquota} = $opts{cpuquota} if defined $opts{cpuquota};
125 1 50       4 $params{shmsize} = $opts{shmsize} if defined $opts{shmsize};
126 1 50       7 $params{networkmode} = $opts{networkmode} if defined $opts{networkmode};
127 1 50       5 $params{platform} = $opts{platform} if defined $opts{platform};
128 1 50       4 $params{target} = $opts{target} if defined $opts{target};
129              
130 1 50       4 if ($opts{buildargs}) {
131 0         0 require JSON::MaybeXS;
132 0         0 $params{buildargs} = JSON::MaybeXS::encode_json($opts{buildargs});
133             }
134 1 50       5 if ($opts{labels}) {
135 0         0 require JSON::MaybeXS;
136 0         0 $params{labels} = JSON::MaybeXS::encode_json($opts{labels});
137             }
138              
139 1 50       71 my $raw = ref $context eq 'SCALAR' ? $$context : $context;
140              
141 1         12 return $self->client->_request('POST', '/build',
142             raw_body => $raw,
143             content_type => 'application/x-tar',
144             params => \%params,
145             );
146             }
147              
148             =method build
149              
150             # Build from a tar archive
151             my $tar_data = path('context.tar')->slurp_raw;
152             my $result = $docker->images->build(
153             context => $tar_data,
154             t => 'myimage:latest',
155             dockerfile => 'Dockerfile',
156             );
157              
158             # Build with build args
159             my $result = $docker->images->build(
160             context => $tar_data,
161             t => 'myapp:v1',
162             buildargs => { APP_VERSION => '1.0' },
163             nocache => 1,
164             );
165              
166             Build an image from a tar archive containing a Dockerfile and build context.
167              
168             The C parameter is required and must contain the raw bytes of a tar
169             archive (or a scalar reference to one).
170              
171             Options:
172              
173             =over
174              
175             =item * C - Tar archive bytes (required)
176              
177             =item * C - Path to Dockerfile within the archive (default: C)
178              
179             =item * C - Tag for the image (e.g. C)
180              
181             =item * C - Suppress verbose build output
182              
183             =item * C - Do not use cache when building
184              
185             =item * C - Always pull base image
186              
187             =item * C - Remove intermediate containers (default: true)
188              
189             =item * C - Always remove intermediate containers
190              
191             =item * C - HashRef of build-time variables
192              
193             =item * C - HashRef of labels to set on the image
194              
195             =item * C - Memory limit in bytes
196              
197             =item * C - Total memory (memory + swap), -1 to disable swap
198              
199             =item * C - CPU shares (relative weight)
200              
201             =item * C - CPUs to use (e.g. C<0-3>, C<0,1>)
202              
203             =item * C - CPU CFS period (microseconds)
204              
205             =item * C - CPU CFS quota (microseconds)
206              
207             =item * C - Size of /dev/shm in bytes
208              
209             =item * C - Network mode during build
210              
211             =item * C - Platform (e.g. C)
212              
213             =item * C - Multi-stage build target
214              
215             =back
216              
217             =cut
218              
219             sub pull {
220 1     1 1 3385 my ($self, %opts) = @_;
221 1 50       6 croak "fromImage required" unless $opts{fromImage};
222 1         3 my %params;
223 1         4 $params{fromImage} = $opts{fromImage};
224 1   50     5 $params{tag} = $opts{tag} // 'latest';
225 1         18 return $self->client->post('/images/create', undef, params => \%params);
226             }
227              
228             =method pull
229              
230             $images->pull(fromImage => 'nginx', tag => 'latest');
231              
232             Pull an image from a registry. C defaults to C.
233              
234             =cut
235              
236             sub inspect {
237 2     2 0 73 my ($self, $name) = @_;
238 2 100       186 croak "Image name required" unless $name;
239 1         14 my $result = $self->client->get("/images/$name/json");
240 1         24 return $self->_wrap($result);
241             }
242              
243             =method inspect
244              
245             my $image = $images->inspect('nginx:latest');
246              
247             Get detailed information about an image. Returns L object.
248              
249             =cut
250              
251             sub history {
252 1     1 0 37 my ($self, $name) = @_;
253 1 50       5 croak "Image name required" unless $name;
254 1         15 return $self->client->get("/images/$name/history");
255             }
256              
257             =method history
258              
259             my $history = $images->history('nginx:latest');
260              
261             Get image history (layers). Returns ArrayRef of layer information.
262              
263             =cut
264              
265             sub push {
266 0     0 0 0 my ($self, $name, %opts) = @_;
267 0 0       0 croak "Image name required" unless $name;
268 0         0 my %params;
269 0 0       0 $params{tag} = $opts{tag} if defined $opts{tag};
270 0         0 return $self->client->post("/images/$name/push", undef, params => \%params);
271             }
272              
273             =method push
274              
275             $images->push('myrepo/nginx', tag => 'v1');
276              
277             Push an image to a registry. Optionally specify C.
278              
279             =cut
280              
281             sub tag {
282 1     1 0 628 my ($self, $name, %opts) = @_;
283 1 50       6 croak "Image name required" unless $name;
284 1         2 my %params;
285 1 50       7 $params{repo} = $opts{repo} if defined $opts{repo};
286 1 50       4 $params{tag} = $opts{tag} if defined $opts{tag};
287 1         9 return $self->client->post("/images/$name/tag", undef, params => \%params);
288             }
289              
290             =method tag
291              
292             $images->tag('nginx:latest', repo => 'myrepo/nginx', tag => 'v1');
293              
294             Tag an image with a new repository and/or tag name.
295              
296             =cut
297              
298             sub remove {
299 2     2 1 1781 my ($self, $name, %opts) = @_;
300 2 100       159 croak "Image name required" unless $name;
301 1         3 my %params;
302 1 0       4 $params{force} = $opts{force} ? 1 : 0 if defined $opts{force};
    50          
303 1 0       4 $params{noprune} = $opts{noprune} ? 1 : 0 if defined $opts{noprune};
    50          
304 1         29 return $self->client->delete_request("/images/$name", params => \%params);
305             }
306              
307             =method remove
308              
309             $images->remove('nginx:latest', force => 1);
310              
311             Remove an image.
312              
313             Options:
314              
315             =over
316              
317             =item * C - Force removal
318              
319             =item * C - Do not delete untagged parents
320              
321             =back
322              
323             =cut
324              
325             sub search {
326 1     1 0 38 my ($self, $term, %opts) = @_;
327 1 50       6 croak "Search term required" unless $term;
328 1         3 my %params;
329 1         4 $params{term} = $term;
330 1 50       5 $params{limit} = $opts{limit} if defined $opts{limit};
331 1 50       5 $params{filters} = $opts{filters} if defined $opts{filters};
332 1         13 return $self->client->get('/images/search', params => \%params);
333             }
334              
335             =method search
336              
337             my $results = $images->search('nginx', limit => 25);
338              
339             Search Docker Hub for images. Returns ArrayRef of search results.
340              
341             Options: C, C.
342              
343             =cut
344              
345             sub prune {
346 0     0 0   my ($self, %opts) = @_;
347 0           my %params;
348 0 0         $params{filters} = $opts{filters} if defined $opts{filters};
349 0           return $self->client->post('/images/prune', undef, params => \%params);
350             }
351              
352             =method prune
353              
354             my $result = $images->prune(filters => { dangling => ['true'] });
355              
356             Delete unused images. Returns hashref with C and C.
357              
358             =cut
359              
360             =seealso
361              
362             =over
363              
364             =item * L - Main Docker client
365              
366             =item * L - Image entity class
367              
368             =back
369              
370             =cut
371              
372             1;