1
0
Fork 0
mirror of https://github.com/containers/ansible-podman-collections.git synced 2026-04-18 23:31:27 +00:00

Redesign idempotency for Podman Pod module (#759)

Signed-off-by: Sagi Shnaidman <sshnaidm@redhat.com>
This commit is contained in:
Sergey 2024-05-27 17:49:32 +03:00 committed by GitHub
parent b3dc57c1cf
commit 47fc4cc119
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 563 additions and 239 deletions

View file

@ -337,3 +337,88 @@ def get_podman_version(module, fail=True):
(executable, err))
return None
return out.split("version")[1].strip()
def createcommand(argument, info_config, boolean_type=False):
"""Returns list of values for given argument from CreateCommand
from Podman container inspect output.
Args:
argument (str): argument name
info_config (dict): dictionary with container info
boolean_type (bool): if True, then argument is boolean type
Returns:
all_values: list of values for given argument from createcommand
"""
if "createcommand" not in info_config:
return []
cr_com = info_config["createcommand"]
argument_values = ARGUMENTS_OPTS_DICT.get(argument, [argument])
all_values = []
for arg in argument_values:
for ind, cr_opt in enumerate(cr_com):
if arg == cr_opt:
if boolean_type:
# This is a boolean argument and doesn't have value
return [True]
if not cr_com[ind + 1].startswith("-"):
# This is a key=value argument
all_values.append(cr_com[ind + 1])
else:
# This is also a false/true switching argument
return [True]
if cr_opt.startswith("%s=" % arg):
all_values.append(cr_opt.split("=", 1)[1])
return all_values
def diff_generic(params, info_config, module_arg, cmd_arg, boolean_type=False):
"""
Generic diff function for module arguments from CreateCommand
in Podman inspection output.
Args:
params (dict): module parameters
info_config (dict): dictionary with container info
module_arg (str): module argument name
cmd_arg (str): command line argument name
boolean_type (bool): if True, then argument is boolean type
Returns:
bool: True if there is a difference, False otherwise
"""
before = createcommand(cmd_arg, info_config, boolean_type=boolean_type)
if before == []:
before = None
after = params[module_arg]
if boolean_type and (before, after) in [(None, False), (False, None)]:
before, after = False, False
return before, after
if before is None and after is None:
return before, after
if after is not None:
if isinstance(after, list):
after = ",".join(sorted([str(i).lower() for i in after]))
if before:
before = ",".join(sorted([str(i).lower() for i in before]))
elif isinstance(after, dict):
after = ",".join(sorted(
[str(k).lower() + "=" + str(v).lower() for k, v in after.items() if v is not None]))
if before:
before = ",".join(sorted([j.lower() for j in before]))
elif isinstance(after, bool):
after = str(after).capitalize()
if before is not None:
before = str(before[0]).capitalize()
elif isinstance(after, int):
after = str(after)
if before is not None:
before = str(before[0])
else:
before = before[0] if before else None
else:
before = ",".join(sorted(before)) if len(before) > 1 else before[0]
return before, after

View file

@ -8,7 +8,8 @@ from ansible_collections.containers.podman.plugins.module_utils.podman.common im
from ansible_collections.containers.podman.plugins.module_utils.podman.common import lower_keys
from ansible_collections.containers.podman.plugins.module_utils.podman.common import generate_systemd
from ansible_collections.containers.podman.plugins.module_utils.podman.common import delete_systemd
from ansible_collections.containers.podman.plugins.module_utils.podman.common import ARGUMENTS_OPTS_DICT
from ansible_collections.containers.podman.plugins.module_utils.podman.common import diff_generic
from ansible_collections.containers.podman.plugins.module_utils.podman.common import createcommand
from ansible_collections.containers.podman.plugins.module_utils.podman.quadlet import create_quadlet_state
from ansible_collections.containers.podman.plugins.module_utils.podman.quadlet import ContainerQuadlet
@ -913,39 +914,6 @@ class PodmanContainerDiff:
params_with_defaults[p] = self.module_params[p]
return params_with_defaults
def _createcommand(self, argument, boolean_type=False):
"""Returns list of values for given argument from CreateCommand
from Podman container inspect output.
Args:
argument (str): argument name
boolean_type (bool): if True, then argument is boolean type
Returns:
all_values: list of values for given argument from createcommand
"""
if "createcommand" not in self.info["config"]:
return []
cr_com = self.info["config"]["createcommand"]
argument_values = ARGUMENTS_OPTS_DICT.get(argument, [argument])
all_values = []
for arg in argument_values:
for ind, cr_opt in enumerate(cr_com):
if arg == cr_opt:
if boolean_type:
# This is a boolean argument and doesn't have value
return [True]
if not cr_com[ind + 1].startswith("-"):
# This is a key=value argument
all_values.append(cr_com[ind + 1])
else:
# This is also a false/true switching argument
return [True]
if cr_opt.startswith("%s=" % arg):
all_values.append(cr_opt.split("=", 1)[1])
return all_values
def _diff_update_and_compare(self, param_name, before, after):
if before != after:
self.diff['before'].update({param_name: before})
@ -967,37 +935,8 @@ class PodmanContainerDiff:
bool: True if there is a difference, False otherwise
"""
before = self._createcommand(cmd_arg, boolean_type=boolean_type)
if before == []:
before = None
after = self.params[module_arg]
if boolean_type and (before, after) in [(None, False), (False, None)]:
before, after = False, False
return self._diff_update_and_compare(module_arg, before, after)
if before is None and after is None:
return self._diff_update_and_compare(module_arg, before, after)
if after is not None:
if isinstance(after, list):
after = ",".join(sorted([str(i).lower() for i in after]))
if before:
before = ",".join(sorted([str(i).lower() for i in before]))
elif isinstance(after, dict):
after = ",".join(sorted(
[str(k).lower() + "=" + str(v).lower() for k, v in after.items() if v is not None]))
if before:
before = ",".join(sorted([j.lower() for j in before]))
elif isinstance(after, bool):
after = str(after).capitalize()
if before is not None:
before = str(before[0]).capitalize()
elif isinstance(after, int):
after = str(after)
if before is not None:
before = str(before[0])
else:
before = before[0] if before else None
else:
before = ",".join(sorted(before)) if len(before) > 1 else before[0]
info_config = self.info["config"]
before, after = diff_generic(self.params, info_config, module_arg, cmd_arg, boolean_type)
return self._diff_update_and_compare(module_arg, before, after)
def diffparam_annotation(self):
@ -1489,7 +1428,7 @@ class PodmanContainerDiff:
return "/"
return x.replace("//", "/").rstrip("/")
before = self._createcommand('--volume')
before = createcommand('--volume', self.info['config'])
if before == []:
before = None
after = self.params['volume']

View file

@ -6,6 +6,8 @@ from ansible_collections.containers.podman.plugins.module_utils.podman.common im
from ansible_collections.containers.podman.plugins.module_utils.podman.common import lower_keys
from ansible_collections.containers.podman.plugins.module_utils.podman.common import generate_systemd
from ansible_collections.containers.podman.plugins.module_utils.podman.common import delete_systemd
from ansible_collections.containers.podman.plugins.module_utils.podman.common import diff_generic
from ansible_collections.containers.podman.plugins.module_utils.podman.common import createcommand
from ansible_collections.containers.podman.plugins.module_utils.podman.quadlet import create_quadlet_state, PodQuadlet
@ -28,9 +30,9 @@ ARGUMENTS_SPEC_POD = dict(
]),
recreate=dict(type='bool', default=False),
add_host=dict(type='list', required=False, elements='str'),
cgroup_parent=dict(type='str', required=False),
blkio_weight=dict(type='str', required=False),
blkio_weight_device=dict(type='list', elements='str', required=False),
cgroup_parent=dict(type='str', required=False),
cpus=dict(type='str', required=False),
cpuset_cpus=dict(type='str', required=False),
cpuset_mems=dict(type='str', required=False),
@ -39,8 +41,9 @@ ARGUMENTS_SPEC_POD = dict(
device_read_bps=dict(type='list', elements='str', required=False),
device_write_bps=dict(type='list', elements='str', required=False),
dns=dict(type='list', elements='str', required=False),
dns_opt=dict(type='list', elements='str', required=False),
dns_opt=dict(type='list', elements='str', aliases=['dns_option'], required=False),
dns_search=dict(type='list', elements='str', required=False),
exit_policy=dict(type='str', required=False, choices=['continue', 'stop']),
generate_systemd=dict(type='dict', default={}),
gidmap=dict(type='list', elements='str', required=False),
gpus=dict(type='str', required=False),
@ -69,6 +72,7 @@ ARGUMENTS_SPEC_POD = dict(
quadlet_dir=dict(type='path'),
quadlet_filename=dict(type='str'),
quadlet_options=dict(type='list', elements='str'),
restart_policy=dict(type='str', required=False),
security_opt=dict(type='list', elements='str', required=False),
share=dict(type='str', required=False),
share_parent=dict(type='bool', required=False),
@ -209,7 +213,7 @@ class PodmanPodModuleParams:
def addparam_dns_opt(self, c):
for g in self.params['dns_opt']:
c += ['--dns-opt', g]
c += ['--dns-option', g]
return c
def addparam_dns_search(self, c):
@ -217,6 +221,9 @@ class PodmanPodModuleParams:
c += ['--dns-search', g]
return c
def addparam_exit_policy(self, c):
return c + ['--exit-policy=%s' % self.params['exit_policy']]
def addparam_gidmap(self, c):
for gidmap in self.params['gidmap']:
c += ['--gidmap', gidmap]
@ -300,6 +307,9 @@ class PodmanPodModuleParams:
c += ['--publish', g]
return c
def addparam_restart_policy(self, c):
return c + ['--restart=%s' % self.params['restart_policy']]
def addparam_security_opt(self, c):
for g in self.params['security_opt']:
c += ['--security-opt', g]
@ -358,10 +368,6 @@ class PodmanPodDefaults:
self.module = module
self.version = podman_version
self.defaults = {
'add_host': [],
'dns': [],
'dns_opt': [],
'dns_search': [],
'infra': True,
'label': {},
}
@ -405,50 +411,77 @@ class PodmanPodDiff:
return True
return False
def _diff_generic(self, module_arg, cmd_arg, boolean_type=False):
"""
Generic diff function for module arguments from CreateCommand
in Podman inspection output.
Args:
module_arg (str): module argument name
cmd_arg (str): command line argument name
boolean_type (bool): if True, then argument is boolean type
Returns:
bool: True if there is a difference, False otherwise
"""
info_config = self.info
before, after = diff_generic(self.params, info_config, module_arg, cmd_arg, boolean_type)
return self._diff_update_and_compare(module_arg, before, after)
def diffparam_add_host(self):
if not self.infra_info:
return self._diff_update_and_compare('add_host', '', '')
before = self.infra_info['hostconfig']['extrahosts'] or []
after = self.params['add_host']
before, after = sorted(list(set(before))), sorted(list(set(after)))
return self._diff_update_and_compare('add_host', before, after)
return self._diff_generic('add_host', '--add-host')
def diffparam_blkio_weight(self):
return self._diff_generic('blkio_weight', '--blkio-weight')
def diffparam_blkio_weight_device(self):
return self._diff_generic('blkio_weight_device', '--blkio-weight-device')
def diffparam_cgroup_parent(self):
before = (self.info.get('cgroupparent', '')
or self.info.get('hostconfig', {}).get('cgroupparent', ''))
after = self.params['cgroup_parent'] or before
return self._diff_update_and_compare('cgroup_parent', before, after)
return self._diff_generic('cgroup_parent', '--cgroup-parent')
def diffparam_cpu_shares(self):
return self._diff_generic('cpu_shares', '--cpu-shares')
def diffparam_cpus(self):
return self._diff_generic('cpus', '--cpus')
def diffparam_cpuset_cpus(self):
return self._diff_generic('cpuset_cpus', '--cpuset-cpus')
def diffparam_cpuset_mems(self):
return self._diff_generic('cpuset_mems', '--cpuset-mems')
def diffparam_device(self):
return self._diff_generic('device', '--device')
def diffparam_device_read_bps(self):
return self._diff_generic('device_read_bps', '--device-read-bps')
def diffparam_device_write_bps(self):
return self._diff_generic('device_write_bps', '--device-write-bps')
def diffparam_dns(self):
if not self.infra_info:
return self._diff_update_and_compare('dns', '', '')
before = self.infra_info['hostconfig']['dns'] or []
after = self.params['dns']
before, after = sorted(list(set(before))), sorted(list(set(after)))
return self._diff_update_and_compare('dns', before, after)
return self._diff_generic('dns', '--dns')
def diffparam_dns_opt(self):
if not self.infra_info:
return self._diff_update_and_compare('dns_opt', '', '')
before = self.infra_info['hostconfig']['dnsoptions'] or []
after = self.params['dns_opt']
before, after = sorted(list(set(before))), sorted(list(set(after)))
return self._diff_update_and_compare('dns_opt', before, after)
return self._diff_generic('dns_opt', '--dns-option')
def diffparam_dns_search(self):
if not self.infra_info:
return self._diff_update_and_compare('dns_search', '', '')
before = self.infra_info['hostconfig']['dnssearch'] or []
after = self.params['dns_search']
before, after = sorted(list(set(before))), sorted(list(set(after)))
return self._diff_update_and_compare('dns_search', before, after)
return self._diff_generic('dns_search', '--dns-search')
def diffparam_exit_policy(self):
return self._diff_generic('exit_policy', '--exit-policy')
def diffparam_gidmap(self):
return self._diff_generic('gidmap', '--gidmap')
def diffparam_gpus(self):
return self._diff_generic('gpus', '--gpus')
def diffparam_hostname(self):
if not self.infra_info:
return self._diff_update_and_compare('hostname', '', '')
before = self.infra_info['config']['hostname']
after = self.params['hostname'] or before
return self._diff_update_and_compare('hostname', before, after)
return self._diff_generic('hostname', '--hostname')
# TODO(sshnaidm): https://github.com/containers/podman/issues/6968
def diffparam_infra(self):
@ -460,30 +493,23 @@ class PodmanPodDiff:
after = self.params['infra']
return self._diff_update_and_compare('infra', before, after)
# TODO(sshnaidm): https://github.com/containers/podman/issues/6969
# def diffparam_infra_command(self):
# before = str(self.info['hostconfig']['infra_command'])
# after = self.params['infra_command']
# return self._diff_update_and_compare('infra_command', before, after)
def diffparam_infra_command(self):
return self._diff_generic('infra_command', '--infra-command')
def diffparam_infra_conmon_pidfile(self):
return self._diff_generic('infra_conmon_pidfile', '--infra-conmon-pidfile')
def diffparam_infra_image(self):
if not self.infra_info:
return self._diff_update_and_compare('infra_image', '', '')
before = str(self.infra_info['imagename'])
after = before
if self.module_params['infra_image']:
after = self.params['infra_image']
before = before.replace(":latest", "")
after = after.replace(":latest", "")
before = before.split("/")[-1] # pylint: disable=W,C,R
after = after.split("/")[-1] # pylint: disable=W,C,R
return self._diff_update_and_compare('infra_image', before, after)
return self._diff_generic('infra_image', '--infra-image')
# TODO(sshnaidm): https://github.com/containers/podman/pull/6956
# def diffparam_ip(self):
# before = str(self.info['hostconfig']['ip'])
# after = self.params['ip']
# return self._diff_update_and_compare('ip', before, after)
def diffparam_infra_name(self):
return self._diff_generic('infra_name', '--infra-name')
def diffparam_ip(self):
return self._diff_generic('ip', '--ip')
def diffparam_ip6(self):
return self._diff_generic('ip6', '--ip6')
def diffparam_label(self):
if 'config' in self.info and 'labels' in self.info['config']:
@ -498,129 +524,99 @@ class PodmanPodDiff:
before.pop('podman_systemd_unit', None)
return self._diff_update_and_compare('label', before, after)
# TODO(sshnaidm): https://github.com/containers/podman/pull/6956
# def diffparam_mac_address(self):
# before = str(self.info['hostconfig']['mac_address'])
# after = self.params['mac_address']
# return self._diff_update_and_compare('mac_address', before, after)
def diffparam_label_file(self):
return self._diff_generic('label_file', '--label-file')
def diffparam_mac_address(self):
return self._diff_generic('mac_address', '--mac-address')
def diffparam_memory(self):
return self._diff_generic('memory', '--memory')
def diffparam_memory_swap(self):
return self._diff_generic('memory_swap', '--memory-swap')
def diffparam_network(self):
if not self.infra_info:
return self._diff_update_and_compare('network', [], [])
net_mode_before = self.infra_info['hostconfig']['networkmode']
net_mode_after = ''
before = list(self.infra_info['networksettings'].get('networks', {}))
# Remove default 'podman' network in v3 for comparison
if before == ['podman']:
before = []
after = self.params['network'] or []
after = [i.lower() for i in after]
# Special case for options for slirp4netns rootless networking from v2
if net_mode_before == 'slirp4netns' and 'createcommand' in self.info:
cr_com = self.info['createcommand']
if '--network' in cr_com:
cr_net = cr_com[cr_com.index('--network') + 1].lower()
if 'slirp4netns:' in cr_net:
before = [cr_net]
if net_mode_before == 'pasta' and 'createcommand' in self.info:
cr_com = self.info['createcommand']
if '--network' in cr_com:
cr_net = cr_com[cr_com.index('--network') + 1].lower()
if 'pasta:' in cr_net:
before = [cr_net]
# Currently supported only 'host' and 'none' network modes idempotency
if after in [['bridge'], ['host'], ['slirp4netns'], ['pasta']]:
net_mode_after = after[0]
return self._diff_generic('network', '--network')
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_after = net_mode_after.replace('pasta', 'default')
net_mode_before = net_mode_before.replace('bridge', 'default')
net_mode_before = net_mode_before.replace('slirp4netns', 'default')
net_mode_before = net_mode_before.replace('pasta', 'default')
return self._diff_update_and_compare('network', net_mode_before, net_mode_after)
# For 4.4.0+ podman versions with no network specified
if not net_mode_after and net_mode_before == 'slirp4netns' and not after:
net_mode_after = 'slirp4netns'
if before == ['slirp4netns']:
after = ['slirp4netns']
if not net_mode_after and net_mode_before == 'bridge' and not after:
net_mode_after = 'bridge'
if before == ['bridge']:
after = ['bridge']
# For pasta networking for Podman v5
if not net_mode_after and net_mode_before == 'pasta' and not after:
net_mode_after = 'pasta'
if before == ['pasta']:
after = ['pasta']
before, after = sorted(list(set(before))), sorted(list(set(after)))
return self._diff_update_and_compare('network', before, after)
def diffparam_network_alias(self):
return self._diff_generic('network_alias', '--network-alias')
# TODO(sshnaidm)
# def diffparam_no_hosts(self):
# before = str(self.info['hostconfig']['no_hosts'])
# after = self.params['no_hosts']
# return self._diff_update_and_compare('no_hosts', before, after)
def diffparam_no_hosts(self):
return self._diff_generic('no_hosts', '--no-hosts', boolean_type=True)
def diffparam_pid(self):
return self._diff_generic('pid', '--pid')
def diffparam_pod_id_file(self):
return self._diff_generic('pod_id_file', '--pod-id-file')
# 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'] == '0.0.0.0' and LooseVersion(self.version) >= LooseVersion('5.0.0'):
return s
if h['hostip']:
return ":".join([h['hostip'], s])
return s
return self._diff_generic('publish', '--publish')
if not self.infra_info:
return self._diff_update_and_compare('publish', '', '')
def diffparam_restart_policy(self):
return self._diff_generic('restart_policy', '--restart')
ports = self.infra_info['hostconfig']['portbindings']
before = []
for port, hosts in ports.items():
if hosts:
for h in hosts:
before.append(compose(port, h))
after = self.params['publish'] or []
after = [
i.replace("/tcp", "").replace("[", "").replace("]", "").replace("0.0.0.0:", "")
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_security_opt(self):
return self._diff_generic('security_opt', '--security-opt')
def diffparam_share(self):
if not self.infra_info:
return self._diff_update_and_compare('share', '', '')
if 'sharednamespaces' in self.info:
before = self.info['sharednamespaces']
elif 'config' in self.info:
before = [
i.split('shares')[1].lower()
for i in self.info['config'] if 'shares' in i]
# TODO(sshnaidm): to discover why in podman v1 'cgroup' appears
before.remove('cgroup')
else:
before = []
if self.params['share'] is not None:
after = self.params['share'].split(",")
else:
after = ['uts', 'ipc', 'net']
# TODO: find out why on Ubuntu the 'net' is not present
if 'net' not in before:
after.remove('net')
if self.params["uidmap"] or self.params["gidmap"] or self.params["userns"]:
after.append('user')
return self._diff_generic('share', '--share')
before, after = sorted(list(set(before))), sorted(list(set(after)))
return self._diff_update_and_compare('share', before, after)
def diffparam_share_parent(self):
return self._diff_generic('share_parent', '--share-parent')
def diffparam_shm_size(self):
return self._diff_generic('shm_size', '--shm-size')
def diffparam_shm_size_systemd(self):
return self._diff_generic('shm_size_systemd', '--shm-size-systemd')
def diffparam_subgidname(self):
return self._diff_generic('subgidname', '--subgidname')
def diffparam_subuidname(self):
return self._diff_generic('subuidname', '--subuidname')
def diffparam_sysctl(self):
return self._diff_generic('sysctl', '--sysctl')
def diffparam_uidmap(self):
return self._diff_generic('uidmap', '--uidmap')
def diffparam_userns(self):
return self._diff_generic('userns', '--userns')
def diffparam_uts(self):
return self._diff_generic('uts', '--uts')
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 = createcommand('--volume', self.info)
if before == []:
before = None
after = self.params['volume']
if after is not None:
after = [":".join(
[clean_volume(i) for i in v.split(":")[:2]]) for v in self.params['volume']]
if before is not None:
before = [":".join([clean_volume(i) for i in v.split(":")[:2]]) for v in before]
self.module.log("PODMAN Before: %s and After: %s" % (before, after))
if before is None and after is None:
return self._diff_update_and_compare('volume', before, after)
if after is not None:
after = ",".join(sorted([str(i).lower() for i in after]))
if before:
before = ",".join(sorted([str(i).lower() for i in before]))
return self._diff_update_and_compare('volume', before, after)
def diffparam_volumes_from(self):
return self._diff_generic('volumes_from', '--volumes-from')
def is_different(self):
diff_func_list = [func for func in dir(self)

View file

@ -474,6 +474,8 @@ class PodQuadlet(Quadlet):
if params["gidmap"]:
for gidmap in params["gidmap"]:
params["podman_args"].append(f"--gidmap {gidmap}")
if params["exit_policy"]:
params["podman_args"].append(f"--exit-policy={params['gpus']}")
if params["gpus"]:
params["podman_args"].append(f"--gpus {params['gpus']}")
if params["hostname"]:
@ -509,6 +511,8 @@ class PodQuadlet(Quadlet):
params["podman_args"].append(f"--pid {params['pid']}")
if params["pod_id_file"]:
params["podman_args"].append(f"--pod-id-file {params['pod_id_file']}")
if params["restart_policy"]:
params["podman_args"].append(f"--restart={params['restart_policy']}")
if params["security_opt"]:
for security_opt in params["security_opt"]:
params["podman_args"].append(f"--security-opt {security_opt}")

View file

@ -117,6 +117,8 @@ options:
all containers in the pod.
type: list
elements: str
aliases:
- dns_option
required: false
dns_search:
description:
@ -125,6 +127,14 @@ options:
type: list
elements: str
required: false
exit_policy:
description:
- Set the exit policy of the pod when the last container exits. Supported policies are stop and continue
choices:
- stop
- continue
type: str
required: false
generate_systemd:
description:
- Generate systemd unit file for container.
@ -367,6 +377,10 @@ options:
options as a list of lines to add.
type: list
elements: str
restart_policy:
description:
- Restart policy to follow when containers exit.
type: str
security_opt:
description:
- Security options for the pod.

View file

@ -0,0 +1,283 @@
- name: Test podman pod idempotency
block:
- name: Delete all pods leftovers from tests
containers.podman.podman_pod:
executable: "{{ test_executable | default('podman') }}"
name: "{{ item }}"
state: absent
loop:
- "podidem1"
- "podidem2"
- name: Delete all container leftovers from tests
containers.podman.podman_container:
executable: "{{ test_executable | default('podman') }}"
name: "{{ item }}"
state: absent
loop:
- "container1"
- "container2"
- name: Create pod
containers.podman.podman_pod:
executable: "{{ test_executable | default('podman') }}"
name: podidem1
state: created
register: podidem1_info
- name: Check info
assert:
that:
- podidem1_info is changed
- >-
(podidem1_info.pod['State']['status'] is defined and
podidem1_info.pod['State']['status'] == 'Created') or
(podidem1_info.pod['State']['status'] is not defined and
podidem1_info.pod['State'] == 'Created')
- name: Create pod again
containers.podman.podman_pod:
executable: "{{ test_executable | default('podman') }}"
name: podidem1
state: created
register: podidem1_info2
- name: Check info
assert:
that:
- podidem1_info2 is not changed
- name: Start pod
containers.podman.podman_pod:
executable: "{{ test_executable | default('podman') }}"
name: podidem1
state: started
register: podidem1_info3
- name: Check info
assert:
that:
- podidem1_info3 is changed
- >-
(podidem1_info3.pod['State']['status'] is defined and
podidem1_info3.pod['State']['status'] == 'Running') or
(podidem1_info3.pod['State']['status'] is not defined and
podidem1_info3.pod['State'] == 'Running')
- name: Start pod again
containers.podman.podman_pod:
executable: "{{ test_executable | default('podman') }}"
name: podidem1
state: started
register: podidem1_info4
- name: Check info
assert:
that:
- podidem1_info4 is not changed
- name: Stop pod
containers.podman.podman_pod:
executable: "{{ test_executable | default('podman') }}"
name: podidem1
state: stopped
register: podidem1_info5
- name: Check info
assert:
that:
- podidem1_info5 is changed
- name: Stop pod again
containers.podman.podman_pod:
executable: "{{ test_executable | default('podman') }}"
name: podidem1
state: stopped
register: podidem1_info6
- name: Check info
assert:
that:
- podidem1_info6 is not changed
- name: Create stopped pod again
containers.podman.podman_pod:
executable: "{{ test_executable | default('podman') }}"
name: podidem1
state: created
register: podidem1_info7
- name: Check info
assert:
that:
- podidem1_info7 is not changed
- name: Create pod with multiple options and containers
containers.podman.podman_pod:
executable: "{{ test_executable | default('podman') }}"
name: podidem2
state: created
infra: true
network: host
share: net
userns: auto
security_opt:
- seccomp=unconfined
- apparmor=unconfined
hostname: mypod
dns:
- 1.1.1.1
volumes:
- /tmp:/tmp/:ro
- /var/run/://var/run
label:
key: cval
otherkey: kddkdk
somekey: someval
add_host:
- "google:5.5.5.5"
register: podidem2_info
- name: Check info
assert:
that:
- podidem2_info is changed
- name: Create same pod
containers.podman.podman_pod:
executable: "{{ test_executable | default('podman') }}"
name: podidem2
state: created
infra: true
network: host
share: net
userns: auto
security_opt:
- seccomp=unconfined
- apparmor=unconfined
hostname: mypod
dns:
- 1.1.1.1
volumes:
- /tmp:/tmp/:ro
- /var/run/://var/run
label:
key: cval
otherkey: kddkdk
somekey: someval
add_host:
- "google:5.5.5.5"
register: podidem2_info2
- name: Check info
assert:
that:
- podidem2_info2 is not changed
- name: Change the pod
containers.podman.podman_pod:
executable: "{{ test_executable | default('podman') }}"
name: podidem2
state: created
infra: true
network: host
share: net
userns: auto
security_opt:
- seccomp=unconfined
- apparmor=unconfined
hostname: mypod
dns:
- 1.1.1.2
volumes:
- /tmp:/tmp/:ro
- /var/run/://var/run
label:
key: cval
otherkey: kddkdk
somekey: someval
add_host:
- "google:5.5.5.5"
register: podidem2_info3
- name: Check info
assert:
that:
- podidem2_info3 is changed
- name: Start the pod
containers.podman.podman_pod:
executable: "{{ test_executable | default('podman') }}"
name: podidem2
state: started
infra: true
network: host
share: net
userns: auto
security_opt:
- seccomp=unconfined
- apparmor=unconfined
hostname: mypod
dns:
- 1.1.1.2
volumes:
- /tmp:/tmp/:ro
- /var/run/://var/run
label:
key: cval
otherkey: kddkdk
somekey: someval
add_host:
- "google:5.5.5.5"
- name: Configure and start the pod again
containers.podman.podman_pod:
executable: "{{ test_executable | default('podman') }}"
name: podidem2
state: started
infra: true
network: host
share: net
userns: auto
security_opt:
- seccomp=unconfined
- apparmor=unconfined
hostname: mypod
dns:
- 1.1.1.2
volumes:
- /tmp:/tmp/:ro
- /var/run/://var/run
label:
key: cval
otherkey: kddkdk
somekey: someval
add_host:
- "google:5.5.5.5"
register: podidem2_info4
- name: Check info
assert:
that:
- podidem2_info4 is not changed
always:
- name: Delete all pods leftovers from tests
containers.podman.podman_pod:
executable: "{{ test_executable | default('podman') }}"
name: "{{ item }}"
state: absent
loop:
- "podidem1"
- "podidem1"
- name: Delete all container leftovers from tests
containers.podman.podman_container:
executable: "{{ test_executable | default('podman') }}"
name: "{{ item }}"
state: absent
loop:
- "container1"
- "container2"

View file

@ -1153,6 +1153,9 @@
- "container1"
- "container2"
- name: Test idempotency rootless pods
include_tasks: idempotency.yml
- name: Test idempotency for root pods
include_tasks: root-pod.yml
vars: