From d25cf5796759111c4314d7562c7ec679a65ab935 Mon Sep 17 00:00:00 2001 From: Sergey <6213510+sshnaidm@users.noreply.github.com> Date: Sun, 7 Jul 2024 22:55:26 +0300 Subject: [PATCH] Idempotency improvements (#795) * Fix integers in Quadlet generation * Work around quotes in command for idempotency Signed-off-by: Sagi Shnaidman --- plugins/module_utils/podman/common.py | 4 ++ .../podman/podman_container_lib.py | 29 ++++++++- plugins/module_utils/podman/quadlet.py | 2 +- .../tasks/idem_all.yml | 63 +++++++++++++++++++ 4 files changed, 95 insertions(+), 3 deletions(-) diff --git a/plugins/module_utils/podman/common.py b/plugins/module_utils/podman/common.py index acdc649..ec06af2 100644 --- a/plugins/module_utils/podman/common.py +++ b/plugins/module_utils/podman/common.py @@ -357,6 +357,10 @@ def createcommand(argument, info_config, boolean_type=False): cr_com = info_config["createcommand"] argument_values = ARGUMENTS_OPTS_DICT.get(argument, [argument]) all_values = [] + # Remove command args from the list + container_cmd = info_config.get("cmd") + if container_cmd and container_cmd == cr_com[-len(container_cmd):]: + cr_com = cr_com[:-len(container_cmd)] for arg in argument_values: for ind, cr_opt in enumerate(cr_com): if arg == cr_opt: diff --git a/plugins/module_utils/podman/podman_container_lib.py b/plugins/module_utils/podman/podman_container_lib.py index 76458f1..44a16fa 100644 --- a/plugins/module_utils/podman/podman_container_lib.py +++ b/plugins/module_utils/podman/podman_container_lib.py @@ -459,7 +459,7 @@ class PodmanModuleParams: return c + ['--dns-search', self.params['dns_search']] def addparam_entrypoint(self, c): - return c + ['--entrypoint', self.params['entrypoint']] + return c + ['--entrypoint=%s' % self.params['entrypoint']] def addparam_env(self, c): for env_value in self.params['env'].items(): @@ -1006,10 +1006,36 @@ class PodmanContainerDiff: # return self._diff_generic('cidfile', '--cidfile') def diffparam_command(self): + def _join_quotes(com_list): + result = [] + buffer = [] + in_quotes = False + + for item in com_list: + if item.startswith('"') and not in_quotes: + buffer.append(item) + in_quotes = True + elif item.endswith('"') and in_quotes: + buffer.append(item) + result.append(' '.join(buffer).strip('"')) + buffer = [] + in_quotes = False + elif in_quotes: + buffer.append(item) + else: + result.append(item) + if in_quotes: + result.extend(buffer) + + return result + # 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'] + before = _join_quotes(before) + if isinstance(after, list): + after = [str(i) for i in after] if isinstance(after, str): after = shlex.split(after) return self._diff_update_and_compare('command', before, after) @@ -1444,7 +1470,6 @@ class PodmanContainerDiff: [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: diff --git a/plugins/module_utils/podman/quadlet.py b/plugins/module_utils/podman/quadlet.py index 429848a..9c1caad 100644 --- a/plugins/module_utils/podman/quadlet.py +++ b/plugins/module_utils/podman/quadlet.py @@ -159,7 +159,7 @@ class ContainerQuadlet(Quadlet): if params["cap_drop"]: params["cap_drop"] = " ".join(params["cap_drop"]) if params["command"]: - params["command"] = (" ".join(params["command"]) + params["command"] = (" ".join([str(j) for j in params["command"]]) if isinstance(params["command"], list) else params["command"]) if params["label"]: diff --git a/tests/integration/targets/podman_container_idempotency/tasks/idem_all.yml b/tests/integration/targets/podman_container_idempotency/tasks/idem_all.yml index 11dbf59..91eec8a 100644 --- a/tests/integration/targets/podman_container_idempotency/tasks/idem_all.yml +++ b/tests/integration/targets/podman_container_idempotency/tasks/idem_all.yml @@ -420,6 +420,69 @@ assert: that: test29 is changed +- name: Run container with complex command + containers.podman.podman_container: + executable: "{{ test_executable | default('podman') }}" + name: idempotency2 + image: alpine + command: + - sh + - -c + - read + - -p + - 8012 + interactive: true + tty: true + device: + - /dev/fuse + register: test30 + +- name: Run container with complex command again + containers.podman.podman_container: + executable: "{{ test_executable | default('podman') }}" + name: idempotency2 + image: alpine + command: + - sh + - -c + - read + - -p + - 8012 + interactive: true + tty: true + device: + - /dev/fuse + register: test31 + +- name: Run container with different complex command + containers.podman.podman_container: + executable: "{{ test_executable | default('podman') }}" + name: idempotency2 + image: alpine + command: + - sh + - -c + - read + - -p + - 8015 + interactive: true + tty: true + device: + - /dev/fuse + register: test32 + +- name: Check info of container with complex command + assert: + that: test30 is changed + +- name: Check info of container with complex command again + assert: + that: test31 is not changed + +- name: Check info of container with complex command + assert: + that: test32 is changed + - name: Remove dependent test container containers.podman.podman_container: executable: "{{ test_executable | default('podman') }}"