diff --git a/src/confcom/HISTORY.rst b/src/confcom/HISTORY.rst index a4a1b5b5ba1..770f05f1382 100644 --- a/src/confcom/HISTORY.rst +++ b/src/confcom/HISTORY.rst @@ -2,6 +2,11 @@ Release History =============== +0.2.13 +* fixing bug where you could not pull by sha value if a tag was not specified +* fixing error message when attempting to use sha value with tar files +* making image caching template-wide instead of container group-wide + 0.2.12 * adding ability for mixed-mode OCI image pulling, e.g. using tar files and remote registries in the same template * adding option to use allow-all regex for environment variables diff --git a/src/confcom/azext_confcom/data/internal_config.json b/src/confcom/azext_confcom/data/internal_config.json index 962a05252af..5c29558af2f 100644 --- a/src/confcom/azext_confcom/data/internal_config.json +++ b/src/confcom/azext_confcom/data/internal_config.json @@ -1,5 +1,5 @@ { - "version": "0.2.12", + "version": "0.2.13", "hcsshim_config": { "maxVersion": "1.0.0", "minVersion": "0.0.1" diff --git a/src/confcom/azext_confcom/rootfs_proxy.py b/src/confcom/azext_confcom/rootfs_proxy.py index 3482704b66d..88ab6025303 100644 --- a/src/confcom/azext_confcom/rootfs_proxy.py +++ b/src/confcom/azext_confcom/rootfs_proxy.py @@ -17,6 +17,9 @@ class SecurityPolicyProxy: # pylint: disable=too-few-public-methods + # static variable to cache layer hashes between container groups + layer_cache = {} + def __init__(self): script_directory = os.path.dirname(os.path.realpath(__file__)) DEFAULT_LIB = "./bin/dmverity-vhd" @@ -49,9 +52,12 @@ def __init__(self): def get_policy_image_layers( self, image: str, tag: str, tar_location: str = "" ) -> List[str]: - policy_bin_str = str(self.policy_bin) + image_name = f"{image}:{tag}" + # populate layer info + if self.layer_cache.get(image_name): + return self.layer_cache.get(image_name) - img = image + ":" + tag + policy_bin_str = str(self.policy_bin) arg_list = [ f"{policy_bin_str}", @@ -64,7 +70,7 @@ def get_policy_image_layers( arg_list += ["-d"] # add the image to the end of the parameter list - arg_list += ["roothash", "-i", f"{img}"] + arg_list += ["roothash", "-i", f"{image_name}"] outputlines = None err = None @@ -93,5 +99,6 @@ def get_policy_image_layers( if err.decode("utf8") != "": output = [] # eprint(err.decode("utf8")) - + # cache output layers + self.layer_cache[image_name] = output return output diff --git a/src/confcom/azext_confcom/security_policy.py b/src/confcom/azext_confcom/security_policy.py index 9ebfce05c2a..f928382ac71 100644 --- a/src/confcom/azext_confcom/security_policy.py +++ b/src/confcom/azext_confcom/security_policy.py @@ -397,7 +397,6 @@ def populate_policy_content_for_all_images( ) tar_location = "" - layer_cache = {} if isinstance(tar_mapping, str): tar_location = tar_mapping proxy = self._get_rootfs_proxy() @@ -475,13 +474,10 @@ def populate_policy_content_for_all_images( if isinstance(tar_mapping, dict): tar_location = get_tar_location_from_mapping(tar_mapping, image_name) # populate layer info - if layer_cache.get(image_name): - image.set_layers(layer_cache.get(image_name)) - else: - image.set_layers(proxy.get_policy_image_layers( - image.base, image.tag, tar_location=tar_location if tar else "" - )) - layer_cache[image_name] = image.get_layers() + image.set_layers(proxy.get_policy_image_layers( + image.base, image.tag, tar_location=tar_location if tar else "" + )) + progress.update() progress.close() self.close() diff --git a/src/confcom/azext_confcom/template_util.py b/src/confcom/azext_confcom/template_util.py index cb7f7c9f199..275c0d982d0 100644 --- a/src/confcom/azext_confcom/template_util.py +++ b/src/confcom/azext_confcom/template_util.py @@ -52,6 +52,10 @@ def case_insensitive_dict_get(dictionary, search_key) -> Any: return None +def image_has_hash(image: str) -> bool: + return "@sha256:" in image + + def get_image_info(progress, message_queue, tar_mapping, image): image_info = None raw_image = None @@ -59,13 +63,15 @@ def get_image_info(progress, message_queue, tar_mapping, image): if not image.base: eprint("Image name cannot be empty") image_name = f"{image.base}:{image.tag}" - if len(image.tag.split(":")) > 1: - eprint( - f"The image name: {image.tag} cannot have the digest present to use a tarball as the image source" - ) + # only try to grab the info locally if that's absolutely what # we want to do if tar_mapping: + if image_has_hash(image_name): + progress.close() + eprint( + f"The image name: {image_name} cannot have the digest present to use a tarball as the image source" + ) tar_location = get_tar_location_from_mapping(tar_mapping, image_name) # if we have a tar location, we can try to get the image info if tar_location: @@ -103,7 +109,7 @@ def get_image_info(progress, message_queue, tar_mapping, image): # pull image to local daemon (if not in local # daemon) if not raw_image: - raw_image = client.images.pull(image.base, image.tag) + raw_image = client.images.pull(image_name) image_info = raw_image.attrs.get("Config") except (docker.errors.ImageNotFound, docker.errors.NotFound): progress.close() diff --git a/src/confcom/setup.py b/src/confcom/setup.py index 5d6211b6250..364ebd90b65 100644 --- a/src/confcom/setup.py +++ b/src/confcom/setup.py @@ -21,7 +21,7 @@ # TODO: Confirm this is the right version number you want and it matches your # HISTORY.rst entry. -VERSION = "0.2.12" +VERSION = "0.2.13" # The full list of classifiers is available at # https://pypi.python.org/pypi?%3Aaction=list_classifiers