diff --git a/data/model/legacy.py b/data/model/legacy.py index 1561ce90a..a6b79c594 100644 --- a/data/model/legacy.py +++ b/data/model/legacy.py @@ -845,27 +845,14 @@ def get_repository(namespace_name, repository_name): def get_repo_image(namespace_name, repository_name, image_id): - location_list = list((ImageStoragePlacement - .select(ImageStoragePlacement, Image, ImageStorage, ImageStorageLocation) - .join(ImageStorageLocation) - .switch(ImageStoragePlacement) - .join(ImageStorage) - .join(Image) - .join(Repository) - .where(Repository.name == repository_name, - Repository.namespace == namespace_name, - Image.docker_image_id == image_id))) - - if not location_list: + def limit_to_image_id(query): + return query.where(Image.docker_image_id == image_id) + + images = _get_repository_images_base(namespace_name, repository_name, limit_to_image_id) + if not images: return None - - location_names = {location.location.name for location in location_list} - - image = location_list[0].storage.image - image.storage = location_list[0].storage - image.storage.locations = location_names - - return image + else: + return images[0] def repository_is_public(namespace_name, repository_name): @@ -1082,8 +1069,8 @@ def set_image_metadata(docker_image_id, namespace_name, repository_name, return fetched -def get_repository_images(namespace_name, repository_name): - location_list = list((ImageStoragePlacement +def _get_repository_images_base(namespace_name, repository_name, query_modifier): + query = (ImageStoragePlacement .select(ImageStoragePlacement, Image, ImageStorage, ImageStorageLocation) .join(ImageStorageLocation) .switch(ImageStoragePlacement) @@ -1091,26 +1078,33 @@ def get_repository_images(namespace_name, repository_name): .join(Image) .join(Repository) .where(Repository.name == repository_name, - Repository.namespace == namespace_name))) + Repository.namespace == namespace_name)) + + query = query_modifier(query) + + location_list = list(query) images = {} for location in location_list: # Make sure we're always retrieving the same image object. image = location.storage.image - image_id = image.docker_image_id - if not image_id in images: - images[image_id] = image + if not image.id in images: + images[image.id] = image image.storage.locations = set() else: - image = images[image_id] + image = images[image.id] # Add the location to the image's locations set. - image.storage.locations.add(location) + image.storage.locations.add(location.location.name) return images.values() +def get_repository_images(namespace_name, repository_name): + return _get_repository_images_base(namespace_name, repository_name, lambda q: q) + + def list_repository_tags(namespace_name, repository_name): select = RepositoryTag.select(RepositoryTag, Image) with_repo = select.join(Repository) @@ -1178,20 +1172,17 @@ def garbage_collect_repository(namespace_name, repository_name): def get_tag_image(namespace_name, repository_name, tag_name): - query = (Image - .select(Image, ImageStorage) - .join(RepositoryTag) - .join(Repository) - .switch(Image) - .join(ImageStorage, JOIN_LEFT_OUTER) - .where(Repository.name == repository_name, - Repository.namespace == namespace_name, - RepositoryTag.name == tag_name)) + def limit_to_tag(query): + return (query + .switch(Image) + .join(RepositoryTag) + .where(RepositoryTag.name == tag_name)) - try: - return query.get() - except Image.DoesNotExist: + images = _get_repository_images_base(namespace_name, repository_name, limit_to_tag) + if not images: raise DataModelException('Unable to find image for tag.') + else: + return images[0] def get_image_by_id(namespace_name, repository_name, docker_image_id): @@ -1212,7 +1203,7 @@ def get_image_by_id(namespace_name, repository_name, docker_image_id): repository_name)) -def get_parent_images(image_obj): +def get_parent_images(namespace_name, repository_name, image_obj): """ Returns a list of parent Image objects in chronilogical order. """ parents = image_obj.ancestors parent_db_ids = parents.strip('/').split('/') @@ -1220,12 +1211,12 @@ def get_parent_images(image_obj): if parent_db_ids == ['']: return [] - parent_images = (Image - .select(Image, ImageStorage) - .join(ImageStorage, JOIN_LEFT_OUTER) - .where(Image.id << parent_db_ids)) + def filter_to_parents(query): + return query.where(Image.id << parent_db_ids) - id_to_image = {unicode(image.id): image for image in parent_images} + parents = _get_repository_images_base(namespace_name, repository_name, filter_to_parents) + + id_to_image = {unicode(image.id): image for image in parents} return [id_to_image[parent_id] for parent_id in parent_db_ids] diff --git a/endpoints/api/image.py b/endpoints/api/image.py index 6eab4837d..cdf06c6e2 100644 --- a/endpoints/api/image.py +++ b/endpoints/api/image.py @@ -23,7 +23,7 @@ def image_view(image): 'ancestors': image.ancestors, 'dbid': image.id, 'size': extended_props.image_size, - 'locations': [l.location.name for l in image.storage.locations] + 'locations': list(image.storage.locations), } diff --git a/endpoints/api/tag.py b/endpoints/api/tag.py index 10d466e81..f9210881c 100644 --- a/endpoints/api/tag.py +++ b/endpoints/api/tag.py @@ -84,7 +84,7 @@ class RepositoryTagImages(RepositoryParamResource): except model.DataModelException: raise NotFound() - parent_images = model.get_parent_images(tag_image) + parent_images = model.get_parent_images(namespace, repository, tag_image) parents = list(parent_images) parents.reverse() diff --git a/endpoints/registry.py b/endpoints/registry.py index 2d4eeca18..c95072e56 100644 --- a/endpoints/registry.py +++ b/endpoints/registry.py @@ -449,7 +449,7 @@ def process_image_changes(namespace, repository, image_id): return image_trie_path image = model.get_image_by_id(namespace, repository, image_id) - parents = model.get_parent_images(image) + parents = model.get_parent_images(namespace, repository, image) # Compute the diffs and fs for the parent first if necessary parent_trie_path = None