Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 39751200B99 for ; Wed, 5 Oct 2016 14:37:08 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 37C6A160ADB; Wed, 5 Oct 2016 12:37:08 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id CC5DA160ADE for ; Wed, 5 Oct 2016 14:37:05 +0200 (CEST) Received: (qmail 71423 invoked by uid 500); 5 Oct 2016 12:37:05 -0000 Mailing-List: contact commits-help@ambari.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: ambari-dev@ambari.apache.org Delivered-To: mailing list commits@ambari.apache.org Received: (qmail 71314 invoked by uid 99); 5 Oct 2016 12:37:04 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 05 Oct 2016 12:37:04 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id B9432DFAF2; Wed, 5 Oct 2016 12:37:04 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: jonathanhurley@apache.org To: commits@ambari.apache.org Date: Wed, 05 Oct 2016 12:37:06 -0000 Message-Id: In-Reply-To: <97b112db99024349b0d7c77212eac7ac@git.apache.org> References: <97b112db99024349b0d7c77212eac7ac@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [3/5] ambari git commit: AMBARI-18313. Capacity Scheduler View: Xml diff view tool to show changes made and queue capacity chart (Akhil PB via pallavkul) archived-at: Wed, 05 Oct 2016 12:37:08 -0000 AMBARI-18313. Capacity Scheduler View: Xml diff view tool to show changes made and queue capacity chart (Akhil PB via pallavkul) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/62dc775e Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/62dc775e Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/62dc775e Branch: refs/heads/branch-feature-AMBARI-18456 Commit: 62dc775ee4156e1a43ce0b991f3f47f68155128d Parents: 26660f2 Author: Pallav Kulshreshtha Authored: Wed Oct 5 15:32:19 2016 +0530 Committer: Pallav Kulshreshtha Committed: Wed Oct 5 15:32:19 2016 +0530 ---------------------------------------------------------------------- .../src/main/resources/ui/app/components.js | 2 + .../ui/app/components/labelCapacityBar.js | 12 +- .../resources/ui/app/components/queueBadge.js | 6 +- .../ui/app/components/queueHierarchy.js | 11 + .../resources/ui/app/components/queueMapping.js | 25 +- .../resources/ui/app/components/queueSummary.js | 23 +- .../ui/app/components/sunburstChart.js | 339 +++++++++++++++++++ .../ui/app/components/xmldiffViewer.js | 101 ++++++ .../resources/ui/app/controllers/advanced.js | 21 +- .../resources/ui/app/controllers/capsched.js | 39 ++- .../resources/ui/app/controllers/editqueue.js | 66 +++- .../resources/ui/app/controllers/queuesconf.js | 106 +++++- .../resources/ui/app/controllers/scheduler.js | 21 +- .../src/main/resources/ui/app/models/queue.js | 9 +- .../src/main/resources/ui/app/router.js | 49 ++- .../resources/ui/app/styles/application.less | 59 ++++ .../src/main/resources/ui/app/templates.js | 2 + .../resources/ui/app/templates/capsched.hbs | 6 + .../ui/app/templates/capsched/advanced.hbs | 13 +- .../capsched/partials/accessControlList.hbs | 4 +- .../capsched/partials/labelCapacity.hbs | 4 +- .../templates/capsched/partials/preemption.hbs | 4 +- .../capsched/partials/queueCapacity.hbs | 34 +- .../capsched/partials/queueResources.hbs | 4 +- .../ui/app/templates/capsched/queuesconf.hbs | 15 +- .../ui/app/templates/capsched/scheduler.hbs | 6 +- .../app/templates/components/queueHierarchy.hbs | 8 +- .../app/templates/components/queueMapping.hbs | 14 +- .../app/templates/components/queueSummary.hbs | 13 - .../app/templates/components/sunburstChart.hbs | 44 +++ .../app/templates/components/xmldiffViewer.hbs | 41 +++ .../src/main/resources/ui/bower.json | 13 +- 32 files changed, 1003 insertions(+), 111 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/62dc775e/contrib/views/capacity-scheduler/src/main/resources/ui/app/components.js ---------------------------------------------------------------------- diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components.js index 8dd7108..8cf9a64 100644 --- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components.js +++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components.js @@ -39,3 +39,5 @@ require('components/editLabelCapacity'); require('components/editQueueCapacity'); require('components/labelCapacityBar'); require('components/displayNodeLabels'); +require('components/xmldiffViewer'); +require('components/sunburstChart'); http://git-wip-us.apache.org/repos/asf/ambari/blob/62dc775e/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/labelCapacityBar.js ---------------------------------------------------------------------- diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/labelCapacityBar.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/labelCapacityBar.js index 7776452..032b2ec 100644 --- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/labelCapacityBar.js +++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/labelCapacityBar.js @@ -49,10 +49,14 @@ App.LabelCapacityBarComponent = Ember.Component.extend({ warnInvalidLabelCapacity: function() { var totalCap = this.get('childrenQueueLabelsTotalCapacity'); - var isInvalid = false; - if (totalCap > 100 || totalCap < 100) { - isInvalid = true; - } + var isInvalid = totalCap !== 100; + this.get('labels').forEach(function(label) { + if (isInvalid) { + label.set('overCapMessage', 'Invalid Total Capacity for label: '+label.get('name')); + } else { + label.set('overCapMessage', undefined); + } + }); this.get('labels').setEach('overCapacity', isInvalid); this.set('warnInvalidTotalLabelCapacity', isInvalid); return isInvalid; http://git-wip-us.apache.org/repos/asf/ambari/blob/62dc775e/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueBadge.js ---------------------------------------------------------------------- diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueBadge.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueBadge.js index f8978c2..0403b3d 100644 --- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueBadge.js +++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueBadge.js @@ -34,11 +34,13 @@ App.WarningInfoComponent = Em.Component.extend({ layout:Em.Handlebars.compile(''), tagName:'span', tooltip:'Warning', + placement:'bottom', initTooltip: function(){ - var tipMsg = this.get('tooltip'); + var tipMsg = this.get('tooltip'), + postion = this.get('placement'); this.$().tooltip({ title:tipMsg, - placement:'bottom' + placement:postion }); }.on('didInsertElement'), }); http://git-wip-us.apache.org/repos/asf/ambari/blob/62dc775e/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueHierarchy.js ---------------------------------------------------------------------- diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueHierarchy.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueHierarchy.js index 64a28343..674c9c7 100644 --- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueHierarchy.js +++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueHierarchy.js @@ -29,6 +29,17 @@ .filterBy('parentPath', this.get('parent')); }.property('depth', 'parent', 'queues.length', 'queues.@each.name'), + cildrenQueues: function() { + var leafQs = this.get('leafQs'), + deltedQs = this.get('deletedQs'); + + var deletedAtDepth = deltedQs + .filterBy('depth', this.get('depth')) + .filterBy('parentPath', this.get('parent')); + + return leafQs.pushObjects(deletedAtDepth); + }.property('leafQs.length', 'deletedQs.[]'), + childDepth: function () { return this.get('leafQs.firstObject.depth') + 1; }.property('depth'), http://git-wip-us.apache.org/repos/asf/ambari/blob/62dc775e/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueMapping.js ---------------------------------------------------------------------- diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueMapping.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueMapping.js index 107b377..1d07351 100644 --- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueMapping.js +++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueMapping.js @@ -34,6 +34,7 @@ selectedLeafQueueNameForUsers: null, selectedLeafQueueNameForGroups: null, isQueueMappingsDirty: false, + scheduler: null, actions: { showMappingOptions: function(){ @@ -51,6 +52,13 @@ }, toggleMappingOverride: function() { this.toggleProperty('mappingsOverrideEnable'); + }, + rollbackProp: function(prop, item) { + if (prop === "queue_mappings") { + var oldMappings = (item.changedAttributes()[prop][0])? item.changedAttributes()[prop][0].split(',') : []; + this.set('queueMappings', oldMappings); + } + this.sendAction("rollbackProp", prop, item); } }, @@ -103,9 +111,10 @@ addCustomQueueMappings: function(csValues, selectedLeafQName){ var that = this; - csValues = csValues.trim() || '', - userOrGroupNames = csValues.split(',') || [], - mappingPattern = this.get('selectedMapping'); + csValues = csValues.trim() || '', + userOrGroupNames = csValues.split(',') || [], + mappingPattern = this.get('selectedMapping'); + userOrGroupNames.forEach(function(ugname){ that.get('queueMappings').pushObject(mappingPattern.replace('%name', ugname).replace('%qname', selectedLeafQName)); }); @@ -143,5 +152,13 @@ destroyEventListeners: function() { this.$('#collapseQueueMappingsBtn').off('click'); - }.on('willDestroyElement') + }.on('willDestroyElement'), + + isMappingsDirty: function() { + return this.get('scheduler').changedAttributes().hasOwnProperty('queue_mappings'); + }.property('scheduler.queue_mappings'), + + isOverrideEnableDirty: function() { + return this.get('scheduler').changedAttributes().hasOwnProperty('queue_mappings_override_enable'); + }.property('scheduler.queue_mappings_override_enable') }); http://git-wip-us.apache.org/repos/asf/ambari/blob/62dc775e/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueSummary.js ---------------------------------------------------------------------- diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueSummary.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueSummary.js index 2690c40..8923e8e 100644 --- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueSummary.js +++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueSummary.js @@ -31,7 +31,7 @@ isQueueStateNeedRefresh: function() { var qsNeedRefresh = this.get('queuesNeedRefresh'), - qq = this.get('queue'); + qq = this.get('queue'); if (qsNeedRefresh && qsNeedRefresh.findBy('path', qq.get('path'))) { return true; @@ -44,7 +44,7 @@ isQueueCapacityNeedRefresh: function() { var qsNeedRefresh = this.get('queuesNeedRefresh'), - qq = this.get('queue'); + qq = this.get('queue'); if (qsNeedRefresh && qsNeedRefresh.findBy('path', qq.get('path'))) { return true; @@ -89,22 +89,5 @@ isNewQueue: function() { return this.get('queue.isNewQueue'); - }.property('queue.isNewQueue'), - - effectiveCapacity: function() { - var currentQ = this.get('queue'), - allQueues = this.get('allQueues'), - effectiveCapacityRatio = 1; - - while (currentQ !== null) { - effectiveCapacityRatio *= (currentQ.get('capacity') / 100); - currentQ = allQueues.findBy('id', currentQ.get('parentPath').toLowerCase()) || null; - } - - var effectiveCapacityPercent = effectiveCapacityRatio * 100, - absoluteCapacity = parseFloat(parseFloat(effectiveCapacityPercent).toFixed(this.get('precision'))); - this.get('queue').set('absolute_capacity', absoluteCapacity || 0); - - return absoluteCapacity; - }.property('queue.capacity', 'allQueues.@each.capacity', 'allQueues.length') + }.property('queue.isNewQueue') }); http://git-wip-us.apache.org/repos/asf/ambari/blob/62dc775e/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/sunburstChart.js ---------------------------------------------------------------------- diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/sunburstChart.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/sunburstChart.js new file mode 100644 index 0000000..d5b19ae --- /dev/null +++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/sunburstChart.js @@ -0,0 +1,339 @@ +/** + * 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. + */ + +var App = require('app'); + +function _getSunburstChartDataForDefault(queue, json, allQueues) { + var childrenQs = allQueues.filterBy('parentPath', queue.get('path')), + qdata = { + "name": queue.get('name'), + "path": queue.get('path'), + "capacity": queue.get('capacity'), + "absoluteCapacity": queue.get('absolute_capacity')||0, + "size": queue.get('capacity'), + "isLabel": false + }; + + if (!Ember.isEmpty(childrenQs)) { + qdata["children"] = []; + } + + if (json["children"]) { + json["children"].push(qdata); + } + + childrenQs.forEach(function(child) { + return _getSunburstChartDataForDefault(child, qdata, allQueues); + }); + return json; +} + +function _getSunburstChartDataForLabel(queue, json, allQueues, labelName) { + var childrenQs = allQueues.filterBy('parentPath', queue.get('path')), + qLabel = queue.get('labels').findBy('name', labelName), + qdata = { + "name": queue.get('name'), + "path": queue.get('path'), + "capacity": qLabel?qLabel.get('capacity') : 0, + "absoluteCapacity": 0, + "size": qLabel? qLabel.get('capacity') : 0, + "isLabel": true + }; + + if (!Ember.isEmpty(childrenQs)) { + qdata["children"] = []; + } + + if (json["children"]) { + json["children"].push(qdata); + } + + childrenQs.forEach(function(child) { + return _getSunburstChartDataForLabel(child, qdata, allQueues, labelName); + }); + return json; +} + +App.SunburstChartComponent = Ember.Component.extend({ + layoutName: 'components/sunburstChart', + queues: null, + selectedQueue: null, + allNodeLabels: null, + + width: 0, + height: 0, + radius: 0, + data: null, + colorScale: null, + chartRendered: false, + queueCapacityTypeSelected: null, + + queueCapacityTypeValues: null, + + didInsertElement: function() { + this.initializeChart(); + this.initializeCapacityTypeOptions(); + this.set("queueCapacityTypeSelected", null); + this.setChartDataForDefault(); + this.renderChart(); + }, + + initializeChart: function() { + var width = this.$().width(); + this.$('.panel-default').height(width); + var height = this.$('.panel-default').height() - this.$('#top_container').outerHeight(); + + var vizWidth = width - 60; + var vizHeight = height - 80; + var radius = Math.min(vizWidth, vizHeight) / 2; + + this.set('width', vizWidth); + this.set('height', vizHeight); + this.set('radius', radius); + this.set('colorScale', d3.scale.category20()); + }, + + initializeCapacityTypeOptions: function() { + var options = [{ + name: "Default", + value: null + }]; + if (this.get('allNodeLabels') !== null) { + this.get('allNodeLabels').forEach(function(label) { + options.push({ + name: "Label: " + label.name, + value: label.name + }); + }); + } + this.set("queueCapacityTypeValues", options); + }, + + setChartDataForDefault: function() { + var queues = this.get('queues'), + rootQ = queues.findBy('name', 'root'), + dataJson = { + "name": "sunburst", + "children": [] + }; + + var data = _getSunburstChartDataForDefault(rootQ, dataJson, queues); + this.set("data", data); + }, + + setChartDataForLabel: function() { + var queues = this.get('queues'), + allNodeLabels = this.get('allNodeLabels'), + rootQ = queues.findBy('name', 'root'), + labelName = this.get('queueCapacityTypeSelected'); + + var dataJson = { + "name": "sunburst", + "children": [] + }; + var data = _getSunburstChartDataForLabel(rootQ, dataJson, queues, labelName); + this.set("data", data); + }, + + renderChart: function() { + var self = this, + width = this.get('width'), + height = this.get('height'), + radius = this.get('radius'), + data = this.get('data'), + colors = this.get('colorScale'); + + var vis = d3.select("#sunburst_chart").append("svg:svg") + .attr("width", width) + .attr("height", height) + .append("svg:g") + .attr("id", "sunburst_container") + .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); + + var partition = d3.layout.partition() + .size([2 * Math.PI, radius * radius]) + .value(function(d) { + return d.size; + }); + + var arc = d3.svg.arc() + .startAngle(function(d) { return d.x; }) + .endAngle(function(d) { return d.x + d.dx; }) + .innerRadius(function(d) { return Math.sqrt(d.y); }) + .outerRadius(function(d) { return Math.sqrt(d.y + d.dy); }); + + vis.append("svg:circle") + .attr("r", radius) + .style("opacity", 0); + + var nodes = partition.nodes(data) + .filter(function(d) { + return (d.dx > 0.005); + }); + + var path = vis.data([data]).selectAll("path") + .data(nodes) + .enter().append("svg:path") + .attr("id", function(d) { return d.path; }) + .attr("data-node", function(d) { + var node = { + name: d.name, + path: d.path, + capacity: d.capacity, + absoluteCapacity: d.absoluteCapacity, + isLabel: d.isLabel + }; + return JSON.stringify(node); + }) + .attr("display", function(d) { return d.depth ? null : "none"; }) + .attr("d", arc) + .attr("fill-rule", "evenodd") + .style("fill", function(d) { + var colr = colors(d.name); + d.color = colr; + return colr; + }) + .style("opacity", 1); + + this.set('chartRendered', true); + this.adjustPositions(); + }, + + mouseover: function(d, elem) { + this.showQueueInfo(d); + d3.selectAll("path").style("opacity", 0.3); + d3.select(elem).style("opacity", 1); + }, + + showQueueInfo: function(node) { + var precentage = node.isLabel? node.capacity : node.absoluteCapacity; + var percentageString = precentage + "%"; + d3.select("#capacityPercentage").text(percentageString); + d3.select("#queuePath").text(node.path); + if (node.isLabel) { + d3.select("#type_text").text("Capacity:"); + } else { + d3.select("#type_text").text("Abs Cap:"); + } + d3.select("#explanation").style("visibility", ""); + d3.select("#queue_info").style("visibility", ""); + }, + + hideQueueInfo: function() { + d3.select("#queuePath").text(""); + d3.select("#type_text").text(""); + d3.select("#capacityPercentage").text(""); + d3.select("#explanation").style("visibility", "hidden"); + d3.select("#queue_info").style("visibility", "hidden"); + }, + + mouseleave: function(d) { + d3.selectAll("path").style("opacity", 1); + d3.select("#explanation").style("visibility", "hidden"); + d3.select("#queue_info").style("visibility", "hidden"); + var queue = this.get("selectedQueue"); + if (queue) { + var node = this.$("path[id='"+queue.get('path')+"']").data('node'); + this.showQueueInfo({ + name: node.name, + path: node.path, + capacity: node.capacity, + absoluteCapacity: node.absoluteCapacity, + isLabel: node.isLabel + }); + } + }, + + hightlightSelectedQueue: function() { + this.removeHighlightFromChart(); + var width = this.get('width'), + height = this.get('height'), + queue = this.get("selectedQueue"); + if (queue) { + d3.selectAll("path").style("opacity", 0.3); + d3.select("path[id='"+queue.get('path')+"']") + .style("fill", "#3276b1") + .style("opacity", 1); + var node = this.$("path[id='"+queue.get('path')+"']").data('node'); + this.showQueueInfo({ + name: node.name, + path: node.path, + capacity: node.capacity, + absoluteCapacity: node.absoluteCapacity, + isLabel: node.isLabel + }); + } + }, + + removeHighlightFromChart: function() { + d3.selectAll("path").style("opacity", 1); + d3.selectAll("path").each(function(node) { + if (node.path) { + d3.select("path[id='"+node.path+"']") + .style("fill", node.color); + } + }); + this.hideQueueInfo(); + }, + + adjustPositions: function() { + var rootOffset = this.$("path[id='root']").offset(), + rootPathDims = this.$("path[id='root']")[0].getBoundingClientRect(), + rootW = rootPathDims.width, + rootH = rootPathDims.height, + explanationH = this.$("#explanation").height(), + explanationW = this.$("#explanation").width(); + + var rootCenterX = rootOffset.left + rootW / 2, + rootCenterY = rootOffset.top + rootH / 2, + posX = rootCenterX - explanationW / 2, + posY = rootCenterY - explanationH / 2; + + this.$("#explanation").offset({left: posX, top: posY}); + }, + + renderObserver: function() { + d3.select("#sunburst_chart svg").remove(); + this.set('chartRendered', false); + this.set("queueCapacityTypeSelected", null); + this.setChartDataForDefault(); + this.renderChart(); + this.hightlightSelectedQueue(); + }.observes('queues', 'queues.[]', 'queues.@each.capacity'), + + queueSelectionObserver: function() { + if (this.get('selectedQueue') && this.get('chartRendered')) { + this.hightlightSelectedQueue(); + } else { + this.removeHighlightFromChart(); + } + }.observes('selectedQueue', 'chartRendered'), + + watchTypeSelection: function() { + d3.select("#sunburst_chart svg").remove(); + this.set('chartRendered', false); + if (this.get("queueCapacityTypeSelected") !== null) { + this.setChartDataForLabel(); + } else { + this.setChartDataForDefault(); + } + this.renderChart(); + this.hightlightSelectedQueue(); + }.observes("queueCapacityTypeSelected") +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/62dc775e/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/xmldiffViewer.js ---------------------------------------------------------------------- diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/xmldiffViewer.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/xmldiffViewer.js new file mode 100644 index 0000000..62431f6 --- /dev/null +++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/xmldiffViewer.js @@ -0,0 +1,101 @@ +/** + * 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. + */ + +var App = require('app'); + +App.XmldiffViewerComponent = Ember.Component.extend({ + layoutName: 'components/xmldiffViewer', + diffConfig: null, + viewConfig: null, + + actions: { + closeDiffViewer: function() { + this.set('diffConfig', null); + this.set('viewConfig', null); + } + }, + + diffViewObserver: function() { + if (this.get('diffConfig')) { + this.showXmlDiffView(); + } + }.observes('diffConfig'), + + viewConfigObserver: function() { + if (this.get('viewConfig')) { + this.showCapSchedViewXml(); + } + }.observes('viewConfig'), + + showXmlDiffView: function() { + this.$("#xmldiffViewerDialog").modal('show'); + var config = this.get('diffConfig'), + basetxt = difflib.stringAsLines(config.baseXML); + newtxt = difflib.stringAsLines(config.newXML), + sm = new difflib.SequenceMatcher(basetxt, newtxt), + opcodes = sm.get_opcodes(), + $diffOutput = this.$('#xmldiffOutput'); + + this.showHideOutputContainers('diffView'); + this.setDialogDimentions(); + + $diffOutput.append(diffview.buildView({ + baseTextLines: basetxt, + newTextLines: newtxt, + opcodes: opcodes, + baseTextName: 'Base XML', + newTextName: 'New XML', + contextSize: 2, + viewType: 0 + })); + }, + + showCapSchedViewXml: function() { + this.$("#xmldiffViewerDialog").modal('show'); + var config = this.get('viewConfig'), + $output = this.$('#capshedViewXml'); + + this.showHideOutputContainers('xmlView'); + this.setDialogDimentions(true); + $output.text(config.xmlConfig); + }, + + showHideOutputContainers: function(viewType) { + this.$('#xmldiffOutput').empty().hide(); + this.$('#capshedViewXml').empty().hide(); + if (viewType === 'diffView') { + this.$('#xmldiffOutput').show(); + } else { + this.$('#capshedViewXml').show(); + } + }, + + setDialogDimentions: function(hideOverflow) { + var dialogHt = this.$("#xmldiffViewerDialog").height(), + contentHt = dialogHt-60, + bodyHt = contentHt-170; + + this.$("#xmldiffViewerDialog").find('.modal-content').height(contentHt); + this.$("#xmldiffViewerDialog").find('.modal-body').height(bodyHt); + if (hideOverflow) { + this.$("#xmldiffViewerDialog").find('.modal-body').css('overflow', 'hidden'); + } else { + this.$("#xmldiffViewerDialog").find('.modal-body').css('overflow', 'auto'); + } + } +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/62dc775e/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/advanced.js ---------------------------------------------------------------------- diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/advanced.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/advanced.js index c079079..af15fa5 100644 --- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/advanced.js +++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/advanced.js @@ -25,6 +25,7 @@ App.CapschedAdvancedController = Ember.Controller.extend({ actions: { rollbackQueueMappingProps: function() { + var tempRefreshNeeded = this.get('isRefreshOrRestartNeeded'); var sched = this.get('scheduler'), attributes = sched.changedAttributes(), props = this.queueMappingProps; @@ -33,6 +34,16 @@ App.CapschedAdvancedController = Ember.Controller.extend({ sched.set(prop, attributes[prop][0]); } }); + this.set('isRefreshOrRestartNeeded', tempRefreshNeeded); + }, + rollbackProp: function(prop, item) { + var tempRefreshNeeded = this.get('isRefreshOrRestartNeeded'); + var attributes = item.changedAttributes(); + if (attributes.hasOwnProperty(prop)) { + item.set(prop, attributes[prop][0]); + } + this.set('isRefreshOrRestartNeeded', tempRefreshNeeded); + this.afterRollbackProp(); }, showSaveConfigDialog: function(mode) { if (mode) { @@ -76,5 +87,13 @@ App.CapschedAdvancedController = Ember.Controller.extend({ forceRefreshRequired: function() { return !this.get('isQueueMappingsDirty') && this.get('isRefreshOrRestartNeeded'); - }.property('isQueueMappingsDirty', 'isRefreshOrRestartNeeded') + }.property('isQueueMappingsDirty', 'isRefreshOrRestartNeeded'), + + afterRollbackProp: function() { + if (this.get('isQueueMappingsDirty')) { + this.set('isRefreshOrRestartNeeded', true); + } else { + this.set('isRefreshOrRestartNeeded', false); + } + } }); http://git-wip-us.apache.org/repos/asf/ambari/blob/62dc775e/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/capsched.js ---------------------------------------------------------------------- diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/capsched.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/capsched.js index 447cae0..631edbb 100644 --- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/capsched.js +++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/capsched.js @@ -19,6 +19,11 @@ var App = require('app'); App.CapschedController = Ember.Controller.extend({ + queues: null, + precision: 2, + selectedQueue: null, + allNodeLabels: Ember.computed.alias('store.nodeLabels.content'), + actions: { loadTagged: function (tag) { this.transitionToRoute('capsched.scheduler').then(function() { @@ -27,7 +32,7 @@ App.CapschedController = Ember.Controller.extend({ }, clearAlert: function () { this.set('alertMessage',null); - }, + } }, /** @@ -42,6 +47,26 @@ App.CapschedController = Ember.Controller.extend({ */ isNotOperator: Ember.computed.not('isOperator'), + queuesWatcher: function() { + var allQueues = this.get('queues') || []; + allQueues.forEach(function(queue) { + var absCap = this.getAbsoluteCapacityForQueue(queue); + queue.set('absolute_capacity', absCap); + }.bind(this)); + }.observes('queues', 'queues.[]', 'queues.@each.capacity').on('init'), + + getAbsoluteCapacityForQueue: function(queue) { + var allQueues = this.get('queues'); + var effectCapRatio = 1; + while (queue !== null) { + effectCapRatio *= queue.get('capacity') / 100; + queue = allQueues.findBy('id', queue.get('parentPath').toLowerCase()) || null; + } + var effectCapPercent = effectCapRatio * 100, + absoluteCap = parseFloat(parseFloat(effectCapPercent).toFixed(this.get('precision')));; + return absoluteCap; + }, + alertMessage: null, tags: function () { @@ -60,5 +85,17 @@ App.CapschedController = Ember.Controller.extend({ stopSpinner: function() { this.set('showSpinner', false); + }, + + diffXmlConfig: null, + + viewConfigXmlDiff: function(config) { + this.set('diffXmlConfig', config); + }, + + viewXmlConfig: null, + + viewCapSchedXml: function(config) { + this.set('viewXmlConfig', config); } }); http://git-wip-us.apache.org/repos/asf/ambari/blob/62dc775e/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/editqueue.js ---------------------------------------------------------------------- diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/editqueue.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/editqueue.js index 7c62ef0..9d84704 100644 --- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/editqueue.js +++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/editqueue.js @@ -66,16 +66,19 @@ App.CapschedQueuesconfEditqueueController = Ember.Controller.extend({ editQueueName: function() { this.set('enableEditQName', true); this.set('updatedQName', this.get('content.name')); + this.set('controllers.capschedQueuesconf.isEditingQueueName', true); }, cancelQNameEdit: function() { this.set('enableEditQName', false); this.set('isInvalidQName', false); this.set('invalidQNameMessage', ''); + this.set('controllers.capschedQueuesconf.isEditingQueueName', false); }, renameQueue: function() { if (this.validateQName()) { return; } + this.set('controllers.capschedQueuesconf.isEditingQueueName', false); this.set('content.name', this.get('updatedQName')); this.set('enableEditQName', false); }, @@ -83,6 +86,24 @@ App.CapschedQueuesconfEditqueueController = Ember.Controller.extend({ this.send('rollbackProp', 'disable_preemption', this.get('content')); this.send('rollbackProp', 'isPreemptionInherited', this.get('content')); this.set('content.isPreemptionOverriden', false); + }, + rollbackProp: function(prop, item) { + var tempRefreshNeeded = this.get('isRefreshOrRestartNeeded'); + var attributes = item.changedAttributes(); + if (attributes.hasOwnProperty(prop)) { + item.set(prop, attributes[prop][0]); + } + this.set('isRefreshOrRestartNeeded', tempRefreshNeeded); + this.afterRollbackProp(); + } + }, + + afterRollbackProp: function() { + var isAnyQDirty = this.get('allQueues').isAny('isAnyDirty', true); + if (isAnyQDirty) { + this.set('isRefreshOrRestartNeeded', true); + } else { + this.set('isRefreshOrRestartNeeded', false); } }, @@ -114,6 +135,15 @@ App.CapschedQueuesconfEditqueueController = Ember.Controller.extend({ this.validateQName(); }.observes('updatedQName', 'updatedQName.length'), + absoluteClusterCapacity: function() { + return this.get('content.absolute_capacity'); + }.property('content', 'content.absolute_capacity'), + + absoluteClusterBarWidth: function() { + var absCap = this.get('absoluteClusterCapacity'); + return this.get('widthPattern').fmt(absCap); + }.property('absoluteClusterCapacity'), + /** * Collection of modified fields in queue. * @type {Object} - { [fileldName] : {Boolean} } @@ -250,9 +280,10 @@ App.CapschedQueuesconfEditqueueController = Ember.Controller.extend({ }, isAnyQueueResourcesDirty: function() { - return this.get('queueDirtyFields.user_limit_factor') || this.get('queueDirtyFields.minimum_user_limit_percent') - || this.get('queueDirtyFields.maximum_applications') || this.get('queueDirtyFields.maximum_am_resource_percent') - || this.get('queueDirtyFields.ordering_policy') || this.get('queueDirtyFields.enable_size_based_weight'); + var changedAttrs = this.get('content').changedAttributes(); + return changedAttrs.hasOwnProperty('user_limit_factor') || changedAttrs.hasOwnProperty('minimum_user_limit_percent') + || changedAttrs.hasOwnProperty('maximum_applications') || changedAttrs.hasOwnProperty('maximum_am_resource_percent') + || changedAttrs.hasOwnProperty('ordering_policy') || changedAttrs.hasOwnProperty('enable_size_based_weight'); }.property( 'content.user_limit_factor', 'content.minimum_user_limit_percent', @@ -382,7 +413,8 @@ App.CapschedQueuesconfEditqueueController = Ember.Controller.extend({ }, isAnyAccessControlListDirty: function() { - return this.get('queueDirtyFields.acl_administer_queue') || this.get('queueDirtyFields.acl_submit_applications'); + var chagedAttrs = this.get('content').changedAttributes(); + return chagedAttrs.hasOwnProperty('acl_administer_queue') || chagedAttrs.hasOwnProperty('acl_submit_applications'); }.property('content.acl_submit_applications', 'content.acl_administer_queue'), /** @@ -443,8 +475,9 @@ App.CapschedQueuesconfEditqueueController = Ember.Controller.extend({ if (this.get('isLeafQ')) { return false; } - return this.get('queueDirtyFields.queues') || this.get('childrenQueues').anyBy('isDirtyCapacity', true) || this.get('childrenQueues').anyBy('isDirtyMaxCapacity', true); - }.property('content', 'content.queues', 'childrenQueues.@each.isDirtyCapacity', 'childrenQueues.@each.isDirtyMaxCapacity'), + return this.get('queueDirtyFields.queues') || this.get('childrenQueues').anyBy('isDirtyCapacity', true) + || this.get('childrenQueues').anyBy('isDirtyMaxCapacity', true) || this.get('warnInvalidCapacity'); + }.property('content', 'content.queues', 'childrenQueues.@each.isDirtyCapacity', 'childrenQueues.@each.isDirtyMaxCapacity', 'warnInvalidCapacity'), /** * Adds observers for each queue attribute. @@ -598,12 +631,14 @@ App.CapschedQueuesconfEditqueueController = Ember.Controller.extend({ warnInvalidTotalLabelCapacity: false, isAnyChildrenQueueLabelDirty: function() { - if (this.get('isLeafQ')) { - return this.get('queueDirtyFields.default_node_label_expression') || false; + var changedAttrs = this.get('content').changedAttributes(); + if (this.get('content.queues') === null) { + return changedAttrs.hasOwnProperty('default_node_label_expression'); } - return this.get('childrenQueues').anyBy('isLabelsDirty', true) || this.get('queueDirtyFields.default_node_label_expression') - || this.get('childrenLabelsForQueue').anyBy('isDirtyLabelCapacity', true) || this.get('childrenLabelsForQueue').anyBy('isDirtyLabelMaxCapacity', true); - }.property('content', 'childrenQueues.@each.isLabelsDirty', 'childrenLabelsForQueue.@each.isDirtyLabelCapacity', 'childrenLabelsForQueue.@each.isDirtyLabelMaxCapacity', 'content.default_node_label_expression'), + return this.get('childrenQueues').anyBy('isLabelsDirty', true) || changedAttrs.hasOwnProperty('default_node_label_expression') + || this.get('childrenLabelsForQueue').anyBy('isDirtyLabelCapacity', true) || this.get('childrenLabelsForQueue').anyBy('isDirtyLabelMaxCapacity', true) + || this.get('warnInvalidTotalLabelCapacity'); + }.property('content', 'childrenQueues.@each.isLabelsDirty', 'childrenLabelsForQueue.@each.isDirtyLabelCapacity', 'childrenLabelsForQueue.@each.isDirtyLabelMaxCapacity', 'content.default_node_label_expression', 'warnInvalidTotalLabelCapacity'), //Preemption isPreemptionSupported: Ember.computed.alias('store.isPreemptionSupported'), @@ -644,7 +679,7 @@ App.CapschedQueuesconfEditqueueController = Ember.Controller.extend({ }, isQueuePreemptionDirty: function() { - return this.get('queueDirtyFields.disable_preemption'); + return this.get('content').changedAttributes().hasOwnProperty('disable_preemption'); }.property('content.disable_preemption', 'content.isPreemptionInherited'), doOverridePreemption: function(key, value) { @@ -667,10 +702,5 @@ App.CapschedQueuesconfEditqueueController = Ember.Controller.extend({ this.set('content.isPreemptionInherited', true); this.set('content.disable_preemption', ''); } - }.observes('content.isPreemptionOverriden'), - - saveRefreshRestartWatcher: function() { - this.set('isRefreshOrRestartNeeded', this.get('isAnyQueueResourcesDirty') || this.get('isAnyAccessControlListDirty') - || this.get('isAnyChildrenQueueCapacityDirty') || this.get('isAnyChildrenQueueLabelDirty') || this.get('isQueuePreemptionDirty')); - }.observes('isAnyQueueResourcesDirty', 'isAnyAccessControlListDirty', 'isAnyChildrenQueueCapacityDirty', 'isAnyChildrenQueueLabelDirty', 'isQueuePreemptionDirty') + }.observes('content.isPreemptionOverriden') }); http://git-wip-us.apache.org/repos/asf/ambari/blob/62dc775e/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/queuesconf.js ---------------------------------------------------------------------- diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/queuesconf.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/queuesconf.js index 6a6717a..e7fba41 100644 --- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/queuesconf.js +++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/queuesconf.js @@ -32,16 +32,19 @@ App.CapschedQueuesconfController = Ember.Controller.extend({ allNodeLabelRecords: [], queuesNeedRefresh: Ember.computed.alias('store.queuesNeedRefresh'), isRefreshOrRestartNeeded: false, + deletedQueues: Ember.computed.alias('store.deletedQueues'), actions: { addNewQueue: function() { this.set('newQueueName', ''); this.set('showQueueNameInput', true); + this.set('isCreatingNewQueue', true); }, createNewQueue: function() { if (this.validateQueueName()) { return; } + this.set('isCreatingNewQueue', false); var store = this.get('store'), queueName = this.get('newQueueName'), parentPath = this.get('selectedQueue.path'), @@ -61,6 +64,7 @@ App.CapschedQueuesconfController = Ember.Controller.extend({ freeLeafCapacity = (totalLeafCapacity < 100) ? 100 - totalLeafCapacity : 0; } var qCapacity = (newInLeaf) ? 100 : freeLeafCapacity; + var requireRestart = (this.get('selectedQueue.isLeafQ') && !this.get('selectedQueue.isNewQueue'))? true : false; newQueue = store.createRecord('queue', { id: queuePath.toLowerCase(), name: queueName, @@ -69,7 +73,8 @@ App.CapschedQueuesconfController = Ember.Controller.extend({ depth: depth, isNewQueue: true, capacity: qCapacity, - maximum_capacity: 100 + maximum_capacity: 100, + requireRestart: requireRestart }); this.set('newQueue', newQueue); store.saveAndUpdateQueue(newQueue).then(Em.run.bind(this, 'saveAndUpdateQueueSuccess', newQueue)); @@ -86,8 +91,11 @@ App.CapschedQueuesconfController = Ember.Controller.extend({ this.set('showQueueNameInput', false); this.set('isInvalidQueueName', false); this.set('invalidQueueNameMessage', ''); + this.set('isCreatingNewQueue', false); }, discardQueuesChanges: function() { + var tempRefreshNeeded = this.get('isRefreshOrRestartNeeded'); + var tempRestart = this.get('isQueuesMustNeedRestart'); var allQueues = this.get('queues'); allQueues.forEach(function(qq){ var qAttrs = qq.changedAttributes(); @@ -105,12 +113,13 @@ App.CapschedQueuesconfController = Ember.Controller.extend({ } } }); - //Setting root label capacities back to 100, - //if discard changes set root label capacity to 0. + //Setting root label capacities back to 100, if discard changes set root label capacity to 0. if (qq.get('id') === 'root') { qq.get('labels').setEach('capacity', 100); } }); + this.set('isRefreshOrRestartNeeded', tempRefreshNeeded); + this.set('isQueuesMustNeedRestart', tempRestart); }, stopQueue: function() { this.set('selectedQueue.state', _stopState); @@ -139,6 +148,17 @@ App.CapschedQueuesconfController = Ember.Controller.extend({ }, showConfirmDialog: function() { this.set('isConfirmDialogOpen', true); + }, + saveCapSchedConfigs: function() { + if (this.get('saveMode') === '') { + var holder = { + refresh: this.get('isRefreshOrRestartNeeded') + }; + this.set('tempRefreshHolder', holder); + } else { + this.set('tempRefreshHolder', null); + } + return true; } }, @@ -146,11 +166,48 @@ App.CapschedQueuesconfController = Ember.Controller.extend({ return this.get('queues').isAny('isAnyDirty', true); }.property('queues.@each.isAnyDirty'), - isQueuesNeedRefreshOrRestart: Ember.computed.or('isAnyQueueDirty', 'needRefresh', 'needRestart', 'isRefreshOrRestartNeeded'), + isQueuesNeedRefreshOrRestart: function() { + var isNeed = this.get('isAnyQueueDirty') || this.get('needRefresh') + || this.get('queuesRequireRestart') || this.get('isRefreshOrRestartNeeded'); + return isNeed; + }.property('isAnyQueueDirty', 'needRefresh', 'queuesRequireRestart', 'isRefreshOrRestartNeeded', 'canNotSave'), + + isQueuesMustNeedRestart: false, forceRefreshOrRestartRequired: function() { - return !this.get('isAnyQueueDirty') && this.get('isRefreshOrRestartNeeded'); - }.property('isAnyQueueDirty', 'isRefreshOrRestartNeeded'), + return !this.get('isAnyQueueDirty') && (this.get('isRefreshOrRestartNeeded') || this.get('isQueuesMustNeedRestart')); + }.property('isAnyQueueDirty', 'isRefreshOrRestartNeeded', 'isQueuesMustNeedRestart'), + + refreshRestartWatcher: function() { + if (this.get('tempRefreshHolder')) { + var holder = this.get('tempRefreshHolder'); + this.set('isRefreshOrRestartNeeded', holder.refresh||false); + this.set('tempRefreshHolder', null); + } + }.observes('isRefreshOrRestartNeeded'), + + isDirtyQueuesNeedRefreshQsOp: function() { + if (this.get('isAnyQueueDirty') || this.get('needRefresh') || this.get('isRefreshOrRestartNeeded')) { + if (this.get('queuesRequireRestart')) { + return false; + } + return true; + } else { + return false; + } + }.property('isAnyQueueDirty', 'needRefresh', 'queuesRequireRestart', 'isRefreshOrRestartNeeded', 'canNotSave'), + + isDirtyQueuesNeedRestartRmOp: function() { + if (this.get('queuesRequireRestart') || this.get('isQueuesMustNeedRestart')) { + return true; + } else { + return false; + } + }.property('isAnyQueueDirty', 'queuesRequireRestart', 'isQueuesMustNeedRestart', 'canNotSave'), + + showNeedRefreshOrRestartWarning: function() { + return this.get('isQueuesNeedRefreshOrRestart') && !this.get('canNotSave'); + }.property('isQueuesNeedRefreshOrRestart', 'canNotSave'), selectedQueue: null, newQueue: null, @@ -159,6 +216,13 @@ App.CapschedQueuesconfController = Ember.Controller.extend({ isInvalidQueueName: false, invalidQueueNameMessage: '', + isCreatingNewQueue: false, + isEditingQueueName: false, + + isCreaingOrRenamingQueue: function() { + return this.get('isCreatingNewQueue')||this.get('isEditingQueueName'); + }.property('isCreatingNewQueue', 'isEditingQueueName'), + validateQueueName: function() { var parentPath = this.get('selectedQueue.path'), queueName = this.get('newQueueName'), @@ -289,6 +353,34 @@ App.CapschedQueuesconfController = Ember.Controller.extend({ }.bind(this)); }.observes('queues.length','queues.@each.capacity'), + newQueuesNeedRestart: function() { + return this.get('queues') + .filterBy('isNewQueue', true) + .filterBy('requireRestart', true); + }.property('queues.length', 'queues.@each.isNewQueue', 'queues.@each.requireRestart'), + + hasNewQueuesNeedRestart: Ember.computed.notEmpty('newQueuesNeedRestart.[]'), + + queuesRequireRestart: Ember.computed.or('needRestart', 'hasNewQueuesNeedRestart', 'isQueuesMustNeedRestart'), + + disableRefreshBtn: function() { + var disable = this.get('canNotSave') || this.get('queuesRequireRestart'); + return disable; + }.property('canNotSave', 'queuesRequireRestart', 'isAnyQueueDirty'), + + restartWatcher: function() { + var restart = this.get('needRestart') || this.get('hasNewQueuesNeedRestart'); + this.set('isQueuesMustNeedRestart', restart); + }.observes('needRestart', 'hasNewQueuesNeedRestart'), + + dirtyQueueWatcher: function() { + if (this.get('isAnyQueueDirty')) { + this.set('isRefreshOrRestartNeeded', true); + } else { + this.set('isRefreshOrRestartNeeded', false); + } + }.observes('isAnyQueueDirty'), + /** * True if newQueue is not empty. * @type {Boolean} @@ -347,7 +439,7 @@ App.CapschedQueuesconfController = Ember.Controller.extend({ * check if RM needs restart * @type {bool} */ - needRestart: Em.computed.and('hasDeletedQueues', 'isOperator'), + needRestart: Ember.computed.and('hasDeletedQueues', 'isOperator'), /** * check there is some changes for save http://git-wip-us.apache.org/repos/asf/ambari/blob/62dc775e/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/scheduler.js ---------------------------------------------------------------------- diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/scheduler.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/scheduler.js index 40e3e24..aa139b1 100644 --- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/scheduler.js +++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/scheduler.js @@ -28,6 +28,7 @@ App.CapschedSchedulerController = Ember.Controller.extend({ actions: { rollbackSchedulerProps: function() { + var tempRefreshNeeded = this.get('isRefreshOrRestartNeeded'); var sched = this.get('scheduler'), attributes = sched.changedAttributes(), props = this.schedulerProps; @@ -36,6 +37,16 @@ App.CapschedSchedulerController = Ember.Controller.extend({ sched.set(prop, attributes[prop][0]); } }); + this.set('isRefreshOrRestartNeeded', tempRefreshNeeded); + }, + rollbackProp: function(prop, item) { + var tempRefreshNeeded = this.get('isRefreshOrRestartNeeded'); + var attributes = item.changedAttributes(); + if (attributes.hasOwnProperty(prop)) { + item.set(prop, attributes[prop][0]); + } + this.set('isRefreshOrRestartNeeded', tempRefreshNeeded); + this.afterRollbackProp(); }, showConfirmDialog: function() { this.set('isConfirmDialogOpen', true); @@ -102,5 +113,13 @@ App.CapschedSchedulerController = Ember.Controller.extend({ }, { label: 'Dominant Resource Calculator', value: 'org.apache.hadoop.yarn.util.resource.DominantResourceCalculator' - }] + }], + + afterRollbackProp: function() { + if (this.get('isSchedulerDirty')) { + this.set('isRefreshOrRestartNeeded', true); + } else { + this.set('isRefreshOrRestartNeeded', false); + } + } }); http://git-wip-us.apache.org/repos/asf/ambari/blob/62dc775e/contrib/views/capacity-scheduler/src/main/resources/ui/app/models/queue.js ---------------------------------------------------------------------- diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/models/queue.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/models/queue.js index 0f68a10..e2d67bd 100644 --- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/models/queue.js +++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/models/queue.js @@ -36,7 +36,6 @@ App.Label = DS.Model.extend({ isDefault: function () { return this.get('queue.default_node_label_expression') === this.get('name'); }.property('queue.default_node_label_expression'), - absoluteCapacity: 0, setCapacity: function(cap) { this.set('capacity', cap); }, @@ -244,7 +243,7 @@ App.Queue = DS.Model.extend({ capacity: DS.attr('number', { defaultValue: 0 }), maximum_capacity: DS.attr('number', { defaultValue: 0 }), - //unfunded_capacity: DS.attr('number', { defaultValue: 0 }), + absolute_capacity: 0, isDirtyCapacity: false, isDirtyMaxCapacity: false, @@ -320,5 +319,9 @@ App.Queue = DS.Model.extend({ if (Em.isEmpty(this.get('labels').findBy('name',this.get('default_node_label_expression')))) { this.set('default_node_label_expression',null); } - }.observes('labels','default_node_label_expression') + }.observes('labels','default_node_label_expression'), + + isLeafQ: function() { + return this.get('queues') === null; + }.property('queues') }); http://git-wip-us.apache.org/repos/asf/ambari/blob/62dc775e/contrib/views/capacity-scheduler/src/main/resources/ui/app/router.js ---------------------------------------------------------------------- diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/router.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/router.js index fd996ae..d838958 100644 --- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/router.js +++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/router.js @@ -202,12 +202,6 @@ App.ErrorRoute = Ember.Route.extend({ App.CapschedRoute = Ember.Route.extend({ actions: { - rollbackProp: function(prop, item) { - var attributes = item.changedAttributes(); - if (attributes.hasOwnProperty(prop)) { - item.set(prop, attributes[prop][0]); - } - }, saveCapSchedConfigs: function(saveMode, forceRefresh) { var store = this.get('store'), that = this, @@ -217,7 +211,8 @@ App.CapschedRoute = Ember.Route.extend({ advancedCtrl = this.controllerFor("capsched.advanced"), restartOrRefreshMap = { schedulerTab: schedulerCtrl.get('isRefreshOrRestartNeeded') || false, - queuesTab: queuesconfCtrl.get('isRefreshOrRestartNeeded') || false, + queuesTabRefresh: queuesconfCtrl.get('isRefreshOrRestartNeeded') || false, + queuesTabRestart: queuesconfCtrl.get('isQueuesMustNeedRestart') || false, advancedTab: advancedCtrl.get('isRefreshOrRestartNeeded') || false }; @@ -246,7 +241,8 @@ App.CapschedRoute = Ember.Route.extend({ Em.run.bind(that,'saveConfigsError', 'save') ).then(function () { schedulerCtrl.set('isRefreshOrRestartNeeded', restartOrRefreshMap.schedulerTab); - queuesconfCtrl.set('isRefreshOrRestartNeeded', restartOrRefreshMap.queuesTab); + queuesconfCtrl.set('isRefreshOrRestartNeeded', restartOrRefreshMap.queuesTabRefresh); + queuesconfCtrl.set('isQueuesMustNeedRestart', restartOrRefreshMap.queuesTabRestart); advancedCtrl.set('isRefreshOrRestartNeeded', restartOrRefreshMap.advancedTab); if (opt) { return store.relaunchCapSched(opt); @@ -255,6 +251,7 @@ App.CapschedRoute = Ember.Route.extend({ if (opt) { schedulerCtrl.set('isRefreshOrRestartNeeded', false); queuesconfCtrl.set('isRefreshOrRestartNeeded', false); + queuesconfCtrl.set('isQueuesMustNeedRestart', false); advancedCtrl.set('isRefreshOrRestartNeeded', false); } return store.getRmSchedulerConfigInfo(); @@ -271,6 +268,15 @@ App.CapschedRoute = Ember.Route.extend({ lastSavedXML = store.get('lastSavedConfigXML'), currentXmlConfigs = store.buildConfig('xml'), diffConfigs = {baseXML: lastSavedXML, newXML: currentXmlConfigs}; + + controller.viewConfigXmlDiff(diffConfigs); + }, + viewCapSchedConfigXml: function() { + var store = this.get('store'), + controller = this.controllerFor("capsched"), + viewXmlConfigs = store.buildConfig('xml'); + + controller.viewCapSchedXml({xmlConfig: viewXmlConfigs}); } }, beforeModel: function(transition) { @@ -383,6 +389,7 @@ App.CapschedRoute = Ember.Route.extend({ schedulerCtrl.set('isRefreshOrRestartNeeded', false); advancedCtrl.set('isRefreshOrRestartNeeded', false); queuesconfCtrl.set('isRefreshOrRestartNeeded', false); + queuesconfCtrl.set('isQueuesMustNeedRestart', false); }).catch( Em.run.bind(that, 'saveConfigsError', opt) ).finally(function() { @@ -398,6 +405,14 @@ App.CapschedIndexRoute = Ember.Route.extend({ } }); +App.CapschedSchedulerRoute = Ember.Route.extend({ + actions: { + didTransition: function() { + this.controllerFor('capsched').set('selectedQueue', null); + } + } +}); + App.CapschedQueuesconfIndexRoute = Ember.Route.extend({ beforeModel: function(transition) { var rootQ = this.store.getById('queue', 'root'); @@ -406,6 +421,16 @@ App.CapschedQueuesconfIndexRoute = Ember.Route.extend({ }); App.CapschedQueuesconfEditqueueRoute = Ember.Route.extend({ + actions: { + willTransition: function(transition) { + if (this.controllerFor('capsched.queuesconf').get('isCreaingOrRenamingQueue')) { + transition.abort(); + } + }, + didTransition: function() { + this.controllerFor('capsched').set('selectedQueue', this.controller.get('model')); + } + }, model: function(params, transition) { var queue = this.store.getById('queue', params.queue_id); if (queue) { @@ -419,6 +444,14 @@ App.CapschedQueuesconfEditqueueRoute = Ember.Route.extend({ } }); +App.CapschedAdvancedRoute = Ember.Route.extend({ + actions: { + didTransition: function() { + this.controllerFor('capsched').set('selectedQueue', null); + } + } +}); + App.CapschedTraceRoute = Ember.Route.extend({ model: function() { return this.controllerFor('capsched').get('alertMessage'); http://git-wip-us.apache.org/repos/asf/ambari/blob/62dc775e/contrib/views/capacity-scheduler/src/main/resources/ui/app/styles/application.less ---------------------------------------------------------------------- diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/styles/application.less b/contrib/views/capacity-scheduler/src/main/resources/ui/app/styles/application.less index bd875ba..1ab1740 100644 --- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/styles/application.less +++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/styles/application.less @@ -1140,6 +1140,9 @@ vertical-align: middle; font-size: 1.5em; } + .collapsible-panel-btn { + cursor: pointer; + } } .queue-summary { @@ -1298,3 +1301,59 @@ .alert-message-dialog { display: block; } + +.xmldiff-viewer { + overflow: hidden; + .modal-dialog { + width: 98%; + .modal-body { + overflow: auto; + } + .modal-footer { + padding: 12px 20px 0 0; + } + .viewxml-textarea { + resize: none; + } + } + table.diff { + th.author { + display: none; + } + } +} + +.hierarchical-piechart { + .sunburst-chart { + position: relative; + path { + stroke: #fff; + stroke-width: 1.5px; + } + svg { + margin-left: 20px; + } + .top-container { + padding-bottom: 15px; + } + .queue-explanation { + position: absolute; + width: 70px; + text-align: center; + color: #666; + z-index: 999; + } + .percentage, .queue-name, .queue-path { + font-weight: bold; + } + .queue-info { + width: 50%; + display: inline-block; + } + .select-capacity-type { + width: 45%; + display: inline-block; + vertical-align: top; + } + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/62dc775e/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates.js ---------------------------------------------------------------------- diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates.js index 2c9609f..487d09a 100644 --- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates.js +++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates.js @@ -60,3 +60,5 @@ require('templates/components/labelCapacityBar'); require('templates/components/displayRootLabel'); require('templates/components/displayLeafLabel'); require('templates/capsched/partials/preemption'); +require('templates/components/xmldiffViewer'); +require('templates/components/sunburstChart'); http://git-wip-us.apache.org/repos/asf/ambari/blob/62dc775e/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched.hbs index 14625c1..7dc0d51 100644 --- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched.hbs +++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched.hbs @@ -40,6 +40,10 @@
+ {{#if selectedQueue}} + {{sunburst-chart queues=queues selectedQueue=selectedQueue allNodeLabels=allNodeLabels}} + {{/if}} + {{partial "versionsPanel"}}
@@ -64,3 +68,5 @@ + +{{xmldiff-viewer diffConfig=diffXmlConfig viewConfig=viewXmlConfig}} http://git-wip-us.apache.org/repos/asf/ambari/blob/62dc775e/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/advanced.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/advanced.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/advanced.hbs index 5a54d85..9973708 100644 --- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/advanced.hbs +++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/advanced.hbs @@ -20,18 +20,25 @@ {{!-- QUEUE MAPPING --}} {{#if isOperator}} {{/if}}
-
+
{{#if isQueueMappignsNeedSaveOrRefresh}} - {{warning-info class="yellow-warning fa-2x resfresh-restart-warning" tooltip="Refresh queues is required"}} + {{warning-info class="yellow-warning fa-2x resfresh-restart-warning" tooltip="Refresh queues is required" placement="top"}} {{/if}} + +
http://git-wip-us.apache.org/repos/asf/ambari/blob/62dc775e/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/accessControlList.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/accessControlList.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/accessControlList.hbs index 922e27e..f5b552a 100644 --- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/accessControlList.hbs +++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/accessControlList.hbs @@ -19,12 +19,12 @@
-
+
Access Control List {{#if isAnyAccessControlListDirty}} {{warning-info class="yellow-warning" tooltip="Need refresh queues / restart RM"}} {{/if}} - +
http://git-wip-us.apache.org/repos/asf/ambari/blob/62dc775e/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/labelCapacity.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/labelCapacity.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/labelCapacity.hbs index 873fb6f..429ef3f 100644 --- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/labelCapacity.hbs +++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/labelCapacity.hbs @@ -19,7 +19,7 @@
-
+
Label Capacity {{#if isAnyChildrenQueueLabelDirty}} {{#if warnInvalidTotalLabelCapacity}} @@ -28,7 +28,7 @@ {{warning-info class="yellow-warning" tooltip="Need refresh queues / restart RM"}} {{/if}} {{/if}} - +
http://git-wip-us.apache.org/repos/asf/ambari/blob/62dc775e/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/preemption.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/preemption.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/preemption.hbs index d594c7e..6d398f6 100644 --- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/preemption.hbs +++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/preemption.hbs @@ -19,12 +19,12 @@
-
+
Preemption {{#if isQueuePreemptionDirty}} {{warning-info class="yellow-warning" tooltip="Need refresh queues / restart RM"}} {{/if}} - +
http://git-wip-us.apache.org/repos/asf/ambari/blob/62dc775e/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/queueCapacity.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/queueCapacity.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/queueCapacity.hbs index 608758f..fdc6800 100644 --- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/queueCapacity.hbs +++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/queueCapacity.hbs @@ -19,7 +19,7 @@
-
+
Children Queue Capacites for Default Partition {{#if isAnyChildrenQueueCapacityDirty}} {{#if warnInvalidCapacity}} @@ -28,7 +28,7 @@ {{warning-info class="yellow-warning" tooltip="Need refresh queues / restart RM"}} {{/if}} {{/if}} - +
@@ -59,13 +59,23 @@
-
+
{{childrenQueuesTotalCapacity}}%
+
+ +
+
+
+
+ {{absoluteClusterCapacity}}% +
+
+
{{#if warnInvalidCapacity}}
@@ -94,6 +104,18 @@
+
+ +
+
+
+
+ {{absoluteClusterCapacity}}% +
+
+
+
+
For this queue: To edit capacity and maximum capacity at parent queue level {{#link-to 'capsched.queuesconf.editqueue' parentQueue}}Click Here{{/link-to}} @@ -111,6 +133,12 @@ {{content.maximum_capacity}}%
+
+
+ + {{absoluteClusterCapacity}}% +
+
{{/if}}
http://git-wip-us.apache.org/repos/asf/ambari/blob/62dc775e/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/queueResources.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/queueResources.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/queueResources.hbs index 809c1c0..7fc5fde 100644 --- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/queueResources.hbs +++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/queueResources.hbs @@ -19,12 +19,12 @@
-
+
Other Configs (User Limit factor, Max AM Resource etc) {{#if isAnyQueueResourcesDirty}} {{warning-info class="yellow-warning" tooltip="Need refresh queues / restart RM"}} {{/if}} - +
http://git-wip-us.apache.org/repos/asf/ambari/blob/62dc775e/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/queuesconf.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/queuesconf.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/queuesconf.hbs index 0c70ee5..3b8ceb5 100644 --- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/queuesconf.hbs +++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/queuesconf.hbs @@ -22,7 +22,7 @@
- {{queue-hierarchy depth=0 queues=queues}} + {{queue-hierarchy depth=0 queues=queues deletedQs=deletedQueues}}
{{#if isOperator}} {{#if selectedQueue}} @@ -81,15 +81,16 @@
{{#if isOperator}} -
- {{#if isQueuesNeedRefreshOrRestart}} - {{warning-info class="yellow-warning fa-2x resfresh-restart-warning" tooltip="Refresh queues / restart RM is required"}} +
+ {{#if showNeedRefreshOrRestartWarning}} + {{warning-info class="yellow-warning fa-2x resfresh-restart-warning" tooltip="Require refresh queues/restart RM" placement="top"}} {{/if}} - - + + - + +
{{/if}}
http://git-wip-us.apache.org/repos/asf/ambari/blob/62dc775e/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/scheduler.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/scheduler.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/scheduler.hbs index 66ef1ad..26150fb 100644 --- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/scheduler.hbs +++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/scheduler.hbs @@ -137,13 +137,15 @@
{{#if isOperator}}
-
+
{{#if isSchedulerPropsNeedSaveOrRestart}} - {{warning-info class="yellow-warning fa-2x resfresh-restart-warning" tooltip="Restart RM is required"}} + {{warning-info class="yellow-warning fa-2x resfresh-restart-warning" tooltip="Restart RM is required" placement="top"}} {{/if}} + +
{{/if}} http://git-wip-us.apache.org/repos/asf/ambari/blob/62dc775e/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/queueHierarchy.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/queueHierarchy.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/queueHierarchy.hbs index fb34d51..e7ff559 100644 --- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/queueHierarchy.hbs +++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/queueHierarchy.hbs @@ -15,7 +15,7 @@ * limitations under the License. }} -{{#each queue in leafQs}} +{{#each queue in cildrenQueues}} {{#link-to 'capsched.queuesconf.editqueue' queue classNameBindings=":list-group-item queue.overCapacity:list-group-item-danger queue.isNew:list-group-item-info" disabled=queue.isDeletedQueue}}
@@ -35,8 +35,12 @@ {{warn-badge}} {{/if}} + {{#if queue.isDeletedQueue}} + {{warning-info class="yellow-warning pull-right" tooltip="Queue is marked for deletion"}} + {{/if}} + {{queue-badge q=queue class="badge pull-right"}}
{{/link-to}} - {{queue-hierarchy depth=childDepth parent=queue.path queues=queues}} + {{queue-hierarchy depth=childDepth parent=queue.path queues=queues deletedQs=deletedQs}} {{/each}} http://git-wip-us.apache.org/repos/asf/ambari/blob/62dc775e/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/queueMapping.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/queueMapping.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/queueMapping.hbs index 33540e9..f143911 100644 --- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/queueMapping.hbs +++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/queueMapping.hbs @@ -17,12 +17,12 @@
-
+
Queue Mappings {{#if isQueueMappingsDirty}} {{warning-info class="yellow-warning" tooltip="Need refresh queues"}} {{/if}} - +
@@ -46,6 +46,11 @@
+ {{#if isMappingsDirty}} +
+ +
+ {{/if}}
{{#if isShowing}}
@@ -164,6 +169,11 @@ message='When checked, applications submitted with queues specified will be used other than those defined in configured queue mapping' }} + {{#if isOverrideEnableDirty}} + + + + {{/if}}
http://git-wip-us.apache.org/repos/asf/ambari/blob/62dc775e/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/queueSummary.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/queueSummary.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/queueSummary.hbs index a7ae9b0..fd46308 100644 --- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/queueSummary.hbs +++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/queueSummary.hbs @@ -51,19 +51,6 @@
- -
-
- {{effectiveCapacity}}% -
- {{#if isQueueCapacityNeedRefresh}} -
- {{warning-info class="yellow-warning" tooltip="Need refresh queues/restart RM to take effect"}} -
- {{/if}} -
-
-
http://git-wip-us.apache.org/repos/asf/ambari/blob/62dc775e/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/sunburstChart.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/sunburstChart.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/sunburstChart.hbs new file mode 100644 index 0000000..462ddf7 --- /dev/null +++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/sunburstChart.hbs @@ -0,0 +1,44 @@ +{{! +* 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. +}} + +
+
+
+ Queue Capacity Chart +
+
+
+
+
+ + {{view Ember.Select + class="form-control input-sm select-capacity-type" + content=queueCapacityTypeValues + optionLabelPath="content.name" + optionValuePath="content.value" + value=queueCapacityTypeSelected + }} +
+ +
+
+