Add back in the cache checking code and remove the old 0.1 build pack code

This commit is contained in:
Joseph Schorr 2015-02-09 12:13:40 -05:00
parent 48949627e0
commit 0065ac8503
3 changed files with 14 additions and 133 deletions

View file

@ -10,7 +10,6 @@ from autobahn.wamp.exception import ApplicationError
from buildman.server import BuildJobResult from buildman.server import BuildJobResult
from buildman.component.basecomponent import BaseComponent from buildman.component.basecomponent import BaseComponent
from buildman.jobutil.buildjob import BuildJobLoadException from buildman.jobutil.buildjob import BuildJobLoadException
from buildman.jobutil.buildpack import BuildPackage, BuildPackageException
from buildman.jobutil.buildstatus import StatusHandler from buildman.jobutil.buildstatus import StatusHandler
from buildman.jobutil.workererror import WorkerError from buildman.jobutil.workererror import WorkerError
@ -20,7 +19,7 @@ HEARTBEAT_DELTA = datetime.timedelta(seconds=30)
HEARTBEAT_TIMEOUT = 10 HEARTBEAT_TIMEOUT = 10
INITIAL_TIMEOUT = 25 INITIAL_TIMEOUT = 25
SUPPORTED_WORKER_VERSIONS = ['0.1-beta', '0.2'] SUPPORTED_WORKER_VERSIONS = ['0.2']
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -56,7 +55,10 @@ class BuildComponent(BaseComponent):
def onJoin(self, details): def onJoin(self, details):
logger.debug('Registering methods and listeners for component %s', self.builder_realm) logger.debug('Registering methods and listeners for component %s', self.builder_realm)
yield trollius.From(self.register(self._on_ready, u'io.quay.buildworker.ready')) yield trollius.From(self.register(self._on_ready, u'io.quay.buildworker.ready'))
yield trollius.From(self.register(self._determine_cache_tag,
u'io.quay.buildworker.determinecachetag'))
yield trollius.From(self.register(self._ping, u'io.quay.buildworker.ping')) yield trollius.From(self.register(self._ping, u'io.quay.buildworker.ping'))
yield trollius.From(self.subscribe(self._on_heartbeat, 'io.quay.builder.heartbeat')) yield trollius.From(self.subscribe(self._on_heartbeat, 'io.quay.builder.heartbeat'))
yield trollius.From(self.subscribe(self._on_log_message, 'io.quay.builder.logmessage')) yield trollius.From(self.subscribe(self._on_log_message, 'io.quay.builder.logmessage'))
@ -91,46 +93,6 @@ class BuildComponent(BaseComponent):
buildpack_url = self.user_files.get_file_url(build_job.repo_build.resource_key, buildpack_url = self.user_files.get_file_url(build_job.repo_build.resource_key,
requires_cors=False) requires_cors=False)
# TODO(jschorr): Remove as soon as the fleet has been transitioned to 0.2.
if self._worker_version == '0.1-beta':
# Retrieve the job's buildpack.
logger.debug('Retrieving build package: %s', buildpack_url)
buildpack = None
try:
buildpack = BuildPackage.from_url(buildpack_url)
except BuildPackageException as bpe:
self._build_failure('Could not retrieve build package', bpe)
raise trollius.Return()
# Extract the base image information from the Dockerfile.
parsed_dockerfile = None
logger.debug('Parsing dockerfile')
try:
parsed_dockerfile = buildpack.parse_dockerfile(build_config.get('build_subdir'))
except BuildPackageException as bpe:
self._build_failure('Could not find Dockerfile in build package', bpe)
raise trollius.Return()
image_and_tag_tuple = parsed_dockerfile.get_image_and_tag()
if image_and_tag_tuple is None or image_and_tag_tuple[0] is None:
self._build_failure('Missing FROM line in Dockerfile')
raise trollius.Return()
base_image_information = {
'repository': image_and_tag_tuple[0],
'tag': image_and_tag_tuple[1]
}
# Extract the number of steps from the Dockerfile.
with self._build_status as status_dict:
status_dict['total_commands'] = len(parsed_dockerfile.commands)
else:
# TODO(jschorr): This is a HACK to make sure the progress bar (sort of) continues working
# until such time as we have the caching code in place.
with self._build_status as status_dict:
status_dict['total_commands'] = 25
# Add the pull robot information, if any. # Add the pull robot information, if any.
if build_job.pull_credentials: if build_job.pull_credentials:
base_image_information['username'] = build_job.pull_credentials.get('username', '') base_image_information['username'] = build_job.pull_credentials.get('username', '')
@ -161,8 +123,7 @@ class BuildComponent(BaseComponent):
'pull_token': build_job.repo_build.access_token.code, 'pull_token': build_job.repo_build.access_token.code,
'push_token': build_job.repo_build.access_token.code, 'push_token': build_job.repo_build.access_token.code,
'tag_names': build_config.get('docker_tags', ['latest']), 'tag_names': build_config.get('docker_tags', ['latest']),
'base_image': base_image_information, 'base_image': base_image_information
'cached_tag': build_job.determine_cached_tag() or ''
} }
# Invoke the build. # Invoke the build.
@ -256,6 +217,14 @@ class BuildComponent(BaseComponent):
elif phase == BUILD_PHASE.BUILDING: elif phase == BUILD_PHASE.BUILDING:
self._build_status.append_log(current_status_string) self._build_status.append_log(current_status_string)
def _determine_cache_tag(self, cache_commands, base_image_name, base_image_tag, base_image_id):
with self._build_status as status_dict:
status_dict['total_commands'] = len(cache_commands) + 1
logger.debug('Checking cache on realm %s. Base image: %s:%s (%s)', self.builder_realm,
base_image_name, base_image_tag, base_image_id)
return self._current_job.determine_cached_tag(base_image_id, cache_commands) or ''
def _build_failure(self, error_message, exception=None): def _build_failure(self, error_message, exception=None):
""" Handles and logs a failed build. """ """ Handles and logs a failed build. """

View file

@ -1,88 +0,0 @@
import tarfile
import requests
import os
from tempfile import TemporaryFile, mkdtemp
from zipfile import ZipFile
from util.dockerfileparse import parse_dockerfile
from util.safetar import safe_extractall
class BuildPackageException(Exception):
""" Exception raised when retrieving or parsing a build package. """
pass
class BuildPackage(object):
""" Helper class for easy reading and updating of a Dockerfile build pack. """
def __init__(self, requests_file):
self._mime_processors = {
'application/zip': BuildPackage._prepare_zip,
'application/x-zip-compressed': BuildPackage._prepare_zip,
'text/plain': BuildPackage._prepare_dockerfile,
'application/octet-stream': BuildPackage._prepare_dockerfile,
'application/x-tar': BuildPackage._prepare_tarball,
'application/gzip': BuildPackage._prepare_tarball,
'application/x-gzip': BuildPackage._prepare_tarball,
}
c_type = requests_file.headers['content-type']
c_type = c_type.split(';')[0] if ';' in c_type else c_type
if c_type not in self._mime_processors:
raise BuildPackageException('Unknown build package mime type: %s' % c_type)
self._package_directory = None
try:
self._package_directory = self._mime_processors[c_type](requests_file)
except Exception as ex:
raise BuildPackageException(ex.message)
def parse_dockerfile(self, subdirectory):
dockerfile_path = os.path.join(self._package_directory, subdirectory, 'Dockerfile')
if not os.path.exists(dockerfile_path):
if subdirectory:
message = 'Build package did not contain a Dockerfile at sub directory %s.' % subdirectory
else:
message = 'Build package did not contain a Dockerfile at the root directory.'
raise BuildPackageException(message)
with open(dockerfile_path, 'r') as dockerfileobj:
return parse_dockerfile(dockerfileobj.read())
@staticmethod
def from_url(url):
buildpack_resource = requests.get(url, stream=True)
return BuildPackage(buildpack_resource)
@staticmethod
def _prepare_zip(request_file):
build_dir = mkdtemp(prefix='docker-build-')
# Save the zip file to temp somewhere
with TemporaryFile() as zip_file:
zip_file.write(request_file.content)
to_extract = ZipFile(zip_file)
to_extract.extractall(build_dir)
return build_dir
@staticmethod
def _prepare_dockerfile(request_file):
build_dir = mkdtemp(prefix='docker-build-')
dockerfile_path = os.path.join(build_dir, "Dockerfile")
with open(dockerfile_path, 'w') as dockerfile:
dockerfile.write(request_file.content)
return build_dir
@staticmethod
def _prepare_tarball(request_file):
build_dir = mkdtemp(prefix='docker-build-')
# Save the zip file to temp somewhere
with tarfile.open(mode='r|*', fileobj=request_file.raw) as tar_stream:
safe_extractall(tar_stream, build_dir)
return build_dir

View file

@ -11,7 +11,7 @@ class StatusHandler(object):
self._build_logs = build_logs self._build_logs = build_logs
self._status = { self._status = {
'total_commands': None, 'total_commands': 0,
'current_command': None, 'current_command': None,
'push_completion': 0.0, 'push_completion': 0.0,
'pull_completion': 0.0, 'pull_completion': 0.0,