Skip to content

Commit

Permalink
Handle docker API schema v2
Browse files Browse the repository at this point in the history
  • Loading branch information
Dramelac committed Nov 9, 2024
1 parent 28e2ce5 commit 85fb7a4
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 11 deletions.
2 changes: 1 addition & 1 deletion exegol/config/ConstantConfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
class ConstantConfig:
"""Constant parameters information"""
# Exegol Version
version: str = "4.3.7"
version: str = "4.3.8b1"

# Exegol documentation link
documentation: str = "https://exegol.rtfd.io/"
Expand Down
3 changes: 2 additions & 1 deletion exegol/model/ExegolImage.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ def __init__(self,
if meta_img and meta_img.meta_id is not None:
self.__setDigest(meta_img.meta_id)
self.__setLatestRemoteId(meta_img.meta_id) # Meta id is always the latest one
logger.debug(f"└── {self.__name}\t→ ({self.getType()}) {self.__digest}")
# Debug every Exegol image init
# logger.debug(f"└── {self.__name}\t→ ({self.getType()}) {self.__digest}")

def __initFromDockerImage(self):
"""Parse Docker object to set up self configuration on creation."""
Expand Down
9 changes: 4 additions & 5 deletions exegol/utils/DockerUtils.py
Original file line number Diff line number Diff line change
Expand Up @@ -412,18 +412,17 @@ def __listRemoteImages(self) -> List[MetaImages]:
remote_results = []
# Define max number of tags to download from dockerhub (in order to limit download time and discard historical versions)
page_size = 20
page_max = 2
current_page = 0
url: Optional[str] = f"https://{ConstantConfig.DOCKER_HUB}/v2/repositories/{ConstantConfig.IMAGE_NAME}/tags?page_size={page_size}"
page_max = 3
current_page = 1
url: Optional[str] = f"https://{ConstantConfig.DOCKER_HUB}/v2/repositories/{ConstantConfig.IMAGE_NAME}/tags?page=1&page_size={page_size}"
# Handle multi-page tags from registry
with console.status(f"Loading registry information from [green]{url}[/green]", spinner_style="blue") as s:
while url is not None:
if current_page == page_max:
if current_page > page_max:
logger.debug("Max page limit reached. In non-verbose mode, downloads will stop there.")
if not logger.isEnabledFor(ExeLog.VERBOSE):
break
current_page += 1
logger.debug(f"Fetching information from: {url}")
s.update(status=f"Fetching registry information from [green]{url}[/green]")
docker_repo_response = WebUtils.runJsonRequest(url, "Dockerhub")
if docker_repo_response is None:
Expand Down
46 changes: 42 additions & 4 deletions exegol/utils/WebUtils.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,47 @@ def getRemoteVersion(cls, tag: str) -> Optional[str]:
version: Optional[str] = None
if response is not None and response.status_code == 200:
data = json.loads(response.content.decode("utf-8"))
# Parse metadata of the current image from v1 schema
metadata = json.loads(data.get("history", [])[0]['v1Compatibility'])
# Find version label and extract data
version = metadata.get("config", {}).get("Labels", {}).get("org.exegol.version", "")
received_media_type = data.get("mediaType")
if received_media_type == "application/vnd.docker.distribution.manifest.v1+json":
# Get image version from legacy v1 manifest (faster)
# Parse metadata of the current image from v1 schema
metadata = json.loads(data.get("history", [])[0]['v1Compatibility'])
# Find version label and extract data
version = metadata.get("config", {}).get("Labels", {}).get("org.exegol.version", "")

# Convert image list to a specific image
elif received_media_type == "application/vnd.docker.distribution.manifest.list.v2+json":
# Get image version from v2 manifest list (slower)
# Retrieve image digest id from manifest image list
manifest = data.get("manifests")
# Get first image manifest
# Handle application/vnd.docker.distribution.manifest.list.v2+json spec
if type(manifest) is list and len(manifest) > 0:
# Get Image digest
first_digest = manifest[0].get("digest")
# Retrieve specific image detail from first image digest (architecture not sensitive)
manifest_headers["Accept"] = "application/vnd.docker.distribution.manifest.v2+json"
url = f"https://{ConstantConfig.DOCKER_REGISTRY}/v2/{ConstantConfig.IMAGE_NAME}/manifests/{first_digest}"
response = cls.__runRequest(url, service_name="Docker Registry", headers=manifest_headers, method="GET")
if response is not None and response.status_code == 200:
data = json.loads(response.content.decode("utf-8"))
# Update received media type to ba handle later
received_media_type = data.get("mediaType")
# Try to extract version tag from a specific image
if received_media_type == "application/vnd.docker.distribution.manifest.v2+json":
# Get image version from v2 manifest (slower)
# Retrieve config detail from config digest
config_digest: Optional[str] = data.get("config", {}).get('digest')
if config_digest is not None:
manifest_headers["Accept"] = "application/json"
url = f"https://{ConstantConfig.DOCKER_REGISTRY}/v2/{ConstantConfig.IMAGE_NAME}/blobs/{config_digest}"
response = cls.__runRequest(url, service_name="Docker Registry", headers=manifest_headers, method="GET")
if response is not None and response.status_code == 200:
data = json.loads(response.content.decode("utf-8"))
# Find version label and extract data
version = data.get("config", {}).get("Labels", {}).get("org.exegol.version")
else:
logger.debug(f"WARNING: Docker API not supported: {received_media_type}")
return version

@classmethod
Expand Down Expand Up @@ -135,6 +172,7 @@ def __runRequest(cls, url: str, service_name: str, headers: Optional[Dict] = Non
no_proxy = os.environ.get('NO_PROXY') or os.environ.get('no_proxy')
if no_proxy:
proxies['no_proxy'] = no_proxy
logger.debug(f"Fetching information from {url}")
response = requests.request(method=method, url=url, timeout=(10, 20), verify=ParametersManager().verify, headers=headers, data=data, proxies=proxies if len(proxies) > 0 else None)
return response
except requests.exceptions.HTTPError as e:
Expand Down

0 comments on commit 85fb7a4

Please sign in to comment.