Merge branch 'master' into quark
This commit is contained in:
commit
fbdbc21eb1
137 changed files with 8691 additions and 2414 deletions
152
static/js/app.js
152
static/js/app.js
|
@ -126,7 +126,7 @@ function getMarkedDown(string) {
|
|||
|
||||
quayDependencies = ['ngRoute', 'chieffancypants.loadingBar', 'angular-tour', 'restangular', 'angularMoment',
|
||||
'mgcrea.ngStrap', 'ngCookies', 'ngSanitize', 'angular-md5', 'pasvaz.bindonce', 'ansiToHtml',
|
||||
'ngAnimate'];
|
||||
'ngAnimate', 'core-ui', 'core-config-setup'];
|
||||
|
||||
if (window.__config && window.__config.MIXPANEL_KEY) {
|
||||
quayDependencies.push('angulartics');
|
||||
|
@ -977,7 +977,7 @@ quayApp = angular.module('quay', quayDependencies, function($provide, cfpLoading
|
|||
return resource;
|
||||
};
|
||||
|
||||
var buildUrl = function(path, parameters) {
|
||||
var buildUrl = function(path, parameters, opt_forcessl) {
|
||||
// We already have /api/v1/ on the URLs, so remove them from the paths.
|
||||
path = path.substr('/api/v1/'.length, path.length);
|
||||
|
||||
|
@ -1017,6 +1017,11 @@ quayApp = angular.module('quay', quayDependencies, function($provide, cfpLoading
|
|||
}
|
||||
}
|
||||
|
||||
// If we are forcing SSL, return an absolutel URL with an SSL prefix.
|
||||
if (opt_forcessl) {
|
||||
path = 'https://' + window.location.host + '/api/v1/' + path;
|
||||
}
|
||||
|
||||
return url;
|
||||
};
|
||||
|
||||
|
@ -1047,12 +1052,35 @@ quayApp = angular.module('quay', quayDependencies, function($provide, cfpLoading
|
|||
}
|
||||
};
|
||||
|
||||
var freshLoginInProgress = [];
|
||||
var reject = function(msg) {
|
||||
for (var i = 0; i < freshLoginInProgress.length; ++i) {
|
||||
freshLoginInProgress[i].deferred.reject({'data': {'message': msg}});
|
||||
}
|
||||
freshLoginInProgress = [];
|
||||
};
|
||||
|
||||
var retry = function() {
|
||||
for (var i = 0; i < freshLoginInProgress.length; ++i) {
|
||||
freshLoginInProgress[i].retry();
|
||||
}
|
||||
freshLoginInProgress = [];
|
||||
};
|
||||
|
||||
var freshLoginFailCheck = function(opName, opArgs) {
|
||||
return function(resp) {
|
||||
var deferred = $q.defer();
|
||||
|
||||
// If the error is a fresh login required, show the dialog.
|
||||
if (resp.status == 401 && resp.data['error_type'] == 'fresh_login_required') {
|
||||
var retryOperation = function() {
|
||||
apiService[opName].apply(apiService, opArgs).then(function(resp) {
|
||||
deferred.resolve(resp);
|
||||
}, function(resp) {
|
||||
deferred.reject(resp);
|
||||
});
|
||||
};
|
||||
|
||||
var verifyNow = function() {
|
||||
var info = {
|
||||
'password': $('#freshPassword').val()
|
||||
|
@ -1062,19 +1090,27 @@ quayApp = angular.module('quay', quayDependencies, function($provide, cfpLoading
|
|||
|
||||
// Conduct the sign in of the user.
|
||||
apiService.verifyUser(info).then(function() {
|
||||
// On success, retry the operation. if it succeeds, then resolve the
|
||||
// On success, retry the operations. if it succeeds, then resolve the
|
||||
// deferred promise with the result. Otherwise, reject the same.
|
||||
apiService[opName].apply(apiService, opArgs).then(function(resp) {
|
||||
deferred.resolve(resp);
|
||||
}, function(resp) {
|
||||
deferred.reject(resp);
|
||||
});
|
||||
retry();
|
||||
}, function(resp) {
|
||||
// Reject with the sign in error.
|
||||
deferred.reject({'data': {'message': 'Invalid verification credentials'}});
|
||||
reject('Invalid verification credentials');
|
||||
});
|
||||
};
|
||||
|
||||
// Add the retry call to the in progress list. If there is more than a single
|
||||
// in progress call, we skip showing the dialog (since it has already been
|
||||
// shown).
|
||||
freshLoginInProgress.push({
|
||||
'deferred': deferred,
|
||||
'retry': retryOperation
|
||||
})
|
||||
|
||||
if (freshLoginInProgress.length > 1) {
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
var box = bootbox.dialog({
|
||||
"message": 'It has been more than a few minutes since you last logged in, ' +
|
||||
'so please verify your password to perform this sensitive operation:' +
|
||||
|
@ -1092,7 +1128,7 @@ quayApp = angular.module('quay', quayDependencies, function($provide, cfpLoading
|
|||
"label": "Cancel",
|
||||
"className": "btn-default",
|
||||
"callback": function() {
|
||||
deferred.reject({'data': {'message': 'Verification canceled'}});
|
||||
reject('Verification canceled')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1124,8 +1160,8 @@ quayApp = angular.module('quay', quayDependencies, function($provide, cfpLoading
|
|||
var path = resource['path'];
|
||||
|
||||
// Add the operation itself.
|
||||
apiService[operationName] = function(opt_options, opt_parameters, opt_background) {
|
||||
var one = Restangular.one(buildUrl(path, opt_parameters));
|
||||
apiService[operationName] = function(opt_options, opt_parameters, opt_background, opt_forcessl) {
|
||||
var one = Restangular.one(buildUrl(path, opt_parameters, opt_forcessl));
|
||||
if (opt_background) {
|
||||
one.withHttpConfig({
|
||||
'ignoreLoadingBar': true
|
||||
|
@ -1244,6 +1280,39 @@ quayApp = angular.module('quay', quayDependencies, function($provide, cfpLoading
|
|||
return cookieService;
|
||||
}]);
|
||||
|
||||
$provide.factory('ContainerService', ['ApiService', '$timeout',
|
||||
function(ApiService, $timeout) {
|
||||
var containerService = {};
|
||||
containerService.restartContainer = function(callback) {
|
||||
ApiService.scShutdownContainer(null, null).then(function(resp) {
|
||||
$timeout(callback, 2000);
|
||||
}, ApiService.errorDisplay('Cannot restart container. Please report this to support.'))
|
||||
};
|
||||
|
||||
containerService.scheduleStatusCheck = function(callback) {
|
||||
$timeout(function() {
|
||||
containerService.checkStatus(callback);
|
||||
}, 2000);
|
||||
};
|
||||
|
||||
containerService.checkStatus = function(callback, force_ssl) {
|
||||
var errorHandler = function(resp) {
|
||||
if (resp.status == 404 || resp.status == 502) {
|
||||
// Container has not yet come back up, so we schedule another check.
|
||||
containerService.scheduleStatusCheck(callback);
|
||||
return;
|
||||
}
|
||||
|
||||
return ApiService.errorDisplay('Cannot load status. Please report this to support')(resp);
|
||||
};
|
||||
|
||||
ApiService.scRegistryStatus(null, null)
|
||||
.then(callback, errorHandler, /* background */true, /* force ssl*/force_ssl);
|
||||
};
|
||||
|
||||
return containerService;
|
||||
}]);
|
||||
|
||||
$provide.factory('UserService', ['ApiService', 'CookieService', '$rootScope', 'Config',
|
||||
function(ApiService, CookieService, $rootScope, Config) {
|
||||
var userResponse = {
|
||||
|
@ -2225,8 +2294,10 @@ quayApp = angular.module('quay', quayDependencies, function($provide, cfpLoading
|
|||
templateUrl: '/static/partials/repo-list.html', controller: RepoListCtrl, reloadOnSearch: false}).
|
||||
when('/user/', {title: 'Account Settings', description:'Account settings for ' + title, templateUrl: '/static/partials/user-admin.html',
|
||||
reloadOnSearch: false, controller: UserAdminCtrl}).
|
||||
when('/superuser/', {title: 'Superuser Admin Panel', description:'Admin panel for ' + title, templateUrl: '/static/partials/super-user.html',
|
||||
reloadOnSearch: false, controller: SuperUserAdminCtrl}).
|
||||
when('/superuser/', {title: 'Enterprise Registry Management', description:'Admin panel for ' + title, templateUrl: '/static/partials/super-user.html',
|
||||
reloadOnSearch: false, controller: SuperUserAdminCtrl, newLayout: true}).
|
||||
when('/setup/', {title: 'Enterprise Registry Setup', description:'Setup for ' + title, templateUrl: '/static/partials/setup.html',
|
||||
reloadOnSearch: false, controller: SetupCtrl, newLayout: true}).
|
||||
when('/guide/', {title: 'Guide', description:'Guide to using private docker repositories on ' + title,
|
||||
templateUrl: '/static/partials/guide.html',
|
||||
controller: GuideCtrl}).
|
||||
|
@ -3908,9 +3979,11 @@ quayApp.directive('registryName', function () {
|
|||
replace: false,
|
||||
transclude: true,
|
||||
restrict: 'C',
|
||||
scope: {},
|
||||
scope: {
|
||||
'isShort': '=isShort'
|
||||
},
|
||||
controller: function($scope, $element, Config) {
|
||||
$scope.name = Config.REGISTRY_TITLE;
|
||||
$scope.name = $scope.isShort ? Config.REGISTRY_TITLE_SHORT : Config.REGISTRY_TITLE;
|
||||
}
|
||||
};
|
||||
return directiveDefinitionObject;
|
||||
|
@ -5751,9 +5824,15 @@ quayApp.directive('buildMessage', function () {
|
|||
case 'building':
|
||||
return 'Building image from Dockerfile';
|
||||
|
||||
case 'checking-cache':
|
||||
return 'Looking up cached images';
|
||||
|
||||
case 'priming-cache':
|
||||
return 'Priming cache for build';
|
||||
|
||||
case 'build-scheduled':
|
||||
return 'Preparing build node';
|
||||
|
||||
case 'pushing':
|
||||
return 'Pushing image built from Dockerfile';
|
||||
|
||||
|
@ -5807,6 +5886,7 @@ quayApp.directive('buildProgress', function () {
|
|||
break;
|
||||
|
||||
case 'initializing':
|
||||
case 'checking-cache':
|
||||
case 'starting':
|
||||
case 'waiting':
|
||||
case 'cannot_load':
|
||||
|
@ -6899,6 +6979,7 @@ quayApp.directive('ngBlur', function() {
|
|||
};
|
||||
});
|
||||
|
||||
|
||||
quayApp.directive("filePresent", [function () {
|
||||
return {
|
||||
restrict: 'A',
|
||||
|
@ -6972,7 +7053,6 @@ quayApp.run(['$location', '$rootScope', 'Restangular', 'UserService', 'PlanServi
|
|||
|
||||
var changeTab = function(activeTab, opt_timeout) {
|
||||
var checkCount = 0;
|
||||
|
||||
$timeout(function() {
|
||||
if (checkCount > 5) { return; }
|
||||
checkCount++;
|
||||
|
@ -7036,6 +7116,8 @@ quayApp.run(['$location', '$rootScope', 'Restangular', 'UserService', 'PlanServi
|
|||
$rootScope.pageClass = current.$$route.pageClass;
|
||||
}
|
||||
|
||||
$rootScope.newLayout = !!current.$$route.newLayout;
|
||||
|
||||
if (current.$$route.description) {
|
||||
$rootScope.description = current.$$route.description;
|
||||
} else {
|
||||
|
@ -7051,26 +7133,28 @@ quayApp.run(['$location', '$rootScope', 'Restangular', 'UserService', 'PlanServi
|
|||
|
||||
// Setup deep linking of tabs. This will change the search field of the URL whenever a tab
|
||||
// is changed in the UI.
|
||||
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
|
||||
var tabName = e.target.getAttribute('data-target').substr(1);
|
||||
$rootScope.$apply(function() {
|
||||
var isDefaultTab = $('a[data-toggle="tab"]')[0] == e.target;
|
||||
var newSearch = $.extend($location.search(), {});
|
||||
if (isDefaultTab) {
|
||||
delete newSearch['tab'];
|
||||
} else {
|
||||
newSearch['tab'] = tabName;
|
||||
}
|
||||
$timeout(function() {
|
||||
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
|
||||
var tabName = e.target.getAttribute('data-target').substr(1);
|
||||
$rootScope.$apply(function() {
|
||||
var isDefaultTab = $('a[data-toggle="tab"]')[0] == e.target;
|
||||
var newSearch = $.extend($location.search(), {});
|
||||
if (isDefaultTab) {
|
||||
delete newSearch['tab'];
|
||||
} else {
|
||||
newSearch['tab'] = tabName;
|
||||
}
|
||||
|
||||
$location.search(newSearch);
|
||||
$location.search(newSearch);
|
||||
});
|
||||
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
if (activeTab) {
|
||||
changeTab(activeTab);
|
||||
}
|
||||
if (activeTab) {
|
||||
changeTab(activeTab);
|
||||
}
|
||||
}, 400); // 400ms to make sure angular has rendered.
|
||||
});
|
||||
|
||||
var initallyChecked = false;
|
||||
|
|
Reference in a new issue