Merge branch 'master' into gitlab

This commit is contained in:
Joseph Schorr 2015-05-03 12:13:09 -04:00
commit e3aededcbc
70 changed files with 1000 additions and 265 deletions

View file

@ -14,7 +14,9 @@ from endpoints.building import start_build, PreparedBuild
from endpoints.trigger import BuildTriggerHandler
from data import model, database
from auth.auth_context import get_authenticated_user
from auth.permissions import ModifyRepositoryPermission, AdministerOrganizationPermission
from auth.permissions import (ReadRepositoryPermission, ModifyRepositoryPermission,
AdministerRepositoryPermission, AdministerOrganizationPermission)
from data.buildlogs import BuildStatusRetrievalError
from util.names import parse_robot_username
@ -33,7 +35,7 @@ def get_job_config(build_obj):
try:
return json.loads(build_obj.job_config)
except:
return None
return {}
def user_view(user):
@ -43,11 +45,12 @@ def user_view(user):
'is_robot': user.robot,
}
def trigger_view(trigger, can_admin=False):
def trigger_view(trigger, can_read=False, can_admin=False):
if trigger and trigger.uuid:
build_trigger = BuildTriggerHandler.get_handler(trigger)
return {
'service': trigger.service.name,
'build_source': build_trigger.config.get('build_source') if can_read else None,
'config': build_trigger.config if can_admin else {},
'id': trigger.uuid,
'connected_user': trigger.connected_user.username,
@ -58,7 +61,7 @@ def trigger_view(trigger, can_admin=False):
return None
def build_status_view(build_obj, can_write=False, can_admin=False):
def build_status_view(build_obj):
phase = build_obj.phase
try:
status = build_logs.get_status(build_obj.uuid)
@ -74,28 +77,39 @@ def build_status_view(build_obj, can_write=False, can_admin=False):
if datetime.datetime.utcnow() - heartbeat > datetime.timedelta(minutes=1):
phase = database.BUILD_PHASE.INTERNAL_ERROR
# If the phase is internal error, return 'error' instead of the number if retries
# If the phase is internal error, return 'error' instead if the number of retries
# on the queue item is 0.
if phase == database.BUILD_PHASE.INTERNAL_ERROR:
retry = build_obj.queue_id and dockerfile_build_queue.has_retries_remaining(build_obj.queue_id)
if not retry:
phase = database.BUILD_PHASE.ERROR
logger.debug('Can write: %s job_config: %s', can_write, build_obj.job_config)
repo_namespace = build_obj.repository.namespace_user.username
repo_name = build_obj.repository.name
can_read = ReadRepositoryPermission(repo_namespace, repo_name).can()
can_write = ModifyRepositoryPermission(repo_namespace, repo_name).can()
can_admin = AdministerRepositoryPermission(repo_namespace, repo_name).can()
job_config = get_job_config(build_obj)
resp = {
'id': build_obj.uuid,
'phase': phase,
'started': format_date(build_obj.started),
'display_name': build_obj.display_name,
'status': status or {},
'job_config': get_job_config(build_obj) if can_write else None,
'subdirectory': job_config.get('build_subdir', ''),
'tags': job_config.get('docker_tags', []),
'manual_user': job_config.get('manual_user', None),
'is_writer': can_write,
'trigger': trigger_view(build_obj.trigger, can_admin),
'trigger': trigger_view(build_obj.trigger, can_read, can_admin),
'trigger_metadata': job_config.get('trigger_metadata', None) if can_read else None,
'resource_key': build_obj.resource_key,
'pull_robot': user_view(build_obj.pull_robot) if build_obj.pull_robot else None,
'repository': {
'namespace': build_obj.repository.namespace_user.username,
'name': build_obj.repository.name
'namespace': repo_namespace,
'name': repo_name
}
}
@ -157,9 +171,8 @@ class RepositoryBuildList(RepositoryParamResource):
since = datetime.datetime.utcfromtimestamp(since)
builds = model.list_repository_builds(namespace, repository, limit, since=since)
can_write = ModifyRepositoryPermission(namespace, repository).can()
return {
'builds': [build_status_view(build, can_write) for build in builds]
'builds': [build_status_view(build) for build in builds]
}
@require_repo_write
@ -211,7 +224,7 @@ class RepositoryBuildList(RepositoryParamResource):
prepared.metadata = {}
build_request = start_build(repo, prepared, pull_robot_name=pull_robot_name)
resp = build_status_view(build_request, can_write=True)
resp = build_status_view(build_request)
repo_string = '%s/%s' % (namespace, repository)
headers = {
'Location': api.url_for(RepositoryBuildStatus, repository=repo_string,
@ -236,8 +249,7 @@ class RepositoryBuildResource(RepositoryParamResource):
except model.InvalidRepositoryBuildException:
raise NotFound()
can_write = ModifyRepositoryPermission(namespace, repository).can()
return build_status_view(build, can_write)
return build_status_view(build)
@require_repo_admin
@nickname('cancelRepoBuild')
@ -271,8 +283,7 @@ class RepositoryBuildStatus(RepositoryParamResource):
build.repository.namespace_user.username != namespace):
raise NotFound()
can_write = ModifyRepositoryPermission(namespace, repository).can()
return build_status_view(build, can_write)
return build_status_view(build)
@resource('/v1/repository/<repopath:repository>/build/<build_uuid>/logs')

View file

@ -432,7 +432,7 @@ class ActivateBuildTrigger(RepositoryParamResource):
except TriggerStartException as tse:
raise InvalidRequest(tse.message)
resp = build_status_view(build_request, can_write=True)
resp = build_status_view(build_request)
repo_string = '%s/%s' % (namespace, repository)
headers = {
'Location': api.url_for(RepositoryBuildStatus, repository=repo_string,
@ -456,7 +456,7 @@ class TriggerBuildList(RepositoryParamResource):
builds = list(model.list_trigger_builds(namespace, repository,
trigger_uuid, limit))
return {
'builds': [build_status_view(build, can_write=True) for build in builds]
'builds': [build_status_view(build) for build in builds]
}

View file

@ -444,19 +444,19 @@ class ConvertToOrganization(ApiResource):
user = get_authenticated_user()
convert_data = request.get_json()
# Ensure that the new admin user is the not user being converted.
admin_username = convert_data['adminUser']
if admin_username == user.username:
raise request_error(reason='invaliduser',
message='The admin user is not valid')
# Ensure that the sign in credentials work.
admin_username = convert_data['adminUser']
admin_password = convert_data['adminPassword']
(admin_user, error_message) = authentication.verify_user(admin_username, admin_password)
if not admin_user:
raise request_error(reason='invaliduser',
message='The admin user credentials are not valid')
# Ensure that the new admin user is the not user being converted.
if admin_user.id == user.id:
raise request_error(reason='invaliduser',
message='The admin user is not valid')
# Subscribe the organization to the new plan.
if features.BILLING:
plan = convert_data.get('plan', 'free')

View file

@ -126,7 +126,7 @@ def github_oauth_callback():
# Exchange the OAuth code.
code = request.args.get('code')
token = google_login.exchange_code_for_token(app.config, client, code)
token = github_login.exchange_code_for_token(app.config, client, code)
# Retrieve the user's information.
user_data = get_user(github_login, token)
@ -214,7 +214,7 @@ def google_oauth_attach():
@require_session_login
def github_oauth_attach():
code = request.args.get('code')
token = google_login.exchange_code_for_token(app.config, client, code)
token = github_login.exchange_code_for_token(app.config, client, code)
user_data = get_user(github_login, token)
if not user_data:
return render_ologin_error('GitHub')

View file

@ -140,7 +140,7 @@ def _repo_verb_signature(namespace, repository, tag, verb, checker=None, **kwarg
# Lookup the derived image storage for the verb.
derived = model.find_derived_storage(repo_image.storage, verb)
if derived is None or derived.uploading:
abort(404)
return make_response('', 202)
# Check if we have a valid signer configured.
if not signer.name:

View file

@ -28,6 +28,7 @@ from util.systemlogs import build_logs_archive
from auth import scopes
import features
import json
logger = logging.getLogger(__name__)
@ -432,16 +433,16 @@ def request_authorization_code():
# Load the application information.
oauth_app = provider.get_application_for_client_id(client_id)
app_email = oauth_app.email or organization.email
app_email = oauth_app.avatar_email or oauth_app.organization.email
oauth_app_view = {
'name': oauth_app.name,
'description': oauth_app.description,
'url': oauth_app.application_uri,
'avatar': avatar.get_data(oauth_app.name, app_email, 'app'),
'avatar': json.dumps(avatar.get_data(oauth_app.name, app_email, 'app')),
'organization': {
'name': oauth_app.organization.username,
'avatar': avatar.get_data_for_org(oauth_app.organization)
'avatar': json.dumps(avatar.get_data_for_org(oauth_app.organization))
}
}
@ -562,6 +563,9 @@ def redirect_to_repository(namespace, reponame, tag):
permission = ReadRepositoryPermission(namespace, reponame)
is_public = model.repository_is_public(namespace, reponame)
if request.args.get('ac-discovery', 0) == 1:
return index('')
if permission.can() or is_public:
repository_name = '/'.join([namespace, reponame])
return redirect(url_for('web.repository', path=repository_name, tag=tag))