diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-servicedef.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-servicedef.js new file mode 100644 index 0000000..2860d7a --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-servicedef.js @@ -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. + */ + +import Ember from 'ember'; +import AbstractAdapter from './abstract'; + +export default AbstractAdapter.extend({ + address: "dashWebAddress", + restNameSpace: "dashService", + serverName: "DASH", + + deployService(request) { + var url = this.buildURL(); + return new Ember.RSVP.Promise(function(resolve, reject) { + Ember.$.ajax({ + url: url, + type: "POST", + data: request, + contentType: "application/json", + dataType: "json", + parseData: false, + success: function(resp) { + Ember.run(null, resolve, resp); + }, + error: function(errr) { + let errmsg = errr.responseText; + Ember.run(null, reject, errmsg); + } + }); + }); + } +}); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/breadcrumb-bar.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/breadcrumb-bar.js index 44edb8e..b8d974a 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/breadcrumb-bar.js +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/breadcrumb-bar.js @@ -21,6 +21,7 @@ import Ember from 'ember'; export default Ember.Component.extend({ breadcrumbs: null, + hideRefresh: false, actions:{ refresh: function () { diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/deploy-service.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/deploy-service.js new file mode 100644 index 0000000..244d199 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/deploy-service.js @@ -0,0 +1,213 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Ember from 'ember'; + +export default Ember.Component.extend({ + viewType: 'standard', + savedStandardTemplates: null, + savedJsonTemplates: null, + savedTemplateName: '', + serviceDef: null, + currentComponent: null, + currentConfig: null, + jsonServiceDef: '', + serviceResp: null, + isLoading: false, + + actions: { + showSaveTemplateModal() { + Ember.$('#saveListModal').modal('show'); + Ember.$('#saveListModal').on('shown.bs.modal', function() { + Ember.$('#saveListModal').find('#templateNameInput').focus(); + }); + }, + + showAddComponentModal() { + var newComp = this.get('serviceDef').createNewServiceComponent(); + this.set('currentComponent', newComp); + Ember.$('#addComponentModal').modal('show'); + }, + + addNewComponent() { + this.get('serviceDef.serviceComponents').addObject(this.get('currentComponent')); + Ember.$('#addComponentModal').modal('hide'); + }, + + removeComponent(component) { + this.get('serviceDef.serviceComponents').removeObject(component); + }, + + showNewConfigurationModal() { + var newConfig = this.get('serviceDef').createNewServiceConfig(); + this.set('currentConfig', newConfig); + Ember.$('#addConfigurationModal').modal('show'); + }, + + addNewConfiguration() { + this.get('serviceDef.serviceConfigs').addObject(this.get('currentConfig')); + Ember.$('#addConfigurationModal').modal('hide'); + }, + + removeConfiguration(config) { + this.get('serviceDef.serviceConfigs').removeObject(config); + }, + + configTypeChanged(type) { + this.set('currentConfig.type', type); + }, + + deployService() { + this.set('serviceResp', null); + if (this.get('isStandardViewType')) { + this.sendAction("deployServiceDef", this.get('serviceDef')); + } else { + this.sendAction("deployServiceJson", this.get('jsonServiceDef')); + } + }, + + updateViewType(type) { + this.set('viewType', type); + }, + + addToSavedList() { + if (this.get('isStandardViewType')) { + this.get('savedStandardTemplates').addObject({ + name: this.get('savedTemplateName'), + defId: this.get('serviceDef.id'), + active: false + }); + this.set('serviceDef.isCached', true); + } else { + this.get('savedJsonTemplates').addObject({ + name: this.get('savedTemplateName'), + json: this.get('jsonServiceDef'), + active: false + }); + } + Ember.$('#saveListModal').modal('hide'); + this.set('savedTemplateName', ''); + }, + + updateServiceDef(def) { + this.selectActiveListItem(def); + if (this.get('isStandardViewType')) { + this.set('serviceDef', this.getStore().peekRecord('yarn-servicedef', def.defId)); + } else { + this.set('jsonServiceDef', def.json); + } + }, + + clearConfigs() { + this.unselectAllSavedList(this.get('getSavedList')); + var store = this.getStore(); + if (this.get('isStandardViewType')) { + var oldDef = this.get('serviceDef'); + var def = store.createRecord('yarn-servicedef', { + id: 'yarn_servicedef_' + Date.now() + }); + this.set('serviceDef', def); + if (!oldDef.get('isCached')) { + store.deleteRecord(oldDef); + } + } else { + this.set('jsonServiceDef', ''); + } + }, + + removeFromSavedList(list) { + if (this.get('isStandardViewType')) { + this.get('savedStandardTemplates').removeObject(list); + } else { + this.get('savedJsonTemplates').removeObject(list); + } + }, + + clearServiceResponse() { + this.set('serviceResp', null); + } + }, + + selectActiveListItem(item) { + this.unselectAllSavedList(this.get('getSavedList')); + Ember.set(item, 'active', true); + }, + + unselectAllSavedList(list) { + list.forEach(function(item) { + Ember.set(item, 'active', false); + }); + }, + + getSavedList: Ember.computed('viewType', function() { + if (this.get('isStandardViewType')) { + return this.get('savedStandardTemplates'); + } else { + return this.get('savedJsonTemplates'); + } + }), + + getStore: function() { + return this.get('serviceDef.store'); + }, + + isStandardViewType: Ember.computed('viewType', function() { + return this.get('viewType') === 'standard'; + }), + + isCustomViewType: Ember.computed('viewType', function() { + return this.get('viewType') === 'custom'; + }), + + isValidTemplateName: Ember.computed('savedTemplateName', function() { + return this.get('savedTemplateName') !== ''; + }), + + isValidServiceDef: Ember.computed('serviceDef.name', 'serviceDef.queue', 'serviceDef.serviceComponents.[]', function () { + return this.get('serviceDef').isValidServiceDef(); + }), + + isValidJsonService: Ember.computed('jsonServiceDef', function() { + return this.get('jsonServiceDef') !== ''; + }), + + enableSaveOrDeployBtn: Ember.computed('isValidServiceDef', 'isValidJsonService', 'viewType', function() { + if (this.get('isStandardViewType')) { + return this.get('isValidServiceDef'); + } else { + return this.get('isValidJsonService'); + } + }), + + isValidCurrentComponent: Ember.computed('currentComponent.name', 'currentComponent.cpus', 'currentComponent.memory', 'currentComponent.numOfContainers', function() { + var current = this.get('currentComponent'); + if (!current) { + return false; + } + return current.get('name') !== '' && current.get('cpus') !== '' + && current.get('memory') !== '' && current.get('numOfContainers') !== ''; + }), + + isValidCurrentConfig: Ember.computed('currentConfig.name', 'currentConfig.value', function() { + var current = this.get('currentConfig'); + if (!current) { + return false; + } + return current.get('name') !== '' && current.get('value') !== ''; + }) +}); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-deploy-service.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-deploy-service.js new file mode 100644 index 0000000..7eda7d4 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-deploy-service.js @@ -0,0 +1,69 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Ember from 'ember'; + +export default Ember.Controller.extend({ + breadcrumbs: [{ + text: "Home", + routeName: 'application' + }, { + text: "Services", + routeName: 'yarn-services', + }, { + text: "New Service", + routeName: 'yarn-deploy-service', + }], + + savedTemplates: [], + savedJsonTemplates: [], + serviceResponse: null, + isLoading: false, + + actions: { + deployServiceDef(serviceDef) { + var defjson = serviceDef.getServiceJSON(); + this.deployServiceApp(JSON.stringify(defjson)); + }, + + deployServiceJson(json) { + this.deployServiceApp(json); + } + }, + + gotoServices() { + Ember.run.later(this, function() { + this.set('serviceResponse', null); + this.transitionToRoute('yarn-services'); + }, 1000); + }, + + deployServiceApp(requestJson) { + var _this = this; + var adapter = this.store.adapterFor('yarn-servicedef'); + this.set('isLoading', true); + adapter.deployService(requestJson).then(function() { + _this.set('isLoading', false); + _this.set('serviceResponse', {message: 'Service has been accepted successfully.', type: 'success'}); + _this.gotoServices(); + }, function(errmsg) { + _this.set('isLoading', false); + _this.set('serviceResponse', {message: errmsg, type: 'error'}); + }); + } +}); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-servicedef.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-servicedef.js new file mode 100644 index 0000000..1538cab --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-servicedef.js @@ -0,0 +1,132 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import DS from 'ember-data'; +import Ember from 'ember'; + +export default DS.Model.extend({ + name: DS.attr('string', {defaultValue: ''}), + queue: DS.attr('string', {defaultValue: ''}), + lifetime: DS.attr('string', {defaultValue: ''}), + isCached: DS.attr('boolean', {defaultValue: false}), + + serviceComponents: DS.attr({defaultValue: function() { + return Ember.A(); + }}), + + serviceConfigs: DS.attr({defaultValue: function() { + return Ember.A(); + }}), + + clear() { + this.set('name', ''); + this.set('queue', ''); + this.set('lifetime', ''); + this.get('serviceComponents').clear(); + this.get('serviceConfigs').clear(); + }, + + isValidServiceDef() { + return this.get('name') !== '' && this.get('queue') !== '' && this.get('serviceComponents.length') > 0; + }, + + createNewServiceComponent() { + return Ember.Object.create({ + name: '', + numOfContainers: '', + cpus: '', + memory: '', + artifactId: 'hortonworks/ycloud-centos6:0.2', + artifactType: 'DOCKER', + launchCommand: '/bootstrap/privileged-centos6-sshd', + dependencies: [] + }); + }, + + createNewServiceConfig() { + return Ember.Object.create({ + name: '', + value: '', + type: 'property' + }); + }, + + getServiceJSON() { + return this.serializeServiceDef(); + }, + + serializeServiceDef() { + var json = { + name: "", + queue: "", + lifetime: "", + components: [], + configuration: { + properties: {}, + env: {} + } + }; + + var components = this.get('serviceComponents'); + var configs = this.get('serviceConfigs'); + + json['name'] = this.get('name'); + json['queue'] = this.get('queue'); + json['lifetime'] = this.get('lifetime'); + + components.forEach(function(component) { + json.components.pushObject(this.serializeComponent(component)); + }.bind(this)); + + configs.forEach(function(config) { + let conf = this.serializeConfiguration(config); + if (conf.type === "property") { + json.configuration.properties[conf.name] = conf.value; + } else { + json.configuration.env[conf.name] = conf.value; + } + }.bind(this)); + + return json; + }, + + serializeComponent(record) { + var json = {}; + json['name'] = record.get('name'); + json['number_of_containers'] = record.get('numOfContainers'); + json['launch_command'] = record.get('launchCommand'); + json['dependencies'] = []; + json['artifact'] = { + id: record.get('artifactId'), + type: record.get('artifactType') + }; + json['resource'] = { + cpus: record.get('cpus'), + memory: record.get('memory') + }; + return json; + }, + + serializeConfiguration(config) { + var json = {}; + json["type"] = config.get('type'); + json["name"] = config.get('name'); + json["value"] = config.get('value'); + return json; + } +}); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/router.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/router.js index a45861e..8b7cf69 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/router.js +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/router.js @@ -49,6 +49,7 @@ Router.map(function() { this.route('yarn-container-log', { path: '/yarn-container-log/:node_id/:node_addr/:container_id/:filename' }); + this.route('yarn-deploy-service'); this.route('cluster-overview'); this.route('yarn-app', { path: '/yarn-app/:app_id' }); this.route('yarn-app-attempt', { path: '/yarn-app-attempt/:app_attempt_id'}); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-deploy-service.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-deploy-service.js new file mode 100644 index 0000000..05ef600 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-deploy-service.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. + */ + +import Ember from 'ember'; + +export default Ember.Route.extend({ + model() { + return this.store.createRecord('yarn-servicedef', { + id: 'yarn_servicedef_' + Date.now() + }); + } +}); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/services/hosts.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/services/hosts.js index 19863e1..0f151ee 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/services/hosts.js +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/services/hosts.js @@ -71,4 +71,8 @@ export default Ember.Service.extend({ rmWebAddress: Ember.computed(function () { return this.normalizeURL(this.get("env.app.hosts.rmWebAddress")); }), + + dashWebAddress: Ember.computed(function () { + return this.normalizeURL(this.get("env.app.hosts.dashWebAddress")); + }) }); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/styles/app.css b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/styles/app.css index dca5b92..9563877 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/styles/app.css +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/styles/app.css @@ -305,3 +305,122 @@ li a.navigation-link.ember-view { .donut-chart svg { width: 100%; } + +.deploy-service textarea { + border-radius: 5px !important; + resize: none; + word-wrap: break-word; + margin-top: -26px; +} + +.deploy-service .loading-state { + opacity: 0.5; +} + +.deploy-service .loading-state img { + width: 80px; + height: 80px; + margin: 40px auto; + left: 50% !important; + position: absolute; + z-index: 9999; +} + +.deploy-service .align-center { + text-align: center; +} + +.deploy-service .saved-list { + min-height: 500px; +} + +.deploy-service .glyphicon { + cursor: pointer; +} + +.deploy-service .remove-icon:hover { + color: #d9534f; +} + +.deploy-service .edit-icon { + margin-right: 5px; +} + +.deploy-service .edit-icon:hover { + color: #5cb85c; +} + +.deploy-service .savedlist-column { + padding-top: 10px; +} + +.deploy-service .definition-column { + padding-top: 10px; + border-left: 1px solid #ddd; +} + +.deploy-service .content-area { + padding: 15px 0px; + border-top: 1px solid #ddd; +} + +.deploy-service .custom-json-area { + padding: 10px 0; +} + +.add-component-modal .modal-dialog, .save-list-modal .modal-dialog, .add-configuration-modal .modal-dialog { + width: 400px; +} + +.add-component-modal .form-group, .save-list-modal .form-group, .add-configuration-modal .form-group { + margin-bottom: 5px; +} + +.deploy-service .action-btns { + text-align: right; + padding-bottom: 15px; + padding-right: 0; +} + +table.component-table > thead > tr > th:last-of-type, table.component-table > tbody > tr > td:last-of-type { + width: 50px !important; + text-align: center; +} + +table.config-table > thead > tr > th:last-of-type, table.config-table > tbody > tr > td:last-of-type { + width: 50px !important; + text-align: center; +} + +.deploy-service .toggle-btn.active { + color: #fff; + background-color: #337ab7; + border-color: #337ab7; + text-shadow: none; +} + +.deploy-service .service-resp { + word-wrap: break-word; +} + +.deploy-service .service-resp .remove-icon { + padding: 5px; +} + +.table-custom-bordered > thead > tr > th, .table-custom-bordered > tbody > tr > td { + border-bottom: 1px solid #ddd !important; + border-right: 1px solid #ddd !important; +} + +.table-custom-striped > thead > tr, .table-custom-striped > tbody > tr:nth-of-type(even) { + background-color: #f9f9f9; +} + +.deploy-service .required label:after, .add-component-modal .required label:after { + content: '*'; + color: #d9534f; +} + +.deploy-service .form-group.shrink-height { + margin-bottom: -8px; +} diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/breadcrumb-bar.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/breadcrumb-bar.hbs index 24acbd9..54229cc 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/breadcrumb-bar.hbs +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/breadcrumb-bar.hbs @@ -18,5 +18,7 @@ diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/deploy-service.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/deploy-service.hbs new file mode 100644 index 0000000..e2f2810 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/deploy-service.hbs @@ -0,0 +1,302 @@ +{{! + * 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 serviceResp}} +
+
+
+ +
+ {{serviceResp.message}} +
+
+
+
+ {{/if}} +
+ {{#if isLoading}} + Loading... + {{/if}} +
+
+
+ +
+ +
+
+ +
+ +
+ + +
+
+ {{#if isStandardViewType}} +
+
+
+ + {{input type="text" class="form-control" placeholder="Service Name" value=serviceDef.name}} +
+
+
+
+ +
+
+
+ + {{input type="text" class="form-control" placeholder="Queue Name" value=serviceDef.queue}} +
+
+
+
+ +
+
+
+ + {{input type="text" class="form-control" placeholder="Service Lifetime (Seconds)" value=serviceDef.lifetime}} +
+
+
+
+ +
+
+
+ + +
+ + + + + + + + + + + + + + {{#each serviceDef.serviceComponents as |component|}} + + + + + + + + + + {{else}} + + + + {{/each}} + +
Component NameCPUMemory# ContainersArtifact IdLaunch CommandAction
{{component.name}}{{component.cpus}}{{component.memory}}{{component.numOfContainers}}{{component.artifactId}}{{component.launchCommand}} + +
No data available
+
+
+
+
+
+ +
+
+
+ + +
+ + + + + + + + + + + {{#each serviceDef.serviceConfigs as |config|}} + + + + + + + {{else}} + + + + {{/each}} + +
NameValueTypeAction
{{config.name}}{{config.value}}{{config.type}} + +
No data available
+
+
+
+
+ {{/if}} + + {{#if isCustomViewType}} +
+ {{textarea class="form-control" rows="24" cols="120" value=jsonServiceDef placeholder="Service JSON configuration here..."}} +
+ {{/if}} +
+ +
+ + + +
+
+
+
+
+
+ + + + + + diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps.hbs index 7aade00..e51916a 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps.hbs +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps.hbs @@ -83,4 +83,4 @@ - \ No newline at end of file + diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps/services.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps/services.hbs index 7556908..d767f95 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps/services.hbs +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps/services.hbs @@ -16,10 +16,16 @@ limitations under the License. --}} +
+ + New Service + +
+ {{#if model.apps}} {{em-table columns=columns rows=model.apps}} {{else}}

Could not find any applications from this cluster

{{/if}} -{{outlet}} \ No newline at end of file +{{outlet}} diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-deploy-service.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-deploy-service.hbs new file mode 100644 index 0000000..b1a0229 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-deploy-service.hbs @@ -0,0 +1,33 @@ +{{! + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +}} + +{{breadcrumb-bar breadcrumbs=breadcrumbs hideRefresh=true}} + +
+
+ {{deploy-service + savedStandardTemplates=savedTemplates + savedJsonTemplates=savedJsonTemplates + serviceDef=model + serviceResp=serviceResponse + isLoading=isLoading + deployServiceDef="deployServiceDef" + deployServiceJson="deployServiceJson" + }} +
+
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/configs.env b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/configs.env index 04577c9..a795fc5 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/configs.env +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/configs.env @@ -40,6 +40,13 @@ ENV = { */ //rmWebAddress: "localhost:8088", + /* + * Dash server web interface can be configured below. + * By default dash web address is set as localhost:9191, uncomment and change + * the following value for pointing to a different address. + */ + //dashWebAddress: "localhost:9191", + /* * Protocol scheme. It can be "http:" or "https:". By default, http is used. */ diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/default-config.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/default-config.js index 70d4ebc..fc279d4 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/default-config.js +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/default-config.js @@ -21,12 +21,14 @@ module.exports = { // Yarn UI App configurations localBaseAddress: "", timelineWebAddress: "localhost:8188", rmWebAddress: "localhost:8088", + dashWebAddress: "localhost:9191", protocolScheme: "http:" }, namespaces: { timeline: 'ws/v1/applicationhistory', cluster: 'ws/v1/cluster', metrics: 'ws/v1/cluster/metrics', + dashService: 'services/v1/applications', node: '{nodeAddress}/ws/v1/node' }, }; diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/deploy-service-test.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/deploy-service-test.js new file mode 100644 index 0000000..ba855a7 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/deploy-service-test.js @@ -0,0 +1,43 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; + +moduleForComponent('deploy-service', 'Integration | Component | deploy service', { + integration: true +}); + +test('it renders', function(assert) { + + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.on('myAction', function(val) { ... });" + EOL + EOL + + + this.render(hbs`{{deploy-service}}`); + + assert.equal(this.$().text().trim(), ''); + + // Template block usage:" + EOL + + this.render(hbs` + {{#deploy-service}} + template block text + {{/deploy-service}} + `); + + assert.equal(this.$().text().trim(), 'template block text'); +}); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/adapters/yarn-servicedef-test.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/adapters/yarn-servicedef-test.js new file mode 100644 index 0000000..ea12bc5 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/adapters/yarn-servicedef-test.js @@ -0,0 +1,30 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { moduleFor, test } from 'ember-qunit'; + +moduleFor('adapter:yarn-servicedef', 'Unit | Adapter | yarn servicedef', { + // Specify the other units that are required for this test. + // needs: ['serializer:foo'] +}); + +// Replace this with your real tests. +test('it exists', function(assert) { + let adapter = this.subject(); + assert.ok(adapter); +}); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-deploy-service-test.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-deploy-service-test.js new file mode 100644 index 0000000..c3918f4 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-deploy-service-test.js @@ -0,0 +1,30 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { moduleFor, test } from 'ember-qunit'; + +moduleFor('controller:yarn-deploy-service', 'Unit | Controller | yarn deploy service', { + // Specify the other units that are required for this test. + // needs: ['controller:foo'] +}); + +// Replace this with your real tests. +test('it exists', function(assert) { + let controller = this.subject(); + assert.ok(controller); +}); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/models/yarn-servicedef-test.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/models/yarn-servicedef-test.js new file mode 100644 index 0000000..141a94b --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/models/yarn-servicedef-test.js @@ -0,0 +1,30 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { moduleForModel, test } from 'ember-qunit'; + +moduleForModel('yarn-servicedef', 'Unit | Model | yarn servicedef', { + // Specify the other units that are required for this test. + needs: [] +}); + +test('it exists', function(assert) { + let model = this.subject(); + // let store = this.store(); + assert.ok(!!model); +}); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-deploy-service-test.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-deploy-service-test.js new file mode 100644 index 0000000..4e2dcf1 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-deploy-service-test.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. + */ + +import { moduleFor, test } from 'ember-qunit'; + +moduleFor('route:yarn-deploy-service', 'Unit | Route | yarn deploy service', { + // Specify the other units that are required for this test. + // needs: ['controller:foo'] +}); + +test('it exists', function(assert) { + let route = this.subject(); + assert.ok(route); +});