Add feature flag to enable viewing builds and build logs for public repos

This commit is contained in:
Joseph Schorr 2017-08-07 15:24:36 -04:00
parent 0359ac8753
commit dff4207a89
6 changed files with 18 additions and 6 deletions

View file

@ -269,6 +269,10 @@ class DefaultConfig(ImmutableConfig):
# only private repositories can be returned. # only private repositories can be returned.
FEATURE_PUBLIC_CATALOG = False FEATURE_PUBLIC_CATALOG = False
# Feature Flag: If set to true, build logs may be read by those with read access to the repo,
# rather than only write access or admin access.
FEATURE_READER_BUILD_LOGS = False
# The namespace to use for library repositories. # The namespace to use for library repositories.
# Note: This must remain 'library' until Docker removes their hard-coded namespace for libraries. # Note: This must remain 'library' until Docker removes their hard-coded namespace for libraries.
# See: https://github.com/docker/docker/blob/master/registry/session.go#L320 # See: https://github.com/docker/docker/blob/master/registry/session.go#L320

View file

@ -8,6 +8,8 @@ import os
from flask import request from flask import request
from urlparse import urlparse from urlparse import urlparse
import features
from app import userfiles as user_files, build_logs, log_archive, dockerfile_build_queue from app import userfiles as user_files, build_logs, log_archive, dockerfile_build_queue
from auth.permissions import (ReadRepositoryPermission, ModifyRepositoryPermission, from auth.permissions import (ReadRepositoryPermission, ModifyRepositoryPermission,
AdministerRepositoryPermission, AdministerOrganizationPermission, AdministerRepositoryPermission, AdministerOrganizationPermission,
@ -147,7 +149,7 @@ def build_status_view(build_obj):
'error': error, 'error': error,
} }
if can_write: if can_write or features.READER_BUILD_LOGS:
if build_obj.resource_key is not None: if build_obj.resource_key is not None:
resp['archive_url'] = user_files.get_file_url(build_obj.resource_key, requires_cors=True) resp['archive_url'] = user_files.get_file_url(build_obj.resource_key, requires_cors=True)
elif job_config.get('archive_url', None): elif job_config.get('archive_url', None):
@ -424,11 +426,15 @@ def get_logs_or_log_url(build):
@path_param('build_uuid', 'The UUID of the build') @path_param('build_uuid', 'The UUID of the build')
class RepositoryBuildLogs(RepositoryParamResource): class RepositoryBuildLogs(RepositoryParamResource):
""" Resource for loading repository build logs. """ """ Resource for loading repository build logs. """
@require_repo_write @require_repo_read
@nickname('getRepoBuildLogs') @nickname('getRepoBuildLogs')
@disallow_for_app_repositories @disallow_for_app_repositories
def get(self, namespace, repository, build_uuid): def get(self, namespace, repository, build_uuid):
""" Return the build logs for the build specified by the build uuid. """ """ Return the build logs for the build specified by the build uuid. """
can_write = ModifyRepositoryPermission(namespace, repository).can()
if not features.READER_BUILD_LOGS and not can_write:
raise Unauthorized()
build = model.build.get_repository_build(build_uuid) build = model.build.get_repository_build(build_uuid)
if (not build or build.repository.name != repository or if (not build or build.repository.name != repository or
build.repository.namespace_user.username != namespace): build.repository.namespace_user.username != namespace):

View file

@ -1,7 +1,7 @@
<span class="build-mini-status-element"> <span class="build-mini-status-element">
<span class="anchor" <span class="anchor"
href="/repository/{{ build.repository.namespace }}/{{ build.repository.name }}/build/{{ build.id }}" href="/repository/{{ build.repository.namespace }}/{{ build.repository.name }}/build/{{ build.id }}"
is-only-text="!isAdmin"> is-only-text="!canView">
<div> <div>
<span class="build-state-icon" build="build"></span> <span class="build-state-icon" build="build"></span>
<span class="timing"> <span class="timing">

View file

@ -40,7 +40,7 @@
<!-- Builds --> <!-- Builds -->
<div ng-if="builds && builds.length"> <div ng-if="builds && builds.length">
<div class="build-mini-status" ng-repeat="build in builds" build="build" <div class="build-mini-status" ng-repeat="build in builds" build="build"
is-admin="repository.can_admin"></div> can-view="repository.can_write || Features.READER_BUILD_LOGS"></div>
</div> </div>
<!-- View All --> <!-- View All -->

View file

@ -13,7 +13,9 @@ angular.module('quay').directive('repoPanelInfo', function () {
'builds': '=builds', 'builds': '=builds',
'isEnabled': '=isEnabled' 'isEnabled': '=isEnabled'
}, },
controller: function($scope, $element, ApiService, Config) { controller: function($scope, $element, ApiService, Config, Features) {
$scope.Features = Features;
$scope.$watch('repository', function(repository) { $scope.$watch('repository', function(repository) {
if (!$scope.repository) { return; } if (!$scope.repository) { return; }

View file

@ -10,7 +10,7 @@ angular.module('quay').directive('buildMiniStatus', function () {
restrict: 'C', restrict: 'C',
scope: { scope: {
'build': '=build', 'build': '=build',
'isAdmin': '=isAdmin' 'canView': '=canView'
}, },
controller: function($scope, $element, BuildService) { controller: function($scope, $element, BuildService) {
$scope.isBuilding = function(build) { $scope.isBuilding = function(build) {