Merge pull request #201 from coreos-inc/basepullissue
Record phase information and make better error messages on pull failure
This commit is contained in:
commit
3e29420718
3 changed files with 46 additions and 51 deletions
|
@ -206,10 +206,10 @@ class BuildComponent(BaseComponent):
|
|||
self._last_heartbeat = datetime.datetime.utcnow()
|
||||
|
||||
# Parse any of the JSON data logged.
|
||||
docker_data = {}
|
||||
log_data = {}
|
||||
if json_data:
|
||||
try:
|
||||
docker_data = json.loads(json_data)
|
||||
log_data = json.loads(json_data)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
|
@ -217,8 +217,8 @@ class BuildComponent(BaseComponent):
|
|||
fully_unwrapped = ''
|
||||
keys_to_extract = ['error', 'status', 'stream']
|
||||
for key in keys_to_extract:
|
||||
if key in docker_data:
|
||||
fully_unwrapped = docker_data[key]
|
||||
if key in log_data:
|
||||
fully_unwrapped = log_data[key]
|
||||
break
|
||||
|
||||
# Determine if this is a step string.
|
||||
|
@ -233,10 +233,10 @@ class BuildComponent(BaseComponent):
|
|||
# Parse and update the phase and the status_dict. The status dictionary contains
|
||||
# the pull/push progress, as well as the current step index.
|
||||
with self._build_status as status_dict:
|
||||
if self._build_status.set_phase(phase):
|
||||
if self._build_status.set_phase(phase, log_data.get('status_data')):
|
||||
logger.debug('Build %s has entered a new phase: %s', self.builder_realm, phase)
|
||||
|
||||
BuildComponent._process_pushpull_status(status_dict, phase, docker_data, self._image_info)
|
||||
BuildComponent._process_pushpull_status(status_dict, phase, log_data, self._image_info)
|
||||
|
||||
# If the current message represents the beginning of a new step, then update the
|
||||
# current command index.
|
||||
|
@ -244,8 +244,8 @@ class BuildComponent(BaseComponent):
|
|||
status_dict['current_command'] = current_step
|
||||
|
||||
# If the json data contains an error, then something went wrong with a push or pull.
|
||||
if 'error' in docker_data:
|
||||
self._build_status.set_error(docker_data['error'])
|
||||
if 'error' in log_data:
|
||||
self._build_status.set_error(log_data['error'])
|
||||
|
||||
if current_step is not None:
|
||||
self._build_status.set_command(current_status_string)
|
||||
|
|
|
@ -1,22 +1,21 @@
|
|||
<div bindonce class="build-log-error-element">
|
||||
<!-- Errors -->
|
||||
<span class="error-message-container">
|
||||
<i class="fa fa-exclamation-triangle"></i>
|
||||
<span class="error-message" bo-text="error.message"></span>
|
||||
<span ng-if="error.message == 'HTTP code: 403' && getLocalPullInfo().isLocal">
|
||||
caused by attempting to pull private repository <a href="/repository/{{ getLocalPullInfo().repo }}">{{ getLocalPullInfo().repo }}</a>
|
||||
<span ng-if="getLocalPullInfo().login">with inaccessible credentials</span>
|
||||
<span ng-if="!getLocalPullInfo().login">without credentials</span>
|
||||
<!-- Local Pull issue -->
|
||||
<span bo-if="isPullError(error) && localPullInfo.isLocal">
|
||||
<span bo-if="!localPullInfo.username" class="error-message">
|
||||
Error 403: Could not pull private base image <a href="/repository/{{ localPullInfo.repo }}">{{ localPullInfo.repo }}</a> without robot account credentials. Please see
|
||||
<a href="http://docs.quay.io/issues/base-pull-issue.html" target="_blank">Setting up build trigger credentials</a> for more information.
|
||||
</span>
|
||||
<span bo-if="localPullInfo.username" class="error-message">
|
||||
Error 403: Could not pull private base image <a href="/repository/{{ localPullInfo.repo }}">{{ localPullInfo.repo }}</a> because robot account <strong>{{ localPullInfo.username}}</strong> does not have access. Please see
|
||||
<a href="http://docs.quay.io/issues/base-pull-issue.html" target="_blank">Setting up build trigger credentials</a> for more information.
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<div class="alert alert-danger" ng-if="error.message == 'HTTP code: 403' && getLocalPullInfo().isLocal">
|
||||
<div ng-if="getLocalPullInfo().login">
|
||||
Note: The credentials <b>{{ getLocalPullInfo().login.username }}</b> for registry <b>{{ getLocalPullInfo().login.registry }}</b> cannot
|
||||
access repository <a href="/repository/{{ getLocalPullInfo().repo }}">{{ getLocalPullInfo().repo }}</a>.
|
||||
</div>
|
||||
<div ng-if="!getLocalPullInfo().login">
|
||||
Note: No robot account is specified for this build. Without such credentials, this pull will always fail. Please setup a new
|
||||
build trigger with a robot account that has access to <a href="/repository/{{ getLocalPullInfo().repo }}">{{ getLocalPullInfo().repo }}</a> or make that repository public.
|
||||
</div>
|
||||
</div>
|
||||
<!-- Other issue -->
|
||||
<span bo-if="!isPullError(error) || !localPullInfo.isLocal"
|
||||
class="error-message" bo-text="error.message"></span>
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
@ -13,16 +13,9 @@ angular.module('quay').directive('buildLogError', function () {
|
|||
'entries': '=entries'
|
||||
},
|
||||
controller: function($scope, $element, Config) {
|
||||
$scope.isInternalError = function() {
|
||||
var entry = $scope.entries[$scope.entries.length - 1];
|
||||
return entry && entry.data && entry.data['internal_error'];
|
||||
};
|
||||
|
||||
$scope.getLocalPullInfo = function() {
|
||||
if ($scope.entries.__localpull !== undefined) {
|
||||
return $scope.entries.__localpull;
|
||||
}
|
||||
$scope.localPullInfo = null;
|
||||
|
||||
var calculateLocalPullInfo = function(entries) {
|
||||
var localInfo = {
|
||||
'isLocal': false
|
||||
};
|
||||
|
@ -32,29 +25,32 @@ angular.module('quay').directive('buildLogError', function () {
|
|||
for (var i = 0; i < $scope.entries.length; ++i) {
|
||||
var entry = $scope.entries[i];
|
||||
if (entry.type == 'phase' && entry.message == 'pulling') {
|
||||
for (var j = 0; j < entry.logs.length(); ++j) {
|
||||
var log = entry.logs.get(j);
|
||||
if (log.data && log.data.phasestep == 'login') {
|
||||
localInfo['login'] = log.data;
|
||||
}
|
||||
|
||||
if (log.data && log.data.phasestep == 'pull') {
|
||||
var repo_url = log.data['repo_url'];
|
||||
var repo_and_tag = repo_url.substring(Config.SERVER_HOSTNAME.length + 1);
|
||||
var tagIndex = repo_and_tag.lastIndexOf(':');
|
||||
var repo = repo_and_tag.substring(0, tagIndex);
|
||||
|
||||
localInfo['repo_url'] = repo_url;
|
||||
localInfo['repo'] = repo;
|
||||
|
||||
localInfo['isLocal'] = repo_url.indexOf(Config.SERVER_HOSTNAME + '/') == 0;
|
||||
}
|
||||
var entryData = entry.data || {};
|
||||
if (entryData.base_image) {
|
||||
localInfo['isLocal'] = true || entryData['base_image'].indexOf(Config.SERVER_HOSTNAME + '/') == 0;
|
||||
localInfo['pullUsername'] = entryData['pull_username'];
|
||||
localInfo['repo'] = entryData['base_image'].substring(Config.SERVER_HOSTNAME.length);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $scope.entries.__localpull = localInfo;
|
||||
$scope.localPullInfo = localInfo;
|
||||
};
|
||||
|
||||
calculateLocalPullInfo($scope.entries);
|
||||
|
||||
$scope.isInternalError = function() {
|
||||
var entry = $scope.entries[$scope.entries.length - 1];
|
||||
return entry && entry.data && entry.data['internal_error'];
|
||||
};
|
||||
|
||||
$scope.isPullError = function(error) {
|
||||
if (!error || !error.data || !error.data.base_error) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return error.data.base_error.indexOf('Error: Status 403 trying to pull repository ') == 0;
|
||||
};
|
||||
}
|
||||
};
|
||||
|
|
Reference in a new issue