Merged by openshift-bot
OpenShift Bot authored on 2016/04/03 12:16:24... | ... |
@@ -1,7 +1,13 @@ |
1 | 1 |
"use strict"; |
2 | 2 |
|
3 | 3 |
angular.module('openshiftConsole') |
4 |
- .directive('podStatusChart', function($timeout, hashSizeFilter, isTroubledPodFilter, numContainersReadyFilter, Logger) { |
|
4 |
+ .directive('podStatusChart', function($timeout, |
|
5 |
+ hashSizeFilter, |
|
6 |
+ isPullingImageFilter, |
|
7 |
+ isTerminatingFilter, |
|
8 |
+ isTroubledPodFilter, |
|
9 |
+ numContainersReadyFilter, |
|
10 |
+ Logger) { |
|
5 | 11 |
// Make sure our charts always have unique IDs even if the same deployment |
6 | 12 |
// or monopod is shown on the overview more than once. |
7 | 13 |
var lastId = 0; |
... | ... |
@@ -17,7 +23,7 @@ angular.module('openshiftConsole') |
17 | 17 |
var chart, config; |
18 | 18 |
|
19 | 19 |
// The phases to show (in order). |
20 |
- var phases = ["Running", "Not Ready", "Warning", "Failed", "Pending", "Succeeded", "Unknown"]; |
|
20 |
+ var phases = ["Running", "Not Ready", "Warning", "Failed", "Pulling", "Pending", "Succeeded", "Terminating", "Unknown"]; |
|
21 | 21 |
|
22 | 22 |
lastId++; |
23 | 23 |
$scope.chartId = 'pods-donut-chart-' + lastId; |
... | ... |
@@ -85,6 +91,9 @@ angular.module('openshiftConsole') |
85 | 85 |
return { top: 0, left: 0 }; |
86 | 86 |
} |
87 | 87 |
}, |
88 |
+ transition: { |
|
89 |
+ duration: 350 |
|
90 |
+ }, |
|
88 | 91 |
data: { |
89 | 92 |
type: "donut", |
90 | 93 |
groups: [ phases ], |
... | ... |
@@ -97,8 +106,10 @@ angular.module('openshiftConsole') |
97 | 97 |
"Not Ready": "#beedf9", |
98 | 98 |
Warning: "#f9d67a", |
99 | 99 |
Failed: "#d9534f", |
100 |
- Pending: "#e8e8e8", |
|
100 |
+ Pulling: "#d1d1d1", |
|
101 |
+ Pending: "#ededed", |
|
101 | 102 |
Succeeded: "#3f9c35", |
103 |
+ Terminating: "#00659c", |
|
102 | 104 |
Unknown: "#f9d67a" |
103 | 105 |
}, |
104 | 106 |
selection: { |
... | ... |
@@ -134,41 +145,47 @@ angular.module('openshiftConsole') |
134 | 134 |
$scope.podStatusData = data.columns; |
135 | 135 |
} |
136 | 136 |
|
137 |
- function countPodPhases() { |
|
138 |
- var countByPhase = {}; |
|
139 |
- var incrementCount = function(phase) { |
|
140 |
- countByPhase[phase] = (countByPhase[phase] || 0) + 1; |
|
141 |
- }; |
|
137 |
+ function isReady(pod) { |
|
138 |
+ var numReady = numContainersReadyFilter(pod); |
|
139 |
+ var total = pod.spec.containers.length; |
|
142 | 140 |
|
143 |
- var isReady = function(pod) { |
|
144 |
- var numReady = numContainersReadyFilter(pod); |
|
145 |
- var total = pod.spec.containers.length; |
|
141 |
+ return numReady === total; |
|
142 |
+ } |
|
146 | 143 |
|
147 |
- return numReady === total; |
|
148 |
- }; |
|
144 |
+ function getPhase(pod) { |
|
145 |
+ if (isTerminatingFilter(pod)) { |
|
146 |
+ return 'Terminating'; |
|
147 |
+ } |
|
149 | 148 |
|
150 |
- angular.forEach($scope.pods, function(pod) { |
|
151 |
- // Count 'Warning' as its own phase, even if not strictly accurate, |
|
152 |
- // so it appears in the donut chart. Warnings are too important not |
|
153 |
- // to call out. |
|
154 |
- if (isTroubledPodFilter(pod)) { |
|
155 |
- incrementCount('Warning'); |
|
156 |
- return; |
|
157 |
- } |
|
149 |
+ if (isTroubledPodFilter(pod)) { |
|
150 |
+ return 'Warning'; |
|
151 |
+ } |
|
158 | 152 |
|
159 |
- // Also count running, but not ready, as its own phase. |
|
160 |
- if (pod.status.phase === 'Running' && !isReady(pod)) { |
|
161 |
- incrementCount('Not Ready'); |
|
162 |
- return; |
|
163 |
- } |
|
153 |
+ if (isPullingImageFilter(pod)) { |
|
154 |
+ return 'Pulling'; |
|
155 |
+ } |
|
156 |
+ |
|
157 |
+ // Also count running, but not ready, as its own phase. |
|
158 |
+ if (pod.status.phase === 'Running' && !isReady(pod)) { |
|
159 |
+ return 'Not Ready'; |
|
160 |
+ } |
|
161 |
+ |
|
162 |
+ return _.get(pod, 'status.phase', 'Unknown'); |
|
163 |
+ } |
|
164 | 164 |
|
165 |
- incrementCount(pod.status.phase); |
|
165 |
+ function countPodPhases() { |
|
166 |
+ var countByPhase = {}; |
|
167 |
+ |
|
168 |
+ angular.forEach($scope.pods, function(pod) { |
|
169 |
+ var phase = getPhase(pod); |
|
170 |
+ countByPhase[phase] = (countByPhase[phase] || 0) + 1; |
|
166 | 171 |
}); |
167 | 172 |
|
168 | 173 |
return countByPhase; |
169 | 174 |
} |
170 | 175 |
|
171 |
- $scope.$watch(countPodPhases, updateChart, true); |
|
176 |
+ var debounceUpdate = _.debounce(updateChart, 350, { maxWait: 500 }); |
|
177 |
+ $scope.$watch(countPodPhases, debounceUpdate, true); |
|
172 | 178 |
$scope.$watch('desired', updateCenterText); |
173 | 179 |
|
174 | 180 |
$scope.$on('destroy', function() { |
... | ... |
@@ -696,6 +696,36 @@ angular.module('openshiftConsole') |
696 | 696 |
return numRestarts; |
697 | 697 |
}; |
698 | 698 |
}) |
699 |
+ .filter('isTerminating', function() { |
|
700 |
+ return function(resource) { |
|
701 |
+ return _.has(resource, 'metadata.deletionTimestamp'); |
|
702 |
+ }; |
|
703 |
+ }) |
|
704 |
+ .filter('isPullingImage', function() { |
|
705 |
+ return function(pod) { |
|
706 |
+ if (!pod) { |
|
707 |
+ return false; |
|
708 |
+ } |
|
709 |
+ |
|
710 |
+ var phase = _.get(pod, 'status.phase'); |
|
711 |
+ if (phase !== 'Pending') { |
|
712 |
+ return false; |
|
713 |
+ } |
|
714 |
+ |
|
715 |
+ var containerStatuses = _.get(pod, 'status.containerStatuses'); |
|
716 |
+ if (!containerStatuses) { |
|
717 |
+ return false; |
|
718 |
+ } |
|
719 |
+ |
|
720 |
+ var containerPulling = function(containerStatus) { |
|
721 |
+ // TODO: Update to use the pulling reason when available. We assume |
|
722 |
+ // ContainerCreating === pulling, which might not be true. |
|
723 |
+ return _.get(containerStatus, 'state.waiting.reason') === 'ContainerCreating'; |
|
724 |
+ }; |
|
725 |
+ |
|
726 |
+ return _.some(containerStatuses, containerPulling); |
|
727 |
+ }; |
|
728 |
+ }) |
|
699 | 729 |
.filter('newestResource', function() { |
700 | 730 |
return function(resources) { |
701 | 731 |
var newest = null; |
... | ... |
@@ -153,6 +153,31 @@ angular.module('openshiftConsole') |
153 | 153 |
return toString(amountAndUnitFilter(value, type, true)); |
154 | 154 |
}; |
155 | 155 |
}) |
156 |
+ .filter('humanizeSize', function() { |
|
157 |
+ return function(bytes) { |
|
158 |
+ if (bytes === null || bytes === undefined || bytes === '') { |
|
159 |
+ return bytes; |
|
160 |
+ } |
|
161 |
+ |
|
162 |
+ bytes = Number(bytes); |
|
163 |
+ if (bytes < 1024) { |
|
164 |
+ return bytes + " bytes"; |
|
165 |
+ } |
|
166 |
+ |
|
167 |
+ var KiB = bytes / 1024; |
|
168 |
+ if (KiB < 1024) { |
|
169 |
+ return KiB.toFixed(1) + " KiB"; |
|
170 |
+ } |
|
171 |
+ |
|
172 |
+ var MiB = KiB / 1024; |
|
173 |
+ if (MiB < 1024) { |
|
174 |
+ return MiB.toFixed(1) + " MiB"; |
|
175 |
+ } |
|
176 |
+ |
|
177 |
+ var GiB = MiB / 1024; |
|
178 |
+ return GiB.toFixed(1) + " GiB"; |
|
179 |
+ }; |
|
180 |
+ }) |
|
156 | 181 |
.filter('computeResourceLabel', function() { |
157 | 182 |
return function(computeResourceType, capitalize) { |
158 | 183 |
switch (computeResourceType) { |
... | ... |
@@ -18,6 +18,9 @@ |
18 | 18 |
<span ng-if="imagesByDockerReference[container.image]"> |
19 | 19 |
<a ng-href="{{imagesByDockerReference[container.image].imageStreamName | navigateResourceURL : 'ImageStream' : imagesByDockerReference[container.image].imageStreamNamespace}}">{{container.image | imageStreamName}}</a> |
20 | 20 |
(<span title="{{imagesByDockerReference[container.image].metadata.name}}">{{imagesByDockerReference[container.image].metadata.name | stripSHAPrefix | limitTo: 7}}</span>) |
21 |
+ <span ng-if="imagesByDockerReference[container.image].dockerImageMetadata.Size" class="small text-muted nowrap"> |
|
22 |
+ {{imagesByDockerReference[container.image].dockerImageMetadata.Size | humanizeSize}} |
|
23 |
+ </span> |
|
21 | 24 |
</span> |
22 | 25 |
</div> |
23 | 26 |
</div> |
... | ... |
@@ -6760,8 +6760,8 @@ return { |
6760 | 6760 |
restrict:"E", |
6761 | 6761 |
templateUrl:"views/directives/_ellipsis-loader.html" |
6762 | 6762 |
}; |
6763 |
-} ]), angular.module("openshiftConsole").directive("podStatusChart", [ "$timeout", "hashSizeFilter", "isTroubledPodFilter", "numContainersReadyFilter", "Logger", function(a, b, c, d, e) { |
|
6764 |
-var f = 0; |
|
6763 |
+} ]), angular.module("openshiftConsole").directive("podStatusChart", [ "$timeout", "hashSizeFilter", "isPullingImageFilter", "isTerminatingFilter", "isTroubledPodFilter", "numContainersReadyFilter", "Logger", function(a, b, c, d, e, f, g) { |
|
6764 |
+var h = 0; |
|
6765 | 6765 |
return { |
6766 | 6766 |
restrict:"E", |
6767 | 6767 |
scope:{ |
... | ... |
@@ -6769,32 +6769,35 @@ pods:"=", |
6769 | 6769 |
desired:"=?" |
6770 | 6770 |
}, |
6771 | 6771 |
templateUrl:"views/_pod-status-chart.html", |
6772 |
-link:function(a, g) { |
|
6773 |
-function h() { |
|
6774 |
-var c, d = d3.select(g[0]).select("text.c3-chart-arcs-title"), f = b(a.pods); |
|
6775 |
-return d ? (c = angular.isNumber(a.desired) && a.desired !== f ? "scaling to " + a.desired + "..." :1 === f ? "pod" :"pods", d.selectAll("*").remove(), d.insert("tspan").text(f).classed("pod-count donut-title-big-pf", !0).attr("dy", 0).attr("x", 0), void d.insert("tspan").text(c).classed("donut-title-small-pf", !0).attr("dy", 20).attr("x", 0)) :void e.warn("Can't select donut title element"); |
|
6772 |
+link:function(a, i) { |
|
6773 |
+function j() { |
|
6774 |
+var c, d = d3.select(i[0]).select("text.c3-chart-arcs-title"), e = b(a.pods); |
|
6775 |
+return d ? (c = angular.isNumber(a.desired) && a.desired !== e ? "scaling to " + a.desired + "..." :1 === e ? "pod" :"pods", d.selectAll("*").remove(), d.insert("tspan").text(e).classed("pod-count donut-title-big-pf", !0).attr("dy", 0).attr("x", 0), void d.insert("tspan").text(c).classed("donut-title-small-pf", !0).attr("dy", 20).attr("x", 0)) :void g.warn("Can't select donut title element"); |
|
6776 | 6776 |
} |
6777 |
-function i(c) { |
|
6777 |
+function k(c) { |
|
6778 | 6778 |
var d = { |
6779 | 6779 |
columns:[] |
6780 | 6780 |
}; |
6781 |
-angular.forEach(m, function(a) { |
|
6781 |
+angular.forEach(q, function(a) { |
|
6782 | 6782 |
d.columns.push([ a, c[a] || 0 ]); |
6783 |
-}), 0 === b(c) ? d.columns.push([ "Empty", 1 ]) :d.unload = "Empty", k ? k.load(d) :(l.data.columns = d.columns, k = c3.generate(l)), a.podStatusData = d.columns; |
|
6783 |
+}), 0 === b(c) ? d.columns.push([ "Empty", 1 ]) :d.unload = "Empty", o ? o.load(d) :(p.data.columns = d.columns, o = c3.generate(p)), a.podStatusData = d.columns; |
|
6784 | 6784 |
} |
6785 |
-function j() { |
|
6786 |
-var b = {}, e = function(a) { |
|
6787 |
-b[a] = (b[a] || 0) + 1; |
|
6788 |
-}, f = function(a) { |
|
6789 |
-var b = d(a), c = a.spec.containers.length; |
|
6785 |
+function l(a) { |
|
6786 |
+var b = f(a), c = a.spec.containers.length; |
|
6790 | 6787 |
return b === c; |
6791 |
-}; |
|
6788 |
+} |
|
6789 |
+function m(a) { |
|
6790 |
+return d(a) ? "Terminating" :e(a) ? "Warning" :c(a) ? "Pulling" :"Running" !== a.status.phase || l(a) ? _.get(a, "status.phase", "Unknown") :"Not Ready"; |
|
6791 |
+} |
|
6792 |
+function n() { |
|
6793 |
+var b = {}; |
|
6792 | 6794 |
return angular.forEach(a.pods, function(a) { |
6793 |
-return c(a) ? void e("Warning") :"Running" !== a.status.phase || f(a) ? void e(a.status.phase) :void e("Not Ready"); |
|
6795 |
+var c = m(a); |
|
6796 |
+b[c] = (b[c] || 0) + 1; |
|
6794 | 6797 |
}), b; |
6795 | 6798 |
} |
6796 |
-var k, l, m = [ "Running", "Not Ready", "Warning", "Failed", "Pending", "Succeeded", "Unknown" ]; |
|
6797 |
-f++, a.chartId = "pods-donut-chart-" + f, l = { |
|
6799 |
+var o, p, q = [ "Running", "Not Ready", "Warning", "Failed", "Pulling", "Pending", "Succeeded", "Terminating", "Unknown" ]; |
|
6800 |
+h++, a.chartId = "pods-donut-chart-" + h, p = { |
|
6798 | 6801 |
type:"donut", |
6799 | 6802 |
bindto:"#" + a.chartId, |
6800 | 6803 |
donut:{ |
... | ... |
@@ -6811,7 +6814,7 @@ width:150 |
6811 | 6811 |
legend:{ |
6812 | 6812 |
show:!1 |
6813 | 6813 |
}, |
6814 |
-onrendered:h, |
|
6814 |
+onrendered:j, |
|
6815 | 6815 |
tooltip:{ |
6816 | 6816 |
format:{ |
6817 | 6817 |
value:function(a, b, c) { |
... | ... |
@@ -6825,9 +6828,12 @@ left:0 |
6825 | 6825 |
}; |
6826 | 6826 |
} |
6827 | 6827 |
}, |
6828 |
+transition:{ |
|
6829 |
+duration:350 |
|
6830 |
+}, |
|
6828 | 6831 |
data:{ |
6829 | 6832 |
type:"donut", |
6830 |
-groups:[ m ], |
|
6833 |
+groups:[ q ], |
|
6831 | 6834 |
order:null, |
6832 | 6835 |
colors:{ |
6833 | 6836 |
Empty:"#ffffff", |
... | ... |
@@ -6835,16 +6841,22 @@ Running:"#00b9e4", |
6835 | 6835 |
"Not Ready":"#beedf9", |
6836 | 6836 |
Warning:"#f9d67a", |
6837 | 6837 |
Failed:"#d9534f", |
6838 |
-Pending:"#e8e8e8", |
|
6838 |
+Pulling:"#d1d1d1", |
|
6839 |
+Pending:"#ededed", |
|
6839 | 6840 |
Succeeded:"#3f9c35", |
6841 |
+Terminating:"#00659c", |
|
6840 | 6842 |
Unknown:"#f9d67a" |
6841 | 6843 |
}, |
6842 | 6844 |
selection:{ |
6843 | 6845 |
enabled:!1 |
6844 | 6846 |
} |
6845 | 6847 |
} |
6846 |
-}, a.$watch(j, i, !0), a.$watch("desired", h), a.$on("destroy", function() { |
|
6847 |
-k && (k = k.destroy()); |
|
6848 |
+}; |
|
6849 |
+var r = _.debounce(k, 350, { |
|
6850 |
+maxWait:500 |
|
6851 |
+}); |
|
6852 |
+a.$watch(n, r, !0), a.$watch("desired", j), a.$on("destroy", function() { |
|
6853 |
+o && (o = o.destroy()); |
|
6848 | 6854 |
}); |
6849 | 6855 |
} |
6850 | 6856 |
}; |
... | ... |
@@ -7617,6 +7629,22 @@ return angular.forEach(a.status.containerStatuses, function(a) { |
7617 | 7617 |
b += a.restartCount; |
7618 | 7618 |
}), b; |
7619 | 7619 |
}; |
7620 |
+}).filter("isTerminating", function() { |
|
7621 |
+return function(a) { |
|
7622 |
+return _.has(a, "metadata.deletionTimestamp"); |
|
7623 |
+}; |
|
7624 |
+}).filter("isPullingImage", function() { |
|
7625 |
+return function(a) { |
|
7626 |
+if (!a) return !1; |
|
7627 |
+var b = _.get(a, "status.phase"); |
|
7628 |
+if ("Pending" !== b) return !1; |
|
7629 |
+var c = _.get(a, "status.containerStatuses"); |
|
7630 |
+if (!c) return !1; |
|
7631 |
+var d = function(a) { |
|
7632 |
+return "ContainerCreating" === _.get(a, "state.waiting.reason"); |
|
7633 |
+}; |
|
7634 |
+return _.some(c, d); |
|
7635 |
+}; |
|
7620 | 7636 |
}).filter("newestResource", function() { |
7621 | 7637 |
return function(a) { |
7622 | 7638 |
var b = null; |
... | ... |
@@ -7840,7 +7868,18 @@ return b ? a + " " + b :a; |
7840 | 7840 |
}); |
7841 | 7841 |
return d(a(b, c, !0)); |
7842 | 7842 |
}; |
7843 |
-} ]).filter("computeResourceLabel", function() { |
|
7843 |
+} ]).filter("humanizeSize", function() { |
|
7844 |
+return function(a) { |
|
7845 |
+if (null === a || void 0 === a || "" === a) return a; |
|
7846 |
+if (a = Number(a), 1024 > a) return a + " bytes"; |
|
7847 |
+var b = a / 1024; |
|
7848 |
+if (1024 > b) return b.toFixed(1) + " KiB"; |
|
7849 |
+var c = b / 1024; |
|
7850 |
+if (1024 > c) return c.toFixed(1) + " MiB"; |
|
7851 |
+var d = c / 1024; |
|
7852 |
+return d.toFixed(1) + " GiB"; |
|
7853 |
+}; |
|
7854 |
+}).filter("computeResourceLabel", function() { |
|
7844 | 7855 |
return function(a, b) { |
7845 | 7856 |
switch (a) { |
7846 | 7857 |
case "cpu": |
... | ... |
@@ -8416,6 +8455,9 @@ var _scriptsTemplatesJs = []byte(`angular.module('openshiftConsoleTemplates', [] |
8416 | 8416 |
"<span ng-if=\"imagesByDockerReference[container.image]\">\n" + |
8417 | 8417 |
"<a ng-href=\"{{imagesByDockerReference[container.image].imageStreamName | navigateResourceURL : 'ImageStream' : imagesByDockerReference[container.image].imageStreamNamespace}}\">{{container.image | imageStreamName}}</a>\n" + |
8418 | 8418 |
"(<span title=\"{{imagesByDockerReference[container.image].metadata.name}}\">{{imagesByDockerReference[container.image].metadata.name | stripSHAPrefix | limitTo: 7}}</span>)\n" + |
8419 |
+ "<span ng-if=\"imagesByDockerReference[container.image].dockerImageMetadata.Size\" class=\"small text-muted nowrap\">\n" + |
|
8420 |
+ "{{imagesByDockerReference[container.image].dockerImageMetadata.Size | humanizeSize}}\n" + |
|
8421 |
+ "</span>\n" + |
|
8419 | 8422 |
"</span>\n" + |
8420 | 8423 |
"</div>\n" + |
8421 | 8424 |
"</div>\n" + |