Merge remote-tracking branch 'origin/master' into nomenclature
Conflicts: endpoints/common.py endpoints/notificationhelper.py test/data/test.db workers/dockerfilebuild.py
This commit is contained in:
commit
1461310ab8
200 changed files with 240935 additions and 798 deletions
372
static/js/app.js
372
static/js/app.js
|
@ -2989,6 +2989,28 @@ quayApp.directive('dockerAuthDialog', function (Config) {
|
|||
});
|
||||
|
||||
|
||||
quayApp.filter('regex', function() {
|
||||
return function(input, regex) {
|
||||
if (!regex) { return []; }
|
||||
|
||||
try {
|
||||
var patt = new RegExp(regex);
|
||||
} catch (ex) {
|
||||
return [];
|
||||
}
|
||||
|
||||
var out = [];
|
||||
for (var i = 0; i < input.length; ++i){
|
||||
var m = input[i].match(patt);
|
||||
if (m && m[0].length == input[i].length) {
|
||||
out.push(input[i]);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
quayApp.filter('reverse', function() {
|
||||
return function(items) {
|
||||
return items.slice().reverse();
|
||||
|
@ -4745,6 +4767,118 @@ quayApp.directive('triggerDescription', function () {
|
|||
});
|
||||
|
||||
|
||||
quayApp.directive('stepView', function ($compile) {
|
||||
var directiveDefinitionObject = {
|
||||
priority: 0,
|
||||
templateUrl: '/static/directives/step-view.html',
|
||||
replace: true,
|
||||
transclude: true,
|
||||
restrict: 'C',
|
||||
scope: {
|
||||
'nextStepCounter': '=nextStepCounter',
|
||||
'currentStepValid': '=currentStepValid',
|
||||
|
||||
'stepsCompleted': '&stepsCompleted'
|
||||
},
|
||||
controller: function($scope, $element, $rootScope) {
|
||||
this.currentStepIndex = -1;
|
||||
this.steps = [];
|
||||
this.watcher = null;
|
||||
|
||||
this.getCurrentStep = function() {
|
||||
return this.steps[this.currentStepIndex];
|
||||
};
|
||||
|
||||
this.reset = function() {
|
||||
this.currentStepIndex = -1;
|
||||
for (var i = 0; i < this.steps.length; ++i) {
|
||||
this.steps[i].element.hide();
|
||||
}
|
||||
|
||||
$scope.currentStepValid = false;
|
||||
};
|
||||
|
||||
this.next = function() {
|
||||
if (this.currentStepIndex >= 0) {
|
||||
if (!this.getCurrentStep().scope.completeCondition) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.getCurrentStep().element.hide();
|
||||
|
||||
if (this.unwatch) {
|
||||
this.unwatch();
|
||||
this.unwatch = null;
|
||||
}
|
||||
}
|
||||
|
||||
this.currentStepIndex++;
|
||||
|
||||
if (this.currentStepIndex < this.steps.length) {
|
||||
var currentStep = this.getCurrentStep();
|
||||
currentStep.element.show();
|
||||
currentStep.scope.load()
|
||||
|
||||
this.unwatch = currentStep.scope.$watch('completeCondition', function(cc) {
|
||||
$scope.currentStepValid = !!cc;
|
||||
});
|
||||
} else {
|
||||
$scope.stepsCompleted();
|
||||
}
|
||||
};
|
||||
|
||||
this.register = function(scope, element) {
|
||||
element.hide();
|
||||
|
||||
this.steps.push({
|
||||
'scope': scope,
|
||||
'element': element
|
||||
});
|
||||
};
|
||||
|
||||
var that = this;
|
||||
$scope.$watch('nextStepCounter', function(nsc) {
|
||||
if (nsc >= 0) {
|
||||
that.next();
|
||||
} else {
|
||||
that.reset();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
return directiveDefinitionObject;
|
||||
});
|
||||
|
||||
|
||||
quayApp.directive('stepViewStep', function () {
|
||||
var directiveDefinitionObject = {
|
||||
priority: 1,
|
||||
require: '^stepView',
|
||||
templateUrl: '/static/directives/step-view-step.html',
|
||||
replace: false,
|
||||
transclude: true,
|
||||
restrict: 'C',
|
||||
scope: {
|
||||
'completeCondition': '=completeCondition',
|
||||
'loadCallback': '&loadCallback',
|
||||
'loadMessage': '@loadMessage'
|
||||
},
|
||||
link: function(scope, element, attrs, controller) {
|
||||
controller.register(scope, element);
|
||||
},
|
||||
controller: function($scope, $element) {
|
||||
$scope.load = function() {
|
||||
$scope.loading = true;
|
||||
$scope.loadCallback({'callback': function() {
|
||||
$scope.loading = false;
|
||||
}});
|
||||
};
|
||||
}
|
||||
};
|
||||
return directiveDefinitionObject;
|
||||
});
|
||||
|
||||
|
||||
quayApp.directive('dropdownSelect', function ($compile) {
|
||||
var directiveDefinitionObject = {
|
||||
priority: 0,
|
||||
|
@ -4987,25 +5121,28 @@ quayApp.directive('setupTriggerDialog', function () {
|
|||
controller: function($scope, $element, ApiService, UserService) {
|
||||
var modalSetup = false;
|
||||
|
||||
$scope.state = {};
|
||||
$scope.nextStepCounter = -1;
|
||||
$scope.currentView = 'config';
|
||||
|
||||
$scope.show = function() {
|
||||
if (!$scope.trigger || !$scope.repository) { return; }
|
||||
|
||||
$scope.activating = false;
|
||||
$scope.pullEntity = null;
|
||||
$scope.publicPull = true;
|
||||
$scope.showPullRequirements = false;
|
||||
|
||||
$scope.currentView = 'config';
|
||||
$('#setupTriggerModal').modal({});
|
||||
|
||||
if (!modalSetup) {
|
||||
$('#setupTriggerModal').on('hidden.bs.modal', function () {
|
||||
if (!$scope.trigger || $scope.trigger['is_active']) { return; }
|
||||
|
||||
$scope.nextStepCounter = -1;
|
||||
$scope.$apply(function() {
|
||||
$scope.cancelSetupTrigger();
|
||||
});
|
||||
});
|
||||
|
||||
modalSetup = true;
|
||||
$scope.nextStepCounter = 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -5018,27 +5155,20 @@ quayApp.directive('setupTriggerDialog', function () {
|
|||
};
|
||||
|
||||
$scope.hide = function() {
|
||||
$scope.activating = false;
|
||||
$('#setupTriggerModal').modal('hide');
|
||||
};
|
||||
|
||||
$scope.setPublicPull = function(value) {
|
||||
$scope.publicPull = value;
|
||||
};
|
||||
|
||||
$scope.checkAnalyze = function(isValid) {
|
||||
$scope.currentView = 'analyzing';
|
||||
$scope.pullInfo = {
|
||||
'is_public': true
|
||||
};
|
||||
|
||||
if (!isValid) {
|
||||
$scope.publicPull = true;
|
||||
$scope.pullEntity = null;
|
||||
$scope.showPullRequirements = false;
|
||||
$scope.checkingPullRequirements = false;
|
||||
$scope.currentView = 'analyzed';
|
||||
return;
|
||||
}
|
||||
|
||||
$scope.checkingPullRequirements = true;
|
||||
$scope.showPullRequirements = true;
|
||||
$scope.pullRequirements = null;
|
||||
|
||||
var params = {
|
||||
'repository': $scope.repository.namespace + '/' + $scope.repository.name,
|
||||
'trigger_uuid': $scope.trigger.id
|
||||
|
@ -5049,26 +5179,20 @@ quayApp.directive('setupTriggerDialog', function () {
|
|||
};
|
||||
|
||||
ApiService.analyzeBuildTrigger(data, params).then(function(resp) {
|
||||
$scope.pullRequirements = resp;
|
||||
|
||||
if (resp['status'] == 'publicbase') {
|
||||
$scope.publicPull = true;
|
||||
$scope.pullEntity = null;
|
||||
} else if (resp['namespace']) {
|
||||
$scope.publicPull = false;
|
||||
$scope.currentView = 'analyzed';
|
||||
|
||||
if (resp['status'] == 'analyzed') {
|
||||
if (resp['robots'] && resp['robots'].length > 0) {
|
||||
$scope.pullEntity = resp['robots'][0];
|
||||
} else {
|
||||
$scope.pullEntity = null;
|
||||
$scope.pullInfo['pull_entity'] = resp['robots'][0];
|
||||
} else {
|
||||
$scope.pullInfo['pull_entity'] = null;
|
||||
}
|
||||
|
||||
$scope.pullInfo['is_public'] = false;
|
||||
}
|
||||
|
||||
$scope.checkingPullRequirements = false;
|
||||
}, function(resp) {
|
||||
$scope.pullRequirements = resp;
|
||||
$scope.checkingPullRequirements = false;
|
||||
});
|
||||
$scope.pullInfo['analysis'] = resp;
|
||||
}, ApiService.errorDisplay('Cannot load Dockerfile information'));
|
||||
};
|
||||
|
||||
$scope.activate = function() {
|
||||
|
@ -5081,11 +5205,11 @@ quayApp.directive('setupTriggerDialog', function () {
|
|||
'config': $scope.trigger['config']
|
||||
};
|
||||
|
||||
if ($scope.pullEntity) {
|
||||
data['pull_robot'] = $scope.pullEntity['name'];
|
||||
if ($scope.pullInfo['pull_entity']) {
|
||||
data['pull_robot'] = $scope.pullInfo['pull_entity']['name'];
|
||||
}
|
||||
|
||||
$scope.activating = true;
|
||||
$scope.currentView = 'activating';
|
||||
|
||||
var errorHandler = ApiService.errorDisplay('Cannot activate build trigger', function(resp) {
|
||||
$scope.hide();
|
||||
|
@ -5126,17 +5250,99 @@ quayApp.directive('triggerSetupGithub', function () {
|
|||
scope: {
|
||||
'repository': '=repository',
|
||||
'trigger': '=trigger',
|
||||
|
||||
'nextStepCounter': '=nextStepCounter',
|
||||
'currentStepValid': '=currentStepValid',
|
||||
|
||||
'analyze': '&analyze'
|
||||
},
|
||||
controller: function($scope, $element, ApiService) {
|
||||
$scope.analyzeCounter = 0;
|
||||
$scope.setupReady = false;
|
||||
$scope.loading = true;
|
||||
|
||||
$scope.branchNames = null;
|
||||
|
||||
$scope.state = {
|
||||
'branchFilter': '',
|
||||
'hasBranchFilter': false,
|
||||
'isInvalidLocation': true,
|
||||
'currentLocation': null
|
||||
};
|
||||
|
||||
$scope.isMatchingBranch = function(branchName, filter) {
|
||||
try {
|
||||
var patt = new RegExp(filter);
|
||||
} catch (ex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var m = branchName.match(patt);
|
||||
return m && m[0].length == branchName.length;
|
||||
}
|
||||
|
||||
$scope.stepsCompleted = function() {
|
||||
$scope.analyze({'isValid': !$scope.state.isInvalidLocation});
|
||||
};
|
||||
|
||||
$scope.loadRepositories = function(callback) {
|
||||
var params = {
|
||||
'repository': $scope.repository.namespace + '/' + $scope.repository.name,
|
||||
'trigger_uuid': $scope.trigger.id
|
||||
};
|
||||
|
||||
ApiService.listTriggerBuildSources(null, params).then(function(resp) {
|
||||
$scope.orgs = resp['sources'];
|
||||
setupTypeahead();
|
||||
callback();
|
||||
}, ApiService.errorDisplay('Cannot load repositories'));
|
||||
};
|
||||
|
||||
$scope.loadBranches = function(callback) {
|
||||
var params = {
|
||||
'repository': $scope.repository.namespace + '/' + $scope.repository.name,
|
||||
'trigger_uuid': $scope.trigger['id'],
|
||||
'field_name': 'branch_name'
|
||||
};
|
||||
|
||||
ApiService.listTriggerFieldValues($scope.trigger['config'], params).then(function(resp) {
|
||||
$scope.branchNames = resp['values'];
|
||||
callback();
|
||||
}, ApiService.errorDisplay('Cannot load branch names'));
|
||||
};
|
||||
|
||||
$scope.loadLocations = function(callback) {
|
||||
$scope.locations = null;
|
||||
|
||||
var params = {
|
||||
'repository': $scope.repository.namespace + '/' + $scope.repository.name,
|
||||
'trigger_uuid': $scope.trigger.id
|
||||
};
|
||||
|
||||
ApiService.listBuildTriggerSubdirs($scope.trigger['config'], params).then(function(resp) {
|
||||
if (resp['status'] == 'error') {
|
||||
callback(resp['message'] || 'Could not load Dockerfile locations');
|
||||
return;
|
||||
}
|
||||
|
||||
$scope.locations = resp['subdir'] || [];
|
||||
|
||||
// Select a default location (if any).
|
||||
if ($scope.locations.length > 0) {
|
||||
$scope.setLocation($scope.locations[0]);
|
||||
} else {
|
||||
$scope.state.currentLocation = null;
|
||||
$scope.state.isInvalidLocation = resp['subdir'].indexOf('') < 0;
|
||||
$scope.trigger.$ready = true;
|
||||
}
|
||||
|
||||
callback();
|
||||
}, ApiService.errorDisplay('Cannot load locations'));
|
||||
}
|
||||
|
||||
$scope.handleLocationInput = function(location) {
|
||||
$scope.state.isInvalidLocation = $scope.locations.indexOf(location) < 0;
|
||||
$scope.trigger['config']['subdir'] = location || '';
|
||||
$scope.isInvalidLocation = $scope.locations.indexOf(location) < 0;
|
||||
$scope.analyze({'isValid': !$scope.isInvalidLocation});
|
||||
$scope.trigger.$ready = true;
|
||||
};
|
||||
|
||||
$scope.handleLocationSelected = function(datum) {
|
||||
|
@ -5144,10 +5350,10 @@ quayApp.directive('triggerSetupGithub', function () {
|
|||
};
|
||||
|
||||
$scope.setLocation = function(location) {
|
||||
$scope.currentLocation = location;
|
||||
$scope.state.currentLocation = location;
|
||||
$scope.state.isInvalidLocation = false;
|
||||
$scope.trigger['config']['subdir'] = location || '';
|
||||
$scope.isInvalidLocation = false;
|
||||
$scope.analyze({'isValid': true});
|
||||
$scope.trigger.$ready = true;
|
||||
};
|
||||
|
||||
$scope.selectRepo = function(repo, org) {
|
||||
|
@ -5161,10 +5367,7 @@ quayApp.directive('triggerSetupGithub', function () {
|
|||
};
|
||||
|
||||
$scope.selectRepoInternal = function(currentRepo) {
|
||||
if (!currentRepo) {
|
||||
$scope.trigger.$ready = false;
|
||||
return;
|
||||
}
|
||||
$scope.trigger.$ready = false;
|
||||
|
||||
var params = {
|
||||
'repository': $scope.repository.namespace + '/' + $scope.repository.name,
|
||||
|
@ -5176,39 +5379,6 @@ quayApp.directive('triggerSetupGithub', function () {
|
|||
'build_source': repo,
|
||||
'subdir': ''
|
||||
};
|
||||
|
||||
// Lookup the possible Dockerfile locations.
|
||||
$scope.locations = null;
|
||||
if (repo) {
|
||||
ApiService.listBuildTriggerSubdirs($scope.trigger['config'], params).then(function(resp) {
|
||||
if (resp['status'] == 'error') {
|
||||
$scope.locationError = resp['message'] || 'Could not load Dockerfile locations';
|
||||
$scope.locations = null;
|
||||
$scope.trigger.$ready = false;
|
||||
$scope.isInvalidLocation = false;
|
||||
$scope.analyze({'isValid': false});
|
||||
return;
|
||||
}
|
||||
|
||||
$scope.locationError = null;
|
||||
$scope.locations = resp['subdir'] || [];
|
||||
$scope.trigger.$ready = true;
|
||||
|
||||
if ($scope.locations.length > 0) {
|
||||
$scope.setLocation($scope.locations[0]);
|
||||
} else {
|
||||
$scope.currentLocation = null;
|
||||
$scope.isInvalidLocation = resp['subdir'].indexOf('') < 0;
|
||||
$scope.analyze({'isValid': !$scope.isInvalidLocation});
|
||||
}
|
||||
}, function(resp) {
|
||||
$scope.locationError = resp['message'] || 'Could not load Dockerfile locations';
|
||||
$scope.locations = null;
|
||||
$scope.trigger.$ready = false;
|
||||
$scope.isInvalidLocation = false;
|
||||
$scope.analyze({'isValid': false});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
var setupTypeahead = function() {
|
||||
|
@ -5238,30 +5408,20 @@ quayApp.directive('triggerSetupGithub', function () {
|
|||
$scope.repoLookahead = repos;
|
||||
};
|
||||
|
||||
var loadSources = function() {
|
||||
var params = {
|
||||
'repository': $scope.repository.namespace + '/' + $scope.repository.name,
|
||||
'trigger_uuid': $scope.trigger.id
|
||||
};
|
||||
|
||||
ApiService.listTriggerBuildSources(null, params).then(function(resp) {
|
||||
$scope.orgs = resp['sources'];
|
||||
setupTypeahead();
|
||||
$scope.loading = false;
|
||||
});
|
||||
};
|
||||
|
||||
var check = function() {
|
||||
if ($scope.repository && $scope.trigger) {
|
||||
loadSources();
|
||||
}
|
||||
};
|
||||
|
||||
$scope.$watch('repository', check);
|
||||
$scope.$watch('trigger', check);
|
||||
|
||||
$scope.$watch('currentRepo', function(repo) {
|
||||
$scope.selectRepoInternal(repo);
|
||||
if (repo) {
|
||||
$scope.selectRepoInternal(repo);
|
||||
}
|
||||
});
|
||||
|
||||
$scope.$watch('state.branchFilter', function(bf) {
|
||||
if (!$scope.trigger) { return; }
|
||||
|
||||
if ($scope.state.hasBranchFilter) {
|
||||
$scope.trigger['config']['branch_regex'] = bf;
|
||||
} else {
|
||||
delete $scope.trigger['config']['branch_regex'];
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -6315,6 +6475,14 @@ quayApp.directive('ngVisible', function () {
|
|||
};
|
||||
});
|
||||
|
||||
quayApp.config( [
|
||||
'$compileProvider',
|
||||
function( $compileProvider )
|
||||
{
|
||||
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|tel|irc):/);
|
||||
}
|
||||
]);
|
||||
|
||||
quayApp.run(['$location', '$rootScope', 'Restangular', 'UserService', 'PlanService', '$http', '$timeout', 'CookieService', 'Features', '$anchorScroll',
|
||||
function($location, $rootScope, Restangular, UserService, PlanService, $http, $timeout, CookieService, Features, $anchorScroll) {
|
||||
|
||||
|
|
Reference in a new issue