def describe_repositories(self, registry_id=None, repository_names=None): """ maxResults and nextToken not implemented """ if repository_names: for repository_name in repository_names: if repository_name not in self.repositories: raise RepositoryNotFoundException( repository_name, registry_id or DEFAULT_REGISTRY_ID) repositories = [] for repository in self.repositories.values(): # If a registry_id was supplied, ensure this repository matches if registry_id: if repository.registry_id != registry_id: continue # If a list of repository names was supplied, esure this repository # is in that list if repository_names: if repository.name not in repository_names: continue repositories.append(repository.response_object) return repositories
def list_images(self, repository_name, registry_id=None): """ maxResults and filtering not implemented """ repository = None found = False if repository_name in self.repositories: repository = self.repositories[repository_name] if registry_id: if repository.registry_id == registry_id: found = True else: found = True if not found: raise RepositoryNotFoundException( repository_name, registry_id or DEFAULT_REGISTRY_ID ) images = [] for image in repository.images: images.append(image) return images
def batch_delete_image(self, repository_name, registry_id=None, image_ids=None): if repository_name in self.repositories: repository = self.repositories[repository_name] else: raise RepositoryNotFoundException( repository_name, registry_id or DEFAULT_REGISTRY_ID ) if not image_ids: raise ParamValidationError( msg='Missing required parameter in input: "imageIds"' ) response = { "imageIds": [], "failures": [] } for image_id in image_ids: image_found = False # Is request missing both digest and tag? if "imageDigest" not in image_id and "imageTag" not in image_id: response["failures"].append( { "imageId": {}, "failureCode": "MissingDigestAndTag", "failureReason": "Invalid request parameters: both tag and digest cannot be null", } ) continue # If we have a digest, is it valid? if "imageDigest" in image_id: pattern = re.compile("^[0-9a-zA-Z_+\.-]+:[0-9a-fA-F]{64}") if not pattern.match(image_id.get("imageDigest")): response["failures"].append( { "imageId": { "imageDigest": image_id.get("imageDigest", "null") }, "failureCode": "InvalidImageDigest", "failureReason": "Invalid request parameters: image digest should satisfy the regex '[a-zA-Z0-9-_+.]+:[a-fA-F0-9]+'", } ) continue for num, image in enumerate(repository.images): # Search by matching both digest and tag if "imageDigest" in image_id and "imageTag" in image_id: if ( image_id["imageDigest"] == image.get_image_digest() and image_id["imageTag"] in image.image_tags ): image_found = True for image_tag in reversed(image.image_tags): repository.images[num].image_tag = image_tag response["imageIds"].append( image.response_batch_delete_image ) repository.images[num].remove_tag(image_tag) del repository.images[num] # Search by matching digest elif "imageDigest" in image_id and image.get_image_digest() == image_id["imageDigest"]: image_found = True for image_tag in reversed(image.image_tags): repository.images[num].image_tag = image_tag response["imageIds"].append(image.response_batch_delete_image) repository.images[num].remove_tag(image_tag) del repository.images[num] # Search by matching tag elif "imageTag" in image_id and image_id["imageTag"] in image.image_tags: image_found = True repository.images[num].image_tag = image_id["imageTag"] response["imageIds"].append(image.response_batch_delete_image) if len(image.image_tags) > 1: repository.images[num].remove_tag(image_id["imageTag"]) else: repository.images.remove(image) if not image_found: failure_response = { "imageId": {}, "failureCode": "ImageNotFound", "failureReason": "Requested image not found", } if "imageDigest" in image_id: failure_response["imageId"]["imageDigest"] = image_id.get("imageDigest", "null") if "imageTag" in image_id: failure_response["imageId"]["imageTag"] = image_id.get("imageTag", "null") response["failures"].append(failure_response) return response
def delete_repository(self, repository_name, registry_id=None): if repository_name in self.repositories: return self.repositories.pop(repository_name) else: raise RepositoryNotFoundException(repository_name, registry_id or DEFAULT_REGISTRY_ID)