Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 39 additions & 1 deletion src/confcom/azext_confcom/os_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def load_tar_mapping_from_file(path: str) -> dict:
return raw_json


def map_image_from_tar(image_name: str, tar: TarFile, tar_location: str):
def map_image_from_tar_backwards_compatibility(image_name: str, tar: TarFile, tar_location: str):
tar_dir = os.path.dirname(tar_location)
# grab all files in the folder and only take the one that's named with hex values and a json extension
members = tar.getmembers()
Expand Down Expand Up @@ -139,3 +139,41 @@ def map_image_from_tar(image_name: str, tar: TarFile, tar_location: str):
image_info["Architecture"] = image_info_raw.get("architecture")

return image_info


def map_image_from_tar(image_name: str, tar: TarFile, tar_location: str):
tar_dir = os.path.dirname(tar_location)
info_file = None
info_file_name = "manifest.json"
# if there's more than one image in the tarball, we need to do some more logic
if len(info_file_name) > 0:
# extract just the manifest file and see if any of the RepoTags match the image_name we're searching for
# the manifest.json should have a list of all the image tags
# and what json files they map to to get env vars, startup cmd, etc.
tar.extract(info_file_name, path=tar_dir)
manifest_path = os.path.join(tar_dir, info_file_name)
manifest = load_json_from_file(manifest_path)
# if we match a RepoTag to the image, stop searching
for image in manifest:
if image_name in image.get("RepoTags"):
info_file = image.get("Config")
break
# remove the extracted manifest file to clean up
os.remove(manifest_path)
else:
eprint(f"Tarball at {tar_location} contains no images")

if not info_file:
return None
tar.extract(info_file, path=tar_dir)

# get the path of the json file and read it in
image_info_file_path = os.path.join(tar_dir, info_file)
image_info_raw = load_json_from_file(image_info_file_path)
# delete the extracted json file to clean up
os.remove(image_info_file_path)
image_info = image_info_raw.get("config")
# importing the constant from config.py gives a circular dependency error
image_info["Architecture"] = image_info_raw.get("architecture")

return image_info
2 changes: 1 addition & 1 deletion src/confcom/azext_confcom/security_policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ def populate_policy_content_for_all_images(
image.set_command(command)

# merge envs for user container image
envs = image_info.get("Env")
envs = image_info.get("Env") or []
env_names = [
env_var[
config.POLICY_FIELD_CONTAINERS_ELEMENTS_ENVS_RULE
Expand Down
11 changes: 8 additions & 3 deletions src/confcom/azext_confcom/template_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,14 @@ def get_image_info(progress, message_queue, tar_mapping, image):
if tar_location:
with tarfile.open(tar_location) as tar:
# get all the info out of the tarfile
image_info = os_util.map_image_from_tar(
image_name, tar, tar_location
)
try:
image_info = os_util.map_image_from_tar_backwards_compatibility(
image_name, tar, tar_location
)
except IndexError:
image_info = os_util.map_image_from_tar(
image_name, tar, tar_location
)
if image_info is not None:
tar = True
message_queue.append(f"{image_name} read from local tar file")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,7 @@ def test_docker_pull(self):

self.assertEqual(
image.id,
"sha256:e525c930fe751104ff24c356a7bcfad66ce4b92797780eb38dc2ff95d7a66fdc",
"sha256:d49a5025be10344cce77d178103a225cb5d7316861e5d8f106e7ff278ae51b62",
)

def test_infrastructure_svn(self):
Expand Down