Merge branch 'master' into gitlab
This commit is contained in:
commit
e3aededcbc
70 changed files with 1000 additions and 265 deletions
|
@ -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')
|
||||
|
|
|
@ -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]
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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))
|
||||
|
|
Reference in a new issue