When speaking to version 0.2-beta of the build worker, properly lookup the cached commands and see if we have a matching image/tag in the repository

This commit is contained in:
Joseph Schorr 2014-12-11 18:03:40 +02:00
parent 81846f6a5f
commit 6601e83285
4 changed files with 123 additions and 37 deletions

View file

@ -31,10 +31,58 @@ class BuildJob(object):
'Could not parse repository build job config with ID %s' % self._job_details['build_uuid']
)
def determine_cached_tag(self):
def determine_cached_tag(self, base_image_id=None, cache_comments=None):
""" Returns the tag to pull to prime the cache or None if none. """
# TODO(jschorr): Change this to use the more complicated caching rules, once we have caching
# be a pull of things besides the constructed tags.
cached_tag = None
if base_image_id and cache_comments:
cached_tag = self._determine_cached_tag_by_comments(base_image_id, cache_comments)
if not cached_tag:
cached_tag = self._determine_cached_tag_by_tag()
return cached_tag
def _determine_cached_tag_by_comments(self, base_image_id, cache_commands):
""" Determines the tag to use for priming the cache for this build job, by matching commands
starting at the given base_image_id. This mimics the Docker cache checking, so it should,
in theory, provide "perfect" caching.
"""
# Lookup the base image in the repository. If it doesn't exist, nothing more to do.
repo_namespace = self._repo_build.repository.namespace_user.username
repo_name = self._repo_build.repository.name
repository = model.get_repository(repo_namespace, repo_name)
if repository is None:
# Should never happen, but just to be sure.
return None
current_image = model.get_image(repository, base_image_id)
if current_image is None:
return None
# For each cache comment, find a child image that matches the command.
for cache_command in cache_commands:
print current_image.docker_image_id
current_image = model.find_child_image(repository, current_image, cache_command)
if current_image is None:
return None
# Find a tag associated with the image, if any.
# TODO(jschorr): We should just return the image ID instead of a parent tag, OR we should
# make this more efficient.
for tag in model.list_repository_tags(repo_namespace, repo_name):
tag_image = tag.image
ancestor_index = '/%s/' % current_image.id
if ancestor_index in tag_image.ancestors:
return tag.name
return None
def _determine_cached_tag_by_tag(self):
""" Determines the cached tag by looking for one of the tags being built, and seeing if it
exists in the repository. This is a fallback for when no comment information is available.
"""
tags = self._build_config.get('docker_tags', ['latest'])
existing_tags = model.list_repository_tags(self._repo_build.repository.namespace_user.username,
self._repo_build.repository.name)

View file

@ -57,6 +57,11 @@ class WorkerError(object):
'io.quay.builder.missingorinvalidargument': {
'message': 'Missing required arguments for builder',
'is_internal': True
},
'io.quay.builder.cachelookupissue': {
'message': 'Error checking for a cached tag',
'is_internal': True
}
}