mirror of
https://github.com/ansible-collections/community.docker.git
synced 2025-12-16 03:52:05 +00:00
* Add docker_compose_v2_pull module. * Improve and extend parsing of events. * Add ignores. * --policy is only available since Compose 2.22.0.
386 lines
10 KiB
Python
386 lines
10 KiB
Python
#!/usr/bin/python
|
|
#
|
|
# Copyright (c) 2023, Felix Fontein <felix@fontein.de>
|
|
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
from __future__ import absolute_import, division, print_function
|
|
__metaclass__ = type
|
|
|
|
|
|
DOCUMENTATION = '''
|
|
|
|
module: docker_compose_v2_pull
|
|
|
|
short_description: Pull a Docker compose project
|
|
|
|
version_added: 3.6.0
|
|
|
|
description:
|
|
- Uses Docker Compose to pull images for a project.
|
|
|
|
extends_documentation_fragment:
|
|
- community.docker.compose_v2
|
|
- community.docker.docker.cli_documentation
|
|
- community.docker.attributes
|
|
- community.docker.attributes.actiongroup_docker
|
|
|
|
attributes:
|
|
check_mode:
|
|
support: full
|
|
diff_mode:
|
|
support: none
|
|
|
|
options:
|
|
policy:
|
|
description:
|
|
- Whether to pull images before running. This is used when C(docker compose up) is ran.
|
|
- V(always) ensures that the images are always pulled, even when already present on the Docker daemon.
|
|
- V(missing) only pulls them when they are not present on the Docker daemon. This is only supported since Docker Compose 2.22.0.
|
|
type: str
|
|
choices:
|
|
- always
|
|
- missing
|
|
default: always
|
|
|
|
requirements:
|
|
- "Docker CLI with Docker compose plugin 2.18.0 or later"
|
|
|
|
author:
|
|
- Felix Fontein (@felixfontein)
|
|
|
|
notes:
|
|
- |-
|
|
The Docker compose CLI plugin has no stable output format (see for example U(https://github.com/docker/compose/issues/10872)),
|
|
and for the main operations also no machine friendly output format. The module tries to accomodate this with various
|
|
version-dependent behavior adjustments and with testing older and newer versions of the Docker compose CLI plugin.
|
|
|
|
Currently the module is tested with multiple plugin versions between 2.18.1 and 2.23.3. The exact list of plugin versions
|
|
will change over time. New releases of the Docker compose CLI plugin can break this module at any time.
|
|
|
|
seealso:
|
|
- module: community.docker.docker_compose
|
|
'''
|
|
|
|
EXAMPLES = '''
|
|
# Examples use the django example at https://docs.docker.com/compose/django. Follow it to create the
|
|
# flask directory
|
|
|
|
- name: Run using a project directory
|
|
hosts: localhost
|
|
gather_facts: false
|
|
tasks:
|
|
- name: Tear down existing services
|
|
community.docker.docker_compose_v2:
|
|
project_src: flask
|
|
state: absent
|
|
|
|
- name: Create and start services
|
|
community.docker.docker_compose_v2:
|
|
project_src: flask
|
|
register: output
|
|
|
|
- name: Show results
|
|
ansible.builtin.debug:
|
|
var: output
|
|
|
|
- name: Run `docker-compose up` again
|
|
community.docker.docker_compose_v2:
|
|
project_src: flask
|
|
register: output
|
|
|
|
- name: Show results
|
|
ansible.builtin.debug:
|
|
var: output
|
|
|
|
- ansible.builtin.assert:
|
|
that: not output.changed
|
|
|
|
- name: Stop all services
|
|
community.docker.docker_compose_v2:
|
|
project_src: flask
|
|
state: stopped
|
|
register: output
|
|
|
|
- name: Show results
|
|
ansible.builtin.debug:
|
|
var: output
|
|
|
|
- name: Verify that web and db services are not running
|
|
ansible.builtin.assert:
|
|
that:
|
|
- "not output.services.web.flask_web_1.state.running"
|
|
- "not output.services.db.flask_db_1.state.running"
|
|
|
|
- name: Restart services
|
|
community.docker.docker_compose_v2:
|
|
project_src: flask
|
|
state: restarted
|
|
register: output
|
|
|
|
- name: Show results
|
|
ansible.builtin.debug:
|
|
var: output
|
|
|
|
- name: Verify that web and db services are running
|
|
ansible.builtin.assert:
|
|
that:
|
|
- "output.services.web.flask_web_1.state.running"
|
|
- "output.services.db.flask_db_1.state.running"
|
|
'''
|
|
|
|
RETURN = '''
|
|
containers:
|
|
description:
|
|
- A list of containers associated to the service.
|
|
returned: success
|
|
type: list
|
|
elements: dict
|
|
contains:
|
|
Command:
|
|
description:
|
|
- The container's command.
|
|
type: raw
|
|
CreatedAt:
|
|
description:
|
|
- The timestamp when the container was created.
|
|
type: str
|
|
sample: "2024-01-02 12:20:41 +0100 CET"
|
|
ExitCode:
|
|
description:
|
|
- The container's exit code.
|
|
type: int
|
|
Health:
|
|
description:
|
|
- The container's health check.
|
|
type: raw
|
|
ID:
|
|
description:
|
|
- The container's ID.
|
|
type: str
|
|
sample: "44a7d607219a60b7db0a4817fb3205dce46e91df2cb4b78a6100b6e27b0d3135"
|
|
Image:
|
|
description:
|
|
- The container's image.
|
|
type: str
|
|
Labels:
|
|
description:
|
|
- Labels for this container.
|
|
type: dict
|
|
LocalVolumes:
|
|
description:
|
|
- The local volumes count.
|
|
type: str
|
|
Mounts:
|
|
description:
|
|
- Mounts.
|
|
type: str
|
|
Name:
|
|
description:
|
|
- The container's primary name.
|
|
type: str
|
|
Names:
|
|
description:
|
|
- List of names of the container.
|
|
type: list
|
|
elements: str
|
|
Networks:
|
|
description:
|
|
- List of networks attached to this container.
|
|
type: list
|
|
elements: str
|
|
Ports:
|
|
description:
|
|
- List of port assignments as a string.
|
|
type: str
|
|
Publishers:
|
|
description:
|
|
- List of port assigments.
|
|
type: list
|
|
elements: dict
|
|
contains:
|
|
URL:
|
|
description:
|
|
- Interface the port is bound to.
|
|
type: str
|
|
TargetPort:
|
|
description:
|
|
- The container's port the published port maps to.
|
|
type: int
|
|
PublishedPort:
|
|
description:
|
|
- The port that is published.
|
|
type: int
|
|
Protocol:
|
|
description:
|
|
- The protocol.
|
|
type: str
|
|
choices:
|
|
- tcp
|
|
- udp
|
|
RunningFor:
|
|
description:
|
|
- Amount of time the container runs.
|
|
type: str
|
|
Service:
|
|
description:
|
|
- The name of the service.
|
|
type: str
|
|
Size:
|
|
description:
|
|
- The container's size.
|
|
type: str
|
|
sample: "0B"
|
|
State:
|
|
description:
|
|
- The container's state.
|
|
type: str
|
|
sample: running
|
|
Status:
|
|
description:
|
|
- The container's status.
|
|
type: str
|
|
sample: Up About a minute
|
|
images:
|
|
description:
|
|
- A list of images associated to the service.
|
|
returned: success
|
|
type: list
|
|
elements: dict
|
|
contains:
|
|
ID:
|
|
description:
|
|
- The image's ID.
|
|
type: str
|
|
sample: sha256:c8bccc0af9571ec0d006a43acb5a8d08c4ce42b6cc7194dd6eb167976f501ef1
|
|
ContainerName:
|
|
description:
|
|
- Name of the conainer this image is used by.
|
|
type: str
|
|
Repository:
|
|
description:
|
|
- The repository where this image belongs to.
|
|
type: str
|
|
Tag:
|
|
description:
|
|
- The tag of the image.
|
|
type: str
|
|
Size:
|
|
description:
|
|
- The image's size in bytes.
|
|
type: int
|
|
actions:
|
|
description:
|
|
- A list of actions that have been applied.
|
|
returned: success
|
|
type: list
|
|
elements: dict
|
|
contains:
|
|
what:
|
|
description:
|
|
- What kind of resource was changed.
|
|
type: str
|
|
sample: container
|
|
choices:
|
|
- container
|
|
- image
|
|
- network
|
|
- service
|
|
- unknown
|
|
- volume
|
|
id:
|
|
description:
|
|
- The ID of the resource that was changed.
|
|
type: str
|
|
sample: container
|
|
status:
|
|
description:
|
|
- The status change that happened.
|
|
type: str
|
|
sample: Creating
|
|
choices:
|
|
- Starting
|
|
- Exiting
|
|
- Restarting
|
|
- Creating
|
|
- Stopping
|
|
- Killing
|
|
- Removing
|
|
- Recreating
|
|
- Pulling
|
|
'''
|
|
|
|
import traceback
|
|
|
|
from ansible.module_utils.common.text.converters import to_native
|
|
|
|
from ansible_collections.community.docker.plugins.module_utils.common_cli import (
|
|
AnsibleModuleDockerClient,
|
|
DockerException,
|
|
)
|
|
|
|
from ansible_collections.community.docker.plugins.module_utils.compose_v2 import (
|
|
BaseComposeManager,
|
|
common_compose_argspec,
|
|
)
|
|
|
|
from ansible_collections.community.docker.plugins.module_utils.version import LooseVersion
|
|
|
|
|
|
DOCKER_COMPOSE_MINIMAL_VERSION = '2.18.0'
|
|
|
|
|
|
class PullManager(BaseComposeManager):
|
|
def __init__(self, client):
|
|
super(PullManager, self).__init__(client, min_version=DOCKER_COMPOSE_MINIMAL_VERSION)
|
|
parameters = self.client.module.params
|
|
|
|
self.policy = parameters['policy']
|
|
|
|
if self.policy != 'always' and self.compose_version < LooseVersion('2.22.0'):
|
|
# https://github.com/docker/compose/pull/10981 - 2.22.0
|
|
self.client.fail('A pull policy other than always is only supported since Docker Compose 2.22.0. {0} has version {1}'.format(
|
|
self.client.get_cli(), self.compose_version))
|
|
|
|
def get_pull_cmd(self, dry_run, no_start=False):
|
|
args = self.get_base_args() + ['pull']
|
|
if self.policy != 'always':
|
|
args.extend(['--policy', self.policy])
|
|
if dry_run:
|
|
args.append('--dry-run')
|
|
args.append('--')
|
|
return args
|
|
|
|
def run(self):
|
|
result = dict()
|
|
args = self.get_pull_cmd(self.check_mode)
|
|
rc, stdout, stderr = self.client.call_cli(*args, cwd=self.project_src)
|
|
events = self.parse_events(stderr, dry_run=self.check_mode)
|
|
self.emit_warnings(events)
|
|
self.update_result(result, events, stdout, stderr)
|
|
self.update_failed(result, events, args, stdout, stderr, rc)
|
|
self.cleanup_result(result)
|
|
return result
|
|
|
|
|
|
def main():
|
|
argument_spec = dict(
|
|
policy=dict(type='str', choices=['always', 'missing'], default='always'),
|
|
)
|
|
argument_spec.update(common_compose_argspec())
|
|
|
|
client = AnsibleModuleDockerClient(
|
|
argument_spec=argument_spec,
|
|
supports_check_mode=True,
|
|
)
|
|
|
|
try:
|
|
result = PullManager(client).run()
|
|
client.module.exit_json(**result)
|
|
except DockerException as e:
|
|
client.fail('An unexpected docker error occurred: {0}'.format(to_native(e)), exception=traceback.format_exc())
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|