You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by yu...@apache.org on 2013/03/14 01:27:04 UTC
svn commit: r1456292 - in /incubator/ambari/trunk: ./ ambari-web/app/
ambari-web/app/controllers/main/service/ ambari-web/app/controllers/wizard/
ambari-web/app/routes/ ambari-web/app/styles/
ambari-web/app/templates/main/service/ ambari-web/app/templa...
Author: yusaku
Date: Thu Mar 14 00:27:03 2013
New Revision: 1456292
URL: http://svn.apache.org/r1456292
Log:
AMBARI-1633. Reassign Master Wizard - Step 5. (yusaku)
Added:
incubator/ambari/trunk/ambari-web/app/controllers/wizard/step14_controller.js
incubator/ambari/trunk/ambari-web/app/templates/wizard/step14.hbs
incubator/ambari/trunk/ambari-web/app/views/wizard/step14_view.js
Modified:
incubator/ambari/trunk/CHANGES.txt
incubator/ambari/trunk/ambari-web/app/controllers.js
incubator/ambari/trunk/ambari-web/app/controllers/main/service/reassign_controller.js
incubator/ambari/trunk/ambari-web/app/messages.js
incubator/ambari/trunk/ambari-web/app/routes/reassign_master_routes.js
incubator/ambari/trunk/ambari-web/app/styles/application.less
incubator/ambari/trunk/ambari-web/app/templates/main/service/reassign.hbs
incubator/ambari/trunk/ambari-web/app/views.js
Modified: incubator/ambari/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/CHANGES.txt?rev=1456292&r1=1456291&r2=1456292&view=diff
==============================================================================
--- incubator/ambari/trunk/CHANGES.txt (original)
+++ incubator/ambari/trunk/CHANGES.txt Thu Mar 14 00:27:03 2013
@@ -12,6 +12,8 @@ Trunk (unreleased changes):
NEW FEATURES
+ AMBARI-1633. Reassign Master Wizard - Step 5. (yusaku)
+
AMBARI-1585. Creating the agent scripts for Hue server installation and
configuration on the Hue host. (swagle)
Modified: incubator/ambari/trunk/ambari-web/app/controllers.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/controllers.js?rev=1456292&r1=1456291&r2=1456292&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/controllers.js (original)
+++ incubator/ambari/trunk/ambari-web/app/controllers.js Thu Mar 14 00:27:03 2013
@@ -82,6 +82,7 @@ require('controllers/wizard/step10_contr
require('controllers/wizard/step11_controller');
require('controllers/wizard/step12_controller');
require('controllers/wizard/step13_controller');
+require('controllers/wizard/step14_controller');
require('controllers/wizard/stack_upgrade/step1_controller');
require('controllers/wizard/stack_upgrade/step2_controller');
require('controllers/wizard/stack_upgrade/step3_controller');
Modified: incubator/ambari/trunk/ambari-web/app/controllers/main/service/reassign_controller.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/controllers/main/service/reassign_controller.js?rev=1456292&r1=1456291&r2=1456292&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/controllers/main/service/reassign_controller.js (original)
+++ incubator/ambari/trunk/ambari-web/app/controllers/main/service/reassign_controller.js Thu Mar 14 00:27:03 2013
@@ -210,6 +210,7 @@ App.ReassignMasterController = App.Wizar
this.loadConfirmedHosts();
case '1':
this.loadComponentToReassign();
+ this.load('cluster');
}
},
Added: incubator/ambari/trunk/ambari-web/app/controllers/wizard/step14_controller.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/controllers/wizard/step14_controller.js?rev=1456292&view=auto
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/controllers/wizard/step14_controller.js (added)
+++ incubator/ambari/trunk/ambari-web/app/controllers/wizard/step14_controller.js Thu Mar 14 00:27:03 2013
@@ -0,0 +1,793 @@
+/**
+ * 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.WizardStep14Controller = Em.Controller.extend({
+
+ status: function () {
+ if (this.get('tasks').someProperty('status', 'FAILED')) {
+ return 'FAILED';
+ }
+ if (this.get('tasks').everyProperty('status', 'COMPLETED')) {
+ return 'COMPLETED';
+ }
+ return 'IN_PROGRESS';
+ }.property('tasks.@each.status'),
+
+ tasks: [],
+
+ /**
+ * Set messages for tasks depending on their status
+ */
+ setTasksMessages: function () {
+ var service = this.get('service.displayName');
+ var master = this.get('masterComponent.display_name');
+ for (i = 0; i < this.get('tasks').length; i++) {
+ var status = this.get('tasks')[i].status.toLowerCase().replace('initialize', 'pending').replace('_', ' ');
+ if (i == 0 || i == 6) {
+ this.get('tasks')[i].set('message', Em.I18n.t('installer.step14.task' + i).format(service) + ' ' + status);
+ } else {
+ this.get('tasks')[i].set('message', Em.I18n.t('installer.step14.task' + i).format(master) + ' ' + status);
+ }
+ }
+ }.observes('tasks.@each.status'),
+
+ configs: [],
+ globals: [],
+ configMapping: require('data/config_mapping'),
+ newConfigsTag: null,
+ createdConfigs: [],
+
+ currentRequestId: null,
+
+ isSubmitDisabled: true,
+
+ service: function () {
+ return App.Service.find().findProperty('serviceName', this.get('masterComponent.service_id'));
+ }.property('masterComponent'),
+
+ masterComponent: function () {
+ return this.get('content.reassign');
+ }.property('content.reassign'),
+
+ loadStep: function () {
+ this.clearStep();
+ this.loadTasks();
+ this.navigateStep();
+ },
+
+ clearStep: function () {
+ var tasks = [];
+ for (var i = 0; i < 8; i++) {
+ tasks.pushObject(Ember.Object.create({
+ status: 'INITIALIZE',
+ logs: '',
+ message: '',
+ progress: 0
+ }));
+ }
+ this.set('tasks', tasks);
+ this.set('isSubmitDisabled', true);
+ this.get('configs').clear();
+ this.get('globals').clear();
+ this.get('createdConfigs').clear();
+ },
+
+ loadTasks: function () {
+
+ },
+
+ /**
+ * Run tasks in proper way
+ */
+ navigateStep: function () {
+ if (this.get('tasks')[0].status == 'INITIALIZE') {
+ this.stopService();
+ }
+ else if (this.get('tasks')[1].status == 'INITIALIZE') {
+ this.createMasterComponent();
+ }
+ else if (this.taskIsReady(2)) {
+ this.createConfigs();
+ }
+ else if (this.taskIsReady(3)) {
+ this.applyConfigs();
+ }
+ else if (this.taskIsReady(4)) {
+ this.putInMaintenanceMode();
+ }
+ else if (this.taskIsReady(5)) {
+ this.installComponent();
+ }
+ else if (this.taskIsReady(6)) {
+ this.startComponents();
+ }
+ else if (this.taskIsReady(7)) {
+ this.removeComponent();
+ }
+ }.observes('tasks.@each.status'),
+
+ /**
+ * Determine preparedness to run task
+ * @param task
+ * @return {Boolean}
+ */
+ taskIsReady: function (task) {
+ var startIndex = (task == 5) ? 0 : 1;
+ var tempArr = this.get('tasks').mapProperty('status').slice(startIndex, task).uniq();
+ return this.get('tasks')[task].status == 'INITIALIZE' && tempArr.length == 1 && tempArr[0] == 'COMPLETED';
+ },
+
+ /**
+ * Change status of the task
+ * @param task
+ * @param status
+ */
+ setTasksStatus: function (task, status) {
+ this.get('tasks')[task].set('status', status);
+ },
+
+ stopService: function () {
+ var self = this;
+ var clusterName = this.get('content.cluster.name');
+ var serviceName = this.get('masterComponent.service_id');
+ var url = App.apiPrefix + '/clusters/' + clusterName + '/services/' + serviceName;
+ var data = '{"ServiceInfo": {"state": "INSTALLED"}}';
+ var method = 'PUT';
+ $.ajax({
+ type: method,
+ url: url,
+ data: data,
+ dataType: 'text',
+ timeout: App.timeout,
+
+ beforeSend: function () {
+ self.setTasksStatus(0, 'PENDING');
+ },
+
+ success: function (data) {
+ if (jQuery.parseJSON(data)) {
+ self.set('currentRequestId', jQuery.parseJSON(data).Requests.id);
+ self.getLogsByRequest();
+ } else {
+ self.setTasksStatus(0, 'FAILED');
+ }
+ },
+
+ error: function () {
+ self.setTasksStatus(0, 'FAILED');
+ },
+
+ statusCode: require('data/statusCodes')
+ });
+ },
+
+ createMasterComponent: function () {
+ var self = this;
+ var clusterName = this.get('content.cluster.name');
+ var hostName = this.get('content.masterComponentHosts').findProperty('component', this.get('content.reassign.component_name')).hostName;
+ var componentName = this.get('masterComponent.component_name');
+ var url = App.apiPrefix + '/clusters/' + clusterName + '/hosts?Hosts/host_name=' + hostName;
+ var data = {
+ "host_components": [
+ {
+ "HostRoles": {
+ "component_name": componentName
+ }
+ }
+ ]
+ };
+ var method = 'POST';
+ $.ajax({
+ type: method,
+ url: url,
+ data: JSON.stringify(data),
+ dataType: 'text',
+ timeout: App.timeout,
+
+ beforeSend: function () {
+ self.setTasksStatus(1, 'PENDING');
+ },
+
+ success: function () {
+ self.setTasksStatus(1, 'COMPLETED');
+ },
+
+ error: function () {
+ self.setTasksStatus(1, 'FAILED');
+ },
+
+ statusCode: require('data/statusCodes')
+ });
+
+ },
+
+ createConfigs: function () {
+ this.loadGlobals();
+ this.loadConfigs();
+ this.set('newConfigsTag', 'version' + (new Date).getTime());
+ var serviceName = this.get('service.serviceName');
+ this.createConfigSite(this.createGlobalSiteObj());
+ this.createConfigSite(this.createCoreSiteObj());
+ if (serviceName == 'HDFS') {
+ this.createConfigSite(this.createHdfsSiteObj());
+ }
+ if (serviceName == 'MAPREDUCE') {
+ this.createConfigSite(this.createMrSiteObj());
+ }
+ if (serviceName == 'HBASE') {
+ this.createConfigSite(this.createHbaseSiteObj());
+ }
+ if (serviceName == 'OOZIE') {
+ this.createConfigSite(this.createOozieSiteObj());
+ }
+ if (serviceName == 'HIVE') {
+ this.createConfigSite(this.createHiveSiteObj());
+ }
+ if (serviceName == 'WEBHCAT') {
+ this.createConfigSite(this.createWebHCatSiteObj());
+ }
+ if (this.get('tasks')[2].status !== 'FAILED') {
+ this.setTasksStatus(2, 'COMPLETED');
+ }
+ },
+
+ createConfigSite: function (data) {
+ var self = this;
+ data.tag = this.get('newConfigsTag');
+ var clusterName = this.get('content.cluster.name');
+ var url = App.apiPrefix + '/clusters/' + clusterName + '/configurations';
+ $.ajax({
+ type: 'POST',
+ url: url,
+ data: JSON.stringify(data),
+ dataType: 'text',
+ timeout: 5000,
+
+ beforeSend: function () {
+ self.setTasksStatus(2, 'PENDING');
+ },
+
+ success: function () {
+ self.get('createdConfigs').push(data.type);
+ },
+
+ error: function () {
+ self.setTasksStatus(2, 'FAILED');
+ },
+
+ statusCode: require('data/statusCodes')
+ });
+ },
+
+ loadGlobals: function () {
+ var globals = this.get('content.serviceConfigProperties').filterProperty('id', 'puppet var');
+ if (globals.someProperty('name', 'hive_database')) {
+ //TODO: Hive host depends on the type of db selected. Change puppet variable name if postgres is not the default db
+ var hiveDb = globals.findProperty('name', 'hive_database');
+ if (hiveDb.value === 'New MySQL Database') {
+ if (globals.someProperty('name', 'hive_ambari_host')) {
+ globals.findProperty('name', 'hive_ambari_host').name = 'hive_mysql_hostname';
+ }
+ globals = globals.without(globals.findProperty('name', 'hive_existing_host'));
+ globals = globals.without(globals.findProperty('name', 'hive_existing_database'));
+ } else {
+ globals.findProperty('name', 'hive_existing_host').name = 'hive_mysql_hostname';
+ globals = globals.without(globals.findProperty('name', 'hive_ambari_host'));
+ globals = globals.without(globals.findProperty('name', 'hive_ambari_database'));
+ }
+ }
+ this.set('globals', globals);
+ },
+
+ loadConfigs: function () {
+ var storedConfigs = this.get('content.serviceConfigProperties').filterProperty('id', 'site property').filterProperty('value');
+ var uiConfigs = this.loadUiSideConfigs();
+ this.set('configs', storedConfigs.concat(uiConfigs));
+ },
+
+ loadUiSideConfigs: function () {
+ var uiConfig = [];
+ var configs = this.get('configMapping').filterProperty('foreignKey', null);
+ configs.forEach(function (_config) {
+ var value = this.getGlobConfigValue(_config.templateName, _config.value, _config.name);
+ uiConfig.pushObject({
+ "id": "site property",
+ "name": _config.name,
+ "value": value,
+ "filename": _config.filename
+ });
+ }, this);
+ var dependentConfig = this.get('configMapping').filterProperty('foreignKey');
+ dependentConfig.forEach(function (_config) {
+ this.setConfigValue(uiConfig, _config);
+ uiConfig.pushObject({
+ "id": "site property",
+ "name": _config.name,
+ "value": _config.value,
+ "filename": _config.filename
+ });
+ }, this);
+ return uiConfig;
+ },
+
+ getGlobConfigValue: function (templateName, expression, name) {
+ var express = expression.match(/<(.*?)>/g);
+ var value = expression;
+ if (express == null) {
+ return expression;
+ }
+ express.forEach(function (_express) {
+ //console.log("The value of template is: " + _express);
+ var index = parseInt(_express.match(/\[([\d]*)(?=\])/)[1]);
+ if (this.get('globals').someProperty('name', templateName[index])) {
+ //console.log("The name of the variable is: " + this.get('content.serviceConfigProperties').findProperty('name', templateName[index]).name);
+ var globValue = this.get('globals').findProperty('name', templateName[index]).value;
+ // Hack for templeton.zookeeper.hosts
+ if (value !== null) { // if the property depends on more than one template name like <templateName[0]>/<templateName[1]> then don't proceed to the next if the prior is null or not found in the global configs
+ if (name === "templeton.zookeeper.hosts" || name === 'hbase.zookeeper.quorum') {
+ // globValue is an array of ZooKeeper Server hosts
+ var zooKeeperPort = '2181';
+ if (name === "templeton.zookeeper.hosts") {
+ var zooKeeperServers = globValue.map(function (item) {
+ return item + ':' + zooKeeperPort;
+ }).join(',');
+ value = value.replace(_express, zooKeeperServers);
+ } else {
+ value = value.replace(_express, globValue.join(','));
+ }
+ } else {
+ value = value.replace(_express, globValue);
+ }
+ }
+ } else {
+ /*
+ console.log("ERROR: The variable name is: " + templateName[index]);
+ console.log("ERROR: mapped config from configMapping file has no corresponding variable in " +
+ "content.serviceConfigProperties. Two possible reasons for the error could be: 1) The service is not selected. " +
+ "and/OR 2) The service_config metadata file has no corresponding global var for the site property variable");
+ */
+ value = null;
+ }
+ }, this);
+ return value;
+ },
+ /**
+ * Set all site property that are derived from other site-properties
+ */
+ setConfigValue: function (uiConfig, config) {
+ if (config.value == null) {
+ return;
+ }
+ var fkValue = config.value.match(/<(foreignKey.*?)>/g);
+ if (fkValue) {
+ fkValue.forEach(function (_fkValue) {
+ var index = parseInt(_fkValue.match(/\[([\d]*)(?=\])/)[1]);
+ if (uiConfig.someProperty('name', config.foreignKey[index])) {
+ var globalValue = uiConfig.findProperty('name', config.foreignKey[index]).value;
+ config.value = config.value.replace(_fkValue, globalValue);
+ } else if (this.get('content.serviceConfigProperties').someProperty('name', config.foreignKey[index])) {
+ var globalValue;
+ if (this.get('content.serviceConfigProperties').findProperty('name', config.foreignKey[index]).value === '') {
+ globalValue = this.get('content.serviceConfigProperties').findProperty('name', config.foreignKey[index]).defaultValue;
+ } else {
+ globalValue = this.get('content.serviceConfigProperties').findProperty('name', config.foreignKey[index]).value;
+ }
+ config.value = config.value.replace(_fkValue, globalValue);
+ }
+ }, this);
+ }
+ if (fkValue = config.name.match(/<(foreignKey.*?)>/g)) {
+ fkValue.forEach(function (_fkValue) {
+ var index = parseInt(_fkValue.match(/\[([\d]*)(?=\])/)[1]);
+ if (uiConfig.someProperty('name', config.foreignKey[index])) {
+ var globalValue = uiConfig.findProperty('name', config.foreignKey[index]).value;
+ config.name = config.name.replace(_fkValue, globalValue);
+ } else if (this.get('content.serviceConfigProperties').someProperty('name', config.foreignKey[index])) {
+ var globalValue;
+ if (this.get('content.serviceConfigProperties').findProperty('name', config.foreignKey[index]).value === '') {
+ globalValue = this.get('content.serviceConfigProperties').findProperty('name', config.foreignKey[index]).defaultValue;
+ } else {
+ globalValue = this.get('content.serviceConfigProperties').findProperty('name', config.foreignKey[index]).value;
+ }
+ config.name = config.name.replace(_fkValue, globalValue);
+ }
+ }, this);
+ }
+ //For properties in the configMapping file having foreignKey and templateName properties.
+
+ var templateValue = config.value.match(/<(templateName.*?)>/g);
+ if (templateValue) {
+ templateValue.forEach(function (_value) {
+ var index = parseInt(_value.match(/\[([\d]*)(?=\])/)[1]);
+ if (this.get('globals').someProperty('name', config.templateName[index])) {
+ var globalValue = this.get('globals').findProperty('name', config.templateName[index]).value;
+ config.value = config.value.replace(_value, globalValue);
+ } else {
+ config.value = null;
+ }
+ }, this);
+ }
+ },
+
+
+ /**
+ * override site properties with the entered key-value pair in *-site.xml
+ */
+ setCustomConfigs: function () {
+ var site = this.get('content.serviceConfigProperties').filterProperty('id', 'conf-site');
+ site.forEach(function (_site) {
+ var keyValue = _site.value.split(/\n+/);
+ if (keyValue) {
+ keyValue.forEach(function (_keyValue) {
+ _keyValue = _keyValue.trim();
+ console.log("The value of the keyValue is: " + _keyValue);
+ // split on the first = encountered (the value may contain ='s)
+ var matches = _keyValue.match(/^([^=]+)=(.*)$/);
+ if (matches) {
+ var key = matches[1];
+ var value = matches[2];
+ if (key) {
+ this.setSiteProperty(key, value, _site.name + '.xml');
+ }
+ }
+ }, this);
+ }
+ }, this);
+ },
+
+ /**
+ * Set property of the site variable
+ */
+ setSiteProperty: function (key, value, filename) {
+ this.get('configs').pushObject({
+ "id": "site property",
+ "name": key,
+ "value": value,
+ "filename": filename
+ });
+ },
+
+ createGlobalSiteObj: function () {
+ var globalSiteProperties = {};
+ //this.get('globals').filterProperty('domain', 'global').forEach(function (_globalSiteObj) {
+ this.get('globals').forEach(function (_globalSiteObj) {
+ // do not pass any globals whose name ends with _host or _hosts
+ if (!/_hosts?$/.test(_globalSiteObj.name)) {
+ // append "m" to JVM memory options except for hadoop_heapsize
+ if (/_heapsize|_newsize|_maxnewsize$/.test(_globalSiteObj.name) && _globalSiteObj.name !== 'hadoop_heapsize') {
+ globalSiteProperties[_globalSiteObj.name] = _globalSiteObj.value + "m";
+ } else {
+ globalSiteProperties[_globalSiteObj.name] = _globalSiteObj.value;
+ }
+ console.log("STEP8: name of the global property is: " + _globalSiteObj.name);
+ console.log("STEP8: value of the global property is: " + _globalSiteObj.value);
+ }
+ }, this);
+ return {"type": "global", "properties": globalSiteProperties};
+ },
+
+ createCoreSiteObj: function () {
+ var serviceName = this.get('service.serviceName');
+ var coreSiteObj = this.get('configs').filterProperty('filename', 'core-site.xml');
+ var coreSiteProperties = {};
+ // hadoop.proxyuser.oozie.hosts needs to be skipped if oozie is not selected
+ var isOozieSelected = serviceName == 'OOZIE';
+ var oozieUser = this.get('globals').someProperty('name', 'oozie_user') ? this.get('globals').findProperty('name', 'oozie_user').value : null;
+ var isHiveSelected = serviceName == 'HIVE';
+ var hiveUser = this.get('globals').someProperty('name', 'hive_user') ? this.get('globals').findProperty('name', 'hive_user').value : null;
+ var isHcatSelected = serviceName == 'WEBHCAT';
+ var hcatUser = this.get('globals').someProperty('name', 'hcat_user') ? this.get('globals').findProperty('name', 'hcat_user').value : null;
+ coreSiteObj.forEach(function (_coreSiteObj) {
+ if ((isOozieSelected || (_coreSiteObj.name != 'hadoop.proxyuser.' + oozieUser + '.hosts' && _coreSiteObj.name != 'hadoop.proxyuser.' + oozieUser + '.groups')) && (isHiveSelected || (_coreSiteObj.name != 'hadoop.proxyuser.' + hiveUser + '.hosts' && _coreSiteObj.name != 'hadoop.proxyuser.' + hiveUser + '.groups')) && (isHcatSelected || (_coreSiteObj.name != 'hadoop.proxyuser.' + hcatUser + '.hosts' && _coreSiteObj.name != 'hadoop.proxyuser.' + hcatUser + '.groups'))) {
+ coreSiteProperties[_coreSiteObj.name] = _coreSiteObj.value;
+ }
+ console.log("STEP*: name of the property is: " + _coreSiteObj.name);
+ console.log("STEP8: value of the property is: " + _coreSiteObj.value);
+ }, this);
+ return {"type": "core-site", "properties": coreSiteProperties};
+ },
+
+ createHdfsSiteObj: function () {
+ var hdfsSiteObj = this.get('configs').filterProperty('filename', 'hdfs-site.xml');
+ var hdfsProperties = {};
+ hdfsSiteObj.forEach(function (_configProperty) {
+ hdfsProperties[_configProperty.name] = _configProperty.value;
+ console.log("STEP*: name of the property is: " + _configProperty.name);
+ console.log("STEP8: value of the property is: " + _configProperty.value);
+ }, this);
+ return {"type": "hdfs-site", "properties": hdfsProperties };
+ },
+
+ createMrSiteObj: function () {
+ var configs = this.get('configs').filterProperty('filename', 'mapred-site.xml');
+ var mrProperties = {};
+ configs.forEach(function (_configProperty) {
+ mrProperties[_configProperty.name] = _configProperty.value;
+ console.log("STEP*: name of the property is: " + _configProperty.name);
+ console.log("STEP8: value of the property is: " + _configProperty.value);
+ }, this);
+ return {type: 'mapred-site', properties: mrProperties};
+ },
+
+ createHbaseSiteObj: function () {
+ var configs = this.get('configs').filterProperty('filename', 'hbase-site.xml');
+ var hbaseProperties = {};
+ configs.forEach(function (_configProperty) {
+ hbaseProperties[_configProperty.name] = _configProperty.value;
+ }, this);
+ return {type: 'hbase-site', properties: hbaseProperties};
+ },
+
+ createOozieSiteObj: function () {
+ var configs = this.get('configs').filterProperty('filename', 'oozie-site.xml');
+ var oozieProperties = {};
+ configs.forEach(function (_configProperty) {
+ oozieProperties[_configProperty.name] = _configProperty.value;
+ }, this);
+ return {type: 'oozie-site', properties: oozieProperties};
+ },
+
+ createHiveSiteObj: function () {
+ var configs = this.get('configs').filterProperty('filename', 'hive-site.xml');
+ var hiveProperties = {};
+ configs.forEach(function (_configProperty) {
+ hiveProperties[_configProperty.name] = _configProperty.value;
+ }, this);
+ return {type: 'hive-site', properties: hiveProperties};
+ },
+
+ createWebHCatSiteObj: function () {
+ var configs = this.get('configs').filterProperty('filename', 'webhcat-site.xml');
+ var webHCatProperties = {};
+ configs.forEach(function (_configProperty) {
+ webHCatProperties[_configProperty.name] = _configProperty.value;
+ }, this);
+ return {type: 'webhcat-site', properties: webHCatProperties};
+ },
+
+ applyConfigs: function () {
+ var self = this;
+ var configTags;
+ var clusterName = this.get('content.cluster.name');
+ var url = App.apiPrefix + '/clusters/' + clusterName + '/services/' + this.get('service.serviceName');
+ $.ajax({
+ type: 'GET',
+ url: url,
+ async: false,
+ timeout: 10000,
+ dataType: 'text',
+ success: function (data) {
+ var jsonData = jQuery.parseJSON(data);
+ configTags = jsonData.ServiceInfo.desired_configs;
+ },
+
+ error: function () {
+ self.setTasksStatus(3, 'FAILED');
+ },
+
+ statusCode: require('data/statusCodes')
+ });
+
+ if (!configTags) {
+ this.setTasksStatus(0, 'FAILED');
+ return;
+ }
+
+ for (var tag in configTags) {
+ if (this.get('createdConfigs').contains(tag)) {
+ configTags[tag] = this.get('newConfigsTag');
+ }
+ }
+ var data = {config: configTags};
+
+ $.ajax({
+ type: 'PUT',
+ url: url,
+ dataType: 'text',
+ data: JSON.stringify(data),
+ timeout: 5000,
+
+ beforeSend: function () {
+ self.setTasksStatus(3, 'PENDING');
+ },
+
+ success: function () {
+ self.setTasksStatus(3, 'COMPLETED');
+ },
+
+ error: function () {
+ self.setTasksStatus(3, 'FAILED');
+ },
+
+ statusCode: require('data/statusCodes')
+ });
+ },
+
+ putInMaintenanceMode: function () {
+ //todo after API providing
+ this.setTasksStatus(4, 'COMPLETED');
+ },
+
+ installComponent: function () {
+ var self = this;
+ var clusterName = this.get('content.cluster.name');
+ var url = App.apiPrefix + '/clusters/' + clusterName + '/host_components?HostRoles/state=INIT';
+ var data = '{"HostRoles": {"state": "INSTALLED"}}';
+ var method = 'PUT';
+ $.ajax({
+ type: method,
+ url: url,
+ data: data,
+ dataType: 'text',
+ timeout: App.timeout,
+
+ beforeSend: function () {
+ self.setTasksStatus(5, 'PENDING');
+ },
+
+ success: function (data) {
+ if (jQuery.parseJSON(data)) {
+ self.set('currentRequestId', jQuery.parseJSON(data).Requests.id);
+ self.getLogsByRequest();
+ } else {
+ self.setTasksStatus(5, 'FAILED');
+ }
+ },
+
+ error: function () {
+ self.setTasksStatus(5, 'FAILED');
+ },
+
+ statusCode: require('data/statusCodes')
+ });
+ },
+
+ startComponents: function () {
+ var self = this;
+ var clusterName = this.get('content.cluster.name');
+ var serviceName = this.get('masterComponent.service_id');
+ var url = App.apiPrefix + '/clusters/' + clusterName + '/services/' + serviceName;
+ var data = '{"ServiceInfo": {"state": "STARTED"}}';
+ var method = 'PUT';
+ $.ajax({
+ type: method,
+ url: url,
+ data: data,
+ dataType: 'text',
+ timeout: App.timeout,
+
+ beforeSend: function () {
+ self.setTasksStatus(6, 'PENDING');
+ },
+
+ success: function (data) {
+ if (jQuery.parseJSON(data)) {
+ self.set('currentRequestId', jQuery.parseJSON(data).Requests.id);
+ self.getLogsByRequest();
+ }
+ },
+
+ error: function () {
+ self.setTasksStatus(6, 'FAILED');
+ },
+
+ statusCode: require('data/statusCodes')
+ });
+ },
+
+ /**
+ * Parse logs to define status of Start, Stop ot Install task
+ * @param logs
+ */
+ parseLogs: function (logs) {
+ var self = this;
+ var task;
+ var stopPolling = false;
+ var starting = false;
+ var polledData = logs.tasks;
+ var status;
+ if ((this.get('tasks')[5].status != 'COMPLETED' && this.get('tasks')[6].status != 'COMPLETED' && this.get('tasks')[0].status != 'COMPLETED') ||
+ ((this.get('tasks')[5].status == 'COMPLETED') && this.get('tasks')[0].status == 'COMPLETED' && this.get('tasks')[6].status != 'COMPLETED')) {
+ //stopping or starting components
+ if (this.get('tasks')[0].status == 'COMPLETED') {
+ task = 6;
+ starting = true;
+ } else {
+ task = 0;
+ }
+ if (!polledData.someProperty('Tasks.status', 'PENDING') && !polledData.someProperty('Tasks.status', 'QUEUED') && !polledData.someProperty('Tasks.status', 'IN_PROGRESS')) {
+ if (polledData.someProperty('Tasks.status', 'FAILED')) {
+ this.setTasksStatus(task, 'FAILED');
+ status = 'FAILED'
+ } else {
+ this.setTasksStatus(task, 'COMPLETED');
+ status = 'COMPLETED';
+ }
+ stopPolling = true;
+ } else if (polledData.someProperty('Tasks.status', 'IN_PROGRESS')) {
+ var progress = polledData.filterProperty('Tasks.status', 'COMPLETED').length / polledData.length * 100;
+ this.setTasksStatus(task, 'IN_PROGRESS');
+ this.get('tasks')[task].set('progress', Math.round(progress));
+ }
+ } else {
+ //installing component
+ status = polledData[0].Tasks.status;
+ this.setTasksStatus(5, status);
+ if (status == 'IN_PROGRESS') {
+ this.get('tasks')[5].set('progress', '50');
+ }
+ if (status == 'COMPLETED' || status == 'FAILED') {
+ stopPolling = true;
+ }
+ }
+ if (!stopPolling) {
+ window.setTimeout(function () {
+ self.getLogsByRequest()
+ }, self.POLL_INTERVAL);
+ } else {
+ if (status == 'FAILED') {
+ //todo show retry
+ }
+ if (starting && status == 'COMPLETED') {
+ this.set('isSubmitDisabled', false);
+ }
+ }
+ },
+
+ POLL_INTERVAL: 4000,
+
+ getLogsByRequest: function () {
+ var self = this;
+ var clusterName = this.get('content.cluster.name');
+ var requestId = this.get('currentRequestId');
+ var url = App.apiPrefix + '/clusters/' + clusterName + '/requests/' + requestId + '?fields=tasks/*';
+ $.ajax({
+ type: 'GET',
+ url: url,
+ timeout: App.timeout,
+ dataType: 'text',
+ success: function (data) {
+ self.parseLogs(jQuery.parseJSON(data));
+ },
+
+ error: function () {
+ this.set('status', 'FAILED');
+ },
+
+ statusCode: require('data/statusCodes')
+ }).retry({times: App.maxRetries, timeout: App.timeout}).then(null,
+ function () {
+ App.showReloadPopup();
+ console.log('Install services all retries FAILED');
+ }
+ );
+ },
+
+ removeComponent: function () {
+ //todo after API providing
+ this.setTasksStatus(7, 'COMPLETED');
+ },
+
+ submit: function () {
+ if (!this.get('isSubmitDisabled')) {
+ App.router.send('next');
+ }
+ }
+})
Modified: incubator/ambari/trunk/ambari-web/app/messages.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/messages.js?rev=1456292&r1=1456291&r2=1456292&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/messages.js (original)
+++ incubator/ambari/trunk/ambari-web/app/messages.js Thu Mar 14 00:27:03 2013
@@ -413,6 +413,17 @@ Em.I18n.translations = {
'installer.step13.sourceHost':'Source Host:',
'installer.step13.changes':'Configs to change:',
'installer.step13.component':'Component name:',
+ 'installer.step14.task0':'{0} stop',
+ 'installer.step14.task1':'{0} create',
+ 'installer.step14.task2':'{0} configs create',
+ 'installer.step14.task3':'{0} configs apply',
+ 'installer.step14.task4':'{0} put in maintenance mode',
+ 'installer.step14.task5':'{0} install',
+ 'installer.step14.task6':'{0} start',
+ 'installer.step14.task7':'{0} remove',
+ 'installer.step14.status.success': 'Successfully reassigned {0}',
+ 'installer.step14.status.failed': 'Failed to reassign {0}',
+ 'installer.step14.status.info': 'Reassigning {0}. \nPlease wait while all tasks will be completed.',
'installer.stackUpgrade.header':'Stack Upgrade Wizard',
'installer.stackUpgrade.step1.newVersion':'New Version',
Modified: incubator/ambari/trunk/ambari-web/app/routes/reassign_master_routes.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/routes/reassign_master_routes.js?rev=1456292&r1=1456291&r2=1456292&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/routes/reassign_master_routes.js (original)
+++ incubator/ambari/trunk/ambari-web/app/routes/reassign_master_routes.js Thu Mar 14 00:27:03 2013
@@ -113,7 +113,7 @@ module.exports = Em.Route.extend({
}),
step4: Em.Route.extend({
- route: '/step3',
+ route: '/step4',
connectOutlets: function (router) {
console.log('in reassignMaster.step4:connectOutlets');
var controller = router.get('reassignMasterController');
@@ -125,6 +125,24 @@ module.exports = Em.Route.extend({
},
back: Em.Router.transitionTo('step3'),
next: function (router) {
+ router.transitionTo('step5');
+ }
+ }),
+
+ step5: Em.Route.extend({
+ route: '/step5',
+ connectOutlets: function (router) {
+ console.log('in reassignMaster.step5:connectOutlets');
+ var controller = router.get('reassignMasterController');
+ controller.setCurrentStep('5');
+ controller.dataLoading().done(function () {
+ controller.loadAllPriorSteps();
+ controller.connectOutlet('wizardStep14', controller.get('content'));
+ })
+ },
+ back: Em.Router.transitionTo('step3'),
+ next: function (router) {
+ //router.transitionTo('step6');
}
}),
Modified: incubator/ambari/trunk/ambari-web/app/styles/application.less
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/styles/application.less?rev=1456292&r1=1456291&r2=1456292&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/styles/application.less (original)
+++ incubator/ambari/trunk/ambari-web/app/styles/application.less Thu Mar 14 00:27:03 2013
@@ -399,6 +399,17 @@ h1 {
}
}
}
+ #step14 {
+ .item {
+ line-height: 30px;
+ i {
+ font-size: 20px;
+ }
+ }
+ .row {
+ margin-left: 0;
+ }
+ }
}
#stack-upgrade {
Modified: incubator/ambari/trunk/ambari-web/app/templates/main/service/reassign.hbs
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/templates/main/service/reassign.hbs?rev=1456292&r1=1456291&r2=1456292&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/templates/main/service/reassign.hbs (original)
+++ incubator/ambari/trunk/ambari-web/app/templates/main/service/reassign.hbs Thu Mar 14 00:27:03 2013
@@ -29,6 +29,7 @@
<li {{bindAttr class="isStep2:active view.isStep2Disabled:disabled"}}><a href="javascript:void(null);" {{action gotoStep2 target="controller"}}>{{t installer.step5.reassign.header}}</a></li>
<li {{bindAttr class="isStep3:active view.isStep3Disabled:disabled"}}><a href="javascript:void(null);" {{action gotoStep3 target="controller"}}>{{t installer.step12.header}}</a></li>
<li {{bindAttr class="isStep4:active view.isStep4Disabled:disabled"}}><a href="javascript:void(null);" {{action gotoStep4 target="controller"}}>{{t installer.step8.header}}</a></li>
+ <li {{bindAttr class="isStep5:active view.isStep5Disabled:disabled"}}><a href="javascript:void(null);" {{action gotoStep5 target="controller"}}>{{t installer.step9.header}}</a></li>
</ul>
</div>
</div>
Added: incubator/ambari/trunk/ambari-web/app/templates/wizard/step14.hbs
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/templates/wizard/step14.hbs?rev=1456292&view=auto
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/templates/wizard/step14.hbs (added)
+++ incubator/ambari/trunk/ambari-web/app/templates/wizard/step14.hbs Thu Mar 14 00:27:03 2013
@@ -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.
+}}
+<div id="step14">
+ <div {{bindAttr class="view.statusClass :alert"}}>{{view.statusMessage}}</div>
+ {{#each task in tasks}}
+ {{#view view.taskView contentBinding="task"}}
+ <div class="item">
+ <i {{bindAttr class="view.icon view.iconColor"}}></i>
+ <a href="javascript:void(0)">{{task.message}}</a>
+ </div>
+ <div {{bindAttr class="view.inProgress::hide :row :span12" }}>
+ <div class="progress-bar span4">
+ <div class="progress-striped active progress-info progress">
+ <div class="bar" {{bindAttr style="view.barWidth"}}></div>
+ </div>
+ </div>
+ <div class="span1">{{task.progress}}%</div>
+ </div>
+ {{/view}}
+ {{/each}}
+ </div>
+ <div class="btn-area">
+ <a class="btn btn-success pull-right" {{bindAttr disabled="controller.isSubmitDisabled"}} {{action submit target="controller"}}>{{t common.next}} →</a>
+</div>
Modified: incubator/ambari/trunk/ambari-web/app/views.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/views.js?rev=1456292&r1=1456291&r2=1456292&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/views.js (original)
+++ incubator/ambari/trunk/ambari-web/app/views.js Thu Mar 14 00:27:03 2013
@@ -134,6 +134,7 @@ require('views/wizard/step10_view');
require('views/wizard/step11_view');
require('views/wizard/step12_view');
require('views/wizard/step13_view');
+require('views/wizard/step14_view');
require('views/wizard/stack_upgrade/step1_view');
require('views/wizard/stack_upgrade/step2_view');
require('views/wizard/stack_upgrade/step3_view');
Added: incubator/ambari/trunk/ambari-web/app/views/wizard/step14_view.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/views/wizard/step14_view.js?rev=1456292&view=auto
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/views/wizard/step14_view.js (added)
+++ incubator/ambari/trunk/ambari-web/app/views/wizard/step14_view.js Thu Mar 14 00:27:03 2013
@@ -0,0 +1,91 @@
+/**
+ * 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.WizardStep14View = Em.View.extend({
+
+ templateName: require('templates/wizard/step14'),
+
+ statusMessage: null,
+ statusClass: 'alert-info',
+
+ didInsertElement: function () {
+ this.get('controller').loadStep();
+ },
+
+ tasks: function () {
+ return this.get('controller.tasks');
+ }.property('controller.tasks'),
+
+ onStatus: function () {
+ var master = this.get('controller.content.reassign.display_name');
+ switch (this.get('controller.status')) {
+ case 'COMPLETED':
+ this.set('statusMessage', Em.I18n.t('installer.step14.status.success').format(master));
+ this.set('statusClass', 'alert-success');
+ break;
+ case 'FAILED':
+ this.set('statusMessage', Em.I18n.t('installer.step14.status.failed').format(master));
+ this.set('statusClass', 'alert-error');
+ break;
+ case 'IN_PROGRESS':
+ default:
+ this.set('statusMessage', Em.I18n.t('installer.step14.status.info').format(master));
+ this.set('statusClass', 'alert-info');
+ }
+ }.observes('controller.status'),
+
+ taskView: Em.View.extend({
+ icon: '',
+ iconColor: '',
+
+ didInsertElement: function () {
+ this.onStatus();
+ },
+
+ barWidth: function () {
+ return 'width: ' + this.get('content.progress') + '%;';
+ }.property('content.progress'),
+
+ onStatus: function () {
+ if (this.get('content.status') === 'IN_PROGRESS') {
+ this.set('icon', 'icon-cog');
+ this.set('iconColor', 'text-info');
+ } else if (this.get('content.status') === 'WARNING') {
+ this.set('icon', 'icon-warning-sign');
+ this.set('iconColor', 'text-warning');
+ } else if (this.get('content.status') === 'FAILED') {
+ this.set('icon', 'icon-exclamation-sign');
+ this.set('iconColor', 'text-error');
+ } else if (this.get('content.status') === 'COMPLETED') {
+ this.set('icon', 'icon-ok');
+ this.set('iconColor', 'text-success');
+ } else {
+ this.set('icon', 'icon-cog');
+ this.set('iconColor', '');
+ }
+ }.observes('content.status'),
+
+ inProgress: function () {
+ return this.get('content.status') === "IN_PROGRESS";
+ }.property('content.status')
+
+ })
+});