Skip to content

Commit

Permalink
Move alternate image name definition from vars/main.yml to tests/opti…
Browse files Browse the repository at this point in the history
…ons.yml
  • Loading branch information
iamjpotts committed Nov 29, 2022
1 parent e8ce92d commit b1b6618
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 32 deletions.
28 changes: 21 additions & 7 deletions plugins/module_utils/image_archive.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ class ImageArchiveManifestSummary(object):

def __init__(self, image_id, repo_tags):
"""
:param image_id String containing file name portion of Config entry, e.g. abcde12345 from abcde12345.json
:param repo_tags List of docker image names, e.g. ["hello-world:latest"]
:param image_id: File name portion of Config entry, e.g. abcde12345 from abcde12345.json
:type image_id: str
:param repo_tags Docker image names, e.g. ["hello-world:latest"]
:type repo_tags: list
"""

self.image_id = image_id
Expand All @@ -32,6 +33,13 @@ def __init__(self, image_id, repo_tags):

class ImageArchiveInvalidException(Exception):
def __init__(self, message, cause):
"""
:param message: Exception message
:type message: str
:param cause: Inner exception that this exception wraps
:type cause: Exception
"""

super(ImageArchiveInvalidException, self).__init__(message)

# Python 2 doesn't support causes
Expand All @@ -42,6 +50,12 @@ def api_image_id(archive_image_id):
"""
Accepts an image hash in the format stored in manifest.json, and returns an equivalent identifier
that represents the same image hash, but in the format presented by the Docker Engine API.
:param archive_image_id: plain image hash
:type archive_image_id: str
:returns: Prefixed hash used by REST api
:rtype: str
"""

return 'sha256:%s' % archive_image_id
Expand All @@ -60,11 +74,11 @@ def archived_image_manifest(archive_path):
ImageArchiveInvalidException if a file already exists at archive_path, but
we could not extract an image ID from it.
Returns:
Either None, if no file exists at archive_path, or the extracted image ID.
The extracted ID will not have a sha256: prefix.
:param archive_path: Tar file to read
:type archive_path: str
:return ImageArchiveManifestSummary
:return: None, if no file at archive_path, or the extracted image ID, which will not have a sha256: prefix.
:rtype: ImageArchiveManifestSummary
"""

try:
Expand Down
41 changes: 31 additions & 10 deletions plugins/modules/docker_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,13 +339,14 @@

from ansible.module_utils.common.text.converters import to_native

from ansible_collections.community.docker.plugins.module_utils.common_api import (
from ..module_utils.common_api import (
AnsibleDockerClient,
RequestException,
)
from ..module_utils.image_archive import (
archived_image_manifest,
ImageArchiveInvalidException
api_image_id,
ImageArchiveInvalidException,
)
from ansible_collections.community.docker.plugins.module_utils.util import (
clean_dict_booleans_for_docker_api,
Expand Down Expand Up @@ -377,6 +378,15 @@
class ImageManager(DockerBaseClass):

def __init__(self, client, results):
"""
Configure a docker_image task.
:param client: Ansible Docker Client wrapper over Docker client
:type client: AnsibleDockerClient
:param results: This task adds its output values to this dictionary
:type results: dict
"""

super(ImageManager, self).__init__()

Expand Down Expand Up @@ -536,8 +546,17 @@ def archived_image_action(failure_logger, archive_path, current_image_name, curr
"""
If the archive is missing or requires replacement, return an action message.
Returns:
Either None, or an Ansible action message.
:param failure_logger: a logging function that accepts one parameter of type str
:type failure_logger: Callable
:param archive_path: Filename to write archive to
:type archive_path: str
:param current_image_name: repo:tag
:type current_image_name: str
:param current_image_id: Hash, including hash type prefix such as "sha256:"
:type current_image_id: str
:returns: Either None, or an Ansible action message.
:rtype: str
"""

def build_msg(reason):
Expand All @@ -551,20 +570,22 @@ def build_msg(reason):

if archived is None:
return build_msg('since none present')
elif current_image_id == ('sha256:%s' % archived.image_id) and [current_image_name] == archived.repo_tags:
elif current_image_id == api_image_id(archived.image_id) and [current_image_name] == archived.repo_tags:
return None
else:
name = ', '.join(archived.repo_tags)

return build_msg('overwriting archive with image %s named %s' % (archived.image_id, name))

def archive_image(self, name, tag):
'''
"""
Archive an image to a .tar file. Called when archive_path is passed.
:param name - name of the image. Type: str
:return None
'''
:param name: Name/repository of the image
:type name: str
:param tag: Optional image tag; assumed to be "latest" if None
:type tag: str
"""

if not tag:
tag = "latest"
Expand All @@ -583,7 +604,7 @@ def archive_image(self, name, tag):
# Will have a 'sha256:' prefix
image_id = image['Id']

action = self.archived_image_action(self.log, self.archive_path, image_name, image_id)
action = self.archived_image_action(self.client.module.debug, self.archive_path, image_name, image_id)

if action:
self.results['actions'].append(action)
Expand Down
2 changes: 1 addition & 1 deletion plugins/plugin_utils/common_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from ansible.errors import AnsibleConnectionFailure
from ansible.utils.display import Display

from ansible_collections.community.docker.plugins.module_utils.common_api import (
from ..module_utils.common_api import (
AnsibleDockerClientBase,
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@
set_fact:
iname: "{{ name_prefix ~ '-options' }}"
iname_1: "{{ name_prefix ~ '-options-1' }}"
hello_world_alt: "{{ name_prefix ~ '-hello-world-alt' }}:v1.2.3-foo"

- name: Registering image name
set_fact:
inames: "{{ inames + [iname, iname_1, docker_test_image_hello_world_archive_alt] }}"
inames: "{{ inames + [iname, iname_1, hello_world_alt] }}"

####################################################################
## build.args ######################################################
Expand Down Expand Up @@ -276,12 +277,12 @@
- name: Tag image with different name
docker_image:
name: "{{ docker_test_image_hello_world }}"
repository: "{{ docker_test_image_hello_world_archive_alt }}"
repository: "{{ hello_world_alt }}"
source: local

- name: Archive image 4th time, should overwrite due to different name even when ID is same
docker_image:
name: "{{ docker_test_image_hello_world_archive_alt }}"
name: "{{ hello_world_alt }}"
# Tagged as docker_test_image_hello_world but has same hash/id (before this task overwrites it)
archive_path: "{{ remote_tmp_dir }}/image_mutated.tar"
source: local
Expand Down
6 changes: 0 additions & 6 deletions tests/integration/targets/docker_image/vars/main.yml

This file was deleted.

11 changes: 6 additions & 5 deletions tests/unit/plugins/test_support/docker_image_archive_stubbing.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ def write_imitation_archive(file_name, image_id, repo_tags):
* manifest.json contains a one-element array
* The element has a Config property with "[image_id].json" as the value name
Args:
file_name: real file to write
image_id: fake sha256 hash (without the sha256: prefix)
repo_tags: list of fake image:tag's
:param file_name: Name of file to create
:type file_name: str
:param image_id: Fake sha256 hash (without the sha256: prefix)
:type image_id: str
:param repo_tags: list of fake image:tag's
:type repo_tags: list
"""

manifest = [
Expand Down

0 comments on commit b1b6618

Please sign in to comment.