mirror of
https://github.com/containers/ansible-podman-collections.git
synced 2026-02-04 07:11:49 +00:00
Move pod logic to separate library (#140)
This commit is contained in:
parent
bf752e4492
commit
90e6bc33f9
2 changed files with 739 additions and 735 deletions
736
plugins/module_utils/podman/podman_pod_lib.py
Normal file
736
plugins/module_utils/podman/podman_pod_lib.py
Normal file
|
|
@ -0,0 +1,736 @@
|
|||
from __future__ import (absolute_import, division, print_function)
|
||||
import json
|
||||
from distutils.version import LooseVersion
|
||||
|
||||
from ansible.module_utils._text import to_bytes, to_native
|
||||
|
||||
from ansible_collections.containers.podman.plugins.module_utils.podman.common import lower_keys
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
ARGUMENTS_SPEC_POD = dict(
|
||||
state=dict(
|
||||
type='str',
|
||||
default="created",
|
||||
choices=[
|
||||
'created',
|
||||
'killed',
|
||||
'restarted',
|
||||
'absent',
|
||||
'started',
|
||||
'stopped',
|
||||
'paused',
|
||||
'unpaused',
|
||||
]),
|
||||
recreate=dict(type='bool', default=False),
|
||||
add_host=dict(type='list', required=False, elements='str'),
|
||||
cgroup_parent=dict(type='str', required=False),
|
||||
dns=dict(type='list', elements='str', required=False),
|
||||
dns_opt=dict(type='list', elements='str', required=False),
|
||||
dns_search=dict(type='list', elements='str', required=False),
|
||||
hostname=dict(type='str', required=False),
|
||||
infra=dict(type='bool', required=False),
|
||||
infra_conmon_pidfile=dict(type='str', required=False),
|
||||
infra_command=dict(type='str', required=False),
|
||||
infra_image=dict(type='str', required=False),
|
||||
ip=dict(type='str', required=False),
|
||||
label=dict(type='dict', required=False),
|
||||
label_file=dict(type='str', required=False),
|
||||
mac_address=dict(type='str', required=False),
|
||||
name=dict(type='str', required=True),
|
||||
network=dict(type='str', required=False),
|
||||
no_hosts=dict(type='bool', required=False),
|
||||
pod_id_file=dict(type='str', required=False),
|
||||
publish=dict(type='list', required=False,
|
||||
elements='str', aliases=['ports']),
|
||||
share=dict(type='str', required=False),
|
||||
executable=dict(type='str', required=False, default='podman'),
|
||||
debug=dict(type='bool', default=False),
|
||||
)
|
||||
|
||||
|
||||
class PodmanPodModuleParams:
|
||||
"""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', 'restart', 'stop', 'delete', 'pause',
|
||||
'unpause', 'kill']:
|
||||
return self._simple_action()
|
||||
if self.action in ['create']:
|
||||
return self._create_action()
|
||||
self.module.fail_json(msg="Unknown action %s" % self.action)
|
||||
|
||||
def _simple_action(self):
|
||||
if self.action in ['start', 'restart', 'stop', 'pause', 'unpause', 'kill']:
|
||||
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]
|
||||
self.module.fail_json(msg="Unknown action %s" % self.action)
|
||||
|
||||
def _create_action(self):
|
||||
cmd = [self.action]
|
||||
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)
|
||||
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_add_host(self, c):
|
||||
for g in self.params['add_host']:
|
||||
c += ['--add-host', g]
|
||||
return c
|
||||
|
||||
def addparam_cgroup_parent(self, c):
|
||||
return c + ['--cgroup-parent', self.params['cgroup_parent']]
|
||||
|
||||
def addparam_dns(self, c):
|
||||
for g in self.params['dns']:
|
||||
c += ['--dns', g]
|
||||
return c
|
||||
|
||||
def addparam_dns_opt(self, c):
|
||||
for g in self.params['dns_opt']:
|
||||
c += ['--dns-opt', g]
|
||||
return c
|
||||
|
||||
def addparam_dns_search(self, c):
|
||||
for g in self.params['dns_search']:
|
||||
c += ['--dns-search', g]
|
||||
return c
|
||||
|
||||
def addparam_hostname(self, c):
|
||||
return c + ['--hostname', self.params['hostname']]
|
||||
|
||||
def addparam_infra(self, c):
|
||||
return c + [b'='.join([b'--infra',
|
||||
to_bytes(self.params['infra'],
|
||||
errors='surrogate_or_strict')])]
|
||||
|
||||
def addparam_infra_conmon_pidfile(self, c):
|
||||
return c + ['--infra-conmon-pidfile', self.params['infra_conmon_pidfile']]
|
||||
|
||||
def addparam_infra_command(self, c):
|
||||
return c + ['--infra-command', self.params['infra_command']]
|
||||
|
||||
def addparam_infra_image(self, c):
|
||||
return c + ['--infra-image', self.params['infra_image']]
|
||||
|
||||
def addparam_ip(self, c):
|
||||
return c + ['--ip', self.params['ip']]
|
||||
|
||||
def addparam_label(self, c):
|
||||
for label in self.params['label'].items():
|
||||
c += ['--label', b'='.join(
|
||||
[to_bytes(l, errors='surrogate_or_strict') for l in label])]
|
||||
return c
|
||||
|
||||
def addparam_label_file(self, c):
|
||||
return c + ['--label-file', self.params['label_file']]
|
||||
|
||||
def addparam_mac_address(self, c):
|
||||
return c + ['--mac-address', self.params['mac_address']]
|
||||
|
||||
def addparam_name(self, c):
|
||||
return c + ['--name', self.params['name']]
|
||||
|
||||
def addparam_network(self, c):
|
||||
return c + ['--network', self.params['network']]
|
||||
|
||||
def addparam_no_hosts(self, c):
|
||||
return c + ["=".join('--no-hosts', self.params['no_hosts'])]
|
||||
|
||||
def addparam_pod_id_file(self, c):
|
||||
return c + ['--pod-id-file', self.params['pod_id_file']]
|
||||
|
||||
def addparam_publish(self, c):
|
||||
for g in self.params['publish']:
|
||||
c += ['--publish', g]
|
||||
return c
|
||||
|
||||
def addparam_share(self, c):
|
||||
return c + ['--share', self.params['share']]
|
||||
|
||||
|
||||
class PodmanPodDefaults:
|
||||
def __init__(self, module, podman_version):
|
||||
self.module = module
|
||||
self.version = podman_version
|
||||
self.defaults = {
|
||||
'add_host': [],
|
||||
'dns': [],
|
||||
'dns_opt': [],
|
||||
'dns_search': [],
|
||||
'infra': True,
|
||||
'label': {},
|
||||
}
|
||||
|
||||
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
|
||||
return self.defaults
|
||||
|
||||
|
||||
class PodmanPodDiff:
|
||||
def __init__(self, module, module_params, info, infra_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.infra_info = lower_keys(infra_info)
|
||||
self.params = self.defaultize()
|
||||
self.diff = {'before': {}, 'after': {}}
|
||||
self.non_idempotent = {}
|
||||
|
||||
def defaultize(self):
|
||||
params_with_defaults = {}
|
||||
self.default_dict = PodmanPodDefaults(
|
||||
self.module, 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_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)
|
||||
|
||||
def diffparam_cgroup_parent(self):
|
||||
if 'cgroupparent' in self.info:
|
||||
before = self.info['cgroupparent']
|
||||
elif 'config' in self.info and self.info['config'].get('cgroupparent'):
|
||||
before = self.info['config']['cgroupparent']
|
||||
after = self.params['cgroup_parent'] or before
|
||||
return self._diff_update_and_compare('cgroup_parent', before, after)
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
# TODO(sshnaidm): https://github.com/containers/podman/issues/6968
|
||||
def diffparam_infra(self):
|
||||
if 'state' in self.info and 'infracontainerid' in self.info['state']:
|
||||
before = self.info['state']['infracontainerid'] != ""
|
||||
else:
|
||||
# TODO(sshnaidm): https://github.com/containers/podman/issues/6968
|
||||
before = 'infracontainerid' in self.info
|
||||
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_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]
|
||||
after = after.split("/")[-1]
|
||||
return self._diff_update_and_compare('infra_image', before, after)
|
||||
|
||||
# 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_label(self):
|
||||
if 'config' in self.info and 'labels' in self.info['config']:
|
||||
before = self.info['config'].get('labels') or {}
|
||||
else:
|
||||
before = self.info['labels'] if 'labels' in self.info else {}
|
||||
after = self.params['label']
|
||||
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_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 = self.infra_info['networksettings'].get('networks', [])
|
||||
after = self.params['network']
|
||||
# Currently supported only 'host' and 'none' network modes idempotency
|
||||
if after in ['bridge', 'host', 'slirp4netns']:
|
||||
net_mode_after = after
|
||||
elif after:
|
||||
after = after.split(",")
|
||||
else:
|
||||
after = []
|
||||
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)
|
||||
|
||||
# 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)
|
||||
|
||||
# TODO(sshnaidm) Need to add port ranges support
|
||||
def diffparam_publish(self):
|
||||
if not self.infra_info:
|
||||
return self._diff_update_and_compare('publish', '', '')
|
||||
ports = self.infra_info['hostconfig']['portbindings']
|
||||
before = [":".join([
|
||||
j[0]['hostip'],
|
||||
str(j[0]["hostport"]),
|
||||
i.replace('/tcp', '')
|
||||
]).strip(':') for i, j in ports.items()]
|
||||
after = self.params['publish'] or []
|
||||
after = [i.replace("/tcp", "") 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_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']
|
||||
before, after = sorted(list(set(before))), sorted(list(set(after)))
|
||||
return self._diff_update_and_compare('share', 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
|
||||
|
||||
|
||||
class PodmanPod:
|
||||
"""Perform pod tasks.
|
||||
|
||||
Manages podman pod, inspects it and checks its current state
|
||||
"""
|
||||
|
||||
def __init__(self, module, name, module_params):
|
||||
"""Initialize PodmanPod class.
|
||||
|
||||
Arguments:
|
||||
module {obj} -- ansible module object
|
||||
name {str} -- name of pod
|
||||
"""
|
||||
|
||||
self.module = module
|
||||
self.module_params = module_params
|
||||
self.name = name
|
||||
self.stdout, self.stderr = '', ''
|
||||
self.info = self.get_info()
|
||||
self.infra_info = self.get_infra_info()
|
||||
self.version = self._get_podman_version()
|
||||
self.diff = {}
|
||||
self.actions = []
|
||||
|
||||
@property
|
||||
def exists(self):
|
||||
"""Check if pod exists."""
|
||||
return bool(self.info != {})
|
||||
|
||||
@property
|
||||
def different(self):
|
||||
"""Check if pod is different."""
|
||||
diffcheck = PodmanPodDiff(
|
||||
self.module,
|
||||
self.module_params,
|
||||
self.info,
|
||||
self.infra_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 pod is running now."""
|
||||
if 'status' in self.info['State']:
|
||||
return self.info['State']['status'] == 'Running'
|
||||
return self.info['State'] == 'Running'
|
||||
|
||||
@property
|
||||
def paused(self):
|
||||
"""Return True if pod is paused now."""
|
||||
if 'status' in self.info['State']:
|
||||
return self.info['State']['status'] == 'Paused'
|
||||
return self.info['State'] == 'Paused'
|
||||
|
||||
@property
|
||||
def stopped(self):
|
||||
"""Return True if pod exists and is not running now."""
|
||||
if not self.exists:
|
||||
return False
|
||||
if 'status' in self.info['State']:
|
||||
return not (self.info['State']['status'] == 'Running')
|
||||
return not (self.info['State'] == 'Running')
|
||||
|
||||
def get_info(self):
|
||||
"""Inspect pod and gather info about it."""
|
||||
# pylint: disable=unused-variable
|
||||
rc, out, err = self.module.run_command(
|
||||
[self.module_params['executable'], b'pod', b'inspect', self.name])
|
||||
return json.loads(out) if rc == 0 else {}
|
||||
|
||||
def get_infra_info(self):
|
||||
"""Inspect pod and gather info about it."""
|
||||
if not self.info:
|
||||
return {}
|
||||
if 'InfraContainerID' in self.info:
|
||||
infra_container_id = self.info['InfraContainerID']
|
||||
elif 'State' in self.info and 'infraContainerID' in self.info['State']:
|
||||
infra_container_id = self.info['State']['infraContainerID']
|
||||
else:
|
||||
return {}
|
||||
# pylint: disable=unused-variable
|
||||
rc, out, err = self.module.run_command(
|
||||
[self.module_params['executable'], b'inspect', infra_container_id])
|
||||
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 pod.
|
||||
|
||||
Arguments:
|
||||
action {str} -- action to perform - start, create, stop, pause
|
||||
unpause, delete, restart, kill
|
||||
"""
|
||||
b_command = PodmanPodModuleParams(action,
|
||||
self.module_params,
|
||||
self.version,
|
||||
self.module,
|
||||
).construct_command_from_params()
|
||||
full_cmd = " ".join([self.module_params['executable'], 'pod']
|
||||
+ [to_native(i) for i in b_command])
|
||||
self.module.log("PODMAN-POD-DEBUG: %s" % full_cmd)
|
||||
self.actions.append(full_cmd)
|
||||
if not self.module.check_mode:
|
||||
rc, out, err = self.module.run_command(
|
||||
[self.module_params['executable'], b'pod'] + b_command,
|
||||
expand_user_and_vars=False)
|
||||
self.stdout = out
|
||||
self.stderr = err
|
||||
if rc != 0:
|
||||
self.module.fail_json(
|
||||
msg="Can't %s pod %s" % (action, self.name),
|
||||
stdout=out, stderr=err)
|
||||
|
||||
def delete(self):
|
||||
"""Delete the pod."""
|
||||
self._perform_action('delete')
|
||||
|
||||
def stop(self):
|
||||
"""Stop the pod."""
|
||||
self._perform_action('stop')
|
||||
|
||||
def start(self):
|
||||
"""Start the pod."""
|
||||
self._perform_action('start')
|
||||
|
||||
def create(self):
|
||||
"""Create the pod."""
|
||||
self._perform_action('create')
|
||||
|
||||
def recreate(self):
|
||||
"""Recreate the pod."""
|
||||
self.delete()
|
||||
self.create()
|
||||
|
||||
def restart(self):
|
||||
"""Restart the pod."""
|
||||
self._perform_action('restart')
|
||||
|
||||
def kill(self):
|
||||
"""Kill the pod."""
|
||||
self._perform_action('kill')
|
||||
|
||||
def pause(self):
|
||||
"""Pause the pod."""
|
||||
self._perform_action('pause')
|
||||
|
||||
def unpause(self):
|
||||
"""Unpause the pod."""
|
||||
self._perform_action('unpause')
|
||||
|
||||
|
||||
class PodmanPodManager:
|
||||
"""Module manager class.
|
||||
|
||||
Defines according to parameters what actions should be applied to pod
|
||||
"""
|
||||
|
||||
def __init__(self, module, params):
|
||||
"""Initialize PodmanManager class.
|
||||
|
||||
Arguments:
|
||||
module {obj} -- ansible module object
|
||||
"""
|
||||
|
||||
self.module = module
|
||||
self.module_params = params
|
||||
self.results = {
|
||||
'changed': False,
|
||||
'actions': [],
|
||||
'pod': {},
|
||||
}
|
||||
self.name = self.module_params['name']
|
||||
self.executable = \
|
||||
self.module.get_bin_path(self.module_params['executable'],
|
||||
required=True)
|
||||
self.state = self.module_params['state']
|
||||
self.recreate = self.module_params['recreate']
|
||||
self.pod = PodmanPod(self.module, self.name, self.module_params)
|
||||
|
||||
def update_pod_result(self, changed=True):
|
||||
"""Inspect the current pod, update results with last info, exit.
|
||||
|
||||
Keyword Arguments:
|
||||
changed {bool} -- whether any action was performed
|
||||
(default: {True})
|
||||
"""
|
||||
facts = self.pod.get_info() if changed else self.pod.info
|
||||
out, err = self.pod.stdout, self.pod.stderr
|
||||
self.results.update({'changed': changed, 'pod': facts,
|
||||
'podman_actions': self.pod.actions},
|
||||
stdout=out, stderr=err)
|
||||
if self.pod.diff:
|
||||
self.results.update({'diff': self.pod.diff})
|
||||
if self.module.params['debug'] or self.module_params['debug']:
|
||||
self.results.update({'podman_version': self.pod.version})
|
||||
|
||||
def execute(self):
|
||||
"""Execute the desired action according to map of actions & states."""
|
||||
states_map = {
|
||||
'created': self.make_created,
|
||||
'started': self.make_started,
|
||||
'stopped': self.make_stopped,
|
||||
'absent': self.make_absent,
|
||||
'killed': self.make_killed,
|
||||
'paused': self.make_paused,
|
||||
'unpaused': self.make_unpaused,
|
||||
|
||||
}
|
||||
process_action = states_map[self.state]
|
||||
process_action()
|
||||
return self.results
|
||||
|
||||
def _create_or_recreate_pod(self):
|
||||
"""Ensure pod exists and is exactly as it should be by input params."""
|
||||
changed = False
|
||||
if self.pod.exists:
|
||||
if self.pod.different or self.recreate:
|
||||
self.pod.recreate()
|
||||
self.results['actions'].append('recreated %s' % self.pod.name)
|
||||
changed = True
|
||||
elif not self.pod.exists:
|
||||
self.pod.create()
|
||||
self.results['actions'].append('created %s' % self.pod.name)
|
||||
changed = True
|
||||
return changed
|
||||
|
||||
def make_created(self):
|
||||
"""Run actions if desired state is 'created'."""
|
||||
if self.pod.exists and not self.pod.different:
|
||||
self.update_pod_result(changed=False)
|
||||
return
|
||||
self._create_or_recreate_pod()
|
||||
self.update_pod_result()
|
||||
|
||||
def make_killed(self):
|
||||
"""Run actions if desired state is 'killed'."""
|
||||
self._create_or_recreate_pod()
|
||||
self.pod.kill()
|
||||
self.results['actions'].append('killed %s' % self.pod.name)
|
||||
self.update_pod_result()
|
||||
|
||||
def make_paused(self):
|
||||
"""Run actions if desired state is 'paused'."""
|
||||
changed = self._create_or_recreate_pod()
|
||||
if self.pod.paused:
|
||||
self.update_pod_result(changed=changed)
|
||||
return
|
||||
self.pod.pause()
|
||||
self.results['actions'].append('paused %s' % self.pod.name)
|
||||
self.update_pod_result()
|
||||
|
||||
def make_unpaused(self):
|
||||
"""Run actions if desired state is 'unpaused'."""
|
||||
changed = self._create_or_recreate_pod()
|
||||
if not self.pod.paused:
|
||||
self.update_pod_result(changed=changed)
|
||||
return
|
||||
self.pod.unpause()
|
||||
self.results['actions'].append('unpaused %s' % self.pod.name)
|
||||
self.update_pod_result()
|
||||
|
||||
def make_started(self):
|
||||
"""Run actions if desired state is 'started'."""
|
||||
changed = self._create_or_recreate_pod()
|
||||
if not changed and self.pod.running:
|
||||
self.update_pod_result(changed=changed)
|
||||
return
|
||||
|
||||
# self.pod.unpause() TODO(sshnaidm): to unpause if state == started?
|
||||
self.pod.start()
|
||||
self.results['actions'].append('started %s' % self.pod.name)
|
||||
self.update_pod_result()
|
||||
|
||||
def make_stopped(self):
|
||||
"""Run actions if desired state is 'stopped'."""
|
||||
changed = self._create_or_recreate_pod()
|
||||
if changed or self.pod.stopped:
|
||||
self.update_pod_result(changed=changed)
|
||||
return
|
||||
elif self.pod.running:
|
||||
self.pod.stop()
|
||||
self.results['actions'].append('stopped %s' % self.pod.name)
|
||||
self.update_pod_result()
|
||||
|
||||
def make_absent(self):
|
||||
"""Run actions if desired state is 'absent'."""
|
||||
if not self.pod.exists:
|
||||
self.results.update({'changed': False})
|
||||
elif self.pod.exists:
|
||||
self.pod.delete()
|
||||
self.results['actions'].append('deleted %s' % self.pod.name)
|
||||
self.results.update({'changed': True})
|
||||
self.results.update({'pod': {},
|
||||
'podman_actions': self.pod.actions})
|
||||
Loading…
Add table
Add a link
Reference in a new issue