1
0
Fork 0
mirror of https://github.com/containers/ansible-podman-collections.git synced 2026-02-03 23:01:48 +00:00

Fix idempotency for tagging local images (#980)

Signed-off-by: Jeoffrey Bakker <jeoffreybakker@users.noreply.github.com>
This commit is contained in:
Jeoffrey Bakker 2025-09-18 13:59:31 +02:00 committed by GitHub
parent 991e461ea5
commit 0d44070261
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 104 additions and 5 deletions

View file

@ -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():

View file

@ -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:

View file

@ -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