mirror of
https://github.com/thegeeklab/docker-tidy.git
synced 2024-06-13 22:00:51 +02:00
Merge pull request #36 from Yelp/remove_volumes
Remove volumes when removing containers
This commit is contained in:
commit
f645eafbad
6
debian/changelog
vendored
6
debian/changelog
vendored
|
@ -1,3 +1,9 @@
|
||||||
|
docker-custodian (0.7.0) lucid; urgency=low
|
||||||
|
|
||||||
|
* Delete volumes along with containers
|
||||||
|
|
||||||
|
-- Paul O'Connor <poc@yelp.com> Wed, 05 Oct 2016 00:58:10 -0700
|
||||||
|
|
||||||
docker-custodian (0.6.1) lucid; urgency=low
|
docker-custodian (0.6.1) lucid; urgency=low
|
||||||
|
|
||||||
* New release for pypi
|
* New release for pypi
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# -*- coding: utf8 -*-
|
# -*- coding: utf8 -*-
|
||||||
|
|
||||||
__version_info__ = (0, 6, 1)
|
__version_info__ = (0, 7, 0)
|
||||||
__version__ = '%d.%d.%d' % __version_info__
|
__version__ = '%d.%d.%d' % __version_info__
|
||||||
|
|
|
@ -25,7 +25,8 @@ def cleanup_containers(client, max_container_age, dry_run):
|
||||||
all_containers = get_all_containers(client)
|
all_containers = get_all_containers(client)
|
||||||
|
|
||||||
for container_summary in reversed(all_containers):
|
for container_summary in reversed(all_containers):
|
||||||
container = api_call(client.inspect_container, container_summary['Id'])
|
container = api_call(client.inspect_container,
|
||||||
|
container=container_summary['Id'])
|
||||||
if not container or not should_remove_container(container,
|
if not container or not should_remove_container(container,
|
||||||
max_container_age):
|
max_container_age):
|
||||||
continue
|
continue
|
||||||
|
@ -36,7 +37,8 @@ def cleanup_containers(client, max_container_age, dry_run):
|
||||||
container['State']['FinishedAt']))
|
container['State']['FinishedAt']))
|
||||||
|
|
||||||
if not dry_run:
|
if not dry_run:
|
||||||
api_call(client.remove_container, container['Id'])
|
api_call(client.remove_container, container=container['Id'],
|
||||||
|
v=True)
|
||||||
|
|
||||||
|
|
||||||
def should_remove_container(container, min_date):
|
def should_remove_container(container, min_date):
|
||||||
|
@ -116,7 +118,7 @@ def no_image_tags(image_tags):
|
||||||
|
|
||||||
|
|
||||||
def remove_image(client, image_summary, min_date, dry_run):
|
def remove_image(client, image_summary, min_date, dry_run):
|
||||||
image = api_call(client.inspect_image, image_summary['Id'])
|
image = api_call(client.inspect_image, image=image_summary['Id'])
|
||||||
if not image or not is_image_old(image, min_date):
|
if not image or not is_image_old(image, min_date):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -127,21 +129,23 @@ def remove_image(client, image_summary, min_date, dry_run):
|
||||||
image_tags = image_summary.get('RepoTags')
|
image_tags = image_summary.get('RepoTags')
|
||||||
# If there are no tags, remove the id
|
# If there are no tags, remove the id
|
||||||
if no_image_tags(image_tags):
|
if no_image_tags(image_tags):
|
||||||
api_call(client.remove_image, image_summary['Id'])
|
api_call(client.remove_image, image=image_summary['Id'])
|
||||||
return
|
return
|
||||||
|
|
||||||
# Remove any repository tags so we don't hit 409 Conflict
|
# Remove any repository tags so we don't hit 409 Conflict
|
||||||
for image_tag in image_tags:
|
for image_tag in image_tags:
|
||||||
api_call(client.remove_image, image_tag)
|
api_call(client.remove_image, image=image_tag)
|
||||||
|
|
||||||
|
|
||||||
def api_call(func, id):
|
def api_call(func, **kwargs):
|
||||||
try:
|
try:
|
||||||
return func(id)
|
return func(**kwargs)
|
||||||
except requests.exceptions.Timeout as e:
|
except requests.exceptions.Timeout as e:
|
||||||
log.warn("Failed to call %s %s %s" % (func.__name__, id, e))
|
params = ','.join('%s=%s' % item for item in kwargs.items())
|
||||||
|
log.warn("Failed to call %s %s %s" % (func.__name__, params, e))
|
||||||
except docker.errors.APIError as ae:
|
except docker.errors.APIError as ae:
|
||||||
log.warn("Error calling %s %s %s" % (func.__name__, id, ae))
|
params = ','.join('%s=%s' % item for item in kwargs.items())
|
||||||
|
log.warn("Error calling %s %s %s" % (func.__name__, params, ae))
|
||||||
|
|
||||||
|
|
||||||
def format_image(image, image_summary):
|
def format_image(image, image_summary):
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
argparse==1.3.0
|
argparse==1.3.0
|
||||||
backports.ssl-match-hostname==3.4.0.2
|
backports.ssl-match-hostname==3.4.0.2
|
||||||
docker-py==1.7.2
|
docker-py==1.8.1
|
||||||
future==0.14.3
|
future==0.14.3
|
||||||
python-dateutil==2.4.0
|
python-dateutil==2.4.0
|
||||||
pytimeparse==1.1.2
|
pytimeparse==1.1.2
|
||||||
|
|
|
@ -65,7 +65,8 @@ def test_cleanup_containers(mock_client, now):
|
||||||
]
|
]
|
||||||
mock_client.inspect_container.side_effect = iter(mock_containers)
|
mock_client.inspect_container.side_effect = iter(mock_containers)
|
||||||
docker_gc.cleanup_containers(mock_client, max_container_age, False)
|
docker_gc.cleanup_containers(mock_client, max_container_age, False)
|
||||||
mock_client.remove_container.assert_called_once_with('abcd')
|
mock_client.remove_container.assert_called_once_with(container='abcd',
|
||||||
|
v=True)
|
||||||
|
|
||||||
|
|
||||||
def test_cleanup_images(mock_client, now):
|
def test_cleanup_images(mock_client, now):
|
||||||
|
@ -88,7 +89,7 @@ def test_cleanup_images(mock_client, now):
|
||||||
|
|
||||||
docker_gc.cleanup_images(mock_client, max_image_age, False, set())
|
docker_gc.cleanup_images(mock_client, max_image_age, False, set())
|
||||||
assert mock_client.remove_image.mock_calls == [
|
assert mock_client.remove_image.mock_calls == [
|
||||||
mock.call(image['Id']) for image in reversed(images)
|
mock.call(image=image['Id']) for image in reversed(images)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -191,7 +192,7 @@ def test_remove_image_no_tags(mock_client, image, now):
|
||||||
mock_client.inspect_image.return_value = image
|
mock_client.inspect_image.return_value = image
|
||||||
docker_gc.remove_image(mock_client, image_summary, now, False)
|
docker_gc.remove_image(mock_client, image_summary, now, False)
|
||||||
|
|
||||||
mock_client.remove_image.assert_called_once_with(image_id)
|
mock_client.remove_image.assert_called_once_with(image=image_id)
|
||||||
|
|
||||||
|
|
||||||
def test_remove_image_new_image_not_removed(mock_client, image, later_time):
|
def test_remove_image_new_image_not_removed(mock_client, image, later_time):
|
||||||
|
@ -214,15 +215,15 @@ def test_remove_image_with_tags(mock_client, image, now):
|
||||||
docker_gc.remove_image(mock_client, image_summary, now, False)
|
docker_gc.remove_image(mock_client, image_summary, now, False)
|
||||||
|
|
||||||
assert mock_client.remove_image.mock_calls == [
|
assert mock_client.remove_image.mock_calls == [
|
||||||
mock.call(tag) for tag in repo_tags
|
mock.call(image=tag) for tag in repo_tags
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def test_api_call_success():
|
def test_api_call_success():
|
||||||
func = mock.Mock()
|
func = mock.Mock()
|
||||||
id = "abcd"
|
container = "abcd"
|
||||||
result = docker_gc.api_call(func, id)
|
result = docker_gc.api_call(func, container=container)
|
||||||
func.assert_called_once_with(id)
|
func.assert_called_once_with(container="abcd")
|
||||||
assert result == func.return_value
|
assert result == func.return_value
|
||||||
|
|
||||||
|
|
||||||
|
@ -230,17 +231,17 @@ def test_api_call_with_timeout():
|
||||||
func = mock.Mock(
|
func = mock.Mock(
|
||||||
side_effect=requests.exceptions.ReadTimeout("msg"),
|
side_effect=requests.exceptions.ReadTimeout("msg"),
|
||||||
__name__="remove_image")
|
__name__="remove_image")
|
||||||
id = "abcd"
|
image = "abcd"
|
||||||
|
|
||||||
with mock.patch(
|
with mock.patch(
|
||||||
'docker_custodian.docker_gc.log',
|
'docker_custodian.docker_gc.log',
|
||||||
autospec=True) as mock_log:
|
autospec=True) as mock_log:
|
||||||
docker_gc.api_call(func, id)
|
docker_gc.api_call(func, image=image)
|
||||||
|
|
||||||
func.assert_called_once_with(id)
|
func.assert_called_once_with(image="abcd")
|
||||||
mock_log.warn.assert_called_once_with(
|
mock_log.warn.assert_called_once_with('Failed to call remove_image '
|
||||||
'Failed to call remove_image abcd msg'
|
+ 'image=abcd msg'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_api_call_with_api_error():
|
def test_api_call_with_api_error():
|
||||||
|
@ -250,16 +251,16 @@ def test_api_call_with_api_error():
|
||||||
mock.Mock(status_code=409, reason="Conflict"),
|
mock.Mock(status_code=409, reason="Conflict"),
|
||||||
explanation="failed"),
|
explanation="failed"),
|
||||||
__name__="remove_image")
|
__name__="remove_image")
|
||||||
id = "abcd"
|
image = "abcd"
|
||||||
|
|
||||||
with mock.patch(
|
with mock.patch(
|
||||||
'docker_custodian.docker_gc.log',
|
'docker_custodian.docker_gc.log',
|
||||||
autospec=True) as mock_log:
|
autospec=True) as mock_log:
|
||||||
docker_gc.api_call(func, id)
|
docker_gc.api_call(func, image=image)
|
||||||
|
|
||||||
func.assert_called_once_with(id)
|
func.assert_called_once_with(image="abcd")
|
||||||
mock_log.warn.assert_called_once_with(
|
mock_log.warn.assert_called_once_with(
|
||||||
'Error calling remove_image abcd '
|
'Error calling remove_image image=abcd '
|
||||||
'409 Client Error: Conflict ("failed")')
|
'409 Client Error: Conflict ("failed")')
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user