You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by db...@apache.org on 2016/04/28 13:12:52 UTC
[1/2] ambari git commit: AMBARI-15384. CapSched View: Revamping the
old UI. (Akhil PB via dipayanb)
Repository: ambari
Updated Branches:
refs/heads/trunk ac731f7b5 -> 79489a8f3
http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/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
new file mode 100644
index 0000000..d57b2ba
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/queuesconf.hbs
@@ -0,0 +1,104 @@
+{{!
+* 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="queue-config-container">
+ <div class="panel panel-default">
+ <div class="panel-body">
+ <div class="row">
+ <div class="col-sm-7">
+ <div class="list-group queue-hierarchy">
+ {{queue-hierarchy depth=0 queues=queues}}
+ </div>
+ {{#if isOperator}}
+ {{#if selectedQueue}}
+ <div class="queue-actions-wrapper">
+ <div class="pull-left">
+ <button type="button" class="btn btn-primary btn-xs" name="addQueueBtn" {{action "addNewQueue"}}>Add Queue</button>
+ </div>
+ <div class="pull-right">
+ {{#unless isRootQSelected}}
+ <button type="button" class="btn btn-danger btn-xs" name="deleteQueueBtn">Delete</button>
+ {{/unless}}
+ {{#if isSelectedQRunning}}
+ <button type="button" class="btn btn-warning btn-xs" name="queueStateBtn">Stop Queue</button>
+ {{else}}
+ <button type="button" class="btn btn-primary btn-xs" name="queueStateBtn">Start Queue</button>
+ {{/if}}
+ </div>
+ </div>
+ {{#if showQueueNameInput}}
+ <div class="add-newqueuename-wrapper">
+ {{input type="text" name="addNewQueueName" class="form-control input-sm new-queue-name" value=newQueueName placeholder="Enter queue name..."}}
+ <div class="btn-group btn-group-sm pull-right">
+ <button type="button" class="btn btn-primary" name="createNewQueueBtn" {{action "createNewQueue"}}>Create</button>
+ <button type="button" class="btn btn-default" name="cancelNewQueueBtn" {{action "cancelCreateQueue"}}>Cancel</button>
+ </div>
+ </div>
+ {{/if}}
+ {{/if}}
+ {{/if}}
+ </div>
+ <div class="col-sm-5">
+ {{queue-summary queue=selectedQueue allQueues=queues}}
+ </div>
+ </div>
+ <hr>
+ <div class="row">
+ <div class="col-sm-12">
+ {{outlet}}
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="btn btn-group-sm col-sm-offset-3">
+ <button type="button" class="btn btn-success" name="saveQueuesconfBtn" {{action "showSaveConfigDialog" target="view"}}>Save And Refresh Queues</button>
+ <button type="button" class="btn btn-danger" name="cancelQueuesconfBtn">Cancel Changes</button>
+ </div>
+</div>
+
+{{!-- CONFIG NOTE MODAL --}}
+<div class="modal fade" id="configNoteModalDialog" tabindex="-1" role="dialog" aria-labelledby="noteConfigModalLabel" aria-hidden="true">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
+ <h4 class="modal-title" id="noteConfigModalLabel">Notes</h4>
+ </div>
+ <div class="modal-body">
+ {{textarea class="form-control" rows="3" style="max-width: 100%;" placeholder="What did you change?" value=configNote}}
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
+ <button {{action 'saveQueuesConfig'}} type="button" class="btn btn-success" data-dismiss="modal">Save Changes</button>
+ </div>
+ </div>
+ </div>
+</div>
+
+{{!-- ALERT --}}
+{{#if alertMessage}}
+ <div class="alert alert-danger">
+ <button {{action 'clearAlert'}} type="button" class="close" aria-hidden="true">×</button>
+ <strong> {{alertMessage.status}} </strong> {{alertMessage.simpleMessage}}
+ <div>
+ <small>{{alertMessage.message}}</small>
+ </div>
+ <br>
+ {{#link-to 'capsched.trace' class="alert-link"}}Trace{{/link-to}}
+ </div>
+{{/if}}
http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/queuesconf/editqueue.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/queuesconf/editqueue.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/queuesconf/editqueue.hbs
new file mode 100644
index 0000000..c5c910a
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/queuesconf/editqueue.hbs
@@ -0,0 +1,47 @@
+{{!
+* 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="edit-queue-wrapper">
+
+ <div class="row edit-queuename-wrapper">
+ <div class="col-md-8 col-sm-8">
+ <label>Queue Name</label>
+ {{input type="text" name="queueName" class="form-control input-sm input-queue-name" value=content.name readonly=isRoot}}
+ {{#if queueDirtyFields.name}}
+ <div class="btn-group btn-group-xs" >
+ <a {{action 'rollbackProp' 'name' content}} href="#" class="btn btn-default btn-warning">
+ <i class="fa fa-undo"></i>
+ </a>
+ </div>
+ {{/if}}
+ </div>
+ </div>
+
+ <div class="queue-capacity-wrapper">
+ {{partial "capsched/partials/queueCapacity"}}
+ </div>
+
+ <div class="queue-acl-wrapper">
+ {{partial "capsched/partials/accessControlList"}}
+ </div>
+
+ <div class="queue-resources-wrapper">
+ {{partial "capsched/partials/queueResources"}}
+ </div>
+
+</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/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
new file mode 100644
index 0000000..364bff2
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/scheduler.hbs
@@ -0,0 +1,135 @@
+{{!
+* 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="scheduler-panel">
+ <div class="panel panel-default">
+ <div class="panel-body">
+ <div class="row form-group">
+ <div class="col-md-4">
+ {{tooltip-label
+ label='Maximum Applications'
+ class="control-label"
+ message='For entire cluster, maximum number of applications that can be running or pending at any point of time'
+ }}
+ </div>
+ {{#if isOperator}}
+ <div class="col-sm-3">
+ {{int-input value=scheduler.maximum_applications maxlength=15 class="input-sm input-int input-control"}}
+ {{#if schedulerDirtyFilelds.maximum_applications}}
+ <div class="btn-group btn-group-xs">
+ <a {{action 'rollbackProp' 'maximum_applications' scheduler}} href="#" class="btn btn-default btn-warning"><i class="fa fa-undo"></i></a>
+ </div>
+ {{/if}}
+ </div>
+ {{else}}
+ <div class="col-sm-2">
+ <p class="form-control-static">{{scheduler.maximum_applications}}</p>
+ </div>
+ {{/if}}
+ </div>
+ <div class="row form-group">
+ <div class="col-md-4">
+ {{tooltip-label
+ label='Maximum AM Resource'
+ class="control-label"
+ message='For entire cluster, maximum percentage of total capacity that can be utilized by application masters at any point in time.'
+ }}
+ </div>
+ {{#if isOperator}}
+ <div class="col-sm-3">
+ <div class="input-group input-resource-percent">
+ {{int-input value=scheduler.maximum_am_resource_percent class="input-sm" maxVal=100}}
+ <span class="input-group-addon">%</span>
+ </div>
+ {{#if schedulerDirtyFilelds.maximum_am_resource_percent}}
+ <div class="btn-group btn-group-xs rollback-resource-percent">
+ <a {{action 'rollbackProp' 'maximum_am_resource_percent' scheduler}} href="#" class="btn btn-default btn-warning"><i class="fa fa-undo"></i></a>
+ </div>
+ {{/if}}
+ </div>
+ {{else}}
+ <div class="col-sm-2">
+ {{#if scheduler.maximum_am_resource_percent}}
+ <p class="form-control-static">{{scheduler.maximum_am_resource_percent}}%</p>
+ {{else}}
+ <p class="form-control-static">-</p>
+ {{/if}}
+ </div>
+ {{/if}}
+ </div>
+ <div class="row form-group">
+ <div class="col-md-4">
+ {{tooltip-label
+ label='Node Locality Delay'
+ class="control-label"
+ message='Number of missed scheduling cycles after which the scheduler attempts to schedule rack-local containers.'
+ }}
+ </div>
+ {{#if isOperator}}
+ <div class="col-sm-3">
+ {{int-input value=scheduler.node_locality_delay maxlength=10 class="input-sm input-int input-control"}}
+ {{#if schedulerDirtyFilelds.node_locality_delay}}
+ <div class="btn-group btn-group-xs" >
+ <a {{action 'rollbackProp' 'node_locality_delay' scheduler}} href="#" class="btn btn-default btn-warning"><i class="fa fa-undo"></i></a>
+ </div>
+ {{/if}}
+ </div>
+ {{else}}
+ <div class="col-sm-2">
+ {{#if scheduler.node_locality_delay}}
+ <p class="form-control-static">{{scheduler.node_locality_delay}}</p>
+ {{else}}
+ <p class="form-control-static">-</p>
+ {{/if}}
+ </div>
+ {{/if}}
+ </div>
+ {{#if isOperator}}
+ <div class="row form-group">
+ <div class="col-md-4">
+ {{tooltip-label
+ label='Resource Calculator'
+ class="control-label"
+ message='The method by which the scheduler calculates resource capacity across resource types. <br/> Default Resource Calculator allocates resources based on memory alone. <br/> Dominant Resource Calculator allocates resources based on memory, cpu etc.'
+ }}
+ </div>
+ <div class="col-sm-4">
+ {{view Ember.Select
+ class="form-control input-sm resource-calc-control"
+ content=resourceCalculatorValues
+ optionLabelPath="content.label"
+ optionValuePath="content.value"
+ value=scheduler.resource_calculator
+ }}
+ {{#if schedulerDirtyFilelds.resource_calculator}}
+ <div class="btn-group btn-group-xs">
+ <a {{action 'rollbackProp' 'resource_calculator' scheduler}} href="#" class="btn btn-default btn-warning"><i class="fa fa-undo"></i></a>
+ </div>
+ {{/if}}
+ </div>
+ </div>
+ {{/if}}
+ </div>
+ </div>
+</div>
+<div class="row">
+ <div class="btn btn-group-md col-md-offset-5">
+ <button type="button" {{bind-attr class=":btn :btn-default :btn-success isSchedulerDirty::disabled"}} name="saveAdvanced">Save</button>
+ <button type="button" {{bind-attr class=":btn :btn-default :btn-danger isSchedulerDirty::disabled"}} name="cancelAdvanced" {{action 'rollbackSchedulerProps'}}>Cancel</button>
+ </div>
+</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/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
new file mode 100644
index 0000000..24f6938
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/queueHierarchy.hbs
@@ -0,0 +1,41 @@
+{{!
+* 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.
+}}
+
+{{#each queue in leafQs}}
+ {{#link-to 'capsched.queuesconf.editqueue' queue class="list-group-item"}}
+ <div class="col-md-offset-{{unbound queue.depth}} col-sm-offset-{{unbound queue.depth}}">
+ {{#unless queue.queues}}
+ <span>
+ <i class="fa fa-leaf"></i>
+ </span>
+ {{else}}
+ <span>
+ <i class="fa fa-th-large"></i>
+ </span>
+ {{/unless}}
+
+ {{queue.name}}
+
+ {{#if queue.noCapacity}}
+ {{warn-badge}}
+ {{/if}}
+
+ {{queue-badge q=queue class="badge pull-right"}}
+ </div>
+ {{/link-to}}
+ {{queue-hierarchy depth=childDepth parent=queue.path queues=queues}}
+{{/each}}
http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/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
new file mode 100644
index 0000000..759c0f3
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/queueMapping.hbs
@@ -0,0 +1,154 @@
+{{!
+* 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="panel panel-default panel-queue-mapping">
+ <div class="panel-heading">
+ <div class="panel-title">
+ Queue Mappings
+ <a href="#queueMappingsCollapsiblePanel" id="collapseQueueMappingsBtn" data-toggle="collapse" {{bind-attr class=":pull-right isCollapsed:collapsed"}}><i {{bind-attr class=":fa isCollapsed:fa-plus:fa-minus"}}></i></a>
+ </div>
+ </div>
+ <div id="queueMappingsCollapsiblePanel" {{bind-attr class=":panel-collapse :collapse isCollapsed::in"}}>
+ <div class="panel-body">
+ <div class="container-fluid">
+ <div class="row">
+ <label>User to Queue Mappings (Precedence is from top to botttom)</label>
+ </div>
+ <div class="row">
+ <ul id="qMappingList" class="list-group">
+ {{#each qm in queueMappings}}
+ <li class="list-group-item">{{queueMappingParser qm}}<span class="pull-right remove-mapping-icon" {{action "removeQueueMapping" qm}}><i class="fa fa-times"></i></span></li>
+ {{else}}
+ <label>No queue mappings defined</label>
+ {{/each}}
+ </ul>
+ </div>
+
+ <div class="add-queue-mapping-container">
+ <div class="row">
+ <div class="btn-group btn-group-sm">
+ <button type="button" class="btn btn-default btn-primary" name="button" {{action "showMappingOptions"}}>Add Mapping</button>
+ </div>
+ </div>
+ {{#if isShowing}}
+ <div class="queue-mapping-options">
+ <div class="row">
+ <div class="radio">
+ <label title="Assign job to queue with same name as user">
+ {{view view.radioButton selectionBinding="selectedMapping" name="queueMappingType" value="u:%user:%user"}}
+ User %user -> queue %user
+ </label>
+ </div>
+ </div>
+ <div class="row">
+ <div class="radio">
+ <label title="Assign job to queue with same name as user's primary group">
+ {{view view.radioButton selectionBinding="selectedMapping" name="queueMappingType" value="u:%user:%primary_group"}}
+ User %user -> queue %primary_group
+ </label>
+ </div>
+ </div>
+ <div class="row">
+ <div class="radio">
+ <label>
+ {{view view.radioButton selectionBinding="selectedMapping" name="queueMappingType" value="u:%name:%qname"}}
+ Assign users to queue
+ </label>
+ </div>
+ {{#if isCustomUserMapping}}
+ <div class="row">
+ <div class="col-md-2">
+ <span>Users</span>
+ </div>
+ <div class="col-md-10">
+ <div class="form-group">
+ {{input type="text" class="form-control" value=customUserMappings size="30" placeholder="Comma-separated list of users"}}
+ </div>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-2">
+ <span>Queue</span>
+ </div>
+ <div class="col-md-5">
+ <div class="form-group">
+ {{view Ember.Select
+ class="form-control"
+ content=leafQueueNames
+ value=selectedLeafQueueNameForUsers
+ prompt="Select Queue"}}
+ </div>
+ </div>
+ </div>
+ {{/if}}
+ </div>
+ <div class="row">
+ <div class="radio">
+ <label>
+ {{view view.radioButton selectionBinding="selectedMapping" name="queueMappingType" value="g:%name:%qname"}}
+ Assign groups to queue
+ </label>
+ </div>
+ {{#if isCustomGroupMapping}}
+ <div class="row">
+ <div class="col-md-2">
+ <span>Groups</span>
+ </div>
+ <div class="col-md-10">
+ <div class="form-group">
+ {{input type="text" class="form-control" value=customGroupMappings size="30" placeholder="Comma-separated list of groups"}}
+ </div>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-2">
+ <span>Queue</span>
+ </div>
+ <div class="col-md-5">
+ <div class="form-group">
+ {{view Ember.Select
+ class="form-control"
+ content=leafQueueNames
+ value=selectedLeafQueueNameForGroups
+ prompt="Select Queue"}}
+ </div>
+ </div>
+ </div>
+ {{/if}}
+ </div>
+ <div class="row">
+ <div class="btn-group btn-group-xs pull-right">
+ <button type="button" class="btn btn-default btn-primary" name="button" {{action "addQueueMapping"}}> Add </button>
+ <button type="button" class="btn btn-default" name="button" {{action "hideMappingOptions"}}>Cancel</button>
+ </div>
+ </div>
+ </div>
+ {{/if}}
+ </div>
+
+ <div class="row">
+ <div class="checkbox">
+ <label>
+ {{input type="checkbox" name="queueMappingOverride" checked=mappingsOverrideEnable}}
+ Allow user to override queue mapping
+ </label>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/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
new file mode 100644
index 0000000..b5c3c04
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/queueSummary.hbs
@@ -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.
+}}
+
+{{#if queue}}
+ <div class="queue-summary">
+ <div class="panel panel-default">
+ <div class="panel-body">
+ <div class="row">
+ <div class="col-sm-6">
+ <label>Name</label>
+ </div>
+ <div class="col-sm-4">
+ <span>{{queue.name}}</span>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-sm-6">
+ <label>Path</label>
+ </div>
+ <div class="col-sm-4">
+ <span>{{queue.path}}</span>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-sm-6">
+ <label>Capacity</label>
+ </div>
+ <div class="col-sm-4">
+ <span>{{queue.capacity}}%</span>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-sm-6">
+ <label>Overall Cluster Capacity</label>
+ </div>
+ <div class="col-sm-4">
+ <span>{{effectiveCapacity}}%</span>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-sm-6">
+ <label>State</label>
+ </div>
+ <div class="col-sm-4">
+ <span {{bind-attr class="isRunningState:text-success:text-danger"}}>{{queueState}}</span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+{{/if}}
http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/versionsPanel.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/versionsPanel.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/versionsPanel.hbs
new file mode 100644
index 0000000..f252005
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/versionsPanel.hbs
@@ -0,0 +1,49 @@
+{{!
+* 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="panel panel-default">
+ <div class="panel-heading">
+ <div class="panel-title">
+ Versions
+ </div>
+ </div>
+ <div class="panel-body">
+ <div id="versions-table-wrap">
+ <table class="table table-condensed">
+ <tbody>
+ {{#each sortedTags}}
+ <tr>
+ <td>
+ <span class="label label-info">v{{id}}</span>
+ {{#if isCurrent}}
+ <span class="label label-success">Current</span>
+ {{/if}}
+ </td>
+ <td>{{timeAgo changed}}</td>
+ <td>
+ <div class="btn-group btn-group-xs btn-block">
+ <button type="button" class="btn btn-default btn-xs btn-block" {{action 'loadTagged' tag}}>load</button>
+ </div>
+ </td>
+ </tr>
+ {{/each}}
+ </tbody>
+ </table>
+ </div>
+ </div>
+</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/contrib/views/capacity-scheduler/src/main/resources/ui/app/views/editQueueCapacity.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/views/editQueueCapacity.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/views/editQueueCapacity.js
new file mode 100644
index 0000000..2628553
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/views/editQueueCapacity.js
@@ -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.
+ */
+
+var App = require('app');
+
+App.CapschedPartialsEditQueueCapacityView = Ember.View.extend({
+ isQueueCapacityDirty: function() {
+ return this.get('controller.content').changedAttributes().hasOwnProperty('capacity');
+ }.property('controller.content.capacity'),
+
+ isQueueMaximumCapacityDirty: function() {
+ return this.get('controller.content').changedAttributes().hasOwnProperty('maximum_capacity');
+ }.property('controller.content.maximum_capacity')
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/contrib/views/capacity-scheduler/src/main/resources/ui/app/views/editqueue.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/views/editqueue.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/views/editqueue.js
new file mode 100644
index 0000000..0dde62b
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/views/editqueue.js
@@ -0,0 +1,50 @@
+/**
+ * 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.CapschedQueuesconfEditqueueView = Ember.View.extend({
+ isAclPanelCollapsed: true,
+ isResourcesPanelCollapsed: true,
+ isCapacityPanelCollapsed: false,
+
+ doExpandCollapsePanel: function() {
+ var that = this;
+ this.$('#collapseQueueAclPanelBtn').on('click', function(e) {
+ Ember.run.next(that, function() {
+ this.toggleProperty('isAclPanelCollapsed');
+ });
+ });
+ this.$('#collapseResourcesPanelBtn').on('click', function(e) {
+ Ember.run.next(that, function() {
+ this.toggleProperty('isResourcesPanelCollapsed');
+ });
+ });
+ this.$('#collapseQueueCapacityPanelBtn').on('click', function(e) {
+ Ember.run.next(that, function() {
+ this.toggleProperty('isCapacityPanelCollapsed');
+ });
+ });
+ }.on('didInsertElement'),
+
+ destroyEventListeners: function() {
+ this.$('#collapseQueueAclPanelBtn').off('click');
+ this.$('#collapseResourcesPanelBtn').off('click');
+ this.$('#collapseQueueCapacityPanelBtn').off('click');
+ }.on('willDestroyElement')
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/contrib/views/capacity-scheduler/src/main/resources/ui/app/views/queuesconf.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/views/queuesconf.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/views/queuesconf.js
new file mode 100644
index 0000000..7cb71a7
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/views/queuesconf.js
@@ -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.
+ */
+
+var App = require('app');
+
+App.CapschedQueuesconfView = Ember.View.extend({
+ actions: {
+ showSaveConfigDialog: function() {
+ this.$('#configNoteModalDialog').modal('show');
+ }
+ }
+});
[2/2] ambari git commit: AMBARI-15384. CapSched View: Revamping the
old UI. (Akhil PB via dipayanb)
Posted by db...@apache.org.
AMBARI-15384. CapSched View: Revamping the old UI. (Akhil PB via dipayanb)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/79489a8f
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/79489a8f
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/79489a8f
Branch: refs/heads/trunk
Commit: 79489a8f35a6b808277a91251beae704aaad982f
Parents: ac731f7
Author: Dipayan Bhowmick <di...@gmail.com>
Authored: Thu Apr 28 16:42:33 2016 +0530
Committer: Dipayan Bhowmick <di...@gmail.com>
Committed: Thu Apr 28 16:42:33 2016 +0530
----------------------------------------------------------------------
.../src/main/resources/ui/app/components.js | 3 +
.../ui/app/components/queueHierarchy.js | 46 +++
.../resources/ui/app/components/queueMapping.js | 141 ++++++++
.../resources/ui/app/components/queueSummary.js | 52 +++
.../src/main/resources/ui/app/controllers.js | 5 +
.../resources/ui/app/controllers/advanced.js | 55 +++
.../resources/ui/app/controllers/capsched.js | 39 +++
.../resources/ui/app/controllers/editqueue.js | 333 +++++++++++++++++++
.../resources/ui/app/controllers/queuesconf.js | 141 ++++++++
.../resources/ui/app/controllers/scheduler.js | 83 +++++
.../src/main/resources/ui/app/helpers.js | 22 ++
.../ui/app/helpers/queueMappingParser.js | 34 ++
.../main/resources/ui/app/helpers/uppercase.js | 21 ++
.../src/main/resources/ui/app/initialize.js | 6 +-
.../src/main/resources/ui/app/router.js | 87 ++++-
.../resources/ui/app/styles/application.less | 285 ++++++++++++++++
.../src/main/resources/ui/app/templates.js | 13 +
.../resources/ui/app/templates/capsched.hbs | 44 +++
.../ui/app/templates/capsched/advanced.hbs | 32 ++
.../capsched/partials/accessControlList.hbs | 154 +++++++++
.../capsched/partials/editQueueCapacity.hbs | 51 +++
.../capsched/partials/queueCapacity.hbs | 95 ++++++
.../capsched/partials/queueResources.hbs | 216 ++++++++++++
.../ui/app/templates/capsched/queuesconf.hbs | 104 ++++++
.../templates/capsched/queuesconf/editqueue.hbs | 47 +++
.../ui/app/templates/capsched/scheduler.hbs | 135 ++++++++
.../app/templates/components/queueHierarchy.hbs | 41 +++
.../app/templates/components/queueMapping.hbs | 154 +++++++++
.../app/templates/components/queueSummary.hbs | 66 ++++
.../ui/app/templates/versionsPanel.hbs | 49 +++
.../resources/ui/app/views/editQueueCapacity.js | 29 ++
.../main/resources/ui/app/views/editqueue.js | 50 +++
.../main/resources/ui/app/views/queuesconf.js | 27 ++
33 files changed, 2657 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/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 ac679b7..7f7bc3b 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
@@ -30,3 +30,6 @@ require('components/dropdownButtons');
require('components/queueBadge');
require('components/diffTooltip');
require('components/tooltipLabel');
+require('components/queueMapping');
+require('components/queueHierarchy');
+require('components/queueSummary');
http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/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
new file mode 100644
index 0000000..64a28343
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueHierarchy.js
@@ -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.
+ */
+
+ var App = require('app');
+
+ App.QueueHierarchyComponent = Ember.Component.extend({
+ layoutName: 'components/queueHierarchy',
+ depth:0,
+ parent:'',
+
+ leafQs: function () {
+ return this.get('queues')
+ .filterBy('depth', this.get('depth'))
+ .filterBy('parentPath', this.get('parent'));
+ }.property('depth', 'parent', 'queues.length', 'queues.@each.name'),
+
+ childDepth: function () {
+ return this.get('leafQs.firstObject.depth') + 1;
+ }.property('depth'),
+
+ didInsertElement: function () {
+ Ember.run.scheduleOnce('afterRender', null, this.setFirstAndLast, this);
+ },
+
+ setFirstAndLast: function (item) {
+ var items = item.$().parents('.queue-hierarchy').find('.list-group-item');
+ items.first().addClass('first');
+ items.last().addClass('last');
+ }
+
+ });
http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/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
new file mode 100644
index 0000000..02062a6
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueMapping.js
@@ -0,0 +1,141 @@
+/**
+ * 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.QueueMappingComponent = Em.Component.extend({
+ layoutName: 'components/queueMapping',
+
+ queues: null,
+ mappings: '',
+ mappingsOverrideEnable: false,
+
+ isShowing: false,
+ queueMappings: [],
+ leafQueueNames: [],
+ selectedMapping: '',
+ customUserMappings: '',
+ customGroupMappings: '',
+ selectedLeafQueueNameForUsers: null,
+ selectedLeafQueueNameForGroups: null,
+
+ actions: {
+ showMappingOptions: function(){
+ this.resetMappingOptions();
+ this.set('isShowing', true);
+ },
+ hideMappingOptions: function(){
+ this.set('isShowing', false);
+ },
+ addQueueMapping: function(){
+ this.addQueueMapping();
+ },
+ removeQueueMapping: function(qm){
+ this.get('queueMappings').removeObject(qm);
+ }
+ },
+
+ resetMappingOptions: function(){
+ this.set('selectedMapping', '');
+ this.set('customUserMappings', '');
+ this.set('customGroupMappings', '');
+ },
+
+ parseMappings: function(){
+ var mappings = this.get('mappings') || '';
+ this.set('queueMappings', mappings.split(',').filter(function(mapping){
+ return mapping !== "";
+ }) || []);
+ }.observes('mappings').on('init'),
+
+ extractLeafQueueNames: function(){
+ var that = this;
+ var queues = this.get('queues') || [];
+ var leafQs = queues.filterBy('queues', null);
+ leafQs.forEach(function(q){
+ that.get('leafQueueNames').pushObject(q.get('name'));
+ });
+ }.observes('queues.length').on('init'),
+
+ addQueueMapping: function(){
+ var that = this;
+ if(this.get('selectedMapping') !== ''){
+ if(this.get('selectedMapping') !== 'u:%name:%qname' && this.get('selectedMapping') !== 'g:%name:%qname'){
+ this.get('queueMappings').pushObject(this.get('selectedMapping'));
+ }else{
+ if(this.get('selectedMapping') === 'u:%name:%qname' && this.get('customUserMappings').trim() !== ''
+ && this.get('selectedLeafQueueNameForUsers') !== null){
+ this.addCustomQueueMappings(this.get('customUserMappings'), this.get('selectedLeafQueueNameForUsers'));
+ }else if(this.get('selectedMapping') === 'g:%name:%qname' && this.get('customGroupMappings').trim() !== ''
+ && this.get('selectedLeafQueueNameForGroups') !== null){
+ this.addCustomQueueMappings(this.get('customGroupMappings'), this.get('selectedLeafQueueNameForGroups'));
+ }
+ }
+ this.resetMappingOptions();
+ }
+ },
+
+ queueMappingsDidChange: function(){
+ var csMappings = this.get('queueMappings').join(',') || '';
+ this.set('mappings', csMappings);
+ }.observes('queueMappings', 'queueMappings.length', 'queueMappings.@each'),
+
+ addCustomQueueMappings: function(csValues, selectedLeafQName){
+ var that = this;
+ 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));
+ });
+ },
+
+ isCustomUserMapping: function(){
+ return this.get('selectedMapping').trim() === 'u:%name:%qname';
+ }.property('selectedMapping'),
+
+ isCustomGroupMapping: function(){
+ return this.get('selectedMapping').trim() === 'g:%name:%qname';
+ }.property('selectedMapping'),
+
+ radioButton: Em.View.extend({
+ tagName: 'input',
+ type: 'radio',
+ attributeBindings: ['type', 'name', 'value', 'checked:checked:'],
+ click: function(){
+ this.set("selection", this.$().val());
+ },
+ checked: function(){
+ return this.get("value") === this.get("selection");
+ }.property('selection')
+ }),
+
+ isCollapsed: true,
+ doExpandCollapse: function(){
+ var that = this;
+ this.$('#collapseQueueMappingsBtn').on('click', function(e){
+ Ember.run.next(that, function(){
+ this.toggleProperty('isCollapsed');
+ });
+ });
+ }.on('didInsertElement'),
+
+ destroyEventListeners: function() {
+ this.$('#collapseQueueMappingsBtn').off('click');
+ }.on('willDestroyElement')
+ });
http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/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
new file mode 100644
index 0000000..3d4f7be
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueSummary.js
@@ -0,0 +1,52 @@
+/**
+ * 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');
+
+ var _runState = 'RUNNING';
+ var _stopState = 'STOPPED';
+
+ App.QueueSummaryComponent = Ember.Component.extend({
+ layoutName: 'components/queueSummary',
+ queue: null,
+ allQueues: null,
+
+ isRunningState: function() {
+ return this.get('queue.state') === _runState || this.get('queue.state') === null;
+ }.property('queue.state'),
+
+ queueState: function() {
+ if (this.get('isRunningState')) {
+ return _runState;
+ } else {
+ return _stopState;
+ }
+ }.property('queue.state'),
+
+ 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 = Math.round(effectiveCapacityRatio * 100);
+ return effectiveCapacityPercent;
+ }.property('queue.capacity', 'allQueues.@each.capacity', 'allQueues.length')
+ });
http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers.js
index 16b7d0a..5cd31ed 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers.js
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers.js
@@ -20,3 +20,8 @@ require('controllers/queue');
require('controllers/queues');
require('controllers/trace');
require('controllers/configs');
+require('controllers/capsched');
+require('controllers/advanced');
+require('controllers/scheduler');
+require('controllers/queuesconf');
+require('controllers/editqueue');
http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/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
new file mode 100644
index 0000000..7af45bb
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/advanced.js
@@ -0,0 +1,55 @@
+/**
+ * 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');
+
+var cmp = Ember.computed;
+
+App.CapschedAdvancedController = Ember.Controller.extend({
+ needs: ['capsched'],
+
+ actions: {
+ rollbackQueueMappingProps: function() {
+ var sched = this.get('scheduler'),
+ attributes = sched.changedAttributes(),
+ props = this.queueMappingProps;
+ props.forEach(function(prop) {
+ if (attributes.hasOwnProperty(prop)) {
+ sched.set(prop, attributes[prop][0]);
+ }
+ });
+ }
+ },
+
+ isOperator: cmp.alias('controllers.capsched.isOperator'),
+ scheduler: cmp.alias('controllers.capsched.content'),
+ queues: cmp.alias('controllers.capsched.queues'),
+ isQueueMappingsDirty: false,
+ queueMappingProps: ['queue_mappings', 'queue_mappings_override_enable'],
+
+ queueMappingsDidChange: function() {
+ var sched = this.get('scheduler'),
+ attributes = sched.changedAttributes(),
+ props = this.queueMappingProps;
+ var isDirty = props.any(function(prop){
+ return attributes.hasOwnProperty(prop);
+ });
+ this.set('isQueueMappingsDirty', isDirty);
+ }.observes('scheduler.queue_mappings', 'scheduler.queue_mappings_override_enable')
+
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/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
new file mode 100644
index 0000000..1ee7a6b
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/capsched.js
@@ -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.
+ */
+
+var App = require('app');
+
+var cmp = Ember.computed;
+
+App.CapschedController = Ember.Controller.extend({
+ actions: {
+
+ },
+
+ /**
+ * User admin status.
+ * @type {Boolean}
+ */
+ isOperator: false,
+
+ /**
+ * Inverted isOperator value.
+ * @type {Boolean}
+ */
+ isNotOperator: cmp.not('isOperator')
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/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
new file mode 100644
index 0000000..69be18c
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/editqueue.js
@@ -0,0 +1,333 @@
+/**
+ * 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');
+
+var _runState = 'RUNNING';
+var _stopState = 'STOPPED';
+
+App.CapschedQueuesconfEditqueueController = Ember.Controller.extend({
+ needs: ['capsched'],
+ isOperator: Ember.computed.alias('controllers.capsched.isOperator'),
+ isNotOperator: Ember.computed.not('isOperator'),
+ scheduler: Ember.computed.alias('controllers.capsched.content'),
+ allQueues: Ember.computed.alias('controllers.capsched.queues'),
+
+ isRangerEnabledForYarn: function() {
+ var isRanger = this.get('controllers.capsched.isRangerEnabledForYarn');
+ if (isRanger == null || typeof isRanger == 'undefined') {
+ return false;
+ }
+ isRanger = isRanger.toLowerCase();
+ if (isRanger == 'yes' || isRanger == 'true') {
+ return true;
+ }
+ return false;
+ }.property('controllers.capsched.isRangerEnabledForYarn'),
+
+ actions: {
+ toggleProperty: function (property, target) {
+ target = target || this;
+ target.toggleProperty(property);
+ },
+ mouseUp: function(){
+ return false;
+ }
+ },
+
+ /**
+ * Collection of modified fields in queue.
+ * @type {Object} - { [fileldName] : {Boolean} }
+ */
+ queueDirtyFields: {},
+
+ isQueueDirty: Ember.computed.bool('content.isDirty'),
+
+ /**
+ * Possible values for ordering policy
+ * @type {Array}
+ */
+ orderingPolicyValues: [
+ {label: 'FIFO', value: 'fifo'},
+ {label: 'Fair', value: 'fair'}
+ ],
+
+ /**
+ * Returns true if queue is root.
+ * @type {Boolean}
+ */
+ isRoot: Ember.computed.match('content.id', /^(root)$/),
+
+ /**
+ * Returns true if queue is default.
+ * @type {Boolean}
+ */
+ isDefaultQ: Ember.computed.match('content.id', /^(root.default)$/),
+
+ /**
+ * Represents queue run state. Returns true if state is null.
+ * @return {Boolean}
+ */
+ isRunning: function() {
+ return this.get('content.state') == _runState || this.get('content.state') == null;
+ }.property('content.state'),
+
+ /**
+ * Current ordering policy value of queue.
+ * @param {String} key
+ * @param {String} value
+ * @return {String}
+ */
+ currentOP: function (key, val) {
+ if (arguments.length > 1) {
+ if (!this.get('isFairOP')) {
+ this.send('rollbackProp', 'enable_size_based_weight', this.get('content'));
+ }
+ this.set('content.ordering_policy', val || null);
+ }
+ return this.get('content.ordering_policy') || 'fifo';
+ }.property('content.ordering_policy'),
+
+ /**
+ * Does ordering policy is equal to 'fair'
+ * @type {Boolean}
+ */
+ isFairOP: Ember.computed.equal('content.ordering_policy', 'fair'),
+
+ /**
+ * Returns maximum applications for a queue if defined,
+ * else the inherited value (for all queues)
+ */
+ maximumApplications: function(key, val) {
+ if (arguments.length > 1) {
+ if (val !== this.get('scheduler.maximum_applications')) {
+ this.set('content.maximum_applications', val);
+ } else {
+ this.set('content.maximum_applications', null);
+ }
+ }
+ return this.get('content.maximum_applications') || this.get('scheduler.maximum_applications');
+ }.property('content.maximum_applications', 'scheduler.maximum_applications'),
+
+ /**
+ * Returns maximum AM resource percent for a queue if defined,
+ * else the inherited value (for all queues)
+ */
+ maximumAMResourcePercent: function(key, val) {
+ if (arguments.length > 1) {
+ if (val !== this.get('scheduler.maximum_am_resource_percent')) {
+ this.set('content.maximum_am_resource_percent', val);
+ } else {
+ this.set('content.maximum_am_resource_percent', null);
+ }
+ }
+ return this.get('content.maximum_am_resource_percent') || this.get('scheduler.maximum_am_resource_percent');
+ }.property('content.maximum_am_resource_percent', 'scheduler.maximum_am_resource_percent'),
+
+ /**
+ * Sets ACL value to '*' or ' ' and returns '*' and 'custom' respectively.
+ * @param {String} key - ACL attribute
+ * @param {String} value - ACL value
+ * @return {String}
+ */
+ handleAcl: function (key, value) {
+ if (value) {
+ this.set(key, (value === '*')? '*' : ' ');
+ }
+ return (this.get(key) === '*' || this.get(key) == null) ? '*' : 'custom';
+ },
+
+ /**
+ * Queue's acl_administer_queue property can be set to '*' (everyone) or ' ' (nobody) thru this property.
+ *
+ * @param {String} key
+ * @param {String} value
+ * @return {String} - '*' if equal to '*' or 'custom' in other case.
+ */
+ acl_administer_queue: function (key, value) {
+ return this.handleAcl('content.acl_administer_queue', value);
+ }.property('content.acl_administer_queue'),
+
+ /**
+ * Returns true if acl_administer_queue is set to '*'
+ * @type {Boolean}
+ */
+ aaq_anyone: Ember.computed.equal('acl_administer_queue', '*'),
+
+ /**
+ * Returns effective permission of the current queue to perform administrative functions on this queue.
+ */
+ aaq_effective_permission: function(key, value){
+ return this.getEffectivePermission('acl_administer_queue');
+ }.property('content.acl_administer_queue'),
+
+ /**
+ * Queue's acl_submit_applications property can be set to '*' (everyone) or ' ' (nobody) thru this property.
+ *
+ * @param {String} key
+ * @param {String} value
+ * @return {String} - '*' if equal to '*' or 'custom' in other case.
+ */
+ acl_submit_applications: function (key, value) {
+ return this.handleAcl('content.acl_submit_applications', value);
+ }.property('content.acl_submit_applications'),
+
+ /**
+ * Returns true if acl_submit_applications is set to '*'
+ * @type {Boolean}
+ */
+ asa_anyone:Ember.computed.equal('acl_submit_applications', '*'),
+
+ /**
+ * Returns effective permission of the current queue to submit application.
+ */
+ asa_effective_permission: function(key, value){
+ return this.getEffectivePermission('acl_submit_applications');
+ }.property('content.acl_submit_applications'),
+
+ /**
+ * Returns effective permission of the current queue.
+ */
+ getEffectivePermission: function(permissionType){
+ var effectivePermission,
+ users = [],
+ groups = [],
+ currentPermissions = this.getPermissions(permissionType);
+ for(var i = 0; i < currentPermissions.length; i++){
+ var permission = currentPermissions[i];
+ if (permission === '*') {
+ return '*';
+ } else if (permission.trim() === '') {
+ effectivePermission = '';
+ } else {
+ var usersAndGroups = permission.split(' ');
+ this.fillUsersAndGroups(users, usersAndGroups[0]);
+ if (usersAndGroups.length === 2) {
+ this.fillUsersAndGroups(groups, usersAndGroups[1]);
+ }
+ }
+ }
+ if(users.length > 0 || groups.length > 0){
+ effectivePermission = users.join(',') + ' ' + groups.join(',');
+ }
+ return effectivePermission;
+ },
+
+ /**
+ * Removes duplicate users or groups.
+ */
+ fillUsersAndGroups: function(usersOrGroups, list){
+ var splitted = list.split(',');
+ splitted.forEach(function(item){
+ if(usersOrGroups.indexOf(item) === -1){
+ usersOrGroups.push(item);
+ }
+ });
+ },
+
+ /**
+ * Returns array of permissions from root to leaf.
+ */
+ getPermissions: function(permissionType){
+ var currentQ = this.get('content'),
+ permissions = [];
+ while (currentQ !== null) {
+ if (currentQ.get(permissionType) !== null) {
+ permissions.push(currentQ.get(permissionType));
+ } else {
+ permissions.push('*');
+ }
+ currentQ = this.store.getById('queue', currentQ.get('parentPath').toLowerCase());
+ }
+ permissions.reverse();//root permission at the 0th position.
+ return permissions;
+ },
+
+ /**
+ * Array of leaf queues.
+ * @return {Array}
+ */
+ childrenQueues: function () {
+ return this.get('allQueues')
+ .filterBy('depth', this.get('content.depth') + 1)
+ .filterBy('parentPath', this.get('content.path'));
+ }.property('allQueues.length', 'content.path', 'content.parentPath'),
+
+ /**
+ * Parent of current queue.
+ * @return {App.Queue}
+ */
+ parentQueue: function () {
+ return this.store.getById('queue', this.get('content.parentPath').toLowerCase());
+ }.property('content.parentPath'),
+
+ /*
+ * Returns true if the current queue is a leaf queue
+ */
+ isLeafQ: function() {
+ return this.get('content.queues') == null;
+ }.property('allQueues.length', 'content.queues'),
+
+ childrenQueuesTotalCapacity: function() {
+ var childrenQs = this.get('childrenQueues'),
+ totalCapacity = 0;
+ childrenQs.forEach(function(currentQ){
+ totalCapacity += currentQ.get('capacity');
+ });
+ return totalCapacity;
+ }.property('childrenQueues.length', 'childrenQueues.@each.capacity'),
+
+ pattern: 'width: %@%',
+
+ warnInvalidCapacity: function() {
+ var totalCap = this.get('childrenQueuesTotalCapacity');
+ if (totalCap > 100 || totalCap < 100) {
+ return true;
+ }
+ return false;
+ }.property('childrenQueuesTotalCapacity'),
+
+ totalCapacityBarWidth: function() {
+ var totalCap = this.get('childrenQueuesTotalCapacity');
+ if (totalCap > 100) {
+ totalCap = 100;
+ }
+ return this.get('pattern').fmt(totalCap);
+ }.property('childrenQueuesTotalCapacity'),
+
+ /**
+ * Adds observers for each queue attribute.
+ * @method dirtyObserver
+ */
+ dirtyObserver: function () {
+ this.get('content.constructor.transformedAttributes.keys.list').forEach(function(item) {
+ this.addObserver('content.' + item, this, 'propertyBecomeDirty');
+ }.bind(this));
+ }.observes('content'),
+
+ /**
+ * Adds modified queue fileds to q queueDirtyFields collection.
+ * @param {String} controller
+ * @param {String} property
+ * @method propertyBecomeDirty
+ */
+ propertyBecomeDirty: function (controller, property) {
+ var queueProp = property.split('.').objectAt(1);
+ this.set('queueDirtyFields.' + queueProp, this.get('content').changedAttributes().hasOwnProperty(queueProp));
+ }
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/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
new file mode 100644
index 0000000..0f4d038
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/queuesconf.js
@@ -0,0 +1,141 @@
+/**
+ * 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');
+var _runState = 'RUNNING';
+var _stopState = 'STOPPED';
+
+App.CapschedQueuesconfController = Ember.Controller.extend({
+ needs: ['capsched', 'loading'],
+ queues: Ember.computed.alias('controllers.capsched.queues'),
+ isOperator: Ember.computed.alias('controllers.capsched.isOperator'),
+
+ actions: {
+ addNewQueue: function() {
+ this.set('newQueueName', '');
+ this.set('showQueueNameInput', true);
+ },
+ createNewQueue: function() {
+ var store = this.get('store'),
+ queueName = this.get('newQueueName'),
+ parentPath = this.get('selectedQueue.path'),
+ queuePath = parentPath + "." + queueName,
+ depth = parentPath.split('.').length,
+ leafQueueNames = store.getById('queue', parentPath.toLowerCase()).get('queuesArray'),
+ newInLeaf = Em.isEmpty(leafQueueNames),
+ existed = store.get('deletedQueues').findBy('path', [parentPath, queueName].join('.')),
+ totalLeafCapacity,
+ freeLeafCapacity,
+ newQueue;
+
+ this.send('cancelCreateQueue');
+
+ if (existed) {
+ newQueue = store.createFromDeleted(existed);
+ } else {
+ if (!newInLeaf) {
+ totalLeafCapacity = leafQueueNames.reduce(function (capacity, qName) {
+ return store.getById('queue', [parentPath, qName].join('.').toLowerCase()).get('capacity') + capacity;
+ }, 0);
+
+ freeLeafCapacity = (totalLeafCapacity < 100) ? 100 - totalLeafCapacity : 0;
+ }
+ var qCapacity = (newInLeaf) ? 100 : freeLeafCapacity;
+
+ newQueue = store.createRecord('queue', {
+ id: queuePath,
+ name: queueName,
+ path: queuePath,
+ parentPath: parentPath,
+ depth: depth,
+ isNewQueue: true,
+ capacity: qCapacity,
+ maximum_capacity: qCapacity
+ });
+
+ this.set('newQueue', newQueue);
+ }
+
+ store.saveAndUpdateQueue(newQueue).then(function() {
+ Em.run.bind(this, 'set', 'newQueue', null);
+ }).catch(Em.run.bind(this, 'saveQueuesConfigError', 'createQueue'));
+ },
+ saveQueuesConfig: function() {
+ var store = this.get('store'),
+ opt = 'saveAndRefresh',
+ saveQs = this.get('queues').save();
+
+ Ember.RSVP.Promise.all([saveQs]).then(
+ Em.run.bind(this, 'saveQueuesConfigSuccess'),
+ Em.run.bind(this, 'saveQueuesConfigError', opt)
+ ).then(function() {
+ return store.relaunchCapSched(opt);
+ }).catch(Em.run.bind(this, 'saveQueuesConfigError', opt));
+
+ },
+ cancelCreateQueue: function() {
+ this.set('newQueueName', '');
+ this.set('showQueueNameInput', false);
+ },
+ clearAlert:function () {
+ this.set('alertMessage', null);
+ }
+ },
+
+ selectedQueue: null,
+ newQueue: null,
+ newQueueName: '',
+ showQueueNameInput: false,
+
+ /**
+ * True if newQueue is not empty.
+ * @type {Boolean}
+ */
+ hasNewQueue: Ember.computed.bool('newQueue'),
+
+ /**
+ * Represents queue run state. Returns true if state is null.
+ * @return {Boolean}
+ */
+ isSelectedQRunning: function() {
+ return this.get('selectedQueue.state') == _runState || this.get('selectedQueue.state') == null;
+ }.property('selectedQueue.state'),
+
+ /**
+ * Returns true if queue is root.
+ * @type {Boolean}
+ */
+ isRootQSelected: Ember.computed.match('selectedQueue.id', /^(root)$/),
+
+ /**
+ * Property for error message which may appear when saving queue.
+ * @type {Object}
+ */
+ alertMessage: null,
+
+ configNote: Ember.computed.alias('store.configNote'),
+
+ saveQueuesConfigSuccess: function() {
+ this.set('store.deletedQueues', []);
+ },
+ saveQueuesConfigError: function(operation, error) {
+ var response = (error && error.responseJSON)? error.responseJSON : {};
+ response.simpleMessage = operation.capitalize() + ' failed!';
+ this.set('alertMessage', response);
+ }
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/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
new file mode 100644
index 0000000..c0c56b6
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/scheduler.js
@@ -0,0 +1,83 @@
+/**
+ * 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');
+
+var cmp = Ember.computed;
+
+App.CapschedSchedulerController = Ember.Controller.extend({
+ needs: ['capsched'],
+ schedulerProps: ['maximum_am_resource_percent', 'maximum_applications', 'node_locality_delay', 'resource_calculator'],
+
+ actions: {
+ rollbackSchedulerProps: function() {
+ var sched = this.get('scheduler'),
+ attributes = sched.changedAttributes(),
+ props = this.schedulerProps;
+ props.forEach(function(prop) {
+ if (attributes.hasOwnProperty(prop)) {
+ sched.set(prop, attributes[prop][0]);
+ }
+ });
+ }
+ },
+
+ isOperator: cmp.alias('controllers.capsched.isOperator'),
+
+ /**
+ * Scheduler record
+ * @type {App.Scheduler}
+ */
+ scheduler: cmp.alias('controllers.capsched.content'),
+ isSchedulerDirty: false,
+
+ schedulerBecomeDirty: function() {
+ var sched = this.get('scheduler'),
+ attributes = sched.changedAttributes(),
+ props = this.schedulerProps;
+ var isDirty = props.any(function(prop){
+ return attributes.hasOwnProperty(prop);
+ });
+ this.set('isSchedulerDirty', isDirty);
+ }.observes('scheduler.maximum_am_resource_percent', 'scheduler.maximum_applications', 'scheduler.node_locality_delay', 'scheduler.resource_calculator'),
+
+ /**
+ * Collection of modified fields in Scheduler.
+ * @type {Object} - { [fileldName] : {Boolean} }
+ */
+ schedulerDirtyFilelds: {},
+
+ dirtyObserver:function () {
+ this.get('scheduler.constructor.transformedAttributes.keys.list').forEach(function(item) {
+ this.addObserver('scheduler.' + item, this, 'propertyBecomeDirty');
+ }.bind(this));
+ }.observes('scheduler').on('init'),
+
+ propertyBecomeDirty:function (controller, property) {
+ var schedProp = property.split('.').objectAt(1);
+ this.set('schedulerDirtyFilelds.' + schedProp, this.get('scheduler').changedAttributes().hasOwnProperty(schedProp));
+ },
+
+ resourceCalculatorValues: [{
+ label: 'Default Resource Calculator',
+ value: 'org.apache.hadoop.yarn.util.resource.DefaultResourceCalculator'
+ }, {
+ label: 'Dominant Resource Calculator',
+ value: 'org.apache.hadoop.yarn.util.resource.DominantResourceCalculator'
+ }]
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/contrib/views/capacity-scheduler/src/main/resources/ui/app/helpers.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/helpers.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/helpers.js
new file mode 100644
index 0000000..95f301d
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/helpers.js
@@ -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.
+ */
+
+require('helpers/timeAgo');
+require('helpers/escapeAcl');
+require('helpers/queueMappingParser');
+require('helpers/uppercase');
http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/contrib/views/capacity-scheduler/src/main/resources/ui/app/helpers/queueMappingParser.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/helpers/queueMappingParser.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/helpers/queueMappingParser.js
new file mode 100644
index 0000000..319b3bc
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/helpers/queueMappingParser.js
@@ -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.
+ */
+
+ Ember.Handlebars.helper('queueMappingParser', function(mapping){
+ var output = '';
+ var parts = mapping.split(':');
+ if(parts[0] === 'u'){
+ if(parts[1] === '%user' && parts[2] === '%user'){
+ output = 'User %user -> queue %user';
+ }else if(parts[1] === '%user' && parts[2] === '%primary_group'){
+ output = 'User %user -> queue %primary_group';
+ }else{
+ output = 'User ' + parts[1] + ' -> queue ' + parts[2];
+ }
+ }else if(parts[0] === 'g'){
+ output = 'Group ' + parts[1] + ' -> queue ' + parts[2];
+ }
+ return output;
+ });
http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/contrib/views/capacity-scheduler/src/main/resources/ui/app/helpers/uppercase.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/helpers/uppercase.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/helpers/uppercase.js
new file mode 100644
index 0000000..222af54
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/helpers/uppercase.js
@@ -0,0 +1,21 @@
+/**
+ * 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.
+ */
+
+ Ember.Handlebars.helper('uppercase', function(value) {
+ return value.toUpperCase();
+ });
http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/contrib/views/capacity-scheduler/src/main/resources/ui/app/initialize.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/initialize.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/initialize.js
index 05bb64c..3dfe363 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/initialize.js
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/initialize.js
@@ -31,8 +31,7 @@ require('serializers');
require('store');
//helpers
-require('helpers/timeAgo');
-require('helpers/escapeAcl');
+require('helpers');
//components
require('components');
@@ -48,6 +47,9 @@ require('models');
//views
require('views/queues');
+require('views/editqueue');
+require('views/editQueueCapacity');
+require('views/queuesconf');
// routes
require('router');
http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/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 a2d50b9..a32e02c 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
@@ -23,6 +23,14 @@ App.Router.map(function() {
this.resource('queue', { path: '/:queue_id' });
this.resource('trace', { path: '/log' });
});
+ this.resource('capsched', {path: '/capacity-scheduler'}, function() {
+ this.route('scheduler', {path: '/scheduler'});
+ this.route('advanced', {path: '/advanced'});
+ this.route('trace', {path: '/log'});
+ this.route('queuesconf', {path: '/queues'}, function() {
+ this.route('editqueue', {path: '/:queue_id'});
+ });
+ });
this.route('refuse');
});
@@ -63,7 +71,6 @@ App.QueuesRoute = Ember.Route.extend({
return store.findQuery( 'config', {siteName : RANGER_SITE, configName : RANGER_YARN_ENABLED}).then(function(){
return store.find( 'config', "siteName_" + RANGER_SITE + "_configName_" + RANGER_YARN_ENABLED)
.then(function(data){
- console.log("router.queuesRoute : data.configValue isRangerEnabled : " + data.get('configValue'));
_this.controllerFor('configs').set('isRangerEnabledForYarn', data.get('configValue'));
});
})
@@ -189,3 +196,81 @@ 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]);
+ }
+ }
+ },
+ beforeModel: function(transition) {
+ var controller = this.container.lookup('controller:loading') || this.generateController('loading');
+ controller.set('model', {
+ message: 'cluster check'
+ });
+ return this.get('store').checkCluster().catch(Em.run.bind(this, 'loadingError', transition));
+ },
+ model: function() {
+ var store = this.get('store'),
+ _this = this,
+ controller = this.controllerFor("capsched"),
+ loadingController = this.container.lookup('controller:loading');
+
+ return new Ember.RSVP.Promise(function(resolve, reject) {
+ loadingController.set('model', {
+ message: 'access check'
+ });
+ store.checkOperator().then(function(isOperator) {
+ controller.set('isOperator', isOperator);
+ loadingController.set('model', {
+ message: 'loading node labels'
+ });
+ return store.get('nodeLabels');
+ }).then(function() {
+ return store.findQuery('config', {
+ siteName: RANGER_SITE,
+ configName: RANGER_YARN_ENABLED
+ }).then(function() {
+ return store.find('config', "siteName_" + RANGER_SITE + "_configName_" + RANGER_YARN_ENABLED)
+ .then(function(data) {
+ controller.set('isRangerEnabledForYarn', data.get('configValue'));
+ });
+ });
+ }).then(function() {
+ loadingController.set('model', {
+ message: 'loading queues'
+ });
+ return store.find('queue');
+ }).then(function(queues) {
+ controller.set('queues', queues);
+ return store.find('scheduler', 'scheduler');
+ }).then(function(scheduler){
+ resolve(scheduler);
+ }).catch(function(e) {
+ reject(e);
+ });
+ }, 'App: CapschedRoute#model');
+ }
+});
+
+App.CapschedIndexRoute = Ember.Route.extend({
+ redirect: function() {
+ this.transitionTo('capsched.scheduler');
+ }
+});
+
+App.CapschedQueuesconfIndexRoute = Ember.Route.extend({
+ beforeModel: function(transition) {
+ var rootQ = this.store.getById('queue', 'root');
+ this.transitionTo('capsched.queuesconf.editqueue', rootQ);
+ }
+});
+
+App.CapschedQueuesconfEditqueueRoute = Ember.Route.extend({
+ setupController: function(controller, model) {
+ controller.set('model', model);
+ this.controllerFor('capsched.queuesconf').set('selectedQueue', model);
+ }
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/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 be79229..a60d39d 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
@@ -880,3 +880,288 @@
.tooltip-label span:first-child {
cursor: help;
}
+
+.panel-queue-mapping {
+ .queue-mapping-options {
+ padding: 10px;
+ border: 1px solid #ddd;
+ border-radius: 4px;
+ margin-left: -15px;
+ margin-right: -15px;
+ .row {
+ margin: 0px;
+ }
+ }
+ .list-group {
+ .list-group-item {
+ margin-bottom: 3px;
+ background-color: #f5f5f5;
+ border-radius: 4px;
+ padding: 5px 15px;
+ }
+ }
+ .remove-mapping-icon {
+ cursor: pointer;
+ &:hover {
+ color: #d9534f;
+ }
+ }
+}
+
+.scheduler-panel {
+ .input-control {
+ width: 75%;
+ display: inline-block;
+ }
+ .input-resource-percent {
+ width: 75%;
+ float: left;
+ }
+ .rollback-resource-percent {
+ margin: 4px;
+ }
+ .resource-calc-control {
+ width: 88%;
+ display: inline-block;
+ }
+}
+
+.queue-config-container {
+ .queue-actions-wrapper {
+ .btn {
+ padding: 1px 5px;
+ }
+ }
+ .add-newqueuename-wrapper {
+ padding-top: 30px;
+ .new-queue-name {
+ width: 100%;
+ display: inline-block;
+ }
+ }
+ hr {
+ margin-top: 5px;
+ margin-bottom: 10px;
+ }
+ .queue-hierarchy.list-group {
+ margin-bottom: 5px;
+ .list-group-item {
+ border: 1px solid #efefef;
+ padding: 5px 10px;
+ &.first {
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+ }
+ &.last {
+ border-bottom-left-radius: 4px;
+ border-bottom-right-radius: 4px;
+ }
+ .badge {
+ background-color: #fff;
+ padding: 2px 3px;
+ }
+ }
+ }
+}
+
+.queue-resources-container {
+ .input-width-control {
+ width: 75%;
+ display: inline-block;
+ }
+ .input-percent-wrap {
+ .input-percent {
+ width: 75%;
+ float: left;
+ }
+ .btn-group.btn-group-xs {
+ margin: 4px;
+ }
+ }
+ .input-toggle-wrap {
+ .btn-group.btn-group-sm {
+ width: 20px;
+ .btn.btn-default {
+ width: 20px;
+ padding: 0;
+ border: none;
+ margin: 0;
+ &:hover, &:active, &:focus {
+ background-color: #fff;
+ }
+ .fa {
+ font-size: 18px
+ }
+ .fa-square-o {
+ margin-left: -6px;
+ }
+ .fa-check-square-o {
+ margin-left: -4px;
+ }
+ }
+ }
+ }
+ .inherited-value {
+ margin: 4px 0px 4px -40px;
+ }
+}
+
+.queue-acl-container {
+ .user-group-input {
+ .col-sm-4 {
+ padding: 15px;
+ }
+ .col-sm-8 {
+ width: 35%;
+ padding: 10px;
+ }
+ .fa-user,.fa-users {
+ top: 8px;
+ right: 7px;
+ opacity: 0.4;
+ }
+ .help-block {
+ float: left !important;
+ }
+ }
+}
+
+.capsched-container {
+ .nav-tabs {
+ border-bottom: none;
+ }
+ .panel-heading {
+ padding: 4px 14px;
+ .panel-title {
+ font-size: 14px;
+ }
+ }
+ .input-group-addon {
+ padding: 7px 6px;
+ width: 26px;
+ }
+}
+
+.queue-summary {
+ .panel-default {
+ border-color: #f5f5f5;
+ }
+}
+
+.queue-capacity-container {
+ .form-inline {
+ margin-bottom: 20px;
+ .queue-name {
+ margin-top: 5px;
+ }
+ .capacity-input-percent {
+ width: 30%;
+ float: left;
+ display: inline-block;
+ input {
+ width: 60%;
+ }
+ }
+ .capacity-input-slider {
+ width: 60%;
+ display: inline-block;
+ }
+ }
+ .progress {
+ display: inline-block;
+ vertical-align: middle;
+ margin-bottom: 0;
+ .progress-bar {
+ color: #000;
+ }
+ }
+ .total-capacity-progress {
+ width: 100%;
+ }
+ input[type=range] {
+ -webkit-appearance: none;
+ width: 100%;
+ background-color: #fefefe;
+ &:focus {
+ outline: none;
+ }
+ &::-webkit-slider-runnable-track {
+ width: 100%;
+ height: 2px;
+ cursor: pointer;
+ background: #555;
+ border-radius: 1.3px;
+ border: 0.2px solid #010101;
+ &:focus {
+ background: #555;
+ }
+ }
+ &::-webkit-slider-thumb {
+ border: 1.8px solid #00001e;
+ height: 15px;
+ width: 20px;
+ border-radius: 15px;
+ background: #ffffff;
+ cursor: pointer;
+ -webkit-appearance: none;
+ margin-top: -7px;
+ }
+ &::-moz-range-track {
+ width: 100%;
+ height: 2px;
+ cursor: pointer;
+ background: #555;
+ border-radius: 1.3px;
+ border: 0.2px solid #010101;
+ }
+ &::-moz-range-thumb {
+ border: 1.8px solid #00001e;
+ height: 15px;
+ width: 20px;
+ border-radius: 15px;
+ background: #ffffff;
+ cursor: pointer;
+ }
+ &::-ms-track {
+ width: 100%;
+ height: 2px;
+ cursor: pointer;
+ background: transparent;
+ border-color: transparent;
+ color: transparent;
+ }
+ &::-ms-thumb {
+ border: 1.8px solid #00001e;
+ width: 20px;
+ border-radius: 15px;
+ background: #ffffff;
+ cursor: pointer;
+ height: 11.4px;
+ }
+ &::-ms-fill-lower {
+ background: rgba(42, 100, 149, 0.78);
+ border: 0.2px solid #010101;
+ border-radius: 2.6px;
+ &:focus {
+ background: #555;
+ }
+ }
+ &::-ms-fill-upper {
+ background: #555;
+ border: 0.2px solid #010101;
+ border-radius: 2.6px;
+ &:focus {
+ background: #555;
+ }
+ }
+ }
+}
+
+.edit-queuename-wrapper {
+ margin-top: 10px;
+ margin-bottom: 20px;
+ .input-queue-name {
+ width: 69%;
+ display: inline-block;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/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 25e2aa9..17b279a 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
@@ -39,3 +39,16 @@ require('templates/components/queueContainer');
require('templates/components/dropdownConfirmation');
require('templates/components/dropdownDownload');
require('templates/components/queueBadge');
+require('templates/components/queueMapping');
+require('templates/capsched');
+require('templates/capsched/scheduler');
+require('templates/capsched/advanced');
+require('templates/capsched/queuesconf');
+require('templates/versionsPanel');
+require('templates/components/queueHierarchy');
+require('templates/capsched/queuesconf/editqueue');
+require('templates/components/queueSummary');
+require('templates/capsched/partials/queueResources');
+require('templates/capsched/partials/accessControlList');
+require('templates/capsched/partials/queueCapacity');
+require('templates/capsched/partials/editQueueCapacity');
http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/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
new file mode 100644
index 0000000..1eead4b
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched.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.
+}}
+
+<nav class="navbar navbar-default navbar-static-top">
+ <div class="navbar-header">
+ <span class="navbar-brand">Capacity Scheduler</span>
+ </div>
+</nav>
+<div class="col-lg-12 capsched-container">
+ <div class="col-lg-8">
+ <ul class="nav nav-tabs">
+ {{#link-to "capsched.scheduler" tagName="li"}}
+ <a href="#">Scheduler</a>
+ {{/link-to}}
+ {{#link-to "capsched.queuesconf" tagName="li"}}
+ <a href="#">Queues</a>
+ {{/link-to}}
+ {{#link-to "capsched.advanced" tagName="li"}}
+ <a href="#">Advanced</a>
+ {{/link-to}}
+ </ul>
+ <div class="tab-content">
+ {{outlet}}
+ </div>
+ </div>
+ <div class="col-lg-4">
+ {{partial "versionsPanel"}}
+ </div>
+</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/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
new file mode 100644
index 0000000..e54e14b
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/advanced.hbs
@@ -0,0 +1,32 @@
+{{!
+* 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="capshed-advanced-container">
+ {{!-- QUEUE MAPPING --}}
+ {{#if isOperator}}
+ <div class="hidden-sm hidden-xs">
+ {{queue-mapping mappings=scheduler.queue_mappings mappingsOverrideEnable=scheduler.queue_mappings_override_enable queues=queues}}
+ </div>
+ {{/if}}
+</div>
+<div class="row">
+ <div class="btn btn-group-md col-md-offset-5">
+ <button type="button" {{bind-attr class=":btn :btn-default :btn-success isQueueMappingsDirty::disabled"}} name="saveAdvanced">Save</button>
+ <button type="button" {{bind-attr class=":btn :btn-default :btn-danger isQueueMappingsDirty::disabled"}} name="cancelAdvanced" {{action "rollbackQueueMappingProps"}}>Cancel</button>
+ </div>
+</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/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
new file mode 100644
index 0000000..1f6fbda
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/accessControlList.hbs
@@ -0,0 +1,154 @@
+{{!
+* 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="queue-acl-container">
+ <div class="panel panel-default">
+ <div class="panel-heading">
+ <div class="panel-title">
+ Access Control List <a id="collapseQueueAclPanelBtn" href="#collapsibleQueueAclPanel" data-toggle="collapse" {{bind-attr class=":pull-right view.isAclPanelCollapsed:collapsed"}}><i {{bind-attr class=":fa view.isAclPanelCollapsed:fa-plus:fa-minus"}}></i></a>
+ </div>
+ </div>
+ <div id="collapsibleQueueAclPanel" {{bind-attr class=":panel-collapse :collapse view.isAclPanelCollapsed::in"}}>
+ <div class="panel-body">
+ {{#unless isRangerEnabledForYarn}}
+ {{#if isOperator}}
+ <div class="row form-group">
+ {{tooltip-label
+ class="col-sm-4 col-md-4 control-label"
+ label='Administer Queue'
+ message='The access control list of users and groups that have authorization to perform administrative functions on this queue.'
+ }}
+ <div class="col-md-6 col-sm-6 control-value">
+ <div class="btn-group btn-group-xs" data-toggle="buttons">
+ {{radio-button label="Anyone" selectionBinding="acl_administer_queue" value="*"}}
+ {{radio-button label="Custom" selectionBinding="acl_administer_queue" value="custom"}}
+ </div>
+ {{#if queueDirtyFields.acl_administer_queue}}
+ <div class="btn-group btn-group-xs">
+ <a {{action 'rollbackProp' 'acl_administer_queue' content}} href="#" class="btn btn-default btn-warning"><i class="fa fa-undo"></i></a>
+ </div>
+ {{/if}}
+ </div>
+ </div>
+ {{#unless aaq_anyone}}
+ {{user-group-input ug=content.acl_administer_queue disabled=aaq_anyone}}
+ {{/unless}}
+ <div class="form-group row">
+ {{tooltip-label
+ tagName='small'
+ class="col-sm-4 col-md-4 control-label"
+ label='Effective Administraters'
+ message='The effective permissions to perform administrative functions on this queue.'
+ }}
+ <div class="col-md-6 col-sm-6 control-value">
+ <label>{{escapeACL aaq_effective_permission}}</label>
+ </div>
+ </div>
+ <hr/>
+ <div class="row form-group">
+ {{tooltip-label
+ class="col-sm-4 col-md-4 control-label"
+ label='Submit Applications'
+ message='The access control list of users and groups that have authorization to submit applications to this queue.'
+ }}
+ <div class="col-sm-6 col-md-6 control-value">
+ <div class="btn-group btn-group-xs" data-toggle="buttons">
+ {{radio-button label="Anyone" selectionBinding="acl_submit_applications" value="*"}}
+ {{radio-button label="Custom" selectionBinding="acl_submit_applications" value="custom"}}
+ </div>
+ {{#if queueDirtyFields.acl_submit_applications}}
+ <div class="btn-group btn-group-xs" >
+ <a {{action 'rollbackProp' 'acl_submit_applications' content}} href="#" class="btn btn-default btn-warning"><i class="fa fa-undo"></i></a>
+ </div>
+ {{/if}}
+ </div>
+ </div>
+ {{#unless asa_anyone}}
+ {{user-group-input ug=content.acl_submit_applications disabled=asa_anyone}}
+ {{/unless}}
+ <div class="form-group row">
+ {{tooltip-label
+ tagName='small'
+ class="col-md-4 col-sm-4 control-label"
+ label='Effective Users'
+ message='The effective permissions to submit applications to this queue.'
+ }}
+ <div class="col-sm-6 col-md-6 control-value">
+ <label>{{escapeACL asa_effective_permission}}</label>
+ </div>
+ </div>
+ {{else}}
+ <div class="form-group row">
+ {{tooltip-label
+ class="col-sm-4 col-md-4 control-label"
+ label='Administer Queue'
+ message='The access control list of users and groups that have authorization to perform administrative functions on this queue.'
+ }}
+ <div class="col-sm-6 col-md-6 control-value">
+ <p class="form-control-static">
+ {{escapeACL content.acl_administer_queue}}
+ </p>
+ </div>
+ </div>
+ <div class="form-group row">
+ {{tooltip-label
+ tagName='small'
+ class="col-sm-4 col-md-4 control-label"
+ label='Effective Administraters'
+ message='The effective permissions to perform administrative functions on this queue.'
+ }}
+ <div class="col-sm-6 col-md-6 control-value">
+ <p class="form-control-static">
+ {{escapeACL aaq_effective_permission}}
+ </p>
+ </div>
+ </div>
+ <hr/>
+ <div class="form-group row">
+ {{tooltip-label
+ class="col-sm-4 col-md-4 control-label"
+ label='Submit Applications'
+ message='The access control list of users and groups that have authorization to submit applications to this queue.'
+ }}
+ <div class="col-sm-6 col-md-6 control-value">
+ <p class="form-control-static">
+ {{escapeACL content.acl_submit_applications}}
+ </p>
+ </div>
+ </div>
+ <div class="form-group row">
+ {{tooltip-label
+ tagName='small'
+ class="col-sm-4 col-md-4 control-label"
+ label='Effective Users'
+ message='The effective permissions to submit applications to this queue.'
+ }}
+ <div class="col-sm-6 col-md-6 control-valu">
+ <p class="form-control-static">
+ {{escapeACL asa_effective_permission}}
+ </p>
+ </div>
+ </div>
+ {{/if}}
+ {{else}}
+ <div>Permissions are managed by Ranger</div>
+ {{/unless}}
+ </div>
+ </div>
+ </div>
+</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/editQueueCapacity.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/editQueueCapacity.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/editQueueCapacity.hbs
new file mode 100644
index 0000000..753fa9b
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/editQueueCapacity.hbs
@@ -0,0 +1,51 @@
+{{!
+* 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 form-inline">
+ <div class="col-md-2 col-sm-2">
+ <span class="queue-name">{{this.name}}</span>
+ </div>
+ <div class="col-md-5 col-md-5">
+ <div class="form-group input-group capacity-input-percent">
+ {{capacity-input class='input-sm' value=this.capacity queue=this maxVal=100}}
+ <span class="input-group-addon">%</span>
+ </div>
+ <div class="form-group capacity-input-slider">
+ {{input-range min="0" max="100" step="1" value=this.capacity class="input-sm"}}
+ </div>
+ {{#if view.isQueueCapacityDirty}}
+ <div class="btn-group btn-group-xs">
+ <a {{action 'rollbackProp' 'capacity' this}} href="#" class="btn btn-default btn-warning"><i class="fa fa-undo"></i></a>
+ </div>
+ {{/if}}
+ </div>
+ <div class="col-md-5 col-sm-5">
+ <div class="form-group input-group capacity-input-percent">
+ {{max-capacity-input class='input-sm' value=this.maximum_capacity queue=this maxVal=100}}
+ <span class="input-group-addon">%</span>
+ </div>
+ <div class="form-group capacity-input-slider">
+ {{input-range min="0" max="100" step="1" value=this.maximum_capacity class="input-sm"}}
+ </div>
+ {{#if view.isQueueMaximumCapacityDirty}}
+ <div class="btn-group btn-group-xs">
+ <a {{action 'rollbackProp' 'maximum_capacity' this}} href="#" class="btn btn-default btn-warning"><i class="fa fa-undo"></i></a>
+ </div>
+ {{/if}}
+ </div>
+</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/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
new file mode 100644
index 0000000..8e278f0
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/queueCapacity.hbs
@@ -0,0 +1,95 @@
+{{!
+* 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="queue-capacity-container">
+ <div class="panel panel-default">
+ <div class="panel-heading">
+ <div class="panel-title">
+ Capacity <a id="collapseQueueCapacityPanelBtn" href="#collapsibleQueueCapacityPanel" data-toggle="collapse" {{bind-attr class=":pull-right view.isCapacityPanelCollapsed:collapsed"}}><i {{bind-attr class=":fa view.isCapacityPanelCollapsed:fa-plus:fa-minus"}}></i></a>
+ </div>
+ </div>
+ <div id="collapsibleQueueCapacityPanel" {{bind-attr class=":panel-collapse :collapse view.isCapacityPanelCollapsed::in"}}>
+ <div class="panel-body">
+ {{#if isOperator}}
+ {{#unless isLeafQ}}
+ <div class="row">
+ <div class="col-md-2 col-sm-2">
+ <label>Children</label>
+ </div>
+ <div class="col-md-5 col-sm-5">
+ {{tooltip-label
+ label='Capacity'
+ message= 'The minimum guaranteed capacity as a percentage of total capacity that is allocated to the queue.'
+ }}
+ </div>
+ <div class="col-md-5 col-sm-5">
+ {{tooltip-label
+ label='Max Capacity'
+ message= 'The cap (maximum capacity) as a percentage of total capacity that this queue can utilize.'
+ }}
+ </div>
+ </div>
+ {{#each childQ in childrenQueues}}
+ {{render "capsched/partials/editQueueCapacity" childQ}}
+ {{/each}}
+ <div class="row">
+ <div class="col-md-2 col-sm-2">
+ <label>Total Capacity</label>
+ </div>
+ <div class="col-sm-5 col-md-5">
+ <div class="progress total-capacity-progress">
+ <div role="progressbar" {{bind-attr class=":progress-bar warnInvalidCapacity:progress-bar-danger:progress-bar-success" style="totalCapacityBarWidth"}}>
+ Used:{{childrenQueuesTotalCapacity}}%
+ </div>
+ </div>
+ </div>
+ </div>
+ {{else}}
+ <div class="row">
+ <div class="col-md-6 col-md-6">
+ <label>Capacity: </label>
+ <span>{{content.capacity}}%</span>
+ </div>
+ <div class="col-md-5 col-md-5">
+ <label>Maximum Capacity: </label>
+ <span>{{content.maximum_capacity}}%</span>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-10 col-sm-10">
+ <span>To edit capacity and maximum capacity at parent queue level</span>
+ <span>{{#link-to 'capsched.queuesconf.editqueue' parentQueue}}Click Here{{/link-to}}</span>
+ </div>
+ </div>
+ {{/unless}}
+ {{else}}
+ <div class="row">
+ <div class="col-md-6 col-md-6">
+ <label>Capacity: </label>
+ <span>{{content.capacity}}%</span>
+ </div>
+ <div class="col-md-5 col-sm-5">
+ <label>Maximum Capacity: </label>
+ <span>{{content.maximum_capacity}}%</span>
+ </div>
+ </div>
+ {{/if}}
+ </div>
+ </div>
+ </div>
+</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/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
new file mode 100644
index 0000000..f25180f
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/queueResources.hbs
@@ -0,0 +1,216 @@
+{{!
+* 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="queue-resources-container">
+ <div class="panel panel-default">
+ <div class="panel-heading">
+ <div class="panel-title">
+ Resources <a id="collapseResourcesPanelBtn" href="#collapsibleQueueResourcesPanel" data-toggle="collapse" {{bind-attr class=":pull-right view.isResourcesPanelCollapsed:collapsed"}}><i {{bind-attr class=":fa view.isResourcesPanelCollapsed:fa-plus:fa-minus"}}></i></a>
+ </div>
+ </div>
+ <div id="collapsibleQueueResourcesPanel" {{bind-attr class=":panel-collapse :collapse view.isResourcesPanelCollapsed::in"}}>
+ <div class="panel-body">
+
+ <div class="row form-group">
+ {{tooltip-label
+ class="col-sm-4 control-label"
+ label='User Limit Factor'
+ message='The upper limit multiple of the queue’s configured minimum capacity that one user’s applications can utilize.'
+ }}
+ {{#if isOperator}}
+ <div class="col-sm-3">
+ {{int-input value=content.user_limit_factor maxlength=10 class="input-sm input-int input-width-control" defaultVal=1 placeholder=1}}
+ {{#if queueDirtyFields.user_limit_factor}}
+ <div class="btn-group btn-group-xs">
+ <a {{action 'rollbackProp' 'user_limit_factor' content}} href="#" class="btn btn-default btn-warning"><i class="fa fa-undo"></i></a>
+ </div>
+ {{/if}}
+ </div>
+ {{else}}
+ <div class="col-sm-2">
+ {{#if content.user_limit_factor}}
+ <p class="form-control-static">{{content.user_limit_factor}}</p>
+ {{else}}
+ <p class="form-control-static">1</p>
+ {{/if}}
+ </div>
+ {{/if}}
+ </div>
+
+ <div class="row form-group">
+ {{tooltip-label
+ class="col-sm-4 control-label"
+ label='Minimum User Limit'
+ message='The minimum guaranteed percentage of queue capacity allocated for a user\'s applications.'
+ }}
+ {{#if isOperator}}
+ <div class="col-sm-3 control-value input-percent-wrap">
+ <div class="input-group input-percent">
+ {{int-input value=content.minimum_user_limit_percent class="input-sm" maxVal=100 placeholder=100}}
+ <span class="input-group-addon">%</span>
+ </div>
+ {{#if queueDirtyFields.minimum_user_limit_percent}}
+ <div class="btn-group btn-group-xs input-percent-rollback">
+ <a {{action 'rollbackProp' 'minimum_user_limit_percent' content}} href="#" class="btn btn-default btn-warning"><i class="fa fa-undo"></i></a>
+ </div>
+ {{/if}}
+ </div>
+ {{else}}
+ <div class="col-sm-2">
+ {{#if content.minimum_user_limit_percent}}
+ <p class="form-control-static">{{content.minimum_user_limit_percent}}%</p>
+ {{else}}
+ <p class="form-control-static">100%</p>
+ {{/if}}
+ </div>
+ {{/if}}
+ </div>
+
+ <div class="row form-group">
+ {{tooltip-label
+ class="col-sm-4 control-label"
+ label='Maximum Applications'
+ message='The maximum number of applications that can be running or pending in this specific queue at any point of time.'
+ }}
+ {{#if isOperator}}
+ <div class="col-sm-3 control-value">
+ {{int-input placeholder="Inherited" maxlength=15 value=maximumApplications class="input-sm input-int input-width-control"}}
+ {{#if queueDirtyFields.maximum_applications}}
+ <div class="btn-group btn-group-xs" >
+ <a {{action 'rollbackProp' 'maximum_applications' content}} href="#" class="btn btn-default btn-warning"><i class="fa fa-undo"></i></a>
+ </div>
+ {{/if}}
+ </div>
+ <div class="col-sm-2 inherited-value">
+ <span>(Inherited)</span>
+ </div>
+ {{else}}
+ <div class="col-sm-3">
+ {{#if maximumApplications}}
+ <p class="form-control-static">{{maximumApplications}} (Inherited)</p>
+ {{else}}
+ <p class="form-control-static">Inherited</p>
+ {{/if}}
+ </div>
+ {{/if}}
+ </div>
+
+ <div class="row form-group">
+ {{tooltip-label
+ class="col-sm-4 control-label"
+ label='Maximum AM Resource'
+ message='The maximum percentage of total capacity of this specific queue that can be utilized by application masters at any point in time.'
+ }}
+ {{#if isOperator}}
+ <div class="col-sm-3 control-value input-percent-wrap">
+ <div class="input-group input-percent">
+ {{int-input placeholder="Inherited" value=maximumAMResourcePercent class="input-sm" maxVal=100}}
+ <span class="input-group-addon">%</span>
+ </div>
+ {{#if queueDirtyFields.maximum_am_resource_percent}}
+ <div class="btn-group btn-group-xs">
+ <a {{action 'rollbackProp' 'maximum_am_resource_percent' content}} href="#" class="btn btn-default btn-warning"><i class="fa fa-undo"></i></a>
+ </div>
+ {{/if}}
+ </div>
+ <div class="col-sm-2 inherited-value">
+ <span>(Inherited)</span>
+ </div>
+ {{else}}
+ <div class="col-sm-2">
+ {{#if maximumAMResourcePercent}}
+ <p class="form-control-static">{{maximumAMResourcePercent}}% (Inherited)</p>
+ {{else}}
+ <p class="form-control-static">Inherited</p>
+ {{/if}}
+ </div>
+ {{/if}}
+ </div>
+
+ <div class="row form-group">
+ {{tooltip-label
+ class="col-sm-4 control-label"
+ label='Ordering policy'
+ message='The ordering policy to use for applications scheduled to this queue. <br/> FIFO: Applications get available capacity based on order they are submitted <br/> Fair: Applications will get fair share of capacity, regardless of order submitted'}}
+ {{#if isOperator}}
+ <div class="col-sm-3 control-value input-percent-wrap">
+ <div class="input-percent">
+ {{view Ember.Select
+ class="form-control input-sm"
+ content=orderingPolicyValues
+ optionLabelPath="content.label"
+ optionValuePath="content.value"
+ value=currentOP}}
+ </div>
+ {{#if queueDirtyFields.ordering_policy}}
+ <div class="btn-group btn-group-xs" >
+ <a {{action 'rollbackProp' 'ordering_policy' content}} href="#" class="btn btn-default btn-warning"><i class="fa fa-undo"></i></a>
+ </div>
+ {{/if}}
+ </div>
+ {{else}}
+ <div class="col-sm-2">
+ {{#if content.ordering_policy}}
+ <p class="form-control-static">{{uppercase content.ordering_policy}}</p>
+ {{else}}
+ <p class="form-control-static">FIFO</p>
+ {{/if}}
+ </div>
+ {{/if}}
+ </div>
+
+ <div class="row">
+ {{#if isFairOP}}
+ <div class="form-group">
+ {{tooltip-label
+ class="col-sm-4 control-label"
+ label='Enable Size Based Weight Ordering'
+ message='If true, then Fair Ordering Policy will use resource needs of an application as way to prioritize capacity allocation - larger applications will get higher priority'
+ }}
+ {{#if isOperator}}
+ <div class="col-sm-3 control-value input-toggle-wrap">
+ <div class="btn-group btn-group-sm">
+ <a href="#" {{action 'toggleProperty' 'enable_size_based_weight' content}} class="btn btn-default">
+ <i {{bind-attr class=":fa content.enable_size_based_weight:fa-check-square-o:fa-square-o"}}></i>
+ </a>
+ </div>
+ {{#if queueDirtyFields.enable_size_based_weight}}
+ <div class="btn-group btn-group-xs" >
+ <a {{action 'rollbackProp' 'enable_size_based_weight' content}} href="#" class="btn btn-default btn-warning"><i class="fa fa-undo"></i></a>
+ </div>
+ {{/if}}
+ </div>
+ {{else}}
+ <div class="col-sm-2">
+ <p class="form-control-static">
+ {{#if content.enable_size_based_weight}}
+ Enabled
+ {{else}}
+ Disabled
+ {{/if}}
+ </p>
+ </div>
+ {{/if}}
+ </div>
+ {{/if}}
+ </div>
+
+ </div>
+ </div>
+ </div>
+</div>