Change to store the pull robot on the repository build and only add the credentials to the queue item. This prevents the credentials from being exposed to the end user. Also fixes the restart build option
This commit is contained in:
parent
2a72e91bdb
commit
9a79d1562a
13 changed files with 110 additions and 68 deletions
|
@ -176,7 +176,7 @@ class RepositoryBuildTrigger(BaseModel):
|
||||||
auth_token = CharField()
|
auth_token = CharField()
|
||||||
config = TextField(default='{}')
|
config = TextField(default='{}')
|
||||||
write_token = ForeignKeyField(AccessToken, null=True)
|
write_token = ForeignKeyField(AccessToken, null=True)
|
||||||
pull_user = ForeignKeyField(User, null=True, related_name='pulluser')
|
pull_robot = ForeignKeyField(User, null=True, related_name='triggerpullrobot')
|
||||||
|
|
||||||
|
|
||||||
class EmailConfirmation(BaseModel):
|
class EmailConfirmation(BaseModel):
|
||||||
|
@ -245,6 +245,7 @@ class RepositoryBuild(BaseModel):
|
||||||
started = DateTimeField(default=datetime.now)
|
started = DateTimeField(default=datetime.now)
|
||||||
display_name = CharField()
|
display_name = CharField()
|
||||||
trigger = ForeignKeyField(RepositoryBuildTrigger, null=True, index=True)
|
trigger = ForeignKeyField(RepositoryBuildTrigger, null=True, index=True)
|
||||||
|
pull_robot = ForeignKeyField(User, null=True, related_name='buildpullrobot')
|
||||||
|
|
||||||
|
|
||||||
class QueueItem(BaseModel):
|
class QueueItem(BaseModel):
|
||||||
|
|
|
@ -1453,27 +1453,42 @@ def get_recent_repository_build(namespace_name, repository_name):
|
||||||
|
|
||||||
|
|
||||||
def create_repository_build(repo, access_token, job_config_obj, dockerfile_id,
|
def create_repository_build(repo, access_token, job_config_obj, dockerfile_id,
|
||||||
display_name, trigger=None):
|
display_name, trigger=None, pull_robot_name=None):
|
||||||
|
pull_robot = None
|
||||||
|
if pull_robot_name:
|
||||||
|
pull_robot = lookup_robot(pull_robot_name)
|
||||||
|
|
||||||
return RepositoryBuild.create(repository=repo, access_token=access_token,
|
return RepositoryBuild.create(repository=repo, access_token=access_token,
|
||||||
job_config=json.dumps(job_config_obj),
|
job_config=json.dumps(job_config_obj),
|
||||||
display_name=display_name, trigger=trigger,
|
display_name=display_name, trigger=trigger,
|
||||||
resource_key=dockerfile_id)
|
resource_key=dockerfile_id,
|
||||||
|
pull_robot=pull_robot)
|
||||||
|
|
||||||
def get_pull_credentials(trigger):
|
|
||||||
if not trigger.pull_user:
|
def get_pull_robot_name(trigger):
|
||||||
|
if not trigger.pull_robot:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return trigger.pull_robot.username
|
||||||
|
|
||||||
|
|
||||||
|
def get_pull_credentials(robotname):
|
||||||
|
robot = lookup_robot(robotname)
|
||||||
|
if not robot:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
login_info = FederatedLogin.get(user=trigger.pull_user)
|
login_info = FederatedLogin.get(user=robot)
|
||||||
except FederatedLogin.DoesNotExist:
|
except FederatedLogin.DoesNotExist:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'username': trigger.pull_user.username,
|
'username': robot.username,
|
||||||
'password': login_info.service_ident,
|
'password': login_info.service_ident,
|
||||||
'registry': '%s://%s/v1/' % (app.config['URL_SCHEME'], app.config['URL_HOST']),
|
'registry': '%s://%s/v1/' % (app.config['URL_SCHEME'], app.config['URL_HOST']),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def create_webhook(repo, params_obj):
|
def create_webhook(repo, params_obj):
|
||||||
return Webhook.create(repository=repo, parameters=json.dumps(params_obj))
|
return Webhook.create(repository=repo, parameters=json.dumps(params_obj))
|
||||||
|
|
||||||
|
@ -1530,12 +1545,12 @@ def log_action(kind_name, user_or_organization_name, performer=None,
|
||||||
metadata_json=json.dumps(metadata), datetime=timestamp)
|
metadata_json=json.dumps(metadata), datetime=timestamp)
|
||||||
|
|
||||||
|
|
||||||
def create_build_trigger(repo, service_name, auth_token, user, pull_user=None):
|
def create_build_trigger(repo, service_name, auth_token, user, pull_robot=None):
|
||||||
service = BuildTriggerService.get(name=service_name)
|
service = BuildTriggerService.get(name=service_name)
|
||||||
trigger = RepositoryBuildTrigger.create(repository=repo, service=service,
|
trigger = RepositoryBuildTrigger.create(repository=repo, service=service,
|
||||||
auth_token=auth_token,
|
auth_token=auth_token,
|
||||||
connected_user=user,
|
connected_user=user,
|
||||||
pull_user=None)
|
pull_robot=pull_robot)
|
||||||
return trigger
|
return trigger
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,10 @@ from endpoints.api import (RepositoryParamResource, parse_args, query_param, nic
|
||||||
from endpoints.common import start_build
|
from endpoints.common import start_build
|
||||||
from endpoints.trigger import BuildTrigger
|
from endpoints.trigger import BuildTrigger
|
||||||
from data import model
|
from data import model
|
||||||
from auth.permissions import ModifyRepositoryPermission
|
from auth.auth_context import get_authenticated_user
|
||||||
|
from auth.permissions import ModifyRepositoryPermission, AdministerOrganizationPermission
|
||||||
from data.buildlogs import BuildStatusRetrievalError
|
from data.buildlogs import BuildStatusRetrievalError
|
||||||
|
from util.names import parse_robot_username
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
@ -33,14 +35,15 @@ def get_job_config(build_obj):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def trigger_view(trigger):
|
def user_view(user):
|
||||||
def user_view(user):
|
|
||||||
return {
|
return {
|
||||||
'name': user.username,
|
'name': user.username,
|
||||||
'kind': 'user',
|
'kind': 'user',
|
||||||
'is_robot': user.robot,
|
'is_robot': user.robot,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def trigger_view(trigger):
|
||||||
|
|
||||||
if trigger and trigger.uuid:
|
if trigger and trigger.uuid:
|
||||||
config_dict = get_trigger_config(trigger)
|
config_dict = get_trigger_config(trigger)
|
||||||
build_trigger = BuildTrigger.get_trigger_for_service(trigger.service.name)
|
build_trigger = BuildTrigger.get_trigger_for_service(trigger.service.name)
|
||||||
|
@ -50,7 +53,7 @@ def trigger_view(trigger):
|
||||||
'id': trigger.uuid,
|
'id': trigger.uuid,
|
||||||
'connected_user': trigger.connected_user.username,
|
'connected_user': trigger.connected_user.username,
|
||||||
'is_active': build_trigger.is_active(config_dict),
|
'is_active': build_trigger.is_active(config_dict),
|
||||||
'pull_user': user_view(trigger.pull_user) if trigger.pull_user else None
|
'pull_robot': user_view(trigger.pull_robot) if trigger.pull_robot else None
|
||||||
}
|
}
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
@ -75,6 +78,7 @@ def build_status_view(build_obj, can_write=False):
|
||||||
'is_writer': can_write,
|
'is_writer': can_write,
|
||||||
'trigger': trigger_view(build_obj.trigger),
|
'trigger': trigger_view(build_obj.trigger),
|
||||||
'resource_key': build_obj.resource_key,
|
'resource_key': build_obj.resource_key,
|
||||||
|
'pull_robot': user_view(build_obj.pull_robot) if build_obj.pull_robot else None,
|
||||||
}
|
}
|
||||||
|
|
||||||
if can_write:
|
if can_write:
|
||||||
|
@ -103,28 +107,9 @@ class RepositoryBuildList(RepositoryParamResource):
|
||||||
'type': 'string',
|
'type': 'string',
|
||||||
'description': 'Subdirectory in which the Dockerfile can be found',
|
'description': 'Subdirectory in which the Dockerfile can be found',
|
||||||
},
|
},
|
||||||
'pull_credentials': {
|
'pull_robot': {
|
||||||
'type': 'object',
|
|
||||||
'description': 'Credentials used by the builder when pulling images',
|
|
||||||
'required': [
|
|
||||||
'username',
|
|
||||||
'password',
|
|
||||||
'registry'
|
|
||||||
],
|
|
||||||
'properties': {
|
|
||||||
'username': {
|
|
||||||
'type': 'string',
|
'type': 'string',
|
||||||
'description': 'The username for the pull'
|
'description': 'Username of a Quay robot account to use as pull credentials',
|
||||||
},
|
|
||||||
'password': {
|
|
||||||
'type': 'string',
|
|
||||||
'description': 'The password for the pull'
|
|
||||||
},
|
|
||||||
'registry': {
|
|
||||||
'type': 'string',
|
|
||||||
'description': 'The registry hostname for the pull'
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -154,7 +139,22 @@ class RepositoryBuildList(RepositoryParamResource):
|
||||||
|
|
||||||
dockerfile_id = request_json['file_id']
|
dockerfile_id = request_json['file_id']
|
||||||
subdir = request_json['subdirectory'] if 'subdirectory' in request_json else ''
|
subdir = request_json['subdirectory'] if 'subdirectory' in request_json else ''
|
||||||
pull_credentials = request_json.get('pull_credentials', None)
|
pull_robot_name = request_json.get('pull_robot', None)
|
||||||
|
|
||||||
|
# Verify the security behind the pull robot.
|
||||||
|
if pull_robot_name:
|
||||||
|
result = parse_robot_username(pull_robot_name)
|
||||||
|
if result:
|
||||||
|
pull_robot = model.lookup_robot(pull_robot_name)
|
||||||
|
if not pull_robot:
|
||||||
|
raise NotFound()
|
||||||
|
|
||||||
|
# Make sure the user has administer permissions for the robot's namespace.
|
||||||
|
(robot_namespace, shortname) = result
|
||||||
|
if not AdministerOrganizationPermission(robot_namespace).can():
|
||||||
|
raise Unauthorized()
|
||||||
|
else:
|
||||||
|
raise Unauthorized()
|
||||||
|
|
||||||
# Check if the dockerfile resource has already been used. If so, then it
|
# Check if the dockerfile resource has already been used. If so, then it
|
||||||
# can only be reused if the user has access to the repository for which it
|
# can only be reused if the user has access to the repository for which it
|
||||||
|
@ -170,7 +170,7 @@ class RepositoryBuildList(RepositoryParamResource):
|
||||||
display_name = user_files.get_file_checksum(dockerfile_id)
|
display_name = user_files.get_file_checksum(dockerfile_id)
|
||||||
|
|
||||||
build_request = start_build(repo, dockerfile_id, ['latest'], display_name, subdir, True,
|
build_request = start_build(repo, dockerfile_id, ['latest'], display_name, subdir, True,
|
||||||
pull_credentials=pull_credentials)
|
pull_robot_name=pull_robot_name)
|
||||||
|
|
||||||
resp = build_status_view(build_request, True)
|
resp = build_status_view(build_request, True)
|
||||||
repo_string = '%s/%s' % (namespace, repository)
|
repo_string = '%s/%s' % (namespace, repository)
|
||||||
|
|
|
@ -190,7 +190,7 @@ class BuildTriggerActivate(RepositoryParamResource):
|
||||||
raise Unauthorized()
|
raise Unauthorized()
|
||||||
|
|
||||||
# Set the pull robot.
|
# Set the pull robot.
|
||||||
trigger.pull_user = pull_robot
|
trigger.pull_robot = pull_robot
|
||||||
|
|
||||||
# Update the config.
|
# Update the config.
|
||||||
new_config_dict = request.get_json()['config']
|
new_config_dict = request.get_json()['config']
|
||||||
|
@ -224,7 +224,7 @@ class BuildTriggerActivate(RepositoryParamResource):
|
||||||
log_action('setup_repo_trigger', namespace,
|
log_action('setup_repo_trigger', namespace,
|
||||||
{'repo': repository, 'namespace': namespace,
|
{'repo': repository, 'namespace': namespace,
|
||||||
'trigger_id': trigger.uuid, 'service': trigger.service.name,
|
'trigger_id': trigger.uuid, 'service': trigger.service.name,
|
||||||
'pull_user': trigger.pull_user.username if trigger.pull_user else None,
|
'pull_robot': trigger.pull_robot.username if trigger.pull_robot else None,
|
||||||
'config': final_config}, repo=repo)
|
'config': final_config}, repo=repo)
|
||||||
|
|
||||||
return trigger_view(trigger)
|
return trigger_view(trigger)
|
||||||
|
@ -254,10 +254,10 @@ class ActivateBuildTrigger(RepositoryParamResource):
|
||||||
dockerfile_id, tags, name, subdir = specs
|
dockerfile_id, tags, name, subdir = specs
|
||||||
|
|
||||||
repo = model.get_repository(namespace, repository)
|
repo = model.get_repository(namespace, repository)
|
||||||
pull_credentials = model.get_pull_credentials(trigger)
|
pull_robot_name = model.get_pull_robot_name(trigger)
|
||||||
|
|
||||||
build_request = start_build(repo, dockerfile_id, tags, name, subdir, True,
|
build_request = start_build(repo, dockerfile_id, tags, name, subdir, True,
|
||||||
pull_credentials=pull_credentials)
|
pull_robot_name=pull_robot_name)
|
||||||
|
|
||||||
resp = build_status_view(build_request, True)
|
resp = build_status_view(build_request, True)
|
||||||
repo_string = '%s/%s' % (namespace, repository)
|
repo_string = '%s/%s' % (namespace, repository)
|
||||||
|
|
|
@ -107,7 +107,7 @@ def check_repository_usage(user_or_org, plan_found):
|
||||||
|
|
||||||
|
|
||||||
def start_build(repository, dockerfile_id, tags, build_name, subdir, manual,
|
def start_build(repository, dockerfile_id, tags, build_name, subdir, manual,
|
||||||
trigger=None, pull_credentials=None):
|
trigger=None, pull_robot_name=None):
|
||||||
host = urlparse.urlparse(request.url).netloc
|
host = urlparse.urlparse(request.url).netloc
|
||||||
repo_path = '%s/%s/%s' % (host, repository.namespace, repository.name)
|
repo_path = '%s/%s/%s' % (host, repository.namespace, repository.name)
|
||||||
|
|
||||||
|
@ -118,18 +118,18 @@ def start_build(repository, dockerfile_id, tags, build_name, subdir, manual,
|
||||||
job_config = {
|
job_config = {
|
||||||
'docker_tags': tags,
|
'docker_tags': tags,
|
||||||
'repository': repo_path,
|
'repository': repo_path,
|
||||||
'build_subdir': subdir,
|
'build_subdir': subdir
|
||||||
'pull_credentials': pull_credentials,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
build_request = model.create_repository_build(repository, token, job_config,
|
build_request = model.create_repository_build(repository, token, job_config,
|
||||||
dockerfile_id, build_name,
|
dockerfile_id, build_name,
|
||||||
trigger)
|
trigger, pull_robot_name = pull_robot_name)
|
||||||
|
|
||||||
dockerfile_build_queue.put(json.dumps({
|
dockerfile_build_queue.put(json.dumps({
|
||||||
'build_uuid': build_request.uuid,
|
'build_uuid': build_request.uuid,
|
||||||
'namespace': repository.namespace,
|
'namespace': repository.namespace,
|
||||||
'repository': repository.name,
|
'repository': repository.name,
|
||||||
|
'pull_credentials': model.get_pull_credentials(pull_robot_name) if pull_robot_name else None
|
||||||
}), retries_remaining=1)
|
}), retries_remaining=1)
|
||||||
|
|
||||||
metadata = {
|
metadata = {
|
||||||
|
|
|
@ -73,10 +73,10 @@ def build_trigger_webhook(namespace, repository, trigger_uuid):
|
||||||
# This was just a validation request, we don't need to build anything
|
# This was just a validation request, we don't need to build anything
|
||||||
return make_response('Okay')
|
return make_response('Okay')
|
||||||
|
|
||||||
pull_credentials = model.get_pull_credentials(trigger)
|
pull_robot_name = model.get_pull_robot_name(trigger)
|
||||||
repo = model.get_repository(namespace, repository)
|
repo = model.get_repository(namespace, repository)
|
||||||
start_build(repo, dockerfile_id, tags, name, subdir, False, trigger,
|
start_build(repo, dockerfile_id, tags, name, subdir, False, trigger,
|
||||||
pull_credentials=pull_credentials)
|
pull_robot_name=pull_robot_name)
|
||||||
|
|
||||||
return make_response('Okay')
|
return make_response('Okay')
|
||||||
|
|
||||||
|
|
|
@ -332,7 +332,7 @@ def populate_database():
|
||||||
token = model.create_access_token(building, 'write')
|
token = model.create_access_token(building, 'write')
|
||||||
|
|
||||||
trigger = model.create_build_trigger(building, 'github', '123authtoken',
|
trigger = model.create_build_trigger(building, 'github', '123authtoken',
|
||||||
new_user_1, pull_user = dtrobot)
|
new_user_1, pull_robot=dtrobot[0])
|
||||||
trigger.config = json.dumps({
|
trigger.config = json.dumps({
|
||||||
'build_source': 'jakedt/testconnect',
|
'build_source': 'jakedt/testconnect',
|
||||||
'subdir': '',
|
'subdir': '',
|
||||||
|
|
|
@ -962,9 +962,13 @@ function RepoBuildCtrl($scope, Restangular, ApiService, $routeParams, $rootScope
|
||||||
|
|
||||||
var data = {
|
var data = {
|
||||||
'file_id': build['resource_key'],
|
'file_id': build['resource_key'],
|
||||||
'subdirectory': subdirectory
|
'subdirectory': subdirectory,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (build['pull_robot']) {
|
||||||
|
data['pull_robot'] = build['pull_robot']['name'];
|
||||||
|
}
|
||||||
|
|
||||||
var params = {
|
var params = {
|
||||||
'repository': namespace + '/' + name
|
'repository': namespace + '/' + name
|
||||||
};
|
};
|
||||||
|
@ -1487,6 +1491,7 @@ function RepoAdminCtrl($scope, Restangular, ApiService, KeyService, $routeParams
|
||||||
|
|
||||||
ApiService.activateBuildTrigger(data, params).then(function(resp) {
|
ApiService.activateBuildTrigger(data, params).then(function(resp) {
|
||||||
trigger['is_active'] = true;
|
trigger['is_active'] = true;
|
||||||
|
trigger['pull_robot'] = resp['pull_robot'];
|
||||||
}, function(resp) {
|
}, function(resp) {
|
||||||
$scope.triggers.splice($scope.triggers.indexOf(trigger), 1);
|
$scope.triggers.splice($scope.triggers.indexOf(trigger), 1);
|
||||||
bootbox.dialog({
|
bootbox.dialog({
|
||||||
|
|
|
@ -270,11 +270,11 @@
|
||||||
Setting up trigger
|
Setting up trigger
|
||||||
</div>
|
</div>
|
||||||
<div ng-show="trigger.is_active" class="trigger-description" trigger="trigger"></div>
|
<div ng-show="trigger.is_active" class="trigger-description" trigger="trigger"></div>
|
||||||
<div class="trigger-pull-credentials" ng-if="trigger.is_active && trigger.pull_user">
|
<div class="trigger-pull-credentials" ng-if="trigger.is_active && trigger.pull_robot">
|
||||||
<span class="context-tooltip" title="The credentials used by the builder when pulling images" bs-tooltip>
|
<span class="context-tooltip" title="The credentials used by the builder when pulling images" bs-tooltip>
|
||||||
Pull Credentials:
|
Pull Credentials:
|
||||||
</span>
|
</span>
|
||||||
<span class="entity-reference" entity="trigger.pull_user"></span>
|
<span class="entity-reference" entity="trigger.pull_robot"></span>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td style="white-space: nowrap;">
|
<td style="white-space: nowrap;">
|
||||||
|
|
Binary file not shown.
|
@ -964,7 +964,7 @@ class TestRequestRepoBuild(ApiTestCase):
|
||||||
def test_requestrepobuild(self):
|
def test_requestrepobuild(self):
|
||||||
self.login(ADMIN_ACCESS_USER)
|
self.login(ADMIN_ACCESS_USER)
|
||||||
|
|
||||||
# Ensure where not yet building.
|
# Ensure we are not yet building.
|
||||||
json = self.getJsonResponse(RepositoryBuildList,
|
json = self.getJsonResponse(RepositoryBuildList,
|
||||||
params=dict(repository=ADMIN_ACCESS_USER + '/simple'))
|
params=dict(repository=ADMIN_ACCESS_USER + '/simple'))
|
||||||
|
|
||||||
|
@ -982,24 +982,20 @@ class TestRequestRepoBuild(ApiTestCase):
|
||||||
|
|
||||||
assert len(json['builds']) > 0
|
assert len(json['builds']) > 0
|
||||||
|
|
||||||
def test_requestrepobuild_with_credentials(self):
|
def test_requestrepobuild_with_robot(self):
|
||||||
self.login(ADMIN_ACCESS_USER)
|
self.login(ADMIN_ACCESS_USER)
|
||||||
|
|
||||||
# Ensure where not yet building.
|
# Ensure we are not yet building.
|
||||||
json = self.getJsonResponse(RepositoryBuildList,
|
json = self.getJsonResponse(RepositoryBuildList,
|
||||||
params=dict(repository=ADMIN_ACCESS_USER + '/simple'))
|
params=dict(repository=ADMIN_ACCESS_USER + '/simple'))
|
||||||
|
|
||||||
assert len(json['builds']) == 0
|
assert len(json['builds']) == 0
|
||||||
|
|
||||||
# Request a (fake) build.
|
# Request a (fake) build.
|
||||||
pull_creds = {
|
pull_robot = ADMIN_ACCESS_USER + '+dtrobot'
|
||||||
'username': 'foo',
|
|
||||||
'password': 'bar',
|
|
||||||
'registry': 'baz'
|
|
||||||
}
|
|
||||||
self.postResponse(RepositoryBuildList,
|
self.postResponse(RepositoryBuildList,
|
||||||
params=dict(repository=ADMIN_ACCESS_USER + '/simple'),
|
params=dict(repository=ADMIN_ACCESS_USER + '/simple'),
|
||||||
data=dict(file_id='foobarbaz', pull_credentials=pull_creds),
|
data=dict(file_id='foobarbaz', pull_robot=pull_robot),
|
||||||
expected_code=201)
|
expected_code=201)
|
||||||
|
|
||||||
# Check for the build.
|
# Check for the build.
|
||||||
|
@ -1009,6 +1005,27 @@ class TestRequestRepoBuild(ApiTestCase):
|
||||||
assert len(json['builds']) > 0
|
assert len(json['builds']) > 0
|
||||||
|
|
||||||
|
|
||||||
|
def test_requestrepobuild_with_invalid_robot(self):
|
||||||
|
self.login(ADMIN_ACCESS_USER)
|
||||||
|
|
||||||
|
# Request a (fake) build.
|
||||||
|
pull_robot = ADMIN_ACCESS_USER + '+invalidrobot'
|
||||||
|
self.postResponse(RepositoryBuildList,
|
||||||
|
params=dict(repository=ADMIN_ACCESS_USER + '/simple'),
|
||||||
|
data=dict(file_id='foobarbaz', pull_robot=pull_robot),
|
||||||
|
expected_code=404)
|
||||||
|
|
||||||
|
def test_requestrepobuild_with_unauthorized_robot(self):
|
||||||
|
self.login(ADMIN_ACCESS_USER)
|
||||||
|
|
||||||
|
# Request a (fake) build.
|
||||||
|
pull_robot = 'freshuser+anotherrobot'
|
||||||
|
self.postResponse(RepositoryBuildList,
|
||||||
|
params=dict(repository=ADMIN_ACCESS_USER + '/simple'),
|
||||||
|
data=dict(file_id='foobarbaz', pull_robot=pull_robot),
|
||||||
|
expected_code=403)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class TestWebhooks(ApiTestCase):
|
class TestWebhooks(ApiTestCase):
|
||||||
def test_webhooks(self):
|
def test_webhooks(self):
|
||||||
|
@ -1746,7 +1763,7 @@ class TestBuildTriggers(ApiTestCase):
|
||||||
|
|
||||||
# Verify that the robot was saved.
|
# Verify that the robot was saved.
|
||||||
self.assertEquals(True, activate_json['is_active'])
|
self.assertEquals(True, activate_json['is_active'])
|
||||||
self.assertEquals(ADMIN_ACCESS_USER + '+dtrobot', activate_json['pull_user']['name'])
|
self.assertEquals(ADMIN_ACCESS_USER + '+dtrobot', activate_json['pull_robot']['name'])
|
||||||
|
|
||||||
# Start a manual build.
|
# Start a manual build.
|
||||||
start_json = self.postJsonResponse(ActivateBuildTrigger,
|
start_json = self.postJsonResponse(ActivateBuildTrigger,
|
||||||
|
|
|
@ -26,4 +26,7 @@ def format_robot_username(parent_username, robot_shortname):
|
||||||
return '%s+%s' % (parent_username, robot_shortname)
|
return '%s+%s' % (parent_username, robot_shortname)
|
||||||
|
|
||||||
def parse_robot_username(robot_username):
|
def parse_robot_username(robot_username):
|
||||||
|
if not '+' in robot_username:
|
||||||
|
return None
|
||||||
|
|
||||||
return robot_username.split('+', 2)
|
return robot_username.split('+', 2)
|
||||||
|
|
|
@ -352,13 +352,14 @@ class DockerfileBuildWorker(Worker):
|
||||||
job_details['repository'],
|
job_details['repository'],
|
||||||
job_details['build_uuid'])
|
job_details['build_uuid'])
|
||||||
|
|
||||||
|
pull_credentials = job_details.get('pull_credentials', None)
|
||||||
|
|
||||||
job_config = json.loads(repository_build.job_config)
|
job_config = json.loads(repository_build.job_config)
|
||||||
|
|
||||||
resource_url = user_files.get_file_url(repository_build.resource_key)
|
resource_url = user_files.get_file_url(repository_build.resource_key)
|
||||||
tag_names = job_config['docker_tags']
|
tag_names = job_config['docker_tags']
|
||||||
build_subdir = job_config['build_subdir']
|
build_subdir = job_config['build_subdir']
|
||||||
repo = job_config['repository']
|
repo = job_config['repository']
|
||||||
pull_credentials = job_config.get('pull_credentials', None)
|
|
||||||
|
|
||||||
access_token = repository_build.access_token.code
|
access_token = repository_build.access_token.code
|
||||||
|
|
||||||
|
|
Reference in a new issue