Fixes and refinements to the dockerfile build system.
This commit is contained in:
parent
9b9a29c310
commit
ffc33e454c
6 changed files with 58 additions and 10 deletions
|
@ -30,6 +30,7 @@ start the workers:
|
||||||
|
|
||||||
```
|
```
|
||||||
STACK=prod python -m workers.diffsworker -D
|
STACK=prod python -m workers.diffsworker -D
|
||||||
|
STACK=prod python -m workers.dockerfilebuild -D
|
||||||
```
|
```
|
||||||
|
|
||||||
bouncing the servers:
|
bouncing the servers:
|
||||||
|
|
|
@ -169,9 +169,9 @@ def start_build():
|
||||||
'id': job_id,
|
'id': job_id,
|
||||||
'total_commands': num_steps,
|
'total_commands': num_steps,
|
||||||
'total_images': None,
|
'total_images': None,
|
||||||
'current_command': 0,
|
'current_command': None,
|
||||||
'current_image': 0,
|
'current_image': None,
|
||||||
'image_completion_percent': 0,
|
'image_completion_percent': None,
|
||||||
'status': 'waiting',
|
'status': 'waiting',
|
||||||
'message': None,
|
'message': None,
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,7 +153,7 @@ class RepositoryTag(BaseModel):
|
||||||
class RepositoryBuild(BaseModel):
|
class RepositoryBuild(BaseModel):
|
||||||
repository = ForeignKeyField(Repository)
|
repository = ForeignKeyField(Repository)
|
||||||
resource_key = CharField()
|
resource_key = CharField()
|
||||||
digitalocean_build_node_id = IntegerField(null=True)
|
build_node_id = IntegerField(null=True)
|
||||||
phase = CharField(default='waiting')
|
phase = CharField(default='waiting')
|
||||||
status_url = CharField(null=True)
|
status_url = CharField(null=True)
|
||||||
|
|
||||||
|
|
|
@ -562,5 +562,12 @@ def get_repository_build(request_dbid):
|
||||||
raise InvalidRepositoryBuildException(msg)
|
raise InvalidRepositoryBuildException(msg)
|
||||||
|
|
||||||
|
|
||||||
|
def list_repository_builds(namespace_name, repository_name):
|
||||||
|
joined = RepositoryBuild.select().join(Repository)
|
||||||
|
fetched = list(joined.where(Repository.name == repository_name,
|
||||||
|
Repository.namespace == namespace_name))
|
||||||
|
return fetched
|
||||||
|
|
||||||
|
|
||||||
def create_repository_build(repo, resource_key):
|
def create_repository_build(repo, resource_key):
|
||||||
return RepositoryBuild.create(repository=repo, resource_key=resource_key)
|
return RepositoryBuild.create(repository=repo, resource_key=resource_key)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import logging
|
import logging
|
||||||
import stripe
|
import stripe
|
||||||
import re
|
import re
|
||||||
|
import requests
|
||||||
|
|
||||||
from flask import request, make_response, jsonify, abort, url_for
|
from flask import request, make_response, jsonify, abort, url_for
|
||||||
from flask.ext.login import login_required, current_user, logout_user
|
from flask.ext.login import login_required, current_user, logout_user
|
||||||
|
@ -180,11 +181,12 @@ user_files = UserRequestFiles(app.config['AWS_ACCESS_KEY'],
|
||||||
@app.route('/api/repository/', methods=['POST'])
|
@app.route('/api/repository/', methods=['POST'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
def create_repo_api():
|
def create_repo_api():
|
||||||
namespace_name = request.values['namespace']
|
owner = current_user.db_user()
|
||||||
|
|
||||||
|
namespace_name = owner.username
|
||||||
repository_name = request.values['repository']
|
repository_name = request.values['repository']
|
||||||
visibility = request.values['visibility']
|
visibility = request.values['visibility']
|
||||||
|
|
||||||
owner = current_user.db_user()
|
|
||||||
repo = model.create_repository(namespace_name, repository_name, owner,
|
repo = model.create_repository(namespace_name, repository_name, owner,
|
||||||
visibility)
|
visibility)
|
||||||
|
|
||||||
|
@ -349,6 +351,8 @@ def get_repo_api(namespace, repository):
|
||||||
tag_dict = {tag.name: tag_view(tag) for tag in tags}
|
tag_dict = {tag.name: tag_view(tag) for tag in tags}
|
||||||
can_write = ModifyRepositoryPermission(namespace, repository).can()
|
can_write = ModifyRepositoryPermission(namespace, repository).can()
|
||||||
can_admin = AdministerRepositoryPermission(namespace, repository).can()
|
can_admin = AdministerRepositoryPermission(namespace, repository).can()
|
||||||
|
builds = model.list_repository_builds(namespace, repository)
|
||||||
|
|
||||||
return jsonify({
|
return jsonify({
|
||||||
'namespace': namespace,
|
'namespace': namespace,
|
||||||
'name': repository,
|
'name': repository,
|
||||||
|
@ -356,13 +360,44 @@ def get_repo_api(namespace, repository):
|
||||||
'tags': tag_dict,
|
'tags': tag_dict,
|
||||||
'can_write': can_write,
|
'can_write': can_write,
|
||||||
'can_admin': can_admin,
|
'can_admin': can_admin,
|
||||||
'is_public': is_public
|
'is_public': is_public,
|
||||||
|
'is_building': len(builds) > 0,
|
||||||
})
|
})
|
||||||
|
|
||||||
abort(404) # Not fount
|
abort(404) # Not fount
|
||||||
abort(403) # Permission denied
|
abort(403) # Permission denied
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/api/repository/<path:repository>/build/', methods=['GET'])
|
||||||
|
@parse_repository_name
|
||||||
|
def get_repo_builds(namespace, repository):
|
||||||
|
permission = AdministerRepositoryPermission(namespace, repository)
|
||||||
|
if permission.can():
|
||||||
|
def build_view(build_obj):
|
||||||
|
if build_obj.status_url:
|
||||||
|
# Delegate the status to the build node
|
||||||
|
node_status = requests.get(build_obj.status_url).json()
|
||||||
|
node_status['id'] = build_obj.id
|
||||||
|
return node_status
|
||||||
|
|
||||||
|
# If there was no status url, do the best we can
|
||||||
|
return {
|
||||||
|
'id': build_obj.id,
|
||||||
|
'total_commands': None,
|
||||||
|
'total_images': None,
|
||||||
|
'current_command': None,
|
||||||
|
'current_image': None,
|
||||||
|
'image_completion_percent': None,
|
||||||
|
'status': build_obj.phase,
|
||||||
|
'message': None,
|
||||||
|
}
|
||||||
|
|
||||||
|
builds = model.list_repository_builds(namespace, repository)
|
||||||
|
return jsonify({
|
||||||
|
'builds': [build_view(build) for build in builds]
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
def role_view(repo_perm_obj):
|
def role_view(repo_perm_obj):
|
||||||
return {
|
return {
|
||||||
'role': repo_perm_obj.role.name
|
'role': repo_perm_obj.role.name
|
||||||
|
|
|
@ -45,7 +45,7 @@ def babysit_builder(request):
|
||||||
repository_build = model.get_repository_build(request['build_id'])
|
repository_build = model.get_repository_build(request['build_id'])
|
||||||
|
|
||||||
# check if there is already a DO node for this build job, if so clean it up
|
# check if there is already a DO node for this build job, if so clean it up
|
||||||
old_id = repository_build.digitalocean_build_node_id
|
old_id = repository_build.build_node_id
|
||||||
if old_id
|
if old_id
|
||||||
old_droplet = digitalocean.Droplet(old_id)
|
old_droplet = digitalocean.Droplet(old_id)
|
||||||
old_droplet.destroy()
|
old_droplet.destroy()
|
||||||
|
@ -60,7 +60,7 @@ def babysit_builder(request):
|
||||||
size_id=66, # 512MB,
|
size_id=66, # 512MB,
|
||||||
backup_active=False)
|
backup_active=False)
|
||||||
droplet.create(ssh_key_ids=[app.config['DO_SSH_KEY_ID']])
|
droplet.create(ssh_key_ids=[app.config['DO_SSH_KEY_ID']])
|
||||||
repository_build.digitalocean_build_node_id = droplet.id
|
repository_build.build_node_id = droplet.id
|
||||||
repository_build.phase = 'starting'
|
repository_build.phase = 'starting'
|
||||||
repository_build.save()
|
repository_build.save()
|
||||||
|
|
||||||
|
@ -115,6 +115,8 @@ def babysit_builder(request):
|
||||||
|
|
||||||
# wait for the job to be complete
|
# wait for the job to be complete
|
||||||
status_url = start_build.headers['Location']
|
status_url = start_build.headers['Location']
|
||||||
|
repository_build.status_url = status_url
|
||||||
|
repository_build.save()
|
||||||
|
|
||||||
logger.debug('Waiting for job to be complete')
|
logger.debug('Waiting for job to be complete')
|
||||||
status = get_status(status_url)
|
status = get_status(status_url)
|
||||||
|
@ -128,12 +130,15 @@ def babysit_builder(request):
|
||||||
repository_build.phase = 'error'
|
repository_build.phase = 'error'
|
||||||
else:
|
else:
|
||||||
repository_build.phase = 'completed'
|
repository_build.phase = 'completed'
|
||||||
repository_build.save()
|
|
||||||
|
|
||||||
# clean up the DO node
|
# clean up the DO node
|
||||||
logger.debug('Cleaning up DO node.')
|
logger.debug('Cleaning up DO node.')
|
||||||
droplet.destroy()
|
droplet.destroy()
|
||||||
|
|
||||||
|
repository_build.status_url = None
|
||||||
|
repository_build.build_node_id = None;
|
||||||
|
repository_build.save()
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
|
Reference in a new issue