Add docker_prune module (#48063)
* Add docker_prune module. * Fix spelling error.
This commit is contained in:
parent
c1385b6073
commit
2728a22f73
4 changed files with 326 additions and 0 deletions
259
lib/ansible/modules/cloud/docker/docker_prune.py
Normal file
259
lib/ansible/modules/cloud/docker/docker_prune.py
Normal file
|
@ -0,0 +1,259 @@
|
|||
#!/usr/bin/python
|
||||
#
|
||||
# Copyright 2016 Red Hat | Ansible
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
|
||||
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
||||
'status': ['preview'],
|
||||
'supported_by': 'community'}
|
||||
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: docker_prune
|
||||
|
||||
short_description: Allows to prune various docker objects
|
||||
|
||||
description:
|
||||
- Allows to run C(docker container prune), C(docker image prune), C(docker network prune)
|
||||
and C(docker volume prune) via the Docker API.
|
||||
|
||||
version_added: "2.8"
|
||||
|
||||
options:
|
||||
containers:
|
||||
description:
|
||||
- Whether to prune containers.
|
||||
type: bool
|
||||
default: no
|
||||
containers_filters:
|
||||
description:
|
||||
- A dictionary of filter values used for selecting containers to delete.
|
||||
- "For example, C(until: 24h)."
|
||||
- See L(the docker documentation,https://docs.docker.com/engine/reference/commandline/container_prune/#filtering)
|
||||
for more information on possible filters.
|
||||
type: dict
|
||||
images:
|
||||
description:
|
||||
- Whether to prune images.
|
||||
type: bool
|
||||
default: no
|
||||
images_filters:
|
||||
description:
|
||||
- A dictionary of filter values used for selecting images to delete.
|
||||
- "For example, C(dangling: true)."
|
||||
- See L(the docker documentation,https://docs.docker.com/engine/reference/commandline/image_prune/#filtering)
|
||||
for more information on possible filters.
|
||||
type: dict
|
||||
networks:
|
||||
description:
|
||||
- Whether to prune networks.
|
||||
type: bool
|
||||
default: no
|
||||
networks_filters:
|
||||
description:
|
||||
- A dictionary of filter values used for selecting networks to delete.
|
||||
- See L(the docker documentation,https://docs.docker.com/engine/reference/commandline/network_prune/#filtering)
|
||||
for more information on possible filters.
|
||||
type: dict
|
||||
volumes:
|
||||
description:
|
||||
- Whether to prune volumes.
|
||||
type: bool
|
||||
default: no
|
||||
volumes_filters:
|
||||
description:
|
||||
- A dictionary of filter values used for selecting volumes to delete.
|
||||
- See L(the docker documentation,https://docs.docker.com/engine/reference/commandline/volume_prune/#filtering)
|
||||
for more information on possible filters.
|
||||
type: dict
|
||||
builder_cache:
|
||||
description:
|
||||
- Whether to prune the builder cache.
|
||||
- Requires version 3.3.0 of the Python Docker SDK or newer.
|
||||
type: bool
|
||||
default: no
|
||||
|
||||
extends_documentation_fragment:
|
||||
- docker
|
||||
|
||||
author:
|
||||
- "Felix Fontein (@felixfontein)"
|
||||
|
||||
requirements:
|
||||
- "python >= 2.6"
|
||||
- "docker >= 2.1.0"
|
||||
- "Please note that the L(docker-py,https://pypi.org/project/docker-py/) Python
|
||||
module has been superseded by L(docker,https://pypi.org/project/docker/)
|
||||
(see L(here,https://github.com/docker/docker-py/issues/1310) for details).
|
||||
Version 2.1.0 or newer is only available with the C(docker) module."
|
||||
- "Docker API >= 1.25"
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Prune containers older than 24h
|
||||
docker_prune:
|
||||
containers: yes
|
||||
containers_filters:
|
||||
# only consider containers created more than 24 hours ago
|
||||
until: 24h
|
||||
|
||||
- name: Prune everything
|
||||
docker_prune:
|
||||
containers: yes
|
||||
images: yes
|
||||
networks: yes
|
||||
volumes: yes
|
||||
builder_cache: yes
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
# containers
|
||||
containers:
|
||||
description:
|
||||
- List of IDs of deleted containers.
|
||||
returned: C(containers) is C(true)
|
||||
type: list
|
||||
sample: '[]'
|
||||
containers_space_reclaimed:
|
||||
description:
|
||||
- Amount of reclaimed disk space from container pruning in bytes.
|
||||
returned: C(containers) is C(true)
|
||||
type: int
|
||||
sample: '0'
|
||||
|
||||
# images
|
||||
images:
|
||||
description:
|
||||
- List of IDs of deleted images.
|
||||
returned: C(images) is C(true)
|
||||
type: list
|
||||
sample: '[]'
|
||||
images_space_reclaimed:
|
||||
description:
|
||||
- Amount of reclaimed disk space from image pruning in bytes.
|
||||
returned: C(images) is C(true)
|
||||
type: int
|
||||
sample: '0'
|
||||
|
||||
# networks
|
||||
networks:
|
||||
description:
|
||||
- List of IDs of deleted networks.
|
||||
returned: C(networks) is C(true)
|
||||
type: list
|
||||
sample: '[]'
|
||||
|
||||
# volumes
|
||||
volumes:
|
||||
description:
|
||||
- List of IDs of deleted volumes.
|
||||
returned: C(volumes) is C(true)
|
||||
type: list
|
||||
sample: '[]'
|
||||
volumes_space_reclaimed:
|
||||
description:
|
||||
- Amount of reclaimed disk space from volumes pruning in bytes.
|
||||
returned: C(volumes) is C(true)
|
||||
type: int
|
||||
sample: '0'
|
||||
|
||||
# builder_cache
|
||||
builder_cache_space_reclaimed:
|
||||
description:
|
||||
- Amount of reclaimed disk space from builder cache pruning in bytes.
|
||||
returned: C(builder_cache) is C(true)
|
||||
type: int
|
||||
sample: '0'
|
||||
'''
|
||||
|
||||
from distutils.version import LooseVersion
|
||||
|
||||
from ansible.module_utils.docker_common import AnsibleDockerClient
|
||||
|
||||
try:
|
||||
from ansible.module_utils.docker_common import docker_version
|
||||
except Exception as dummy:
|
||||
# missing docker-py handled in ansible.module_utils.docker
|
||||
pass
|
||||
|
||||
|
||||
def get_filters(module, name):
|
||||
result = dict()
|
||||
filters = module.params.get(name)
|
||||
if filters is not None:
|
||||
for k, v in filters.items():
|
||||
# Go doesn't like 'True' or 'False'
|
||||
if v is True:
|
||||
v = 'true'
|
||||
elif v is False:
|
||||
v = 'false'
|
||||
else:
|
||||
v = str(v)
|
||||
result[str(k)] = v
|
||||
return result
|
||||
|
||||
|
||||
def main():
|
||||
argument_spec = dict(
|
||||
containers=dict(type='bool', default=False),
|
||||
containers_filters=dict(type='dict'),
|
||||
images=dict(type='bool', default=False),
|
||||
images_filters=dict(type='dict'),
|
||||
networks=dict(type='bool', default=False),
|
||||
networks_filters=dict(type='dict'),
|
||||
volumes=dict(type='bool', default=False),
|
||||
volumes_filters=dict(type='dict'),
|
||||
builder_cache=dict(type='bool', default=False),
|
||||
)
|
||||
|
||||
client = AnsibleDockerClient(
|
||||
argument_spec=argument_spec,
|
||||
# supports_check_mode=True,
|
||||
min_docker_api_version='1.25',
|
||||
min_docker_version='2.1.0',
|
||||
)
|
||||
|
||||
# Version checks
|
||||
if client.module.params['builder_cache'] and LooseVersion(docker_version) < LooseVersion('3.3.0'):
|
||||
msg = "Error: docker version is %s. Minimum version required for builds option is %s. Use `pip install --upgrade docker` to upgrade."
|
||||
client.module.fail(msg=(msg % (docker_version, )))
|
||||
|
||||
result = dict()
|
||||
|
||||
if client.module.params['containers']:
|
||||
filters = get_filters(client.module, 'containers_filters')
|
||||
res = client.prune_containers(filters=filters)
|
||||
result['containers'] = res.get('ContainersDeleted') or []
|
||||
result['containers_space_reclaimed'] = res['SpaceReclaimed']
|
||||
|
||||
if client.module.params['images']:
|
||||
filters = get_filters(client.module, 'images_filters')
|
||||
res = client.prune_images(filters=filters)
|
||||
result['images'] = res.get('ImagesDeleted') or []
|
||||
result['images_space_reclaimed'] = res['SpaceReclaimed']
|
||||
|
||||
if client.module.params['networks']:
|
||||
filters = get_filters(client.module, 'networks_filters')
|
||||
res = client.prune_networks(filters=filters)
|
||||
result['networks'] = res.get('NetworksDeleted') or []
|
||||
|
||||
if client.module.params['volumes']:
|
||||
filters = get_filters(client.module, 'volumes_filters')
|
||||
res = client.prune_volumes(filters=filters)
|
||||
result['volumes'] = res.get('VolumesDeleted') or []
|
||||
result['volumes_space_reclaimed'] = res['SpaceReclaimed']
|
||||
|
||||
if client.module.params['builder_cache']:
|
||||
res = client.prune_builds()
|
||||
result['builder_cache_space_reclaimed'] = res['SpaceReclaimed']
|
||||
|
||||
client.module.exit_json(**result)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
4
test/integration/targets/docker_prune/aliases
Normal file
4
test/integration/targets/docker_prune/aliases
Normal file
|
@ -0,0 +1,4 @@
|
|||
shippable/posix/group2
|
||||
skip/osx
|
||||
skip/freebsd
|
||||
destructive
|
3
test/integration/targets/docker_prune/meta/main.yml
Normal file
3
test/integration/targets/docker_prune/meta/main.yml
Normal file
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
dependencies:
|
||||
- setup_docker
|
60
test/integration/targets/docker_prune/tasks/main.yml
Normal file
60
test/integration/targets/docker_prune/tasks/main.yml
Normal file
|
@ -0,0 +1,60 @@
|
|||
---
|
||||
- name: Create random names
|
||||
set_fact:
|
||||
cname: "{{ 'ansible-container-%0x' % ((2**32) | random) }}"
|
||||
nname: "{{ 'ansible-network-%0x' % ((2**32) | random) }}"
|
||||
vname: "{{ 'ansible-volume-%0x' % ((2**32) | random) }}"
|
||||
|
||||
- block:
|
||||
# Create objects to be pruned
|
||||
- docker_container:
|
||||
name: "{{ cname }}"
|
||||
image: hello-world
|
||||
state: present
|
||||
register: container
|
||||
- docker_network:
|
||||
name: "{{ nname }}"
|
||||
state: present
|
||||
register: network
|
||||
- docker_volume:
|
||||
name: "{{ vname }}"
|
||||
state: present
|
||||
register: volume
|
||||
|
||||
# Prune objects
|
||||
- docker_prune:
|
||||
containers: yes
|
||||
images: yes
|
||||
networks: yes
|
||||
volumes: yes
|
||||
builder_cache: yes
|
||||
register: result
|
||||
|
||||
# Analyze result
|
||||
- debug: var=result
|
||||
- assert:
|
||||
that:
|
||||
# containers
|
||||
- container.ansible_facts.docker_container.Id in result.containers
|
||||
- "'containers_space_reclaimed' in result"
|
||||
# images
|
||||
- "'images_space_reclaimed' in result"
|
||||
# networks
|
||||
- network.ansible_facts.docker_network.Name in result.networks
|
||||
# volumes
|
||||
- volume.ansible_facts.docker_volume.Name in result.volumes
|
||||
- "'volumes_space_reclaimed' in result"
|
||||
# builder_cache
|
||||
- "'builder_cache_space_reclaimed' in result"
|
||||
|
||||
# Test with filters
|
||||
- docker_prune:
|
||||
images: yes
|
||||
images_filters:
|
||||
dangling: true
|
||||
register: result
|
||||
|
||||
- debug: var=result
|
||||
|
||||
# Skip for CentOS 6
|
||||
when: ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6
|
Loading…
Reference in a new issue