Merge remote-tracking branch 'origin/master' into waltermitty

This commit is contained in:
Jake Moshenko 2014-09-12 11:45:07 -04:00
commit b55e79e5d3
6 changed files with 93 additions and 12 deletions

View file

@ -25,7 +25,7 @@ class RedisBuildLogs(object):
""" """
return self._redis.rpush(self._logs_key(build_id), json.dumps(log_obj)) return self._redis.rpush(self._logs_key(build_id), json.dumps(log_obj))
def append_log_message(self, build_id, log_message, log_type=None): def append_log_message(self, build_id, log_message, log_type=None, log_data=None):
""" """
Wraps the message in an envelope and push it to the end of the log entry Wraps the message in an envelope and push it to the end of the log entry
list and returns the index at which it was inserted. list and returns the index at which it was inserted.
@ -37,6 +37,9 @@ class RedisBuildLogs(object):
if log_type: if log_type:
log_obj['type'] = log_type log_obj['type'] = log_type
if log_data:
log_obj['data'] = log_data
return self._redis.rpush(self._logs_key(build_id), json.dumps(log_obj)) - 1 return self._redis.rpush(self._logs_key(build_id), json.dumps(log_obj)) - 1
def get_log_entries(self, build_id, start_index): def get_log_entries(self, build_id, start_index):

View file

@ -2558,7 +2558,7 @@ p.editable:hover i {
margin-top: 10px; margin-top: 10px;
} }
.repo-build .build-log-error-element { .repo-build .build-log-error-element .error-message-container {
position: relative; position: relative;
display: inline-block; display: inline-block;
margin: 10px; margin: 10px;
@ -2568,7 +2568,7 @@ p.editable:hover i {
margin-left: 22px; margin-left: 22px;
} }
.repo-build .build-log-error-element i.fa { .repo-build .build-log-error-element .error-message-container i.fa {
color: red; color: red;
position: absolute; position: absolute;
top: 13px; top: 13px;

View file

@ -1,4 +1,23 @@
<span bindonce class="build-log-error-element"> <div bindonce class="build-log-error-element">
<span class="error-message-container">
<i class="fa fa-exclamation-triangle"></i> <i class="fa fa-exclamation-triangle"></i>
<span class="error-message" bo-text="error.message"></span> <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 crdentials</span>
<span ng-if="!getLocalPullInfo().login">without credentials</span>
</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>
</div>

View file

@ -153,6 +153,14 @@ quayApp = angular.module('quay', quayDependencies, function($provide, cfpLoading
this.currentIndex_ = 0; this.currentIndex_ = 0;
} }
_ViewArray.prototype.length = function() {
return this.entries.length;
};
_ViewArray.prototype.get = function(index) {
return this.entries[index];
};
_ViewArray.prototype.push = function(elem) { _ViewArray.prototype.push = function(elem) {
this.entries.push(elem); this.entries.push(elem);
this.hasEntries = true; this.hasEntries = true;
@ -4440,9 +4448,48 @@ quayApp.directive('buildLogError', function () {
transclude: false, transclude: false,
restrict: 'C', restrict: 'C',
scope: { scope: {
'error': '=error' 'error': '=error',
'entries': '=entries'
}, },
controller: function($scope, $element) { controller: function($scope, $element, Config) {
$scope.getLocalPullInfo = function() {
if ($scope.entries.__localpull !== undefined) {
return $scope.entries.__localpull;
}
var localInfo = {
'isLocal': false
};
// Find the 'pulling' phase entry, and then extra any metadata found under
// it.
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;
}
}
break;
}
}
return $scope.entries.__localpull = localInfo;
};
} }
}; };
return directiveDefinitionObject; return directiveDefinitionObject;

View file

@ -77,7 +77,7 @@
<span class="container-content build-log-phase" phase="container"></span> <span class="container-content build-log-phase" phase="container"></span>
</div> </div>
<div ng-switch-when="error"> <div ng-switch-when="error">
<span class="container-content build-log-error" error="container"></span> <span class="container-content build-log-error" error="container" entries="logEntries"></span>
</div> </div>
<div ng-switch-when="command"> <div ng-switch-when="command">
<span class="container-content build-log-command" command="container"></span> <span class="container-content build-log-command" command="container"></span>

View file

@ -225,6 +225,13 @@ class DockerfileBuildContext(object):
if self._pull_credentials: if self._pull_credentials:
logger.debug('Logging in with pull credentials: %s@%s', logger.debug('Logging in with pull credentials: %s@%s',
self._pull_credentials['username'], self._pull_credentials['registry']) self._pull_credentials['username'], self._pull_credentials['registry'])
self._build_logger('Pulling base image: %s' % image_and_tag, log_data = {
'phasestep': 'login',
'username': self._pull_credentials['username'],
'registry': self._pull_credentials['registry']
})
self._build_cl.login(self._pull_credentials['username'], self._pull_credentials['password'], self._build_cl.login(self._pull_credentials['username'], self._pull_credentials['password'],
registry=self._pull_credentials['registry'], reauth=True) registry=self._pull_credentials['registry'], reauth=True)
@ -235,7 +242,12 @@ class DockerfileBuildContext(object):
raise JobException('Missing FROM command in Dockerfile') raise JobException('Missing FROM command in Dockerfile')
image_and_tag = ':'.join(image_and_tag_tuple) image_and_tag = ':'.join(image_and_tag_tuple)
self._build_logger('Pulling base image: %s' % image_and_tag)
self._build_logger('Pulling base image: %s' % image_and_tag, log_data = {
'phasestep': 'pull',
'repo_url': image_and_tag
})
pull_status = self._build_cl.pull(image_and_tag, stream=True) pull_status = self._build_cl.pull(image_and_tag, stream=True)
self.__monitor_completion(pull_status, 'Downloading', self._status, 'pull_completion') self.__monitor_completion(pull_status, 'Downloading', self._status, 'pull_completion')