Fixes to the build server.

This commit is contained in:
yackob03 2013-12-31 16:22:58 -05:00
parent 39fa982ef2
commit 8981f576fc
3 changed files with 33 additions and 30 deletions

View file

@ -22,5 +22,5 @@ RUN venv/bin/pip install -r requirements.txt
VOLUME /var/lib/docker VOLUME /var/lib/docker
EXPOSE 5002:5002 EXPOSE 5002
CMD startserver CMD startserver

View file

@ -6,10 +6,9 @@ import re
import requests import requests
import json import json
from flask import Flask, jsonify, url_for, abort, make_response from flask import Flask, jsonify, abort, make_response
from zipfile import ZipFile from zipfile import ZipFile
from tempfile import TemporaryFile, mkdtemp from tempfile import TemporaryFile, mkdtemp
from uuid import uuid4
from multiprocessing.pool import ThreadPool from multiprocessing.pool import ThreadPool
from base64 import b64encode from base64 import b64encode
@ -53,16 +52,24 @@ def prepare_dockerfile(request_file):
return build_dir return build_dir
def total_completion(statuses, total_images):
percentage_with_sizes = float(len(statuses.values()))/total_images
sent_bytes = sum([status[u'current'] for status in statuses.values()])
total_bytes = sum([status[u'total'] for status in statuses.values()])
return float(sent_bytes)/total_bytes*percentage_with_sizes
def build_image(build_dir, tag_name, num_steps, result_object): def build_image(build_dir, tag_name, num_steps, result_object):
try: try:
logger.debug('Starting build.') logger.debug('Starting build.')
docker_cl = docker.Client(version='1.5') docker_cl = docker.Client(timeout=1200)
result_object['status'] = 'building' result_object['status'] = 'building'
build_status = docker_cl.build(path=build_dir, tag=tag_name) build_status = docker_cl.build(path=build_dir, tag=tag_name, stream=True)
current_step = 0 current_step = 0
built_image = None built_image = None
for status in build_status: for status in build_status:
# logger.debug('Status: %s', str(status))
step_increment = re.search(r'Step ([0-9]+) :', status) step_increment = re.search(r'Step ([0-9]+) :', status)
if step_increment: if step_increment:
current_step = int(step_increment.group(1)) current_step = int(step_increment.group(1))
@ -84,40 +91,36 @@ def build_image(build_dir, tag_name, num_steps, result_object):
result_object['message'] = 'Unable to build dockerfile.' result_object['message'] = 'Unable to build dockerfile.'
return return
history = docker_cl.history(built_image) history = json.loads(docker_cl.history(built_image))
num_images = len(history) num_images = len(history)
result_object['total_images'] = num_images result_object['total_images'] = num_images
result_object['status'] = 'pushing' result_object['status'] = 'pushing'
logger.debug('Pushing to tag name: %s' % tag_name) logger.debug('Pushing to tag name: %s' % tag_name)
resp = docker_cl.push(tag_name) resp = docker_cl.push(tag_name, stream=True)
current_image = 0 for status_str in resp:
image_progress = 0 status = json.loads(status_str)
for status in resp: logger.debug('Status: %s', status_str)
if u'status' in status: if u'status' in status:
status_msg = status[u'status'] status_msg = status[u'status']
next_image = r'(Pushing|Image) [a-z0-9]+( already pushed, skipping)?$'
match = re.match(next_image, status_msg)
if match:
current_image += 1
image_progress = 0
logger.debug('Now pushing image %s/%s' %
(current_image, num_images))
elif status_msg == u'Pushing' and u'progress' in status: if status_msg == 'Pushing':
percent = r'\(([0-9]+)%\)' if u'progressDetail' in status and u'id' in status:
match = re.search(percent, status[u'progress']) image_id = status[u'id']
if match: detail = status[u'progressDetail']
image_progress = int(match.group(1))
result_object['current_image'] = current_image if u'current' in detail and 'total' in detail:
result_object['image_completion_percent'] = image_progress images = result_object['image_completion']
images[image_id] = detail
result_object['push_completion'] = total_completion(images,
num_images)
elif u'errorDetail' in status: elif u'errorDetail' in status:
result_object['status'] = 'error' result_object['status'] = 'error'
if u'message' in status[u'errorDetail']: if u'message' in status[u'errorDetail']:
result_object['message'] = status[u'errorDetail'][u'message'] result_object['message'] = str(status[u'errorDetail'][u'message'])
return return
result_object['status'] = 'complete' result_object['status'] = 'complete'
@ -136,12 +139,11 @@ MIME_PROCESSORS = {
build = { build = {
'total_commands': None, 'total_commands': None,
'total_images': None,
'current_command': None, 'current_command': None,
'current_image': None, 'push_completion': 0.0,
'image_completion_percent': None,
'status': 'waiting', 'status': 'waiting',
'message': None, 'message': None,
'image_completion': {},
} }
pool = ThreadPool(1) pool = ThreadPool(1)

View file

@ -26,7 +26,8 @@ formatter = logging.Formatter(FORMAT)
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
BUILD_SERVER_CMD = ('docker run -d -lxc-conf="lxc.aa_profile=unconfined" ' + BUILD_SERVER_CMD = ('docker run -d -p 5002:5002 ' +
'-lxc-conf="lxc.aa_profile=unconfined" ' +
'-privileged -e \'RESOURCE_URL=%s\' -e \'TAG=%s\' ' + '-privileged -e \'RESOURCE_URL=%s\' -e \'TAG=%s\' ' +
'-e \'TOKEN=%s\' quay.io/quay/buildserver') '-e \'TOKEN=%s\' quay.io/quay/buildserver')
@ -189,7 +190,7 @@ def babysit_builder(request):
retry_command(droplet.destroy) retry_command(droplet.destroy)
repository_build.status_url = None repository_build.status_url = None
repository_build.build_node_id = None; repository_build.build_node_id = None
repository_build.save() repository_build.save()
return True return True