diff --git a/plugins/modules/podman_tag.py b/plugins/modules/podman_tag.py index 1c6536e..88c07ce 100644 --- a/plugins/modules/podman_tag.py +++ b/plugins/modules/podman_tag.py @@ -50,19 +50,80 @@ EXAMPLES = """ from ansible.module_utils.basic import AnsibleModule # noqa: E402 +def create_full_qualified_image_name(name): + if "@" in name: + name, digest = name.split("@", 1) + tag_or_digest = "@" + digest + else: + tag_or_digest = "" + + parts = name.split("/") + + if len(parts) > 1 and (("." in parts[0] or ":" in parts[0]) or parts[0] == "localhost"): + registry = parts[0] + rest = parts[1:] + else: + registry = "localhost" + rest = parts + + if len(rest) == 1: + if registry == "docker.io": + namespace = "library" + else: + namespace = "" + image_name = rest[0] + else: + namespace = "/".join(rest[:-1]) + image_name = rest[-1] + + if not tag_or_digest and ":" in image_name: + image_name, tag_or_digest = image_name.split(":", 1) + tag_or_digest = ":" + tag_or_digest + + if not tag_or_digest: + tag_or_digest = ":latest" + + if namespace == "": + qualified = f"{registry}/{image_name}{tag_or_digest}" + else: + qualified = f"{registry}/{namespace}/{image_name}{tag_or_digest}" + + return qualified + + +def get_image_id(module, executable, name): + command = [executable, "image", "ls", "-q", name] + rc, out, err = module.run_command(command) + if rc != 0: + return None + return out.strip() + + def tag(module, executable): changed = False command = [executable, "tag"] command.append(module.params["image"]) command.extend(module.params["target_names"]) + + id = get_image_id(module, executable, module.params["image"]) + if id: + for name in module.params["target_names"]: + image_id = get_image_id(module, executable, name) + if image_id != id or image_id == "": + changed = True + if module.check_mode: return changed, "", "" - rc, out, err = module.run_command(command) - if rc == 0: - changed = True + + if changed: + rc, out, err = module.run_command(command) + if rc == 0: + changed = True + else: + module.fail_json(msg="Error tagging local image %s: %s" % (module.params["image"], err)) + return changed, out, err else: - module.fail_json(msg="Error tagging local image %s: %s" % (module.params["image"], err)) - return changed, out, err + return False, "", "" def main(): diff --git a/tests/integration/targets/podman_tag/tasks/main.yml b/tests/integration/targets/podman_tag/tasks/main.yml index ee7a6e2..0ab58fd 100644 --- a/tests/integration/targets/podman_tag/tasks/main.yml +++ b/tests/integration/targets/podman_tag/tasks/main.yml @@ -13,6 +13,22 @@ target_names: - openjdk8 - jdk8 + register: tag_result + + - name: Tag image again to test idempotency + containers.podman.podman_tag: + executable: "{{ test_executable | default('podman') }}" + image: docker.io/library/alpine + target_names: + - openjdk8 + - jdk8 + register: tag_result_idempotency + + - name: Check idempotency + assert: + that: + - tag_result.changed == true + - tag_result_idempotency.changed == false - name: Get tagged image info containers.podman.podman_image_info: diff --git a/tests/unit/plugins/modules/test_podman_tag.py b/tests/unit/plugins/modules/test_podman_tag.py new file mode 100644 index 0000000..2858375 --- /dev/null +++ b/tests/unit/plugins/modules/test_podman_tag.py @@ -0,0 +1,22 @@ +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +import pytest + +from ansible_collections.containers.podman.plugins.modules.podman_tag import create_full_qualified_image_name + + +@pytest.mark.parametrize( + "test_input, expected", + [ + ("alpine", "localhost/alpine:latest"), + ("alpine:3.19", "localhost/alpine:3.19"), + ("docker.io/library/alpine", "docker.io/library/alpine:latest"), + ("docker.io/alpine", "docker.io/library/alpine:latest"), + ("docker.io/alpine@sha256:1234567890abcdef", "docker.io/library/alpine@sha256:1234567890abcdef"), + ], +) +def test_create_full_qualified_image_name(test_input, expected): + print(create_full_qualified_image_name.__code__.co_filename) + assert create_full_qualified_image_name(test_input) == expected