-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'refs/remotes/origin/develop' into SS-12…
- Loading branch information
Showing
44 changed files
with
667 additions
and
337 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
from typing import List | ||
|
||
import requests | ||
from django.conf import settings | ||
|
||
|
||
def fetch_docker_hub_images_and_tags(query: str) -> List[str]: | ||
""" | ||
Fetch Docker images and latest tags matching a query. | ||
This function fetches images with the highest pull count. | ||
""" | ||
image_search_url = f"{settings.DOCKER_HUB_IMAGE_SEARCH}?query={query}" | ||
try: | ||
response = requests.get(image_search_url, timeout=3) | ||
response.raise_for_status() | ||
results = response.json().get("results", []) | ||
except requests.RequestException: | ||
return [] | ||
|
||
# Sort images by pull count | ||
sorted_results = sorted(results, key=lambda x: x.get("pull_count", 0), reverse=True) | ||
|
||
images = [] | ||
# Use the top 5 images | ||
for repo in sorted_results[:5]: | ||
repo_name = repo["repo_name"] | ||
|
||
# Fetch available tags | ||
tags_search_url = f"{settings.DOCKER_HUB_TAG_SEARCH}{repo_name}/tags/?page_size=3" | ||
try: | ||
tag_response = requests.get(tags_search_url, timeout=2) | ||
tag_response.raise_for_status() | ||
tags = [tag["name"] for tag in tag_response.json().get("results", [])] | ||
except requests.RequestException: | ||
# Default to latest if tags cannot be fetched | ||
tags = ["latest"] | ||
|
||
for tag in tags: | ||
images.append(f"docker.io/{repo_name}:{tag}") | ||
|
||
return images |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import requests | ||
from crispy_forms.layout import HTML, Div, Field, MultiField | ||
from django import forms | ||
from django.conf import settings | ||
|
||
|
||
class ContainerImageMixin: | ||
"""Mixin to add a reusable container image field and validation method.""" | ||
|
||
image = forms.CharField( | ||
max_length=255, | ||
required=True, | ||
widget=forms.TextInput( | ||
attrs={ | ||
"class": "form-control", | ||
"placeholder": "e.g. docker.io/username/image-name:image-tag", | ||
"list": "docker-image-list", | ||
} | ||
), | ||
) | ||
|
||
def __init__(self, *args, **kwargs): | ||
super().__init__(*args, **kwargs) | ||
self._setup_container_image_field() | ||
|
||
def _setup_container_image_field(self): | ||
"""Setup the container image field in the form.""" | ||
self.fields["image"] = self.image | ||
|
||
def _setup_container_image_helper(self): | ||
"""Returns the crispy layout for the container image field.""" | ||
return Div( | ||
Field( | ||
"image", | ||
css_class="form-control", | ||
placeholder="e.g. docker.io/username/image-name:image-tag", | ||
list="docker-image-list", | ||
), | ||
HTML('<datalist id="docker-image-list"></datalist>'), | ||
css_class="mb-3", | ||
) | ||
|
||
def clean_image(self): | ||
"""Validate the container image input.""" | ||
image = self.cleaned_data.get("image", "").strip() | ||
if not image: | ||
self.add_error("image", "Container image field cannot be empty.") | ||
return image | ||
|
||
# Ignore non-Docker images for now | ||
if "docker.io" not in image: | ||
return image | ||
|
||
# Split image into repository and tag | ||
if ":" in image: | ||
repository, tag = image.rsplit(":", 1) | ||
else: | ||
repository, tag = image, "latest" | ||
|
||
repository = repository.replace("docker.io/", "", 1) | ||
|
||
# Ensure repository is in the correct format | ||
# The request to Docker hub will fail otherwise | ||
if "/" not in repository: | ||
repository = f"library/{repository}" | ||
|
||
# Docker Hub API endpoint for checking the image | ||
docker_api_url = f"{settings.DOCKER_HUB_TAG_SEARCH}{repository}/tags/{tag}" | ||
|
||
try: | ||
response = requests.get(docker_api_url, timeout=5) | ||
if response.status_code != 200: | ||
self.add_error( | ||
"image", | ||
f"Docker image '{image}' is not publicly available on Docker Hub. " | ||
"The URL you have entered may be incorrect, or the image might be private.", | ||
) | ||
return image | ||
except requests.RequestException: | ||
self.add_error("image", "Could not validate the Docker image. Please try again.") | ||
return image | ||
|
||
return image |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.