[ARVADOS] created: 02c0cb4b9417de0e144185176d14146a3f20e772
git at public.curoverse.com
git at public.curoverse.com
Fri Oct 30 17:55:03 EDT 2015
at 02c0cb4b9417de0e144185176d14146a3f20e772 (commit)
commit 02c0cb4b9417de0e144185176d14146a3f20e772
Author: Tom Clegg <tom at curoverse.com>
Date: Fri Oct 30 17:53:24 2015 -0400
7444: Delete containers as soon as they stop.
diff --git a/services/dockercleaner/arvados_docker/cleaner.py b/services/dockercleaner/arvados_docker/cleaner.py
index 191cb55..85f78b7 100755
--- a/services/dockercleaner/arvados_docker/cleaner.py
+++ b/services/dockercleaner/arvados_docker/cleaner.py
@@ -177,9 +177,10 @@ class DockerImageUseRecorder(DockerEventListener):
class DockerImageCleaner(DockerImageUseRecorder):
event_handlers = DockerImageUseRecorder.event_handlers.copy()
- def __init__(self, images, docker_client, events):
+ def __init__(self, images, docker_client, events, remove_stopped_containers=False):
super().__init__(images, docker_client, events)
self.logged_unknown = set()
+ self.remove_stopped_containers = remove_stopped_containers
def new_container(self, event, container_hash):
container_image_id = container_hash['Image']
@@ -188,6 +189,18 @@ class DockerImageCleaner(DockerImageUseRecorder):
self.images.add_image(image_hash)
return super().new_container(event, container_hash)
+ @event_handlers.on('die')
+ def clean_container(self, event=None):
+ if not self.remove_stopped_containers:
+ return
+ cid = event['id']
+ try:
+ self.docker_client.remove_container(cid)
+ except docker.errors.APIError as error:
+ logger.warning("Failed to remove container %s: %s", cid, error)
+ else:
+ logger.info("Removed container %s", cid)
+
@event_handlers.on('destroy')
def clean_images(self, event=None):
for image_id in self.images.should_delete():
@@ -226,6 +239,9 @@ def parse_arguments(arguments):
'--quota', action='store', type=human_size, required=True,
help="space allowance for Docker images, suffixed with K/M/G/T")
parser.add_argument(
+ '--remove-stopped-containers', action='store_true', default=True,
+ help="remove all containers as soon as they stop")
+ parser.add_argument(
'--verbose', '-v', action='count', default=0,
help="log more information")
return parser.parse_args(arguments)
@@ -246,7 +262,8 @@ def run(args, docker_client):
images, docker_client, docker_client.events(since=1, until=start_time))
use_recorder.run()
cleaner = DockerImageCleaner(
- images, docker_client, docker_client.events(since=start_time))
+ images, docker_client, docker_client.events(since=start_time),
+ remove_stopped_containers=args.remove_stopped_containers)
logger.info("Starting cleanup loop")
cleaner.clean_images()
cleaner.run()
diff --git a/services/dockercleaner/tests/test_cleaner.py b/services/dockercleaner/tests/test_cleaner.py
index fd959de..52efabc 100644
--- a/services/dockercleaner/tests/test_cleaner.py
+++ b/services/dockercleaner/tests/test_cleaner.py
@@ -354,3 +354,23 @@ class RunTestCase(unittest.TestCase):
self.assertLessEqual(test_start_time, event_kwargs[0]['until'])
self.assertIn('since', event_kwargs[1])
self.assertEqual(event_kwargs[0]['until'], event_kwargs[1]['since'])
+
+
+class ContainerRemovalTestCase(unittest.TestCase):
+ def setUp(self):
+ self.args = mock.MagicMock(name='args')
+ self.docker_client = mock.MagicMock(name='docker_client')
+
+ def test_remove_on_die(self):
+ mockID = MockDockerId()
+ self.docker_client.events.return_value = [
+ MockEvent(x, docker_id=mockID).encoded()
+ for x in ['create', 'attach', 'start', 'resize', 'die', 'destroy']]
+ cleaner.run(self.args, self.docker_client)
+ self.docker_client.remove_container.assert_called_once_with(mockID)
+
+ def test_disabled_flag(self):
+ self.args.remove_stopped_containers = False
+ self.docker_client.events.return_value = [MockEvent('die').encoded()]
+ cleaner.run(self.args, self.docker_client)
+ self.assertEqual(0, self.docker_client.remove_container.call_count)
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list