YARN-5321. [YARN-3368] Add resource usage for application by node managers (Wangda Tan via Sunil G)
YARN-5320. [YARN-3368] Add resource usage by applications and queues to cluster overview page (Wangda Tan via Sunil G) YARN-5322. [YARN-3368] Add a node heat chart map (Wangda Tan via Sunil G) YARN-5347. [YARN-3368] Applications page improvements (Sreenath Somarajapuram via Sunil G) YARN-5348. [YARN-3368] Node details page improvements (Sreenath Somarajapuram via Sunil G) YARN-5346. [YARN-3368] Queues page improvements (Sreenath Somarajapuram via Sunil G) YARN-5345. [YARN-3368] Cluster overview page improvements (Sreenath Somarajapuram via Sunil G) YARN-5344. [YARN-3368] Generic UI improvements (Sreenath Somarajapuram via Sunil G)
This commit is contained in:
parent
35f08122e2
commit
8f584a561e
|
@ -23,6 +23,20 @@ export default AbstractAdapter.extend({
|
|||
restNameSpace: "cluster",
|
||||
serverName: "RM",
|
||||
|
||||
urlForQuery(query, modelName) {
|
||||
var url = this._buildURL();
|
||||
if (query.state) {
|
||||
url = url + '/apps/?state=' + query.state;
|
||||
}
|
||||
return url;
|
||||
},
|
||||
|
||||
urlForFindRecord(id, modelName, snapshot) {
|
||||
var url = this._buildURL();
|
||||
url = url + '/apps/' + id;
|
||||
return url;
|
||||
},
|
||||
|
||||
pathForType(modelName) {
|
||||
return 'apps'; // move to some common place, return path by modelname.
|
||||
},
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Ember from 'ember';
|
||||
import DonutChart from 'yarn-ui/components/donut-chart';
|
||||
import BaseUsageDonutChart from 'yarn-ui/components/base-usage-donut-chart';
|
||||
import ColorUtils from 'yarn-ui/utils/color-utils';
|
||||
import HrefAddressUtils from 'yarn-ui/utils/href-address-utils';
|
||||
|
||||
export default BaseUsageDonutChart.extend({
|
||||
colors: d3.scale.category20().range(),
|
||||
|
||||
draw: function() {
|
||||
this.initChart();
|
||||
var usageByApps = [];
|
||||
var avail = 100;
|
||||
|
||||
this.get("data").forEach(function (app) {
|
||||
var v = app.get("clusterUsagePercentage");
|
||||
if (v > 1e-2) {
|
||||
usageByApps.push({
|
||||
label: app.get("id"),
|
||||
link: HrefAddressUtils.getApplicationLink(app.get("id")),
|
||||
value: v.toFixed(2)
|
||||
});
|
||||
|
||||
console.log(v);
|
||||
avail = avail - v;
|
||||
}
|
||||
}.bind(this));
|
||||
|
||||
usageByApps.sort(function(a,b) {
|
||||
return b.value - a.value;
|
||||
});
|
||||
|
||||
usageByApps = this.mergeLongTails(usageByApps, 8);
|
||||
|
||||
usageByApps.push({
|
||||
label: "Available",
|
||||
value: avail.toFixed(4)
|
||||
})
|
||||
|
||||
this.colors = ColorUtils.getColors(usageByApps.length, ["others", "good"], true);
|
||||
|
||||
this.renderDonutChart(usageByApps, this.get("title"), this.get("showLabels"),
|
||||
this.get("middleLabel"), "100%", "%");
|
||||
},
|
||||
|
||||
didInsertElement: function() {
|
||||
this.draw();
|
||||
},
|
||||
})
|
|
@ -116,6 +116,11 @@ export default BaseChartComponent.extend({
|
|||
this.renderBarChart(this.get("data"), this.get("title"), this.get("textWidth"));
|
||||
},
|
||||
|
||||
_dataChange: Ember.observer("data", function() {
|
||||
this.chart.g.selectAll("*").remove();
|
||||
this.renderBarChart(this.get("data"), this.get("title"), this.get("textWidth"));
|
||||
}),
|
||||
|
||||
didInsertElement: function() {
|
||||
this.draw();
|
||||
},
|
||||
|
|
|
@ -17,23 +17,26 @@
|
|||
*/
|
||||
|
||||
import Ember from 'ember';
|
||||
import Converter from 'yarn-ui/utils/converter';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
chart: undefined,
|
||||
tooltip : undefined,
|
||||
colors: d3.scale.category10().range(),
|
||||
|
||||
initChart: function() {
|
||||
this.chart = {
|
||||
init: function () {
|
||||
this._super();
|
||||
this.set("chart", {
|
||||
svg: undefined,
|
||||
g: undefined,
|
||||
h: 0,
|
||||
w: 0,
|
||||
tooltip: undefined
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
initChart: function(removeLast = false) {
|
||||
// Init tooltip if it is not initialized
|
||||
this.tooltip = d3.select("#chart-tooltip");
|
||||
// this.tooltip = d3.select("#chart-tooltip");
|
||||
if (!this.tooltip) {
|
||||
this.tooltip = d3.select("body")
|
||||
.append("div")
|
||||
|
@ -42,13 +45,16 @@ export default Ember.Component.extend({
|
|||
.style("opacity", 0);
|
||||
}
|
||||
|
||||
// Init svg
|
||||
var svg = this.chart.svg;
|
||||
if (svg) {
|
||||
svg.remove();
|
||||
var parentId = this.get("parentId");
|
||||
|
||||
if (removeLast) {
|
||||
// Init svg
|
||||
var svg = d3.select("#" + parentId + "-svg");
|
||||
if (svg) {
|
||||
svg.remove();
|
||||
}
|
||||
}
|
||||
|
||||
var parentId = this.get("parentId");
|
||||
var parent = d3.select("#" + parentId);
|
||||
var bbox = parent.node().getBoundingClientRect();
|
||||
this.chart.w = bbox.width - 30;
|
||||
|
@ -65,12 +71,13 @@ export default Ember.Component.extend({
|
|||
|
||||
this.chart.svg = parent.append("svg")
|
||||
.attr("width", this.chart.w)
|
||||
.attr("height", this.chart.h);
|
||||
.attr("height", this.chart.h)
|
||||
.attr("id", parentId + "-svg");
|
||||
|
||||
this.chart.g = this.chart.svg.append("g");
|
||||
},
|
||||
|
||||
renderTitleAndBG: function(g, title, layout) {
|
||||
renderTitleAndBG: function(g, title, layout, background=true) {
|
||||
var bg = g.append("g");
|
||||
bg.append("text")
|
||||
.text(title)
|
||||
|
@ -78,12 +85,14 @@ export default Ember.Component.extend({
|
|||
.attr("y", layout.y1 + layout.margin + 20)
|
||||
.attr("class", "chart-title");
|
||||
|
||||
bg.append("rect")
|
||||
.attr("x", layout.x1)
|
||||
.attr("y", layout.y1)
|
||||
.attr("width", layout.x2 - layout.x1)
|
||||
.attr("height", layout.y2 - layout.y1)
|
||||
.attr("class", "chart-frame");
|
||||
if (background) {
|
||||
bg.append("rect")
|
||||
.attr("x", layout.x1)
|
||||
.attr("y", layout.y1)
|
||||
.attr("width", layout.x2 - layout.x1)
|
||||
.attr("height", layout.y2 - layout.y1)
|
||||
.attr("class", "chart-frame");
|
||||
}
|
||||
},
|
||||
|
||||
bindTooltip: function(d) {
|
||||
|
@ -100,7 +109,11 @@ export default Ember.Component.extend({
|
|||
}
|
||||
|
||||
this.tooltip.style("opacity", .9);
|
||||
this.tooltip.html(data.label + " = " + data.value)
|
||||
var value = data.value;
|
||||
if (this.get("type") == "memory") {
|
||||
value = Converter.memoryToSimpliedUnit(value);
|
||||
}
|
||||
this.tooltip.html(data.label + " = " + value)
|
||||
.style("left", (d3.event.pageX) + "px")
|
||||
.style("top", (d3.event.pageY - 28) + "px");
|
||||
}.bind(this))
|
||||
|
@ -109,6 +122,10 @@ export default Ember.Component.extend({
|
|||
}.bind(this));
|
||||
},
|
||||
|
||||
adjustMaxHeight: function(h) {
|
||||
this.chart.svg.attr("height", h);
|
||||
},
|
||||
|
||||
getLayout: function() {
|
||||
var x1 = 0;
|
||||
var y1 = 0;
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Ember from 'ember';
|
||||
import DonutChart from 'yarn-ui/components/donut-chart';
|
||||
|
||||
export default DonutChart.extend({
|
||||
mergeLongTails: function(usages, nItemsKept) {
|
||||
var arr = [];
|
||||
for (var i = 0; i < Math.min(usages.length, nItemsKept); i++) {
|
||||
arr.push(usages[i]);
|
||||
}
|
||||
|
||||
var others = {
|
||||
label: "Used by others",
|
||||
value: 0
|
||||
}
|
||||
|
||||
for (var i = nItemsKept; i < usages.length; i++) {
|
||||
others.value += Number(usages[i].value);
|
||||
}
|
||||
others.value = others.value.toFixed(2);
|
||||
|
||||
arr.push(others)
|
||||
|
||||
return arr;
|
||||
},
|
||||
})
|
|
@ -18,13 +18,15 @@
|
|||
|
||||
import Ember from 'ember';
|
||||
import BaseChartComponent from 'yarn-ui/components/base-chart-component';
|
||||
import ColorUtils from 'yarn-ui/utils/color-utils';
|
||||
import Converter from 'yarn-ui/utils/converter';
|
||||
|
||||
export default BaseChartComponent.extend({
|
||||
/*
|
||||
* data = [{label="xx", value=},{...}]
|
||||
*/
|
||||
renderDonutChart: function(data, title, showLabels = false,
|
||||
middleLabel = "Total", middleValue = undefined) {
|
||||
middleLabel = "Total", middleValue = undefined, suffix = "") {
|
||||
var g = this.chart.g;
|
||||
var layout = this.getLayout();
|
||||
this.renderTitleAndBG(g, title, layout);
|
||||
|
@ -39,7 +41,11 @@ export default BaseChartComponent.extend({
|
|||
}
|
||||
|
||||
if (!middleValue) {
|
||||
middleValue = total;
|
||||
if (this.get("type") == "memory") {
|
||||
middleValue = Converter.memoryToSimpliedUnit(total);
|
||||
} else {
|
||||
middleValue = total;
|
||||
}
|
||||
}
|
||||
|
||||
//Width and height
|
||||
|
@ -48,6 +54,8 @@ export default BaseChartComponent.extend({
|
|||
// 50 is for title
|
||||
var outerRadius = (h - 50 - 2 * layout.margin) / 2;
|
||||
var innerRadius = outerRadius * 0.618;
|
||||
console.log("inner:" + innerRadius + " outer:" + outerRadius);
|
||||
|
||||
var arc = d3.svg.arc()
|
||||
.innerRadius(innerRadius)
|
||||
.outerRadius(outerRadius);
|
||||
|
@ -104,12 +112,14 @@ export default BaseChartComponent.extend({
|
|||
return this.colors[i];
|
||||
}
|
||||
}.bind(this))
|
||||
.attr("stroke-dasharray", function(d, i) {
|
||||
if (d.value <= 1e-6) {
|
||||
return "10,10";
|
||||
}
|
||||
}.bind(this));
|
||||
this.bindTooltip(path);
|
||||
path.on("click", function (d) {
|
||||
var data = d.data;
|
||||
if (data.link) {
|
||||
this.tooltip.remove();
|
||||
document.location.href = data.link;
|
||||
}
|
||||
}.bind(this))
|
||||
|
||||
// Show labels
|
||||
if (showLabels) {
|
||||
|
@ -126,27 +136,30 @@ export default BaseChartComponent.extend({
|
|||
}.bind(this))
|
||||
.attr("x", lx)
|
||||
.attr("y", function(d, i) {
|
||||
return layout.y1 + 50 + (squareW + margin) * i + layout.margin;
|
||||
return layout.y1 + 75 + (squareW + margin) * i + layout.margin;
|
||||
})
|
||||
.attr("width", squareW)
|
||||
.attr("height", squareW);
|
||||
select.append("text")
|
||||
.attr("x", lx + squareW + margin)
|
||||
.attr("y", function(d, i) {
|
||||
return layout.y1 + 50 + (squareW + margin) * i + layout.margin + squareW / 2;
|
||||
return layout.y1 + 80 + (squareW + margin) * i + layout.margin + squareW / 2;
|
||||
})
|
||||
.text(function(d) {
|
||||
return d.label + ' = ' + d.value;
|
||||
});
|
||||
var value = d.value;
|
||||
if (this.get("type") == "memory") {
|
||||
value = Converter.memoryToSimpliedUnit(value);
|
||||
}
|
||||
return d.label + ' = ' + value + suffix;
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
if (middleLabel) {
|
||||
var highLightColor = this.colors[0];
|
||||
g.append("text").text(middleLabel).attr("x", cx).attr("y", cy - 10).
|
||||
attr("class", "donut-highlight-text").attr("fill", highLightColor);
|
||||
g.append("text").text(middleValue).attr("x", cx).attr("y", cy + 20).
|
||||
attr("class", "donut-highlight-text").attr("fill", highLightColor).
|
||||
style("font-size", "30px");
|
||||
g.append("text").text(middleValue).attr("x", cx).attr("y", cy + 15).
|
||||
attr("class", "donut-highlight-sub").attr("fill", highLightColor);
|
||||
}
|
||||
|
||||
path.transition()
|
||||
|
@ -154,8 +167,22 @@ export default BaseChartComponent.extend({
|
|||
.attrTween('d', tweenPie);
|
||||
},
|
||||
|
||||
_dataChange: Ember.observer("data", function() {
|
||||
this.chart.g.selectAll("*").remove();
|
||||
this.renderDonutChart(this.get("data"), this.get("title"), this.get("showLabels"),
|
||||
this.get("middleLabel"), this.get("middleValue"));
|
||||
}),
|
||||
|
||||
draw: function() {
|
||||
this.initChart();
|
||||
|
||||
var colorTargets = this.get("colorTargets");
|
||||
if (colorTargets) {
|
||||
var colorTargetReverse = Boolean(this.get("colorTargetReverse"));
|
||||
var targets = colorTargets.split(" ");
|
||||
this.colors = ColorUtils.getColors(this.get("data").length, targets, colorTargetReverse);
|
||||
}
|
||||
|
||||
this.renderDonutChart(this.get("data"), this.get("title"), this.get("showLabels"),
|
||||
this.get("middleLabel"), this.get("middleValue"));
|
||||
},
|
||||
|
|
|
@ -0,0 +1,209 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import BaseChartComponent from 'yarn-ui/components/base-chart-component';
|
||||
import Mock from 'yarn-ui/utils/mock';
|
||||
|
||||
export default BaseChartComponent.extend({
|
||||
CELL_WIDTH: 250,
|
||||
SAMPLE_CELL_WIDTH: 100,
|
||||
SAMPLE_HEIGHT: 30,
|
||||
CELL_HEIGHT: 30,
|
||||
CELL_MARGIN: 2,
|
||||
RACK_MARGIN: 20,
|
||||
filter: "",
|
||||
|
||||
bindTP: function(element) {
|
||||
element.on("mouseover", function() {
|
||||
this.tooltip
|
||||
.style("left", (d3.event.pageX) + "px")
|
||||
.style("top", (d3.event.pageY - 28) + "px");
|
||||
element.style("opacity", 1.0);
|
||||
}.bind(this))
|
||||
.on("mousemove", function() {
|
||||
// Handle pie chart case
|
||||
var text = element.attr("tooltiptext");
|
||||
|
||||
this.tooltip.style("opacity", .9);
|
||||
this.tooltip.html(text)
|
||||
.style("left", (d3.event.pageX) + "px")
|
||||
.style("top", (d3.event.pageY - 28) + "px");
|
||||
}.bind(this))
|
||||
.on("mouseout", function() {
|
||||
this.tooltip.style("opacity", 0);
|
||||
element.style("opacity", 0.8);
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
// data:
|
||||
// [{label=label1, value=value1}, ...]
|
||||
// ...
|
||||
renderCells: function (model, title) {
|
||||
var data = [];
|
||||
model.forEach(function (o) {
|
||||
data.push(o);
|
||||
});
|
||||
|
||||
this.chart.g.remove();
|
||||
this.chart.g = this.chart.svg.append("g");
|
||||
var g = this.chart.g;
|
||||
var layout = this.getLayout();
|
||||
layout.margin = 50;
|
||||
|
||||
let racks = new Set();
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
racks.add(data[i].get("rack"));
|
||||
}
|
||||
|
||||
let racksArray = [];
|
||||
racks.forEach(v => racksArray.push(v));
|
||||
|
||||
var xOffset = layout.margin;
|
||||
var yOffset = layout.margin * 3;
|
||||
|
||||
var colorFunc = d3.interpolate(d3.rgb("#bdddf5"), d3.rgb("#0f3957"));
|
||||
|
||||
var sampleXOffset = (layout.x2 - layout.x1) / 2 - 2.5 * this.SAMPLE_CELL_WIDTH -
|
||||
2 * this.CELL_MARGIN;
|
||||
var sampleYOffset = layout.margin * 2;
|
||||
|
||||
for (var i = 1; i <= 5; i++) {
|
||||
var ratio = i * 0.2 - 0.1;
|
||||
|
||||
var rect = g.append("rect")
|
||||
.attr("x", sampleXOffset)
|
||||
.attr("y", sampleYOffset)
|
||||
.attr("fill", colorFunc(ratio))
|
||||
.attr("width", this.SAMPLE_CELL_WIDTH)
|
||||
.attr("height", this.SAMPLE_HEIGHT);
|
||||
g.append("text")
|
||||
.text("" + (ratio * 100).toFixed(1) + "% Used")
|
||||
.attr("y", sampleYOffset + this.SAMPLE_HEIGHT / 2 + 5)
|
||||
.attr("x", sampleXOffset + this.SAMPLE_CELL_WIDTH / 2)
|
||||
.attr("class", "heatmap-cell");
|
||||
sampleXOffset += this.CELL_MARGIN + this.SAMPLE_CELL_WIDTH;
|
||||
}
|
||||
|
||||
var chartXOffset = -1;
|
||||
|
||||
for (var i = 0; i < racksArray.length; i++) {
|
||||
var text = g.append("text")
|
||||
.text(racksArray[i])
|
||||
.attr("y", yOffset + this.CELL_HEIGHT / 2 + 5)
|
||||
.attr("x", layout.margin)
|
||||
.attr("class", "heatmap-rack");
|
||||
|
||||
if (-1 == chartXOffset) {
|
||||
chartXOffset = layout.margin + text.node().getComputedTextLength() + 30;
|
||||
}
|
||||
|
||||
xOffset = chartXOffset;
|
||||
|
||||
for (var j = 0; j < data.length; j++) {
|
||||
var rack = data[j].get("rack");
|
||||
var host = data[j].get("nodeHostName");
|
||||
|
||||
if (rack == racksArray[i]) {
|
||||
if (!rack.includes(this.filter) && !host.includes(this.filter)) {
|
||||
this.addNode(g, xOffset, yOffset, colorFunc, data[j], false);
|
||||
var text = g.append("text")
|
||||
.text(host)
|
||||
.attr("y", yOffset + this.CELL_HEIGHT / 2 + 5)
|
||||
.attr("x", xOffset + this.CELL_WIDTH / 2)
|
||||
.attr("class", "heatmap-cell-notselected");
|
||||
} else {
|
||||
this.addNode(g, xOffset, yOffset, colorFunc, data[j], true);
|
||||
g.append("text")
|
||||
.text(host)
|
||||
.attr("y", yOffset + this.CELL_HEIGHT / 2 + 5)
|
||||
.attr("x", xOffset + this.CELL_WIDTH / 2)
|
||||
.attr("class", "heatmap-cell");
|
||||
}
|
||||
|
||||
xOffset += this.CELL_MARGIN + this.CELL_WIDTH;
|
||||
if (xOffset + this.CELL_MARGIN + this.CELL_WIDTH >= layout.x2 -
|
||||
layout.margin) {
|
||||
xOffset = chartXOffset;
|
||||
yOffset = yOffset + this.CELL_MARGIN + this.CELL_HEIGHT;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
while (xOffset > chartXOffset && xOffset + this.CELL_MARGIN +
|
||||
this.CELL_WIDTH < layout.x2 - layout.margin) {
|
||||
this.addPlaceholderNode(g, xOffset, yOffset);
|
||||
xOffset += this.CELL_MARGIN + this.CELL_WIDTH;
|
||||
}
|
||||
|
||||
if (xOffset != chartXOffset) {
|
||||
xOffset = chartXOffset;
|
||||
yOffset += this.CELL_MARGIN + this.CELL_HEIGHT;
|
||||
}
|
||||
yOffset += this.RACK_MARGIN;
|
||||
}
|
||||
|
||||
layout.y2 = yOffset + layout.margin;
|
||||
this.adjustMaxHeight(layout.y2);
|
||||
this.renderTitleAndBG(g, title, layout, false);
|
||||
},
|
||||
|
||||
addNode: function (g, xOffset, yOffset, colorFunc, data, selected) {
|
||||
var rect = g.append("rect")
|
||||
.attr("y", yOffset)
|
||||
.attr("x", xOffset)
|
||||
.attr("height", this.CELL_HEIGHT)
|
||||
.attr("fill", colorFunc(data.get("usedMemoryMB") /
|
||||
(data.get("usedMemoryMB") + data.get("availMemoryMB"))))
|
||||
.attr("width", this.CELL_WIDTH)
|
||||
.attr("tooltiptext", data.get("toolTipText"));
|
||||
if (selected) {
|
||||
rect.style("opacity", 0.8);
|
||||
this.bindTP(rect);
|
||||
} else {
|
||||
rect.style("opacity", 0.8);
|
||||
rect.attr("fill", "DimGray");
|
||||
}
|
||||
},
|
||||
|
||||
addPlaceholderNode: function(g, xOffset, yOffset) {
|
||||
var rect = g.append("rect")
|
||||
.attr("y", yOffset)
|
||||
.attr("x", xOffset)
|
||||
.attr("height", this.CELL_HEIGHT)
|
||||
.attr("fill", "grey")
|
||||
.attr("width", this.CELL_WIDTH)
|
||||
.style("opacity", 0.20);
|
||||
},
|
||||
|
||||
draw: function() {
|
||||
this.initChart(true);
|
||||
this.renderCells(this.get("model"), this.get("title"), this.get("textWidth"));
|
||||
},
|
||||
|
||||
didInsertElement: function () {
|
||||
this.draw();
|
||||
},
|
||||
|
||||
actions: {
|
||||
applyFilter: function(event) {
|
||||
this.filter = event.srcElement.value;
|
||||
this.didInsertElement();
|
||||
}
|
||||
}
|
||||
})
|
|
@ -0,0 +1,88 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import StackedBarchart from 'yarn-ui/components/stacked-barchart';
|
||||
import Converter from 'yarn-ui/utils/converter';
|
||||
|
||||
export default StackedBarchart.extend({
|
||||
getDataForRender: function(containers, nodes) {
|
||||
var arr = [];
|
||||
var nodeToResources = {};
|
||||
nodes.forEach(function(n) {
|
||||
nodeToResources[n.id] =
|
||||
{
|
||||
used: Number(n.get("usedMemoryMB")),
|
||||
avail: Number(n.get("availMemoryMB"))
|
||||
}
|
||||
});
|
||||
|
||||
containers.forEach(function(c) {
|
||||
res = nodeToResources[c.get("assignedNodeId")];
|
||||
if (res) {
|
||||
if (!res.usedByTheApp) {
|
||||
res.usedByTheApp = 0;
|
||||
}
|
||||
res.usedByTheApp += Number(c.get("allocatedMB"));
|
||||
}
|
||||
});
|
||||
|
||||
for (var nodeId in nodeToResources) {
|
||||
var res = nodeToResources[nodeId];
|
||||
|
||||
var subArr = [];
|
||||
var value = res.usedByTheApp ? res.usedByTheApp : 0;
|
||||
subArr.push({
|
||||
value: value,
|
||||
bindText: "This app uses " + Converter.memoryToSimpliedUnit(value) + ". On node=" + nodeId,
|
||||
});
|
||||
|
||||
value = res.used - value;
|
||||
value = Math.max(value, 0);
|
||||
subArr.push({
|
||||
value: value,
|
||||
bindText: "Other applications uses " + Converter.memoryToSimpliedUnit(value) + ". On node=" + nodeId,
|
||||
});
|
||||
|
||||
subArr.push({
|
||||
value: res.avail,
|
||||
bindText: "Free resource " + Converter.memoryToSimpliedUnit(res.avail) + " . On node=" + nodeId
|
||||
});
|
||||
|
||||
arr.push(subArr);
|
||||
}
|
||||
|
||||
console.log(arr);
|
||||
|
||||
return arr;
|
||||
},
|
||||
|
||||
didInsertElement: function() {
|
||||
this.initChart(true);
|
||||
|
||||
this.colors = ["Orange", "Grey", "LimeGreen"];
|
||||
|
||||
var containers = this.get("rmContainers");
|
||||
var nodes = this.get("nodes");
|
||||
|
||||
var data = this.getDataForRender(containers, nodes);
|
||||
|
||||
this.show(
|
||||
data, this.get("title"), ["Used by this app", "Used by other apps",
|
||||
"Available"]);
|
||||
},
|
||||
})
|
|
@ -0,0 +1,67 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import StackedBarchart from 'yarn-ui/components/stacked-barchart';
|
||||
|
||||
export default StackedBarchart.extend({
|
||||
getDataForRender: function(containers, nodes) {
|
||||
var arr = [];
|
||||
var nodeToContainers = {};
|
||||
nodes.forEach(function(n) {
|
||||
nodeToContainers[n.id] = 0;
|
||||
});
|
||||
|
||||
containers.forEach(function(c) {
|
||||
var nodeId = c.get("assignedNodeId");
|
||||
var n = nodeToContainers[nodeId];
|
||||
if (undefined != n) {
|
||||
nodeToContainers[nodeId] += 1;
|
||||
}
|
||||
});
|
||||
|
||||
for (var nodeId in nodeToContainers) {
|
||||
var n = nodeToContainers[nodeId];
|
||||
|
||||
var subArr = [];
|
||||
subArr.push({
|
||||
value: n,
|
||||
bindText: "This app has " + n + " containers running on node=" + nodeId
|
||||
});
|
||||
|
||||
arr.push(subArr);
|
||||
}
|
||||
|
||||
console.log(arr);
|
||||
|
||||
return arr;
|
||||
},
|
||||
|
||||
didInsertElement: function() {
|
||||
this.initChart(true);
|
||||
|
||||
this.colors = ["Orange", "Grey", "Gainsboro"];
|
||||
|
||||
var containers = this.get("rmContainers");
|
||||
var nodes = this.get("nodes");
|
||||
|
||||
var data = this.getDataForRender(containers, nodes);
|
||||
|
||||
this.show(
|
||||
data, this.get("title"), ["Running containers from this app"]);
|
||||
},
|
||||
})
|
|
@ -0,0 +1,69 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Ember from 'ember';
|
||||
import DonutChart from 'yarn-ui/components/donut-chart';
|
||||
import BaseUsageDonutChart from 'yarn-ui/components/base-usage-donut-chart';
|
||||
import ColorUtils from 'yarn-ui/utils/color-utils';
|
||||
import HrefAddressUtils from 'yarn-ui/utils/href-address-utils';
|
||||
|
||||
export default BaseUsageDonutChart.extend({
|
||||
colors: d3.scale.category20().range(),
|
||||
|
||||
draw: function() {
|
||||
this.initChart();
|
||||
var usageByQueues = [];
|
||||
var avail = 100;
|
||||
|
||||
this.get("data").forEach(function (queue) {
|
||||
var v = queue.get("absUsedCapacity");
|
||||
|
||||
if (queue.get("isLeafQueue")) {
|
||||
if (v > 1e-2) {
|
||||
usageByQueues.push({
|
||||
label: queue.get("id"),
|
||||
link: HrefAddressUtils.getQueueLink(queue.get("id")),
|
||||
value: v.toFixed(2)
|
||||
});
|
||||
|
||||
avail = avail - v;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
usageByQueues.sort(function(a, b) {
|
||||
return b.value - a.value;
|
||||
});
|
||||
|
||||
usageByQueues = this.mergeLongTails(usageByQueues, 8);
|
||||
|
||||
usageByQueues.push({
|
||||
label: "Available",
|
||||
value: avail.toFixed(4)
|
||||
});
|
||||
|
||||
this.colors = ColorUtils.getColors(usageByQueues.length, ["others", "good"], true);
|
||||
|
||||
this.renderDonutChart(usageByQueues, this.get("title"), this.get("showLabels"),
|
||||
this.get("middleLabel"), "100%", "%");
|
||||
},
|
||||
|
||||
didInsertElement: function() {
|
||||
this.draw();
|
||||
},
|
||||
})
|
|
@ -90,7 +90,6 @@ export default Ember.Component.extend(ChartUtilsMixin, {
|
|||
.attr("class", "queue");
|
||||
|
||||
circle.on('mouseover', function () {
|
||||
circle.style("fill", this.queueColors[1]);
|
||||
}.bind(this));
|
||||
circle.on('mouseout', function () {
|
||||
if (circle != this.queues.selectedQueueCircle) {
|
||||
|
@ -206,7 +205,7 @@ export default Ember.Component.extend(ChartUtilsMixin, {
|
|||
|
||||
renderQueueCapacities: function (queue, layout) {
|
||||
// Render bar chart
|
||||
this.renderBarChart(this.charts.g, [{
|
||||
this.renderCells(this.charts.g, [{
|
||||
label: "Cap",
|
||||
value: queue.get("capacity")
|
||||
}, {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
|
@ -24,6 +25,7 @@ export default Ember.Component.extend({
|
|||
var ordering = this.get("ordering") ? true : this.get("ordering");
|
||||
var info = this.get("info") ? true : this.get("info");
|
||||
var bFilter = this.get("bFilter") ? true : this.get("bFilter");
|
||||
var defaultSearch = this.get("defaultSearch") ? this.get("defaultSearch") : "";
|
||||
|
||||
// Defines sorter for the columns if not default.
|
||||
// Can also specify a custom sorter.
|
||||
|
@ -66,11 +68,14 @@ export default Ember.Component.extend({
|
|||
console.log(orderArr[0]);
|
||||
Ember.$('#' + this.get('table-id')).DataTable({
|
||||
"paging": paging,
|
||||
"ordering": ordering,
|
||||
"ordering": ordering,
|
||||
"info": info,
|
||||
"bFilter": bFilter,
|
||||
"order": orderArr,
|
||||
"columnDefs": colDefs
|
||||
"columnDefs": colDefs,
|
||||
"oSearch": {
|
||||
"sSearch": defaultSearch
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
@ -0,0 +1,198 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import BaseChartComponent from 'yarn-ui/components/base-chart-component';
|
||||
import Mock from 'yarn-ui/utils/mock';
|
||||
|
||||
export default BaseChartComponent.extend({
|
||||
MAX_BAR_HEIGHT: 120,
|
||||
MAX_BAR_WIDTH: 30,
|
||||
GAP: 5,
|
||||
filter: "",
|
||||
WIDTH_OF_SAMPLE: 200,
|
||||
|
||||
bindTP: function(element) {
|
||||
element.on("mouseover", function() {
|
||||
this.tooltip
|
||||
.style("left", (d3.event.pageX) + "px")
|
||||
.style("top", (d3.event.pageY - 28) + "px");
|
||||
element.style("opacity", 1.0);
|
||||
}.bind(this))
|
||||
.on("mousemove", function() {
|
||||
// Handle pie chart case
|
||||
var text = element.attr("tooltiptext");
|
||||
|
||||
this.tooltip.style("opacity", .9);
|
||||
this.tooltip.html(text)
|
||||
.style("left", (d3.event.pageX) + "px")
|
||||
.style("top", (d3.event.pageY - 28) + "px");
|
||||
}.bind(this))
|
||||
.on("mouseout", function() {
|
||||
this.tooltip.style("opacity", 0);
|
||||
element.style("opacity", 0.8);
|
||||
}.bind(this));
|
||||
|
||||
element.on("click", function() {
|
||||
if (element.attr("link")) {
|
||||
this.tooltip.remove();
|
||||
document.location.href = element.attr("link");
|
||||
}
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
printSamples: function(n, layout, g, colorTitles) {
|
||||
var yOffset = layout.margin * 3;
|
||||
|
||||
for (var i = 0; i < n; i++) {
|
||||
var xOffset = layout.x2 - this.WIDTH_OF_SAMPLE - layout.margin;
|
||||
g.append("rect").
|
||||
attr("fill", this.colors[i]).
|
||||
attr("x", xOffset).
|
||||
attr("y", yOffset).
|
||||
attr("width", 20).
|
||||
attr("height", 20);
|
||||
|
||||
g.append("text").
|
||||
attr("x", xOffset + 30).
|
||||
attr("y", yOffset + 10).
|
||||
text(colorTitles[i]);
|
||||
|
||||
yOffset = yOffset + 30;
|
||||
}
|
||||
},
|
||||
|
||||
// data:
|
||||
// [[{value=xx, bindText=xx}, {value=yy, bindText=yy}], [ ... ]]
|
||||
// __________________________________________________ ___________
|
||||
// bar-1 bar-2
|
||||
show: function (data, title, colorTitles) {
|
||||
var width = this.MAX_BAR_WIDTH;
|
||||
var height = this.MAX_BAR_HEIGHT;
|
||||
|
||||
this.chart.g.remove();
|
||||
this.chart.g = this.chart.svg.append("g");
|
||||
var g = this.chart.g;
|
||||
var layout = this.getLayout();
|
||||
layout.margin = 50;
|
||||
|
||||
var nBarPerRow = Math.floor((layout.x2 - layout.x1 - 3 * layout.margin -
|
||||
this.WIDTH_OF_SAMPLE) /
|
||||
(width + this.GAP));
|
||||
|
||||
var xOffset;
|
||||
var yOffset = layout.margin * 2;
|
||||
|
||||
var maxValue = 0;
|
||||
var maxN = 0;
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var total = 0;
|
||||
for (var j = 0; j < data[i].length; j++) {
|
||||
total += data[i][j].value;
|
||||
}
|
||||
|
||||
if (total > maxValue) {
|
||||
maxValue = total;
|
||||
}
|
||||
if (data[i].length > maxN) {
|
||||
maxN = data[i].length;
|
||||
}
|
||||
}
|
||||
|
||||
// print samples
|
||||
this.printSamples(maxN, layout, g, colorTitles);
|
||||
|
||||
// print data
|
||||
data.sort(function(a, b) {
|
||||
return b[0].value - a[0].value;
|
||||
});
|
||||
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
if (i % nBarPerRow == 0) {
|
||||
xOffset = layout.margin;
|
||||
yOffset += layout.margin + height;
|
||||
}
|
||||
|
||||
var leftTopY = yOffset;
|
||||
for (var j = 0; j < data[i].length; j++) {
|
||||
var dy = data[i][j].value * height / maxValue;
|
||||
if (dy > 0) {
|
||||
leftTopY = leftTopY - dy;
|
||||
|
||||
var node = g.append("rect").
|
||||
attr("fill", this.colors[j]).
|
||||
attr("x", xOffset).
|
||||
attr("y", leftTopY).
|
||||
attr("width", width).
|
||||
attr("height", dy).
|
||||
attr("tooltiptext",
|
||||
(data[i][j].bindText) ? data[i][j].bindText : data[i][j].value).
|
||||
attr("link", data[i][j].link)
|
||||
.style("opacity", 0.8);
|
||||
|
||||
this.bindTP(node);
|
||||
}
|
||||
}
|
||||
|
||||
if (data[i].length == 1) {
|
||||
g.append("text")
|
||||
.text(data[i][0].value)
|
||||
.attr("y", leftTopY - 10)
|
||||
.attr("x", xOffset + width / 2)
|
||||
.attr("class", "heatmap-cell")
|
||||
.style("fill", "black");
|
||||
}
|
||||
|
||||
xOffset += width + this.GAP;
|
||||
}
|
||||
|
||||
layout.y2 = yOffset + layout.margin;
|
||||
this.adjustMaxHeight(layout.y2);
|
||||
this.renderTitleAndBG(g, title, layout, false);
|
||||
},
|
||||
|
||||
draw: function(data, title, textWidth) {
|
||||
this.initChart(true);
|
||||
//Mock.initMockNodesData(this);
|
||||
|
||||
// mock data
|
||||
var arr = [];
|
||||
for (var i = 0; i < 5; i++) {
|
||||
var subArr = [];
|
||||
for (var j = 0; j < Math.random() * 4 + 1; j++) {
|
||||
subArr.push({
|
||||
value : Math.abs(Math.random())
|
||||
});
|
||||
}
|
||||
arr.push(subArr);
|
||||
}
|
||||
|
||||
this.show(
|
||||
arr, this.get("title"));
|
||||
},
|
||||
|
||||
didInsertElement: function () {
|
||||
this.draw();
|
||||
},
|
||||
|
||||
actions: {
|
||||
applyFilter: function(event) {
|
||||
this.filter = event.srcElement.value;
|
||||
this.didInsertElement();
|
||||
}
|
||||
}
|
||||
})
|
|
@ -105,7 +105,7 @@ export default Ember.Component.extend({
|
|||
var border = 30;
|
||||
var singleBarHeight = this.getPerItemHeight();
|
||||
var gap = this.getPerItemGap();
|
||||
var textWidth = 50;
|
||||
var textWidth = 200;
|
||||
/*
|
||||
start-time end-time
|
||||
|--------------------------------------|
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
import Ember from 'ember';
|
||||
|
||||
const INBETWEEN_HEIGHT = 130;
|
||||
|
||||
export default Ember.Component.extend({
|
||||
// Map: <queue-name, queue>
|
||||
map : undefined,
|
||||
|
@ -124,12 +126,25 @@ export default Ember.Component.extend({
|
|||
var nodeEnter = node.enter().append("g")
|
||||
.attr("class", "node")
|
||||
.attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
|
||||
.on("click", function(d,i){
|
||||
.on("mouseover", function(d,i){
|
||||
if (d.queueData.get("name") != this.get("selected")) {
|
||||
document.location.href = "#/yarn-queue/" + d.queueData.get("name");
|
||||
document.location.href = "#/yarn-queues/" + d.queueData.get("name");
|
||||
}
|
||||
}.bind(this));
|
||||
// .on("click", click);
|
||||
|
||||
Ember.run.later(this, function () {
|
||||
var treeWidth = this.maxDepth * 200;
|
||||
var treeHeight = this.numOfLeafQueue * INBETWEEN_HEIGHT;
|
||||
var tree = d3.layout.tree().size([treeHeight, treeWidth]);
|
||||
var diagonal = d3.svg.diagonal()
|
||||
.projection(function(d) { return [d.y, d.x]; });
|
||||
|
||||
this.update(this.treeData, this.treeData, tree, diagonal);
|
||||
}, 100);
|
||||
|
||||
}.bind(this))
|
||||
.on("click", function (d) {
|
||||
document.location.href = "#/yarn-queue/" + d.queueData.get("name");
|
||||
});
|
||||
|
||||
nodeEnter.append("circle")
|
||||
.attr("r", 1e-6)
|
||||
|
@ -148,6 +163,7 @@ export default Ember.Component.extend({
|
|||
nodeEnter.append("text")
|
||||
.attr("x", function(d) { return 0; })
|
||||
.attr("dy", ".35em")
|
||||
.attr("fill", "white")
|
||||
.attr("text-anchor", function(d) { return "middle"; })
|
||||
.text(function(d) {
|
||||
var usedCap = d.queueData.get("usedCapacity");
|
||||
|
@ -161,9 +177,9 @@ export default Ember.Component.extend({
|
|||
|
||||
// append queue name
|
||||
nodeEnter.append("text")
|
||||
.attr("x", function(d) { return 40; })
|
||||
.attr("dy", ".35em")
|
||||
.attr("text-anchor", function(d) { return "start"; })
|
||||
.attr("x", "0px")
|
||||
.attr("dy", "45px")
|
||||
.attr("text-anchor", "middle")
|
||||
.text(function(d) { return d.name; })
|
||||
.style("fill-opacity", 1e-6);
|
||||
|
||||
|
@ -173,14 +189,21 @@ export default Ember.Component.extend({
|
|||
.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });
|
||||
|
||||
nodeUpdate.select("circle")
|
||||
.attr("r", 20)
|
||||
.attr("r", 30)
|
||||
.attr("href",
|
||||
function(d) {
|
||||
return "#/yarn-queues/" + d.queueData.get("name");
|
||||
})
|
||||
.style("stroke-width", function(d) {
|
||||
if (d.queueData.get("name") == this.get("selected")) {
|
||||
return 7;
|
||||
} else {
|
||||
return 2;
|
||||
}
|
||||
}.bind(this))
|
||||
.style("stroke", function(d) {
|
||||
if (d.queueData.get("name") == this.get("selected")) {
|
||||
return "red";
|
||||
return "gray";
|
||||
} else {
|
||||
return "gray";
|
||||
}
|
||||
|
@ -239,7 +262,7 @@ export default Ember.Component.extend({
|
|||
|
||||
var margin = {top: 20, right: 120, bottom: 20, left: 120};
|
||||
var treeWidth = this.maxDepth * 200;
|
||||
var treeHeight = this.numOfLeafQueue * 80;
|
||||
var treeHeight = this.numOfLeafQueue * INBETWEEN_HEIGHT;
|
||||
var width = treeWidth + margin.left + margin.right;
|
||||
var height = treeHeight + margin.top + margin.bottom;
|
||||
var layout = { };
|
||||
|
|
|
@ -20,4 +20,13 @@ import Ember from 'ember';
|
|||
|
||||
export default Ember.Controller.extend({
|
||||
loading: true,
|
||||
|
||||
breadcrumbs: [{
|
||||
text: "Home",
|
||||
routeName: 'application'
|
||||
}, {
|
||||
text: "Cluster Overview",
|
||||
routeName: 'cluster-overview',
|
||||
}]
|
||||
|
||||
});
|
|
@ -0,0 +1,40 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
|
||||
breadcrumbs: Ember.computed("model.attempt.appId", function () {
|
||||
var appId = this.get("model.attempt.appId");
|
||||
return [{
|
||||
text: "Home",
|
||||
routeName: 'application'
|
||||
},{
|
||||
text: "Applications",
|
||||
routeName: 'yarn-apps'
|
||||
}, {
|
||||
text: `App [${appId}]`,
|
||||
routeName: 'yarn-app',
|
||||
model: appId
|
||||
}, {
|
||||
text: "Attempt",
|
||||
}];
|
||||
})
|
||||
|
||||
});
|
|
@ -0,0 +1,40 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
|
||||
breadcrumbs: Ember.computed("model.appId", function () {
|
||||
var appId = this.get("model.appId");
|
||||
return [{
|
||||
text: "Home",
|
||||
routeName: 'application'
|
||||
},{
|
||||
text: "Applications",
|
||||
routeName: 'yarn-apps'
|
||||
}, {
|
||||
text: `App [${appId}]`,
|
||||
routeName: 'yarn-app',
|
||||
model: appId
|
||||
}, {
|
||||
text: "Attempts",
|
||||
}];
|
||||
})
|
||||
|
||||
});
|
|
@ -0,0 +1,38 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
|
||||
breadcrumbs: Ember.computed("model.app.id", function () {
|
||||
var appId = this.get("model.app.id");
|
||||
return [{
|
||||
text: "Home",
|
||||
routeName: 'application'
|
||||
},{
|
||||
text: "Applications",
|
||||
routeName: 'yarn-apps'
|
||||
}, {
|
||||
text: `App [${appId}]`,
|
||||
routeName: 'yarn-app',
|
||||
model: appId
|
||||
}];
|
||||
})
|
||||
|
||||
});
|
|
@ -19,4 +19,13 @@
|
|||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
|
||||
breadcrumbs: [{
|
||||
text: "Home",
|
||||
routeName: 'application'
|
||||
}, {
|
||||
text: "Applications",
|
||||
routeName: 'yarn-apps',
|
||||
}]
|
||||
|
||||
});
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
|
||||
breadcrumbs: Ember.computed("model.attempt.appId", function () {
|
||||
var nodeInfo = this.get("model.nodeInfo");
|
||||
return [{
|
||||
text: "Home",
|
||||
routeName: 'application'
|
||||
},{
|
||||
text: "Nodes",
|
||||
routeName: 'yarn-nodes'
|
||||
}, {
|
||||
text: `Node [ ${nodeInfo.id} ]`,
|
||||
href: `/#/yarn-node/${nodeInfo.id}/${nodeInfo.addr}`,
|
||||
}, {
|
||||
text: "Applications",
|
||||
}];
|
||||
})
|
||||
|
||||
});
|
|
@ -0,0 +1,39 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
|
||||
breadcrumbs: Ember.computed("model.nodeInfo", function () {
|
||||
var nodeInfo = this.get("model.nodeInfo");
|
||||
return [{
|
||||
text: "Home",
|
||||
routeName: 'application'
|
||||
},{
|
||||
text: "Nodes",
|
||||
routeName: 'yarn-nodes'
|
||||
}, {
|
||||
text: `Node [ ${nodeInfo.id} ]`,
|
||||
href: `/#/yarn-node/${nodeInfo.id}/${nodeInfo.addr}`,
|
||||
}, {
|
||||
text: "Containers",
|
||||
}];
|
||||
})
|
||||
|
||||
});
|
|
@ -0,0 +1,37 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
|
||||
breadcrumbs: Ember.computed("model.attempt.appId", function () {
|
||||
var nodeInfo = this.get("model.nodeInfo");
|
||||
return [{
|
||||
text: "Home",
|
||||
routeName: 'application'
|
||||
},{
|
||||
text: "Nodes",
|
||||
routeName: 'yarn-nodes'
|
||||
}, {
|
||||
text: `Node [ ${nodeInfo.id} ]`,
|
||||
href: `/#/yarn-node/${nodeInfo.id}/${nodeInfo.addr}`,
|
||||
}];
|
||||
})
|
||||
|
||||
});
|
|
@ -0,0 +1,36 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
needReload: true,
|
||||
selectedQueue: undefined,
|
||||
|
||||
breadcrumbs: [{
|
||||
text: "Home",
|
||||
routeName: 'application'
|
||||
}, {
|
||||
text: "Nodes",
|
||||
routeName: 'yarn-nodes',
|
||||
}, {
|
||||
text: "Heatmap",
|
||||
routeName: 'yarn-nodes-heatmap',
|
||||
}]
|
||||
|
||||
});
|
|
@ -0,0 +1,33 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
needReload: true,
|
||||
selectedQueue: undefined,
|
||||
|
||||
breadcrumbs: [{
|
||||
text: "Home",
|
||||
routeName: 'application'
|
||||
}, {
|
||||
text: "Nodes",
|
||||
routeName: 'yarn-nodes',
|
||||
}]
|
||||
|
||||
});
|
|
@ -0,0 +1,46 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
needReload: true,
|
||||
selectedQueue: undefined,
|
||||
|
||||
breadcrumbs: Ember.computed("model.selected", function () {
|
||||
var queueName = this.get("model.selected");
|
||||
|
||||
return [{
|
||||
text: "Home",
|
||||
routeName: 'application'
|
||||
}, {
|
||||
text: "Queues",
|
||||
routeName: 'yarn-queues',
|
||||
model: 'root'
|
||||
}, {
|
||||
text: `Queue [ ${queueName} ]`,
|
||||
routeName: 'yarn-queue',
|
||||
model: queueName
|
||||
}, {
|
||||
text: "Applications",
|
||||
}];
|
||||
|
||||
}),
|
||||
|
||||
|
||||
});
|
|
@ -21,4 +21,24 @@ import Ember from 'ember';
|
|||
export default Ember.Controller.extend({
|
||||
needReload: true,
|
||||
selectedQueue: undefined,
|
||||
|
||||
breadcrumbs: Ember.computed("model.selected", function () {
|
||||
var queueName = this.get("model.selected");
|
||||
|
||||
return [{
|
||||
text: "Home",
|
||||
routeName: 'application'
|
||||
}, {
|
||||
text: "Queues",
|
||||
routeName: 'yarn-queues',
|
||||
model: 'root'
|
||||
}, {
|
||||
text: `Queue [ ${queueName} ]`,
|
||||
routeName: 'yarn-queue',
|
||||
model: queueName
|
||||
}];
|
||||
|
||||
}),
|
||||
|
||||
|
||||
});
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
needReload: true,
|
||||
selectedQueue: undefined,
|
||||
|
||||
breadcrumbs: [{
|
||||
text: "Home",
|
||||
routeName: 'application'
|
||||
}, {
|
||||
text: "Queues",
|
||||
routeName: 'yarn-queues',
|
||||
model: 'root'
|
||||
}]
|
||||
|
||||
});
|
|
@ -0,0 +1,34 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
|
||||
breadcrumbs: [{
|
||||
text: "Home",
|
||||
routeName: 'application'
|
||||
}, {
|
||||
text: "Applications",
|
||||
routeName: 'yarn-apps',
|
||||
}, {
|
||||
text: "Long Running Services",
|
||||
routeName: 'yarn-services',
|
||||
}]
|
||||
|
||||
});
|
|
@ -125,7 +125,7 @@ export default DS.Model.extend({
|
|||
});
|
||||
arr.push({
|
||||
label: "Available",
|
||||
value: this.get("available" + type)
|
||||
value: Math.max(this.get("available" + type), 0)
|
||||
});
|
||||
|
||||
return arr;
|
||||
|
|
|
@ -30,6 +30,17 @@ export default DS.Model.extend({
|
|||
hosts: DS.attr('string'),
|
||||
logsLink: DS.attr('string'),
|
||||
state: DS.attr('string'),
|
||||
appAttemptId: DS.attr('string'),
|
||||
|
||||
appId: Ember.computed("id",function () {
|
||||
var id = this.get("id");
|
||||
id = id.split("_");
|
||||
|
||||
id[0] = "application";
|
||||
id.pop();
|
||||
|
||||
return id.join("_");
|
||||
}),
|
||||
|
||||
attemptStartedTime: function() {
|
||||
var startTime = this.get("startTime");
|
||||
|
|
|
@ -36,6 +36,7 @@ export default DS.Model.extend({
|
|||
unmanagedApplication: DS.attr('string'),
|
||||
amNodeLabelExpression: DS.attr('string'),
|
||||
applicationTags: DS.attr('string'),
|
||||
applicationType: DS.attr('string'),
|
||||
priority: DS.attr('number'),
|
||||
allocatedMB: DS.attr('number'),
|
||||
allocatedVCores: DS.attr('number'),
|
||||
|
@ -46,6 +47,9 @@ export default DS.Model.extend({
|
|||
preemptedResourceVCores: DS.attr('number'),
|
||||
numNonAMContainerPreempted: DS.attr('number'),
|
||||
numAMContainerPreempted: DS.attr('number'),
|
||||
clusterUsagePercentage: DS.attr('number'),
|
||||
queueUsagePercentage: DS.attr('number'),
|
||||
currentAppAttemptId: DS.attr('string'),
|
||||
|
||||
isFailed: function() {
|
||||
return this.get('finalStatus') == "FAILED"
|
||||
|
|
|
@ -89,4 +89,11 @@ export default DS.Model.extend({
|
|||
});
|
||||
return arr;
|
||||
}.property("availableVirtualCores", "usedVirtualCores"),
|
||||
|
||||
toolTipText: function() {
|
||||
return "<p>Rack: " + this.get("rack") + '</p>' +
|
||||
"<p>Host: " + this.get("nodeHostName") + '</p>' +
|
||||
"<p>Used Memory: " + Math.round(this.get("usedMemoryMB")) + ' MB</p>' +
|
||||
"<p>Available Memory: " + Math.round(this.get("availMemoryMB")) + ' MB</p>';
|
||||
}.property(),
|
||||
});
|
||||
|
|
|
@ -24,8 +24,15 @@ var Router = Ember.Router.extend({
|
|||
});
|
||||
|
||||
Router.map(function() {
|
||||
this.route('yarn-apps');
|
||||
this.route('yarn-nodes');
|
||||
this.route('yarn-apps', function () {
|
||||
this.route('apps');
|
||||
this.route('services');
|
||||
});
|
||||
this.route('yarn-nodes', function(){
|
||||
this.route('table');
|
||||
this.route('heatmap');
|
||||
});
|
||||
this.route('yarn-nodes-heatmap');
|
||||
this.route('yarn-node', { path: '/yarn-node/:node_id/:node_addr' });
|
||||
this.route('yarn-node-apps', { path: '/yarn-node-apps/:node_id/:node_addr' });
|
||||
this.route('yarn-node-app',
|
||||
|
@ -37,11 +44,15 @@ Router.map(function() {
|
|||
this.route('yarn-container-log', { path:
|
||||
'/yarn-container-log/:node_id/:node_addr/:container_id/:filename' });
|
||||
this.route('yarn-queue', { path: '/yarn-queue/:queue_name' });
|
||||
|
||||
this.route('cluster-overview');
|
||||
this.route('yarn-app', { path: '/yarn-app/:app_id' });
|
||||
this.route('yarn-app-attempt', { path: '/yarn-app-attempt/:app_attempt_id'});
|
||||
this.route('error');
|
||||
this.route('notfound', { path: '*:' });
|
||||
this.route('yarn-app-attempts', { path: '/yarn-app-attempts/:app_id' });
|
||||
this.route('yarn-queues', { path: '/yarn-queues/:queue_name' });
|
||||
this.route('yarn-queue-apps', { path: '/yarn-queue-apps/:queue_name' });
|
||||
});
|
||||
|
||||
export default Router;
|
||||
|
|
|
@ -27,6 +27,8 @@ export default Ember.Route.extend({
|
|||
* error handler page.
|
||||
*/
|
||||
error: function (error) {
|
||||
Ember.Logger.log(error.stack);
|
||||
|
||||
if (error && error.errors[0] &&
|
||||
error.errors[0].status == 404) {
|
||||
this.intermediateTransitionTo('/notfound');
|
||||
|
|
|
@ -20,7 +20,14 @@ import Ember from 'ember';
|
|||
|
||||
export default Ember.Route.extend({
|
||||
model() {
|
||||
return this.store.findAll('ClusterMetric');
|
||||
return Ember.RSVP.hash({
|
||||
clusterMetrics: this.store.findAll('ClusterMetric'),
|
||||
apps: this.store.query('yarn-app',
|
||||
{
|
||||
state: "RUNNING"
|
||||
}),
|
||||
queues: this.store.findAll('yarn-queue'),
|
||||
});
|
||||
},
|
||||
|
||||
afterModel() {
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Route.extend({
|
||||
model(param) {
|
||||
return this.store.query('yarn-app-attempt', { appId: param.app_id}).then(function (attempts) {
|
||||
return {
|
||||
appId: param.app_id,
|
||||
attempts: attempts
|
||||
};
|
||||
});
|
||||
}
|
||||
});
|
|
@ -22,7 +22,22 @@ export default Ember.Route.extend({
|
|||
model(param) {
|
||||
return Ember.RSVP.hash({
|
||||
app: this.store.find('yarn-app', param.app_id),
|
||||
attempts: this.store.query('yarn-app-attempt', { appId: param.app_id})
|
||||
|
||||
rmContainers: this.store.find('yarn-app', param.app_id).then(function(app) {
|
||||
return this.store.query('yarn-app-attempt', {appId: param.app_id}).then(function (attempts) {
|
||||
if (attempts && attempts.get('firstObject')) {
|
||||
var appAttemptId = attempts.get('firstObject').get('appAttemptId');
|
||||
var rmContainers = this.store.query('yarn-container',
|
||||
{
|
||||
app_attempt_id: appAttemptId,
|
||||
is_rm: true
|
||||
});
|
||||
return rmContainers;
|
||||
}
|
||||
}.bind(this));
|
||||
}.bind(this)),
|
||||
|
||||
nodes: this.store.findAll('yarn-rm-node'),
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
@ -20,7 +20,9 @@ import Ember from 'ember';
|
|||
|
||||
export default Ember.Route.extend({
|
||||
model() {
|
||||
var apps = this.store.findAll('yarn-app');
|
||||
return apps;
|
||||
return Ember.RSVP.hash({
|
||||
apps: this.store.findAll('yarn-app'),
|
||||
clusterMetrics: this.store.findAll('ClusterMetric'),
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Route.extend({
|
||||
});
|
|
@ -0,0 +1,22 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Route.extend({
|
||||
});
|
|
@ -22,6 +22,7 @@ export default Ember.Route.extend({
|
|||
model(param) {
|
||||
// Fetches data from both NM and RM. RM is queried to get node usage info.
|
||||
return Ember.RSVP.hash({
|
||||
nodeInfo: { id: param.node_id, addr: param.node_addr },
|
||||
node: this.store.findRecord('yarn-node', param.node_addr),
|
||||
rmNode: this.store.findRecord('yarn-rm-node', param.node_id)
|
||||
});
|
||||
|
|
|
@ -20,6 +20,9 @@ import Ember from 'ember';
|
|||
|
||||
export default Ember.Route.extend({
|
||||
model() {
|
||||
return this.store.findAll('yarn-rm-node');
|
||||
return Ember.RSVP.hash({
|
||||
nodes: this.store.findAll('yarn-rm-node'),
|
||||
clusterMetrics: this.store.findAll('ClusterMetric'),
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Route.extend({
|
||||
});
|
|
@ -0,0 +1,22 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Route.extend({
|
||||
});
|
|
@ -0,0 +1,36 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Route.extend({
|
||||
model(param) {
|
||||
return Ember.RSVP.hash({
|
||||
selected : param.queue_name,
|
||||
queues: this.store.findAll('yarn-queue'),
|
||||
selectedQueue : undefined,
|
||||
apps: undefined, // apps of selected queue
|
||||
});
|
||||
},
|
||||
|
||||
afterModel(model) {
|
||||
var store = this.store;
|
||||
model.selectedQueue = this.store.peekRecord('yarn-queue', model.selected);
|
||||
model.apps = store.findAll('yarn-app');
|
||||
}
|
||||
});
|
|
@ -0,0 +1,38 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Route.extend({
|
||||
model(param) {
|
||||
return Ember.RSVP.hash({
|
||||
selected : param.queue_name,
|
||||
queues: this.store.findAll('yarn-queue'),
|
||||
selectedQueue : undefined,
|
||||
apps: undefined, // apps of selected queue
|
||||
});
|
||||
},
|
||||
|
||||
afterModel(model) {
|
||||
model.selectedQueue = this.store.peekRecord('yarn-queue', model.selected);
|
||||
model.apps = this.store.findAll('yarn-app');
|
||||
model.apps.forEach(function(o) {
|
||||
console.log(o);
|
||||
})
|
||||
}
|
||||
});
|
|
@ -40,7 +40,8 @@ export default DS.JSONAPISerializer.extend({
|
|||
nodeId: payload.nodeId,
|
||||
hosts: payload.host,
|
||||
state: payload.appAttemptState,
|
||||
logsLink: payload.logsLink
|
||||
logsLink: payload.logsLink,
|
||||
appAttemptId: payload.appAttemptId
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -59,12 +60,16 @@ export default DS.JSONAPISerializer.extend({
|
|||
// return expected is { data: [ {}, {} ] }
|
||||
var normalizedArrayResponse = {};
|
||||
|
||||
// payload has apps : { app: [ {},{},{} ] }
|
||||
// need some error handling for ex apps or app may not be defined.
|
||||
normalizedArrayResponse.data = payload.appAttempts.appAttempt.map(singleApp => {
|
||||
return this.internalNormalizeSingleResponse(store, primaryModelClass,
|
||||
singleApp, singleApp.id, requestType);
|
||||
}, this);
|
||||
if (payload.appAttempts && payload.appAttempts.appAttempt) {
|
||||
// payload has apps : { app: [ {},{},{} ] }
|
||||
// need some error handling for ex apps or app may not be defined.
|
||||
normalizedArrayResponse.data = payload.appAttempts.appAttempt.map(singleApp => {
|
||||
return this.internalNormalizeSingleResponse(store, primaryModelClass,
|
||||
singleApp, singleApp.id, requestType);
|
||||
}, this);
|
||||
} else {
|
||||
normalizedArrayResponse.data = [];
|
||||
}
|
||||
return normalizedArrayResponse;
|
||||
}
|
||||
});
|
|
@ -39,6 +39,7 @@ export default DS.JSONAPISerializer.extend({
|
|||
finishedTime: Converter.timeStampToDate(payload.finishedTime),
|
||||
finalStatus: payload.finalStatus,
|
||||
progress: payload.progress,
|
||||
applicationType: payload.applicationType,
|
||||
diagnostics: payload.diagnostics,
|
||||
amContainerLogs: payload.amContainerLogs,
|
||||
amHostHttpAddress: payload.amHostHttpAddress,
|
||||
|
@ -54,7 +55,10 @@ export default DS.JSONAPISerializer.extend({
|
|||
preemptedResourceMB: payload.preemptedResourceMB,
|
||||
preemptedResourceVCores: payload.preemptedResourceVCores,
|
||||
numNonAMContainerPreempted: payload.numNonAMContainerPreempted,
|
||||
numAMContainerPreempted: payload.numAMContainerPreempted
|
||||
numAMContainerPreempted: payload.numAMContainerPreempted,
|
||||
clusterUsagePercentage: payload.clusterUsagePercentage,
|
||||
queueUsagePercentage: payload.queueUsagePercentage,
|
||||
currentAppAttemptId: payload.currentAppAttemptId
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -75,7 +79,7 @@ export default DS.JSONAPISerializer.extend({
|
|||
|
||||
// payload has apps : { app: [ {},{},{} ] }
|
||||
// need some error handling for ex apps or app may not be defined.
|
||||
if(payload.apps) {
|
||||
if(payload.apps && payload.apps.app) {
|
||||
normalizedArrayResponse.data = payload.apps.app.map(singleApp => {
|
||||
return this.internalNormalizeSingleResponse(store, primaryModelClass,
|
||||
singleApp, singleApp.id, requestType);
|
||||
|
|
|
@ -57,13 +57,19 @@ export default DS.JSONAPISerializer.extend({
|
|||
var normalizedArrayResponse = {};
|
||||
|
||||
if (payload && payload.container) {
|
||||
// payload has apps : { app: [ {},{},{} ] }
|
||||
// need some error handling for ex apps or app may not be defined.
|
||||
normalizedArrayResponse.data = payload.container.map(singleContainer => {
|
||||
return this.internalNormalizeSingleResponse(store, primaryModelClass,
|
||||
singleContainer, singleContainer.id, requestType);
|
||||
}, this);
|
||||
return normalizedArrayResponse;
|
||||
if (Array.isArray(payload.container)) {
|
||||
// payload has apps : { app: [ {},{},{} ] }
|
||||
// need some error handling for ex apps or app may not be defined.
|
||||
normalizedArrayResponse.data = payload.container.map(singleContainer => {
|
||||
return this.internalNormalizeSingleResponse(store, primaryModelClass,
|
||||
singleContainer, singleContainer.id, requestType);
|
||||
}, this);
|
||||
} else {
|
||||
normalizedArrayResponse.data = [this.internalNormalizeSingleResponse(
|
||||
store, primaryModelClass, payload.container, payload.container.id,
|
||||
requestType)];
|
||||
}
|
||||
return normalizedArrayResponse;
|
||||
} else {
|
||||
normalizedArrayResponse.data = [];
|
||||
}
|
||||
|
|
|
@ -16,11 +16,20 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
body, html, body > .ember-view {
|
||||
height: 100%;
|
||||
overflow: visible;
|
||||
color: @text-color;
|
||||
}
|
||||
body, html {
|
||||
min-width: 1024px;
|
||||
}
|
||||
|
||||
/*
|
||||
Over all style
|
||||
*/
|
||||
text {
|
||||
font: 12px sans-serif;
|
||||
font: 16px sans-serif;
|
||||
}
|
||||
|
||||
text.small {
|
||||
|
@ -35,6 +44,7 @@ html, body
|
|||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
queue's style (left banner of queues)
|
||||
*/
|
||||
|
@ -45,14 +55,30 @@ text.queue {
|
|||
fill : gray;
|
||||
}
|
||||
|
||||
path.queue {
|
||||
stroke: gray;
|
||||
fill: none;
|
||||
text.heatmap-cell {
|
||||
font: 14px sans-serif;
|
||||
font-weight: bold;
|
||||
text-anchor: middle;
|
||||
fill: Azure;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
circle.queue {
|
||||
r: 10;
|
||||
fill: Steelblue;
|
||||
text.heatmap-cell-notselected {
|
||||
font: 14px sans-serif;
|
||||
font-weight: bold;
|
||||
text-anchor: middle;
|
||||
fill: Silver;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
text.heatmap-rack {
|
||||
font: 20px sans-serif;
|
||||
fill: DimGray;
|
||||
}
|
||||
|
||||
path.queue {
|
||||
stroke: "red";
|
||||
fill: none;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -76,24 +102,21 @@ text.chart-title {
|
|||
fill: Gray;
|
||||
}
|
||||
|
||||
text.donut-highlight-text {
|
||||
font-size: 20px;
|
||||
text.donut-highlight-text, text.donut-highlight-sub {
|
||||
font-size: 15px;
|
||||
font-family: sans-serif;
|
||||
text-anchor: middle;
|
||||
fill: Gray;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
rect.chart-frame {
|
||||
fill: none;
|
||||
stroke: gray;
|
||||
stroke-dasharray: 10,10;
|
||||
text.donut-highlight-sub {
|
||||
font-size: 23px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
line.chart-leftbanner {
|
||||
stroke-width: 2;
|
||||
stroke: gray;
|
||||
stroke-dasharray: 10,10;
|
||||
rect.chart-frame {
|
||||
fill: none;
|
||||
}
|
||||
|
||||
text.bar-chart-text {
|
||||
|
@ -106,9 +129,8 @@ text.bar-chart-text {
|
|||
div.tooltip {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
/*height: 28px;*/
|
||||
padding: 2px;
|
||||
font: 12px sans-serif;
|
||||
padding: 2px;
|
||||
font: 24px sans-serif;
|
||||
background: lightsteelblue;
|
||||
border: 0px;
|
||||
border-radius: 8px;
|
||||
|
@ -135,6 +157,19 @@ table.dataTable thead .sorting_desc_disabled {
|
|||
background-image: url("/assets/images/datatables/sort_desc_disabled.png");
|
||||
}
|
||||
|
||||
.add-ellipsis {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.breadcrumb {
|
||||
padding-bottom: 3px;
|
||||
}
|
||||
|
||||
.navbar-default .navbar-nav > li > a {
|
||||
color: #337ab7;
|
||||
}
|
||||
|
||||
/*
|
||||
* Queue selector
|
||||
*/
|
||||
|
@ -158,6 +193,70 @@ table.dataTable thead .sorting_desc_disabled {
|
|||
stroke-width: 2px;
|
||||
}
|
||||
|
||||
.lr-margin {
|
||||
margin: 0px 30px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
background-color: @white;
|
||||
color: @text-color;
|
||||
|
||||
padding: 10px 0px;
|
||||
margin: 0px;
|
||||
|
||||
border-top: 1px lightgrey solid;
|
||||
|
||||
font-size: .9em;
|
||||
}
|
||||
|
||||
.table {
|
||||
margin-bottom: 0px;
|
||||
border: none;
|
||||
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.table-bordered > thead > tr > th, .table-bordered > tbody > tr > th, .table-bordered > tfoot > tr > th, .table-bordered > thead > tr > td, .table-bordered > tbody > tr > td, .table-bordered > tfoot > tr > td {
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.dataTables_wrapper .table {
|
||||
border: 1px solid lightgrey;
|
||||
border-bottom: 1px solid lightgrey !important;
|
||||
border-radious: 5px;
|
||||
}
|
||||
|
||||
.dataTables_wrapper .table-bordered > thead > tr > th, .table-bordered > tbody > tr > th, .table-bordered > tfoot > tr > th, .table-bordered > thead > tr > td, .table-bordered > tbody > tr > td, .table-bordered > tfoot > tr > td {
|
||||
border: 1px solid lightgrey;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 8px 15px 8px 15px !important;
|
||||
}
|
||||
|
||||
.footer-frame {
|
||||
height: 60px;
|
||||
}
|
||||
.footer {
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.footer-pusher {
|
||||
min-height: 100%;
|
||||
height: auto !important;
|
||||
height: 100%;
|
||||
margin: 0 auto -40px; // Must be same as footer & footer-frame
|
||||
}
|
||||
|
||||
.panel-default .container-fluid {
|
||||
margin-top: -45px !important;
|
||||
margin-bottom: -10px !important;
|
||||
}
|
||||
|
||||
.panel-heading {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hadoop-brand-image {
|
||||
margin-top: -10px;
|
||||
width: auto;
|
||||
|
|
|
@ -16,47 +16,70 @@
|
|||
* limitations under the License.
|
||||
}}
|
||||
|
||||
<nav class="navbar navbar-default">
|
||||
<div class="footer-pusher">
|
||||
|
||||
<nav class="navbar navbar-default">
|
||||
<div class="container-fluid">
|
||||
<!-- Brand and toggle get grouped for better mobile display -->
|
||||
<div class="navbar-header">
|
||||
<a class="navbar-brand" href="#">
|
||||
<img class="hadoop-brand-image" alt="Apache Hadoop" src="assets/images/hadoop_logo.png" />
|
||||
</a>
|
||||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Collect the nav links, forms, and other content for toggling -->
|
||||
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
||||
<ul class="nav navbar-nav">
|
||||
{{#link-to 'cluster-overview' tagName="li"}}
|
||||
{{#link-to 'cluster-overview' class="navigation-link"}}Cluster Overview
|
||||
<span class="sr-only">(current)</span>
|
||||
{{/link-to}}
|
||||
{{/link-to}}
|
||||
{{#link-to 'yarn-queues' 'root' tagName="li"}}
|
||||
{{#link-to 'yarn-queues' 'root' class="navigation-link"}}Queues
|
||||
<span class="sr-only">(current)</span>
|
||||
{{/link-to}}
|
||||
{{/link-to}}
|
||||
{{#link-to 'yarn-apps.apps' tagName="li"}}
|
||||
{{#link-to 'yarn-apps.apps' class="navigation-link"}}Applications
|
||||
<span class="sr-only">(current)</span>
|
||||
{{/link-to}}
|
||||
{{/link-to}}
|
||||
{{#link-to 'yarn-nodes.table' tagName="li"}}
|
||||
{{#link-to 'yarn-nodes.table' class="navigation-link"}}Nodes
|
||||
<span class="sr-only">(current)</span>
|
||||
{{/link-to}}
|
||||
{{/link-to}}
|
||||
</ul>
|
||||
</div><!-- /.navbar-collapse -->
|
||||
</div><!-- /.container-fluid -->
|
||||
</nav>
|
||||
|
||||
<div class="container-fluid">
|
||||
<!-- Brand and toggle get grouped for better mobile display -->
|
||||
<div class="navbar-header">
|
||||
<a class="navbar-brand" href="#">
|
||||
<img class="hadoop-brand-image" alt="Apache Hadoop" src="assets/images/hadoop_logo.png" />
|
||||
</a>
|
||||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
{{outlet}}
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
<div class="container-fluid content">
|
||||
<a href={{env.app.hrefs.license}} target="_blank">
|
||||
Licensed under the Apache License, Version 2.0.
|
||||
</a>
|
||||
<div class="ui-info">
|
||||
{{#if env.app.timezone}}
|
||||
<span>Timezone <b>{{env.app.timezone}}</b></span>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<!-- Collect the nav links, forms, and other content for toggling -->
|
||||
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
||||
<ul class="nav navbar-nav">
|
||||
{{#link-to 'yarn-queue' 'root' tagName="li"}}
|
||||
{{#link-to 'yarn-queue' 'root' class="navigation-link"}}Queues
|
||||
<span class="sr-only">(current)</span>
|
||||
{{/link-to}}
|
||||
{{/link-to}}
|
||||
{{#link-to 'yarn-apps' tagName="li"}}
|
||||
{{#link-to 'yarn-apps' class="navigation-link"}}Applications
|
||||
<span class="sr-only">(current)</span>
|
||||
{{/link-to}}
|
||||
{{/link-to}}
|
||||
{{#link-to 'cluster-overview' tagName="li"}}
|
||||
{{#link-to 'cluster-overview' class="navigation-link"}}Cluster Overview
|
||||
<span class="sr-only">(current)</span>
|
||||
{{/link-to}}
|
||||
{{/link-to}}
|
||||
{{#link-to 'yarn-nodes' tagName="li"}}
|
||||
{{#link-to 'yarn-nodes' class="navigation-link"}}Nodes
|
||||
<span class="sr-only">(current)</span>
|
||||
{{/link-to}}
|
||||
{{/link-to}}
|
||||
</ul>
|
||||
</div><!-- /.navbar-collapse -->
|
||||
</div><!-- /.container-fluid -->
|
||||
</nav>
|
||||
|
||||
{{outlet}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -16,59 +16,137 @@
|
|||
* limitations under the License.
|
||||
}}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-3 container-fluid" id="finishedapps-donut-chart">
|
||||
{{donut-chart data=model.firstObject.getFinishedAppsDataForDonutChart
|
||||
title="Finished Apps"
|
||||
showLabels=true
|
||||
parentId="finishedapps-donut-chart"
|
||||
ratio=0.55
|
||||
maxHeight=350}}
|
||||
<div class="col-md-12 container-fluid">
|
||||
{{em-breadcrumbs items=breadcrumbs}}
|
||||
</div>
|
||||
|
||||
{{#if model}}
|
||||
|
||||
<div class="col-md-12 container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-lg-6 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
Cluster Resource Usage By Applications
|
||||
</div>
|
||||
<div class="container-fluid" id="appusage-donut-chart">
|
||||
{{app-usage-donut-chart data=model.apps
|
||||
showLabels=true
|
||||
parentId="appusage-donut-chart"
|
||||
ratio=0.6
|
||||
maxHeight=400}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-6 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
Cluster Resource Usage By Leaf Queues
|
||||
</div>
|
||||
<div class="container-fluid" id="queueusage-donut-chart">
|
||||
{{queue-usage-donut-chart data=model.queues
|
||||
showLabels=true
|
||||
parentId="queueusage-donut-chart"
|
||||
ratio=0.6
|
||||
maxHeight=400}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-4 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
Finished Apps
|
||||
</div>
|
||||
<div class="container-fluid" id="finishedapps-donut-chart">
|
||||
{{donut-chart data=model.clusterMetrics.firstObject.getFinishedAppsDataForDonutChart
|
||||
showLabels=true
|
||||
parentId="finishedapps-donut-chart"
|
||||
ratio=0.6
|
||||
maxHeight=350
|
||||
colorTargets="good warn error"}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
Running Apps
|
||||
</div>
|
||||
<div class="container-fluid" id="runningapps-donut-chart">
|
||||
{{donut-chart data=model.clusterMetrics.firstObject.getRunningAppsDataForDonutChart
|
||||
showLabels=true
|
||||
parentId="runningapps-donut-chart"
|
||||
ratio=0.6
|
||||
maxHeight=350
|
||||
colorTargets="warn good"}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
Node Managers
|
||||
</div>
|
||||
<div class="container-fluid" id="nodes-donut-chart">
|
||||
{{donut-chart data=model.clusterMetrics.firstObject.getNodesDataForDonutChart
|
||||
showLabels=true
|
||||
parentId="nodes-donut-chart"
|
||||
ratio=0.6
|
||||
maxHeight=350
|
||||
colorTargets="good error warn"}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-3 container-fluid" id="runningapps-donut-chart">
|
||||
{{donut-chart data=model.firstObject.getRunningAppsDataForDonutChart
|
||||
title="Running Apps"
|
||||
showLabels=true
|
||||
parentId="runningapps-donut-chart"
|
||||
ratio=0.55
|
||||
maxHeight=350}}
|
||||
<hr>
|
||||
<div class="row">
|
||||
|
||||
<div class="col-lg-4 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
Resource - Memory
|
||||
</div>
|
||||
<div class="container-fluid" id="mem-donut-chart">
|
||||
{{donut-chart data=model.clusterMetrics.firstObject.getMemoryDataForDonutChart
|
||||
showLabels=true
|
||||
parentId="mem-donut-chart"
|
||||
ratio=0.6
|
||||
maxHeight=350
|
||||
colorTargets="good"
|
||||
colorTargetReverse=true
|
||||
type="memory"}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
Resource - VCores
|
||||
</div>
|
||||
<div class="container-fluid" id="vcore-donut-chart">
|
||||
{{donut-chart data=model.clusterMetrics.firstObject.getVCoreDataForDonutChart
|
||||
showLabels=true
|
||||
parentId="vcore-donut-chart"
|
||||
ratio=0.6
|
||||
maxHeight=350
|
||||
colorTargets="good"
|
||||
colorTargetReverse=true}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
{{/if}}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-3 container-fluid" id="nodes-donut-chart">
|
||||
{{donut-chart data=model.firstObject.getNodesDataForDonutChart
|
||||
title="Node Managers"
|
||||
showLabels=true
|
||||
parentId="nodes-donut-chart"
|
||||
ratio=0.55
|
||||
maxHeight=350}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-3 container-fluid" id="mem-donut-chart">
|
||||
{{donut-chart data=model.firstObject.getMemoryDataForDonutChart
|
||||
title="Resource - Memory"
|
||||
showLabels=true
|
||||
parentId="mem-donut-chart"
|
||||
ratio=0.55
|
||||
maxHeight=350}}
|
||||
</div>
|
||||
|
||||
<div class="col-lg-3 container-fluid" id="vcore-donut-chart">
|
||||
{{donut-chart data=model.firstObject.getVCoreDataForDonutChart
|
||||
title="Resource - VCores"
|
||||
showLabels=true
|
||||
parentId="vcore-donut-chart"
|
||||
ratio=0.6
|
||||
maxHeight=350}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{outlet}}
|
|
@ -20,6 +20,7 @@
|
|||
<thead>
|
||||
<tr>
|
||||
<th>Application ID</th>
|
||||
<th>Application Type</th>
|
||||
<th>Name</th>
|
||||
<th>User</th>
|
||||
<th>Queue</th>
|
||||
|
@ -30,13 +31,15 @@
|
|||
<th>Finished Time</th>
|
||||
<th>Priority</th>
|
||||
<th>Progress</th>
|
||||
</tr>
|
||||
<th>%Cluster</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#if arr}}
|
||||
{{#each arr as |app|}}
|
||||
<tr>
|
||||
<td><a href="#/yarn-app/{{app.id}}">{{app.id}}</a></td>
|
||||
<td>{{app.applicationType}}</td>
|
||||
<td>{{app.appName}}</td>
|
||||
<td>{{app.user}}</td>
|
||||
<td>{{app.queue}}</td>
|
||||
|
@ -53,11 +56,13 @@
|
|||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>{{app.clusterUsagePercentage}}</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
{{else}}
|
||||
<tr>
|
||||
<td><a href="#/yarn-app/{{app.id}}">{{app.id}}</a></td>
|
||||
<td>{{app.applicationType}}</td>
|
||||
<td>{{app.appName}}</td>
|
||||
<td>{{app.user}}</td>
|
||||
<td>{{app.queue}}</td>
|
||||
|
@ -74,7 +79,8 @@
|
|||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<td>{{app.clusterUsagePercentage}}</td>
|
||||
</tr>
|
||||
{{/if}}
|
||||
</tbody>
|
||||
</table>
|
|
@ -19,7 +19,7 @@
|
|||
<div class="col-md-2 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4>Node Manager<br>({{node-name nodeId}})</h4>
|
||||
<h4>Node Manager</h4>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<ul class="nav nav-pills nav-stacked" id="stacked-menu">
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
{{!
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
}}
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-6 container-fluid">
|
||||
<input type="text" class="form-control" aria-label="..." placeholder="Enter part of host/rack to filter nodes"
|
||||
onchange={{action "applyFilter"}}>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p/>
|
|
@ -24,10 +24,6 @@
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Queue Name</td>
|
||||
<td>{{queue.id}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Configured Capacity</td>
|
||||
<td>{{queue.capacity}}</td>
|
||||
|
|
|
@ -16,21 +16,13 @@
|
|||
* limitations under the License.
|
||||
}}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-4">
|
||||
<select class="js-example-basic-single" width="100%" id="queue-name-selector">
|
||||
{{item-selector element-id="queue-name-selector" prefix="Queue : " model=model}}
|
||||
</select>
|
||||
</div>
|
||||
</div><!-- /.row -->
|
||||
|
||||
<!-- queue selector -->
|
||||
<div class="row">
|
||||
<div class="col-md-12 container-fluid" id="tree-selector-container">
|
||||
<div class="col-md-12 container-fluid">
|
||||
<div class="panel panel-default" id="tree-selector-container">
|
||||
{{tree-selector model=model parentId="tree-selector-container" selected=selected}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
{{outlet}}
|
|
@ -26,12 +26,13 @@
|
|||
{{/if}}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<br/><br/>
|
||||
<div class="col-md-8 container-fluid" id={{parent-id}}>
|
||||
</div>
|
||||
|
||||
<!-- diag info -->
|
||||
<div class="col-md-4 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel panel-default add-ellipsis">
|
||||
<div class="panel-heading">
|
||||
{{#if selected.link}}
|
||||
{{#link-to selected.linkname selected.id}}{{selected.id}}{{/link-to}}
|
||||
|
|
|
@ -16,10 +16,21 @@
|
|||
* limitations under the License.
|
||||
}}
|
||||
|
||||
<div class="col-md-12 container-fluid">
|
||||
{{em-breadcrumbs items=breadcrumbs}}
|
||||
</div>
|
||||
<br/><br/><br/>
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
{{#if model.attempt}}
|
||||
{{app-attempt-table attempt=model.attempt}}
|
||||
<div class="container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
Application attempt Information
|
||||
</div>
|
||||
{{app-attempt-table attempt=model.attempt}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
{{!
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
}}
|
||||
|
||||
<div class="col-md-12 container-fluid">
|
||||
{{em-breadcrumbs items=breadcrumbs}}
|
||||
</div>
|
||||
|
||||
<div class="col-md-12 container-fluid">
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-2 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4>Application</h4>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<ul class="nav nav-pills nav-stacked" id="stacked-menu">
|
||||
<ul class="nav nav-pills nav-stacked collapse in">
|
||||
{{#link-to 'yarn-app' tagName="li"}}
|
||||
{{#link-to 'yarn-app' model.appId}}Information
|
||||
{{/link-to}}
|
||||
{{/link-to}}
|
||||
{{#link-to 'yarn-app-attempts' tagName="li"}}
|
||||
{{#link-to 'yarn-app-attempts' model.appId}}Attempts List
|
||||
{{/link-to}}
|
||||
{{/link-to}}
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-10 container-fluid">
|
||||
<!-- timeline view of children -->
|
||||
<div class="row">
|
||||
{{timeline-view parent-id="attempt-timeline-div" my-id="timeline-view" height="100%" rmModel=model.attempts label="shortAppAttemptId" attemptModel=true}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{{outlet}}
|
|
@ -16,148 +16,238 @@
|
|||
* limitations under the License.
|
||||
}}
|
||||
|
||||
<div class="container-fluid">
|
||||
<!-- app table -->
|
||||
<div class="row">
|
||||
<div class="col-md-12 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
Application Basic Information
|
||||
</div>
|
||||
{{app-table table-id="app-table" app=model.app}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- diag info and other infos -->
|
||||
<div class="row">
|
||||
<!-- diag info -->
|
||||
<div class="col-md-4 container-fluid">
|
||||
{{#if model.app.isFailed}}
|
||||
<div class="panel panel-danger">
|
||||
<div class="panel-heading">
|
||||
Diagnostics
|
||||
</div>
|
||||
<div class="panel-body">{{model.app.diagnostics}}</div>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
Diagnostics
|
||||
</div>
|
||||
<div class="panel-footer">{{model.app.diagnostics}}</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<div class="col-md-5 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">Scheduling Info</div>
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Allocated Resource</td>
|
||||
<td>{{model.app.allocatedResource}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Running Containers</td>
|
||||
<td>{{model.app.runningContainersNumber}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Preempted Resource</td>
|
||||
<td>{{model.app.preemptedResource}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Num Non-AM container preempted</td>
|
||||
<td>{{model.app.numAMContainerPreempted}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Num AM container preempted</td>
|
||||
<td>{{model.app.numAMContainerPreempted}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Aggregated Resource Usage</td>
|
||||
<td>{{model.app.aggregatedResourceUsage}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- other info -->
|
||||
<div class="col-md-3 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">Other Info</div>
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>AM Container Log</td>
|
||||
<td><a href={{model.app.amContainerLogs}}>Link</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>AM Host Http Addr</td>
|
||||
<td><a href={{model.app.amHostHttpAddress}}>Link</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Log Aggregation Status</td>
|
||||
<td>{{model.app.logAggregationStatus}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Is Unmanaged AM</td>
|
||||
<td>{{model.app.unmanagedApplication}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>AM Node Label Expression</td>
|
||||
<td>{{model.app.amNodeLabelExpression}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--
|
||||
<div class="row">
|
||||
<div class="col-md-12 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
Application Attempts
|
||||
</div>
|
||||
<table id="app-attempt-table" class="table table-striped table-bordered" cellspacing="0" width="100%" height="100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Start Time</th>
|
||||
<th>Master ContainerId</th>
|
||||
<th>Node Http Address</th>
|
||||
<th>Node Id</th>
|
||||
<th>Logs Link</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#each model.attempts as |attempt|}}
|
||||
<tr>
|
||||
<td>{{attempt.startTime}}</td>
|
||||
<td>{{attempt.containerId}}</td>
|
||||
<td><a href={{attempt.nodeHttpAddress}}>{{attempt.nodeHttpAddress}}</a></td>
|
||||
<td>{{attempt.nodeId}}</td>
|
||||
<td><a href={{attempt.logsLink}}>link</a></td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
-->
|
||||
<!-- timeline view of children -->
|
||||
<div class="row">
|
||||
{{timeline-view parent-id="attempt-timeline-div" my-id="timeline-view" height="100%" rmModel=model.attempts label="shortAppAttemptId" attemptModel=true}}
|
||||
</div>
|
||||
<div class="col-md-12 container-fluid">
|
||||
{{em-breadcrumbs items=breadcrumbs}}
|
||||
</div>
|
||||
|
||||
<!--
|
||||
{{simple-table table-id="app-attempt-table" paging=false bFilter=false}}
|
||||
-->
|
||||
{{#if model.app}}
|
||||
<div class="col-md-12 container-fluid">
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-2 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4>Application</h4>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<ul class="nav nav-pills nav-stacked" id="stacked-menu">
|
||||
<ul class="nav nav-pills nav-stacked collapse in">
|
||||
{{#link-to 'yarn-app' tagName="li"}}
|
||||
{{#link-to 'yarn-app' model.app.id}}Information
|
||||
{{/link-to}}
|
||||
{{/link-to}}
|
||||
{{#link-to 'yarn-app-attempts' tagName="li"}}
|
||||
{{#link-to 'yarn-app-attempts' model.app.id}}Attempts List
|
||||
{{/link-to}}
|
||||
{{/link-to}}
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-10 container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-12 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">Basic Info</div>
|
||||
<table class="display table table-striped table-bordered"
|
||||
cellspacing="0" width="100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Application ID</th>
|
||||
<th>Name</th>
|
||||
<th>User</th>
|
||||
<th>Queue</th>
|
||||
<th>State</th>
|
||||
<th>Final Status</th>
|
||||
<th>Start Time</th>
|
||||
<th>Elapsed Time</th>
|
||||
<th>Finished Time</th>
|
||||
<th>Priority</th>
|
||||
<th>Progress</th>
|
||||
<th>Is Unmanaged AM</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{{model.app.id}}</td>
|
||||
<td>{{model.app.appName}}</td>
|
||||
<td>{{model.app.user}}</td>
|
||||
<td>{{model.app.queue}}</td>
|
||||
<td>{{model.app.state}}</td>
|
||||
<td>
|
||||
<span class={{model.app.finalStatusStyle}}>
|
||||
{{model.app.finalStatus}}
|
||||
</span>
|
||||
</td>
|
||||
<td>{{model.app.startTime}}</td>
|
||||
<td>{{model.app.elapsedTime}}</td>
|
||||
<td>{{model.app.validatedFinishedTs}}</td>
|
||||
<td>{{model.app.priority}}</td>
|
||||
<td>
|
||||
<div class="progress" style="margin-bottom: 0;">
|
||||
<div class="progress-bar" role="progressbar"
|
||||
aria-valuenow="60" aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
style={{model.app.progressStyle}}>
|
||||
{{model.app.progress}}%
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>{{model.app.unmanagedApplication}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
{{#if model.app.diagnostics}}
|
||||
<div class="col-md-12 container-fluid">
|
||||
{{#if model.app.isFailed}}
|
||||
<div class="panel panel-danger">
|
||||
<div class="panel-heading">
|
||||
Diagnostics
|
||||
</div>
|
||||
<div class="panel-body">{{model.app.diagnostics}}</div>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
Diagnostics
|
||||
</div>
|
||||
<div class="panel-footer">{{model.app.diagnostics}}</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-8 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">Scheduling Info</div>
|
||||
<table class="display table table-striped table-bordered"
|
||||
cellspacing="0" width="100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Allocated Resource</th>
|
||||
<th>Running Containers</th>
|
||||
<th>Preempted Resource</th>
|
||||
<th>Num Non-AM container preempted</th>
|
||||
<th>Num AM container preempted</th>
|
||||
<th>Aggregated Resource Usage</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{{model.app.allocatedResource}}</td>
|
||||
<td>{{model.app.runningContainersNumber}}</td>
|
||||
<td>{{model.app.preemptedResource}}</td>
|
||||
<td>{{model.app.numAMContainerPreempted}}</td>
|
||||
<td>{{model.app.numAMContainerPreempted}}</td>
|
||||
<td>{{model.app.aggregatedResourceUsage}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">App Master Info</div>
|
||||
<table class="display table table-striped table-bordered"
|
||||
cellspacing="0" width="100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Master Container Log</th>
|
||||
<td>Master Node</td>
|
||||
<td>Master Node Label Expr</td>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><a href={{model.app.amContainerLogs}}>Link</a></td>
|
||||
<td><a href={{model.app.amHostHttpAddress}}>Link</a></td>
|
||||
<td>{{model.app.amNodeLabelExpression}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#if model.nodes}}
|
||||
{{#if model.rmContainers}}
|
||||
<div class="row" id="stackd-bar-chart-mem">
|
||||
{{per-app-memusage-by-nodes-stacked-barchart
|
||||
nodes=model.nodes
|
||||
rmContainers=model.rmContainers
|
||||
parentId="stackd-bar-chart-mem"
|
||||
title=(concat 'Memory usage by nodes for: [' model.app.id ']')}}
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="row" id="stackd-bar-chart-ncontainer">
|
||||
{{per-app-ncontainers-by-nodes-stacked-barchart
|
||||
nodes=model.nodes
|
||||
rmContainers=model.rmContainers
|
||||
parentId="stackd-bar-chart-ncontainer"
|
||||
title=(concat 'Running #Containers by nodes for: [' model.app.id ']')}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<!--
|
||||
<div class="row">
|
||||
<div class="col-md-12 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
Application Attempts
|
||||
</div>
|
||||
<table id="app-attempt-table" class="table table-striped table-bordered" cellspacing="0" width="100%" height="100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Start Time</th>
|
||||
<th>Master ContainerId</th>
|
||||
<th>Node Http Address</th>
|
||||
<th>Node Id</th>
|
||||
<th>Logs Link</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#each model.attempts as |attempt|}}
|
||||
<tr>
|
||||
<td>{{attempt.startTime}}</td>
|
||||
<td>{{attempt.containerId}}</td>
|
||||
<td><a href={{attempt.nodeHttpAddress}}>{{attempt.nodeHttpAddress}}</a></td>
|
||||
<td>{{attempt.nodeId}}</td>
|
||||
<td><a href={{attempt.logsLink}}>link</a></td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
-->
|
||||
|
||||
<!-- timeline view of children -->
|
||||
<!--
|
||||
<div class="row">
|
||||
{{timeline-view parent-id="attempt-timeline-div" my-id="timeline-view" height="100%" rmModel=model.attempts label="shortAppAttemptId" attemptModel=true}}
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{outlet}}
|
|
@ -15,10 +15,78 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
}}
|
||||
{{#if model}}
|
||||
{{app-table table-id="apps-table" arr=model}}
|
||||
{{simple-table table-id="apps-table" bFilter=true colsOrder="0,desc" colTypes="natural elapsed-time" colTargets="0 7"}}
|
||||
{{else}}
|
||||
<h4 align = "center">Could not find any applications from this cluster</h4>
|
||||
{{/if}}
|
||||
{{outlet}}
|
||||
|
||||
<div class="col-md-12 container-fluid">
|
||||
{{em-breadcrumbs items=breadcrumbs}}
|
||||
</div>
|
||||
|
||||
<div class="col-md-12 container-fluid">
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-2 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4>Application</h4>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<ul class="nav nav-pills nav-stacked" id="stacked-menu">
|
||||
<ul class="nav nav-pills nav-stacked collapse in">
|
||||
{{#link-to 'yarn-apps.apps' tagName="li"}}
|
||||
{{#link-to 'yarn-apps.apps'}}All Applications
|
||||
{{/link-to}}
|
||||
{{/link-to}}
|
||||
{{#link-to 'yarn-apps.services' tagName="li"}}
|
||||
{{#link-to 'yarn-apps.services'}}Long Running Services
|
||||
{{/link-to}}
|
||||
{{/link-to}}
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-10 container-fluid">
|
||||
{{#if model.clusterMetrics}}
|
||||
<div class="row">
|
||||
<div class="col-lg-4 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
Finished Apps
|
||||
</div>
|
||||
<div class="container-fluid" id="finishedapps-donut-chart">
|
||||
{{donut-chart data=model.clusterMetrics.firstObject.getFinishedAppsDataForDonutChart
|
||||
showLabels=true
|
||||
parentId="finishedapps-donut-chart"
|
||||
ratio=0.6
|
||||
maxHeight=350
|
||||
colorTargets="good warn error"
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
Running Apps
|
||||
</div>
|
||||
<div class="container-fluid" id="runningapps-donut-chart">
|
||||
{{donut-chart data=model.clusterMetrics.firstObject.getRunningAppsDataForDonutChart
|
||||
showLabels=true
|
||||
parentId="runningapps-donut-chart"
|
||||
ratio=0.6
|
||||
maxHeight=350
|
||||
colorTargets="warn good"
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<div class="row">
|
||||
{{outlet}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,24 @@
|
|||
{{!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
--}}
|
||||
|
||||
{{#if model.apps}}
|
||||
{{app-table table-id="apps-table" arr=model.apps}}
|
||||
{{simple-table table-id="apps-table" bFilter=true colsOrder="0,desc" colTypes="natural elapsed-time" colTargets="0 7"}}
|
||||
{{else}}
|
||||
<h4 align="center">Could not find any applications from this cluster</h4>
|
||||
{{/if}}
|
|
@ -0,0 +1,27 @@
|
|||
{{!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
--}}
|
||||
|
||||
{{#if model.apps}}
|
||||
{{app-table table-id="apps-table" arr=model.apps}}
|
||||
{{simple-table table-id="apps-table" bFilter=true colsOrder="0,desc"
|
||||
colTypes="natural elapsed-time" colTargets="0 7" defaultSearch="slider"}}
|
||||
{{else}}
|
||||
<h4 align="center">Could not find any applications from this cluster</h4>
|
||||
{{/if}}
|
||||
|
||||
{{outlet}}
|
|
@ -16,6 +16,10 @@
|
|||
limitations under the License.
|
||||
--}}
|
||||
|
||||
<div class="col-md-12 container-fluid">
|
||||
{{em-breadcrumbs items=breadcrumbs}}
|
||||
</div>
|
||||
|
||||
<div class="col-md-12 container-fluid">
|
||||
<div class="row">
|
||||
{{node-menu-panel path="yarn-node-apps" nodeAddr=model.nodeInfo.addr nodeId=model.nodeInfo.id}}
|
||||
|
|
|
@ -16,6 +16,10 @@
|
|||
limitations under the License.
|
||||
--}}
|
||||
|
||||
<div class="col-md-12 container-fluid">
|
||||
{{em-breadcrumbs items=breadcrumbs}}
|
||||
</div>
|
||||
|
||||
<div class="col-md-12 container-fluid">
|
||||
<div class="row">
|
||||
{{node-menu-panel path="yarn-node-container" nodeAddr=model.nodeInfo.addr nodeId=model.nodeInfo.id}}
|
||||
|
|
|
@ -16,6 +16,10 @@
|
|||
limitations under the License.
|
||||
--}}
|
||||
|
||||
<div class="col-md-12 container-fluid">
|
||||
{{em-breadcrumbs items=breadcrumbs}}
|
||||
</div>
|
||||
|
||||
<div class="col-md-12 container-fluid">
|
||||
<div class="row">
|
||||
{{node-menu-panel path="yarn-node-containers" nodeAddr=model.nodeInfo.addr nodeId=model.nodeInfo.id}}
|
||||
|
|
|
@ -16,79 +16,105 @@
|
|||
limitations under the License.
|
||||
--}}
|
||||
|
||||
<div class="col-md-12 container-fluid">
|
||||
{{em-breadcrumbs items=breadcrumbs}}
|
||||
</div>
|
||||
|
||||
<div class="col-md-12 container-fluid">
|
||||
<div class="row">
|
||||
|
||||
{{node-menu-panel path="yarn-node" nodeId=model.rmNode.id nodeAddr=model.node.id}}
|
||||
|
||||
<div class="col-md-10 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">Node Information</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">Node Information</div>
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Total Vmem allocated for Containers</td>
|
||||
<td>{{divide num=model.node.totalVmemAllocatedContainersMB den=1024}} GB</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Vmem enforcement enabled</td>
|
||||
<td>{{model.node.vmemCheckEnabled}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Total Pmem allocated for Containers</td>
|
||||
<td>{{divide num=model.node.totalPmemAllocatedContainersMB den=1024}} GB</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Pmem enforcement enabled</td>
|
||||
<td>{{model.node.pmemCheckEnabled}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Total VCores allocated for Containers</td>
|
||||
<td>{{model.node.totalVCoresAllocatedContainers}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Node Healthy Status</td>
|
||||
<td>{{model.node.nodeHealthy}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Last Node Health Report Time</td>
|
||||
<td>{{model.node.lastNodeUpdateTime}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Node Health Report</td>
|
||||
<td>{{model.node.healthReport}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Node Manager Start Time</td>
|
||||
<td>{{model.node.nmStartupTime}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Node Manager Version</td>
|
||||
<td>{{model.node.nodeManagerBuildVersion}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Hadoop Version</td>
|
||||
<td>{{model.node.hadoopBuildVersion}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Total Vmem allocated for Containers</td>
|
||||
<td>{{divide num=model.node.totalVmemAllocatedContainersMB den=1024}} GB</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Vmem enforcement enabled</td>
|
||||
<td>{{model.node.vmemCheckEnabled}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Total Pmem allocated for Containers</td>
|
||||
<td>{{divide num=model.node.totalPmemAllocatedContainersMB den=1024}} GB</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Pmem enforcement enabled</td>
|
||||
<td>{{model.node.pmemCheckEnabled}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Total VCores allocated for Containers</td>
|
||||
<td>{{model.node.totalVCoresAllocatedContainers}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Node Healthy Status</td>
|
||||
<td>{{model.node.nodeHealthy}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Last Node Health Report Time</td>
|
||||
<td>{{model.node.lastNodeUpdateTime}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Node Health Report</td>
|
||||
<td>{{model.node.healthReport}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Node Manager Start Time</td>
|
||||
<td>{{model.node.nmStartupTime}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Node Manager Version</td>
|
||||
<td>{{model.node.nodeManagerBuildVersion}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Hadoop Version</td>
|
||||
<td>{{model.node.hadoopBuildVersion}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-lg-4 container-fluid" id="mem-donut-chart">
|
||||
{{donut-chart data=model.rmNode.getMemoryDataForDonutChart
|
||||
title="Resource - Memory (in MB)"
|
||||
showLabels=true
|
||||
parentId="mem-donut-chart"
|
||||
ratio=0.55
|
||||
maxHeight=350}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4 container-fluid" id="vcore-donut-chart">
|
||||
{{donut-chart data=model.rmNode.getVCoreDataForDonutChart
|
||||
title="Resource - VCores"
|
||||
showLabels=true
|
||||
parentId="vcore-donut-chart"
|
||||
ratio=0.55
|
||||
maxHeight=350}}
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-4 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
Resource - Memory (in MB)
|
||||
</div>
|
||||
<div class="container-fluid" id="mem-donut-chart">
|
||||
{{donut-chart data=model.rmNode.getMemoryDataForDonutChart
|
||||
showLabels=true
|
||||
parentId="mem-donut-chart"
|
||||
ratio=0.6
|
||||
maxHeight=350}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
Resource - VCores
|
||||
</div>
|
||||
<div class="container-fluid" id="vcore-donut-chart">
|
||||
{{donut-chart data=model.rmNode.getVCoreDataForDonutChart
|
||||
showLabels=true
|
||||
parentId="vcore-donut-chart"
|
||||
ratio=0.6
|
||||
maxHeight=350}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{outlet}}
|
||||
|
|
|
@ -16,48 +16,57 @@
|
|||
limitations under the License.
|
||||
--}}
|
||||
|
||||
{{#if model}}
|
||||
<table id="nodes-table" class="display table table-striped table-bordered" cellspacing="0" width="100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Node Labels</th>
|
||||
<th>Rack</th>
|
||||
<th>Node State</th>
|
||||
<th>Node Address</th>
|
||||
<th>Node HTTP Address</th>
|
||||
<th>Last Health Update</th>
|
||||
<th>Health-Report</th>
|
||||
<th>Containers</th>
|
||||
<th>Mem Used</th>
|
||||
<th>Mem Avail</th>
|
||||
<th>VCores Used</th>
|
||||
<th>VCores Avail</th>
|
||||
<th>Version</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#each model as |node|}}
|
||||
<tr>
|
||||
<td>{{node.nodeLabelsAsString}}</td>
|
||||
<td>{{node.rack}}</td>
|
||||
<td><span class={{node.nodeStateStyle}}>{{node.state}}</span></td>
|
||||
<td>{{node.id}}</td>
|
||||
{{node-link nodeId=node.id nodeHTTPAddress=node.nodeHTTPAddress nodeState=node.state}}
|
||||
<td>{{node.lastHealthUpdate}}</td>
|
||||
<td>{{node.healthReport}}</td>
|
||||
<td>{{node.numContainers}}</td>
|
||||
<td>{{divide num=node.usedMemoryMB den=1024}} GB</td>
|
||||
<td>{{divide num=node.availMemoryMB den=1024}} GB</td>
|
||||
<td>{{node.usedVirtualCores}}</td>
|
||||
<td>{{node.availableVirtualCores}}</td>
|
||||
<td>{{node.version}}</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="col-md-12 container-fluid">
|
||||
{{em-breadcrumbs items=breadcrumbs}}
|
||||
</div>
|
||||
|
||||
{{simple-table table-id="nodes-table" bFilter=true}}
|
||||
{{else}}
|
||||
<h4 align = "center">No nodes found on this cluster</h4>
|
||||
{{/if}}
|
||||
{{outlet}}
|
||||
<div class="row">
|
||||
<div class="col-md-2 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4>Nodes</h4>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<ul class="nav nav-pills nav-stacked" id="stacked-menu">
|
||||
<ul class="nav nav-pills nav-stacked collapse in">
|
||||
|
||||
{{#link-to "yarn-nodes.table" tagName="li"}}
|
||||
{{#link-to 'yarn-nodes.table'}}Nodes Table
|
||||
{{/link-to}}
|
||||
{{/link-to}}
|
||||
|
||||
{{#link-to 'yarn-nodes.heatmap' tagName="li"}}
|
||||
{{#link-to 'yarn-nodes.heatmap'}}Nodes Heatmap Chart
|
||||
{{/link-to}}
|
||||
{{/link-to}}
|
||||
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-10 container-fluid">
|
||||
{{#if model.clusterMetrics}}
|
||||
<div class="row">
|
||||
<div class="col-lg-4 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
Node Managers
|
||||
</div>
|
||||
<div class="container-fluid" id="nodes-donut-chart">
|
||||
{{donut-chart data=model.clusterMetrics.firstObject.getNodesDataForDonutChart
|
||||
showLabels=true
|
||||
parentId="nodes-donut-chart"
|
||||
ratio=0.6
|
||||
maxHeight=350
|
||||
colorTargets="good error warn"}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{outlet}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
{{!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
--}}
|
||||
|
||||
{{#if model.nodes}}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-12 container-fluid" id="nodes-heatmap-chart">
|
||||
{{nodes-heatmap model=model.nodes parentId="nodes-heatmap-chart"
|
||||
title="Node Heatmap Chart (Usage of Memory)"}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{outlet}}
|
|
@ -0,0 +1,67 @@
|
|||
{{!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
--}}
|
||||
<div class="row">
|
||||
|
||||
{{#if model.nodes}}
|
||||
<table id="nodes-table" class="display table table-striped table-bordered"
|
||||
cellspacing="0" width="100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Node Labels</th>
|
||||
<th>Rack</th>
|
||||
<th>Node State</th>
|
||||
<th>Node Address</th>
|
||||
<th>Node HTTP Address</th>
|
||||
<th>Last Health Update</th>
|
||||
<th>Health-Report</th>
|
||||
<th>Containers</th>
|
||||
<th>Mem Used</th>
|
||||
<th>Mem Avail</th>
|
||||
<th>VCores Used</th>
|
||||
<th>VCores Avail</th>
|
||||
<th>Version</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#each model.nodes as |node|}}
|
||||
<tr>
|
||||
<td>{{node.nodeLabelsAsString}}</td>
|
||||
<td>{{node.rack}}</td>
|
||||
<td><span class={{node.nodeStateStyle}}>{{node.state}}</span></td>
|
||||
<td>{{node.id}}</td>
|
||||
{{node-link nodeId=node.id nodeHTTPAddress=node.nodeHTTPAddress nodeState=node.state}}
|
||||
<td>{{node.lastHealthUpdate}}</td>
|
||||
<td>{{node.healthReport}}</td>
|
||||
<td>{{node.numContainers}}</td>
|
||||
<td>{{divide num=node.usedMemoryMB den=1024}} GB</td>
|
||||
<td>{{divide num=node.availMemoryMB den=1024}} GB</td>
|
||||
<td>{{node.usedVirtualCores}}</td>
|
||||
<td>{{node.availableVirtualCores}}</td>
|
||||
<td>{{node.version}}</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
{{simple-table table-id="nodes-table" bFilter=true}}
|
||||
{{else}}
|
||||
<h4 align="center">No nodes found on this cluster</h4>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
{{outlet}}
|
|
@ -0,0 +1,66 @@
|
|||
{{!
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
}}
|
||||
|
||||
<div class="col-md-12 container-fluid">
|
||||
{{em-breadcrumbs items=breadcrumbs}}
|
||||
</div>
|
||||
|
||||
<div class="col-md-12 container-fluid">
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-2 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4>Application</h4>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<ul class="nav nav-pills nav-stacked" id="stacked-menu">
|
||||
<ul class="nav nav-pills nav-stacked collapse in">
|
||||
{{#link-to 'yarn-queue' tagName="li"}}
|
||||
{{#link-to 'yarn-queue' model.selected}}Information
|
||||
{{/link-to}}
|
||||
{{/link-to}}
|
||||
{{#link-to 'yarn-queue-apps' tagName="li"}}
|
||||
{{#link-to 'yarn-queue-apps' model.selected}}Applications List
|
||||
{{/link-to}}
|
||||
{{/link-to}}
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-10 container-fluid">
|
||||
<!-- timeline view of children -->
|
||||
<div class="row">
|
||||
|
||||
<div class="col-lg-12 container-fluid">
|
||||
{{#if model.apps}}
|
||||
{{app-table table-id="apps-table" arr=model.apps}}
|
||||
{{simple-table table-id="apps-table" bFilter=true colTypes="elapsed-time" colTargets="7"}}
|
||||
{{else}}
|
||||
<h4 align = "center">Could not find any applications from this cluster</h4>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{{outlet}}
|
|
@ -16,55 +16,95 @@
|
|||
* limitations under the License.
|
||||
}}
|
||||
|
||||
<div class="container-fluid">
|
||||
{{queue-navigator model=model.queues selected=model.selected}}
|
||||
<div class="col-md-12 container-fluid">
|
||||
{{em-breadcrumbs items=breadcrumbs}}
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-3 container-fluid">
|
||||
{{queue-configuration-table queue=model.selectedQueue}}
|
||||
</div>
|
||||
<div class="col-md-12 container-fluid">
|
||||
<div class="row">
|
||||
|
||||
<div class="col-lg-3 container-fluid" id="capacity-bar-chart">
|
||||
{{bar-chart data=model.selectedQueue.capacitiesBarChartData
|
||||
title="Queue Capacities"
|
||||
parentId="capacity-bar-chart"
|
||||
textWidth=150
|
||||
ratio=0.5
|
||||
maxHeight=350}}
|
||||
</div>
|
||||
<div class="col-md-2 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4>Application</h4>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<ul class="nav nav-pills nav-stacked" id="stacked-menu">
|
||||
<ul class="nav nav-pills nav-stacked collapse in">
|
||||
{{#link-to 'yarn-queue' tagName="li"}}
|
||||
{{#link-to 'yarn-queue' model.selected}}Information
|
||||
{{/link-to}}
|
||||
{{/link-to}}
|
||||
{{#link-to 'yarn-queue-apps' tagName="li"}}
|
||||
{{#link-to 'yarn-queue-apps' model.selected}}Applications List
|
||||
{{/link-to}}
|
||||
{{/link-to}}
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#if model.selectedQueue.hasUserUsages}}
|
||||
<div class="col-lg-3 container-fluid" id="userusage-donut-chart">
|
||||
{{donut-chart data=model.selectedQueue.userUsagesDonutChartData
|
||||
title="User Usages"
|
||||
showLabels=true
|
||||
parentId="userusage-donut-chart"
|
||||
maxHeight=350}}
|
||||
</div>
|
||||
{{/if}}
|
||||
<div class="col-md-10 container-fluid">
|
||||
<!-- timeline view of children -->
|
||||
<div class="row">
|
||||
|
||||
<div class="col-lg-4 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
Queue Information
|
||||
</div>
|
||||
{{queue-configuration-table queue=model.selectedQueue}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
Queue Capacities
|
||||
</div>
|
||||
<div class="container-fluid" id="capacity-bar-chart">
|
||||
<br/>
|
||||
{{bar-chart data=model.selectedQueue.capacitiesBarChartData
|
||||
title=""
|
||||
parentId="capacity-bar-chart"
|
||||
textWidth=170
|
||||
ratio=0.55
|
||||
maxHeight=350}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#if model.selectedQueue.hasUserUsages}}
|
||||
<div class="col-lg-4 container-fluid" id="userusage-donut-chart">
|
||||
{{donut-chart data=model.selectedQueue.userUsagesDonutChartData
|
||||
title="User Usages"
|
||||
showLabels=true
|
||||
parentId="userusage-donut-chart"
|
||||
type="memory"
|
||||
ratio=0.6
|
||||
maxHeight=350}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<div class="col-lg-4 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
Running Apps
|
||||
</div>
|
||||
<div class="container-fluid" id="numapplications-donut-chart">
|
||||
{{donut-chart data=model.selectedQueue.numOfApplicationsDonutChartData
|
||||
showLabels=true
|
||||
parentId="numapplications-donut-chart"
|
||||
ratio=0.6
|
||||
maxHeight=350}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-3 container-fluid" id="numapplications-donut-chart">
|
||||
{{donut-chart data=model.selectedQueue.numOfApplicationsDonutChartData
|
||||
title="Running Apps"
|
||||
showLabels=true
|
||||
parentId="numapplications-donut-chart"
|
||||
ratio=0.5
|
||||
maxHeight=350}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12 container-fluid">
|
||||
{{#if model.apps}}
|
||||
{{app-table table-id="apps-table" arr=model.apps}}
|
||||
{{simple-table table-id="apps-table" bFilter=true colTypes="elapsed-time" colTargets="7"}}
|
||||
{{else}}
|
||||
<h4 align = "center">Could not find any applications from this cluster</h4>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{outlet}}
|
||||
{{outlet}}
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
{{!
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
}}
|
||||
|
||||
<div class="col-md-12 container-fluid">
|
||||
{{em-breadcrumbs items=breadcrumbs}}
|
||||
</div>
|
||||
|
||||
<div class="container-fluid">
|
||||
{{queue-navigator model=model.queues selected=model.selected}}
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-lg-4 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
Queue Information
|
||||
</div>
|
||||
{{queue-configuration-table queue=model.selectedQueue}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
Queue Capacities
|
||||
</div>
|
||||
<div class="container-fluid" id="capacity-bar-chart">
|
||||
<br/>
|
||||
{{bar-chart data=model.selectedQueue.capacitiesBarChartData
|
||||
title=""
|
||||
parentId="capacity-bar-chart"
|
||||
textWidth=150
|
||||
ratio=0.55
|
||||
maxHeight=350}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
Running Apps
|
||||
</div>
|
||||
<div class="container-fluid" id="numapplications-donut-chart">
|
||||
{{donut-chart data=model.selectedQueue.numOfApplicationsDonutChartData
|
||||
showLabels=true
|
||||
parentId="numapplications-donut-chart"
|
||||
ratio=0.6
|
||||
maxHeight=350}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{outlet}}
|
|
@ -0,0 +1,67 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Constants from 'yarn-ui/constants';
|
||||
|
||||
export default {
|
||||
preDefinedColors : ["#1f77b4", "#aec7e8", "#ffbb78",
|
||||
"#98df8a", "#ff9896", "#9467bd", "#c5b0d5", "#8c564b",
|
||||
"#c49c94", "#e377c2", "#f7b6d2", "#c7c7c7", "#bcbd22",
|
||||
"#dbdb8d", "#17becf", "#9edae5"],
|
||||
|
||||
colorMap: {
|
||||
"warn": "#ff7f0e",
|
||||
"good": "#2ca02c",
|
||||
"error": "#d62728",
|
||||
"others": "#7f7f7f",
|
||||
},
|
||||
|
||||
getColors: function(nColors, colorsTarget, reverse = false) {
|
||||
var colors = [];
|
||||
for (var i = 0; i < nColors; i++) {
|
||||
colors.push(undefined);
|
||||
}
|
||||
|
||||
var startIdx = 0;
|
||||
|
||||
if (reverse) {
|
||||
startIdx = Math.max(nColors - colorsTarget.length, 0);
|
||||
}
|
||||
|
||||
for (var i = 0; i < colorsTarget.length; i++) {
|
||||
if (i + startIdx < nColors) {
|
||||
colors[i + startIdx] = this.getColorByTarget(colorsTarget[i]);
|
||||
}
|
||||
}
|
||||
|
||||
var idx = 0;
|
||||
for (var i = 0; i < nColors; i++) {
|
||||
if (!colors[i]) {
|
||||
colors[i] = this.preDefinedColors[i % this.preDefinedColors.length];
|
||||
idx ++;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(colors);
|
||||
return colors;
|
||||
},
|
||||
|
||||
getColorByTarget: function(target) {
|
||||
return this.colorMap[target];
|
||||
}
|
||||
};
|
|
@ -106,4 +106,21 @@ export default {
|
|||
return [splits[0], splits[1], fileName];
|
||||
}
|
||||
},
|
||||
memoryToSimpliedUnit: function(mb) {
|
||||
var unit = "MB"
|
||||
var value = mb;
|
||||
if (value / 1024 >= 0.9) {
|
||||
value = value / 1024;
|
||||
unit = "GB";
|
||||
}
|
||||
if (value / 1024 >= 0.9) {
|
||||
value = value / 1024;
|
||||
unit = "TB";
|
||||
}
|
||||
if (value / 1024 >= 0.9) {
|
||||
value = value / 1024;
|
||||
unit = "PB";
|
||||
}
|
||||
return value.toFixed(1) + " " + unit;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Constants from 'yarn-ui/constants';
|
||||
|
||||
export default {
|
||||
getApplicationLink: function(applicationId) {
|
||||
return "#/yarn-app/" + applicationId;
|
||||
},
|
||||
|
||||
getQueueLink: function(queueName) {
|
||||
return '#/yarn-queue/' + queueName;
|
||||
}
|
||||
};
|
|
@ -0,0 +1,36 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export default {
|
||||
initMockNodesData: function(ref) {
|
||||
var data = [];
|
||||
for (var i = 0; i < 3; i++) {
|
||||
for (var j = 0; j < 38; j++) {
|
||||
var node = ref.get('targetObject.store').createRecord('YarnRmNode', {
|
||||
rack: "/rack-" + i,
|
||||
nodeHostName: "hadoop-" + ["centos6", "ubuntu7", "win"][i % 3] + "-" + ["web", "etl", "dm"][j % 3] + "-" + j,
|
||||
usedMemoryMB: Math.abs(Math.random() * 10000),
|
||||
availMemoryMB: Math.abs(Math.random() * 10000)
|
||||
});
|
||||
data.push(node);
|
||||
}
|
||||
}
|
||||
|
||||
ref.set("model", data);
|
||||
},
|
||||
}
|
|
@ -18,6 +18,7 @@
|
|||
"datatables": "~1.10.8",
|
||||
"spin.js": "~2.3.2",
|
||||
"momentjs": "~2.10.6",
|
||||
"select2": "4.0.0"
|
||||
"select2": "4.0.0",
|
||||
"snippet-ss": "~1.11.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
"devDependencies": {
|
||||
"broccoli-asset-rev": "2.4.2",
|
||||
"broccoli-funnel": "1.0.1",
|
||||
"em-table": "0.1.6",
|
||||
"ember-bootstrap": "0.5.1",
|
||||
"ember-array-contains-helper": "1.0.2",
|
||||
"ember-cli": "1.13.13",
|
||||
|
@ -45,5 +46,8 @@
|
|||
"ember-spin-spinner": "0.2.3",
|
||||
"ember-truth-helpers": "1.2.0",
|
||||
"select2": "4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"em-helpers": "^0.5.13"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { moduleFor, test } from 'ember-qunit';
|
||||
|
||||
moduleFor('controller:yarn-app-attempt', 'Unit | Controller | yarn app attempt', {
|
||||
// Specify the other units that are required for this test.
|
||||
// needs: ['controller:foo']
|
||||
});
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function(assert) {
|
||||
let controller = this.subject();
|
||||
assert.ok(controller);
|
||||
});
|
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { moduleFor, test } from 'ember-qunit';
|
||||
|
||||
moduleFor('controller:yarn-app-attempts', 'Unit | Controller | yarn app attempts', {
|
||||
// Specify the other units that are required for this test.
|
||||
// needs: ['controller:foo']
|
||||
});
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function(assert) {
|
||||
let controller = this.subject();
|
||||
assert.ok(controller);
|
||||
});
|
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { moduleFor, test } from 'ember-qunit';
|
||||
|
||||
moduleFor('controller:yarn-app', 'Unit | Controller | yarn app', {
|
||||
// Specify the other units that are required for this test.
|
||||
// needs: ['controller:foo']
|
||||
});
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function(assert) {
|
||||
let controller = this.subject();
|
||||
assert.ok(controller);
|
||||
});
|
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { moduleFor, test } from 'ember-qunit';
|
||||
|
||||
moduleFor('controller:yarn-node-apps', 'Unit | Controller | yarn node apps', {
|
||||
// Specify the other units that are required for this test.
|
||||
// needs: ['controller:foo']
|
||||
});
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function(assert) {
|
||||
let controller = this.subject();
|
||||
assert.ok(controller);
|
||||
});
|
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { moduleFor, test } from 'ember-qunit';
|
||||
|
||||
moduleFor('controller:yarn-node-containers', 'Unit | Controller | yarn node containers', {
|
||||
// Specify the other units that are required for this test.
|
||||
// needs: ['controller:foo']
|
||||
});
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function(assert) {
|
||||
let controller = this.subject();
|
||||
assert.ok(controller);
|
||||
});
|
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { moduleFor, test } from 'ember-qunit';
|
||||
|
||||
moduleFor('controller:yarn-node', 'Unit | Controller | yarn node', {
|
||||
// Specify the other units that are required for this test.
|
||||
// needs: ['controller:foo']
|
||||
});
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function(assert) {
|
||||
let controller = this.subject();
|
||||
assert.ok(controller);
|
||||
});
|
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { moduleFor, test } from 'ember-qunit';
|
||||
|
||||
moduleFor('controller:yarn-nodes-heatmap', 'Unit | Controller | yarn nodes heatmap', {
|
||||
// Specify the other units that are required for this test.
|
||||
// needs: ['controller:foo']
|
||||
});
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function(assert) {
|
||||
let controller = this.subject();
|
||||
assert.ok(controller);
|
||||
});
|
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { moduleFor, test } from 'ember-qunit';
|
||||
|
||||
moduleFor('controller:yarn-nodes', 'Unit | Controller | yarn nodes', {
|
||||
// Specify the other units that are required for this test.
|
||||
// needs: ['controller:foo']
|
||||
});
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function(assert) {
|
||||
let controller = this.subject();
|
||||
assert.ok(controller);
|
||||
});
|
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { moduleFor, test } from 'ember-qunit';
|
||||
|
||||
moduleFor('controller:yarn-queue-apps', 'Unit | Controller | yarn queue apps', {
|
||||
// Specify the other units that are required for this test.
|
||||
// needs: ['controller:foo']
|
||||
});
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function(assert) {
|
||||
let controller = this.subject();
|
||||
assert.ok(controller);
|
||||
});
|
|
@ -18,13 +18,13 @@
|
|||
|
||||
import { moduleFor, test } from 'ember-qunit';
|
||||
|
||||
moduleFor('controller:yarn-queues', {
|
||||
moduleFor('controller:yarn-queues', 'Unit | Controller | yarn queues', {
|
||||
// Specify the other units that are required for this test.
|
||||
// needs: ['controller:foo']
|
||||
});
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function(assert) {
|
||||
var controller = this.subject();
|
||||
let controller = this.subject();
|
||||
assert.ok(controller);
|
||||
});
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { moduleFor, test } from 'ember-qunit';
|
||||
|
||||
moduleFor('controller:yarn-services', 'Unit | Controller | yarn services', {
|
||||
// Specify the other units that are required for this test.
|
||||
// needs: ['controller:foo']
|
||||
});
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function(assert) {
|
||||
let controller = this.subject();
|
||||
assert.ok(controller);
|
||||
});
|
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { moduleFor, test } from 'ember-qunit';
|
||||
|
||||
moduleFor('route:yarn-app-attempts', 'Unit | Route | yarn app attempts', {
|
||||
// Specify the other units that are required for this test.
|
||||
// needs: ['controller:foo']
|
||||
});
|
||||
|
||||
test('it exists', function(assert) {
|
||||
let route = this.subject();
|
||||
assert.ok(route);
|
||||
});
|
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { moduleFor, test } from 'ember-qunit';
|
||||
|
||||
moduleFor('route:yarn-queue-apps', 'Unit | Route | yarn queue apps', {
|
||||
// Specify the other units that are required for this test.
|
||||
// needs: ['controller:foo']
|
||||
});
|
||||
|
||||
test('it exists', function(assert) {
|
||||
let route = this.subject();
|
||||
assert.ok(route);
|
||||
});
|
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { moduleFor, test } from 'ember-qunit';
|
||||
|
||||
moduleFor('route:yarn-queues', 'Unit | Route | yarn queues', {
|
||||
// Specify the other units that are required for this test.
|
||||
// needs: ['controller:foo']
|
||||
});
|
||||
|
||||
test('it exists', function(assert) {
|
||||
let route = this.subject();
|
||||
assert.ok(route);
|
||||
});
|
Loading…
Reference in New Issue