From ca2592150443a8a92176c00fe1980d0edd0d6e45 Mon Sep 17 00:00:00 2001 From: Sagi Shnaidman Date: Mon, 10 May 2021 20:28:48 +0300 Subject: [PATCH] Use podman collection instead of podman* modules Switch to using Ansible Podman collections, remove all podman modules from tripleo-ansible. Depends-On: https://review.opendev.org/c/openstack/tripleo-heat-templates/+/793168 Change-Id: I8846c8a22e5b39cdfbf68fc7f814a81e4e99901a --- .ansible-lint | 3 - .../modules/modules-podman_container.rst | 14 - .../roles/role-tripleo_container_manage.rst | 2 +- tox.ini | 7 - .../action/container_status.py | 2 +- .../action/podman_containers.py | 84 - .../module_utils/podman/common.py | 28 - .../podman/podman_container_lib.py | 1577 ----------------- .../modules/podman_container.py | 940 ---------- .../modules/podman_container_info.py | 426 ----- .../modules/podman_containers.py | 61 - .../modules/podman_volume_info.py | 115 -- .../molecule/podman_container/converge.yml | 438 ----- .../molecule/podman_container/molecule.yml | 50 - .../molecule/podman_container/prepare.yml | 39 - .../podman_container_info/converge.yml | 60 - .../podman_container_info/molecule.yml | 50 - .../podman_container_info/prepare.yml | 22 - .../molecule/podman_volume_info/converge.yml | 63 - .../molecule/podman_volume_info/molecule.yml | 51 - .../molecule/podman_volume_info/prepare.yml | 22 - .../molecule/default/prepare.yml | 6 +- .../molecule/default/converge.yml | 18 +- .../tasks/delete_orphan.yml | 2 +- .../tasks/podman/create.yml | 2 +- .../tasks/podman/start_order.yml | 2 +- .../molecule/default/prepare.yml | 4 +- .../molecule/legacy_vars/prepare.yml | 4 +- .../molecule/podman-rm-stopped/prepare.yml | 6 +- .../tasks/tripleo_podman_container_rm.yml | 2 +- .../molecule/default/prepare.yml | 4 +- .../molecule/default/prepare.yml | 2 +- .../molecule/default/prepare.yml | 4 +- .../tripleo_podman/molecule/login/prepare.yml | 6 +- zuul.d/molecule.yaml | 11 - zuul.d/playbooks/pre.yml | 8 + 36 files changed, 41 insertions(+), 4094 deletions(-) delete mode 100644 doc/source/modules/modules-podman_container.rst delete mode 100644 tripleo_ansible/ansible_plugins/action/podman_containers.py delete mode 100644 tripleo_ansible/ansible_plugins/module_utils/podman/common.py delete mode 100644 tripleo_ansible/ansible_plugins/module_utils/podman/podman_container_lib.py delete mode 100644 tripleo_ansible/ansible_plugins/modules/podman_container.py delete mode 100644 tripleo_ansible/ansible_plugins/modules/podman_container_info.py delete mode 100644 tripleo_ansible/ansible_plugins/modules/podman_containers.py delete mode 100644 tripleo_ansible/ansible_plugins/modules/podman_volume_info.py delete mode 100644 tripleo_ansible/ansible_plugins/tests/molecule/podman_container/converge.yml delete mode 100644 tripleo_ansible/ansible_plugins/tests/molecule/podman_container/molecule.yml delete mode 100644 tripleo_ansible/ansible_plugins/tests/molecule/podman_container/prepare.yml delete mode 100644 tripleo_ansible/ansible_plugins/tests/molecule/podman_container_info/converge.yml delete mode 100644 tripleo_ansible/ansible_plugins/tests/molecule/podman_container_info/molecule.yml delete mode 100644 tripleo_ansible/ansible_plugins/tests/molecule/podman_container_info/prepare.yml delete mode 100644 tripleo_ansible/ansible_plugins/tests/molecule/podman_volume_info/converge.yml delete mode 100644 tripleo_ansible/ansible_plugins/tests/molecule/podman_volume_info/molecule.yml delete mode 100644 tripleo_ansible/ansible_plugins/tests/molecule/podman_volume_info/prepare.yml diff --git a/.ansible-lint b/.ansible-lint index 9b53e5eea..5d119fe2e 100644 --- a/.ansible-lint +++ b/.ansible-lint @@ -29,9 +29,6 @@ mock_modules: - os_baremetal_provide_node - os_tripleo_baremetal_configure - os_tripleo_baremetal_node_introspection - - podman_container - - podman_container_info - - podman_volume_info - tripleo_baremetal_check_existing - tripleo_baremetal_expand_roles - tripleo_baremetal_populate_environment diff --git a/doc/source/modules/modules-podman_container.rst b/doc/source/modules/modules-podman_container.rst deleted file mode 100644 index 025456dd5..000000000 --- a/doc/source/modules/modules-podman_container.rst +++ /dev/null @@ -1,14 +0,0 @@ -========================= -Module - podman_container -========================= - - -This module provides for the following ansible plugin: - - * podman_container - - -.. ansibleautoplugin:: - :module: tripleo_ansible/ansible_plugins/modules/podman_container.py - :documentation: true - :examples: true diff --git a/doc/source/roles/role-tripleo_container_manage.rst b/doc/source/roles/role-tripleo_container_manage.rst index 08d99e591..b7729bce7 100644 --- a/doc/source/roles/role-tripleo_container_manage.rst +++ b/doc/source/roles/role-tripleo_container_manage.rst @@ -226,4 +226,4 @@ TripleO Heat Templates. Note that it doesn't write down the overrides in the JSON file so if an update / upgrade is executed, the container will be re-configured with the configuration that is in the JSON file. -.. _podman_container: https://docs.openstack.org/tripleo-ansible/latest/modules/modules-podman_container.html +.. _podman_container: https://github.com/containers/ansible-podman-collections diff --git a/tox.ini b/tox.ini index d4f7c9304..854a7f9ed 100644 --- a/tox.ini +++ b/tox.ini @@ -105,10 +105,3 @@ commands = echo -e '\n\nNo molecule tests have been executed\nSee https://docs.openstack.org/tripleo-ansible/latest/contributing.html#local-testing-of-new-roles\n\n'; \ fi" {[testenv:linters]commands} - -[testenv:modules] -deps= - {[testenv:linters]deps} -commands = - bash -c "cd {toxinidir}/tripleo_ansible/ansible_plugins/tests; molecule test --all;" - {[testenv:linters]commands} diff --git a/tripleo_ansible/ansible_plugins/action/container_status.py b/tripleo_ansible/ansible_plugins/action/container_status.py index b30daf507..fb3c2b12b 100644 --- a/tripleo_ansible/ansible_plugins/action/container_status.py +++ b/tripleo_ansible/ansible_plugins/action/container_status.py @@ -202,7 +202,7 @@ class ActionModule(ActionBase): """ tvars = copy.deepcopy(task_vars) result = self._execute_module( - module_name='podman_container_info', + module_name='containers.podman.podman_container_info', module_args=dict(name=containers), task_vars=tvars ) diff --git a/tripleo_ansible/ansible_plugins/action/podman_containers.py b/tripleo_ansible/ansible_plugins/action/podman_containers.py deleted file mode 100644 index f1ae990e2..000000000 --- a/tripleo_ansible/ansible_plugins/action/podman_containers.py +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# Copyright 2020 Red Hat, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -from ansible.plugins.action import ActionBase -from ansible.utils.display import Display - -DISPLAY = Display() - - -class ActionModule(ActionBase): - """Action plugin for podman_container module""" - - _VALID_ARGS = frozenset(( - 'containers', - )) - - def __init__(self, *args, **kwargs): - super(ActionModule, self).__init__(*args, **kwargs) - - def run(self, tmp=None, task_vars=None): - self._supports_check_mode = True - self._supports_async = True - del tmp # tmp no longer has any effect - if task_vars is None: - task_vars = {} - - if 'containers' not in self._task.args: - return {'failed': True, - 'msg': 'Task must have "containers" argument!'} - containers = self._task.args.get('containers') - if not containers: - return {'failed': True, - 'msg': 'Task must have non empty "containers" argument!'} - DISPLAY.vvvv('Running for containers: %s' % str(containers)) - wrap_async = self._task.async_val and ( - not self._connection.has_native_async) - results = [self._execute_module( - module_name='podman_container', - module_args=container, - task_vars=task_vars, wrap_async=wrap_async - ) for container in containers] - - changed = any([i.get('changed', False) for i in results]) - skipped = all([i.get('skipped', False) for i in results]) - failed = any([i.get('failed', False) for i in results]) - - try: - if not wrap_async: - # remove a temporary path we created - self._remove_tmp_path(self._connection._shell.tmpdir) - except Exception: - pass - finally: - if skipped: - return {'results': results, - 'changed': False, - 'skipped': skipped} - if failed: - msg = "\n".join([i.get('msg', '') for i in results]) - return {'results': results, - 'changed': changed, - 'failed': failed, - 'msg': msg} - return {'results': results, - 'changed': changed, - 'failed': False, - 'msg': 'All items completed'} diff --git a/tripleo_ansible/ansible_plugins/module_utils/podman/common.py b/tripleo_ansible/ansible_plugins/module_utils/podman/common.py deleted file mode 100644 index d7b0ed790..000000000 --- a/tripleo_ansible/ansible_plugins/module_utils/podman/common.py +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/python -# Copyright (c) 2020 Red Hat -# 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 - - -def run_podman_command(module, executable='podman', args=None, expected_rc=0, ignore_errors=False): - if not isinstance(executable, list): - command = [executable] - if args is not None: - command.extend(args) - rc, out, err = module.run_command(command) - if not ignore_errors and rc != expected_rc: - module.fail_json( - msg='Failed to run {command} {args}: {err}'.format( - command=command, args=args, err=err)) - return rc, out, err - - -def lower_keys(x): - if isinstance(x, list): - return [lower_keys(v) for v in x] - elif isinstance(x, dict): - return dict((k.lower(), lower_keys(v)) for k, v in x.items()) - else: - return x diff --git a/tripleo_ansible/ansible_plugins/module_utils/podman/podman_container_lib.py b/tripleo_ansible/ansible_plugins/module_utils/podman/podman_container_lib.py deleted file mode 100644 index 952525ab7..000000000 --- a/tripleo_ansible/ansible_plugins/module_utils/podman/podman_container_lib.py +++ /dev/null @@ -1,1577 +0,0 @@ -#!/usr/bin/python -# Copyright (c) 2019 OpenStack Foundation -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -from __future__ import (absolute_import, division, print_function) -import json # noqa: F402 -import shlex # noqa: F402 -from distutils.version import LooseVersion # noqa: F402 - -from ansible.module_utils._text import to_bytes, to_native # noqa: F402 -try: - from ansible.module_utils.podman.common import lower_keys -except ImportError: - from tripleo_ansible.ansible_plugins.module_utils.podman.common import lower_keys # noqa: F402 - -__metaclass__ = type - -ARGUMENTS_SPEC_CONTAINER = dict( - name=dict(required=True, type='str'), - executable=dict(default='podman', type='str'), - state=dict(type='str', default='started', choices=[ - 'absent', 'present', 'stopped', 'started', 'created']), - image=dict(type='str'), - annotation=dict(type='dict'), - authfile=dict(type='path'), - blkio_weight=dict(type='int'), - blkio_weight_device=dict(type='dict'), - cap_add=dict(type='list', elements='str', aliases=['capabilities']), - cap_drop=dict(type='list', elements='str'), - cgroup_parent=dict(type='path'), - cgroupns=dict(type='str'), - cgroups=dict(type='str', choices=['default', 'disabled']), - cidfile=dict(type='path'), - cmd_args=dict(type='list', elements='str'), - conmon_pidfile=dict(type='path'), - command=dict(type='raw'), - cpu_period=dict(type='int'), - cpu_rt_period=dict(type='int'), - cpu_rt_runtime=dict(type='int'), - cpu_shares=dict(type='int'), - cpus=dict(type='str'), - cpuset_cpus=dict(type='str'), - cpuset_mems=dict(type='str'), - detach=dict(type='bool', default=True), - debug=dict(type='bool', default=False), - detach_keys=dict(type='str', no_log=False), - device=dict(type='list', elements='str'), - device_read_bps=dict(type='list'), - device_read_iops=dict(type='list'), - device_write_bps=dict(type='list'), - device_write_iops=dict(type='list'), - dns=dict(type='list', elements='str', aliases=['dns_servers']), - dns_option=dict(type='str', aliases=['dns_opts']), - dns_search=dict(type='str', aliases=['dns_search_domains']), - entrypoint=dict(type='str'), - env=dict(type='dict'), - env_file=dict(type='path'), - env_host=dict(type='bool'), - etc_hosts=dict(type='dict', aliases=['add_hosts']), - expose=dict(type='list', elements='str', aliases=[ - 'exposed', 'exposed_ports']), - force_restart=dict(type='bool', default=False, - aliases=['restart']), - gidmap=dict(type='list', elements='str'), - group_add=dict(type='list', aliases=['groups']), - healthcheck=dict(type='str'), - healthcheck_interval=dict(type='str'), - healthcheck_retries=dict(type='int'), - healthcheck_start_period=dict(type='str'), - healthcheck_timeout=dict(type='str'), - hostname=dict(type='str'), - http_proxy=dict(type='bool'), - image_volume=dict(type='str', choices=['bind', 'tmpfs', 'ignore']), - image_strict=dict(type='bool', default=False), - init=dict(type='bool'), - init_path=dict(type='str'), - interactive=dict(type='bool'), - ip=dict(type='str'), - ipc=dict(type='str', aliases=['ipc_mode']), - kernel_memory=dict(type='str'), - label=dict(type='dict', aliases=['labels']), - label_file=dict(type='str'), - log_driver=dict(type='str', choices=[ - 'k8s-file', 'journald', 'json-file']), - log_level=dict( - type='str', - choices=["debug", "info", "warn", "error", "fatal", "panic"]), - log_opt=dict(type='dict', aliases=['log_options'], - options=dict( - max_size=dict(type='str'), - path=dict(type='str'), - tag=dict(type='str'))), - mac_address=dict(type='str'), - memory=dict(type='str'), - memory_reservation=dict(type='str'), - memory_swap=dict(type='str'), - memory_swappiness=dict(type='int'), - mount=dict(type='str'), - network=dict(type='list', elements='str', aliases=['net', 'network_mode']), - no_hosts=dict(type='bool'), - oom_kill_disable=dict(type='bool'), - oom_score_adj=dict(type='int'), - pid=dict(type='str', aliases=['pid_mode']), - pids_limit=dict(type='str'), - pod=dict(type='str'), - privileged=dict(type='bool'), - publish=dict(type='list', elements='str', aliases=[ - 'ports', 'published', 'published_ports']), - publish_all=dict(type='bool'), - read_only=dict(type='bool'), - read_only_tmpfs=dict(type='bool'), - recreate=dict(type='bool', default=False), - restart_policy=dict(type='str'), - rm=dict(type='bool', aliases=['remove', 'auto_remove']), - rootfs=dict(type='bool'), - security_opt=dict(type='list', elements='str'), - shm_size=dict(type='str'), - sig_proxy=dict(type='bool'), - stop_signal=dict(type='int'), - stop_timeout=dict(type='int'), - subgidname=dict(type='str'), - subuidname=dict(type='str'), - sysctl=dict(type='dict'), - systemd=dict(type='str'), - tmpfs=dict(type='dict'), - tty=dict(type='bool'), - uidmap=dict(type='list', elements='str'), - ulimit=dict(type='list', aliases=['ulimits']), - user=dict(type='str'), - userns=dict(type='str', aliases=['userns_mode']), - uts=dict(type='str'), - volume=dict(type='list', elements='str', aliases=['volumes']), - volumes_from=dict(type='list', elements='str'), - workdir=dict(type='str', aliases=['working_dir']) -) - - -class PodmanModuleParams: - """Creates list of arguments for podman CLI command. - - Arguments: - action {str} -- action type from 'run', 'stop', 'create', 'delete', - 'start' - params {dict} -- dictionary of module parameters - - """ - - def __init__(self, action, params, podman_version, module): - self.params = params - self.action = action - self.podman_version = podman_version - self.module = module - - def construct_command_from_params(self): - """Create a podman command from given module parameters. - - Returns: - list -- list of byte strings for Popen command - """ - if self.action in ['start', 'stop', 'delete']: - return self.start_stop_delete() - if self.action in ['create', 'run']: - cmd = [self.action, '--name', self.params['name']] - all_param_methods = [func for func in dir(self) - if callable(getattr(self, func)) - and func.startswith("addparam")] - params_set = (i for i in self.params if self.params[i] is not None) - for param in params_set: - func_name = "_".join(["addparam", param]) - if func_name in all_param_methods: - cmd = getattr(self, func_name)(cmd) - cmd.append(self.params['image']) - if self.params['command']: - if isinstance(self.params['command'], list): - cmd += self.params['command'] - else: - cmd += self.params['command'].split() - return [to_bytes(i, errors='surrogate_or_strict') for i in cmd] - - def start_stop_delete(self): - - if self.action in ['stop', 'start']: - cmd = [self.action, self.params['name']] - return [to_bytes(i, errors='surrogate_or_strict') for i in cmd] - - if self.action == 'delete': - cmd = ['rm', '-f', self.params['name']] - return [to_bytes(i, errors='surrogate_or_strict') for i in cmd] - - def check_version(self, param, minv=None, maxv=None): - if minv and LooseVersion(minv) > LooseVersion( - self.podman_version): - self.module.fail_json(msg="Parameter %s is supported from podman " - "version %s only! Current version is %s" % ( - param, minv, self.podman_version)) - if maxv and LooseVersion(maxv) < LooseVersion( - self.podman_version): - self.module.fail_json(msg="Parameter %s is supported till podman " - "version %s only! Current version is %s" % ( - param, minv, self.podman_version)) - - def addparam_annotation(self, c): - for annotate in self.params['annotation'].items(): - c += ['--annotation', '='.join(annotate)] - return c - - def addparam_authfile(self, c): - return c + ['--authfile', self.params['authfile']] - - def addparam_blkio_weight(self, c): - return c + ['--blkio-weight', self.params['blkio_weight']] - - def addparam_blkio_weight_device(self, c): - for blkio in self.params['blkio_weight_device'].items(): - c += ['--blkio-weight-device', ':'.join(blkio)] - return c - - def addparam_cap_add(self, c): - for cap_add in self.params['cap_add']: - c += ['--cap-add', cap_add] - return c - - def addparam_cap_drop(self, c): - for cap_drop in self.params['cap_drop']: - c += ['--cap-drop', cap_drop] - return c - - def addparam_cgroups(self, c): - self.check_version('--cgroups', minv='1.6.0') - return c + ['--cgroups=%s' % self.params['cgroups']] - - def addparam_cgroupns(self, c): - self.check_version('--cgroupns', minv='1.6.2') - return c + ['--cgroupns=%s' % self.params['cgroupns']] - - def addparam_cgroup_parent(self, c): - return c + ['--cgroup-parent', self.params['cgroup_parent']] - - def addparam_cidfile(self, c): - return c + ['--cidfile', self.params['cidfile']] - - def addparam_conmon_pidfile(self, c): - return c + ['--conmon-pidfile', self.params['conmon_pidfile']] - - def addparam_cpu_period(self, c): - return c + ['--cpu-period', self.params['cpu_period']] - - def addparam_cpu_rt_period(self, c): - return c + ['--cpu-rt-period', self.params['cpu_rt_period']] - - def addparam_cpu_rt_runtime(self, c): - return c + ['--cpu-rt-runtime', self.params['cpu_rt_runtime']] - - def addparam_cpu_shares(self, c): - return c + ['--cpu-shares', self.params['cpu_shares']] - - def addparam_cpus(self, c): - return c + ['--cpus', self.params['cpus']] - - def addparam_cpuset_cpus(self, c): - return c + ['--cpuset-cpus', self.params['cpuset_cpus']] - - def addparam_cpuset_mems(self, c): - return c + ['--cpuset-mems', self.params['cpuset_mems']] - - def addparam_detach(self, c): - return c + ['--detach=%s' % self.params['detach']] - - def addparam_detach_keys(self, c): - return c + ['--detach-keys', self.params['detach_keys']] - - def addparam_device(self, c): - for dev in self.params['device']: - c += ['--device', dev] - return c - - def addparam_device_read_bps(self, c): - for dev in self.params['device_read_bps']: - c += ['--device-read-bps', dev] - return c - - def addparam_device_read_iops(self, c): - for dev in self.params['device_read_iops']: - c += ['--device-read-iops', dev] - return c - - def addparam_device_write_bps(self, c): - for dev in self.params['device_write_bps']: - c += ['--device-write-bps', dev] - return c - - def addparam_device_write_iops(self, c): - for dev in self.params['device_write_iops']: - c += ['--device-write-iops', dev] - return c - - def addparam_dns(self, c): - return c + ['--dns', ','.join(self.params['dns'])] - - def addparam_dns_option(self, c): - return c + ['--dns-option', self.params['dns_option']] - - def addparam_dns_search(self, c): - return c + ['--dns-search', self.params['dns_search']] - - def addparam_entrypoint(self, c): - return c + ['--entrypoint', self.params['entrypoint']] - - def addparam_env(self, c): - for env_value in self.params['env'].items(): - c += ['--env', - b"=".join([to_bytes(k, errors='surrogate_or_strict') - for k in env_value])] - return c - - def addparam_env_file(self, c): - return c + ['--env-file', self.params['env_file']] - - def addparam_env_host(self, c): - self.check_version('--env-host', minv='1.5.0') - return c + ['--env-host=%s' % self.params['env_host']] - - def addparam_etc_hosts(self, c): - for host_ip in self.params['etc_hosts'].items(): - c += ['--add-host', ':'.join(host_ip)] - return c - - def addparam_expose(self, c): - for exp in self.params['expose']: - c += ['--expose', exp] - return c - - def addparam_gidmap(self, c): - for gidmap in self.params['gidmap']: - c += ['--gidmap', gidmap] - return c - - def addparam_group_add(self, c): - for g in self.params['group_add']: - c += ['--group-add', g] - return c - - def addparam_healthcheck(self, c): - return c + ['--healthcheck-command', self.params['healthcheck']] - - def addparam_healthcheck_interval(self, c): - return c + ['--healthcheck-interval', - self.params['healthcheck_interval']] - - def addparam_healthcheck_retries(self, c): - return c + ['--healthcheck-retries', - self.params['healthcheck_retries']] - - def addparam_healthcheck_start_period(self, c): - return c + ['--healthcheck-start-period', - self.params['healthcheck_start_period']] - - def addparam_healthcheck_timeout(self, c): - return c + ['--healthcheck-timeout', - self.params['healthcheck_timeout']] - - def addparam_hostname(self, c): - return c + ['--hostname', self.params['hostname']] - - def addparam_http_proxy(self, c): - return c + ['--http-proxy=%s' % self.params['http_proxy']] - - def addparam_image_volume(self, c): - return c + ['--image-volume', self.params['image_volume']] - - def addparam_init(self, c): - if self.params['init']: - c += ['--init'] - return c - - def addparam_init_path(self, c): - return c + ['--init-path', self.params['init_path']] - - def addparam_interactive(self, c): - return c + ['--interactive=%s' % self.params['interactive']] - - def addparam_ip(self, c): - return c + ['--ip', self.params['ip']] - - def addparam_ipc(self, c): - return c + ['--ipc', self.params['ipc']] - - def addparam_kernel_memory(self, c): - return c + ['--kernel-memory', self.params['kernel_memory']] - - def addparam_label(self, c): - for label in self.params['label'].items(): - c += ['--label', b'='.join([to_bytes(la, errors='surrogate_or_strict') - for la in label])] - return c - - def addparam_label_file(self, c): - return c + ['--label-file', self.params['label_file']] - - def addparam_log_driver(self, c): - return c + ['--log-driver', self.params['log_driver']] - - def addparam_log_opt(self, c): - for k, v in self.params['log_opt'].items(): - if v is not None: - c += ['--log-opt', - b"=".join([to_bytes(k.replace('max_size', 'max-size'), - errors='surrogate_or_strict'), - to_bytes(v, - errors='surrogate_or_strict')])] - return c - - def addparam_log_level(self, c): - return c + ['--log-level', self.params['log_level']] - - def addparam_mac_address(self, c): - return c + ['--mac-address', self.params['mac_address']] - - def addparam_memory(self, c): - return c + ['--memory', self.params['memory']] - - def addparam_memory_reservation(self, c): - return c + ['--memory-reservation', self.params['memory_reservation']] - - def addparam_memory_swap(self, c): - return c + ['--memory-swap', self.params['memory_swap']] - - def addparam_memory_swappiness(self, c): - return c + ['--memory-swappiness', self.params['memory_swappiness']] - - def addparam_mount(self, c): - return c + ['--mount', self.params['mount']] - - def addparam_network(self, c): - return c + ['--network', ",".join(self.params['network'])] - - def addparam_no_hosts(self, c): - return c + ['--no-hosts=%s' % self.params['no_hosts']] - - def addparam_oom_kill_disable(self, c): - return c + ['--oom-kill-disable=%s' % self.params['oom_kill_disable']] - - def addparam_oom_score_adj(self, c): - return c + ['--oom-score-adj', self.params['oom_score_adj']] - - def addparam_pid(self, c): - return c + ['--pid', self.params['pid']] - - def addparam_pids_limit(self, c): - return c + ['--pids-limit', self.params['pids_limit']] - - def addparam_pod(self, c): - return c + ['--pod', self.params['pod']] - - def addparam_privileged(self, c): - return c + ['--privileged=%s' % self.params['privileged']] - - def addparam_publish(self, c): - for pub in self.params['publish']: - c += ['--publish', pub] - return c - - def addparam_publish_all(self, c): - return c + ['--publish-all=%s' % self.params['publish_all']] - - def addparam_read_only(self, c): - return c + ['--read-only=%s' % self.params['read_only']] - - def addparam_read_only_tmpfs(self, c): - return c + ['--read-only-tmpfs=%s' % self.params['read_only_tmpfs']] - - def addparam_restart_policy(self, c): - return c + ['--restart=%s' % self.params['restart_policy']] - - def addparam_rm(self, c): - if self.params['rm']: - c += ['--rm'] - return c - - def addparam_rootfs(self, c): - return c + ['--rootfs=%s' % self.params['rootfs']] - - def addparam_security_opt(self, c): - for secopt in self.params['security_opt']: - c += ['--security-opt', secopt] - return c - - def addparam_shm_size(self, c): - return c + ['--shm-size', self.params['shm_size']] - - def addparam_sig_proxy(self, c): - return c + ['--sig-proxy=%s' % self.params['sig_proxy']] - - def addparam_stop_signal(self, c): - return c + ['--stop-signal', self.params['stop_signal']] - - def addparam_stop_timeout(self, c): - return c + ['--stop-timeout', self.params['stop_timeout']] - - def addparam_subgidname(self, c): - return c + ['--subgidname', self.params['subgidname']] - - def addparam_subuidname(self, c): - return c + ['--subuidname', self.params['subuidname']] - - def addparam_sysctl(self, c): - for sysctl in self.params['sysctl'].items(): - c += ['--sysctl', - b"=".join([to_bytes(k, errors='surrogate_or_strict') - for k in sysctl])] - return c - - def addparam_systemd(self, c): - return c + ['--systemd=%s' % str(self.params['systemd']).lower()] - - def addparam_tmpfs(self, c): - for tmpfs in self.params['tmpfs'].items(): - c += ['--tmpfs', ':'.join(tmpfs)] - return c - - def addparam_tty(self, c): - return c + ['--tty=%s' % self.params['tty']] - - def addparam_uidmap(self, c): - for uidmap in self.params['uidmap']: - c += ['--uidmap', uidmap] - return c - - def addparam_ulimit(self, c): - for u in self.params['ulimit']: - c += ['--ulimit', u] - return c - - def addparam_user(self, c): - return c + ['--user', self.params['user']] - - def addparam_userns(self, c): - return c + ['--userns', self.params['userns']] - - def addparam_uts(self, c): - return c + ['--uts', self.params['uts']] - - def addparam_volume(self, c): - for vol in self.params['volume']: - if vol: - c += ['--volume', vol] - return c - - def addparam_volumes_from(self, c): - for vol in self.params['volumes_from']: - c += ['--volumes-from', vol] - return c - - def addparam_workdir(self, c): - return c + ['--workdir', self.params['workdir']] - - # Add your own args for podman command - def addparam_cmd_args(self, c): - return c + self.params['cmd_args'] - - -class PodmanDefaults: - def __init__(self, image_info, podman_version): - self.version = podman_version - self.image_info = image_info - self.defaults = { - "blkio_weight": 0, - "cgroups": "default", - "cidfile": "", - "cpus": 0.0, - "cpu_shares": 0, - "cpu_quota": 0, - "cpu_period": 0, - "cpu_rt_runtime": 0, - "cpu_rt_period": 0, - "cpuset_cpus": "", - "cpuset_mems": "", - "detach": True, - "device": [], - "env_host": False, - "etc_hosts": {}, - "group_add": [], - "ipc": "", - "kernelmemory": "0", - "log_driver": "k8s-file", - "log_level": "error", - "memory": "0", - "memory_swap": "0", - "memory_reservation": "0", - # "memory_swappiness": -1, - "no_hosts": False, - # libpod issue with networks in inspection - "oom_score_adj": 0, - "pid": "", - "privileged": False, - "rm": False, - "security_opt": [], - "stop_signal": self.image_info['config'].get('stopsignal', "15"), - "tty": False, - "user": self.image_info.get('user', ''), - "workdir": self.image_info['config'].get('workingdir', '/'), - "uts": "", - } - - def default_dict(self): - # make here any changes to self.defaults related to podman version - # https://github.com/containers/libpod/pull/5669 - if (LooseVersion(self.version) >= LooseVersion('1.8.0') - and LooseVersion(self.version) < LooseVersion('1.9.0')): - self.defaults['cpu_shares'] = 1024 - if (LooseVersion(self.version) >= LooseVersion('2.0.0')): - self.defaults['network'] = ["slirp4netns"] - self.defaults['ipc'] = "private" - self.defaults['uts'] = "private" - self.defaults['pid'] = "private" - if (LooseVersion(self.version) >= LooseVersion('3.0.0')): - self.defaults['log_level'] = "warning" - return self.defaults - - -class PodmanContainerDiff: - def __init__(self, module, module_params, info, image_info, podman_version): - self.module = module - self.module_params = module_params - self.version = podman_version - self.default_dict = None - self.info = lower_keys(info) - self.image_info = lower_keys(image_info) - self.params = self.defaultize() - self.diff = {'before': {}, 'after': {}} - self.non_idempotent = {} - - def defaultize(self): - params_with_defaults = {} - self.default_dict = PodmanDefaults( - self.image_info, self.version).default_dict() - for p in self.module_params: - if self.module_params[p] is None and p in self.default_dict: - params_with_defaults[p] = self.default_dict[p] - else: - params_with_defaults[p] = self.module_params[p] - return params_with_defaults - - def _diff_update_and_compare(self, param_name, before, after): - if before != after: - self.diff['before'].update({param_name: before}) - self.diff['after'].update({param_name: after}) - return True - return False - - def diffparam_annotation(self): - before = self.info['config']['annotations'] or {} - after = before.copy() - if self.module_params['annotation'] is not None: - after.update(self.params['annotation']) - return self._diff_update_and_compare('annotation', before, after) - - def diffparam_env_host(self): - # It's impossible to get from inspest, recreate it if not default - before = False - after = self.params['env_host'] - return self._diff_update_and_compare('env_host', before, after) - - def diffparam_blkio_weight(self): - before = self.info['hostconfig']['blkioweight'] - after = self.params['blkio_weight'] - return self._diff_update_and_compare('blkio_weight', before, after) - - def diffparam_blkio_weight_device(self): - before = self.info['hostconfig']['blkioweightdevice'] - if before == [] and self.module_params['blkio_weight_device'] is None: - after = [] - else: - after = self.params['blkio_weight_device'] - return self._diff_update_and_compare('blkio_weight_device', before, after) - - def diffparam_cap_add(self): - before = self.info['effectivecaps'] or [] - before = [i.lower() for i in before] - after = [] - if self.module_params['cap_add'] is not None: - for cap in self.module_params['cap_add']: - cap = cap.lower() - cap = cap if cap.startswith('cap_') else 'cap_' + cap - after.append(cap) - after += before - before, after = sorted(list(set(before))), sorted(list(set(after))) - return self._diff_update_and_compare('cap_add', before, after) - - def diffparam_cap_drop(self): - before = self.info['effectivecaps'] or [] - before = [i.lower() for i in before] - after = before[:] - if self.module_params['cap_drop'] is not None: - for cap in self.module_params['cap_drop']: - cap = cap.lower() - cap = cap if cap.startswith('cap_') else 'cap_' + cap - if cap in after: - after.remove(cap) - before, after = sorted(list(set(before))), sorted(list(set(after))) - return self._diff_update_and_compare('cap_drop', before, after) - - def diffparam_cgroup_parent(self): - before = self.info['hostconfig']['cgroupparent'] - after = self.params['cgroup_parent'] - if after is None: - after = before - return self._diff_update_and_compare('cgroup_parent', before, after) - - def diffparam_cgroups(self): - # Cgroups output is not supported in all versions - if 'cgroups' in self.info['hostconfig']: - before = self.info['hostconfig']['cgroups'] - after = self.params['cgroups'] - return self._diff_update_and_compare('cgroups', before, after) - return False - - def diffparam_cidfile(self): - before = self.info['hostconfig']['containeridfile'] - after = self.params['cidfile'] - return self._diff_update_and_compare('cidfile', before, after) - - def diffparam_command(self): - # TODO(sshnaidm): to inspect image to get the default command - if self.module_params['command'] is not None: - before = self.info['config']['cmd'] - after = self.params['command'] - if isinstance(after, str): - after = shlex.split(after) - return self._diff_update_and_compare('command', before, after) - return False - - def diffparam_conmon_pidfile(self): - before = self.info['conmonpidfile'] - if self.module_params['conmon_pidfile'] is None: - after = before - else: - after = self.params['conmon_pidfile'] - return self._diff_update_and_compare('conmon_pidfile', before, after) - - def diffparam_cpu_period(self): - before = self.info['hostconfig']['cpuperiod'] - after = self.params['cpu_period'] - return self._diff_update_and_compare('cpu_period', before, after) - - def diffparam_cpu_rt_period(self): - before = self.info['hostconfig']['cpurealtimeperiod'] - after = self.params['cpu_rt_period'] - return self._diff_update_and_compare('cpu_rt_period', before, after) - - def diffparam_cpu_rt_runtime(self): - before = self.info['hostconfig']['cpurealtimeruntime'] - after = self.params['cpu_rt_runtime'] - return self._diff_update_and_compare('cpu_rt_runtime', before, after) - - def diffparam_cpu_shares(self): - before = self.info['hostconfig']['cpushares'] - after = self.params['cpu_shares'] - return self._diff_update_and_compare('cpu_shares', before, after) - - def diffparam_cpus(self): - before = int(self.info['hostconfig']['nanocpus']) / 1000000000 - after = self.params['cpus'] - return self._diff_update_and_compare('cpus', before, after) - - def diffparam_cpuset_cpus(self): - before = self.info['hostconfig']['cpusetcpus'] - after = self.params['cpuset_cpus'] - return self._diff_update_and_compare('cpuset_cpus', before, after) - - def diffparam_cpuset_mems(self): - before = self.info['hostconfig']['cpusetmems'] - after = self.params['cpuset_mems'] - return self._diff_update_and_compare('cpuset_mems', before, after) - - def diffparam_device(self): - before = [":".join([i['pathonhost'], i['pathincontainer']]) - for i in self.info['hostconfig']['devices']] - after = [":".join(i.split(":")[:2]) for i in self.params['device']] - before, after = sorted(list(set(before))), sorted(list(set(after))) - return self._diff_update_and_compare('devices', before, after) - - def diffparam_device_read_bps(self): - before = self.info['hostconfig']['blkiodevicereadbps'] or [] - before = ["%s:%s" % (i['path'], i['rate']) for i in before] - after = self.params['device_read_bps'] or [] - before, after = sorted(list(set(before))), sorted(list(set(after))) - return self._diff_update_and_compare('device_read_bps', before, after) - - def diffparam_device_read_iops(self): - before = self.info['hostconfig']['blkiodevicereadiops'] or [] - before = ["%s:%s" % (i['path'], i['rate']) for i in before] - after = self.params['device_read_iops'] or [] - before, after = sorted(list(set(before))), sorted(list(set(after))) - return self._diff_update_and_compare('device_read_iops', before, after) - - def diffparam_device_write_bps(self): - before = self.info['hostconfig']['blkiodevicewritebps'] or [] - before = ["%s:%s" % (i['path'], i['rate']) for i in before] - after = self.params['device_write_bps'] or [] - before, after = sorted(list(set(before))), sorted(list(set(after))) - return self._diff_update_and_compare('device_write_bps', before, after) - - def diffparam_device_write_iops(self): - before = self.info['hostconfig']['blkiodevicewriteiops'] or [] - before = ["%s:%s" % (i['path'], i['rate']) for i in before] - after = self.params['device_write_iops'] or [] - before, after = sorted(list(set(before))), sorted(list(set(after))) - return self._diff_update_and_compare('device_write_iops', before, after) - - # Limited idempotency, it can't guess default values - def diffparam_env(self): - env_before = self.info['config']['env'] or {} - before = {i.split("=")[0]: "=".join(i.split("=")[1:]) - for i in env_before} - after = before.copy() - if self.params['env']: - after.update(self.params['env']) - return self._diff_update_and_compare('env', before, after) - - def diffparam_etc_hosts(self): - if self.info['hostconfig']['extrahosts']: - before = dict([i.split(":") - for i in self.info['hostconfig']['extrahosts']]) - else: - before = {} - after = self.params['etc_hosts'] - return self._diff_update_and_compare('etc_hosts', before, after) - - def diffparam_group_add(self): - before = self.info['hostconfig']['groupadd'] - after = self.params['group_add'] - return self._diff_update_and_compare('group_add', before, after) - - # Healthcheck is only defined in container config if a healthcheck - # was configured; otherwise the config key isn't part of the config. - def diffparam_healthcheck(self): - if 'healthcheck' in self.info['config']: - # the "test" key is a list of 2 items where the first one is - # "CMD-SHELL" and the second one is the actual healthcheck command. - before = self.info['config']['healthcheck']['test'][1] - else: - before = '' - after = self.params['healthcheck'] or before - return self._diff_update_and_compare('healthcheck', before, after) - - # Because of hostname is random generated, this parameter has partial idempotency only. - def diffparam_hostname(self): - before = self.info['config']['hostname'] - after = self.params['hostname'] or before - return self._diff_update_and_compare('hostname', before, after) - - def diffparam_image(self): - before_id = self.info['image'] - after_id = self.image_info['id'] - if before_id == after_id: - return self._diff_update_and_compare('image', before_id, after_id) - before = self.info['config']['image'] - after = self.params['image'] - mode = self.params['image_strict'] - if mode is None or not mode: - # In a idempotency 'lite mode' assume all images from different registries are the same - before = before.replace(":latest", "") - after = after.replace(":latest", "") - before = before.split("/")[-1] - after = after.split("/")[-1] - else: - return self._diff_update_and_compare('image', before_id, after_id) - return self._diff_update_and_compare('image', before, after) - - def diffparam_ipc(self): - before = self.info['hostconfig']['ipcmode'] - after = self.params['ipc'] - if self.params['pod'] and not self.module_params['ipc']: - after = before - return self._diff_update_and_compare('ipc', before, after) - - def diffparam_label(self): - before = self.info['config']['labels'] or {} - after = self.image_info.get('labels') or {} - if self.params['label']: - after.update({ - str(k).lower(): str(v) - for k, v in self.params['label'].items() - }) - return self._diff_update_and_compare('label', before, after) - - def diffparam_log_driver(self): - before = self.info['hostconfig']['logconfig']['type'] - after = self.params['log_driver'] - return self._diff_update_and_compare('log_driver', before, after) - - def diffparam_log_level(self): - excom = self.info['exitcommand'] - if '--log-level' in excom: - before = excom[excom.index('--log-level') + 1].lower() - else: - before = self.params['log_level'] - after = self.params['log_level'] - return self._diff_update_and_compare('log_level', before, after) - - # Parameter has limited idempotency - def diffparam_log_opt(self): - before, after = {}, {} - # Log path - path_before = None - if 'logpath' in self.info: - path_before = self.info['logpath'] - # For Podman v3 - if ('logconfig' in self.info['hostconfig'] - and 'path' in self.info['hostconfig']['logconfig']): - path_before = self.info['hostconfig']['logconfig']['path'] - if path_before is not None: - if (self.module_params['log_opt'] - and 'path' in self.module_params['log_opt'] - and self.module_params['log_opt']['path'] is not None): - path_after = self.params['log_opt']['path'] - else: - path_after = path_before - if path_before != path_after: - before.update({'log-path': path_before}) - after.update({'log-path': path_after}) - # Log tag - tag_before = None - if 'logtag' in self.info: - tag_before = self.info['logtag'] - # For Podman v3 - if ('logconfig' in self.info['hostconfig'] - and 'tag' in self.info['hostconfig']['logconfig']): - tag_before = self.info['hostconfig']['logconfig']['tag'] - if tag_before is not None: - if (self.module_params['log_opt'] - and 'tag' in self.module_params['log_opt'] - and self.module_params['log_opt']['tag'] is not None): - tag_after = self.params['log_opt']['tag'] - else: - tag_after = '' - if tag_before != tag_after: - before.update({'log-tag': tag_before}) - after.update({'log-tag': tag_after}) - return self._diff_update_and_compare('log_opt', before, after) - - def diffparam_mac_address(self): - before = str(self.info['networksettings']['macaddress']) - if self.module_params['mac_address'] is not None: - after = self.params['mac_address'] - else: - after = before - return self._diff_update_and_compare('mac_address', before, after) - - def diffparam_memory(self): - before = str(self.info['hostconfig']['memory']) - after = self.params['memory'] - return self._diff_update_and_compare('memory', before, after) - - def diffparam_memory_swap(self): - # By default it's twice memory parameter - before = str(self.info['hostconfig']['memoryswap']) - after = self.params['memory_swap'] - if (self.module_params['memory_swap'] is None - and self.params['memory'] != 0 - and self.params['memory'].isdigit()): - after = str(int(self.params['memory']) * 2) - return self._diff_update_and_compare('memory_swap', before, after) - - def diffparam_memory_reservation(self): - before = str(self.info['hostconfig']['memoryreservation']) - after = self.params['memory_reservation'] - return self._diff_update_and_compare('memory_reservation', before, after) - - def diffparam_network(self): - net_mode_before = self.info['hostconfig']['networkmode'] - net_mode_after = '' - before = list(self.info['networksettings'].get('networks', {})) - # Remove default 'podman' network in v3 for comparison - if before == ['podman']: - before = [] - # Special case for options for slirp4netns rootless networking from v2 - if net_mode_before == 'slirp4netns' and 'createcommand' in self.info['config']: - cr_com = self.info['config']['createcommand'] - if '--network' in cr_com: - cr_net = cr_com[cr_com.index('--network') + 1].lower() - if 'slirp4netns:' in cr_net: - before = [cr_net] - after = self.params['network'] or [] - # If container is in pod and no networks are provided - if not self.module_params['network'] and self.params['pod']: - after = before - return self._diff_update_and_compare('network', before, after) - # Check special network modes - if after in [['bridge'], ['host'], ['slirp4netns'], ['none']]: - net_mode_after = after[0] - # If changes are only for network mode and container has no networks - if net_mode_after and not before: - # Remove differences between v1 and v2 - net_mode_after = net_mode_after.replace('bridge', 'default') - net_mode_after = net_mode_after.replace('slirp4netns', 'default') - net_mode_before = net_mode_before.replace('bridge', 'default') - net_mode_before = net_mode_before.replace('slirp4netns', 'default') - return self._diff_update_and_compare('network', net_mode_before, net_mode_after) - before, after = sorted(list(set(before))), sorted(list(set(after))) - return self._diff_update_and_compare('network', before, after) - - def diffparam_no_hosts(self): - before = not bool(self.info['hostspath']) - # For newer verions of Podman - if 'resolvconfpath' in self.info: - before = not bool(self.info['resolvconfpath']) - after = self.params['no_hosts'] - if self.params['network'] == ['none']: - after = True - return self._diff_update_and_compare('no_hosts', before, after) - - def diffparam_oom_score_adj(self): - before = self.info['hostconfig']['oomscoreadj'] - after = self.params['oom_score_adj'] - return self._diff_update_and_compare('oom_score_adj', before, after) - - def diffparam_privileged(self): - before = self.info['hostconfig']['privileged'] - after = self.params['privileged'] - return self._diff_update_and_compare('privileged', before, after) - - def diffparam_pid(self): - before = self.info['hostconfig']['pidmode'] - after = self.params['pid'] - return self._diff_update_and_compare('pid', before, after) - - # TODO(sshnaidm) Need to add port ranges support - def diffparam_publish(self): - def compose(p, h): - s = ":".join( - [str(h["hostport"]), p.replace('/tcp', '')] - ).strip(":") - if h['hostip']: - return ":".join([h['hostip'], s]) - return s - - ports = self.info['hostconfig']['portbindings'] - before = [] - for port, hosts in ports.items(): - for h in hosts: - before.append(compose(port, h)) - after = self.params['publish'] or [] - if self.params['publish_all']: - image_ports = self.image_info['config'].get('exposedports', {}) - if image_ports: - after += list(image_ports.keys()) - after = [ - i.replace("/tcp", "").replace("[", "").replace("]", "") - for i in after] - # No support for port ranges yet - for ports in after: - if "-" in ports: - return self._diff_update_and_compare('publish', '', '') - before, after = sorted(list(set(before))), sorted(list(set(after))) - return self._diff_update_and_compare('publish', before, after) - - def diffparam_rm(self): - before = self.info['hostconfig']['autoremove'] - after = self.params['rm'] - return self._diff_update_and_compare('rm', before, after) - - def diffparam_security_opt(self): - before = self.info['hostconfig']['securityopt'] - # In rootful containers with apparmor there is a default security opt - before = [o for o in before if 'apparmor=containers-default' not in o] - after = self.params['security_opt'] - before, after = sorted(list(set(before))), sorted(list(set(after))) - return self._diff_update_and_compare('security_opt', before, after) - - def diffparam_stop_signal(self): - signals = { - "sighup": "1", - "sigint": "2", - "sigquit": "3", - "sigill": "4", - "sigtrap": "5", - "sigabrt": "6", - "sigiot": "6", - "sigbus": "7", - "sigfpe": "8", - "sigkill": "9", - "sigusr1": "10", - "sigsegv": "11", - "sigusr2": "12", - "sigpipe": "13", - "sigalrm": "14", - "sigterm": "15", - "sigstkflt": "16", - "sigchld": "17", - "sigcont": "18", - "sigstop": "19", - "sigtstp": "20", - "sigttin": "21", - "sigttou": "22", - "sigurg": "23", - "sigxcpu": "24", - "sigxfsz": "25", - "sigvtalrm": "26", - "sigprof": "27", - "sigwinch": "28", - "sigio": "29", - "sigpwr": "30", - "sigsys": "31", - "sigrtmin+3": "37" - } - before = str(self.info['config']['stopsignal']) - if not before.isdigit(): - before = signals[before.lower()] - after = str(self.params['stop_signal']) - if not after.isdigit(): - after = signals[after.lower()] - return self._diff_update_and_compare('stop_signal', before, after) - - def diffparam_tty(self): - before = self.info['config']['tty'] - after = self.params['tty'] - return self._diff_update_and_compare('tty', before, after) - - def diffparam_user(self): - before = self.info['config']['user'] - after = self.params['user'] - return self._diff_update_and_compare('user', before, after) - - def diffparam_ulimit(self): - after = self.params['ulimit'] or [] - # In case of latest podman - if 'createcommand' in self.info['config']: - ulimits = [] - for k, c in enumerate(self.info['config']['createcommand']): - if c == '--ulimit': - ulimits.append(self.info['config']['createcommand'][k + 1]) - before = ulimits - before, after = sorted(before), sorted(after) - return self._diff_update_and_compare('ulimit', before, after) - if after: - ulimits = self.info['hostconfig']['ulimits'] - before = { - u['name'].replace('rlimit_', ''): "%s:%s" % (u['soft'], u['hard']) for u in ulimits} - after = {i.split('=')[0]: i.split('=')[1] - for i in self.params['ulimit']} - new_before = [] - new_after = [] - for u in list(after.keys()): - # We don't support unlimited ulimits because it depends on platform - if u in before and "-1" not in after[u]: - new_before.append([u, before[u]]) - new_after.append([u, after[u]]) - return self._diff_update_and_compare('ulimit', new_before, new_after) - return self._diff_update_and_compare('ulimit', '', '') - - def diffparam_uts(self): - before = self.info['hostconfig']['utsmode'] - after = self.params['uts'] - if self.params['pod'] and not self.module_params['uts']: - after = before - return self._diff_update_and_compare('uts', before, after) - - def diffparam_volume(self): - def clean_volume(x): - '''Remove trailing and double slashes from volumes.''' - if not x.rstrip("/"): - return "/" - return x.replace("//", "/").rstrip("/") - - before = self.info['mounts'] - before_local_vols = [] - if before: - volumes = [] - local_vols = [] - for m in before: - if m['type'] != 'volume': - volumes.append([m['source'], m['destination']]) - elif m['type'] == 'volume': - local_vols.append([m['name'], m['destination']]) - before = [":".join(v) for v in volumes] - before_local_vols = [":".join(v) for v in local_vols] - if self.params['volume'] is not None: - after = [":".join( - [clean_volume(i) for i in v.split(":")[:2]] - ) for v in self.params['volume']] - else: - after = [] - if before_local_vols: - after = list(set(after).difference(before_local_vols)) - before, after = sorted(list(set(before))), sorted(list(set(after))) - return self._diff_update_and_compare('volume', before, after) - - def diffparam_volumes_from(self): - # Possibly volumesfrom is not in config - before = self.info['hostconfig'].get('volumesfrom', []) or [] - after = self.params['volumes_from'] or [] - return self._diff_update_and_compare('volumes_from', before, after) - - def diffparam_workdir(self): - before = self.info['config']['workingdir'] - after = self.params['workdir'] - return self._diff_update_and_compare('workdir', before, after) - - def is_different(self): - diff_func_list = [func for func in dir(self) - if callable(getattr(self, func)) and func.startswith( - "diffparam")] - fail_fast = not bool(self.module._diff) - different = False - for func_name in diff_func_list: - dff_func = getattr(self, func_name) - if dff_func(): - if fail_fast: - return True - different = True - # Check non idempotent parameters - for p in self.non_idempotent: - if self.module_params[p] is not None and self.module_params[p] not in [{}, [], '']: - different = True - return different - - -def ensure_image_exists(module, image, module_params): - """If image is passed, ensure it exists, if not - pull it or fail. - - Arguments: - module {obj} -- ansible module object - image {str} -- name of image - - Returns: - list -- list of image actions - if it pulled or nothing was done - """ - image_actions = [] - module_exec = module_params['executable'] - if not image: - return image_actions - rc, out, err = module.run_command([module_exec, 'image', 'exists', image]) - if rc == 0: - return image_actions - rc, out, err = module.run_command([module_exec, 'image', 'pull', image]) - if rc != 0: - module.fail_json(msg="Can't pull image %s" % image, stdout=out, - stderr=err) - image_actions.append("pulled image %s" % image) - return image_actions - - -class PodmanContainer: - """Perform container tasks. - - Manages podman container, inspects it and checks its current state - """ - - def __init__(self, module, name, module_params): - """Initialize PodmanContainer class. - - Arguments: - module {obj} -- ansible module object - name {str} -- name of container - """ - - self.module = module - self.module_params = module_params - self.name = name - self.stdout, self.stderr = '', '' - self.info = self.get_info() - self.version = self._get_podman_version() - self.diff = {} - self.actions = [] - - @property - def exists(self): - """Check if container exists.""" - return bool(self.info != {}) - - @property - def different(self): - """Check if container is different.""" - diffcheck = PodmanContainerDiff( - self.module, - self.module_params, - self.info, - self.get_image_info(), - self.version) - is_different = diffcheck.is_different() - diffs = diffcheck.diff - if self.module._diff and is_different and diffs['before'] and diffs['after']: - self.diff['before'] = "\n".join( - ["%s - %s" % (k, v) for k, v in sorted( - diffs['before'].items())]) + "\n" - self.diff['after'] = "\n".join( - ["%s - %s" % (k, v) for k, v in sorted( - diffs['after'].items())]) + "\n" - return is_different - - @property - def running(self): - """Return True if container is running now.""" - return self.exists and self.info['State']['Running'] - - @property - def stopped(self): - """Return True if container exists and is not running now.""" - return self.exists and not self.info['State']['Running'] - - def get_info(self): - """Inspect container and gather info about it.""" - # pylint: disable=unused-variable - rc, out, err = self.module.run_command( - [self.module_params['executable'], b'container', b'inspect', self.name]) - return json.loads(out)[0] if rc == 0 else {} - - def get_image_info(self): - """Inspect container image and gather info about it.""" - # pylint: disable=unused-variable - rc, out, err = self.module.run_command( - [self.module_params['executable'], b'image', b'inspect', self.module_params['image']]) - return json.loads(out)[0] if rc == 0 else {} - - def _get_podman_version(self): - # pylint: disable=unused-variable - rc, out, err = self.module.run_command( - [self.module_params['executable'], b'--version']) - if rc != 0 or not out or "version" not in out: - self.module.fail_json(msg="%s run failed!" % - self.module_params['executable']) - return out.split("version")[1].strip() - - def _perform_action(self, action): - """Perform action with container. - - Arguments: - action {str} -- action to perform - start, create, stop, run, - delete - """ - def clean_stderr(err): - # Inspect STDERR for logs to avoid modules failures in case of - # increased log level verbosity - return "\n".join( - [line for line in err.splitlines() if 'level=' not in line]).strip() - - b_command = PodmanModuleParams(action, - self.module_params, - self.version, - self.module, - ).construct_command_from_params() - if action == 'create': - b_command.remove(b'--detach=True') - full_cmd = " ".join([self.module_params['executable']] - + [to_native(i) for i in b_command]) - self.actions.append(full_cmd) - if self.module.check_mode: - self.module.log( - "PODMAN-CONTAINER-DEBUG (check_mode): %s" % full_cmd) - else: - rc, out, err = self.module.run_command( - [self.module_params['executable'], b'container'] + b_command, - expand_user_and_vars=False) - self.module.log("PODMAN-CONTAINER-DEBUG: %s" % full_cmd) - if self.module_params['debug']: - self.module.log("PODMAN-CONTAINER-DEBUG STDOUT: %s" % out) - self.module.log("PODMAN-CONTAINER-DEBUG STDERR: %s" % err) - self.module.log("PODMAN-CONTAINER-DEBUG RC: %s" % rc) - self.stdout = out - self.stderr = err - if rc != 0 or clean_stderr(err) != '': - self.module.fail_json( - msg="Failed %s container %s" % (action, self.name), - stdout=out, stderr=err) - - def run(self): - """Run the container.""" - self._perform_action('run') - - def delete(self): - """Delete the container.""" - self._perform_action('delete') - - def stop(self): - """Stop the container.""" - self._perform_action('stop') - - def start(self): - """Start the container.""" - self._perform_action('start') - - def create(self): - """Create the container.""" - self._perform_action('create') - - def recreate(self): - """Recreate the container.""" - if self.running: - self.stop() - self.delete() - self.create() - - def recreate_run(self): - """Recreate and run the container.""" - if self.running: - self.stop() - self.delete() - self.run() - - def restart(self): - """Restart the container.""" - self.stop() - self.start() - - -class PodmanManager: - """Module manager class. - - Defines according to parameters what actions should be applied to container - """ - - def __init__(self, module, params): - """Initialize PodmanManager class. - - Arguments: - module {obj} -- ansible module object - """ - - self.module = module - self.results = { - 'changed': False, - 'actions': [], - 'container': {}, - } - self.module_params = params - self.name = self.module_params['name'] - self.executable = \ - self.module.get_bin_path(self.module_params['executable'], - required=True) - self.image = self.module_params['image'] - image_actions = ensure_image_exists( - self.module, self.image, self.module_params) - self.results['actions'] += image_actions - self.state = self.module_params['state'] - self.restart = self.module_params['force_restart'] - self.recreate = self.module_params['recreate'] - self.container = PodmanContainer( - self.module, self.name, self.module_params) - - def update_container_result(self, changed=True): - """Inspect the current container, update results with last info, exit. - - Keyword Arguments: - changed {bool} -- whether any action was performed - (default: {True}) - """ - facts = self.container.get_info() if changed else self.container.info - out, err = self.container.stdout, self.container.stderr - self.results.update({'changed': changed, 'container': facts, - 'podman_actions': self.container.actions}, - stdout=out, stderr=err) - if self.container.diff: - self.results.update({'diff': self.container.diff}) - if self.module.params['debug'] or self.module_params['debug']: - self.results.update({'podman_version': self.container.version}) - - def make_started(self): - """Run actions if desired state is 'started'.""" - if self.container.exists and self.restart: - if self.container.running: - self.container.restart() - self.results['actions'].append('restarted %s' % - self.container.name) - else: - self.container.start() - self.results['actions'].append('started %s' % - self.container.name) - self.update_container_result() - return - if self.container.running and \ - (self.container.different or self.recreate): - self.container.recreate_run() - self.results['actions'].append('recreated %s' % - self.container.name) - self.update_container_result() - return - elif self.container.running and not self.container.different: - if self.restart: - self.container.restart() - self.results['actions'].append('restarted %s' % - self.container.name) - self.update_container_result() - return - self.update_container_result(changed=False) - return - elif not self.container.exists: - self.container.run() - self.results['actions'].append('started %s' % self.container.name) - self.update_container_result() - return - elif self.container.stopped and self.container.different: - self.container.recreate_run() - self.results['actions'].append('recreated %s' % - self.container.name) - self.update_container_result() - return - elif self.container.stopped and not self.container.different: - self.container.start() - self.results['actions'].append('started %s' % self.container.name) - self.update_container_result() - return - - def make_created(self): - """Run actions if desired state is 'created'.""" - if not self.container.exists and not self.image: - self.module.fail_json(msg='Cannot create container when image' - ' is not specified!') - if not self.container.exists: - self.container.create() - self.results['actions'].append('created %s' % self.container.name) - self.update_container_result() - return - else: - if (self.container.different or self.recreate): - self.container.recreate() - self.results['actions'].append('recreated %s' % - self.container.name) - self.update_container_result() - return - self.update_container_result(changed=False) - return - - def make_stopped(self): - """Run actions if desired state is 'stopped'.""" - if not self.container.exists and not self.image: - self.module.fail_json(msg='Cannot create container when image' - ' is not specified!') - if not self.container.exists: - self.container.create() - self.results['actions'].append('created %s' % self.container.name) - self.update_container_result() - return - if self.container.stopped: - self.update_container_result(changed=False) - return - elif self.container.running: - self.container.stop() - self.results['actions'].append('stopped %s' % self.container.name) - self.update_container_result() - return - - def make_absent(self): - """Run actions if desired state is 'absent'.""" - if not self.container.exists: - self.results.update({'changed': False}) - elif self.container.exists: - self.container.delete() - self.results['actions'].append('deleted %s' % self.container.name) - self.results.update({'changed': True}) - self.results.update({'container': {}, - 'podman_actions': self.container.actions}) - - def execute(self): - """Execute the desired action according to map of actions & states.""" - states_map = { - 'present': self.make_started, - 'started': self.make_started, - 'absent': self.make_absent, - 'stopped': self.make_stopped, - 'created': self.make_created, - } - process_action = states_map[self.state] - process_action() - return self.results diff --git a/tripleo_ansible/ansible_plugins/modules/podman_container.py b/tripleo_ansible/ansible_plugins/modules/podman_container.py deleted file mode 100644 index 85313fc40..000000000 --- a/tripleo_ansible/ansible_plugins/modules/podman_container.py +++ /dev/null @@ -1,940 +0,0 @@ -#!/usr/bin/python -# Copyright (c) 2019 OpenStack Foundation -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -# flake8: noqa: E501 - -from __future__ import absolute_import, division, print_function - -__metaclass__ = type - - -DOCUMENTATION = r""" -module: podman_container -author: - - "Sagi Shnaidman (@sshnaidm)" -version_added: '1.0.0' -short_description: Manage podman containers -notes: [] -description: - - Start, stop, restart and manage Podman containers -requirements: - - podman -options: - name: - description: - - Name of the container - required: True - type: str - executable: - description: - - Path to C(podman) executable if it is not in the C($PATH) on the - machine running C(podman) - default: 'podman' - type: str - state: - description: - - I(absent) - A container matching the specified name will be stopped and - removed. - - I(present) - Asserts the existence of a container matching the name and - any provided configuration parameters. If no container matches the - name, a container will be created. If a container matches the name but - the provided configuration does not match, the container will be - updated, if it can be. If it cannot be updated, it will be removed and - re-created with the requested config. Image version will be taken into - account when comparing configuration. Use the recreate option to force - the re-creation of the matching container. - - I(started) - Asserts there is a running container matching the name and - any provided configuration. If no container matches the name, a - container will be created and started. Use recreate to always re-create - a matching container, even if it is running. Use force_restart to force - a matching container to be stopped and restarted. - - I(stopped) - Asserts that the container is first I(present), and then - if the container is running moves it to a stopped state. - - I(created) - Asserts that the container exists with given configuration. - If container doesn't exist, the module creates it and leaves it in - 'created' state. If configuration doesn't match or 'recreate' option is - set, the container will be recreated - type: str - default: started - choices: - - absent - - present - - stopped - - started - - created - image: - description: - - Repository path (or image name) and tag used to create the container. - If an image is not found, the image will be pulled from the registry. - If no tag is included, C(latest) will be used. - - Can also be an image ID. If this is the case, the image is assumed to - be available locally. - type: str - annotation: - description: - - Add an annotation to the container. The format is key value, multiple - times. - type: dict - authfile: - description: - - Path of the authentication file. Default is - ``${XDG_RUNTIME_DIR}/containers/auth.json`` - (Not available for remote commands) You can also override the default - path of the authentication file by setting the ``REGISTRY_AUTH_FILE`` - environment variable. ``export REGISTRY_AUTH_FILE=path`` - type: path - blkio_weight: - description: - - Block IO weight (relative weight) accepts a weight value between 10 and - 1000 - type: int - blkio_weight_device: - description: - - Block IO weight (relative device weight, format DEVICE_NAME[:]WEIGHT). - type: dict - cap_add: - description: - - List of capabilities to add to the container. - type: list - elements: str - aliases: - - capabilities - cap_drop: - description: - - List of capabilities to drop from the container. - type: list - elements: str - cgroup_parent: - description: - - Path to cgroups under which the cgroup for the container will be - created. - If the path is not absolute, the path is considered to be relative to - the cgroups path of the init process. Cgroups will be created if they - do not already exist. - type: path - cgroupns: - description: - - Path to cgroups under which the cgroup for the container will be - created. - type: str - cgroups: - description: - - Determines whether the container will create CGroups. - Valid values are enabled and disabled, which the default being enabled. - The disabled option will force the container to not create CGroups, - and thus conflicts with CGroup options cgroupns and cgroup-parent. - type: str - choices: - - default - - disabled - cidfile: - description: - - Write the container ID to the file - type: path - cmd_args: - description: - - Any additional command options you want to pass to podman command, - cmd_args - ['--other-param', 'value'] - Be aware module doesn't support idempotency if this is set. - type: list - elements: str - conmon_pidfile: - description: - - Write the pid of the conmon process to a file. - conmon runs in a separate process than Podman, - so this is necessary when using systemd to restart Podman containers. - type: path - command: - description: - - Override command of container. Can be a string or a list. - type: raw - cpu_period: - description: - - Limit the CPU real-time period in microseconds - type: int - cpu_rt_period: - description: - - Limit the CPU real-time period in microseconds. - Limit the container's Real Time CPU usage. This flag tell the kernel to - restrict the container's Real Time CPU usage to the period you specify. - type: int - cpu_rt_runtime: - description: - - Limit the CPU real-time runtime in microseconds. - This flag tells the kernel to limit the amount of time in a given CPU - period Real Time tasks may consume. - type: int - cpu_shares: - description: - - CPU shares (relative weight) - type: int - cpus: - description: - - Number of CPUs. The default is 0.0 which means no limit. - type: str - cpuset_cpus: - description: - - CPUs in which to allow execution (0-3, 0,1) - type: str - cpuset_mems: - description: - - Memory nodes (MEMs) in which to allow execution (0-3, 0,1). Only - effective on NUMA systems. - type: str - detach: - description: - - Run container in detach mode - type: bool - default: True - debug: - description: - - Return additional information which can be helpful for investigations. - type: bool - default: False - detach_keys: - description: - - Override the key sequence for detaching a container. Format is a single - character or ctrl-value - type: str - device: - description: - - Add a host device to the container. - The format is [:][:] - (e.g. device /dev/sdc:/dev/xvdc:rwm) - type: list - elements: str - device_read_bps: - description: - - Limit read rate (bytes per second) from a device - (e.g. device-read-bps /dev/sda:1mb) - type: list - device_read_iops: - description: - - Limit read rate (IO per second) from a device - (e.g. device-read-iops /dev/sda:1000) - type: list - device_write_bps: - description: - - Limit write rate (bytes per second) to a device - (e.g. device-write-bps /dev/sda:1mb) - type: list - device_write_iops: - description: - - Limit write rate (IO per second) to a device - (e.g. device-write-iops /dev/sda:1000) - type: list - dns: - description: - - Set custom DNS servers - type: list - elements: str - aliases: - - dns_servers - dns_option: - description: - - Set custom DNS options - type: str - aliases: - - dns_opts - dns_search: - description: - - Set custom DNS search domains (Use dns_search with '' if you don't wish - to set the search domain) - type: str - aliases: - - dns_search_domains - entrypoint: - description: - - Overwrite the default ENTRYPOINT of the image - type: str - env: - description: - - Set environment variables. - This option allows you to specify arbitrary environment variables that - are available for the process that will be launched inside of the - container. - type: dict - env_file: - description: - - Read in a line delimited file of environment variables. Doesn't support - idempotency. If users changes the file with environment variables it's - on them to recreate the container. - type: path - env_host: - description: - - Use all current host environment variables in container. - Defaults to false. - type: bool - etc_hosts: - description: - - Dict of host-to-IP mappings, where each host name is a key in the - dictionary. Each host name will be added to the container's - ``/etc/hosts`` file. - type: dict - aliases: - - add_hosts - expose: - description: - - Expose a port, or a range of ports (e.g. expose "3300-3310") to set up - port redirection on the host system. - type: list - elements: str - aliases: - - exposed - - exposed_ports - force_restart: - description: - - Force restart of container. - type: bool - default: False - aliases: - - restart - gidmap: - description: - - Run the container in a new user namespace using the supplied mapping. - type: list - elements: str - group_add: - description: - - Add additional groups to run as - type: list - aliases: - - groups - healthcheck: - description: - - Set or alter a healthcheck command for a container. - type: str - healthcheck_interval: - description: - - Set an interval for the healthchecks - (a value of disable results in no automatic timer setup) - (default "30s") - type: str - healthcheck_retries: - description: - - The number of retries allowed before a healthcheck is considered to be - unhealthy. The default value is 3. - type: int - healthcheck_start_period: - description: - - The initialization time needed for a container to bootstrap. - The value can be expressed in time format like 2m3s. The default value - is 0s - type: str - healthcheck_timeout: - description: - - The maximum time allowed to complete the healthcheck before an interval - is considered failed. Like start-period, the value can be expressed in - a time format such as 1m22s. The default value is 30s - type: str - hostname: - description: - - Container host name. Sets the container host name that is available - inside the container. - type: str - http_proxy: - description: - - By default proxy environment variables are passed into the container if - set for the podman process. This can be disabled by setting the - http_proxy option to false. The environment variables passed in - include http_proxy, https_proxy, ftp_proxy, no_proxy, and also the - upper case versions of those. - Defaults to true - type: bool - image_volume: - description: - - Tells podman how to handle the builtin image volumes. - The options are bind, tmpfs, or ignore (default bind) - type: str - choices: - - 'bind' - - 'tmpfs' - - 'ignore' - image_strict: - description: - - Whether to compare images in idempotency by taking into account a full - name with registry and namespaces. - type: bool - default: False - init: - description: - - Run an init inside the container that forwards signals and reaps - processes. The default is false. - type: bool - init_path: - description: - - Path to the container-init binary. - type: str - interactive: - description: - - Keep STDIN open even if not attached. The default is false. - When set to true, keep stdin open even if not attached. - The default is false. - type: bool - ip: - description: - - Specify a static IP address for the container, for example - '10.88.64.128'. - Can only be used if no additional CNI networks to join were specified - via 'network:', and if the container is not joining another container's - network namespace via 'network container:'. - The address must be within the default CNI network's pool - (default 10.88.0.0/16). - type: str - ipc: - description: - - Default is to create a private IPC namespace (POSIX SysV IPC) for the - container - type: str - aliases: - - ipc_mode - kernel_memory: - description: - - Kernel memory limit - (format [], where unit = b, k, m or g) - Note - idempotency is supported for integers only. - type: str - label: - description: - - Add metadata to a container, pass dictionary of label names and values - aliases: - - labels - type: dict - label_file: - description: - - Read in a line delimited file of labels - type: str - log_driver: - description: - - Logging driver. Used to set the log driver for the container. - For example log_driver "k8s-file". - type: str - choices: - - k8s-file - - journald - - json-file - log_level: - description: - - Logging level for Podman. Log messages above specified level - ("debug"|"info"|"warn"|"error"|"fatal"|"panic") (default "error") - type: str - choices: - - debug - - info - - warn - - error - - fatal - - panic - log_opt: - description: - - Logging driver specific options. Used to set the path to the container - log file. - type: dict - aliases: - - log_options - suboptions: - path: - description: - - Specify a path to the log file (e.g. /var/log/container/mycontainer.json). - type: str - required: false - max_size: - description: - - Specify a max size of the log file (e.g 10mb). - type: str - required: false - tag: - description: - - Specify a custom log tag for the container. - type: str - required: false - - mac_address: - description: - - Specify a MAC address for the container, for example - '92:d0:c6:0a:29:33'. - Don't forget that it must be unique within one Ethernet network. - type: str - memory: - description: - - Memory limit (format 10k, where unit = b, k, m or g) - Note - idempotency is supported for integers only. - type: str - memory_reservation: - description: - - Memory soft limit (format 100m, where unit = b, k, m or g) - Note - idempotency is supported for integers only. - type: str - memory_swap: - description: - - A limit value equal to memory plus swap. Must be used with the -m - (--memory) flag. - The swap LIMIT should always be larger than -m (--memory) value. - By default, the swap LIMIT will be set to double the value of --memory - Note - idempotency is supported for integers only. - type: str - memory_swappiness: - description: - - Tune a container's memory swappiness behavior. Accepts an integer - between 0 and 100. - type: int - mount: - description: - - Attach a filesystem mount to the container. bind or tmpfs - For example mount - "type=bind,source=/path/on/host,destination=/path/in/container" - type: str - network: - description: - - Set the Network mode for the container - * bridge create a network stack on the default bridge - * none no networking - * container: reuse another container's network stack - * host use the podman host network stack. - * | connect to a user-defined network - * ns: path to a network namespace to join - * slirp4netns use slirp4netns to create a user network stack. - This is the default for rootless containers - type: list - elements: str - aliases: - - net - - network_mode - no_hosts: - description: - - Do not create /etc/hosts for the container - Default is false. - type: bool - oom_kill_disable: - description: - - Whether to disable OOM Killer for the container or not. - Default is false. - type: bool - oom_score_adj: - description: - - Tune the host's OOM preferences for containers (accepts -1000 to 1000) - type: int - pid: - description: - - Set the PID mode for the container - type: str - aliases: - - pid_mode - pids_limit: - description: - - Tune the container's PIDs limit. Set -1 to have unlimited PIDs for the - container. - type: str - pod: - description: - - Run container in an existing pod. - If you want podman to make the pod for you, preference the pod name - with "new:" - type: str - privileged: - description: - - Give extended privileges to this container. The default is false. - type: bool - publish: - description: - - Publish a container's port, or range of ports, to the host. - Format - ip:hostPort:containerPort | ip::containerPort | - hostPort:containerPort | containerPort - In case of only containerPort is set, the hostPort will chosen - randomly by Podman. - type: list - elements: str - aliases: - - ports - - published - - published_ports - publish_all: - description: - - Publish all exposed ports to random ports on the host interfaces. The - default is false. - type: bool - read_only: - description: - - Mount the container's root filesystem as read only. Default is false - type: bool - read_only_tmpfs: - description: - - If container is running in --read-only mode, then mount a read-write - tmpfs on /run, /tmp, and /var/tmp. The default is true - type: bool - recreate: - description: - - Use with present and started states to force the re-creation of an - existing container. - type: bool - default: False - restart_policy: - description: - - Restart policy to follow when containers exit. - Restart policy will not take effect if a container is stopped via the - podman kill or podman stop commands. Valid values are - * no - Do not restart containers on exit - * on-failure[:max_retries] - Restart containers when they exit with a - non-0 exit code, retrying indefinitely - or until the optional max_retries count is hit - * always - Restart containers when they exit, regardless of status, - retrying indefinitely - type: str - rm: - description: - - Automatically remove the container when it exits. The default is false. - type: bool - aliases: - - remove - - auto_remove - rootfs: - description: - - If true, the first argument refers to an exploded container on the file - system. The default is false. - type: bool - security_opt: - description: - - Security Options. For example security_opt "seccomp=unconfined" - type: list - elements: str - shm_size: - description: - - Size of /dev/shm. The format is . number must be greater - than 0. - Unit is optional and can be b (bytes), k (kilobytes), m(megabytes), or - g (gigabytes). - If you omit the unit, the system uses bytes. If you omit the size - entirely, the system uses 64m - type: str - sig_proxy: - description: - - Proxy signals sent to the podman run command to the container process. - SIGCHLD, SIGSTOP, and SIGKILL are not proxied. The default is true. - type: bool - stop_signal: - description: - - Signal to stop a container. Default is SIGTERM. - type: int - stop_timeout: - description: - - Timeout (in seconds) to stop a container. Default is 10. - type: int - subgidname: - description: - - Run the container in a new user namespace using the map with 'name' in - the /etc/subgid file. - type: str - subuidname: - description: - - Run the container in a new user namespace using the map with 'name' in - the /etc/subuid file. - type: str - sysctl: - description: - - Configure namespaced kernel parameters at runtime - type: dict - systemd: - description: - - Run container in systemd mode. The default is true. - type: str - tmpfs: - description: - - Create a tmpfs mount. For example tmpfs - "/tmp" "rw,size=787448k,mode=1777" - type: dict - tty: - description: - - Allocate a pseudo-TTY. The default is false. - type: bool - uidmap: - description: - - Run the container in a new user namespace using the supplied mapping. - type: list - elements: str - ulimit: - description: - - Ulimit options - type: list - aliases: - - ulimits - user: - description: - - Sets the username or UID used and optionally the groupname or GID for - the specified command. - type: str - userns: - description: - - Set the user namespace mode for the container. - It defaults to the PODMAN_USERNS environment variable. - An empty value means user namespaces are disabled. - type: str - aliases: - - userns_mode - uts: - description: - - Set the UTS mode for the container - type: str - volume: - description: - - Create a bind mount. If you specify, volume /HOST-DIR:/CONTAINER-DIR, - podman bind mounts /HOST-DIR in the host to /CONTAINER-DIR in the - podman container. - type: list - elements: str - aliases: - - volumes - volumes_from: - description: - - Mount volumes from the specified container(s). - type: list - elements: str - workdir: - description: - - Working directory inside the container. - The default working directory for running binaries within a container - is the root directory (/). - type: str - aliases: - - working_dir -""" - -EXAMPLES = r""" -- name: Run container - podman_container: - name: container - image: quay.io/bitnami/wildfly - state: started - -- name: Create a data container - podman_container: - name: mydata - image: busybox - volume: - - /tmp/data - -- name: Re-create a redis container - podman_container: - name: myredis - image: redis - command: redis-server --appendonly yes - state: present - recreate: yes - expose: - - 6379 - volumes_from: - - mydata - -- name: Restart a container - podman_container: - name: myapplication - image: redis - state: started - restart: yes - etc_hosts: - other: "127.0.0.1" - restart_policy: "no" - device: "/dev/sda:/dev/xvda:rwm" - ports: - - "8080:9000" - - "127.0.0.1:8081:9001/udp" - env: - SECRET_KEY: "ssssh" - BOOLEAN_KEY: "yes" - -- name: Container present - podman_container: - name: mycontainer - state: present - image: ubuntu:14.04 - command: "sleep 1d" - -- name: Stop a container - podman_container: - name: mycontainer - state: stopped - -- name: Start 4 load-balanced containers - podman_container: - name: "container{{ item }}" - recreate: yes - image: someuser/anotherappimage - command: sleep 1d - with_sequence: count=4 - -- name: remove container - podman_container: - name: ohno - state: absent - -- name: Writing output - podman_container: - name: myservice - image: busybox - log_options: path=/var/log/container/mycontainer.json - log_driver: k8s-file -""" - -RETURN = r""" -container: - description: - - Facts representing the current state of the container. Matches the - podman inspection output. - - Note that facts are part of the registered vars since Ansible 2.8. For - compatibility reasons, the facts - are also accessible directly as C(podman_container). Note that the - returned fact will be removed in Ansible 2.12. - - Empty if C(state) is I(absent). - returned: always - type: dict - sample: '{ - "AppArmorProfile": "", - "Args": [ - "sh" - ], - "BoundingCaps": [ - "CAP_CHOWN", - ... - ], - "Config": { - "Annotations": { - "io.kubernetes.cri-o.ContainerType": "sandbox", - "io.kubernetes.cri-o.TTY": "false" - }, - "AttachStderr": false, - "AttachStdin": false, - "AttachStdout": false, - "Cmd": [ - "sh" - ], - "Domainname": "", - "Entrypoint": "", - "Env": [ - "PATH=/usr/sbin:/usr/bin:/sbin:/bin", - "TERM=xterm", - "HOSTNAME=", - "container=podman" - ], - "Hostname": "", - "Image": "docker.io/library/busybox:latest", - "Labels": null, - "OpenStdin": false, - "StdinOnce": false, - "StopSignal": 15, - "Tty": false, - "User": { - "gid": 0, - "uid": 0 - }, - "Volumes": null, - "WorkingDir": "/" - }, - "ConmonPidFile": "...", - "Created": "2019-06-17T19:13:09.873858307+03:00", - "Dependencies": [], - "Driver": "overlay", - "EffectiveCaps": [ - "CAP_CHOWN", - ... - ], - "ExecIDs": [], - "ExitCommand": [ - "/usr/bin/podman", - "--root", - ... - ], - "GraphDriver": { - ... - }, - "HostConfig": { - ... - }, - "HostnamePath": "...", - "HostsPath": "...", - "ID": "...", - "Image": "...", - "ImageName": "docker.io/library/busybox:latest", - "IsInfra": false, - "LogPath": "/tmp/container/mycontainer.json", - "MountLabel": "system_u:object_r:container_file_t:s0:c282,c782", - "Mounts": [ - ... - ], - "Name": "myservice", - "Namespace": "", - "NetworkSettings": { - "Bridge": "", - ... - }, - "Path": "sh", - "ProcessLabel": "system_u:system_r:container_t:s0:c282,c782", - "ResolvConfPath": "...", - "RestartCount": 0, - "Rootfs": "", - "State": { - "Dead": false, - "Error": "", - "ExitCode": 0, - "FinishedAt": "2019-06-17T19:13:10.157518963+03:00", - "Healthcheck": { - "FailingStreak": 0, - "Log": null, - "Status": "" - }, - "OOMKilled": false, - "OciVersion": "1.0.1-dev", - "Paused": false, - "Pid": 4083, - "Restarting": false, - "Running": false, - "StartedAt": "2019-06-17T19:13:10.152479729+03:00", - "Status": "exited" - }, - "StaticDir": "..." - ... - }' -""" - -from ansible.module_utils.basic import AnsibleModule # noqa: F402 - -try: - from ansible.module_utils.podman.podman_container_lib import PodmanManager - from ansible.module_utils.podman.podman_container_lib import ARGUMENTS_SPEC_CONTAINER # noqa: F402 -except ImportError: - from tripleo_ansible.ansible_plugins.module_utils.podman.podman_container_lib import PodmanManager # noqa: F402 - from tripleo_ansible.ansible_plugins.module_utils.podman.podman_container_lib import ARGUMENTS_SPEC_CONTAINER # noqa: F402 - - -def main(): - module = AnsibleModule( - argument_spec=ARGUMENTS_SPEC_CONTAINER, - mutually_exclusive=( - ['no_hosts', 'etc_hosts'], - ), - supports_check_mode=True, - ) - - # work on input vars - if (module.params['state'] in ['started', 'present', 'created'] - and not module.params['force_restart'] - and not module.params['image']): - module.fail_json(msg="State '%s' required image to be configured!" % - module.params['state']) - - results = PodmanManager(module, module.params).execute() - module.exit_json(**results) - - -if __name__ == '__main__': - main() diff --git a/tripleo_ansible/ansible_plugins/modules/podman_container_info.py b/tripleo_ansible/ansible_plugins/modules/podman_container_info.py deleted file mode 100644 index 6fbf33064..000000000 --- a/tripleo_ansible/ansible_plugins/modules/podman_container_info.py +++ /dev/null @@ -1,426 +0,0 @@ -# Copyright 2019 Red Hat, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -DOCUMENTATION = r''' -module: podman_container_info -author: - - Sagi Shnaidman (@sshnaidm) - - Emilien Macchi (@EmilienM) -short_description: Gather facts about containers using podman -notes: - - Podman may require elevated privileges in order to run properly. -description: - - Gather facts about containers using C(podman) -requirements: - - "Podman installed on host" -options: - name: - description: - - List of container names to gather facts about. If no name is given - return facts about all containers. - type: list - elements: str - executable: - description: - - Path to C(podman) executable if it is not in the C($PATH) on the - machine running C(podman) - default: 'podman' - type: str -''' - -EXAMPLES = r""" -- name: Gather facts for all containers - podman_container_info: - -- name: Gather facts on a specific container - podman_container_info: - name: web1 - -- name: Gather facts on several containers - podman_container_info: - name: - - redis - - web1 -""" - -RETURN = r""" -containers: - description: Facts from all or specificed containers - returned: always - type: list - elements: dict - sample: [ - { - "Id": "c5c39f9b80a6ea2ad665aa9946435934e478a0c5322da835f3883872f", - "Created": "2019-10-01T12:51:00.233106443Z", - "Path": "dumb-init", - "Args": [ - "--single-child", - "--", - "kolla_start" - ], - "State": { - "OciVersion": "1.0.1-dev", - "Status": "configured", - "Running": false, - "Paused": false, - "Restarting": false, - "OOMKilled": false, - "Dead": false, - "Pid": 0, - "ExitCode": 0, - "Error": "", - "StartedAt": "0001-01-01T00:00:00Z", - "FinishedAt": "0001-01-01T00:00:00Z", - "Healthcheck": { - "Status": "", - "FailingStreak": 0, - "Log": null - } - }, - "Image": "0e267acda67d0ebd643e900d820a91b961d859743039e620191ca1", - "ImageName": "docker.io/tripleomaster/centos-haproxy:latest", - "Rootfs": "", - "Pod": "", - "ResolvConfPath": "", - "HostnamePath": "", - "HostsPath": "", - "OCIRuntime": "runc", - "Name": "haproxy", - "RestartCount": 0, - "Driver": "overlay", - "MountLabel": "system_u:object_r:svirt_sandbox_file_t:s0:c78,c866", - "ProcessLabel": "system_u:system_r:svirt_lxc_net_t:s0:c785,c866", - "AppArmorProfile": "", - "EffectiveCaps": [ - "CAP_CHOWN", - "CAP_DAC_OVERRIDE", - "CAP_FSETID", - "CAP_FOWNER", - "CAP_MKNOD", - "CAP_NET_RAW", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETFCAP", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_SYS_CHROOT", - "CAP_KILL", - "CAP_AUDIT_WRITE" - ], - "BoundingCaps": [ - "CAP_CHOWN", - "CAP_DAC_OVERRIDE", - "CAP_FSETID", - "CAP_FOWNER", - "CAP_MKNOD", - "CAP_NET_RAW", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETFCAP", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_SYS_CHROOT", - "CAP_KILL", - "CAP_AUDIT_WRITE" - ], - "ExecIDs": [], - "GraphDriver": { - "Name": "overlay" - }, - "Mounts": [], - "Dependencies": [], - "NetworkSettings": { - "Bridge": "", - "SandboxID": "", - "HairpinMode": false, - "LinkLocalIPv6Address": "", - "LinkLocalIPv6PrefixLen": 0, - "Ports": [], - "SandboxKey": "", - "SecondaryIPAddresses": null, - "SecondaryIPv6Addresses": null, - "EndpointID": "", - "Gateway": "", - "GlobalIPv6Address": "", - "GlobalIPv6PrefixLen": 0, - "IPAddress": "", - "IPPrefixLen": 0, - "IPv6Gateway": "", - "MacAddress": "" - }, - "ExitCommand": [ - "/usr/bin/podman", - "--root", - "/var/lib/containers/storage", - "--runroot", - "/var/run/containers/storage", - "--log-level", - "error", - "--cgroup-manager", - "systemd", - "--tmpdir", - "/var/run/libpod", - "--runtime", - "runc", - "--storage-driver", - "overlay", - "--events-backend", - "journald", - "container", - "cleanup", - "c9e813703f9b80a6ea2ad665aa9946435934e478a0c5322da835f3883872f" - ], - "Namespace": "", - "IsInfra": false, - "Config": { - "Hostname": "c5c39e813703", - "Domainname": "", - "User": "", - "AttachStdin": false, - "AttachStdout": false, - "AttachStderr": false, - "Tty": false, - "OpenStdin": false, - "StdinOnce": false, - "Env": [ - "PATH=/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", - "TERM=xterm", - "HOSTNAME=", - "container=oci", - "KOLLA_INSTALL_METATYPE=rdo", - "KOLLA_BASE_DISTRO=centos", - "KOLLA_INSTALL_TYPE=binary", - "KOLLA_DISTRO_PYTHON_VERSION=2.7", - "KOLLA_BASE_ARCH=x86_64" - ], - "Cmd": [ - "kolla_start" - ], - "Image": "docker.io/tripleomaster/centos-haproxy:latest", - "Volumes": null, - "WorkingDir": "/", - "Entrypoint": "dumb-init --single-child --", - "OnBuild": null, - "Labels": { - "build-date": "20190919", - "kolla_version": "8.1.0", - "name": "haproxy", - "org.label-schema.build-date": "20190801", - "org.label-schema.license": "GPLv2", - "org.label-schema.name": "CentOS Base Image", - "org.label-schema.schema-version": "1.0", - "org.label-schema.vendor": "CentOS" - }, - "Annotations": { - "io.kubernetes.cri-o.ContainerType": "sandbox", - "io.kubernetes.cri-o.TTY": "false", - "io.podman.annotations.autoremove": "FALSE", - "io.podman.annotations.init": "FALSE", - "io.podman.annotations.privileged": "FALSE", - "io.podman.annotations.publish-all": "FALSE" - }, - "StopSignal": 15 - }, - "HostConfig": { - "Binds": [], - "ContainerIDFile": "", - "LogConfig": { - "Type": "k8s-file", - "Config": null - }, - "NetworkMode": "default", - "PortBindings": {}, - "RestartPolicy": { - "Name": "", - "MaximumRetryCount": 0 - }, - "AutoRemove": false, - "VolumeDriver": "", - "VolumesFrom": null, - "CapAdd": [], - "CapDrop": [], - "Dns": [], - "DnsOptions": [], - "DnsSearch": [], - "ExtraHosts": [], - "GroupAdd": [], - "IpcMode": "", - "Cgroup": "", - "Links": null, - "OomScoreAdj": 0, - "PidMode": "", - "Privileged": false, - "PublishAllPorts": false, - "ReadonlyRootfs": false, - "SecurityOpt": [], - "Tmpfs": {}, - "UTSMode": "", - "UsernsMode": "", - "ShmSize": 65536000, - "Runtime": "oci", - "ConsoleSize": [ - 0, - 0 - ], - "Isolation": "", - "CpuShares": 0, - "Memory": 0, - "NanoCpus": 0, - "CgroupParent": "", - "BlkioWeight": 0, - "BlkioWeightDevice": null, - "BlkioDeviceReadBps": null, - "BlkioDeviceWriteBps": null, - "BlkioDeviceReadIOps": null, - "BlkioDeviceWriteIOps": null, - "CpuPeriod": 0, - "CpuQuota": 0, - "CpuRealtimePeriod": 0, - "CpuRealtimeRuntime": 0, - "CpusetCpus": "", - "CpusetMems": "", - "Devices": [], - "DiskQuota": 0, - "KernelMemory": 0, - "MemoryReservation": 0, - "MemorySwap": 0, - "MemorySwappiness": -1, - "OomKillDisable": false, - "PidsLimit": 0, - "Ulimits": [ - { - "Name": "RLIMIT_NOFILE", - "Soft": 1048576, - "Hard": 1048576 - }, - { - "Name": "RLIMIT_NPROC", - "Soft": 1048576, - "Hard": 1048576 - } - ], - "CpuCount": 0, - "CpuPercent": 0, - "IOMaximumIOps": 0, - "IOMaximumBandwidth": 0 - } - } - ] -""" - -import json # noqa: F402 -import time -from ansible.module_utils.basic import AnsibleModule # noqa: F402 - - -def get_containers_facts(module, executable, name): - """Collect containers facts for all containers or for specified in 'name'. - - Arguments: - module {AnsibleModule} -- instance of AnsibleModule - executable {string} -- binary to execute when inspecting containers - name {list} -- list of names or None in case of all containers - - Returns: - list of containers info, stdout, stderr - """ - retry = 0 - retry_limit = 4 - if not name: - all_names = [executable, 'container', 'ls', '-q', '-a'] - rc, out, err = module.run_command(all_names) - # This should not fail in regular circumstances, so retry again - # https://github.com/containers/podman/issues/10225 - while rc != 0 and retry <= retry_limit: - module.log(msg="Unable to get list of containers: %s" % err) - time.sleep(1) - retry += 1 - rc, out, err = module.run_command(all_names) - if rc != 0: - module.fail_json(msg="Unable to get list of containers during" - " %s retries" % retry_limit) - name = out.split() - if not name: - return [], out, err - command = [executable, 'container', 'inspect'] - command.extend(name) - rc, out, err = module.run_command(command) - if rc == 0: - json_out = json.loads(out) if out else None - if json_out is None: - return [], out, err - return json_out, out, err - if rc != 0 and 'no such ' in err: - if len(name) < 2: - return [], out, err - return cycle_over(module, executable, name) - module.fail_json(msg="Unable to gather info for %s: %s" % (",".join(name), err)) - - -def cycle_over(module, executable, name): - """Inspect each container in a cycle in case some of them don't exist. - - Arguments: - module {AnsibleModule} -- instance of AnsibleModule - executable {string} -- binary to execute when inspecting containers - name {list} -- list of containers names to inspect - - Returns: - list of containers info, stdout as empty, stderr - """ - inspection = [] - stderrs = [] - for container in name: - command = [executable, 'container', 'inspect', container] - rc, out, err = module.run_command(command) - if rc != 0 and 'no such ' not in err: - module.fail_json(msg="Unable to gather info for %s: %s" % (container, err)) - if rc == 0 and out: - json_out = json.loads(out) - if json_out: - inspection += json_out - stderrs.append(err) - return inspection, "", "\n".join(stderrs) - - -def main(): - module = AnsibleModule( - argument_spec=dict( - executable=dict(type='str', default='podman'), - name=dict(type='list', elements='str') - ), - supports_check_mode=True, - ) - - name = module.params['name'] - executable = module.get_bin_path(module.params['executable'], required=True) - # pylint: disable=unused-variable - inspect_results, out, err = get_containers_facts(module, executable, name) - - results = { - "changed": False, - "containers": inspect_results, - "stderr": err - } - - module.exit_json(**results) - - -if __name__ == '__main__': - main() diff --git a/tripleo_ansible/ansible_plugins/modules/podman_containers.py b/tripleo_ansible/ansible_plugins/modules/podman_containers.py deleted file mode 100644 index ab5ba079c..000000000 --- a/tripleo_ansible/ansible_plugins/modules/podman_containers.py +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# Copyright 2020 Red Hat, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - -ANSIBLE_METADATA = { - 'metadata_version': '1.0', - 'status': ['preview'], - 'supported_by': 'community' -} - -DOCUMENTATION = ''' ---- -module: podman_containers -author: - - "Sagi Shnaidman (@sshnaidm)" -version_added: '2.9' -short_description: Manage podman containers in a batch -notes: [] -description: - - Manage groups of podman containers -requirements: - - "Podman installed on host" -options: - containers: - description: - - List of dictionaries with data for running containers - for podman_container module. - required: True - type: list - elements: dict -''' - -EXAMPLES = ''' -- name: Run three containers at once - podman_containers: - containers: - - name: alpine - image: alpine - command: sleep 1d - - name: web - image: nginx - - name: test - image: python:3-alpine - command: python -V -''' diff --git a/tripleo_ansible/ansible_plugins/modules/podman_volume_info.py b/tripleo_ansible/ansible_plugins/modules/podman_volume_info.py deleted file mode 100644 index a4c0fa776..000000000 --- a/tripleo_ansible/ansible_plugins/modules/podman_volume_info.py +++ /dev/null @@ -1,115 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -__metaclass__ = type - -ANSIBLE_METADATA = { - 'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community' -} - -DOCUMENTATION = """ -module: podman_volume_info -author: - - "Sagi Shnaidman (@sshnaidm)" -version_added: '2.10' -short_description: Gather info about podman volumes -notes: [] -description: - - Gather info about podman volumes with podman inspect command. -requirements: - - "Podman installed on host" -options: - name: - description: - - Name of the volume - type: str - executable: - description: - - Path to C(podman) executable if it is not in the C($PATH) on the - machine running C(podman) - default: 'podman' - type: str -""" -EXAMPLES = """ -- name: Gather info about all present volumes - podman_volume_info: - -- name: Gather info about specific volume - podman_volume_info: - name: specific_volume -""" -RETURN = """ -volumes: - description: Facts from all or specified volumes - returned: always - type: list - sample: [ - { - "name": "testvolume", - "labels": {}, - "mountPoint": "/home/ansible/.local/share/testvolume/_data", - "driver": "local", - "options": {}, - "scope": "local" - } - ] -""" - -import json -from ansible.module_utils.basic import AnsibleModule - - -def get_volume_info(module, executable, name): - command = [executable, 'volume', 'inspect'] - if name: - command.append(name) - else: - command.append("--all") - rc, out, err = module.run_command(command) - if rc != 0 or 'no such volume' in err: - module.fail_json(msg="Unable to gather info for %s: %s" % (name or 'all volumes', err)) - if not out or json.loads(out) is None: - return [], out, err - return json.loads(out), out, err - - -def main(): - module = AnsibleModule( - argument_spec=dict( - executable=dict(type='str', default='podman'), - name=dict(type='str') - ), - supports_check_mode=True, - ) - - name = module.params['name'] - executable = module.get_bin_path(module.params['executable'], required=True) - - inspect_results, out, err = get_volume_info(module, executable, name) - - results = { - "changed": False, - "volumes": inspect_results, - "stderr": err - } - - module.exit_json(**results) - - -if __name__ == '__main__': - main() diff --git a/tripleo_ansible/ansible_plugins/tests/molecule/podman_container/converge.yml b/tripleo_ansible/ansible_plugins/tests/molecule/podman_container/converge.yml deleted file mode 100644 index ed50a7c0d..000000000 --- a/tripleo_ansible/ansible_plugins/tests/molecule/podman_container/converge.yml +++ /dev/null @@ -1,438 +0,0 @@ ---- -- name: Converge - hosts: all - tasks: - - name: Test podman_container - become: true - block: - - name: Delete all container leftovers from tests - podman_container: - name: "{{ item }}" - state: absent - loop: - - "ubi-minimal" - - "container" - - "container2" - - - name: Test no image with default action - podman_container: - name: container - ignore_errors: true - register: no_image - - - name: Test no image with state 'started' - podman_container: - name: container - state: started - ignore_errors: true - register: no_image1 - - - name: Test no image with state 'present' - podman_container: - name: container - state: present - ignore_errors: true - register: no_image2 - - - name: Check no image - assert: - that: - - no_image is failed - - no_image1 is failed - - no_image2 is failed - - no_image.msg == "State 'started' required image to be configured!" - - no_image1.msg == "State 'started' required image to be configured!" - - no_image2.msg == "State 'present' required image to be configured!" - fail_msg: No image test failed! - success_msg: No image test passed! - - - name: Ensure image doesn't exist - podman_image: - name: registry.access.redhat.com/ubi8/ubi-minimal - state: absent - - - name: Check pulling image - podman_container: - name: container - image: registry.access.redhat.com/ubi8/ubi-minimal - state: present - command: sleep 1d - register: image - - - name: Check using already pulled image - podman_container: - name: container2 - image: registry.access.redhat.com/ubi8/ubi-minimal - state: present - command: sleep 1d - register: image2 - - - name: Check output is correct - assert: - that: - - image is changed - - image.container is defined - - image.container['State']['Running'] - - "'pulled image registry.access.redhat.com/ubi8/ubi-minimal' in image.actions" - - "'started container' in image.actions" - - image2 is changed - - image2.container is defined - - image2.container['State']['Running'] - - "'pulled image registry.access.redhat.com/ubi8/ubi-minimal' not in image2.actions" - - "'started container2' in image2.actions" - fail_msg: Pulling image test failed! - success_msg: Pulling image test passed! - - - name: Check failed image pull - podman_container: - name: container - image: quay.io/ineverneverneverexist - state: present - command: sleep 1d - register: imagefail - ignore_errors: true - - - name: Check output is correct - assert: - that: - - imagefail is failed - - - name: Force container recreate - podman_container: - name: container - image: registry.access.redhat.com/ubi8/ubi-minimal - state: present - command: sleep 1d - recreate: true - register: recreated - - - name: Check output is correct - assert: - that: - - recreated is changed - - recreated.container is defined - - recreated.container['State']['Running'] - - "'recreated container' in recreated.actions" - fail_msg: Force recreate test failed! - success_msg: Force recreate test passed! - - - name: Stop container - podman_container: - name: container - state: stopped - register: stopped - - - name: Stop the same container again (idempotency) - podman_container: - name: container - state: stopped - register: stopped_again - - - name: Check output is correct - assert: - that: - - stopped is changed - - stopped.container is defined - - not stopped.container['State']['Running'] - - "'stopped container' in stopped.actions" - - stopped_again is not changed - - stopped_again.container is defined - - not stopped_again.container['State']['Running'] - - stopped_again.actions == [] - fail_msg: Stopping container test failed! - success_msg: Stopping container test passed! - - - name: Delete stopped container - podman_container: - name: container - state: absent - register: deleted - - - name: Delete again container (idempotency) - podman_container: - name: container - state: absent - register: deleted_again - - - name: Check output is correct - assert: - that: - - deleted is changed - - deleted.container is defined - - deleted.container == {} - - "'deleted container' in deleted.actions" - - deleted_again is not changed - - deleted_again.container is defined - - deleted_again.container == {} - - deleted_again.actions == [] - fail_msg: Deleting stopped container test failed! - success_msg: Deleting stopped container test passed! - - - name: Create container, but don't run - podman_container: - name: container - image: registry.access.redhat.com/ubi8/ubi-minimal - state: stopped - command: sleep 1d - register: created - - - name: Check output is correct - assert: - that: - - created is changed - - created.container is defined - - created.container != {} - - not created.container['State']['Running'] - - "'created container' in created.actions" - fail_msg: "Creating stopped container test failed!" - success_msg: "Creating stopped container test passed!" - - - name: Delete created container - podman_container: - name: container - state: absent - - - name: Start container that was deleted - podman_container: - name: container - image: registry.access.redhat.com/ubi8/ubi-minimal - state: started - command: sleep 1d - register: started - - - name: Check output is correct - assert: - that: - - started is changed - - started.container is defined - - started.container['State']['Running'] - - "'pulled image registry.access.redhat.com/ubi8/ubi-minimal' not in started.actions" - - - name: Delete started container - podman_container: - name: container - state: absent - register: deleted - - - name: Delete again container (idempotency) - podman_container: - name: container - state: absent - register: deleted_again - - - name: Check output is correct - assert: - that: - - deleted is changed - - deleted.container is defined - - deleted.container == {} - - "'deleted container' in deleted.actions" - - deleted_again is not changed - - deleted_again.container is defined - - deleted_again.container == {} - - deleted_again.actions == [] - fail_msg: Deleting started container test failed! - success_msg: Deleting started container test passed! - - - name: Recreate container with parameters - podman_container: - name: container - image: registry.access.redhat.com/ubi8/ubi-minimal - state: started - command: sleep 1d - recreate: true - etc_hosts: - host1: 127.0.0.1 - host2: 127.0.0.1 - annotation: - this: "annotation_value" - dns: - - 1.1.1.1 - - 8.8.4.4 - dns_search: example.com - cap_add: - - SYS_TIME - - NET_ADMIN - publish: - - "9000:80" - - "9001:8000" - workdir: "/bin" - env: - FOO: bar - BAR: foo - TEST: 1 - BOOL: false - label: - somelabel: labelvalue - otheralbe: othervalue - volumes: - - /tmp:/data - register: test - - - name: Check output is correct - assert: - that: - - test is changed - - test.container is defined - - test.container != {} - - test.container['State']['Running'] - # test capabilities - - "'CAP_SYS_TIME' in test.container['BoundingCaps']" - - "'CAP_NET_ADMIN' in test.container['BoundingCaps']" - # test annotations - - test.container['Config']['Annotations']['this'] is defined - - test.container['Config']['Annotations']['this'] == "annotation_value" - # test DNS - - >- - (test.container['HostConfig']['Dns'] is defined and - test.container['HostConfig']['Dns'] == ['1.1.1.1', '8.8.4.4']) or - (test.container['HostConfig']['DNS'] is defined and - test.container['HostConfig']['DNS'] == ['1.1.1.1', '8.8.4.4']) - # test ports - - test.container['NetworkSettings']['Ports']|length == 2 - # test working dir - - test.container['Config']['WorkingDir'] == "/bin" - # test dns search - - >- - (test.container['HostConfig']['DnsSearch'] is defined and - test.container['HostConfig']['DnsSearch'] == ['example.com']) or - (test.container['HostConfig']['DNSSearch'] is defined and - test.container['HostConfig']['DNSSearch'] == ['example.com']) - # test environment variables - - "'FOO=bar' in test.container['Config']['Env']" - - "'BAR=foo' in test.container['Config']['Env']" - - "'TEST=1' in test.container['Config']['Env']" - - "'BOOL=False' in test.container['Config']['Env']" - # test labels - - test.container['Config']['Labels'] | length >= 2 - - test.container['Config']['Labels']['somelabel'] == "labelvalue" - - test.container['Config']['Labels']['otheralbe'] == "othervalue" - # test mounts - - >- - (test.container['Mounts'][0]['Destination'] is defined and - '/data' in test.container['Mounts'] | map(attribute='Destination') | list) or - (test.container['Mounts'][0]['destination'] is defined and - '/data' in test.container['Mounts'] | map(attribute='destination') | list) - - >- - (test.container['Mounts'][0]['Source'] is defined and - '/tmp' in test.container['Mounts'] | map(attribute='Source') | list) or - (test.container['Mounts'][0]['source'] is defined and - '/tmp' in test.container['Mounts'] | map(attribute='source') | list) - fail_msg: Parameters container test failed! - success_msg: Parameters container test passed! - - - name: Check basic idempotency of running container - podman_container: - name: testidem - image: registry.access.redhat.com/ubi8/ubi-minimal - state: present - command: sleep 20m - - - name: Check basic idempotency of running container - run it again - podman_container: - name: testidem - image: ubi-minimal:latest - state: present - command: sleep 20m - register: idem - - - name: Check that nothing was changed - assert: - that: - - not idem.changed - - - name: Run changed container (with tty enabled) - podman_container: - name: testidem - image: ubi-minimal - state: present - command: sleep 20m - tty: true - register: idem1 - - - name: Check that container is recreated when changed - assert: - that: - - idem1 is changed - - - name: Run changed container without specifying an option, use defaults - podman_container: - name: testidem - image: ubi-minimal - state: present - command: sleep 20m - register: idem2 - - - name: Check that container is recreated when changed to default value - assert: - that: - - idem2 is changed - - - name: Remove container - podman_container: - name: testidem - state: absent - register: remove - - - name: Check podman_actions - assert: - that: - - "'podman rm -f testidem' in remove.podman_actions" - - - name: Check basic idempotency of pod container - podman_container: - name: testidem-pod - image: registry.access.redhat.com/ubi8/ubi-minimal - state: present - command: sleep 20m - pod: "new:testidempod" - - - name: Check basic idempotency of pod container - run it again - podman_container: - name: testidem-pod - image: ubi-minimal:latest - state: present - command: sleep 20m - pod: testidempod - register: idem - - - name: Check that nothing was changed in pod containers - assert: - that: - - not idem.changed - - - name: Run changed pod container (with tty enabled) - podman_container: - name: testidem-pod - image: ubi-minimal - state: present - command: sleep 20m - tty: true - pod: testidempod - register: idem1 - - - name: Check that container is recreated when changed - assert: - that: - - idem1 is changed - - - name: Remove container - podman_container: - name: testidem-pod - state: absent - - always: - - name: Delete all container leftovers from tests - podman_container: - name: "{{ item }}" - state: absent - loop: - - "container" - - "container2" - - "ubi-minimal" - - "web" - - "test" - - "testidem" - - - name: Remove pod - shell: podman pod rm -f testidempod diff --git a/tripleo_ansible/ansible_plugins/tests/molecule/podman_container/molecule.yml b/tripleo_ansible/ansible_plugins/tests/molecule/podman_container/molecule.yml deleted file mode 100644 index 006e9ffef..000000000 --- a/tripleo_ansible/ansible_plugins/tests/molecule/podman_container/molecule.yml +++ /dev/null @@ -1,50 +0,0 @@ ---- -driver: - name: delegated - options: - managed: false - login_cmd_template: >- - ssh - -o UserKnownHostsFile=/dev/null - -o StrictHostKeyChecking=no - -o Compression=no - -o TCPKeepAlive=yes - -o VerifyHostKeyDNS=no - -o ForwardX11=no - -o ForwardAgent=no - {instance} - ansible_connection_options: - ansible_connection: ssh - -log: true - -platforms: - - name: instance - -provisioner: - name: ansible - config_options: - defaults: - fact_caching: jsonfile - fact_caching_connection: /tmp/molecule/facts - inventory: - hosts: - all: - hosts: - instance: - ansible_host: localhost - log: true - env: - ANSIBLE_STDOUT_CALLBACK: yaml - ANSIBLE_ROLES_PATH: "${ANSIBLE_ROLES_PATH:-/usr/share/ansible/roles}:${HOME}/zuul-jobs/roles" - ANSIBLE_LIBRARY: "${ANSIBLE_LIBRARY:-/usr/share/ansible/plugins/modules}" - ANSIBLE_FILTER_PLUGINS: "${ANSIBLE_FILTER_PLUGINS:-/usr/share/ansible/plugins/filter}" - -scenario: - test_sequence: - - prepare - - converge - - verify - -verifier: - name: testinfra diff --git a/tripleo_ansible/ansible_plugins/tests/molecule/podman_container/prepare.yml b/tripleo_ansible/ansible_plugins/tests/molecule/podman_container/prepare.yml deleted file mode 100644 index 9bbae21a9..000000000 --- a/tripleo_ansible/ansible_plugins/tests/molecule/podman_container/prepare.yml +++ /dev/null @@ -1,39 +0,0 @@ ---- -# Copyright 2019 Red Hat, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -- name: Prepare - hosts: all - gather_facts: true - roles: - - role: test_deps - test_deps_extra_packages: - - podman - - post_tasks: - - name: Check podman version - command: podman version - register: p_ver - changed_when: false - - - name: Print podman version - debug: - msg: | - podman version: - {{ p_ver.stdout }} - - Testing with ansible {{ ansible_version.full }} - with python {{ ansible_python_version }} - on host {{ ansible_distribution }} {{ ansible_distribution_version }} diff --git a/tripleo_ansible/ansible_plugins/tests/molecule/podman_container_info/converge.yml b/tripleo_ansible/ansible_plugins/tests/molecule/podman_container_info/converge.yml deleted file mode 100644 index fb70ad1c1..000000000 --- a/tripleo_ansible/ansible_plugins/tests/molecule/podman_container_info/converge.yml +++ /dev/null @@ -1,60 +0,0 @@ ---- -- name: Converge - hosts: all - tasks: - - name: Test podman_container_info - become: true - block: - - name: Generate random value for container name - set_fact: - container_name: "{{ 'ansible-test-podman-%0x' % ((2**32) | random) }}" - - - name: Make sure container doesn't exist - command: podman container rm -f {{ container_name }} - ignore_errors: true - - - name: Get missing container info - podman_container_info: - name: "{{ container_name }}" - register: nonexist - ignore_errors: true - - - name: Check results - assert: - that: - - nonexist.containers == [] - - nonexist is not failed - - - name: Make sure container exists - command: podman container run -d --name {{ container_name }} alpine sleep 15m - - - name: Get existing container info - podman_container_info: - name: "{{ container_name }}" - register: existing_container - - - name: Get all containers info - podman_container_info: - register: all_containers - - - name: Dump podman container inspect result - debug: var=existing_container - - - name: Cleanup - command: podman container rm -f {{ container_name }} - - - name: Make checks - assert: - that: - - "'containers' in existing_container" - - existing_container.containers - - always: - - name: Delete all container leftovers from tests - podman_container: - name: "{{ item }}" - state: absent - loop: - - "alpine:3.7" - - "container" - - "container2" diff --git a/tripleo_ansible/ansible_plugins/tests/molecule/podman_container_info/molecule.yml b/tripleo_ansible/ansible_plugins/tests/molecule/podman_container_info/molecule.yml deleted file mode 100644 index 006e9ffef..000000000 --- a/tripleo_ansible/ansible_plugins/tests/molecule/podman_container_info/molecule.yml +++ /dev/null @@ -1,50 +0,0 @@ ---- -driver: - name: delegated - options: - managed: false - login_cmd_template: >- - ssh - -o UserKnownHostsFile=/dev/null - -o StrictHostKeyChecking=no - -o Compression=no - -o TCPKeepAlive=yes - -o VerifyHostKeyDNS=no - -o ForwardX11=no - -o ForwardAgent=no - {instance} - ansible_connection_options: - ansible_connection: ssh - -log: true - -platforms: - - name: instance - -provisioner: - name: ansible - config_options: - defaults: - fact_caching: jsonfile - fact_caching_connection: /tmp/molecule/facts - inventory: - hosts: - all: - hosts: - instance: - ansible_host: localhost - log: true - env: - ANSIBLE_STDOUT_CALLBACK: yaml - ANSIBLE_ROLES_PATH: "${ANSIBLE_ROLES_PATH:-/usr/share/ansible/roles}:${HOME}/zuul-jobs/roles" - ANSIBLE_LIBRARY: "${ANSIBLE_LIBRARY:-/usr/share/ansible/plugins/modules}" - ANSIBLE_FILTER_PLUGINS: "${ANSIBLE_FILTER_PLUGINS:-/usr/share/ansible/plugins/filter}" - -scenario: - test_sequence: - - prepare - - converge - - verify - -verifier: - name: testinfra diff --git a/tripleo_ansible/ansible_plugins/tests/molecule/podman_container_info/prepare.yml b/tripleo_ansible/ansible_plugins/tests/molecule/podman_container_info/prepare.yml deleted file mode 100644 index 9c4724137..000000000 --- a/tripleo_ansible/ansible_plugins/tests/molecule/podman_container_info/prepare.yml +++ /dev/null @@ -1,22 +0,0 @@ ---- -# Copyright 2019 Red Hat, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -- name: Prepare - hosts: all - roles: - - role: test_deps - test_deps_extra_packages: - - podman diff --git a/tripleo_ansible/ansible_plugins/tests/molecule/podman_volume_info/converge.yml b/tripleo_ansible/ansible_plugins/tests/molecule/podman_volume_info/converge.yml deleted file mode 100644 index d955222c3..000000000 --- a/tripleo_ansible/ansible_plugins/tests/molecule/podman_volume_info/converge.yml +++ /dev/null @@ -1,63 +0,0 @@ ---- -- name: Converge - hosts: all - tasks: - - name: Test podman_volume_info - become: true - block: - - name: Print podman version - command: podman version - - - name: Generate random value for volume name - set_fact: - volume_name: "{{ 'ansible-test-podman-%0x' % ((2**32) | random) }}" - - - name: Make sure volume doesn't exist - command: podman volume rm {{ volume_name }} - ignore_errors: true - - - name: Get missing volume info - podman_volume_info: - name: "{{ volume_name }}" - register: nonexist - ignore_errors: true - - - name: Check results - assert: - that: - - "'volumes' not in nonexist" - - nonexist is failed - - - name: Make sure volume exists - command: podman volume create {{ volume_name }} - - - name: Get existing volume info - podman_volume_info: - name: "{{ volume_name }}" - register: existing_volume - - - name: Dump podman volume inspect result - debug: var=existing_volume - - - name: Comparison with 'podman volume inspect' - command: podman volume inspect "{{ volume_name }}" - register: podman_inspect - - - name: Convert podman inspect output to JSON - set_fact: - podman_inspect_result: "{{ podman_inspect.stdout | from_json }}" - - - name: Cleanup - command: podman volume rm {{ volume_name }} - - - name: Make checks - assert: - that: - - "'volumes' in existing_volume" - - existing_volume.volumes - - "existing_volume.volumes == podman_inspect_result" - always: - - - name: Cleanup - command: podman volume rm {{ volume_name }} - ignore_errors: true diff --git a/tripleo_ansible/ansible_plugins/tests/molecule/podman_volume_info/molecule.yml b/tripleo_ansible/ansible_plugins/tests/molecule/podman_volume_info/molecule.yml deleted file mode 100644 index 591ab0bd6..000000000 --- a/tripleo_ansible/ansible_plugins/tests/molecule/podman_volume_info/molecule.yml +++ /dev/null @@ -1,51 +0,0 @@ ---- -driver: - name: delegated - options: - managed: false - login_cmd_template: >- - ssh - -o UserKnownHostsFile=/dev/null - -o StrictHostKeyChecking=no - -o Compression=no - -o TCPKeepAlive=yes - -o VerifyHostKeyDNS=no - -o ForwardX11=no - -o ForwardAgent=no - {instance} - ansible_connection_options: - ansible_connection: ssh - -log: true - -platforms: - - name: instance - -provisioner: - name: ansible - config_options: - defaults: - fact_caching: jsonfile - fact_caching_connection: /tmp/molecule/facts - inventory: - hosts: - all: - hosts: - instance: - ansible_host: localhost - log: true - env: - ANSIBLE_STDOUT_CALLBACK: yaml - ANSIBLE_ROLES_PATH: "${ANSIBLE_ROLES_PATH:-/usr/share/ansible/roles}:${HOME}/zuul-jobs/roles" - ANSIBLE_LIBRARY: "${ANSIBLE_LIBRARY:-/usr/share/ansible/plugins/modules}" - ANSIBLE_FILTER_PLUGINS: "${ANSIBLE_FILTER_PLUGINS:-/usr/share/ansible/plugins/filter}" - -scenario: - name: podman_volume_info - test_sequence: - - prepare - - converge - - verify - -verifier: - name: testinfra diff --git a/tripleo_ansible/ansible_plugins/tests/molecule/podman_volume_info/prepare.yml b/tripleo_ansible/ansible_plugins/tests/molecule/podman_volume_info/prepare.yml deleted file mode 100644 index 9c4724137..000000000 --- a/tripleo_ansible/ansible_plugins/tests/molecule/podman_volume_info/prepare.yml +++ /dev/null @@ -1,22 +0,0 @@ ---- -# Copyright 2019 Red Hat, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -- name: Prepare - hosts: all - roles: - - role: test_deps - test_deps_extra_packages: - - podman diff --git a/tripleo_ansible/roles/backup_and_restore/molecule/default/prepare.yml b/tripleo_ansible/roles/backup_and_restore/molecule/default/prepare.yml index 378559a1b..4a211d767 100644 --- a/tripleo_ansible/roles/backup_and_restore/molecule/default/prepare.yml +++ b/tripleo_ansible/roles/backup_and_restore/molecule/default/prepare.yml @@ -80,14 +80,14 @@ } - name: pull some images - podman_image: + containers.podman.podman_image: name: "{{ item }}" with_items: - registry.access.redhat.com/ubi8/ubi-minimal - mysql - name: Create a data container - podman_container: + containers.podman.podman_container: name: "{{ item }}" image: ubi-minimal state: started @@ -97,7 +97,7 @@ - test-container2 - name: Start myql container - podman_container: + containers.podman.podman_container: name: mysql image: mysql state: started diff --git a/tripleo_ansible/roles/tripleo_container_manage/molecule/default/converge.yml b/tripleo_ansible/roles/tripleo_container_manage/molecule/default/converge.yml index 9e8d6617a..f7c99236b 100644 --- a/tripleo_ansible/roles/tripleo_container_manage/molecule/default/converge.yml +++ b/tripleo_ansible/roles/tripleo_container_manage/molecule/default/converge.yml @@ -76,7 +76,7 @@ - name: Check for fedora container command: podman container exists fedora - name: Gather facts about fedora container - podman_container_info: + containers.podman.podman_container_info: name: fedora register: fedora_infos - name: Assert that fedora container has the right image @@ -110,7 +110,7 @@ - name: Check for fedora_bis container command: podman container exists fedora_bis - name: Gather facts about fedora_bis container - podman_container_info: + containers.podman.podman_container_info: name: fedora_bis register: fedora_bis_infos - name: Assert that fedora_bis container has the right image @@ -124,7 +124,7 @@ - name: Check for fedora_three container command: podman container exists fedora_three - name: Gather facts about fedora_three container - podman_container_info: + containers.podman.podman_container_info: name: fedora_three register: fedora_three_infos - name: Assert that fedora_three container has the right image @@ -145,7 +145,7 @@ tripleo_container_manage_systemd_order: true tasks: - name: Gather facts about fedora container before new run - podman_container_info: + containers.podman.podman_container_info: name: fedora register: fedora_infos_old when: @@ -153,7 +153,7 @@ - include_role: name: tripleo_container_manage - name: Gather facts about fedora container after new run - podman_container_info: + containers.podman.podman_container_info: name: fedora register: fedora_infos_new when: @@ -222,7 +222,7 @@ - name: Check for fedora container command: podman container exists fedora - name: Gather facts about fedora container - podman_container_info: + containers.podman.podman_container_info: name: fedora register: fedora_infos - name: Assert that fedora container has the right image @@ -271,7 +271,7 @@ - name: Check for fedora container command: podman container exists fedora - name: Gather facts about fedora container - podman_container_info: + containers.podman.podman_container_info: name: fedora register: fedora_infos - name: Check if tripleo_fedora systemd service is active @@ -357,7 +357,7 @@ - name: Check for fedora_bis container command: podman container exists fedora_bis - name: Gather facts about fedora_bis container - podman_container_info: + containers.podman.podman_container_info: name: fedora_bis register: fedora_bis_infos - name: Assert that fedora_bis container has the right image @@ -394,7 +394,7 @@ - name: Check for fedora_bis container command: podman container exists fedora_bis - name: Gather facts about fedora_bis container - podman_container_info: + containers.podman.podman_container_info: name: fedora_bis register: fedora_bis_infos - name: Assert that fedora_bis container has the right image diff --git a/tripleo_ansible/roles/tripleo_container_manage/tasks/delete_orphan.yml b/tripleo_ansible/roles/tripleo_container_manage/tasks/delete_orphan.yml index 21edc802a..2094943a5 100644 --- a/tripleo_ansible/roles/tripleo_container_manage/tasks/delete_orphan.yml +++ b/tripleo_ansible/roles/tripleo_container_manage/tasks/delete_orphan.yml @@ -15,7 +15,7 @@ # under the License. - name: Gather podman infos - podman_container_info: {} + containers.podman.podman_container_info: {} register: podman_containers no_log: "{{ not (tripleo_container_manage_debug | bool) }}" when: diff --git a/tripleo_ansible/roles/tripleo_container_manage/tasks/podman/create.yml b/tripleo_ansible/roles/tripleo_container_manage/tasks/podman/create.yml index c85bdaacb..c6499b54b 100644 --- a/tripleo_ansible/roles/tripleo_container_manage/tasks/podman/create.yml +++ b/tripleo_ansible/roles/tripleo_container_manage/tasks/podman/create.yml @@ -34,7 +34,7 @@ loop_control: label: "{{ lookup('dict', container_data).key }}" loop_var: container_data - podman_container: + containers.podman.podman_container: annotation: "{{ lookup('dict', container_data).value.annotation | default(omit) }}" cap_add: "{{ lookup('dict', container_data).value.cap_add | default(omit) }}" cap_drop: "{{ lookup('dict', container_data).value.cap_drop | default(omit) }}" diff --git a/tripleo_ansible/roles/tripleo_container_manage/tasks/podman/start_order.yml b/tripleo_ansible/roles/tripleo_container_manage/tasks/podman/start_order.yml index 337f43727..ced059096 100644 --- a/tripleo_ansible/roles/tripleo_container_manage/tasks/podman/start_order.yml +++ b/tripleo_ansible/roles/tripleo_container_manage/tasks/podman/start_order.yml @@ -15,7 +15,7 @@ # under the License. - name: Gather podman infos - podman_container_info: {} + containers.podman.podman_container_info: {} register: podman_containers no_log: "{{ tripleo_container_manage_hide_sensitive_logs | bool }}" when: diff --git a/tripleo_ansible/roles/tripleo_container_rm/molecule/default/prepare.yml b/tripleo_ansible/roles/tripleo_container_rm/molecule/default/prepare.yml index adeef81c5..9021d88ef 100644 --- a/tripleo_ansible/roles/tripleo_container_rm/molecule/default/prepare.yml +++ b/tripleo_ansible/roles/tripleo_container_rm/molecule/default/prepare.yml @@ -32,11 +32,11 @@ state: latest - name: Pull container image - podman_image: + containers.podman.podman_image: name: fedora - name: Create test containers - podman_container: + containers.podman.podman_container: name: "{{ item }}" interactive: true tty: true diff --git a/tripleo_ansible/roles/tripleo_container_rm/molecule/legacy_vars/prepare.yml b/tripleo_ansible/roles/tripleo_container_rm/molecule/legacy_vars/prepare.yml index de7ccaa26..005ea57f3 100644 --- a/tripleo_ansible/roles/tripleo_container_rm/molecule/legacy_vars/prepare.yml +++ b/tripleo_ansible/roles/tripleo_container_rm/molecule/legacy_vars/prepare.yml @@ -32,11 +32,11 @@ state: latest - name: Pull container image - podman_image: + containers.podman.podman_image: name: fedora - name: Create test containers - podman_container: + containers.podman.podman_container: name: "{{ item }}" interactive: true tty: true diff --git a/tripleo_ansible/roles/tripleo_container_rm/molecule/podman-rm-stopped/prepare.yml b/tripleo_ansible/roles/tripleo_container_rm/molecule/podman-rm-stopped/prepare.yml index 2ef972ef8..1695eb0f9 100644 --- a/tripleo_ansible/roles/tripleo_container_rm/molecule/podman-rm-stopped/prepare.yml +++ b/tripleo_ansible/roles/tripleo_container_rm/molecule/podman-rm-stopped/prepare.yml @@ -32,11 +32,11 @@ state: latest - name: Pull container image - podman_image: + containers.podman.podman_image: name: fedora - name: Create test containers - podman_container: + containers.podman.podman_container: name: "{{ item }}" interactive: true tty: true @@ -48,7 +48,7 @@ - podman-container2 - name: Stop test containers - podman_container: + containers.podman.podman_container: name: "{{ item }}" state: stopped with_items: diff --git a/tripleo_ansible/roles/tripleo_container_rm/tasks/tripleo_podman_container_rm.yml b/tripleo_ansible/roles/tripleo_container_rm/tasks/tripleo_podman_container_rm.yml index 953fb3f3e..b78ac60ca 100644 --- a/tripleo_ansible/roles/tripleo_container_rm/tasks/tripleo_podman_container_rm.yml +++ b/tripleo_ansible/roles/tripleo_container_rm/tasks/tripleo_podman_container_rm.yml @@ -79,7 +79,7 @@ daemon_reload: true - name: Stop and remove container if exists - podman_container: + containers.podman.podman_container: name: "{{ container }}" state: absent register: result diff --git a/tripleo_ansible/roles/tripleo_container_stop/molecule/default/prepare.yml b/tripleo_ansible/roles/tripleo_container_stop/molecule/default/prepare.yml index adeef81c5..9021d88ef 100644 --- a/tripleo_ansible/roles/tripleo_container_stop/molecule/default/prepare.yml +++ b/tripleo_ansible/roles/tripleo_container_stop/molecule/default/prepare.yml @@ -32,11 +32,11 @@ state: latest - name: Pull container image - podman_image: + containers.podman.podman_image: name: fedora - name: Create test containers - podman_container: + containers.podman.podman_container: name: "{{ item }}" interactive: true tty: true diff --git a/tripleo_ansible/roles/tripleo_keystone_resources/molecule/default/prepare.yml b/tripleo_ansible/roles/tripleo_keystone_resources/molecule/default/prepare.yml index 1501e88d5..71cac84e3 100644 --- a/tripleo_ansible/roles/tripleo_keystone_resources/molecule/default/prepare.yml +++ b/tripleo_ansible/roles/tripleo_keystone_resources/molecule/default/prepare.yml @@ -40,7 +40,7 @@ become: false - name: Create test containers - podman_container: + containers.podman.podman_container: name: keystone-podman image: keystone-img detach: true diff --git a/tripleo_ansible/roles/tripleo_podman/molecule/default/prepare.yml b/tripleo_ansible/roles/tripleo_podman/molecule/default/prepare.yml index 0b85e8371..09358dfd9 100644 --- a/tripleo_ansible/roles/tripleo_podman/molecule/default/prepare.yml +++ b/tripleo_ansible/roles/tripleo_podman/molecule/default/prepare.yml @@ -35,11 +35,11 @@ - role: test_deps post_tasks: - name: pull an image - podman_image: + containers.podman.podman_image: name: "ubi8:latest" - name: Create a data container - podman_container: + containers.podman.podman_container: name: "{{ item }}" image: "ubi8:latest" detach: true diff --git a/tripleo_ansible/roles/tripleo_podman/molecule/login/prepare.yml b/tripleo_ansible/roles/tripleo_podman/molecule/login/prepare.yml index 2115af788..9100ab4f4 100644 --- a/tripleo_ansible/roles/tripleo_podman/molecule/login/prepare.yml +++ b/tripleo_ansible/roles/tripleo_podman/molecule/login/prepare.yml @@ -41,12 +41,12 @@ state: disabled - name: Ensure registry doesn't exist - podman_container: + containers.podman.podman_container: name: registry state: absent - name: Pull ubuntu image - podman_image: + containers.podman.podman_image: name: ubuntu tag: 16.04 @@ -63,7 +63,7 @@ executable: /bin/bash - name: Create registry - podman_container: + containers.podman.podman_container: name: registry image: "registry:2.7.0" restart_policy: always diff --git a/zuul.d/molecule.yaml b/zuul.d/molecule.yaml index 228844231..47831b537 100644 --- a/zuul.d/molecule.yaml +++ b/zuul.d/molecule.yaml @@ -10,7 +10,6 @@ - tripleo-ansible-centos-8-molecule-login_defs - tripleo-ansible-centos-8-molecule-test_deps - tripleo-ansible-centos-8-molecule-test_package_action - - tripleo-ansible-centos-8-molecule-tripleo-modules - tripleo-ansible-centos-8-molecule-tripleo_bootstrap - tripleo-ansible-centos-8-molecule-tripleo_cellv2 - tripleo-ansible-centos-8-molecule-tripleo_ceph_client @@ -72,7 +71,6 @@ - tripleo-ansible-centos-8-molecule-login_defs - tripleo-ansible-centos-8-molecule-test_deps - tripleo-ansible-centos-8-molecule-test_package_action - # - tripleo-ansible-centos-8-molecule-tripleo-modules - tripleo-ansible-centos-8-molecule-tripleo_bootstrap - tripleo-ansible-centos-8-molecule-tripleo_cellv2 - tripleo-ansible-centos-8-molecule-tripleo_ceph_client @@ -135,7 +133,6 @@ - tripleo-ansible-centos-8-molecule-login_defs - tripleo-ansible-centos-8-molecule-test_deps - tripleo-ansible-centos-8-molecule-test_package_action - - tripleo-ansible-centos-8-molecule-tripleo-modules - tripleo-ansible-centos-8-molecule-tripleo_bootstrap - tripleo-ansible-centos-8-molecule-tripleo_cellv2 - tripleo-ansible-centos-8-molecule-tripleo_ceph_client @@ -229,12 +226,6 @@ parent: tripleo-ansible-centos-8-base vars: tripleo_role_name: test_package_action -- job: - files: - - ^tripleo_ansible/ansible_plugins/.*$ - name: tripleo-ansible-centos-8-molecule-tripleo-modules - parent: tripleo-ansible-centos-8-base - voting: false - job: files: - ^tripleo_ansible/roles/tripleo_bootstrap/.* @@ -320,8 +311,6 @@ - ^tripleo_ansible/ansible_plugins/modules/container_config_data.py$ - ^tripleo_ansible/ansible_plugins/modules/container_puppet_config.py$ - ^tripleo_ansible/ansible_plugins/modules/container_startup_config.py$ - - ^tripleo_ansible/ansible_plugins/modules/podman_container.py$ - - ^tripleo_ansible/ansible_plugins/modules/podman_container_info.py$ name: tripleo-ansible-centos-8-molecule-tripleo_container_manage parent: tripleo-ansible-centos-8-base vars: diff --git a/zuul.d/playbooks/pre.yml b/zuul.d/playbooks/pre.yml index 9322cc583..10d86cc65 100644 --- a/zuul.d/playbooks/pre.yml +++ b/zuul.d/playbooks/pre.yml @@ -109,3 +109,11 @@ {{ tripleo_ansible_project_path }}/tripleo_ansible/ansible-role-requirements.yml environment: ANSIBLE_ROLES_PATH: "{{ tripleo_ansible_project_path }}/tripleo_ansible/roles.galaxy" + + - name: Get Ansible Galaxy collections + command: >- + {{ ansible_user_dir }}/test-python/bin/ansible-galaxy collection install + -fr + {{ tripleo_ansible_project_path }}/tripleo_ansible/requirements.yml + environment: + ANSIBLE_ROLES_PATH: "{{ tripleo_ansible_project_path }}/tripleo_ansible/roles.galaxy"