diff --git a/assets/app/scripts/controllers/overview.js b/assets/app/scripts/controllers/overview.js
index 3be09fff59b0..4a385d9790c1 100644
--- a/assets/app/scripts/controllers/overview.js
+++ b/assets/app/scripts/controllers/overview.js
@@ -20,7 +20,9 @@ angular.module('openshiftConsole')
Logger,
ImageStreamResolver,
ObjectDescriber,
- $parse) {
+ $parse,
+ $filter,
+ $interval) {
$scope.pods = {};
$scope.services = {};
$scope.routes = {};
@@ -56,6 +58,8 @@ angular.module('openshiftConsole')
// "" service key for deployment configs not under any service
$scope.deploymentConfigsByService = {};
+ $scope.recentBuildsByOutputImage = {};
+
$scope.labelSuggestions = {};
$scope.alerts = $scope.alerts || {};
$scope.emptyMessage = "Loading...";
@@ -82,6 +86,7 @@ angular.module('openshiftConsole')
$scope.topologyItems = { };
$scope.topologyRelations = [ ];
+ var intervals = [];
var watches = [];
watches.push(DataService.watch("pods", $scope, function(pods) {
@@ -311,49 +316,9 @@ angular.module('openshiftConsole')
Logger.log("imagestreams (subscribe)", $scope.imageStreams);
}));
- function associateDeploymentConfigTriggersToBuild(deploymentConfig, build) {
- // Make sure we have both a deploymentConfig and a build
- if (!deploymentConfig || !build) {
- return;
- }
- // Make sure the deployment config has triggers.
- if (!deploymentConfig.spec.triggers) {
- return;
- }
- // Make sure we have a build output
- if (!build.spec.output.to) {
- return;
- }
- for (var i = 0; i < deploymentConfig.spec.triggers.length; i++) {
- var trigger = deploymentConfig.spec.triggers[i];
- if (trigger.type === "ImageChange") {
- var buildOutputImage = imageObjectRefFilter(build.spec.output.to, build.metadata.namespace);
- var deploymentTriggerImage = imageObjectRefFilter(trigger.imageChangeParams.from, deploymentConfig.metadata.namespace);
- if (buildOutputImage !== deploymentTriggerImage) {
- continue;
- }
-
- trigger.builds = trigger.builds || {};
- trigger.builds[build.metadata.name] = build;
- }
- }
- }
-
// Sets up subscription for deploymentConfigs, associates builds to triggers on deploymentConfigs
- watches.push(DataService.watch("deploymentconfigs", $scope, function(deploymentConfigs, action, deploymentConfig) {
+ watches.push(DataService.watch("deploymentconfigs", $scope, function(deploymentConfigs) {
$scope.deploymentConfigs = deploymentConfigs.by("metadata.name");
- if (!action) {
- angular.forEach($scope.deploymentConfigs, function(depConfig) {
- angular.forEach($scope.builds, function(build) {
- associateDeploymentConfigTriggersToBuild(depConfig, build);
- });
- });
- }
- else if (action !== 'DELETED') {
- angular.forEach($scope.builds, function(build) {
- associateDeploymentConfigTriggersToBuild(deploymentConfig, build);
- });
- }
deploymentConfigsByService();
// Must be called after deploymentConfigsByService()
@@ -363,24 +328,25 @@ angular.module('openshiftConsole')
Logger.log("deploymentconfigs (subscribe)", $scope.deploymentConfigs);
}));
+ function updateRecentBuildsByOutputImage() {
+ $scope.recentBuildsByOutputImage = {};
+ angular.forEach($scope.builds, function(build) {
+ // pre-filter the list to save us some time on each digest loop later
+ if ($filter('isRecentBuild')(build) || $filter('isOscActiveObject')(build)) {
+ var buildOutputImage = imageObjectRefFilter(build.spec.output.to, build.metadata.namespace);
+ $scope.recentBuildsByOutputImage[buildOutputImage] = $scope.recentBuildsByOutputImage[buildOutputImage] || [];
+ $scope.recentBuildsByOutputImage[buildOutputImage].push(build);
+ }
+ });
+ }
+
// Sets up subscription for builds, associates builds to triggers on deploymentConfigs
- watches.push(DataService.watch("builds", $scope, function(builds, action, build) {
+ watches.push(DataService.watch("builds", $scope, function(builds) {
$scope.builds = builds.by("metadata.name");
- if (!action) {
- angular.forEach($scope.builds, function(bld) {
- angular.forEach($scope.deploymentConfigs, function(depConfig) {
- associateDeploymentConfigTriggersToBuild(depConfig, bld);
- });
- });
- }
- else if (action === 'ADDED' || action === 'MODIFIED') {
- angular.forEach($scope.deploymentConfigs, function(depConfig) {
- associateDeploymentConfigTriggersToBuild(depConfig, build);
- });
- }
- else if (action === 'DELETED'){
- // TODO
- }
+ updateRecentBuildsByOutputImage();
+
+ intervals.push($interval(updateRecentBuildsByOutputImage, 5 * 60 * 1000)); // prune the list every 5 minutes
+
updateTopologyLater();
Logger.log("builds (subscribe)", $scope.builds);
}));
@@ -543,5 +509,8 @@ angular.module('openshiftConsole')
DataService.unwatchAll(watches);
window.clearTimeout(updateTimeout);
ObjectDescriber.removeResourceChangedCallback(selectionChanged);
+ angular.forEach(intervals, function (interval){
+ $interval.cancel(interval);
+ });
});
});
diff --git a/assets/app/scripts/directives/resources.js b/assets/app/scripts/directives/resources.js
index 5c6afbed0c6b..12deefecf88b 100644
--- a/assets/app/scripts/directives/resources.js
+++ b/assets/app/scripts/directives/resources.js
@@ -83,7 +83,9 @@ angular.module('openshiftConsole')
return {
restrict: 'E',
scope: {
- triggers: '='
+ triggers: '=',
+ buildsByOutputImage: '=',
+ namespace: '='
},
link: function(scope) {
scope.isBuildHidden = function(build) {
diff --git a/assets/app/styles/_core.less b/assets/app/styles/_core.less
index c79bb651b985..ac9e53a40afc 100644
--- a/assets/app/styles/_core.less
+++ b/assets/app/styles/_core.less
@@ -777,3 +777,7 @@ labels + .resource-details {
h1 small.meta {
font-size: 12px;
}
+
+.action-divider {
+ color: @gray-light;
+}
\ No newline at end of file
diff --git a/assets/app/views/_triggers.html b/assets/app/views/_triggers.html
index 4a9bec84ed01..ce534a54f37f 100644
--- a/assets/app/views/_triggers.html
+++ b/assets/app/views/_triggers.html
@@ -1,47 +1,43 @@
diff --git a/assets/app/views/project.html b/assets/app/views/project.html
index 1c2f6d483e88..9772763f0590 100644
--- a/assets/app/views/project.html
+++ b/assets/app/views/project.html
@@ -145,7 +145,7 @@
Pods in deployments created from this deployment config will be routed to by this service.
Show things related to triggers that are about to create stuff, like builds.
-->
-
+
-
+
Pods in deployments created from this deployment config will not be routed to by any service.
Show things related to triggers that are about to create stuff, like builds.
-->
-
+
diff --git a/pkg/assets/bindata.go b/pkg/assets/bindata.go
index c72b5b5712fd..0e76e50f11bc 100644
--- a/pkg/assets/bindata.go
+++ b/pkg/assets/bindata.go
@@ -3106,8 +3106,8 @@ a.state && a.state.running && b++;
}, a.$on("$destroy", function() {
d.unwatchAll(i);
});
-} ]), angular.module("openshiftConsole").controller("OverviewController", [ "$scope", "DataService", "annotationFilter", "hashSizeFilter", "imageObjectRefFilter", "deploymentCausesFilter", "labelFilter", "LabelFilter", "Logger", "ImageStreamResolver", "ObjectDescriber", "$parse", function(a, b, c, d, e, f, g, h, i, j, k, l) {
-function m() {
+} ]), angular.module("openshiftConsole").controller("OverviewController", [ "$scope", "DataService", "annotationFilter", "hashSizeFilter", "imageObjectRefFilter", "deploymentCausesFilter", "labelFilter", "LabelFilter", "Logger", "ImageStreamResolver", "ObjectDescriber", "$parse", "$filter", "$interval", function(a, b, c, d, e, f, g, h, i, j, k, l, m, n) {
+function o() {
a.monopodsByService = {
"":{}
}, a.podsByService = {}, a.podsByDeployment = {};
@@ -3132,13 +3132,13 @@ angular.forEach(f, function(b) {
j = j || a.deploymentsByService[h] && a.deploymentsByService[h][b];
}), j || (a.monopodsByService[h] = a.monopodsByService[h] || {}, a.monopodsByService[h][e] = d);
}
-}), 0 === f.length && 0 === g.length && n(d) && (a.monopodsByService[""][e] = d);
-}), i.log("podsByDeployment", a.podsByDeployment), i.log("podsByService", a.podsByService), i.log("monopodsByService", a.monopodsByService), v();
+}), 0 === f.length && 0 === g.length && p(d) && (a.monopodsByService[""][e] = d);
+}), i.log("podsByDeployment", a.podsByDeployment), i.log("podsByService", a.podsByService), i.log("monopodsByService", a.monopodsByService), x();
}
-function n(a) {
+function p(a) {
return "Succeeded" === a.status.phase || "Terminated" === a.status.phase || "Failed" === a.status.phase ? !1 :g(a, "openshift.io/deployer-pod-for.name") ? !1 :c(a, "openshift.io/build.name") ? !1 :!0;
}
-function o() {
+function q() {
a.deploymentConfigsByService = {
"":{}
}, angular.forEach(a.deploymentConfigs, function(b, c) {
@@ -3150,7 +3150,7 @@ h.covers(f) && (a.deploymentConfigsByService[g][c] = b, d = !0);
}), d || (a.deploymentConfigsByService[""][c] = b);
});
}
-function p() {
+function r() {
var b = a.deploymentsByService = {
"":{}
}, d = a.deploymentsByServiceByDeploymentConfig = {
@@ -3165,34 +3165,32 @@ h.covers(i) && (b[c][f] = e, d[c][j] = d[c][j] || {}, d[c][j][f] = e, g = !0);
}), g || (b[""][f] = e, d[""][j] = d[""][j] || {}, d[""][j][f] = e);
});
}
-function q(a, b) {
-if (a && b && a.spec.triggers && b.spec.output.to) for (var c = 0; c < a.spec.triggers.length; c++) {
-var d = a.spec.triggers[c];
-if ("ImageChange" === d.type) {
-var f = e(b.spec.output.to, b.metadata.namespace), g = e(d.imageChangeParams.from, a.metadata.namespace);
-if (f !== g) continue;
-d.builds = d.builds || {}, d.builds[b.metadata.name] = b;
-}
+function s() {
+a.recentBuildsByOutputImage = {}, angular.forEach(a.builds, function(b) {
+if (m("isRecentBuild")(b) || m("isOscActiveObject")(b)) {
+var c = e(b.spec.output.to, b.metadata.namespace);
+a.recentBuildsByOutputImage[c] = a.recentBuildsByOutputImage[c] || [], a.recentBuildsByOutputImage[c].push(b);
}
+});
}
-function r() {
+function t() {
var b = 0 === d(a.unfilteredServices) && 0 === d(a.pods) && 0 === d(a.deployments) && 0 === d(a.deploymentConfigs);
a.renderOptions.showSidebarRight = !b, a.renderOptions.showGetStarted = b;
}
-function s() {
+function u() {
h.getLabelSelector().isEmpty() || !$.isEmptyObject(a.services) || $.isEmptyObject(a.unfilteredServices) ? delete a.alerts.services :a.alerts.services = {
type:"warning",
details:"The active filters are hiding all services."
};
}
-function t(a) {
+function v(a) {
return "true" === c(a, "openshift.io/host.generated");
}
-function u() {
+function w() {
function b(a) {
return a.kind + a.metadata.uid;
}
-y = null;
+B = null;
var c = [], d = {};
angular.forEach(a.services, function(a) {
d[b(a)] = a;
@@ -3200,7 +3198,7 @@ d[b(a)] = a;
angular.forEach(c, function(e, f) {
var g = a.services[f];
(!f || g) && angular.forEach(e, function(e) {
-(c !== a.monopodsByService || n(e)) && (d[b(e)] = e);
+(c !== a.monopodsByService || p(e)) && (d[b(e)] = e);
});
});
}), [ a.podsByService, a.monopodsByService, a.routesByService ].forEach(function(d) {
@@ -3231,69 +3229,59 @@ target:b(d)
a.topologyItems = d, a.topologyRelations = c;
});
}
-function v() {
-y || (y = window.setTimeout(u, 100));
+function x() {
+B || (B = window.setTimeout(w, 100));
}
-function w(b) {
+function y(b) {
a.topologySelection = b;
}
-a.pods = {}, a.services = {}, a.routes = {}, a.routesByService = {}, a.displayRouteByService = {}, a.unfilteredServices = {}, a.deployments = {}, a.deploymentConfigs = void 0, a.builds = {}, a.imageStreams = {}, a.imagesByDockerReference = {}, a.imageStreamImageRefByDockerReference = {}, a.podsByService = {}, a.podsByDeployment = {}, a.monopodsByService = {}, a.deploymentsByServiceByDeploymentConfig = {}, a.deploymentsByService = {}, a.deploymentConfigsByService = {}, a.labelSuggestions = {}, a.alerts = a.alerts || {}, a.emptyMessage = "Loading...", a.renderOptions = a.renderOptions || {}, a.renderOptions.showSidebarRight = !1, a.topologyKinds = {
+a.pods = {}, a.services = {}, a.routes = {}, a.routesByService = {}, a.displayRouteByService = {}, a.unfilteredServices = {}, a.deployments = {}, a.deploymentConfigs = void 0, a.builds = {}, a.imageStreams = {}, a.imagesByDockerReference = {}, a.imageStreamImageRefByDockerReference = {}, a.podsByService = {}, a.podsByDeployment = {}, a.monopodsByService = {}, a.deploymentsByServiceByDeploymentConfig = {}, a.deploymentsByService = {}, a.deploymentConfigsByService = {}, a.recentBuildsByOutputImage = {}, a.labelSuggestions = {}, a.alerts = a.alerts || {}, a.emptyMessage = "Loading...", a.renderOptions = a.renderOptions || {}, a.renderOptions.showSidebarRight = !1, a.topologyKinds = {
DeploymentConfig:location.href + "#vertex-DeploymentConfig",
Pod:location.href + "#vertex-Pod",
ReplicationController:location.href + "#vertex-ReplicationController",
Route:location.href + "#vertex-Route",
Service:location.href + "#vertex-Service"
}, a.topologySelection = null, a.topologyItems = {}, a.topologyRelations = [];
-var x = [];
-x.push(b.watch("pods", a, function(b) {
-a.pods = b.by("metadata.name"), m(), r(), j.fetchReferencedImageStreamImages(a.pods, a.imagesByDockerReference, a.imageStreamImageRefByDockerReference, a), v(), i.log("pods", a.pods);
-})), x.push(b.watch("services", a, function(b) {
-a.unfilteredServices = b.by("metadata.name"), h.addLabelSuggestionsFromResources(a.unfilteredServices, a.labelSuggestions), h.setLabelSuggestions(a.labelSuggestions), a.services = h.getLabelSelector().select(a.unfilteredServices), p(), o(), m(), r(), a.emptyMessage = "No services to show", s(), v(), i.log("services (list)", a.services);
-})), x.push(b.watch("routes", a, function(b) {
+var z = [], A = [];
+A.push(b.watch("pods", a, function(b) {
+a.pods = b.by("metadata.name"), o(), t(), j.fetchReferencedImageStreamImages(a.pods, a.imagesByDockerReference, a.imageStreamImageRefByDockerReference, a), x(), i.log("pods", a.pods);
+})), A.push(b.watch("services", a, function(b) {
+a.unfilteredServices = b.by("metadata.name"), h.addLabelSuggestionsFromResources(a.unfilteredServices, a.labelSuggestions), h.setLabelSuggestions(a.labelSuggestions), a.services = h.getLabelSelector().select(a.unfilteredServices), r(), q(), o(), t(), a.emptyMessage = "No services to show", u(), x(), i.log("services (list)", a.services);
+})), A.push(b.watch("routes", a, function(b) {
a.routes = b.by("metadata.name");
var c = a.routesByService = {}, d = a.displayRouteByService = {};
angular.forEach(a.routes, function(a, b) {
if ("Service" === a.spec.to.kind) {
var e = a.spec.to.name;
-c[e] = c[e] || {}, c[e][b] = a, (!d[e] || !t(a) && t(d[e])) && (d[e] = a);
+c[e] = c[e] || {}, c[e][b] = a, (!d[e] || !v(a) && v(d[e])) && (d[e] = a);
}
-}), v(), i.log("routes (subscribe)", a.routesByService);
-})), x.push(b.watch("replicationcontrollers", a, function(b, c, d) {
+}), x(), i.log("routes (subscribe)", a.routesByService);
+})), A.push(b.watch("replicationcontrollers", a, function(b, c, d) {
a.deployments = b.by("metadata.name"), d ? "DELETED" !== c && (d.causes = f(d)) :angular.forEach(a.deployments, function(a) {
a.causes = f(a);
-}), p(), m(), r(), v(), i.log("deployments (subscribe)", a.deployments);
-})), x.push(b.watch("imagestreams", a, function(b) {
-a.imageStreams = b.by("metadata.name"), j.buildDockerRefMapForImageStreams(a.imageStreams, a.imageStreamImageRefByDockerReference), j.fetchReferencedImageStreamImages(a.pods, a.imagesByDockerReference, a.imageStreamImageRefByDockerReference, a), v(), i.log("imagestreams (subscribe)", a.imageStreams);
-})), x.push(b.watch("deploymentconfigs", a, function(b, c, d) {
-a.deploymentConfigs = b.by("metadata.name"), c ? "DELETED" !== c && angular.forEach(a.builds, function(a) {
-q(d, a);
-}) :angular.forEach(a.deploymentConfigs, function(b) {
-angular.forEach(a.builds, function(a) {
-q(b, a);
-});
-}), o(), r(), v(), i.log("deploymentconfigs (subscribe)", a.deploymentConfigs);
-})), x.push(b.watch("builds", a, function(b, c, d) {
-a.builds = b.by("metadata.name"), c ? ("ADDED" === c || "MODIFIED" === c) && angular.forEach(a.deploymentConfigs, function(a) {
-q(a, d);
-}) :angular.forEach(a.builds, function(b) {
-angular.forEach(a.deploymentConfigs, function(a) {
-q(a, b);
-});
-}), v(), i.log("builds (subscribe)", a.builds);
+}), r(), o(), t(), x(), i.log("deployments (subscribe)", a.deployments);
+})), A.push(b.watch("imagestreams", a, function(b) {
+a.imageStreams = b.by("metadata.name"), j.buildDockerRefMapForImageStreams(a.imageStreams, a.imageStreamImageRefByDockerReference), j.fetchReferencedImageStreamImages(a.pods, a.imagesByDockerReference, a.imageStreamImageRefByDockerReference, a), x(), i.log("imagestreams (subscribe)", a.imageStreams);
+})), A.push(b.watch("deploymentconfigs", a, function(b) {
+a.deploymentConfigs = b.by("metadata.name"), q(), t(), x(), i.log("deploymentconfigs (subscribe)", a.deploymentConfigs);
+})), A.push(b.watch("builds", a, function(b) {
+a.builds = b.by("metadata.name"), s(), z.push(n(s, 3e5)), x(), i.log("builds (subscribe)", a.builds);
})), h.onActiveFiltersChanged(function(b) {
a.$apply(function() {
-a.services = b.select(a.unfilteredServices), s(), u();
+a.services = b.select(a.unfilteredServices), u(), w();
});
});
-var y = null;
+var B = null;
a.$on("select", function(b, c) {
a.$apply(function() {
a.topologySelection = c, c ? k.setObject(c, c.kind) :k.clearObject();
});
-}, !0), k.onResourceChanged(w), a.$watch("overviewMode", function(a) {
+}, !0), k.onResourceChanged(y), a.$watch("overviewMode", function(a) {
"topology" === a && (k.source = null);
}), a.$on("$destroy", function() {
-b.unwatchAll(x), window.clearTimeout(y), k.removeResourceChangedCallback(w);
+b.unwatchAll(A), window.clearTimeout(B), k.removeResourceChangedCallback(y), angular.forEach(z, function(a) {
+n.cancel(a);
+});
});
} ]), angular.module("openshiftConsole").controller("SettingsController", [ "$scope", "DataService", "AlertMessageService", "$filter", "$modal", "$location", "LabelFilter", "$timeout", "Logger", function(a, b, c, d, e, f, g, h, i) {
a.quotas = {}, a.limitRanges = {}, a.limitsByType = {}, a.labelSuggestions = {}, a.alerts = a.alerts || {}, a.emptyMessageQuotas = "Loading...", a.emptyMessageLimitRanges = "Loading...", a.renderOptions = a.renderOptions || {}, a.renderOptions.hideFilterWidget = !0;
@@ -4490,7 +4478,9 @@ return "hide/build/" + a.metadata.uid;
return {
restrict:"E",
scope:{
-triggers:"="
+triggers:"=",
+buildsByOutputImage:"=",
+namespace:"="
},
link:function(b) {
b.isBuildHidden = function(b) {
@@ -6579,16 +6569,10 @@ var _scriptsTemplatesJs = []byte(`angular.module('openshiftConsoleTemplates', []
$templateCache.put('views/_triggers.html',
"\n" +
"
\n" +
- "
\n" +
+ "
\n" +
+ "
\n" +
"\n" +
- "
\n" +
- "\n" +
- "\n" +
- "\n" +
- "\n" +
- "\n" +
- "\n" +
- "\n" +
+ "
\n" +
"\n" +
"Build\n" +
"
\n" +
@@ -6600,7 +6584,7 @@ var _scriptsTemplatesJs = []byte(`angular.module('openshiftConsoleTemplates', []
"\n" +
"{{build.metadata.name}}\n" +
"\n" +
- "\n" +
+ "\n" +
"completed.\n" +
"failed.\n" +
"encountered an error.\n" +
@@ -6614,7 +6598,9 @@ var _scriptsTemplatesJs = []byte(`angular.module('openshiftConsoleTemplates', []
"\n" +
"View Log\n" +
"\n" +
- "Dismiss\n" +
+ "|\n" +
+ "Dismiss\n" +
+ "\n" +
"
\n" +
"
\n" +
"
"
@@ -9265,14 +9251,14 @@ var _scriptsTemplatesJs = []byte(`angular.module('openshiftConsoleTemplates', []
"\n" +
"
\n" +
"\n" +
- "\n" +
+ "\n" +
"
\n" +
"\n" +
"
\n" +
"\n" +
"
\n" +
"\n" +
- "\n" +
+ "\n" +
"
\n" +
"
0 || (deployment | isRecentDeployment : deploymentConfigs[deploymentConfigId]) || !(deployment | isDeployment)\" class=\"animate-repeat\">\n" +
"\n" +
@@ -9295,7 +9281,7 @@ var _scriptsTemplatesJs = []byte(`angular.module('openshiftConsoleTemplates', []
"
0\">\n" +
"
\n" +
"\n" +
- "\n" +
+ "\n" +
"
\n" +
"\n" +
"
\n" +
@@ -69767,6 +69753,7 @@ labels+.resource-details{margin-top:10px}
[flex].page-header{margin-top:21px}
.resource-details h3{padding-bottom:10px;border-bottom:1px solid #eee}
h1 small.meta{font-size:12px}
+.action-divider{color:#999}
.ellipsis-loader{display:inline-block;position:relative;vertical-align:middle}
.ellipsis-loader div{position:absolute}
.ellipsis-loader div:after,.ellipsis-loader div:before{content:"";position:absolute}