Never load the full repo image list

Always make smaller queries per tag to ensure we scale better

Fixes #754
This commit is contained in:
Joseph Schorr 2015-11-03 18:15:23 -05:00
parent 43720b27e7
commit 4f41f79fa8
15 changed files with 268 additions and 254 deletions

View file

@ -4,7 +4,7 @@ from flask import request, abort
from endpoints.api import (resource, nickname, require_repo_read, require_repo_write,
RepositoryParamResource, log_action, NotFound, validate_json_request,
path_param, parse_args, query_param)
path_param, parse_args, query_param, truthy_bool)
from endpoints.api.image import image_view
from data import model
from auth.auth_context import get_authenticated_user
@ -135,7 +135,10 @@ class RepositoryTagImages(RepositoryParamResource):
""" Resource for listing the images in a specific repository tag. """
@require_repo_read
@nickname('listTagImages')
def get(self, namespace, repository, tag):
@parse_args
@query_param('owned', 'If specified, only images wholely owned by this tag are returned.',
type=truthy_bool, default=False)
def get(self, args, namespace, repository, tag):
""" List the images for the specified repository tag. """
try:
tag_image = model.tag.get_tag_image(namespace, repository, tag)
@ -144,15 +147,37 @@ class RepositoryTagImages(RepositoryParamResource):
parent_images = model.image.get_parent_images(namespace, repository, tag_image)
image_map = {}
image_map[str(tag_image.id)] = tag_image
for image in parent_images:
image_map[str(image.id)] = image
image_map_all = dict(image_map)
parents = list(parent_images)
parents.reverse()
all_images = [tag_image] + parents
# Filter the images returned to those not found in the ancestry of any of the other tags in
# the repository.
if args['owned']:
all_tags = model.tag.list_repository_tags(namespace, repository)
for current_tag in all_tags:
if current_tag.name == tag:
continue
# Remove the tag's image ID.
tag_image_id = str(current_tag.image_id)
image_map.pop(tag_image_id, None)
# Remove any ancestors:
for ancestor_id in current_tag.image.ancestors.split('/'):
image_map.pop(ancestor_id, None)
return {
'images': [image_view(image, image_map) for image in all_images]
'images': [image_view(image, image_map_all) for image in all_images
if not args['owned'] or (str(image.id) in image_map)]
}