/
exit_remove_built_image.py
68 lines (53 loc) · 2.44 KB
/
exit_remove_built_image.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
"""
Copyright (c) 2015 Red Hat, Inc
All rights reserved.
This software may be modified and distributed under the terms
of the BSD license. See the LICENSE file for details.
Remove built image (this only makes sense if you store the image in some registry first)
"""
from atomic_reactor.plugin import ExitPlugin
from docker.errors import APIError
__all__ = ('GarbageCollectionPlugin', )
def defer_removal(workflow, image):
key = GarbageCollectionPlugin.key
workflow.plugin_workspace.setdefault(key, {})
workspace = workflow.plugin_workspace[key]
workspace.setdefault('images_to_remove', set())
workspace['images_to_remove'].add(image)
class GarbageCollectionPlugin(ExitPlugin):
key = "remove_built_image"
def __init__(self, tasker, workflow, remove_pulled_base_image=True):
"""
constructor
:param tasker: ContainerTasker instance
:param workflow: DockerBuildWorkflow instance
:param remove_pulled_base_image: bool, remove also base image? default=True
"""
# call parent constructor
super(GarbageCollectionPlugin, self).__init__(tasker, workflow)
self.remove_base_image = remove_pulled_base_image
def run(self):
image = self.workflow.builder.image_id
if image:
self.remove_image(image, force=True)
if self.remove_base_image and self.workflow.pulled_base_images:
# FIXME: we may need to add force here, let's try it like this for now
# FIXME: when ID of pulled img matches an ID of an image already present, don't remove
for base_image_tag in self.workflow.pulled_base_images:
self.remove_image(base_image_tag, force=False)
workspace = self.workflow.plugin_workspace.get(self.key, {})
images_to_remove = workspace.get('images_to_remove', [])
for image in images_to_remove:
self.remove_image(image, force=True)
def remove_image(self, image, force=False):
try:
self.tasker.remove_image(image, force=force)
except APIError as ex:
if ex.is_client_error():
self.log.warning("failed to remove image %s (%s: %s), ignoring",
image, ex.response.status_code, ex.response.reason)
else:
raise
except Exception as ex:
self.log.warning("exception while removing image %s: %r, ignoring",
image, ex)