diff options
author | Yusaku Sako <yusaku@apache.org> | 2012-12-09 15:23:01 +0000 |
---|---|---|
committer | Yusaku Sako <yusaku@apache.org> | 2012-12-09 15:23:01 +0000 |
commit | 9b15091e8f0ebae95f513fc27a4bf075bd052eda (patch) | |
tree | 11541a766b3b8dd419f0bffec6050c430b0aa81b /ambari-web | |
parent | 750bc81fc796b8b8bc348ea75336966f656de083 (diff) |
AMBARI-1059. Refactor cluster management. (yusaku)
git-svn-id: https://svn.apache.org/repos/asf/incubator/ambari/branches/AMBARI-666@1419009 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'ambari-web')
64 files changed, 1799 insertions, 786 deletions
diff --git a/ambari-web/app/assets/data/apps/runs.json b/ambari-web/app/assets/data/apps/runs.json index 6763e2bab6..e665a4eb89 100644 --- a/ambari-web/app/assets/data/apps/runs.json +++ b/ambari-web/app/assets/data/apps/runs.json @@ -53,7 +53,9 @@ } }, "workflowId": "hive_7c779523-6bca-416e-89b3-b01b73a60174", - "workflowName": "script1-hadoop.pig" + "workflowName": "script1-hadoop.pig", + "inputBytes": 473423, + "outputBytes": 82434 }, { "elapsedTime": 910360, @@ -84,7 +86,9 @@ } }, "workflowId": "pig_5750f4cf-f0d2-4e3d-a7ce-90912b309c12", - "workflowName": "script1-hadoop.pig" + "workflowName": "script1-hadoop.pig", + "inputBytes": 923423, + "outputBytes": 32434 }, { "elapsedTime": 920579, @@ -115,7 +119,9 @@ } }, "workflowId": "mr_25547729-88f9-4287-a45a-64901a82f22b", - "workflowName": "script1-hadoop.pig" + "workflowName": "script1-hadoop.pig", + "inputBytes": 623423, + "outputBytes": 42434 }, { "elapsedTime": 687631, @@ -138,7 +144,9 @@ } }, "workflowId": "hive_a5b9c06f-96d2-4ea8-80e0-3c063ae831d4", - "workflowName": "script2-hadoop.pig" + "workflowName": "script2-hadoop.pig", + "inputBytes": 483423, + "outputBytes": 82434 }, { "elapsedTime": 905375, @@ -169,7 +177,9 @@ } }, "workflowId": "pig_90ac94ff-20c4-4637-8b1c-51379cfe10df", - "workflowName": "script1-hadoop.pig" + "workflowName": "script1-hadoop.pig", + "inputBytes": 428423, + "outputBytes": 32434 }, { "elapsedTime": 683055, @@ -192,7 +202,9 @@ } }, "workflowId": "hive_c832f923-9bd4-421f-9a51-8f45991d91de", - "workflowName": "script2-hadoop.pig" + "workflowName": "script2-hadoop.pig", + "inputBytes": 723423, + "outputBytes": 62434 }, { "elapsedTime": 35150977, @@ -223,7 +235,9 @@ } }, "workflowId": "mr_a0aade31-47f8-475b-b887-60a79bcea5c4", - "workflowName": "script1-hadoop.pig" + "workflowName": "script1-hadoop.pig", + "inputBytes": 463423, + "outputBytes": 57434 }, { "elapsedTime": 888790, @@ -254,7 +268,9 @@ } }, "workflowId": "pig_b4365f79-18da-4db6-bbfd-e8a850d6c6e8", - "workflowName": "script1-hadoop.pig" + "workflowName": "script1-hadoop.pig", + "inputBytes": 723423, + "outputBytes": 82434 }, { "elapsedTime": 902653, @@ -285,7 +301,9 @@ } }, "workflowId": "hive_b6bf29a4-324f-4435-8ed3-bee10622ea48", - "workflowName": "script1-hadoop.pig" + "workflowName": "script1-hadoop.pig", + "inputBytes": 923423, + "outputBytes": 52434 }, { "elapsedTime": 884834, @@ -316,7 +334,9 @@ } }, "workflowId": "pig_a6a6fb32-b3fd-4427-ab54-449d0895fbb2", - "workflowName": "script1-hadoop.pig" + "workflowName": "script1-hadoop.pig", + "inputBytes": 403423, + "outputBytes": 82434 }, { "elapsedTime": 674392, @@ -339,7 +359,9 @@ } }, "workflowId": "pig_f69499b1-a504-433e-8904-0760deb5a183", - "workflowName": "script2-hadoop.pig" + "workflowName": "script2-hadoop.pig", + "inputBytes": 423123, + "outputBytes": 52434 }, { "elapsedTime": 926853, @@ -370,7 +392,9 @@ } }, "workflowId": "mr_73e04732-ea7f-43b8-9a2f-0f5a30e665da", - "workflowName": "script1-hadoop.pig" + "workflowName": "script1-hadoop.pig", + "inputBytes": 523423, + "outputBytes": 92434 }, { "elapsedTime": 0, @@ -401,7 +425,9 @@ } }, "workflowId": "pig_31b2111b-cc2e-4024-a8db-d181855a463f", - "workflowName": "script1-hadoop.pig" + "workflowName": "script1-hadoop.pig", + "inputBytes": 443423, + "outputBytes": 32434 }, { "elapsedTime": 670929, @@ -424,6 +450,8 @@ } }, "workflowId": "hive_097d0698-3620-4232-9c79-4deccbf6c98a", - "workflowName": "script2-hadoop.pig" + "workflowName": "script2-hadoop.pig", + "inputBytes": 428423, + "outputBytes": 18434 } ]}
\ No newline at end of file diff --git a/ambari-web/app/assets/data/wizard/bootstrap/single_host_information.json b/ambari-web/app/assets/data/wizard/bootstrap/single_host_information.json index eefe832f12..e3db291ddc 100644 --- a/ambari-web/app/assets/data/wizard/bootstrap/single_host_information.json +++ b/ambari-web/app/assets/data/wizard/bootstrap/single_host_information.json @@ -1,12 +1,70 @@ { - "href" : "http://localhost:8080/api/v1/hosts?fields=Hosts/total_mem,Hosts/cpu_count", - "items" : [ + "href": "http://localhost:8080/api/v1/hosts?fields=Hosts/total_mem,Hosts/cpu_count", + "items": [ { - "href" : "http://localhost:8080/api/v1/hosts/localhost.localdomain", - "Hosts" : { - "cpu_count" : 1, - "total_mem" : 4057989, - "host_name" : "localhost.localdomain" + "href": "http://localhost:8080/api/v1/hosts/localhost.localdomain", + "Hosts": { + "cpu_count": 1, + "total_mem": 4057989, + "host_name": "localhost.localdomain", + "disk_info": [ + { + "available": "47574176", + "used": "3507828", + "percent": "7%", + "size": "51606140", + "type": "ext4", + "mountpoint": "/" + }, + { + "available": "47574176", + "used": "3507828", + "percent": "7%", + "size": "51606140", + "type": "ext4", + "mountpoint": "/grid/0" + }, + { + "available": "1027204", + "used": "260", + "percent": "1%", + "size": "1027464", + "type": "tmpfs", + "mountpoint": "/dev/shm" + }, + { + "available": "432210", + "used": "38034", + "percent": "9%", + "size": "495844", + "type": "ext4", + "mountpoint": "/boot" + }, + { + "available": "44459872", + "used": "184220", + "percent": "1%", + "size": "47033288", + "type": "ext4", + "mountpoint": "/home" + }, + { + "available": "450200708", + "used": "281534268", + "percent": "39%", + "size": "731734976", + "type": "vboxsf", + "mountpoint": "/media/sf_ambari" + }, + { + "available": "450200708", + "used": "281534268", + "percent": "39%", + "size": "731734976", + "type": "vboxsf", + "mountpoint": "/host" + } + ] } } ] diff --git a/ambari-web/app/assets/img/spinner.gif b/ambari-web/app/assets/img/spinner.gif Binary files differnew file mode 100644 index 0000000000..39fcb67510 --- /dev/null +++ b/ambari-web/app/assets/img/spinner.gif diff --git a/ambari-web/app/controllers/application.js b/ambari-web/app/controllers/application.js index 08bde9a4fc..50dc017b6e 100644 --- a/ambari-web/app/controllers/application.js +++ b/ambari-web/app/controllers/application.js @@ -23,12 +23,12 @@ App.ApplicationController = Em.Controller.extend({ name: 'applicationController', clusterName: function () { - var name = App.db.getClusterName(); + var name = App.router.get('clusterController.clusterName'); if (name) { return name.capitalize(); } - return ''; - }.property(), + return Em.I18n.t('installer.header'); + }.property('App.router.clusterController.clusterName'), isClusterDataLoaded: function() { return App.router.get('clusterController.isLoaded'); }.property('App.router.clusterController.isLoaded'), diff --git a/ambari-web/app/controllers/global/background_operations_controller.js b/ambari-web/app/controllers/global/background_operations_controller.js index 28acac970d..374e96ddd0 100644 --- a/ambari-web/app/controllers/global/background_operations_controller.js +++ b/ambari-web/app/controllers/global/background_operations_controller.js @@ -28,6 +28,11 @@ App.BackgroundOperationsController = Em.Controller.extend({ allOperations: [], allOperationsCount : 0, + executeTasks: [], + + getTasksByRole: function (role) { + return this.get('allOperations').filterProperty('role', role); + }, getOperationsForRequestId: function(requestId){ return this.get('allOperations').filterProperty('request_id', requestId); @@ -129,45 +134,69 @@ App.BackgroundOperationsController = Em.Controller.extend({ }.observes('isWorking'), /** - * Add new operations to <code>this.allOperations</code> variable + * Update info about background operations + * Put all tasks with command 'EXECUTE' into <code>executeTasks</code>, other tasks with it they are still running put into <code>runningTasks</code> + * Put all task that should be shown in popup modal window into <code>this.allOperations</code> * @param data json loaded from server */ - updateBackgroundOperations : function(data){ + updateBackgroundOperations: function (data) { var runningTasks = []; + var executeTasks = this.get('executeTasks'); data.items.forEach(function (item) { item.tasks.forEach(function (task) { - if (task.Tasks.status == 'QUEUED' || task.Tasks.status == 'PENDING') { - runningTasks.push(task.Tasks); + if (task.Tasks.command == 'EXECUTE') { + if (!executeTasks.someProperty('id', task.Tasks.id)) { + executeTasks.push(task.Tasks); + } + } else { + if (task.Tasks.status == 'QUEUED' || task.Tasks.status == 'PENDING' || task.Tasks.status == 'IN_PROGRESS') { + runningTasks.push(task.Tasks); + } } }); }); - runningTasks = runningTasks.sort(function(a,b){ + for (var i = 0; i < executeTasks.length; i++) { + if (executeTasks[i].status == 'QUEUED' || executeTasks[i].status == 'PENDING' || executeTasks[i].status == 'IN_PROGRESS') { + var url = App.testMode ? '/data/background_operations/list_on_start.json' : + App.apiPrefix + '/clusters/' + App.router.getClusterName() + '/requests/' + executeTasks[i].request_id + '/tasks/' + executeTasks[i].id; + var j = i; + $.ajax({ + type: "GET", + url: url, + dataType: 'json', + timeout: App.timeout, + success: function (data) { + if (data) { + executeTasks[j] = data.Tasks; + } + }, + error: function () { + console.log('ERROR: error during executeTask update'); + }, + + statusCode: require('data/statusCodes') + }); + } + } + ; + var currentTasks; + currentTasks = runningTasks.concat(executeTasks); + currentTasks = currentTasks.sort(function (a, b) { return a.id - b.id; }); - var currentTasks = this.get('allOperations'); - - runningTasks.forEach(function(item){ - var task = currentTasks.findProperty('id', item.id); - if(task){ - currentTasks[currentTasks.indexOf(task)] = item; - } else { - currentTasks.pushObject(item); + this.get('allOperations').filterProperty('isOpen').mapProperty('id').forEach(function(id){ + if (currentTasks.someProperty('id', id)) { + currentTasks.findProperty('id', id).isOpen = true; } }); - for(var i = currentTasks.length-1; i>=0; i--){ - var isTaskFinished = !runningTasks.someProperty('id', currentTasks[i].id); - if(isTaskFinished){ - currentTasks.removeAt(i); - } - } - - this.set('allOperationsCount', currentTasks.length); + this.set('allOperations', currentTasks); + this.set('allOperationsCount', runningTasks.length + executeTasks.filterProperty('status', 'PENDING').length + executeTasks.filterProperty('status', 'QUEUED').length + executeTasks.filterProperty('status', 'IN_PROGRESS').length); var eventsArray = this.get('eventsArray'); - if(eventsArray.length){ + if (eventsArray.length) { var itemsToRemove = []; eventsArray.forEach(function(item){ @@ -190,6 +219,7 @@ App.BackgroundOperationsController = Em.Controller.extend({ * Onclick handler for background operations number located right to logo */ showPopup: function(){ + this.set('executeTasks', []); this.loadOperations(); App.ModalPopup.show({ headerClass: Ember.View.extend({ diff --git a/ambari-web/app/controllers/installer.js b/ambari-web/app/controllers/installer.js index f1e627a71b..9498b50ea3 100644 --- a/ambari-web/app/controllers/installer.js +++ b/ambari-web/app/controllers/installer.js @@ -38,38 +38,8 @@ App.InstallerController = App.WizardController.extend({ controllerName: 'installerController' }), - /** - * Load clusterInfo(step1) to model - */ - loadClusterInfo: function () { - var cStatus = App.db.getClusterStatus() || {status: "", isCompleted: false}; - var cluster = { - name: App.db.getClusterName() || "", - status: cStatus.status, - isCompleted: cStatus.isCompleted, - requestId: cStatus.requestId, - installStartTime: cStatus.installStartTime, - installTime: cStatus.installTime - }; - this.set('content.cluster', cluster); - - console.log("InstallerController:loadClusterInfo: loaded data ", cluster); - }, - - /** - * Save all info about cluster to model - * @param stepController Step1WizardController - */ - saveClusterInfo: function (stepController) { - var cluster = stepController.get('content.cluster'); - var clusterStatus = { - status: cluster.status, - isCompleted: cluster.isCompleted - }; - App.db.setClusterName(cluster.name); - App.db.setClusterStatus(clusterStatus); - - console.log("InstallerController:saveClusterInfo: saved data ", cluster); + getCluster: function(){ + return jQuery.extend(this.get('clusterStatusTemplate'), {}); }, /** @@ -95,7 +65,7 @@ App.InstallerController = App.WizardController.extend({ //TODO : rewire it as model. or not :) var hostsInfo = Em.Object.create(); - hostsInfo.hostNames = App.db.getAllHostNames() || ''; //empty string if undefined + hostsInfo.hostNames = App.db.getAllHostNamesPattern() || ''; //empty string if undefined //TODO : should we check installType for add host wizard???? var installType = App.db.getInstallType(); @@ -128,7 +98,8 @@ App.InstallerController = App.WizardController.extend({ //TODO: put data to content.hosts and only then save it) //App.db.setBootStatus(false); - App.db.setAllHostNames(stepController.get('hostNames')); + App.db.setAllHostNames(stepController.get('hostNameArr').join("\n")); + App.db.setAllHostNamesPattern(stepController.get('hostNames')); App.db.setBootRequestId(stepController.get('bootRequestId')); App.db.setHosts(stepController.getHostInfo()); if (stepController.get('manualInstall') === false) { @@ -164,6 +135,7 @@ App.InstallerController = App.WizardController.extend({ name: _host.name, cpu: _host.cpu, memory: _host.memory, + disk_info: _host.disk_info, bootStatus: _host.bootStatus, isInstalled: false }; @@ -361,7 +333,7 @@ App.InstallerController = App.WizardController.extend({ _content.get('configs').forEach(function (_configProperties) { var displayType = _configProperties.get('displayType'); if (displayType === 'directories' || displayType === 'directory') { - var value = _configProperties.get('value').split(/\s+/g).join(','); + var value = _configProperties.get('value').trim().split(/\s+/g).join(','); _configProperties.set('value', value); } var configProperty = { @@ -370,6 +342,7 @@ App.InstallerController = App.WizardController.extend({ value: _configProperties.get('value'), defaultValue: _configProperties.get('defaultValue'), service: _configProperties.get('serviceName'), + domain: _configProperties.get('domain'), filename: _configProperties.get('filename') }; serviceConfigProperties.push(configProperty); @@ -386,12 +359,17 @@ App.InstallerController = App.WizardController.extend({ var slaveCategory = _content.get('configCategories').findProperty('isForSlaveComponent', true); slaveCategory.get('slaveConfigs.groups').forEach(function (_group) { _group.get('properties').forEach(function (_property) { + var displayType = _property.get('displayType'); + if (displayType === 'directories' || displayType === 'directory') { + var value = _property.get('value').trim().split(/\s+/g).join(','); + _property.set('value', value); + } _property.set('storeValue', _property.get('value')); }, this); }, this); slaveConfigProperties.pushObject(slaveCategory.get('slaveConfigs')); } - }, this) + }, this); App.db.setSlaveProperties(slaveConfigProperties); this.set('content.slaveGroupProperties', slaveConfigProperties); }, @@ -492,7 +470,7 @@ App.InstallerController = App.WizardController.extend({ case '2': this.loadInstallOptions(); case '1': - this.loadClusterInfo(); + this.load('cluster'); } }, @@ -609,49 +587,20 @@ App.InstallerController = App.WizardController.extend({ return serviceComponents; }, - - /* - Bootstrap selected hosts. - */ - launchBootstrap: function (bootStrapData) { - var self = this; - var requestId = null; - var method = App.testMode ? 'GET' : 'POST'; - var url = App.testMode ? '/data/wizard/bootstrap/bootstrap.json' : App.apiPrefix + '/bootstrap'; - $.ajax({ - type: method, - url: url, - async: false, - data: bootStrapData, - timeout: App.timeout, - contentType: 'application/json', - success: function (data) { - console.log("TRACE: POST bootstrap succeeded"); - requestId = data.requestId; - }, - error: function () { - console.log("ERROR: POST bootstrap failed"); - alert('Bootstrap call failed. Please try again.'); - }, - statusCode: require('data/statusCodes') - }); - return requestId; - }, - - /** * Clear all temporary data */ finish: function () { - this.setCurrentStep('1', false); + this.setCurrentStep('1'); App.db.setService(undefined); //not to use this data at AddService page App.db.setHosts(undefined); App.db.setMasterComponentHosts(undefined); App.db.setSlaveComponentHosts(undefined); - App.db.setClusterStatus(undefined); + App.db.setCluster(undefined); App.db.setAllHostNames(undefined); + App.db.setSlaveProperties(undefined); + App.db.setSshKey(undefined); } -}) -; +}); diff --git a/ambari-web/app/controllers/main.js b/ambari-web/app/controllers/main.js index 5891d3b820..2f407b7b0e 100644 --- a/ambari-web/app/controllers/main.js +++ b/ambari-web/app/controllers/main.js @@ -22,13 +22,25 @@ require('models/background_operation'); App.MainController = Em.Controller.extend({ name: 'mainController', clusterName: function () { - var name = App.db.getClusterName(); + var name = App.router.get('clusterController.clusterName'); if (name) { var displayName = name.length > 13 ? name.substr(0, 10) + "..." : name; return displayName.capitalize(); } - return ''; - }.property(), + return 'My Cluster'; + }.property('App.router.clusterController.clusterName'), + + updateTitle: function(){ + var name = App.router.get('clusterController.clusterName'); + if (name) { + name = name.length > 13 ? name.substr(0, 10) + "..." : name; + name = name.capitalize(); + } else{ + name = 'Loading'; + } + $('title').text('Ambari - ' + name); + }.observes('App.router.clusterController.clusterName'), + isClusterDataLoaded: function(){ return App.router.get('clusterController.isLoaded'); }.property('App.router.clusterController.isLoaded'), @@ -40,7 +52,6 @@ App.MainController = Em.Controller.extend({ App.router.get('clusterController').loadClusterData(); App.router.get('updateController').updateServiceMetric(); setInterval( this.updateAll , App.contentUpdateInterval); - $('title').text('Ambari - ' + this.get('clusterName')); }, updateAll: function(){ App.router.get('updateController').updateAll(); diff --git a/ambari-web/app/controllers/main/host/add_controller.js b/ambari-web/app/controllers/main/host/add_controller.js index 23a8ad9bcc..19813685cf 100644 --- a/ambari-web/app/controllers/main/host/add_controller.js +++ b/ambari-web/app/controllers/main/host/add_controller.js @@ -54,24 +54,10 @@ App.AddHostController = App.WizardController.extend({ isWizard: true }), - /** - * Load clusterInfo(step1) to model - */ - loadClusterInfo: function () { - var cluster = App.db.getClusterStatus(); - if (!cluster) { - cluster = { - name: App.router.getClusterName(), - status: undefined, - isCompleted: false, - requestId: undefined, - installStartTime: undefined, - installTime: undefined - }; - App.db.setClusterStatus(cluster); - } - this.set('content.cluster', cluster); - console.log("AddHostController:loadClusterInfo: loaded data ", cluster); + getCluster: function(){ + return jQuery.extend(this.get('clusterStatusTemplate'), { + name: App.router.getClusterName() + }); }, showMoreHosts: function () { @@ -149,7 +135,7 @@ App.AddHostController = App.WizardController.extend({ hostsInfo.showMoreHostsText = "...and %@ more".fmt(moreHostNames.length); } - hostsInfo.hostNames = App.db.getAllHostNames() || ''; //empty string if undefined + hostsInfo.hostNames = App.db.getAllHostNamesPattern() || ''; //empty string if undefined var installType = App.db.getInstallType(); //false if installType not equals 'manual' @@ -164,6 +150,7 @@ App.AddHostController = App.WizardController.extend({ hostsInfo.localRepoPath = ''; } + hostsInfo.bootRequestId = App.db.getBootRequestId() || null; hostsInfo.sshKey = ''; hostsInfo.passphrase = ''; hostsInfo.confirmPassphrase = ''; @@ -180,7 +167,9 @@ App.AddHostController = App.WizardController.extend({ //TODO: put data to content.hosts and only then save it) //App.db.setBootStatus(false); - App.db.setAllHostNames(stepController.get('hostNames')); + App.db.setAllHostNames(stepController.get('hostNameArr').join("\n")); + App.db.setAllHostNamesPattern(stepController.get('hostNames')); + App.db.setBootRequestId(stepController.get('bootRequestId')); App.db.setHosts(stepController.getHostInfo()); if (stepController.get('manualInstall') === false) { App.db.setInstallType({installType: 'ambari' }); @@ -559,7 +548,7 @@ App.AddHostController = App.WizardController.extend({ case '1': this.loadInstallOptions(); case '0': - this.loadClusterInfo(); + this.load('cluster'); } }, @@ -625,12 +614,12 @@ App.AddHostController = App.WizardController.extend({ * Clear all temporary data */ finish: function () { - this.setCurrentStep('1', false); + this.setCurrentStep('1'); App.db.setService(undefined); //not to use this data at AddService page App.db.setHosts(undefined); App.db.setMasterComponentHosts(undefined); App.db.setSlaveComponentHosts(undefined); - App.db.setClusterStatus(undefined); + App.db.setCluster(undefined); App.router.get('updateController').updateAll(); } diff --git a/ambari-web/app/controllers/main/service/add_controller.js b/ambari-web/app/controllers/main/service/add_controller.js index 56c18e00c2..cab97110c6 100644 --- a/ambari-web/app/controllers/main/service/add_controller.js +++ b/ambari-web/app/controllers/main/service/add_controller.js @@ -54,21 +54,10 @@ App.AddServiceController = App.WizardController.extend({ isWizard: true }), - /** - * Load clusterInfo(step1) to model - */ - loadClusterInfo: function(){ - var cluster = App.db.getClusterStatus(); - if(!cluster){ - cluster = { - name: App.router.getClusterName(), - status: "", - isCompleted: false - }; - App.db.setClusterStatus(cluster); - } - this.set('content.cluster', cluster); - console.log("AddServiceController:loadClusterInfo: loaded data ", cluster); + getCluster: function(){ + return jQuery.extend(this.get('clusterStatusTemplate'), { + name: App.router.getClusterName() + }); }, /** @@ -462,7 +451,7 @@ App.AddServiceController = App.WizardController.extend({ case '7': case '6': case '5': - this.loadClusterInfo(); + this.load('cluster'); case '4': this.loadServiceConfigProperties(); case '3': @@ -539,12 +528,12 @@ App.AddServiceController = App.WizardController.extend({ * Clear all temporary data */ finish: function(){ - this.setCurrentStep('1', false); + this.setCurrentStep('1'); App.db.setService(undefined); //not to use this data at AddService page App.db.setHosts(undefined); App.db.setMasterComponentHosts(undefined); App.db.setSlaveComponentHosts(undefined); - App.db.setClusterStatus(undefined); + App.db.setCluster(undefined); App.db.setAllHostNames(undefined); } diff --git a/ambari-web/app/controllers/wizard.js b/ambari-web/app/controllers/wizard.js index 0221e9a984..8a8923f806 100644 --- a/ambari-web/app/controllers/wizard.js +++ b/ambari-web/app/controllers/wizard.js @@ -220,15 +220,29 @@ App.WizardController = Em.Controller.extend({ App.db.setAllHostNames(null); }, + toObject: function(object){ + var result = {}; + for(var i in object){ + if(object.hasOwnProperty(i)){ + result[i] = object[i]; + } + } + return result; + }, + /** * save status of the cluster. This is called from step8 and step9 to persist install and start requestId * @param clusterStatus object with status, isCompleted, requestId, isInstallError and isStartError field. */ saveClusterStatus: function (clusterStatus) { - clusterStatus.name = this.get('content.cluster.name'); + var oldStatus = this.toObject(this.get('content.cluster')); + clusterStatus = jQuery.extend(oldStatus, clusterStatus); + if(clusterStatus.requestId && + clusterStatus.oldRequestsId.indexOf(clusterStatus.requestId) === -1){ + clusterStatus.oldRequestsId.push(clusterStatus.requestId); + } this.set('content.cluster', clusterStatus); - console.log(this.get('name') + '.saveClusterStatus: ' + JSON.stringify(clusterStatus)); - App.db.setClusterStatus(clusterStatus); + this.save('cluster'); }, /** @@ -242,7 +256,7 @@ App.WizardController = Em.Controller.extend({ var self = this; var clusterName = this.get('content.cluster.name'); - var url = (App.testMode) ? '/data/wizard/deploy/poll_1.json' : App.apiPrefix + '/clusters/' + clusterName + '/services?ServiceInfo/state=INIT'; + var url = (App.testMode) ? '/data/wizard/deploy/2_hosts/poll_1.json' : App.apiPrefix + '/clusters/' + clusterName + '/services?ServiceInfo/state=INIT'; var method = (App.testMode) ? 'GET' : 'PUT'; var data = '{"ServiceInfo": {"state": "INSTALLED"}}'; $.ajax({ @@ -258,7 +272,7 @@ App.WizardController = Em.Controller.extend({ console.log("TRACE: In success function for the installService call"); console.log("TRACE: value of the url is: " + url); if (jsonData) { - var requestId = jsonData.href.match(/.*\/(.*)$/)[1]; + var requestId = jsonData.Requests.id; console.log('requestId is: ' + requestId); var clusterStatus = { status: 'PENDING', @@ -292,13 +306,70 @@ App.WizardController = Em.Controller.extend({ }, + /* + Bootstrap selected hosts. + */ + launchBootstrap: function (bootStrapData) { + var self = this; + var requestId = null; + var method = App.testMode ? 'GET' : 'POST'; + var url = App.testMode ? '/data/wizard/bootstrap/bootstrap.json' : App.apiPrefix + '/bootstrap'; + $.ajax({ + type: method, + url: url, + async: false, + data: bootStrapData, + timeout: App.timeout, + contentType: 'application/json', + success: function (data) { + console.log("TRACE: POST bootstrap succeeded"); + requestId = data.requestId; + }, + error: function () { + console.log("ERROR: POST bootstrap failed"); + alert('Bootstrap call failed. Please try again.'); + }, + statusCode: require('data/statusCodes') + }); + return requestId; + }, + + /** + * Load <code>content.<name></code> variable from localStorage, if wasn't loaded before. + * If you specify <code>reload</code> to true - it will reload it. + * @param name + * @param reload + * @return {Boolean} + */ load: function (name, reload) { if (this.get('content.' + name) && !reload) { return false; } - var result = App.db['get' + name.capitalize()]; - if (!result) result = this['get' + name.capitalize()]; + var result = App.db['get' + name.capitalize()](); + if (!result){ + result = this['get' + name.capitalize()](); + App.db['set' + name.capitalize()](result); + console.log(this.get('name') + ": created " + name, result); + } this.set('content.' + name, result); - console.log("Installer controller: loaded" + name, result); + console.log(this.get('name') + ": loaded " + name, result); + }, + + save: function(name){ + var value = this.toObject(this.get('content.' + name)); + App.db['set' + name.capitalize()](value); + console.log(this.get('name') + ": saved " + name, value); + }, + + clusterStatusTemplate : { + name: "", + status: "PENDING", + isCompleted: false, + requestId: null, + installStartTime: null, + installTime: null, + isInstallError: false, + isStartError: false, + oldRequestsId: [] } }) diff --git a/ambari-web/app/controllers/wizard/slave_component_groups_controller.js b/ambari-web/app/controllers/wizard/slave_component_groups_controller.js index 4d1fbcae7c..7668d805ba 100644 --- a/ambari-web/app/controllers/wizard/slave_component_groups_controller.js +++ b/ambari-web/app/controllers/wizard/slave_component_groups_controller.js @@ -47,10 +47,14 @@ App.SlaveComponentGroupsController = Em.ArrayController.extend({ var categoryConfig = _serviceConfig.get('configCategories'); if (categoryConfig.someProperty('isForSlaveComponent', true)) { var slaveCategory = categoryConfig.findProperty('isForSlaveComponent', true); + // this.get('content') -> Output of Step 6: Mapping of each slave component and set of hosts it runs on if (this.get('content')) { if (this.get('content').someProperty('componentName', slaveCategory.get('primaryName'))) { + // component --> each column in Step 6 is a component ( slave component ) var component = this.get('content').findProperty('componentName', slaveCategory.get('primaryName')); + // slaveConfigs --> originally set as null in the class App.SlaveCategory in model/service_config.js var slaveConfigs = slaveCategory.get('slaveConfigs'); + slaveCategory.set('slaveConfigs', App.SlaveConfigs.create(component)); var slaveGroups = []; if (component.groups) { @@ -77,6 +81,7 @@ App.SlaveComponentGroupsController = Em.ArrayController.extend({ }, this); }, + // returns key-value pairs i.e. all fields for slave component for this specific service. componentProperties: function (serviceName) { var serviceConfigs = require('data/service_configs').findProperty('serviceName', serviceName); @@ -96,6 +101,15 @@ App.SlaveComponentGroupsController = Em.ArrayController.extend({ var slaveConfigs = serviceConfigs.configs.filterProperty('category', componentName); slaveConfigs.forEach(function (_serviceConfigProperty) { var serviceConfigProperty = App.ServiceConfigProperty.create(_serviceConfigProperty); + + switch(serviceConfigProperty.name){ + case 'dfs_data_dir' : + serviceConfigProperty.initialValue(); + break; + case 'mapred_local_dir' : + serviceConfigProperty.initialValue(); + break; + } configs.pushObject(serviceConfigProperty); serviceConfigProperty.validate(); }, this); diff --git a/ambari-web/app/controllers/wizard/step10_controller.js b/ambari-web/app/controllers/wizard/step10_controller.js index a1c0997a2e..f05a5e0a2c 100644 --- a/ambari-web/app/controllers/wizard/step10_controller.js +++ b/ambari-web/app/controllers/wizard/step10_controller.js @@ -115,11 +115,11 @@ App.WizardStep10Controller = Em.Controller.extend({ var timedOutTasks = _host.tasks.filterProperty('Tasks.status', 'TIMEDOUT'); timedOutTasks.forEach(function (_task) { - var abortStatement = clusterState + App.format.role(_task.Tasks.role) + ' timed out on ' + _host.name; + var timedOutStatement = clusterState + App.format.role(_task.Tasks.role) + ' timed out on ' + _host.name; this.get('clusterInfo').findProperty('id', 1).get('status').findProperty('id', 2).get('statements').pushObject(Ember.Object.create({ status: 'timedout', color: 'text-info', - displayStatement: timedOutTasks + displayStatement: timedOutStatement })); }, this); }, this); diff --git a/ambari-web/app/controllers/wizard/step1_controller.js b/ambari-web/app/controllers/wizard/step1_controller.js index 6cfac60f6b..bfb32096fd 100644 --- a/ambari-web/app/controllers/wizard/step1_controller.js +++ b/ambari-web/app/controllers/wizard/step1_controller.js @@ -21,31 +21,15 @@ var App = require('app'); App.WizardStep1Controller = Em.Controller.extend({ name: 'wizardStep1Controller', - clusterName: function(){ - return this.get('content.cluster.name'); - }.property('content.cluster.name'), - - hasSubmitted : false, - clearStep: function() { - this.set('content.cluster.name',''); - }, - loadStep: function () { - var clusterName; this.set('hasSubmitted',false); - console.log('The value of the cluster name is: ' + App.db.getClusterName()); - if (App.db.getClusterName() !== undefined) { - this.set('clusterName', App.db.getClusterName()); - } else { - this.set('clusterNameError',''); - this.set('invalidClusterName',true); - } }, invalidClusterName : function(){ if(!this.get('hasSubmitted')){ + this.set('clusterNameError', ''); return false; } @@ -76,8 +60,8 @@ App.WizardStep1Controller = Em.Controller.extend({ submit: function () { this.set('hasSubmitted', true); if (!this.get('invalidClusterName')) { - this.set('content.cluster',{name: this.get('clusterName'), status: 'PENDING', isCompleted: false}); - // App.router.get('installerController').saveClusterStatus({status: 'PENDING', isCompleted: false}); + this.set('content.cluster.status', 'PENDING'); + this.set('content.cluster.isCompleted', false); App.router.send('next'); } } diff --git a/ambari-web/app/controllers/wizard/step2_controller.js b/ambari-web/app/controllers/wizard/step2_controller.js index 5dca8551de..8533717191 100644 --- a/ambari-web/app/controllers/wizard/step2_controller.js +++ b/ambari-web/app/controllers/wizard/step2_controller.js @@ -21,32 +21,33 @@ var App = require('app'); App.WizardStep2Controller = Em.Controller.extend({ name: 'wizardStep2Controller', hostNameArr: [], + isPattern: false, bootRequestId: null, hasSubmitted: false, hostNames: function () { - return this.get('content.hostNames'); - }.property('content.hostNames'), + return this.get('content.hosts.hostNames'); + }.property('content.hosts.hostNames'), manualInstall: function () { - return this.get('content.manualInstall'); - }.property('content.manualInstall'), + return this.get('content.hosts.manualInstall'); + }.property('content.hosts.manualInstall'), localRepo: function () { - return this.get('content.localRepo'); - }.property('content.localRepo'), + return this.get('content.hosts.localRepo'); + }.property('content.hosts.localRepo'), sshKey: function () { - return this.get('content.sshKey'); - }.property('content.sshKey'), + return this.get('content.hosts.sshKey'); + }.property('content.hosts.sshKey'), passphrase: function () { - return this.get('content.passphrase'); - }.property('content.passphrase'), + return this.get('content.hosts.passphrase'); + }.property('content.hosts.passphrase'), confirmPassphrase: function () { - return this.get('content.confirmPassphrase'); - }.property('content.confirmPassphrase'), + return this.get('content.hosts.confirmPassphrase'); + }.property('content.hosts.confirmPassphrase'), installType: function () { if (this.get('manualInstall') === true) { @@ -98,7 +99,7 @@ App.WizardStep2Controller = Em.Controller.extend({ hostInfo[hostNameArr[i]] = { name: hostNameArr[i], installType: this.get('installType'), - bootStatus: 'pending' + bootStatus: 'PENDING' }; } @@ -117,6 +118,45 @@ App.WizardStep2Controller = Em.Controller.extend({ return false; } + if(this.isPattern) + { + this.hostNamePatternPopup(this.hostNameArr); + return false; + } + + this.proceedNext(); + + }, + + patternExpression: function(){ + var self = this; + var hostNames = []; + $.each(this.hostNameArr, function(e,a){ + var start, end, extra = ""; + if(/\[\d*\-\d*\]/.test(a)){ + start=a.match(/\[\d*/); + end=a.match(/\-\d*/); + start=start[0].substr(1); + end=end[0].substr(1); + + if(parseInt(start) <= parseInt(end) && parseInt(start) >= 0){ + self.isPattern = true; + if(start[0] == "0" && start.length > 1) + { + extra = start[0]; + } + for (var i = parseInt(start); i < parseInt(end) + 1; i++) { + hostNames.push(a.replace(/\[\d*\-\d*\]/, extra+i )) + } + } + }else{ + hostNames.push(a); + } + }); + this.hostNameArr = hostNames; + }, + + proceedNext: function(){ if (this.get('manualInstall') === true) { this.manualInstallPopup(); return false; @@ -129,13 +169,28 @@ App.WizardStep2Controller = Em.Controller.extend({ return true; } - var requestId = App.get('router.installerController').launchBootstrap(bootStrapData); + var requestId = App.router.get(this.get('content.controllerName')).launchBootstrap(bootStrapData); if(requestId) { - this.set('bootRequestId',requestId); - App.router.send('next'); + this.set('bootRequestId',requestId); + App.router.send('next'); } }, + hostNamePatternPopup: function (hostNames) { + var self = this; + App.ModalPopup.show({ + header: Em.I18n.t('installer.step2.hostName.pattern.header'), + onPrimary: function () { + self.proceedNext(); + this.hide(); + }, + bodyClass: Ember.View.extend({ + template: Ember.Handlebars.compile(['{{#each host in view.hostNames}}<p>{{host}}</p>{{/each}}'].join('\n')), + hostNames: hostNames + }) + }); + }, + manualInstallPopup: function (event) { App.ModalPopup.show({ header: Em.I18n.t('installer.step2.manualInstall.popup.header'), diff --git a/ambari-web/app/controllers/wizard/step3_controller.js b/ambari-web/app/controllers/wizard/step3_controller.js index fe1d6da1ef..da8fcbff67 100644 --- a/ambari-web/app/controllers/wizard/step3_controller.js +++ b/ambari-web/app/controllers/wizard/step3_controller.js @@ -23,10 +23,47 @@ App.WizardStep3Controller = Em.Controller.extend({ hosts: [], content: [], bootHosts: [], - maxRegistrationAttempts: 20, - registrationAttempts: null, + registrationStartedAt: null, + registrationTimeoutSecs: 120, isSubmitDisabled: true, - categories: ['All Hosts', 'Success', 'Installing', 'Registering', 'Failed'], + hostStatusString: Em.I18n.t('installer.step3.hosts.summary'), + hostStatusSummary: function () { + var self = this; + return this.get('hostStatusString').fmt(self.getCategory('value', 'Installing').get('hostsCount'), + self.getCategory('value', 'Registering').get('hostsCount'), + self.getCategory('value', 'Success').get('hostsCount'), + self.getCategory('value', 'Failed').get('hostsCount')); + + }.property('categories.@each.hostsCount'), + categoryObject: Em.Object.extend({ + hostsCount: function () { + var category = this; + var hosts = this.get('controller.hosts').filterProperty('bootStatus', category.get('hostsBootStatus')); + return hosts.get('length'); + }.property('controller.hosts.@each.bootStatus'), // 'hosts.@each.bootStatus' + label: function () { + return "%@ (%@)".fmt(this.get('value'), this.get('hostsCount')); + }.property('value', 'hostsCount') + }), + getCategory: function(field, value){ + return this.get('categories').find(function(item){ + return item.get(field) == value; + }); + }, + categories: function () { + var self = this; + self.categoryObject.reopen({ + controller: self + }); + + return [ + self.categoryObject.create({value: 'All Hosts', hostsCount: function () { return this.get('controller.hosts.length'); }.property('controller.hosts.length') }), + self.categoryObject.create({value: 'Success', hostsBootStatus: 'REGISTERED' }), + self.categoryObject.create({value: 'Installing', hostsBootStatus: 'RUNNING'}), + self.categoryObject.create({value: 'Registering', hostsBootStatus: 'REGISTERING'}), + self.categoryObject.create({value: 'Failed', hostsBootStatus: 'FAILED' }) + ] + }.property(), category: 'All Hosts', allChecked: false, @@ -41,7 +78,7 @@ App.WizardStep3Controller = Em.Controller.extend({ isRetryDisabled: function () { return !(this.get('bootHosts').someProperty('bootStatus', 'FAILED') && !this.get('isSubmitDisabled')); - }.property('bootHosts.@each.bootStatus','isSubmitDisabled'), + }.property('bootHosts.@each.bootStatus', 'isSubmitDisabled'), mockData: require('data/mock/step3_hosts'), mockRetryData: require('data/mock/step3_pollData'), @@ -54,13 +91,15 @@ App.WizardStep3Controller = Em.Controller.extend({ } } else { this.set('bootHosts', this.get('hosts')); - if (App.testMode && App.skipBootstrap) { + if (App.testMode) { this.get('bootHosts').setEach('bootStatus', 'REGISTERED'); this.get('bootHosts').setEach('cpu', '2'); this.get('bootHosts').setEach('memory', '2000000'); this.getHostInfo(); } else { - this.isHostsRegistered(); + this.set('registrationStartedAt', null); + this.get('bootHosts').setEach('bootStatus', 'DONE'); + this.startRegistration(); } } }, @@ -69,17 +108,18 @@ App.WizardStep3Controller = Em.Controller.extend({ this.hosts.clear(); this.bootHosts.clear(); this.set('isSubmitDisabled', true); - this.set('registrationAttempts', 1); }, loadStep: function () { console.log("TRACE: Loading step3: Confirm Hosts"); - if (!this.get('hosts').length) { - this.clearStep(); - var hosts = this.loadHosts(); - // hosts.setEach('bootStatus', 'RUNNING'); - this.renderHosts(hosts); - } else { + this.set('registrationStartedAt', null); + + this.clearStep(); + var hosts = this.loadHosts(); + // hosts.setEach('bootStatus', 'RUNNING'); + this.renderHosts(hosts); + + if(this.get('hosts').length) { this.set('isSubmitDisabled', false); } }, @@ -119,7 +159,10 @@ App.WizardStep3Controller = Em.Controller.extend({ parseHostInfo: function (hostsStatusFromServer) { hostsStatusFromServer.forEach(function (_hostStatus) { var host = this.get('bootHosts').findProperty('name', _hostStatus.hostName); - if (host !== null && host !== undefined) { // check if hostname extracted from REST API data matches any hostname in content + // check if hostname extracted from REST API data matches any hostname in content + // also, make sure that bootStatus modified by isHostsRegistered call does not get overwritten + // since these calls are being made in parallel + if (host && !['REGISTERED', 'REGISTERING'].contains(host.get('bootStatus'))) { host.set('bootStatus', _hostStatus.status); host.set('bootLog', _hostStatus.log); } @@ -130,16 +173,9 @@ App.WizardStep3Controller = Em.Controller.extend({ /* Returns the current set of visible hosts on view (All, Succeeded, Failed) */ visibleHosts: function () { - if (this.get('category') === 'Success') { - return (this.hosts.filterProperty('bootStatus', 'REGISTERED')); - } else if (this.get('category') === 'Installing') { - return (this.hosts.filterProperty('bootStatus', 'RUNNING')); - } else if (this.get('category') === 'Registering') { - return (this.hosts.filter(function(host) { - return host.bootStatus == 'DONE' || host.bootStatus == 'REGISTERING'; - })); - } else if (this.get('category') === 'Failed') { - return (this.hosts.filterProperty('bootStatus', 'FAILED')); + var self = this; + if (this.get('category.hostsBootStatus')) { + return this.hosts.filterProperty('bootStatus', self.get('category.hostsBootStatus')); } else { // if (this.get('category') === 'All Hosts') return this.hosts; } @@ -185,13 +221,15 @@ App.WizardStep3Controller = Em.Controller.extend({ retryHosts: function (hosts) { var bootStrapData = JSON.stringify({'verbose': true, 'sshKey': this.get('content.hosts.sshKey'), hosts: hosts.mapProperty('name')}); this.numPolls = 0; - this.set('registrationAttempts', null); if (this.get('content.hosts.manualInstall') !== true) { var requestId = App.router.get('installerController').launchBootstrap(bootStrapData); this.set('content.hosts.bootRequestId', requestId); + this.set('registrationStartedAt', null); this.doBootstrap(); } else { - this.isHostsRegistered(); + this.set('registrationStartedAt', null); + this.get('bootHosts').setEach('bootStatus', 'DONE'); + this.startRegistration(); } }, @@ -211,7 +249,9 @@ App.WizardStep3Controller = Em.Controller.extend({ startBootstrap: function () { //this.set('isSubmitDisabled', true); //TODO: uncomment after actual hookup this.numPolls = 0; + this.set('registrationStartedAt', null); this.set('bootHosts', this.get('hosts')); + this.get('bootHosts').setEach('bootStatus', 'PENDING'); this.doBootstrap(); }, @@ -225,26 +265,28 @@ App.WizardStep3Controller = Em.Controller.extend({ timeout: App.timeout, success: function (data) { if (data.hostsStatus !== null) { - // in case of bootstrapping just one host, the server returns an object rather than an array... + // in case of bootstrapping just one host, the server returns an object rather than an array, so + // force into an array if (!(data.hostsStatus instanceof Array)) { data.hostsStatus = [ data.hostsStatus ]; } console.log("TRACE: In success function for the GET bootstrap call"); - var result = self.parseHostInfo(data.hostsStatus); - if (result) { + var keepPolling = self.parseHostInfo(data.hostsStatus); + if (data.hostsStatus.someProperty('status', 'DONE') || data.hostsStatus.someProperty('status', 'FAILED')) { + // kicking off registration polls after at least one host has succeeded + self.startRegistration(); + } + if (keepPolling) { window.setTimeout(function () { self.doBootstrap() }, 3000); return; } } - console.log('Bootstrap failed'); - self.stopBootstrap(); }, error: function () { console.log('Bootstrap failed'); - self.stopBootstrap(); }, statusCode: require('data/statusCodes') @@ -252,72 +294,93 @@ App.WizardStep3Controller = Em.Controller.extend({ }, - stopBootstrap: function () { - //TODO: uncomment following line after the hook up with the API call - console.log('stopBootstrap() called'); - // this.set('isSubmitDisabled',false); - Ember.run.later(this, function () { - this.startRegistration(); - }, 1000); - }, + /* + stopBootstrap: function () { + console.log('stopBootstrap() called'); + Ember.run.later(this, function () { + this.startRegistration(); + }, 1000); + }, + */ startRegistration: function () { - this.isHostsRegistered(); + if (this.get('registrationStartedAt') == null) { + this.set('registrationStartedAt', new Date().getTime()); + console.log('registration started at ' + this.get('registrationStartedAt')); + this.isHostsRegistered(); + } }, isHostsRegistered: function () { var self = this; var hosts = this.get('bootHosts'); var url = App.testMode ? '/data/wizard/bootstrap/single_host_registration.json' : App.apiPrefix + '/hosts'; - var method = 'GET'; + $.ajax({ type: 'GET', url: url, timeout: App.timeout, success: function (data) { - console.log('registration attempt #' + self.get('registrationAttempts')); + console.log('registration attempt...'); var jsonData = App.testMode ? data : jQuery.parseJSON(data); if (!jsonData) { console.log("Error: jsonData is null"); return; } - // keep polling until all hosts are registered - var allRegistered = true; + // keep polling until all hosts have registered/failed, or registrationTimeout seconds after the last host finished bootstrapping + var stopPolling = true; hosts.forEach(function (_host, index) { // Change name of first host for test mode. - if (App.testMode === true) { + if (App.testMode) { if (index == 0) { _host.set('name', 'localhost.localdomain'); } } - if (jsonData.items.someProperty('Hosts.host_name', _host.name)) { - if (_host.get('bootStatus') != 'REGISTERED') { - _host.set('bootStatus', 'REGISTERED'); - _host.set('bootLog', (_host.get('bootLog') != null ? _host.get('bootLog') : '') + '\nRegistration with the server succeeded.'); - } - } else if (_host.get('bootStatus') == 'FAILED') { - // ignore FAILED hosts - } else { - // there are some hosts that are not REGISTERED or FAILED - // we need to keep polling - allRegistered = false; - if (_host.get('bootStatus') != 'REGISTERING') { + // actions to take depending on the host's current bootStatus + // RUNNING - bootstrap is running; leave it alone + // DONE - bootstrap is done; transition to REGISTERING + // REGISTERING - bootstrap is done but has not registered; transition to REGISTERED if host found in polling API result + // REGISTERED - bootstrap and registration is done; leave it alone + // FAILED - either bootstrap or registration failed; leave it alone + console.log(_host.name + ' bootStatus=' + _host.get('bootStatus')); + switch (_host.get('bootStatus')) { + case 'DONE': _host.set('bootStatus', 'REGISTERING'); - currentBootLog = _host.get('bootLog') != null ? _host.get('bootLog') : ''; _host.set('bootLog', (_host.get('bootLog') != null ? _host.get('bootLog') : '') + '\nRegistering with the server...'); - } + // update registration timestamp so that the timeout is computed from the last host that finished bootstrapping + self.get('registrationStartedAt', new Date().getTime()); + stopPolling = false; + break; + case 'REGISTERING': + if (jsonData.items.someProperty('Hosts.host_name', _host.name)) { + console.log(_host.name + ' has been registered'); + _host.set('bootStatus', 'REGISTERED'); + _host.set('bootLog', (_host.get('bootLog') != null ? _host.get('bootLog') : '') + '\nRegistration with the server succeeded.'); + } else { + console.log(_host.name + ' is registering...'); + stopPolling = false; + } + break; + case 'RUNNING': + stopPolling = false; + break; + case 'REGISTERED': + case 'FAILED': + default: + break; } }, this); - if (allRegistered) { + + if (stopPolling) { self.getHostInfo(); - } else if (self.get('maxRegistrationAttempts') - self.get('registrationAttempts') >= 0) { - self.set('registrationAttempts', self.get('registrationAttempts') + 1); + } else if (new Date().getTime() - self.get('registrationStartedAt') < self.get('registrationTimeoutSecs') * 1000) { window.setTimeout(function () { self.isHostsRegistered(); }, 3000); } else { - // maxed out on registration attempts. mark all REGISTERING hosts to FAILED + // registration timed out. mark all REGISTERING hosts to FAILED + console.log('registration timed out'); hosts.filterProperty('bootStatus', 'REGISTERING').forEach(function (_host) { _host.set('bootStatus', 'FAILED'); _host.set('bootLog', (_host.get('bootLog') != null ? _host.get('bootLog') : '') + '\nRegistration with the server failed.'); @@ -353,7 +416,7 @@ App.WizardStep3Controller = Em.Controller.extend({ var self = this; var kbPerGb = 1024; var hosts = this.get('bootHosts'); - var url = App.testMode ? '/data/wizard/bootstrap/single_host_information.json' : App.apiPrefix + '/hosts?fields=Hosts/total_mem,Hosts/cpu_count'; + var url = App.testMode ? '/data/wizard/bootstrap/single_host_information.json' : App.apiPrefix + '/hosts?fields=Hosts/total_mem,Hosts/cpu_count,Hosts/disk_info'; var method = 'GET'; $.ajax({ type: 'GET', @@ -361,12 +424,18 @@ App.WizardStep3Controller = Em.Controller.extend({ contentType: 'application/json', timeout: App.timeout, success: function (data) { - var jsonData = App.testMode ? data : jQuery.parseJSON(data); + var jsonData = (App.testMode) ? data : jQuery.parseJSON(data); hosts.forEach(function (_host) { - var host = jsonData.items.findProperty('Hosts.host_name', _host.name); - if (host) { + var host = (App.testMode) ? jsonData.items[0] : jsonData.items.findProperty('Hosts.host_name', _host.name); + if (App.skipBootstrap) { + _host.cpu = 2; + _host.memory = ((parseInt(2000000))).toFixed(2); + _host.disk_info = [{"mountpoint": "/", "type":"ext4"},{"mountpoint": "/grid/0", "type":"ext4"}, {"mountpoint": "/grid/1", "type":"ext4"}, {"mountpoint": "/grid/2", "type":"ext4"}]; + } else if (host) { _host.cpu = host.Hosts.cpu_count; _host.memory = ((parseInt(host.Hosts.total_mem))).toFixed(2); + _host.disk_info = host.Hosts.disk_info; + console.log("The value of memory is: " + _host.memory); } }); diff --git a/ambari-web/app/controllers/wizard/step5_controller.js b/ambari-web/app/controllers/wizard/step5_controller.js index 6e93cf2a3a..0e872add71 100644 --- a/ambari-web/app/controllers/wizard/step5_controller.js +++ b/ambari-web/app/controllers/wizard/step5_controller.js @@ -64,6 +64,7 @@ App.WizardStep5Controller = Em.Controller.extend({ cpu:_host.cpu, memory:_host.memory, + disk_info:_host.disk_info, host_info:"%@ (%@, %@ cores)".fmt(_host.name, (_host.memory * 1024).bytesToSize(1, 'parseFloat'), _host.cpu) // Uncomment to test sorting with random cpu, memory, host_info diff --git a/ambari-web/app/controllers/wizard/step7_controller.js b/ambari-web/app/controllers/wizard/step7_controller.js index 86d3712ab2..04a141f369 100644 --- a/ambari-web/app/controllers/wizard/step7_controller.js +++ b/ambari-web/app/controllers/wizard/step7_controller.js @@ -52,7 +52,7 @@ App.WizardStep7Controller = Em.Controller.extend({ slaveComponentHosts: function () { return this.get('content.slaveGroupProperties'); - }.property('content.slaveGroupProperties','content.slaveComponentHosts'), + }.property('content.slaveGroupProperties', 'content.slaveComponentHosts'), serviceConfigs: require('data/service_configs'), configMapping: require('data/config_mapping'), @@ -71,6 +71,37 @@ App.WizardStep7Controller = Em.Controller.extend({ this.clearStep(); var serviceConfigs = this.get('serviceConfigs'); var advancedConfig = this.get('content.advancedServiceConfig') || []; + this.loadAdvancedConfig(serviceConfigs,advancedConfig); + this.loadHostConfigs(); + this.loadCustomConfig(); + this.renderServiceConfigs(serviceConfigs); + var storedServices = this.get('content.serviceConfigProperties'); + if (storedServices) { + var configs = new Ember.Set(); + + // for all services` + this.get('stepConfigs').forEach(function (_content) { + //for all components + _content.get('configs').forEach(function (_config) { + + var componentVal = storedServices.findProperty('name', _config.get('name')); + //if we have config for specified component + if (componentVal) { + //set it + _config.set('value', componentVal.value) + } + + }, this); + }, this); + + } + }, + + /* + Loads the advanced configs fetched from the server metadata libarary + */ + + loadAdvancedConfig: function (serviceConfigs,advancedConfig) { advancedConfig.forEach(function (_config) { if (_config) { var service = serviceConfigs.findProperty('serviceName', _config.serviceName); @@ -81,12 +112,16 @@ App.WizardStep7Controller = Em.Controller.extend({ _config.category = 'Advanced'; _config.displayName = _config.name; _config.defaultValue = _config.value; + // make all advanced configs optional and populated by default + /* if (/\${.*}/.test(_config.value) || (service.serviceName !== 'OOZIE' && service.serviceName !== 'HBASE')) { _config.isRequired = false; _config.value = ''; } else if (/^\s+$/.test(_config.value)) { _config.isRequired = false; } + */ + _config.isRequired = false; _config.isVisible = true; _config.displayType = 'advanced'; service.configs.pushObject(_config); @@ -94,28 +129,13 @@ App.WizardStep7Controller = Em.Controller.extend({ } } }, this); - this.loadCustomConfig(); - this.renderServiceConfigs(serviceConfigs); - var storedServices = this.get('content.serviceConfigProperties'); - if (storedServices) { - var configs = new Ember.Set(); - - // for all services` - this.get('stepConfigs').forEach(function (_content) { - //for all components - _content.get('configs').forEach(function (_config) { - - var componentVal = storedServices.findProperty('name', _config.get('name')); - //if we have config for specified component - if (componentVal) { - //set it - _config.set('value', componentVal.value) - } + }, - }, this); - }, this); + /* + loads host related configs obtained from server. + */ + loadHostConfigs: function() { - } }, diff --git a/ambari-web/app/controllers/wizard/step8_controller.js b/ambari-web/app/controllers/wizard/step8_controller.js index 56a6d654ed..caba53bb11 100644 --- a/ambari-web/app/controllers/wizard/step8_controller.js +++ b/ambari-web/app/controllers/wizard/step8_controller.js @@ -48,66 +48,15 @@ App.WizardStep8Controller = Em.Controller.extend({ this.loadGlobals(); this.loadConfigs(); this.setCustomConfigs(); - this.loadClusterInfo(); this.loadSlaveConfiguration(); + this.loadClusterInfo(); this.loadServices(); }, - loadSlaveConfiguration: function () { - var slaveComponentConfig = this.convertSlaveConfig(this.get('content.slaveGroupProperties')); - this.set("slaveComponentConfig", slaveComponentConfig); - }, - - convertSlaveConfig: function (slaveContent) { - var dest = { - "version": "1.0", - "components": [ - ] - }; - - slaveContent.forEach(function (_slaveContent) { - var newComponent = {}; - newComponent.componentName = _slaveContent.componentName; - newComponent.serviceName = this.getServiceName(newComponent.componentName); - newComponent.groups = []; - _slaveContent.groups.forEach(function (_group) { - var newGroup = {}; - newGroup.groupName = _group.name; - newGroup.configVersion = "1.0"; // TODO : every time a new version should be generated - newGroup.hostNames = _slaveContent.hosts.filterProperty("group", newGroup.groupName); - newGroup.properties = _group.properties; - if (!Ember.empty(newGroup.hostNames)) { - newComponent.groups.push(newGroup); - } - }, this); - dest.components.push(newComponent); - }, this); - return dest; - - }, - - getServiceName: function (componentName) { - var serviceName = null - switch (componentName) { - case 'DATANODE': - serviceName = 'HDFS'; - break; - case 'TASKTRACKER': - serviceName = 'MAPREDUCE'; - break; - case 'HBASE_REGIONSERVER': - serviceName = 'HBASE'; - break; - default: - serviceName = null; - } - return serviceName; - }, - 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 postgress is not the default db + //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 PostgreSQL Database') { globals.findProperty('name', 'hive_ambari_host').name = 'hive_mysql_host'; @@ -284,6 +233,100 @@ App.WizardStep8Controller = Em.Controller.extend({ } }, + loadSlaveConfiguration: function () { + + var slaveComponentConfig = this.convertSlaveConfig(this.get('content.slaveGroupProperties')); + this.set("slaveComponentConfig", slaveComponentConfig); + }, + + convertSlaveConfig: function (slaveContent) { + var dest = { + "version": "1.0", + "components": [ + ], + "slaveHostComponents": [] + }; + + slaveContent.forEach(function (_slaveContent) { + var newComponent = {}; + newComponent.componentName = _slaveContent.componentName; + newComponent.serviceName = this.getServiceInfo(newComponent.componentName).name; + newComponent.groups = []; + var index = 2; + _slaveContent.groups.forEach(function (_group) { + var newGroup = {}; + newGroup.groupName = _group.name; + newGroup.configVersion = {config: {'global': 'version1', 'core-site': 'version1'}}; // TODO : every time a new version should be generated + if (this.getServiceInfo(_slaveContent.componentName)) { + newGroup.configVersion.config[this.getServiceInfo(_slaveContent.componentName).domain] = 'version' + index; + newGroup.configVersion.config[this.getServiceInfo(_slaveContent.componentName).siteName] = 'version' + index; + } + newGroup.siteVersion = 'version' + index; + newGroup.hostNames = _slaveContent.hosts.filterProperty("group", newGroup.groupName).mapProperty('hostName'); + newGroup.properties = _group.properties; + if (!Ember.empty(newGroup.hostNames)) { + newComponent.groups.push(newGroup); + } + index++; + }, this); + dest.components.push(newComponent); + }, this); + var hostsInfo = this.get('content.hostsInfo'); + + for (var index in hostsInfo) { + var hostIndex = 2; + var slaveHost = {name: null, configVersion: null, slaveComponents: []}; + dest.components.forEach(function (_component) { + _component.groups.forEach(function (_group) { + if (_group.hostNames.contains(hostsInfo[index].name)) { + var slaveComponent = {}; + slaveHost.name = hostsInfo[index].name; + slaveComponent.componentName = _component.componentName; + slaveComponent.groupName = _group.groupName; + slaveComponent.properties = _group.properties; + slaveHost.slaveComponents.pushObject(slaveComponent); + } + }, this); + }, this); + hostIndex++; + if (!Ember.none(slaveHost.name)) { + dest.slaveHostComponents.pushObject(slaveHost); + } + + } + return dest; + }, + + getServiceInfo: function (componentName) { + var serviceConfig; + switch (componentName) { + case 'DATANODE': + serviceConfig = { + name: 'HDFS', + siteName: 'hdfs-site', + domain: 'datanode-global' + }; + break; + case 'TASKTRACKER': + serviceConfig = { + name: 'MAPREDUCE', + siteName: 'mapred-site', + domain: 'tasktracker-global' + }; + break; + case 'HBASE_REGIONSERVER': + serviceConfig = { + name: 'HBASE', + siteName: 'hbase-site', + domain: 'regionserver-global' + }; + break; + default: + serviceConfig = null; + } + return serviceConfig; + }, + /** * Load all info about cluster to <code>clusterInfo</code> variable */ @@ -406,7 +449,7 @@ App.WizardStep8Controller = Em.Controller.extend({ loadDnValue: function (dnComponent) { var dnHosts = this.get('content.slaveComponentHosts').findProperty('displayName', 'DataNode'); var totalDnHosts = dnHosts.hosts.length; - var totalGroups = this.get('slaveComponentConfig.components').findProperty('componentName','DATANODE').groups.length; + var totalGroups = this.get('slaveComponentConfig.components').findProperty('componentName', 'DATANODE').groups.length; var groupLabel; if (totalGroups == 1) { groupLabel = 'group'; @@ -444,7 +487,7 @@ App.WizardStep8Controller = Em.Controller.extend({ loadTtValue: function (ttComponent) { var ttHosts = this.get('content.slaveComponentHosts').findProperty('displayName', 'TaskTracker'); var totalTtHosts = ttHosts.hosts.length; - var totalGroups = this.get('slaveComponentConfig.components').findProperty('componentName','TASKTRACKER').groups.length; + var totalGroups = this.get('slaveComponentConfig.components').findProperty('componentName', 'TASKTRACKER').groups.length; var groupLabel; if (totalGroups == 1) { groupLabel = 'group'; @@ -522,7 +565,7 @@ App.WizardStep8Controller = Em.Controller.extend({ loadRegionServerValue: function (rsComponent) { var rsHosts = this.get('content.slaveComponentHosts').findProperty('displayName', 'RegionServer'); var totalRsHosts = rsHosts.hosts.length; - var totalGroups = this.get('slaveComponentConfig.components').findProperty('componentName','HBASE_REGIONSERVER').groups.length; + var totalGroups = this.get('slaveComponentConfig.components').findProperty('componentName', 'HBASE_REGIONSERVER').groups.length; var groupLabel; if (totalGroups == 1) { groupLabel = 'group'; @@ -667,33 +710,35 @@ App.WizardStep8Controller = Em.Controller.extend({ this.createComponents(); this.registerHostsToCluster(); this.createAllHostComponents(); + this.applyCreatedConfToSlaveGroups(); + this.ajaxQueueFinished = function(){ + console.log('everything is loaded') + App.router.send('next'); + }; + this.doNextAjaxCall(); + } else { + App.router.send('next'); } - - App.router.send('next'); }, setAmbariUIDb: function () { + var dbContent = this.get('content.slaveGroupProperties'); var slaveComponentConfig = this.get("slaveComponentConfig"); - this.persistKeyValues(slaveComponentConfig.version, slaveComponentConfig); + this.persistKeyValues(slaveComponentConfig.version, dbContent); + this.persistKeyValues('current_version',slaveComponentConfig.version); }, persistKeyValues: function (key, value) { var str = "{ '" + key + "' : '" + JSON.stringify(value) + "'}"; var obj = eval("(" + str + ")"); - $.ajax({ + + this.ajax({ type: "POST", url: App.apiPrefix + '/persist', data: JSON.stringify(obj), - async: false, - dataType: 'text', - timeout: App.timeout, - success: function (data) { - console.debug('success...ajax call returned'); - }, - - error: function (request, ajaxOptions, error) { - console.log('Step8: Error message is: ' + request.responseText); + beforeSend: function () { + console.log('BeforeSend: persistKeyValues', obj); } }); }, @@ -712,61 +757,35 @@ App.WizardStep8Controller = Em.Controller.extend({ return false; } - var url = App.apiPrefix + '/clusters/' + this.get('clusterName'); + var clusterName = this.get('clusterName'); + var url = App.apiPrefix + '/clusters/' + clusterName; var stackVersion = (App.db.getSoftRepo().repoType == 'local') ? App.defaultLocalStackVersion : App.defaultStackVersion; - $.ajax({ + this.ajax({ type: 'POST', url: url, - async: false, - //accepts: 'text', - dataType: 'text', data: JSON.stringify({ "Clusters": {"version": stackVersion }}), - timeout: App.timeout, - success: function (data) { - var jsonData = jQuery.parseJSON(data); - console.log("TRACE: Step8 -> In success function for createCluster call"); - console.log("TRACE: Step8 -> value of the received data is: " + jsonData); - }, - - error: function (request, ajaxOptions, error) { - console.log('Step8: In Error '); - console.log('Step8: Error message is: ' + request.responseText); - }, - - statusCode: require('data/statusCodes') + beforeSend: function () { + console.log("BeforeSend: createCluster for " + clusterName); + } }); - console.log("Exiting createCluster"); }, - createSelectedServices: function (service, httpMethod) { + createSelectedServices: function () { var url = App.apiPrefix + '/clusters/' + this.get('clusterName') + '/services'; var data = this.createServiceData(); var httpMethod = 'POST'; - $.ajax({ + + this.ajax({ type: httpMethod, url: url, data: JSON.stringify(data), - async: false, - dataType: 'text', - timeout: App.timeout, - success: function (data) { - var jsonData = jQuery.parseJSON(data); - console.log("TRACE: Step8 -> In success function for the createSelectedServices call"); - console.log("TRACE: Step8 -> value of the url is: " + url); - console.log("TRACE: Step8 -> value of the received data is: " + jsonData); - - }, - - error: function (request, ajaxOptions, error) { - console.log('Step8: In Error '); - console.log('Step8: Error message is: ' + request.responseText); - }, - - statusCode: require('data/statusCodes') + beforeSend: function () { + console.log('BeforeSend: createSelectedServices ', data); + } }); }, @@ -795,26 +814,14 @@ App.WizardStep8Controller = Em.Controller.extend({ var data = { "components": componentsData } - $.ajax({ + + this.ajax({ type: 'POST', url: url, - async: false, - dataType: 'text', data: JSON.stringify(data), - timeout: App.timeout, - success: function (data) { - var jsonData = jQuery.parseJSON(data); - console.log("TRACE: Step8 -> In success function for createComponents"); - console.log("TRACE: Step8 -> value of the url is: " + url); - console.log("TRACE: Step8 -> value of the received data is: " + jsonData); - }, - - error: function (request, ajaxOptions, error) { - console.log('Step8: In Error '); - console.log('Step8: Error message is: ' + request.responseText); - }, - - statusCode: require('data/statusCodes') + beforeSend: function () { + console.log('BeforeSend: createComponents for ' + _service, componentsData); + } }); }, this); @@ -829,27 +836,13 @@ App.WizardStep8Controller = Em.Controller.extend({ return; } - $.ajax({ + this.ajax({ type: 'POST', url: url, data: JSON.stringify(data), - async: false, - dataType: 'text', - timeout: App.timeout, - success: function (data) { - var jsonData = jQuery.parseJSON(data); - console.log("TRACE: Step8 -> In success function for registerHostsToCluster"); - console.log("TRACE: Step8 -> value of the url is: " + url); - console.log("TRACE: Step8 -> value of the received data is: " + jsonData); - - }, - - error: function (request, ajaxOptions, error) { - console.log('Step8: In Error '); - console.log('Step8: Error message is: ' + request.responseText); - }, - - statusCode: require('data/statusCodes') + beforeSend: function () { + console.log('BeforeSend: registerHostsToCluster', data); + } }); }, @@ -933,7 +926,7 @@ App.WizardStep8Controller = Em.Controller.extend({ // return 'Hosts/host_name=' + hostName; // }).join('|'); - var queryStrArr = [] + var queryStrArr = []; var queryStr = ''; hostNames.forEach(function (hostName) { queryStr += 'Hosts/host_name=' + hostName + '|'; @@ -960,26 +953,13 @@ App.WizardStep8Controller = Em.Controller.extend({ ] }; - $.ajax({ + this.ajax({ type: 'POST', url: url, - async: false, - dataType: 'text', - timeout: App.timeout, data: JSON.stringify(data), - success: function (data) { - var jsonData = jQuery.parseJSON(data); - console.log("TRACE: Step8 -> In success function for the registerHostsToComponent"); - console.log("TRACE: Step8 -> value of the url is: " + url); - console.log("TRACE: Step8 -> value of the received data is: " + jsonData); - }, - - error: function (request, ajaxOptions, error) { - console.log('Step8: In Error '); - console.log('Step8: Error message is: ' + request.responseText); - }, - - statusCode: require('data/statusCodes') + beforeSend: function () { + console.log('BeforeSend: registerHostsToComponent for ' + queryStr + ' and component ' + componentName); + } }); }, this); }, @@ -987,64 +967,56 @@ App.WizardStep8Controller = Em.Controller.extend({ createConfigurations: function () { var selectedServices = this.get('selectedServices'); if (!this.get('content.isWizard')) { - this.createConfigSite(this.createGlobalSiteObj()); - this.createConfigSite(this.createCoreSiteObj()); - this.createConfigSite(this.createHdfsSiteObj('HDFS')); + this.createConfigSiteForService(this.createGlobalSiteObj()); + this.createGlobalSitePerSlaveGroup(); + this.createConfigSiteForService(this.createCoreSiteObj()); + this.createConfigSiteForService(this.createHdfsSiteObj()); + this.createHdfsSitePerSlaveGroup('HDFS'); } if (selectedServices.someProperty('serviceName', 'MAPREDUCE')) { - this.createConfigSite(this.createMrSiteObj('MAPREDUCE')); + this.createConfigSiteForService(this.createMrSiteObj()); + this.createMrSitePerSlaveGroup('MAPREDUCE'); } if (selectedServices.someProperty('serviceName', 'HBASE')) { - this.createConfigSite(this.createHbaseSiteObj('HBASE')); + this.createConfigSiteForService(this.createHbaseSiteObj()); + this.createHbaseSitePerSlaveGroup('HBASE'); } if (selectedServices.someProperty('serviceName', 'OOZIE')) { - this.createConfigSite(this.createOozieSiteObj('OOZIE')); + this.createConfigSiteForService(this.createOozieSiteObj('OOZIE')); } if (selectedServices.someProperty('serviceName', 'HIVE')) { - // TODO - // this.createConfigSite(this.createHiveSiteObj('HIVE')); + this.createConfigSiteForService(this.createHiveSiteObj('HIVE')); } }, - createConfigSite: function (data) { - console.log("Inside createConfigSite"); + createConfigSiteForService: function (data) { + console.log("Inside createConfigSiteForService"); var url = App.apiPrefix + '/clusters/' + this.get('clusterName') + '/configurations'; - $.ajax({ + + this.ajax({ type: 'POST', url: url, data: JSON.stringify(data), - async: false, - dataType: 'text', - timeout: App.timeout, - success: function (data) { - var jsonData = jQuery.parseJSON(data); - console.log("TRACE: STep8 -> In success function for the createConfigSite"); - console.log("TRACE: STep8 -> value of the url is: " + url); - console.log("TRACE: STep8 -> value of the received data is: " + jsonData); - }, - - error: function (request, ajaxOptions, error) { - console.log('Step8: In Error '); - console.log('Step8: Error message is: ' + request.responseText); - console.log("TRACE: STep8 -> value of the url is: " + url); - }, - - statusCode: require('data/statusCodes') + beforeSend: function () { + console.log("BeforeSend: createConfigSiteForService for " + data.type); + } }); - console.log("Exiting createConfigSite"); }, createGlobalSiteObj: function () { var globalSiteProperties = {}; - this.get('globals').forEach(function (_globalSiteObj) { + this.get('globals').filterProperty('domain', 'global').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 + var value = null; if (/_heapsize|_newsize|_maxnewsize$/.test(_globalSiteObj.name)) { - _globalSiteObj.value += "m"; + value = _globalSiteObj.value + "m"; + globalSiteProperties[_globalSiteObj.name] = value; + } else { + globalSiteProperties[_globalSiteObj.name] = _globalSiteObj.value; } - 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); } @@ -1052,6 +1024,36 @@ App.WizardStep8Controller = Em.Controller.extend({ return {"type": "global", "tag": "version1", "properties": globalSiteProperties}; }, + createGlobalSitePerSlaveGroup: function () { + this.get('slaveComponentConfig.components').forEach(function (_component) { + _component.groups.forEach(function (_group) { + var globalSiteProperties = {}; + var properties = _group.properties; + properties.forEach(function (_property) { + if (!/_hosts?$/.test(_property.name)) { + // append "m" to JVM memory options + var value = null; + if (/_heapsize|_newsize|_maxnewsize$/.test(_property.name)) { + value = _property.value + "m"; + globalSiteProperties[_property.name] = value; + } else { + globalSiteProperties[_property.name] = _property.storeValue; + } + console.log("STEP8: name of the global property is: " + _property.name); + console.log("STEP8: value of the global property is: " + _property.storeValue); + } + }, this); + var config = _group.configVersion.config; + for (var index in config) { + if (index === 'datanode-global' || index === 'tasktracker-global' || index === 'regionserver-global') { + var data = {"type": index, "tag": config[index], "properties": globalSiteProperties}; + this.createConfigSiteForService(data); + } + } + }, this); + }, this); + }, + createCoreSiteObj: function () { var coreSiteObj = this.get('configs').filterProperty('filename', 'core-site.xml'); var coreSiteProperties = {}; @@ -1067,7 +1069,7 @@ App.WizardStep8Controller = Em.Controller.extend({ return {"type": "core-site", "tag": "version1", "properties": coreSiteProperties}; }, - createHdfsSiteObj: function (serviceName) { + createHdfsSiteObj: function () { var hdfsSiteObj = this.get('configs').filterProperty('filename', 'hdfs-site.xml'); var hdfsProperties = {}; hdfsSiteObj.forEach(function (_configProperty) { @@ -1078,7 +1080,29 @@ App.WizardStep8Controller = Em.Controller.extend({ return {"type": "hdfs-site", "tag": "version1", "properties": hdfsProperties }; }, - createMrSiteObj: function (serviceName) { + createHdfsSitePerSlaveGroup: function (serviceName) { + var hdfsSite = this.createHdfsSiteObj(); + var component = this.get('slaveComponentConfig.components').findProperty('serviceName', serviceName); + component.groups.forEach(function (_group) { + var siteProperties = hdfsSite.properties; + _group.properties.forEach(function (_property) { + this.get('configMapping').forEach(function (_config) { + if (_config.templateName.contains(_property.name)) { + this.get('globals').findProperty('name', _property.name).value = _property.storeValue; + var value = this.getGlobConfigValue(_config.templateName, _config.value); + if (siteProperties[_config.name]) { + siteProperties[_config.name] = value; + } + } + }, this); + }, this); + var data = {"type": hdfsSite.type, "tag": _group.siteVersion, "properties": siteProperties}; + console.log("The value of globalConfig is: " + JSON.stringify(siteProperties)); + this.createConfigSiteForService(data); + }, this); + }, + + createMrSiteObj: function () { var configs = this.get('configs').filterProperty('filename', 'mapred-site.xml'); var mrProperties = {}; configs.forEach(function (_configProperty) { @@ -1089,7 +1113,28 @@ App.WizardStep8Controller = Em.Controller.extend({ return {type: 'mapred-site', tag: 'version1', properties: mrProperties}; }, - createHbaseSiteObj: function (serviceName) { + createMrSitePerSlaveGroup: function (serviceName) { + var mrSite = this.createMrSiteObj(); + var component = this.get('slaveComponentConfig.components').findProperty('serviceName', serviceName); + component.groups.forEach(function (_group) { + var siteProperties = mrSite.properties; + _group.properties.forEach(function (_property) { + this.get('configMapping').forEach(function (_config) { + if (_config.templateName.contains(_property.name)) { + this.get('globals').findProperty('name', _property.name).value = _property.storeValue; + var value = this.getGlobConfigValue(_config.templateName, _config.value); + if (siteProperties[_config.name]) { + siteProperties[_config.name] = value; + } + } + }, this); + }, this); + var data = {"type": mrSite.type, "tag": _group.siteVersion, "properties": siteProperties}; + this.createConfigSiteForService(data); + }, this); + }, + + createHbaseSiteObj: function () { var configs = this.get('configs').filterProperty('filename', 'hbase-site.xml'); var hbaseProperties = {}; configs.forEach(function (_configProperty) { @@ -1102,17 +1147,38 @@ App.WizardStep8Controller = Em.Controller.extend({ return {type: 'hbase-site', tag: 'version1', properties: hbaseProperties}; }, + createHbaseSitePerSlaveGroup: function (serviceName) { + var hbaseSite = this.createHbaseSiteObj(); + var component = this.get('slaveComponentConfig.components').findProperty('serviceName', serviceName); + component.groups.forEach(function (_group) { + var siteProperties = hbaseSite.properties; + _group.properties.forEach(function (_property) { + this.get('configMapping').forEach(function (_config) { + if (_config.templateName.contains(_property.name)) { + this.get('globals').findProperty('name', _property.name).value = _property.storeValue; + var value = this.getGlobConfigValue(_config.templateName, _config.value); + if (siteProperties[_config.name]) { + siteProperties[_config.name] = value; + } + } + }, this); + }, this); + var data = {"type": hbaseSite.type, "tag": _group.siteVersion, "properties": siteProperties}; + this.createConfigSiteForService(data); + }, this); + }, + createOozieSiteObj: function (serviceName) { var configs = this.get('configs').filterProperty('filename', 'oozie-site.xml'); var oozieProperties = {}; configs.forEach(function (_configProperty) { oozieProperties[_configProperty.name] = _configProperty.value; }, this); - var baseUrl = oozieProperties['oozie.base.url']; - oozieProperties = { - "oozie.service.JPAService.jdbc.password": " ", "oozie.db.schema.name": "oozie", "oozie.service.JPAService.jdbc.url": "jdbc:derby:/var/data/oozie/oozie-db;create=true", "oozie.service.JPAService.jdbc.driver": "org.apache.derby.jdbc.EmbeddedDriver", "oozie.service.WorkflowAppService.system.libpath": "/user/oozie/share/lib", "oozie.service.JPAService.jdbc.username": "sa", "oozie.service.SchemaService.wf.ext.schemas": "shell-action-0.1.xsd,email-action-0.1.xsd,hive-action-0.2.xsd,sqoop-action-0.2.xsd,ssh-action-0.1.xsd,distcp-action-0.1.xsd", "oozie.service.JPAService.create.db.schema": "false", "use.system.libpath.for.mapreduce.and.pig.jobs": "false", "oozie.service.ActionService.executor.ext.classes": "org.apache.oozie.action.email.EmailActionExecutor,org.apache.oozie.action.hadoop.HiveActionExecutor,org.apache.oozie.action.hadoop.ShellActionExecutor,org.apache.oozie.action.hadoop.SqoopActionExecutor,org.apache.oozie.action.hadoop.DistcpActionExecutor", "oozie.service.HadoopAccessorService.hadoop.configurations": "*=/etc/hadoop/conf" - }; - oozieProperties['oozie.base.url'] = baseUrl; + // var baseUrl = oozieProperties['oozie.base.url']; + // oozieProperties = { + // "oozie.service.JPAService.jdbc.password": " ", "oozie.db.schema.name": "oozie", "oozie.service.JPAService.jdbc.url": "jdbc:derby:/var/data/oozie/oozie-db;create=true", "oozie.service.JPAService.jdbc.driver": "org.apache.derby.jdbc.EmbeddedDriver", "oozie.service.WorkflowAppService.system.libpath": "/user/oozie/share/lib", "oozie.service.JPAService.jdbc.username": "sa", "oozie.service.SchemaService.wf.ext.schemas": "shell-action-0.1.xsd,email-action-0.1.xsd,hive-action-0.2.xsd,sqoop-action-0.2.xsd,ssh-action-0.1.xsd,distcp-action-0.1.xsd", "oozie.service.JPAService.create.db.schema": "false", "use.system.libpath.for.mapreduce.and.pig.jobs": "false", "oozie.service.ActionService.executor.ext.classes": "org.apache.oozie.action.email.EmailActionExecutor,org.apache.oozie.action.hadoop.HiveActionExecutor,org.apache.oozie.action.hadoop.ShellActionExecutor,org.apache.oozie.action.hadoop.SqoopActionExecutor,org.apache.oozie.action.hadoop.DistcpActionExecutor", "oozie.service.HadoopAccessorService.hadoop.configurations": "*=/etc/hadoop/conf" + // }; + // oozieProperties['oozie.base.url'] = baseUrl; return {type: 'oozie-site', tag: 'version1', properties: oozieProperties}; }, @@ -1122,7 +1188,7 @@ App.WizardStep8Controller = Em.Controller.extend({ configs.forEach(function (_configProperty) { hiveProperties[_configProperty.name] = _configProperty.value; }, this); - return {type: 'hbase-site', tag: 'version1', properties: hiveProperties}; + return {type: 'hive-site', tag: 'version1', properties: hiveProperties}; }, applyCreatedConfToServices: function () { @@ -1138,28 +1204,45 @@ App.WizardStep8Controller = Em.Controller.extend({ var url = App.apiPrefix + '/clusters/' + this.get('clusterName') + '/services/' + service; - $.ajax({ + this.ajax({ type: httpMethod, url: url, - async: false, - dataType: 'text', data: JSON.stringify(data), - timeout: App.timeout, - success: function (data) { - var jsonData = jQuery.parseJSON(data); - console.log("TRACE: STep8 -> In success function for the applyCreatedConfToService call"); - console.log("TRACE: STep8 -> value of the url is: " + url); - console.log("TRACE: STep8 -> value of the received data is: " + jsonData); - }, + beforeSend: function () { + console.log("BeforeSend: applyCreatedConfToService for " + service); + } + }); + }, - error: function (request, ajaxOptions, error) { - console.log('Step8: In Error '); - console.log('Step8: Error message is: ' + request.responseText); - }, - statusCode: require('data/statusCodes') + applyCreatedConfToSlaveGroups: function () { + this.get('slaveComponentConfig.components').forEach(function (_component) { + _component.groups.forEach(function (_group) { + var aggregatedHostNames = ''; + _group.hostNames.forEach(function (_hostName, index) { + aggregatedHostNames += 'HostRoles/host_name=' + _hostName; + if (index !== _group.hostNames.length-1) { + aggregatedHostNames += '|'; + } + }, this); + console.log("The aggregated hostNames value is: " + aggregatedHostNames); + this.applyCreatedConfToSlaveGroup(aggregatedHostNames, 'PUT', _group.configVersion,_group.groupName); + }, this); + }, this); + }, + + applyCreatedConfToSlaveGroup: function (aggregatedHostNames, httpMethod, data, groupName) { + console.log("Inside applyCreatedConfToHost"); + var url = App.apiPrefix + '/clusters/' + this.get('clusterName') + '/host_components?' + aggregatedHostNames; + + this.ajax({ + type: httpMethod, + url: url, + data: JSON.stringify(data), + beforeSend: function () { + console.log("BeforeSend: applyCreatedConfToSlaveGroup for group: " + groupName); + } }); - console.log("Exiting applyCreatedConfToService"); }, getConfigForService: function (serviceName) { @@ -1175,6 +1258,85 @@ App.WizardStep8Controller = Em.Controller.extend({ default: return {config: {'global': 'version1'}}; } + }, + + ajaxQueue: [], + + ajaxQueueFinished: function () { + //do something + }, + + doNextAjaxCall: function () { + + if (this.get('ajaxBusy')) { + return; + } + + var queue = this.get('ajaxQueue'); + if (!queue.length) { + this.ajaxQueueFinished(); + return; + } + + var first = queue[0]; + this.set('ajaxQueue', queue.slice(1)); + + this.set('ajaxBusy', true); + console.log('AJAX send ' + first.url); + $.ajax(first); + + }, + + /** + * We need to do a lot of ajax calls(about 10 or more) async in special order. + * To do this i generate array of ajax objects and then send requests step by step. + * All ajax objects are stored in <code>ajaxQueue</code> + * @param params + */ + + ajax: function(params){ + if(App.testMode) return; + + var self = this; + params = jQuery.extend({ + async: true, + dataType: 'text', + statusCode: require('data/statusCodes'), + timeout: App.timeout, + error: function (request, ajaxOptions, error) { + console.log('Step8: In Error '); + console.log('Step8: Error message is: ' + request.responseText); + }, + success: function (data) { + var jsonData = jQuery.parseJSON(data); + console.log("TRACE: STep8 -> In success function"); + console.log("TRACE: STep8 -> value of the url is: " + params.url); + console.log("TRACE: STep8 -> value of the received data is: " + jsonData); + } + }, params); + + var success = params.success; + var error = params.error; + + params.success = function () { + if (success) { + success(); + } + ; + self.set('ajaxBusy', false); + self.doNextAjaxCall(); + } + + params.error = function () { + if (error) { + error(); + } + ; + self.set('ajaxBusy', false); + self.doNextAjaxCall(); + } + + this.get('ajaxQueue').pushObject(params); } }) diff --git a/ambari-web/app/controllers/wizard/step9_controller.js b/ambari-web/app/controllers/wizard/step9_controller.js index f52391cfb9..90c6901363 100644 --- a/ambari-web/app/controllers/wizard/step9_controller.js +++ b/ambari-web/app/controllers/wizard/step9_controller.js @@ -70,6 +70,7 @@ App.WizardStep9Controller = Em.Controller.extend({ this.launchStartServices(); } else { this.loadStep(); + this.loadLogData(this.get('content.cluster.requestId')); this.startPolling(); } } else { @@ -240,13 +241,11 @@ App.WizardStep9Controller = Em.Controller.extend({ console.log("TRACE: Step9 -> In success function for the startService call"); console.log("TRACE: Step9 -> value of the url is: " + url); console.log("TRACE: Step9 -> value of the received data is: " + jsonData); - var requestId = jsonData.href.match(/.*\/(.*)$/)[1]; + var requestId = jsonData.Requests.id; console.log('requestId is: ' + requestId); var clusterStatus = { - name: clusterName, status: 'INSTALLED', requestId: requestId, - installStartTime: self.get('content.cluster').installStartTime, isStartError: false, isCompleted: false }; @@ -258,9 +257,7 @@ App.WizardStep9Controller = Em.Controller.extend({ error: function () { console.log("ERROR"); var clusterStatus = { - name: clusterName, status: 'START FAILED', - installStartTime: self.get('content.cluster').installStartTime, isStartError: true, isCompleted: false }; @@ -387,8 +384,7 @@ App.WizardStep9Controller = Em.Controller.extend({ clusterStatus = { status: 'INSTALLED', requestId: requestId, - isCompleted: true, - installStartTime: this.get('content.cluster.installStartTime') + isCompleted: true } if (this.isSuccess(polledData)) { clusterStatus.status = 'STARTED'; @@ -414,8 +410,7 @@ App.WizardStep9Controller = Em.Controller.extend({ clusterStatus = { status: 'PENDING', requestId: requestId, - isCompleted: false, - installStartTime: this.get('content.cluster.installStartTime') + isCompleted: false } if (this.isStepFailed(polledData)) { console.log("In installation failure"); @@ -525,25 +520,28 @@ App.WizardStep9Controller = Em.Controller.extend({ loadLogData:function(requestId){ var url = this.getUrl(requestId); - + var requestsId = App.db.getCluster().oldRequestsId; if (App.testMode) { this.POLL_INTERVAL = 1; this.numPolls++; - if (this.numPolls == 5) { - url = this.get('mockDataPrefix') + '/poll_5.json'; - // url = this.get('mockDataPrefix') + '/poll_5_failed.json'; - } else { - url = this.get('mockDataPrefix') + '/poll_' + this.numPolls + '.json'; - } } - this.getLogsByRequest(url); - if(typeof(requestId) === 'number' && requestId > 1){ - requestId--; - this.loadLogData(requestId); - } + requestsId.forEach(function(requestId) { + url = this.getUrl(requestId); + if (App.testMode) { + this.POLL_INTERVAL = 1; + + if (requestId == 1) { + url = this.get('mockDataPrefix') + '/poll_' + this.numPolls + '.json'; + // url = this.get('mockDataPrefix') + '/poll_5_failed.json'; + } else { + url = this.get('mockDataPrefix') + '/poll_9.json'; + } + } + this.getLogsByRequest(url, false); + }, this); }, - getLogsByRequest: function(url){ + getLogsByRequest: function(url, polling){ var self = this; $.ajax({ type: 'GET', @@ -555,6 +553,9 @@ App.WizardStep9Controller = Em.Controller.extend({ console.log("TRACE: In success function for the GET logs data"); console.log("TRACE: STep9 -> The value is: ", jQuery.parseJSON(data)); var result = self.parseHostInfo(jQuery.parseJSON(data)); + if(!polling){ + return; + } if (result !== true) { window.setTimeout(function () { self.doPolling(); @@ -578,16 +579,10 @@ App.WizardStep9Controller = Em.Controller.extend({ var url = this.getUrl(); if (App.testMode) { - this.POLL_INTERVAL = 1; this.numPolls++; - if (this.numPolls == 5) { - url = this.get('mockDataPrefix') + '/poll_5.json'; - // url = this.get('mockDataPrefix') + '/poll_5_failed.json'; - } else { - url = this.get('mockDataPrefix') + '/poll_' + this.numPolls + '.json'; - } + url = this.get('mockDataPrefix') + '/poll_' + this.get('numPolls') + '.json'; } - this.getLogsByRequest(url); + this.getLogsByRequest(url, true); }, stopPolling: function () { @@ -597,8 +592,6 @@ App.WizardStep9Controller = Em.Controller.extend({ submit: function () { if (!this.get('isSubmitDisabled')) { - this.set('content.cluster.status', this.get('status')); - this.set('content.cluster.isCompleted', true); App.router.send('next'); } }, diff --git a/ambari-web/app/data/config_mapping.js b/ambari-web/app/data/config_mapping.js index 77e1bb437a..a83853b15b 100644 --- a/ambari-web/app/data/config_mapping.js +++ b/ambari-web/app/data/config_mapping.js @@ -294,7 +294,7 @@ module.exports = [ "value": "http://<templateName[0]>:11000/oozie", "filename": "oozie-site.xml" }, - //TODO: Oozie configs hardcoded for now. Map them to templates later + /* { "name": "oozie.service.JPAService.jdbc.password", "templateName": [], @@ -323,6 +323,7 @@ module.exports = [ "value": " ", "filename": "oozie-site.xml" }, + */ { "name": "javax.jdo.option.ConnectionURL", "templateName": ["hive_mysql_host", "hive_database_name"], diff --git a/ambari-web/app/data/config_properties.js b/ambari-web/app/data/config_properties.js index 5a6d97604a..e9382ad9b8 100644 --- a/ambari-web/app/data/config_properties.js +++ b/ambari-web/app/data/config_properties.js @@ -73,6 +73,7 @@ module.exports = "description": "The host that has been assigned to run HBase Master", "displayType": "masterHost", "isVisible": true, + "domain": "global", "serviceName": "HBASE", "category": "HBase Master" }, @@ -86,6 +87,7 @@ module.exports = "displayType": "slaveHosts", "isVisible": true, "isRequired": false, + "domain": "regionserver-global", "serviceName": "HBASE", "category": "RegionServer" }, @@ -98,6 +100,7 @@ module.exports = "isReconfigurable": false, "displayType": "directory", "isVisible": true, + "domain": "global", "serviceName": "HBASE", "category": "Advanced" }, @@ -110,6 +113,7 @@ module.exports = "isReconfigurable": false, "displayType": "directory", "isVisible": true, + "domain": "global", "serviceName": "HBASE", "category": "Advanced" }, @@ -122,6 +126,7 @@ module.exports = "displayType": "int", "unit": "MB", "isVisible": true, + "domain": "regionserver-global", "serviceName": "HBASE", "category": "RegionServer" }, @@ -134,6 +139,7 @@ module.exports = "displayType": "int", "unit": "MB", "isVisible": true, + "domain": "global", "serviceName": "HBASE", "category": "HBase Master" }, @@ -145,6 +151,7 @@ module.exports = "defaultValue": "3", "displayType": "int", "isVisible": true, + "domain": "global", "serviceName": "HBASE" }, { @@ -155,6 +162,7 @@ module.exports = "defaultValue": "0.25", "displayType": "float", "isVisible": true, + "domain": "global", "serviceName": "HBASE" }, { @@ -166,6 +174,7 @@ module.exports = "displayType": "int", "unit": "bytes", "isVisible": true, + "domain": "global", "serviceName": "HBASE" }, { @@ -176,6 +185,7 @@ module.exports = "defaultValue": "30", "displayType": "int", "isVisible": true, + "domain": "regionserver-global", "serviceName": "HBASE", "category": "RegionServer" }, @@ -188,6 +198,7 @@ module.exports = "displayType": "int", "unit": "ms", "isVisible": true, + "domain": "regionserver-global", "serviceName": "HBASE", "category": "RegionServer" }, @@ -199,6 +210,7 @@ module.exports = "defaultValue": "2", "displayType": "int", "isVisible": true, + "domain": "regionserver-global", "serviceName": "HBASE", "category": "RegionServer" }, @@ -211,6 +223,7 @@ module.exports = "displayType": "int", "unit": "bytes", "isVisible": true, + "domain": "regionserver-global", "serviceName": "HBASE", "category": "RegionServer" }, @@ -223,6 +236,7 @@ module.exports = "displayType": "int", "unit": "rows", "isVisible": true, + "domain": "global", "serviceName": "HBASE" }, { @@ -234,6 +248,7 @@ module.exports = "displayType": "int", "unit": "ms", "isVisible": true, + "domain": "global", "serviceName": "HBASE" }, { @@ -245,6 +260,7 @@ module.exports = "displayType": "int", "unit": "bytes", "isVisible": true, + "domain": "global", "serviceName": "HBASE" }, /* { @@ -268,6 +284,7 @@ module.exports = "isRequired": true, "displayType": "advanced", "isVisible": false, + "domain": "global", "serviceName": "HBASE", "category": "Advanced" }, @@ -280,6 +297,7 @@ module.exports = "isRequired": false, "displayType": "advanced", "isVisible": false, + "domain": "global", "serviceName": "HBASE", "category": "Advanced" }, @@ -292,6 +310,7 @@ module.exports = "isRequired": false, "displayType": "checkbox", "isVisible": true, + "domain": "global", "serviceName": "HBASE", "category": "Advanced" }, @@ -304,6 +323,7 @@ module.exports = "isRequired": false, "displayType": "checkbox", "isVisible": true, + "domain": "global", "serviceName": "HBASE", "category": "Advanced" }, @@ -316,6 +336,7 @@ module.exports = "isRequired": false, "displayType": "checkbox", "isVisible": true, + "domain": "global", "serviceName": "HBASE", "category": "Advanced" }, @@ -330,6 +351,7 @@ module.exports = "isRequired": true, "displayType": "init", "isVisible": true, + "domain": "global", "serviceName": "HBASE", "category": "Advanced" }, @@ -342,6 +364,7 @@ module.exports = "isRequired": false, "displayType": "checkbox", "isVisible": false, + "domain": "global", "serviceName": "HBASE", "category": "Advanced" }, @@ -354,6 +377,7 @@ module.exports = "isRequired": false, "displayType": "float", "isVisible": false, + "domain": "global", "serviceName": "HBASE", "category": "Advanced" }, @@ -366,6 +390,7 @@ module.exports = "isRequired": true, "displayType": "float", "isVisible": false, + "domain": "global", "serviceName": "HBASE", "category": "Advanced" }, @@ -378,6 +403,7 @@ module.exports = "isRequired": false, "displayType": "directory", "isVisible": false, + "domain": "global", "serviceName": "MISC", "category": "General" }, @@ -390,6 +416,7 @@ module.exports = "description": "The host that has been assigned to run NameNode", "displayType": "masterHost", "isVisible": true, + "domain": "global", "serviceName": "HDFS", "category": "NameNode" }, @@ -399,9 +426,11 @@ module.exports = "displayName": "NameNode directories", "description": "NameNode directories for HDFS to store the file system image", "defaultValue": "/grid/0/hadoop/hdfs/namenode\n/grid/1/hadoop/hdfs/namenode\n", + "defaultDirectory": "hadoop/hdfs/namenode", "isReconfigurable": false, "displayType": "directories", "isVisible": true, + "domain": "global", "serviceName": "HDFS", "category": "NameNode" }, @@ -414,6 +443,7 @@ module.exports = "description": "The host that has been assigned to run SecondaryNameNode", "displayType": "masterHost", "isVisible": true, + "domain": "global", "serviceName": "HDFS", "category": "SNameNode" }, @@ -423,9 +453,11 @@ module.exports = "displayName": "SecondaryNameNode Checkpoint directory", "description": "Directory on the local filesystem where the Secondary NameNode should store the temporary images to merge", "defaultValue": "/grid/0/hadoop/hdfs/namesecondary", + "defaultDirectory": "hadoop/hdfs/namesecondary", "isReconfigurable": false, "displayType": "directory", "isVisible": true, + "domain": "global", "serviceName": "HDFS", "category": "SNameNode" }, @@ -439,6 +471,7 @@ module.exports = "displayType": "slaveHosts", "isRequired": false, "isVisible": true, + "domain": "datanode-global", "serviceName": "HDFS", "category": "DataNode" }, @@ -448,9 +481,11 @@ module.exports = "displayName": "DataNode directories", "description": "DataNode directories for HDFS to store the data blocks", "defaultValue": "/tmp/hadoop-hdfs/dfs/data", + "defaultDirectory": "hadoop-hdfs/dfs/data", "isReconfigurable": false, "displayType": "directories", "isVisible": true, + "domain": "datanode-global", "serviceName": "HDFS", "category": "DataNode" }, @@ -463,6 +498,7 @@ module.exports = "isReconfigurable": false, "displayType": "directory", "isVisible": true, + "domain": "global", "serviceName": "HDFS", "category": "Advanced" }, @@ -475,6 +511,7 @@ module.exports = "isReconfigurable": false, "displayType": "directory", "isVisible": true, + "domain": "global", "serviceName": "HDFS", "category": "Advanced" }, @@ -486,6 +523,7 @@ module.exports = "defaultValue": true, "displayType": "checkbox", "isVisible": true, + "domain": "global", "serviceName": "HDFS" }, { @@ -496,6 +534,7 @@ module.exports = "defaultValue": false, "displayType": "checkbox", "isVisible": true, + "domain": "global", "serviceName": "HDFS" }, { @@ -507,6 +546,7 @@ module.exports = "displayType": "int", "unit": "MB", "isVisible": true, + "domain": "global", "serviceName": "HDFS" }, { @@ -518,6 +558,7 @@ module.exports = "displayType": "int", "unit": "MB", "isVisible": true, + "domain": "global", "serviceName": "HDFS", "category": "NameNode" }, @@ -530,6 +571,7 @@ module.exports = "displayType": "int", "unit": "MB", "isVisible": true, + "domain": "global", "serviceName": "HDFS", "category": "NameNode" }, @@ -542,6 +584,7 @@ module.exports = "displayType": "int", "unit": "MB", "isVisible": false, + "domain": "global", "serviceName": "HDFS", "category": "NameNode" }, @@ -554,6 +597,7 @@ module.exports = "displayType": "int", "unit": "GB", "isVisible": true, + "domain": "global", "serviceName": "HDFS" }, { @@ -565,6 +609,7 @@ module.exports = "displayType": "int", "unit": "MB", "isVisible": true, + "domain": "datanode-global", "serviceName": "HDFS", "category": "DataNode" }, @@ -576,6 +621,7 @@ module.exports = "defaultValue": "0", "displayType": "int", "isVisible": true, + "domain": "datanode-global", "serviceName": "HDFS", "category": "DataNode" }, @@ -589,6 +635,7 @@ module.exports = "displayType": "int", "unit": "seconds", "isVisible": true, + "domain": "global", "filename": "core-site.xml", "serviceName": "HDFS" }, @@ -603,6 +650,7 @@ module.exports = "displayType": "float", "unit": "GB", "isVisible": true, + "domain": "global", "filename": "core-site.xml", "serviceName": "HDFS" }, @@ -616,6 +664,7 @@ module.exports = "displayType": "advanced", "isVisible": true, "filename": "core-site.xml", + "domain": "global", "serviceName": "MISC", "category": "Users and Groups" }, @@ -629,6 +678,7 @@ module.exports = "displayType": "advanced", "isVisible": true, "filename": "hdfs-site.xml", + "domain": "global", "serviceName": "HDFS", "category": "Advanced" }, @@ -642,6 +692,7 @@ module.exports = "displayType": "advanced", "isVisible": true, "filename": "hdfs-site.xml", + "domain": "global", "serviceName": "HDFS", "category": "Advanced" }, @@ -655,6 +706,7 @@ module.exports = "isReconfigurable": false, "isVisible": true, "filename": "hdfs-site.xml", + "domain": "global", "serviceName": "HDFS", "category": "Advanced" }, @@ -668,6 +720,7 @@ module.exports = "isReconfigurable": false, "isVisible": true, "filename": "hdfs-site.xml", + "domain": "global", "serviceName": "HDFS", "category": "Advanced" }, @@ -681,6 +734,7 @@ module.exports = "displayType": "int", "isVisible": true, "filename": "hdfs-site.xml", + "domain": "global", "serviceName": "MISC", "category": "Advanced" }, @@ -694,6 +748,7 @@ module.exports = "displayType": "int", "isVisible": true, "filename": "hdfs-site.xml", + "domain": "global", "serviceName": "MISC", "category": "Advanced" }, @@ -707,6 +762,7 @@ module.exports = "displayType": "int", "isVisible": true, "filename": "hdfs-site.xml", + "domain": "global", "serviceName": "MISC", "category": "Advanced" }, @@ -720,6 +776,7 @@ module.exports = "displayType": "int", "isVisible": false, "filename": "hdfs-site.xml", + "domain": "global", "serviceName": "HDFS", "category": "Advanced" }, @@ -732,6 +789,7 @@ module.exports = "isRequired": false, "displayType": "checkbox", "isVisible": false, + "domain": "global", "serviceName": "HDFS", "category": "Advanced" }, @@ -743,6 +801,7 @@ module.exports = "defaultValue": "EXAMPLE.COM", "isRequired": true, "isVisible": false, + "domain": "global", "serviceName": "HDFS", "category": "Advanced" }, @@ -755,6 +814,7 @@ module.exports = "isRequired": true, "displayType": "password", "isVisible": false, + "domain": "global", "serviceName": "HDFS", "category": "Advanced" }, @@ -767,6 +827,7 @@ module.exports = "isRequired": true, "displayType": "advanced", "isVisible": false, + "domain": "global", "serviceName": "HDFS", "category": "Advanced" }, @@ -794,6 +855,7 @@ module.exports = "serviceName": "HIVE", "category": "Hive Metastore" }, + /* Comment out the other hive_database and uncomment this for Hive with Postgres support { "id": "puppet var", "name": "hive_database", @@ -810,10 +872,64 @@ module.exports = foreignKeys: ['hive_existing_database', 'hive_existing_host'] } ], - "description": "PostgreSQL will be installed by ambari. Any other database will have to be installed by the user.", + "description": "PostgreSQL will be installed by Ambari. Any other database will have to be installed by the user.", + "displayType": "radio button", + "radioName": "hive-database", + "isVisible": true, + "domain": "global", + "serviceName": "HIVE", + "category": "Hive Metastore" + }, + */ + { + "id": "puppet var", + "name": "hive_database", + "displayName": "Hive Database", + "value": "", + "defaultValue": "New MySQL Database", + "options": [ + { + displayName: 'New MySQL Database', + foreignKeys: ['hive_ambari_database', 'hive_ambari_host'] + }, + { + displayName: 'Existing MySQL Database', + foreignKeys: ['hive_existing_database', 'hive_existing_host'] + } + ], + "description": "MySQL will be installed by Ambari", "displayType": "radio button", "radioName": "hive-database", "isVisible": true, + "domain": "global", + "serviceName": "HIVE", + "category": "Hive Metastore" + }, + { + "id": "puppet var", + "name": "hive_existing_database", + "displayName": "Database Type", + "value": "", + "defaultValue": "MySQL", + "description": "Using an existing database for Hive Metastore", + "displayType": "masterHost", + "isVisible": false, + "domain": "global", + "serviceName": "HIVE", + "category": "Hive Metastore" + }, + /* Uncomment for Hive with Postgres support + { + "id": "puppet var", + "name": "hive_existing_database", + "displayName": "Hive Database", + "value": "", + "defaultValue": "MySQL", + "description": "Select the database, if you already have existing one for Hive Metastore.", + "displayType": "string", + "isVisible": false, + "options": ['MySQL', 'PostgreSQL'], + "domain": "global", "serviceName": "HIVE", "category": "Hive Metastore" }, @@ -827,30 +943,34 @@ module.exports = "displayType": "combobox", "isVisible": false, "options": ['MySQL', 'PostgreSQL'], + "domain": "global", "serviceName": "HIVE", "category": "Hive Metastore" }, + */ { "id": "puppet var", "name": "hive_existing_host", "displayName": "Database host", - "description": "Select the host on which the existing database is hosted.", + "description": "Specify the host on which the existing database is hosted", "defaultValue": "", "isReconfigurable": false, "displayType": "host", "isVisible": false, + "domain": "global", "serviceName": "HIVE", "category": "Hive Metastore" }, { "id": "puppet var", "name": "hive_ambari_database", - "displayName": "Hive Database", + "displayName": "Database Type", "value": "", - "defaultValue": "PostgreSQL", - "description": "PostgreSQL will be installed by ambari.", + "defaultValue": "MySQL", + "description": "MySQL will be installed by Ambari", "displayType": "masterHost", "isVisible": true, + "domain": "global", "serviceName": "HIVE", "category": "Hive Metastore" }, @@ -860,10 +980,11 @@ module.exports = "value": "", "defaultValue": "", "displayName": "PostgreSQL host", - "description": "Host on which the PostgreSQL database will be created by ambari. ", + "description": "Host on which the PostgreSQL database will be created by Ambari", "isReconfigurable": false, "displayType": "masterHost", "isVisible": true, + "domain": "global", "serviceName": "HIVE", "category": "Hive Metastore" }, @@ -876,6 +997,7 @@ module.exports = "isReconfigurable": false, "displayType": "host", "isVisible": true, + "domain": "global", "serviceName": "HIVE", "category": "Hive Metastore" }, @@ -888,6 +1010,7 @@ module.exports = "isReconfigurable": false, "displayType": "user", "isVisible": true, + "domain": "global", "serviceName": "HIVE", "category": "Hive Metastore" }, @@ -900,6 +1023,7 @@ module.exports = "isReconfigurable": false, "displayType": "password", "isVisible": true, + "domain": "global", "serviceName": "HIVE", "category": "Hive Metastore" }, @@ -912,6 +1036,7 @@ module.exports = "isReconfigurable": false, "displayType": "int", "isVisible": false, + "domain": "global", "serviceName": "HIVE", "category": "Advanced" }, @@ -924,6 +1049,7 @@ module.exports = "isReconfigurable": false, "displayType": "directory", "isVisible": false, + "domain": "global", "serviceName": "HIVE", "category": "Advanced" }, @@ -936,6 +1062,7 @@ module.exports = "isReconfigurable": false, "displayType": "directory", "isVisible": false, + "domain": "global", "serviceName": "HIVE", "category": "Advanced" }, @@ -948,6 +1075,7 @@ module.exports = "isReconfigurable": false, "displayType": "directory", "isVisible": false, + "domain": "global", "serviceName": "HIVE", "category": "Advanced" }, @@ -960,6 +1088,7 @@ module.exports = "isReconfigurable": false, "displayType": "directory", "isVisible": false, + "domain": "global", "serviceName": "HIVE", "category": "Advanced" }, @@ -972,6 +1101,7 @@ module.exports = "isReconfigurable": false, "displayType": "directory", "isVisible": true, + "domain": "global", "serviceName": "HIVE", "category": "Advanced" }, @@ -984,6 +1114,7 @@ module.exports = "isReconfigurable": false, "displayType": "advanced", "isVisible": false, + "domain": "global", "serviceName": "MISC", "category": "General" }, @@ -996,6 +1127,7 @@ module.exports = "isReconfigurable": false, "displayType": "advanced", "isVisible": false, + "domain": "global", "serviceName": "MISC", "category": "General" }, @@ -1008,6 +1140,7 @@ module.exports = "isReconfigurable": false, "displayType": "directory", "isVisible": false, + "domain": "global", "serviceName": "HIVE", "category": "Advanced" }, @@ -1020,6 +1153,7 @@ module.exports = "isReconfigurable": false, "displayType": "directory", "isVisible": false, + "domain": "global", "serviceName": "HIVE", "category": "Advanced" }, @@ -1032,6 +1166,7 @@ module.exports = "isReconfigurable": false, "displayType": "directory", "isVisible": false, + "domain": "global", "serviceName": "GANGLIA", "category": "Advanced" }, @@ -1044,6 +1179,7 @@ module.exports = "isReconfigurable": false, "displayType": "directory", "isVisible": false, + "domain": "global", "serviceName": "MISC", "category": "General" }, @@ -1056,6 +1192,7 @@ module.exports = "isReconfigurable": false, "displayType": "advanced", "isVisible": false, + "domain": "global", "serviceName": "MISC", "category": "Users and Groups" }, @@ -1068,6 +1205,7 @@ module.exports = "isReconfigurable": false, "displayType": "advanced", "isVisible": false, + "domain": "global", "serviceName": "MISC", "category": "Users and Groups" }, @@ -1080,6 +1218,7 @@ module.exports = "isReconfigurable": false, "displayType": "directory", "isVisible": false, + "domain": "global", "serviceName": "MISC", "category": "General" }, @@ -1092,6 +1231,7 @@ module.exports = "isReconfigurable": false, "displayType": "advanced", "isVisible": false, + "domain": "global", "serviceName": "MISC", "category": "General" }, @@ -1104,6 +1244,7 @@ module.exports = "isReconfigurable": false, "displayType": "directory", "isVisible": true, + "domain": "global", "serviceName": "HIVE", "category": "Advanced" }, @@ -1116,6 +1257,7 @@ module.exports = "isReconfigurable": false, "displayType": "directory", "isVisible": true, + "domain": "global", "serviceName": "HIVE", "category": "Advanced" }, @@ -1140,6 +1282,7 @@ module.exports = "description": "The host that has been assigned to run JobTracker", "displayType": "masterHost", "isVisible": true, + "domain": "global", "serviceName": "MAPREDUCE", "category": "JobTracker" }, @@ -1153,6 +1296,7 @@ module.exports = "displayType": "slaveHosts", "isVisible": true, "isRequired": false, + "domain": "tasktracker-global", "serviceName": "MAPREDUCE", "category": "TaskTracker" }, @@ -1162,9 +1306,11 @@ module.exports = "displayName": "MapReduce local directories", "description": "Directories for MapReduce to store intermediate data files", "defaultValue": "/grid/0/hadoop/mapred\n/grid/1/hadoop/mapred\n", + "defaultDirectory": "hadoop/mapred", "displayType": "directories", "isReconfigurable": false, "isVisible": true, + "domain": "tasktracker-global", "serviceName": "MAPREDUCE", "category": "TaskTracker" }, @@ -1178,6 +1324,7 @@ module.exports = "isReconfigurable": false, "isVisible": true, "isRequired": false, + "domain": "global", "serviceName": "MAPREDUCE", "category": "Advanced" }, @@ -1200,6 +1347,7 @@ module.exports = "displayType": "int", "unit": "MB", "isVisible": true, + "domain": "global", "serviceName": "MAPREDUCE", "category": "JobTracker" }, @@ -1212,6 +1360,7 @@ module.exports = "displayType": "int", "unit": "MB", "isVisible": true, + "domain": "global", "serviceName": "MAPREDUCE", "category": "JobTracker" }, @@ -1224,6 +1373,7 @@ module.exports = "displayType": "int", "unit": "MB", "isVisible": true, + "domain": "global", "serviceName": "MAPREDUCE", "category": "JobTracker" }, @@ -1235,6 +1385,7 @@ module.exports = "defaultValue": "4", "displayType": "int", "isVisible": true, + "domain": "tasktracker-global", "serviceName": "MAPREDUCE", "category": "TaskTracker" }, @@ -1247,6 +1398,7 @@ module.exports = "displayType": "int", "isVisible": true, "isRequired": false, + "domain": "tasktracker-global", "serviceName": "MAPREDUCE", "category": "TaskTracker" }, @@ -1259,6 +1411,7 @@ module.exports = "displayType": "int", "unit": "MB", "isVisible": true, + "domain": "global", "serviceName": "MAPREDUCE" }, { @@ -1270,6 +1423,7 @@ module.exports = "displayType": "int", "unit": "MB", "isVisible": true, + "domain": "global", "serviceName": "MAPREDUCE" }, { @@ -1281,6 +1435,7 @@ module.exports = "displayType": "int", "unit": "MB", "isVisible": true, + "domain": "global", "serviceName": "MAPREDUCE" }, { @@ -1292,6 +1447,7 @@ module.exports = "displayType": "int", "unit": "MB", "isVisible": true, + "domain": "global", "serviceName": "MAPREDUCE" }, { @@ -1303,6 +1459,7 @@ module.exports = "displayType": "int", "unit": "MB", "isVisible": true, + "domain": "global", "serviceName": "MAPREDUCE" }, { @@ -1314,6 +1471,7 @@ module.exports = "displayType": "int", "unit": "MB", "isVisible": true, + "domain": "global", "serviceName": "MAPREDUCE" }, { @@ -1325,6 +1483,7 @@ module.exports = "displayType": "int", "unit": "MB", "isVisible": true, + "domain": "tasktracker-global", "serviceName": "MAPREDUCE", "category": "TaskTracker" }, @@ -1337,6 +1496,7 @@ module.exports = "displayType": "int", "unit": "MB", "isVisible": true, + "domain": "global", "serviceName": "MAPREDUCE" }, { @@ -1347,6 +1507,7 @@ module.exports = "defaultValue": "0.9", "displayType": "float", "isVisible": true, + "domain": "global", "serviceName": "MAPREDUCE" }, { @@ -1358,6 +1519,7 @@ module.exports = "displayType": "int", "unit": "hours", "isVisible": true, + "domain": "global", "serviceName": "MAPREDUCE" }, { @@ -1368,6 +1530,7 @@ module.exports = "defaultValue": "-1", "displayType": "int", "isVisible": true, + "domain": "global", "serviceName": "MAPREDUCE" }, { @@ -1378,6 +1541,7 @@ module.exports = "defaultValue": false, "displayType": "checkbox", "isVisible": true, + "domain": "global", "serviceName": "MAPREDUCE" }, { @@ -1389,6 +1553,7 @@ module.exports = "isReconfigurable": false, "displayType": "checkbox", "isVisible": true, + "domain": "global", "serviceName": "MAPREDUCE" }, { @@ -1400,6 +1565,7 @@ module.exports = "isReconfigurable": true, "displayType": "checkbox", "isVisible": true, + "domain": "global", "serviceName": "MAPREDUCE" }, /*{ @@ -1423,6 +1589,7 @@ module.exports = "displayType": "directories", "isVisible": false, "serviceName": "MAPREDUCE", + "domain": "global", "category": "Advanced" }, { @@ -1434,6 +1601,7 @@ module.exports = "displayType": "directories", "isVisible": false, "serviceName": "MAPREDUCE", + "domain": "global", "category": "Advanced" }, { @@ -1445,6 +1613,7 @@ module.exports = "displayType": "advanced", "isVisible": false, "serviceName": "MAPREDUCE", + "domain": "global", "category": "Advanced" }, { @@ -1456,6 +1625,7 @@ module.exports = "displayType": "advanced", "isVisible": false, "serviceName": "MAPREDUCE", + "domain": "global", "category": "Advanced" }, /* @@ -1476,12 +1646,13 @@ module.exports = "id": "puppet var", "name": "java64_home", "displayName": "Path to 64-bit JAVA_HOME", - "description": "Path to 64-bit JAVA_HOME", - "defaultValue": "", - "isRequired": false, + "description": "Path to 64-bit JAVA_HOME. /usr/jdk/jdk1.6.0_31 is the default used by Ambari. You can override this to a specific path that contains the JDK. Note that the path must be valid on ALL hosts in your cluster.", + "defaultValue": "/usr/jdk64/jdk1.6.0_31", + "isRequired": true, "isReconfigurable": false, "displayType": "directory", "isVisible": true, + "domain": "global", "serviceName": "MISC" }, { @@ -1494,6 +1665,7 @@ module.exports = "isReconfigurable": false, "displayType": "directory", "isVisible": false, + "domain": "global", "serviceName": "MISC", "category": "Advanced" }, @@ -1507,6 +1679,7 @@ module.exports = "isReconfigurable": false, "displayType": "directory", "isVisible": false, + "domain": "global", "serviceName": "MISC", "category": "Advanced" }, @@ -1520,6 +1693,7 @@ module.exports = "isReconfigurable": false, "displayType": "directory", "isVisible": false, + "domain": "global", "serviceName": "HDFS", "category": "NameNode" }, @@ -1533,6 +1707,7 @@ module.exports = "isReconfigurable": false, "displayType": "directory", "isVisible": false, + "domain": "global", "serviceName": "HDFS", "category": "Advanced" }, @@ -1546,6 +1721,7 @@ module.exports = "isReconfigurable": false, "displayType": "directory", "isVisible": false, + "domain": "global", "serviceName": "MISC" }, { @@ -1558,6 +1734,7 @@ module.exports = "isReconfigurable": false, "displayType": "directory", "isVisible": false, + "domain": "global", "serviceName": "MISC" }, { @@ -1570,6 +1747,7 @@ module.exports = "isReconfigurable": false, "displayType": "directory", "isVisible": false, + "domain": "global", "serviceName": "MISC" }, { @@ -1582,6 +1760,7 @@ module.exports = "isReconfigurable": false, "displayType": "directory", "isVisible": false, + "domain": "global", "serviceName": "MISC" }, /* @@ -1607,7 +1786,6 @@ module.exports = "isVisible": true, "serviceName": "MISC", "category": "Advanced" }, - */ { "id": "puppet var", "name": "using_local_repo", @@ -1616,7 +1794,8 @@ module.exports = "defaultValue": false, "isReconfigurable": false, "displayType": "checkbox", - "isVisible": true, + "isVisible": false, + "domain": "global", "serviceName": "MISC" }, { @@ -1628,8 +1807,10 @@ module.exports = "isReconfigurable": false, "displayType": "directory", "isVisible": true, + "domain": "global", "serviceName": "MISC" }, + */ { "id": "puppet var", "name": "hdfs_user", @@ -1640,6 +1821,7 @@ module.exports = "displayType": "user", "isVisible": true, "serviceName": "MISC", + "domain": "global", "category": "Users and Groups" }, { @@ -1651,6 +1833,7 @@ module.exports = "isReconfigurable": false, "displayType": "user", "isVisible": true, + "domain": "global", "serviceName": "MISC", "category": "Users and Groups" }, @@ -1663,6 +1846,7 @@ module.exports = "isReconfigurable": false, "displayType": "user", "isVisible": true, + "domain": "global", "serviceName": "MISC", "category": "Users and Groups" }, @@ -1675,6 +1859,7 @@ module.exports = "isReconfigurable": false, "displayType": "user", "isVisible": true, + "domain": "global", "serviceName": "MISC", "category": "Users and Groups" }, @@ -1687,6 +1872,7 @@ module.exports = "isReconfigurable": false, "displayType": "user", "isVisible": true, + "domain": "global", "serviceName": "MISC", "category": "Users and Groups" }, @@ -1699,6 +1885,7 @@ module.exports = "isReconfigurable": false, "displayType": "user", "isVisible": true, + "domain": "global", "serviceName": "MISC", "category": "Users and Groups" }, @@ -1711,6 +1898,7 @@ module.exports = "isReconfigurable": false, "displayType": "user", "isVisible": true, + "domain": "global", "serviceName": "MISC", "category": "Users and Groups" }, @@ -1723,6 +1911,7 @@ module.exports = "isReconfigurable": false, "displayType": "directory", "isVisible": false, + "domain": "global", "serviceName": "MISC", "category": "General" }, @@ -1735,6 +1924,7 @@ module.exports = "isReconfigurable": false, "displayType": "directory", "isVisible": false, + "domain": "global", "serviceName": "MISC", "category": "General" }, @@ -1747,6 +1937,7 @@ module.exports = "isReconfigurable": false, "displayType": "user", "isVisible": true, + "domain": "global", "serviceName": "MISC", "category": "Users and Groups" }, @@ -1759,6 +1950,7 @@ module.exports = "isReconfigurable": false, "displayType": "directory", "isVisible": false, + "domain": "global", "serviceName": "MISC", "category": "General" }, @@ -1771,6 +1963,7 @@ module.exports = "isReconfigurable": false, "displayType": "directory", "isVisible": false, + "domain": "global", "serviceName": "MISC", "category": "General" }, @@ -1783,6 +1976,7 @@ module.exports = "isReconfigurable": false, "displayType": "user", "isVisible": true, + "domain": "global", "serviceName": "MISC", "category": "Users and Groups" }, @@ -1795,6 +1989,7 @@ module.exports = "isReconfigurable": false, "displayType": "user", "isVisible": true, + "domain": "global", "serviceName": "MISC", "category": "Users and Groups" }, @@ -1807,6 +2002,7 @@ module.exports = "isReconfigurable": false, "displayType": "user", "isVisible": true, + "domain": "global", "serviceName": "MISC", "category": "Users and Groups" }, @@ -1818,6 +2014,7 @@ module.exports = "defaultValue": "nagios", "isReconfigurable": false, "displayType": "user", + "domain": "global", "isVisible": false, "serviceName": "NAGIOS" }, @@ -1829,6 +2026,7 @@ module.exports = "defaultValue": "nagios", "isReconfigurable": false, "displayType": "user", + "domain": "global", "isVisible": false, "serviceName": "NAGIOS" }, @@ -1840,6 +2038,7 @@ module.exports = "defaultValue": "nagiosadmin", "isReconfigurable": false, "displayType": "user", + "domain": "global", "isVisible": true, "serviceName": "NAGIOS" }, @@ -1852,6 +2051,7 @@ module.exports = "isReconfigurable": false, "displayType": "password", "isVisible": true, + "domain": "global", "serviceName": "NAGIOS" }, { @@ -1862,6 +2062,7 @@ module.exports = "defaultValue": "", "displayType": "email", "isVisible": true, + "domain": "global", "serviceName": "NAGIOS" }, { @@ -1873,6 +2074,7 @@ module.exports = "description": "The host that has been assigned to run Oozie Server", "displayType": "masterHost", "isVisible": true, + "domain": "global", "serviceName": "OOZIE", "category": "Oozie Server" }, @@ -1997,6 +2199,7 @@ module.exports = "displayType": "directory", "isVisible": true, "isRequired": false, + "domain": "global", "serviceName": "OOZIE", "category": "Oozie Server" }, @@ -2009,6 +2212,7 @@ module.exports = "isReconfigurable": false, "displayType": "directory", "isVisible": true, + "domain": "global", "serviceName": "OOZIE", "category": "Advanced" }, @@ -2021,6 +2225,7 @@ module.exports = "isReconfigurable": false, "displayType": "directory", "isVisible": true, + "domain": "global", "serviceName": "OOZIE", "category": "Advanced" }, @@ -2043,9 +2248,11 @@ module.exports = "displayName": "ZooKeeper directory", "description": "Data directory for ZooKeeper", "defaultValue": "/grid/0/hadoop/zookeeper", + "defaultDirectory": "hadoop/zookeeper", "isReconfigurable": false, "displayType": "directory", "isVisible": true, + "domain": "global", "serviceName": "ZOOKEEPER", "category": "ZooKeeper Server" }, @@ -2058,6 +2265,7 @@ module.exports = "isReconfigurable": false, "displayType": "directory", "isVisible": true, + "domain": "global", "serviceName": "ZOOKEEPER", "category": "Advanced" }, @@ -2070,6 +2278,7 @@ module.exports = "isReconfigurable": false, "displayType": "directory", "isVisible": true, + "domain": "global", "serviceName": "ZOOKEEPER", "category": "Advanced" }, @@ -2082,6 +2291,7 @@ module.exports = "isReconfigurable": false, "displayType": "directory", "isVisible": false, + "domain": "global", "serviceName": "ZOOKEEPER", "category": "Advanced" }, @@ -2094,6 +2304,7 @@ module.exports = "displayType": "int", "unit": "ms", "isVisible": true, + "domain": "global", "serviceName": "ZOOKEEPER", "category": "ZooKeeper Server" }, @@ -2105,6 +2316,7 @@ module.exports = "defaultValue": "10", "displayType": "int", "isVisible": true, + "domain": "global", "serviceName": "ZOOKEEPER", "category": "ZooKeeper Server" }, @@ -2116,6 +2328,7 @@ module.exports = "defaultValue": "5", "displayType": "int", "isVisible": true, + "domain": "global", "serviceName": "ZOOKEEPER", "category": "ZooKeeper Server" }, @@ -2127,6 +2340,7 @@ module.exports = "defaultValue": "2181", "displayType": "int", "isVisible": true, + "domain": "global", "serviceName": "ZOOKEEPER", "category": "ZooKeeper Server" }, @@ -2138,6 +2352,7 @@ module.exports = "defaultValue": "/etc/conf/", "displayType": "directory", "isVisible": false, + "domain": "global", "serviceName": "MISC", "category": "General" } diff --git a/ambari-web/app/data/service_components.js b/ambari-web/app/data/service_components.js index 0feebb5450..6b68e7090a 100644 --- a/ambari-web/app/data/service_components.js +++ b/ambari-web/app/data/service_components.js @@ -164,13 +164,21 @@ module.exports = new Ember.Set([ }, { service_name: 'HIVE', - component_name: 'HIVE_MYSQL', + component_name: 'MYSQL_SERVER', display_name: 'MySql Server for Hive', isMaster: false, isClient: false, description: 'The slave for HBase' }, { + service_name: 'HCATALOG', + component_name: 'HCAT', + display_name: 'HCat Client', + isMaster: false, + isClient: true, + description: '' + }, + { service_name: 'TEMPLETON', component_name: 'TEMPLETON_SERVER', display_name: 'Templeton Server', diff --git a/ambari-web/app/data/service_configs.js b/ambari-web/app/data/service_configs.js index 5f18c4cfc0..4e9112175b 100644 --- a/ambari-web/app/data/service_configs.js +++ b/ambari-web/app/data/service_configs.js @@ -107,7 +107,7 @@ module.exports = [ serviceName: 'MISC', displayName: 'Misc', configCategories: [ - // App.ServiceConfigCategory.create({ name: 'General'}), + App.ServiceConfigCategory.create({ name: 'General'}), App.ServiceConfigCategory.create({ name: 'Users and Groups'}) ], configs: configProperties.filterProperty('serviceName', 'MISC') diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js index 7b1c7814f4..53c87c1d13 100644 --- a/ambari-web/app/messages.js +++ b/ambari-web/app/messages.js @@ -62,6 +62,7 @@ Em.I18n.translations = { 'installer.step2.hostName.error.required':'You must specify at least one host name', 'installer.step2.hostName.error.notRequired':'Host Names will be ignored if not using SSH to automatically configure hosts', 'installer.step2.hostName.error.invalid':'Invalid Host Name(s) - cannot start or end with a hyphen', + 'installer.step2.hostName.pattern.header':'Host name pattern expressions', 'installer.step2.sshKey':'Host Connectivity Information', 'installer.step2.sshKey.info':'Provide your SSH Private Key (<b>id_rsa</b> for <b>root</b>)', 'installer.step2.sshKey.error.required':'SSH Private Key is required', @@ -74,13 +75,11 @@ Em.I18n.translations = { 'installer.step2.localRepo.header':'Software Repository', 'installer.step2.localRepo.label':'Use a local software repository', 'installer.step2.localRepo.error.required':'Local repository file path is required', - 'installer.step2.localRepo.info':'The repository configuration file should be installed on each host in your cluster. ' + - 'This file instructs the package manager to use your local software repository to retrieve software packages, instead of ' + - 'downloading them from the internet.', + 'installer.step2.localRepo.info':'Instructs the package manager to use your local software repository to retrieve software packages, instead of ' + + 'downloading from the internet.', 'installer.step2.localRepo.tooltip.title':'Local Software Repository', - 'installer.step2.localRepo.tooltip.content':'The repository configuration file should be installed on each host ' + - 'in your cluster. This file instructs package manager to use your local' + - 'software repository to retrieve software packages, instead of using the internet.', + 'installer.step2.localRepo.tooltip.content':'Instructs the package manager to use your local software repository to retrieve software packages, instead of' + + 'downloading from the internet.', 'installer.step2.manualInstall.tooltip.title':'Not Using SSH (Manual Install)', 'installer.step2.manualInstall.tooltip.content':'If you do not wish Ambari to automatically configure the target hosts via SSH,' + ' you have the option of configuring them yourself. This involves installing and starting Ambari Agent on each of your target hosts.', @@ -88,17 +87,18 @@ Em.I18n.translations = { 'installer.step2.manualInstall.popup.body':'You must install Ambari Agents on each host you want to manage before you proceed. <a href="#" target="_blank">Learn more</a>', 'installer.step3.header':'Confirm Hosts', - 'installer.step3.body':'Here are the results of the host discovery process.<br>' + - 'Please verify and remove the ones that you do not want to be part of the cluster.', - 'installer.step3.hostLog.popup.header':'Bootstrap log for {0}', + 'installer.step3.body':'Registering your hosts.<br>' + + 'Please confirm the host list and remove any hosts you do not want to include the cluster.', + 'installer.step3.hostLog.popup.header':'Registration log for {0}', 'installer.step3.hosts.remove.popup.header':'Remove Hosts', 'installer.step3.hosts.remove.popup.body':'Are you sure you want to remove the selected host(s)?', 'installer.step3.hosts.retry.popup.header':'Retry Host Discovery', 'installer.step3.hosts.retry.popup.body':'Are you sure you want to retry discovery of the selected host(s)?', + 'installer.step3.hosts.summary' : 'Installing: %@, Registering: %@, Successful: %@, Failed: %@ ', 'installer.step3.hostInformation.popup.header':'Error in retrieving host Information', 'installer.step3.hostInformation.popup.body' : 'All bootstrapped hosts registered but unable to retrieve cpu and memory related information', 'installer.step4.header':'Choose Services', - 'installer.step4.body':'Choose which services you want to install on your cluster.<br>Note that some services have dependencies (e.g., HBase requires ZooKeeper.)', + 'installer.step4.body':'Choose which services you want to install on your cluster.', 'installer.step4.mapreduceCheck.popup.header':'MapReduce Needed', 'installer.step4.mapreduceCheck.popup.body':'You did not select MapReduce, but it is needed by other services you selected. We will automatically add MapReduce. Is this OK?', 'installer.step4.monitoringCheck.popup.header':'Limited Functionality Warning', @@ -109,7 +109,7 @@ Em.I18n.translations = { 'installer.step5.body':'Assign master components to hosts you want to run them on.', 'installer.step6.header':'Assign Slaves and Clients', - 'installer.step6.body':'Assign slave and client components to hosts you want to run them on. <br/>Client component will install ', + 'installer.step6.body':'Assign slave and client components to hosts you want to run them on.<br/>Hosts that are assigned master components are shown with <i class=icon-asterisks>✵</i>. <br/>"Client" will install ', 'installer.step6.error.mustSelectOne':'You must assign at least one host to each.', 'installer.step7.header':'Customize Services', diff --git a/ambari-web/app/models/hosts.js b/ambari-web/app/models/hosts.js index da2a3428d6..85feab5433 100644 --- a/ambari-web/app/models/hosts.js +++ b/ambari-web/app/models/hosts.js @@ -27,10 +27,12 @@ App.HostInfo = Ember.Object.extend({ barColor: 'progress-info', isChecked: true, bootLog:null, - bootStatus:'RUNNING', + bootStatus: 'PENDING', bootStatusForDisplay:function () { switch (this.get('bootStatus')) { + case 'PENDING': + return 'Preparing'; case 'REGISTERED': return 'Success'; case 'FAILED': @@ -50,6 +52,7 @@ App.HostInfo = Ember.Object.extend({ return 'progress-success'; case 'FAILED': return 'progress-danger'; + case 'PENDING': case 'RUNNING': case 'DONE': case 'REGISTERING': @@ -64,6 +67,7 @@ App.HostInfo = Ember.Object.extend({ return 'text-success'; case 'FAILED': return 'text-error'; + case 'PENDING': case 'RUNNING': case 'DONE': case 'REGISTERING': @@ -77,6 +81,7 @@ App.HostInfo = Ember.Object.extend({ case 'REGISTERED': case 'FAILED': return true; + case 'PENDING': case 'RUNNING': case 'DONE': case 'REGISTERING': @@ -85,6 +90,4 @@ App.HostInfo = Ember.Object.extend({ } }.property('bootStatus') - /* horizonData: - [{"cpu":"61","date":"2012-09-05T11:03:00+03:00","id":"0","memory":"44","name":"Node-0.0","network":"36","status":"LIVE","rackName":"Rack-0","io":"23"},{"cpu":"1","date":"2012-09-05T11:06:00+03:00","id":"0","memory":"46","name":"Node-0.0","network":"54","status":"LIVE","rackName":"Rack-0","io":"96"},{"cpu":"36","date":"2012-09-05T11:09:00+03:00","id":"0","memory":"65","name":"Node-0.0","network":"42","status":"LIVE","rackName":"Rack-0","io":"49"},{"cpu":"50","date":"2012-09-05T11:12:00+03:00","id":"0","memory":"46","name":"Node-0.0","network":"76","status":"LIVE","rackName":"Rack-0","io":"67"},{"cpu":"79","date":"2012-09-05T11:15:00+03:00","id":"0","memory":"91","name":"Node-0.0","network":"14","status":"LIVE","rackName":"Rack-0","io":"47"},{"cpu":"65","date":"2012-09-05T11:18:00+03:00","id":"0","memory":"44","name":"Node-0.0","network":"90","status":"LIVE","rackName":"Rack-0","io":"74"},{"cpu":"42","date":"2012-09-05T11:21:00+03:00","id":"0","memory":"96","name":"Node-0.0","network":"29","status":"LIVE","rackName":"Rack-0","io":"6"},{"cpu":"76","date":"2012-09-05T11:24:00+03:00","id":"0","memory":"28","name":"Node-0.0","network":"52","status":"LIVE","rackName":"Rack-0","io":"1"},{"cpu":"24","date":"2012-09-05T11:27:00+03:00","id":"0","memory":"66","name":"Node-0.0","network":"75","status":"LIVE","rackName":"Rack-0","io":"31"},{"cpu":"71","date":"2012-09-05T11:30:00+03:00","id":"0","memory":"8","name":"Node-0.0","network":"1","status":"LIVE","rackName":"Rack-0","io":"36"},{"cpu":"3","date":"2012-09-05T11:33:00+03:00","id":"0","memory":"57","name":"Node-0.0","network":"12","status":"LIVE","rackName":"Rack-0","io":"71"},{"cpu":"85","date":"2012-09-05T11:36:00+03:00","id":"0","memory":"44","name":"Node-0.0","network":"76","status":"LIVE","rackName":"Rack-0","io":"54"},{"cpu":"49","date":"2012-09-05T11:39:00+03:00","id":"0","memory":"8","name":"Node-0.0","network":"28","status":"LIVE","rackName":"Rack-0","io":"60"},{"cpu":"46","date":"2012-09-05T11:42:00+03:00","id":"0","memory":"75","name":"Node-0.0","network":"7","status":"LIVE","rackName":"Rack-0","io":"86"},{"cpu":"61","date":"2012-09-05T11:45:00+03:00","id":"0","memory":"11","name":"Node-0.0","network":"65","status":"LIVE","rackName":"Rack-0","io":"65"},{"cpu":"5","date":"2012-09-05T11:48:00+03:00","id":"0","memory":"24","name":"Node-0.0","network":"14","status":"LIVE","rackName":"Rack-0","io":"62"},{"cpu":"30","date":"2012-09-05T11:51:00+03:00","id":"0","memory":"40","name":"Node-0.0","network":"52","status":"LIVE","rackName":"Rack-0","io":"98"},{"cpu":"5","date":"2012-09-05T11:54:00+03:00","id":"0","memory":"38","name":"Node-0.0","network":"17","status":"LIVE","rackName":"Rack-0","io":"27"},{"cpu":"22","date":"2012-09-05T11:57:00+03:00","id":"0","memory":"80","name":"Node-0.0","network":"62","status":"LIVE","rackName":"Rack-0","io":"38"}] */ }); diff --git a/ambari-web/app/models/service_config.js b/ambari-web/app/models/service_config.js index 22d4cfc87c..1238807896 100644 --- a/ambari-web/app/models/service_config.js +++ b/ambari-web/app/models/service_config.js @@ -106,6 +106,7 @@ App.ServiceConfigProperty = Ember.Object.extend({ displayName: '', value: '', defaultValue: '', + defaultDirectory: '', description: '', displayType: 'string', // string, digits, number, directories, custom unit: '', @@ -127,6 +128,8 @@ App.ServiceConfigProperty = Ember.Object.extend({ initialValue: function () { var masterComponentHostsInDB = App.db.getMasterComponentHosts(); //console.log("value in initialvalue: " + JSON.stringify(masterComponentHostsInDB)); + var hostsInfo = App.db.getHosts(); // which we are setting in installerController in step3. + var isOnlyFirstOneNeeded = true; switch (this.get('name')) { case 'namenode_host': var temp = masterComponentHostsInDB.findProperty('component', 'NAMENODE'); @@ -156,9 +159,112 @@ App.ServiceConfigProperty = Ember.Object.extend({ case 'zookeeperserver_hosts': this.set('value', masterComponentHostsInDB.findProperty('component', 'ZOOKEEPER_SERVER').hostName); break; + case 'dfs_name_dir': + case 'dfs_data_dir': + case 'mapred_local_dir': + this.unionAllMountPoints( !isOnlyFirstOneNeeded ); + break; + case 'fs_checkpoint_dir': + case 'zk_data_dir' : + this.unionAllMountPoints( isOnlyFirstOneNeeded ); + break; } }, + unionAllMountPoints : function( isOnlyFirstOneNeeded ){ + var datanode_hostname = ''; + var mountPointsPerHost = []; + var mountPointsAsRoot = []; + var mountPointsAsBoot = []; + var mountPointsAsHome = []; + var mountPointsFortmpfs = []; + var mountPointsForVboxsf = []; + var masterComponentHostsInDB = App.db.getMasterComponentHosts(); + var slaveComponentHostsInDB = App.db.getSlaveComponentHosts(); + var hostsInfo = App.db.getHosts(); // which we are setting in installerController in step3. + var temp = ''; + var setOfHostNames = []; + switch(this.get('name')){ + case 'dfs_name_dir': + var components = masterComponentHostsInDB.filterProperty('component', 'NAMENODE'); + components.forEach(function(component){ + setOfHostNames.push(component.hostName); + },this); + break; + case 'fs_checkpoint_dir': + var components = masterComponentHostsInDB.filterProperty('component', 'SECONDARY_NAMENODE'); + components.forEach(function(component){ + setOfHostNames.push(component.hostName); + },this); + break; + case 'dfs_data_dir': + temp = slaveComponentHostsInDB.findProperty('componentName', 'DATANODE'); + temp.hosts.forEach(function(host){ + setOfHostNames.push(host.hostName); + },this); + break; + + case 'mapred_local_dir': + temp = slaveComponentHostsInDB.findProperty('componentName', 'TASKTRACKER'); + temp.hosts.forEach(function(host){ + setOfHostNames.push(host.hostName); + },this); + break; + + case 'zk_data_dir': + var components = masterComponentHostsInDB.filterProperty('component', 'ZOOKEEPER_SERVER'); + components.forEach(function(component){ + setOfHostNames.push(component.hostName); + },this); + break; + } + var allMountPoints = []; + for(var i = 0; i < setOfHostNames.length; i++ ){ + datanode_hostname = setOfHostNames[i]; + mountPointsPerHost = hostsInfo[datanode_hostname].disk_info; + mountPointsAsRoot = mountPointsPerHost.filterProperty('mountpoint', '/'); + mountPointsAsBoot = mountPointsPerHost.filterProperty('mountpoint', '/boot'); + mountPointsAsHome = mountPointsPerHost.filterProperty('mountpoint', '/home'); + mountPointsFortmpfs = mountPointsPerHost.filterProperty('type', 'tmpfs'); + mountPointsForVboxsf = mountPointsPerHost.filterProperty('type', 'vboxsf'); + + var mountPointsToBeIgnored = []; + mountPointsToBeIgnored.push(mountPointsAsRoot); + mountPointsToBeIgnored.push(mountPointsAsBoot); + mountPointsToBeIgnored.push(mountPointsAsHome); + + mountPointsFortmpfs.forEach(function(mpoint){ + mountPointsToBeIgnored.push(mpoint); + },this); + mountPointsForVboxsf.forEach(function(mpoint){ + mountPointsToBeIgnored.push(mpoint); + },this); + + mountPointsPerHost = mountPointsPerHost.removeAll(mountPointsToBeIgnored); + + mountPointsPerHost.forEach(function(mPoint){ + allMountPoints.push(mPoint); + },this); + } + if( allMountPoints.length == 0 ){ + allMountPoints.push(mountPointsAsRoot[0]); + } + this.set('value',''); + if( !isOnlyFirstOneNeeded ){ + allMountPoints.forEach(function(eachDrive){ + var mPoint = this.get('value'); + if(!mPoint) + mPoint = ""; + mPoint += ( eachDrive.mountpoint + this.get('defaultDirectory') + "\n" ); + this.set('value', mPoint); + this.set('defaultValue', mPoint ); + },this); + } else{ + this.set('value', allMountPoints[0].mountpoint + this.get('defaultDirectory') ); + this.set('defaultValue', allMountPoints[0].mountpoint + this.get('defaultDirectory') ); + } + + }, isValid: function () { return this.get('errorMessage') === ''; }.property('errorMessage'), diff --git a/ambari-web/app/router.js b/ambari-web/app/router.js index 1bfaadd2d7..9e8f315688 100644 --- a/ambari-web/app/router.js +++ b/ambari-web/app/router.js @@ -255,18 +255,53 @@ App.Router = Em.Router.extend({ return 'installer'; } }, + logOff: function(context){ - console.log('logging off'); + var hash = window.btoa(this.get('loginController.loginName') + ":" + this.get('loginController.password')); + // App.db.cleanUp() must be called before router.clearAllSteps(). // otherwise, this.set('installerController.currentStep, 0) would have no effect // since it's a computed property but we are not setting it as a dependent of App.db. App.db.cleanUp(); this.clearAllSteps(); - console.log("Log off: " + App.db.getClusterName()); + console.log("Log off: " + App.router.getClusterName()); this.set('loginController.loginName', ''); this.set('loginController.password', ''); + + if (!App.testMode) { + $.ajax({ + url: App.apiPrefix + '/logout', + dataType: 'json', + type: 'GET', + beforeSend: function (xhr) { + xhr.setRequestHeader("Authorization", "Basic " + hash); + }, + statusCode: { + 200: function () { + console.log("Status code 200: Success."); + }, + 401: function () { + console.log("Error code 401: Unauthorized."); + }, + 403: function () { + console.log("Error code 403: Forbidden."); + } + }, + success: function (data) { + console.log("invoked logout on the server successfully"); + }, + error: function (data) { + console.log("failed to invoke logout on the server"); + }, + complete: function () { + console.log('done'); + } + }); + } + this.transitionTo('login', context); }, + root: Em.Route.extend({ index: Em.Route.extend({ route: '/', diff --git a/ambari-web/app/routes/add_host_routes.js b/ambari-web/app/routes/add_host_routes.js index bdfceef4a5..4c3cdc93ad 100644 --- a/ambari-web/app/routes/add_host_routes.js +++ b/ambari-web/app/routes/add_host_routes.js @@ -32,6 +32,7 @@ module.exports = Em.Route.extend({ }), primary:Em.I18n.t('form.cancel'), secondary: null, + showFooter: false, onPrimary:function () { this.hide(); @@ -57,15 +58,19 @@ module.exports = Em.Route.extend({ connectOutlets: function (router) { console.log('in addHost.step1:connectOutlets'); var controller = router.get('addHostController'); - controller.setCurrentStep('1', false); + controller.setCurrentStep('1'); controller.set('hideBackButton', true); controller.dataLoading().done(function () { - controller.loadAllPriorSteps(); - controller.connectOutlet('wizardStep2', controller.get('content.hosts')); + controller.loadAllPriorSteps(); + controller.connectOutlet('wizardStep2', controller.get('content')); }) }, next: function (router) { + var controller = router.get('addHostController'); + var wizardStep2Controller = router.get('wizardStep2Controller'); + wizardStep2Controller.patternExpression(); + controller.saveHosts(wizardStep2Controller); router.transitionTo('step2'); App.db.setBootStatus(false); }, @@ -77,7 +82,6 @@ module.exports = Em.Route.extend({ wizardStep2Controller.set('hasSubmitted', true); if (!wizardStep2Controller.get('isSubmitDisabled')) { - addHostController.saveHosts(wizardStep2Controller); wizardStep2Controller.evaluateStep(); } } @@ -88,7 +92,7 @@ module.exports = Em.Route.extend({ connectOutlets: function (router) { console.log('in addHost.step2:connectOutlets'); var controller = router.get('addHostController'); - controller.setCurrentStep('2', false); + controller.setCurrentStep('2'); controller.dataLoading().done(function () { controller.loadAllPriorSteps(); controller.connectOutlet('wizardStep3', controller.get('content')); @@ -122,7 +126,7 @@ module.exports = Em.Route.extend({ connectOutlets: function (router, context) { console.log('in addHost.step3:connectOutlets'); var controller = router.get('addHostController'); - controller.setCurrentStep('3', false); + controller.setCurrentStep('3'); controller.dataLoading().done(function () { controller.loadAllPriorSteps(); controller.connectOutlet('wizardStep6', controller.get('content')); @@ -148,7 +152,7 @@ module.exports = Em.Route.extend({ connectOutlets: function (router) { console.log('in addHost.step4:connectOutlets'); var controller = router.get('addHostController'); - controller.setCurrentStep('4', false); + controller.setCurrentStep('4'); controller.dataLoading().done(function () { controller.loadAllPriorSteps(); controller.connectOutlet('wizardStep7', controller.get('content')); @@ -168,7 +172,7 @@ module.exports = Em.Route.extend({ connectOutlets: function (router, context) { console.log('in addHost.step5:connectOutlets'); var controller = router.get('addHostController'); - controller.setCurrentStep('5', false); + controller.setCurrentStep('5'); controller.dataLoading().done(function () { controller.loadAllPriorSteps(); controller.connectOutlet('wizardStep8', controller.get('content')); @@ -189,7 +193,7 @@ module.exports = Em.Route.extend({ connectOutlets: function (router, context) { console.log('in addHost.step6:connectOutlets'); var controller = router.get('addHostController'); - controller.setCurrentStep('6', false); + controller.setCurrentStep('6'); controller.dataLoading().done(function () { controller.loadAllPriorSteps(); if (!App.testMode) { //if test mode is ON don't disable prior steps link. @@ -228,7 +232,7 @@ module.exports = Em.Route.extend({ connectOutlets: function (router, context) { console.log('in addHost.step7:connectOutlets'); var controller = router.get('addHostController'); - controller.setCurrentStep('7', false); + controller.setCurrentStep('7'); controller.dataLoading().done(function () { controller.loadAllPriorSteps(); controller.connectOutlet('wizardStep10', controller.get('content')); diff --git a/ambari-web/app/routes/add_service_routes.js b/ambari-web/app/routes/add_service_routes.js index 9eb1a2aff2..248d3796d9 100644 --- a/ambari-web/app/routes/add_service_routes.js +++ b/ambari-web/app/routes/add_service_routes.js @@ -31,6 +31,7 @@ module.exports = Em.Route.extend({ controllerBinding: 'App.router.addServiceController' }), primary:Em.I18n.t('form.cancel'), + showFooter: false, secondary: null, onPrimary:function () { @@ -62,7 +63,7 @@ module.exports = Em.Route.extend({ connectOutlets: function (router) { console.log('in addService.step1:connectOutlets'); var controller = router.get('addServiceController'); - controller.setCurrentStep('1', false); + controller.setCurrentStep('1'); controller.set('hideBackButton', true); controller.dataLoading().done(function () { controller.loadAllPriorSteps(); @@ -84,7 +85,7 @@ module.exports = Em.Route.extend({ connectOutlets: function (router) { console.log('in addService.step2:connectOutlets'); var controller = router.get('addServiceController'); - controller.setCurrentStep('2', false); + controller.setCurrentStep('2'); controller.set('hideBackButton', false); controller.dataLoading().done(function () { controller.loadAllPriorSteps(); @@ -107,7 +108,7 @@ module.exports = Em.Route.extend({ connectOutlets: function (router) { console.log('in addService.step3:connectOutlets'); var controller = router.get('addServiceController'); - controller.setCurrentStep('3', false); + controller.setCurrentStep('3'); controller.dataLoading().done(function () { controller.loadAllPriorSteps(); controller.connectOutlet('wizardStep6', controller.get('content')); @@ -140,7 +141,7 @@ module.exports = Em.Route.extend({ connectOutlets: function (router) { console.log('in addService.step4:connectOutlets'); var controller = router.get('addServiceController'); - controller.setCurrentStep('4', false); + controller.setCurrentStep('4'); controller.dataLoading().done(function () { controller.loadAllPriorSteps(); controller.connectOutlet('wizardStep7', controller.get('content')); @@ -169,7 +170,7 @@ module.exports = Em.Route.extend({ connectOutlets: function (router, context) { console.log('in addService.step5:connectOutlets'); var controller = router.get('addServiceController'); - controller.setCurrentStep('5', false); + controller.setCurrentStep('5'); controller.dataLoading().done(function () { controller.loadAllPriorSteps(); controller.connectOutlet('wizardStep8', controller.get('content')); @@ -190,7 +191,7 @@ module.exports = Em.Route.extend({ connectOutlets: function (router, context) { console.log('in addService.step6:connectOutlets'); var controller = router.get('addServiceController'); - controller.setCurrentStep('6', false); + controller.setCurrentStep('6'); controller.dataLoading().done(function () { controller.loadAllPriorSteps(); if (!App.testMode) { //if test mode is ON don't disable prior steps link. @@ -229,7 +230,7 @@ module.exports = Em.Route.extend({ connectOutlets: function (router, context) { console.log('in addService.step7:connectOutlets'); var controller = router.get('addServiceController'); - controller.setCurrentStep('7', false); + controller.setCurrentStep('7'); controller.dataLoading().done(function () { controller.loadAllPriorSteps(); controller.connectOutlet('wizardStep10', controller.get('content')); diff --git a/ambari-web/app/routes/installer.js b/ambari-web/app/routes/installer.js index d72e3dad7e..f448872950 100644 --- a/ambari-web/app/routes/installer.js +++ b/ambari-web/app/routes/installer.js @@ -72,15 +72,14 @@ module.exports = Em.Route.extend({ connectOutlets: function (router) { console.log('in installer.step1:connectOutlets'); var controller = router.get('installerController'); - controller.setCurrentStep('1', false); + controller.setCurrentStep('1'); controller.loadAllPriorSteps(); controller.connectOutlet('wizardStep1', controller.get('content')); }, next: function (router) { var installerController = router.get('installerController'); - var wizardStep1Controller = router.get('wizardStep1Controller'); - installerController.saveClusterInfo(wizardStep1Controller); + installerController.save('cluster'); installerController.clearHosts(); router.transitionTo('step2'); } @@ -92,14 +91,15 @@ module.exports = Em.Route.extend({ router.setNavigationFlow('step2'); var controller = router.get('installerController'); - controller.setCurrentStep('2', false); + controller.setCurrentStep('2'); controller.loadAllPriorSteps(); - controller.connectOutlet('wizardStep2', controller.get('content.hosts')); + controller.connectOutlet('wizardStep2', controller.get('content')); }, back: Em.Router.transitionTo('step1'), next: function (router) { var controller = router.get('installerController'); var wizardStep2Controller = router.get('wizardStep2Controller'); + wizardStep2Controller.patternExpression(); controller.saveHosts(wizardStep2Controller); router.transitionTo('step3'); App.db.setBootStatus(false); @@ -114,7 +114,6 @@ module.exports = Em.Route.extend({ wizardStep2Controller.set('hasSubmitted', true); if (!wizardStep2Controller.get('isSubmitDisabled')) { - App.db.setBootStatus(false); wizardStep2Controller.evaluateStep(); } } @@ -125,7 +124,7 @@ module.exports = Em.Route.extend({ connectOutlets: function (router) { console.log('in installer.step3:connectOutlets'); var controller = router.get('installerController'); - controller.setCurrentStep('3', false); + controller.setCurrentStep('3'); controller.loadAllPriorSteps(); controller.connectOutlet('wizardStep3', controller.get('content')); }, @@ -134,7 +133,6 @@ module.exports = Em.Route.extend({ var installerController = router.get('installerController'); var wizardStep3Controller = router.get('wizardStep3Controller'); installerController.saveConfirmedHosts(wizardStep3Controller); - App.db.setSshKey(null); App.db.setBootStatus(true); var displayOrderConfig = require('data/services'); var apiUrl = '/stacks/HDP/version/1.2.0'; @@ -161,7 +159,7 @@ module.exports = Em.Route.extend({ connectOutlets: function (router, context) { router.setNavigationFlow('step4'); var controller = router.get('installerController'); - controller.setCurrentStep('4', false); + controller.setCurrentStep('4'); controller.loadAllPriorSteps(); controller.loadServices(); controller.connectOutlet('wizardStep4', controller.get('content.services')); @@ -186,7 +184,7 @@ module.exports = Em.Route.extend({ var controller = router.get('installerController'); var wizardStep5Controller = router.get('wizardStep5Controller'); - controller.setCurrentStep('5', false); + controller.setCurrentStep('5'); controller.loadAllPriorSteps(); controller.connectOutlet('wizardStep5', controller.get('content')); }, @@ -206,7 +204,7 @@ module.exports = Em.Route.extend({ router.setNavigationFlow('step6'); var controller = router.get('installerController'); - controller.setCurrentStep('6', false); + controller.setCurrentStep('6'); controller.loadAllPriorSteps(); controller.connectOutlet('wizardStep6', controller.get('content')); }, @@ -233,7 +231,7 @@ module.exports = Em.Route.extend({ enter: function (router) { console.log('in /wizardStep7Controller:enter'); var controller = router.get('installerController'); - controller.setCurrentStep('7', false); + controller.setCurrentStep('7'); controller.loadAllPriorSteps(); }, connectOutlets: function (router, context) { @@ -254,7 +252,7 @@ module.exports = Em.Route.extend({ connectOutlets: function (router, context) { console.log('in installer.step8:connectOutlets'); var controller = router.get('installerController'); - controller.setCurrentStep('8', false); + controller.setCurrentStep('8'); controller.loadAllPriorSteps(); controller.connectOutlet('wizardStep8', controller.get('content')); }, @@ -274,7 +272,7 @@ module.exports = Em.Route.extend({ connectOutlets: function (router, context) { console.log('in installer.step9:connectOutlets'); var controller = router.get('installerController'); - controller.setCurrentStep('9', false); + controller.setCurrentStep('9'); controller.loadAllPriorSteps(); if (!App.testMode) { // if test mode is ON don't disable prior steps link. controller.setLowerStepsDisable(9); @@ -311,7 +309,7 @@ module.exports = Em.Route.extend({ connectOutlets: function (router, context) { console.log('in installer.step10:connectOutlets'); var controller = router.get('installerController'); - controller.setCurrentStep('10', false); + controller.setCurrentStep('10'); controller.loadAllPriorSteps(); controller.connectOutlet('wizardStep10', controller.get('content')); }, diff --git a/ambari-web/app/routes/main.js b/ambari-web/app/routes/main.js index a7bbcc4f89..029a17768a 100644 --- a/ambari-web/app/routes/main.js +++ b/ambari-web/app/routes/main.js @@ -259,7 +259,7 @@ module.exports = Em.Route.extend({ }, showDetails:function (router, event) { router.get('mainHostDetailsController').setBack(true); - router.transitionTo('hosts.hostDetails.index', event.context) + router.transitionTo('hosts.hostDetails.summary', event.context); }, filterHosts:function (router, component) { router.transitionTo('hosts'); @@ -335,7 +335,7 @@ module.exports = Em.Route.extend({ }, showDetails:function (router, event) { router.get('mainHostDetailsController').setBack(true); - router.transitionTo('hosts.hostDetails.index', event.context) + router.transitionTo('hosts.hostDetails.summary', event.context); } }), showService:Em.Router.transitionTo('service'), diff --git a/ambari-web/app/styles/application.less b/ambari-web/app/styles/application.less index 628ab558b2..1ce5e0a8c6 100644 --- a/ambari-web/app/styles/application.less +++ b/ambari-web/app/styles/application.less @@ -52,10 +52,6 @@ footer { padding: 20px 0; } -.modal-body { - max-height: 500px; -} - #top-nav { .navbar { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; @@ -194,6 +190,22 @@ h1 { color: #5AB400; } +.icon-empty { + height: 21px; + display: inline-block; + width: 8px; +} + +.icon-caret-right { + min-width:8px; + padding-top: 2px; +} + +.icon-caret-left { + min-width:8px; + padding-top: 2px; +} + .icon-remove { color: #FF4B4B; } @@ -291,10 +303,10 @@ h1 { width: 30%; } th.status { - width: 40%; + width: 30%; } th.messgage { - width: 30%; + width: 40%; } .progress-bar { width: 80%; @@ -528,7 +540,7 @@ a:focus { } table.table { margin-top: 14px; - color: #7b7b7b; + color: #666; font-size: 13px; //width: 80%; tr > td:first-child { @@ -576,7 +588,7 @@ a:focus { #summary-info { border-top: none; border-collapse: collapse; - color: #7B7B7B; + color: #666; font-size: 13px; td.summary-label { @@ -678,9 +690,10 @@ a:focus { } .modal-graph-line { - width: 750px; + width: 790px; .modal-body { - min-height: 320px !important; + min-height: 420px !important; + overflow: hidden; } } @@ -691,16 +704,38 @@ a:focus { cursor: pointer; cursor:-moz-zoom-in; cursor:-webkit-zoom-in; + &.chart-container-popup { - cursor: auto; + cursor: auto !important; + margin-left: 0; + overflow: visible; + width: 650px; + .chart { + left: 60px; + overflow: visible; + position: relative; + } + .chart-y-axis { + position: absolute; + top: -15px; + bottom: 0; + width: 60px; + } + .chart-legend { + left: 60px; + top: 245px; + } + .x_tick { + .title { + margin-top: 35px !important; + } + } } position: relative; margin: 20px 15px 0px 15px; .chart { - padding-bottom: 0px !important; position: relative; - height: 160px; z-index: 1; } .chart-y-axis { @@ -718,11 +753,30 @@ a:focus { width: 30%; z-index: 2; } + .x_tick { + margin-top: 5px; + .title { + padding: 0 2px 0 2px; + opacity: 1 !important; + top: 148px; + } + } + svg { + g { + g:nth-child(1) { + display: none; + } + } + } + text{ + font-weight: 700; + opacity: 1 !important; + } .chart-legend { font-family: 'Courier New'; position: absolute; top: 180px; - z-index: 2; + z-index: 3; } .rickshaw_legend { background-color: #999999 !important; @@ -984,6 +1038,9 @@ a:focus { div.view-wrapper { float: left; + .btn-group{ + margin-bottom: 9px; + } } a.ui-icon-circle-close { @@ -1193,6 +1250,12 @@ a:focus { } .background-operations { + .progress { + margin-bottom: 5px; + .bar { + width: 100%; + } + } .open-details { clear: left; display: block; @@ -1835,6 +1898,14 @@ ul.inline li { } } +.screensaver{ + width: 90%; + height: 160px; + border: 1px solid silver; + margin: 20px 15px 10px 15px; + background: url(/img/spinner.gif) no-repeat center center; +} + /* TIME RANGE WIDGET END */ #host-details .host-components .btn-group > .btn { @@ -1927,3 +1998,46 @@ ul.inline li { } } } + + +// +// Gray palette +// +.nav-pills > .active > a, .nav-pills > .active > a:hover { + background-color: #666666; +} + +.nav-list > .active > a, .nav-list > .active > a:hover { + background-color: #666666; +} + +.alert-info { + background-color: #E6F1F6; + border-color: #D2D9DD; + color: #4E575B; + text-shadow: none; +} + +/* +.progress-striped .bar { + background-color: #A5A5A5; +} + +.progress-info.progress-striped .bar, .progress-striped .bar-info { + background-color: #A5A5A5; +} +*/ + +.btn-primary:active, .btn-primary.active, .btn-primary.disabled, .btn-primary[disabled] { + background-color: #555555; +} + +#main-nav .brand { + background-color: #777777; + color: #FFFFFF; + text-shadow: none; +} + +.modal-body { + max-height: none; +}
\ No newline at end of file diff --git a/ambari-web/app/templates/application.hbs b/ambari-web/app/templates/application.hbs index 612796854a..b1558e8516 100644 --- a/ambari-web/app/templates/application.hbs +++ b/ambari-web/app/templates/application.hbs @@ -23,15 +23,11 @@ <div class="container"> <a {{translateAttr href="topnav.logo.href"}} target="_blank"><img id="logo" src="/img/logo-small.gif"></a> <a class="brand" {{translateAttr href="topnav.logo.href"}} target="_blank">{{t app.name}}</a> - {{#if isClusterDataLoaded}} - <a class="brand cluster-name" href="#"> - - {{clusterName}} - </a> - {{else}} - <a class="brand cluster-name" href="#"> - - Install Wizard - </a> - {{/if}} + {{#if App.router.loggedIn}} + <a class="brand cluster-name" href="#"> + - {{clusterName}} + </a> + {{/if}} <ul class="nav"> <li class="right"><a class="help" {{translateAttr href="topnav.help.href"}} target="_blank">Help</a></li> {{#if App.router.loggedIn}} diff --git a/ambari-web/app/templates/login.hbs b/ambari-web/app/templates/login.hbs index 479ba29b22..d6d60598ce 100644 --- a/ambari-web/app/templates/login.hbs +++ b/ambari-web/app/templates/login.hbs @@ -24,7 +24,7 @@ </div> {{/if}} <label>{{t login.username}}</label> - {{view Ember.TextField valueBinding="loginName" class="span4"}} + {{view view.loginTextField valueBinding="loginName" class="span4"}} <label>{{t login.password}}</label> {{view view.passTextField type="password" valueBinding="password" class="span4"}} <button class="btn btn-success" {{action "submit" target="controller"}}>{{t login.loginButton}}</button> diff --git a/ambari-web/app/templates/main.hbs b/ambari-web/app/templates/main.hbs index 473c64887a..6a1573ad56 100644 --- a/ambari-web/app/templates/main.hbs +++ b/ambari-web/app/templates/main.hbs @@ -21,17 +21,13 @@ <div class="navbar"> <div class="navbar-inner"> <a class="brand" href="#"> - {{#if clusterName}} - {{clusterName}} - {{else}} - My Cluster - {{/if}} - {{#view App.EmptyView controllerBinding="App.router.backgroundOperationsController"}} - {{#if allOperationsCount}} - <span class="label operations-count" {{action "showPopup" target="controller"}}>{{allOperationsCount}}</span> - {{/if}} - {{/view}} + {{clusterName}} + {{#view App.EmptyView controllerBinding="App.router.backgroundOperationsController"}} + {{#if allOperationsCount}} + <span class="label operations-count" {{action "showPopup" target="controller"}}>{{allOperationsCount}}</span> + {{/if}} + {{/view}} </a> {{view App.MainMenuView}} </div> diff --git a/ambari-web/app/templates/main/background_operations_popup.hbs b/ambari-web/app/templates/main/background_operations_popup.hbs index 75f61869c1..610256488f 100644 --- a/ambari-web/app/templates/main/background_operations_popup.hbs +++ b/ambari-web/app/templates/main/background_operations_popup.hbs @@ -18,30 +18,36 @@ {{#each operation in allOperations}} {{#view App.MainBackgroundOperation contentBinding="operation"}} +<div> + <a {{action showOperationLog target="view"}} href="#"> + <i {{bindAttr class="view.iconClass"}}></i> + {{#if view.isOpen}}Hide{{else}}Show{{/if}} info about {{operation.command}} {{operation.role}} + on {{operation.host_name}} + </a> + {{#if view.hasProgressBar}} + <div {{bindAttr class="view.isInProgress:progress-striped :active view.barColor :progress"}}> + <div class="bar"></div> + </div> + {{/if}} + <div class="content-area"> + <div class="textTrigger">click to highlight</div> + {{#if view.isOpen}} + {{#if view.isTextArea}} <div> - <a {{action showOperationLog target="view"}} href="#"> - <i {{bindAttr class="view.iconClass"}}></i> - {{#if view.isOpen}}Hide{{else}}Show{{/if}} info about {{operation.command}} {{operation.role}} on {{operation.host_name}} - </a> - <div class="content-area"> - <div class="textTrigger">click to highlight</div> - {{#if view.isOpen}} - {{#if view.isTextArea}} - <div> {{view view.textArea contentBinding="operation"}} - </div> - {{else}} - <div> - <h5>exitcode:</h5> - <pre class="stderr">{{operation.exit_code}}</pre> - <h5>stderr:</h5> - <pre class="stderr">{{highlight operation.stderr [err;fail]}}</pre> - <h5>stdout:</h5> - <pre class="stdout">{{highlight operation.stdout [err;fail]}}</pre> - </div> - {{/if}} - {{/if}} - </div> - </div> + </div> + {{else}} + <div> + <h5>exitcode:</h5> + <pre class="stderr">{{operation.exit_code}}</pre> + <h5>stderr:</h5> + <pre class="stderr">{{highlight operation.stderr [err;fail]}}</pre> + <h5>stdout:</h5> + <pre class="stdout">{{highlight operation.stdout [err;fail]}}</pre> + </div> + {{/if}} + {{/if}} + </div> +</div> {{/view}} {{/each}}
\ No newline at end of file diff --git a/ambari-web/app/templates/main/charts/linear_time.hbs b/ambari-web/app/templates/main/charts/linear_time.hbs index f89e26decc..b4ed659154 100644 --- a/ambari-web/app/templates/main/charts/linear_time.hbs +++ b/ambari-web/app/templates/main/charts/linear_time.hbs @@ -15,7 +15,11 @@ * See the License for the specific language governing permissions and * limitations under the License. }} -<div id="{{unbound view.id}}-container" class="chart-container" {{action showGraphInPopup target="view"}} title="Click to zoom"> + +<div class="screensaver chart-container" {{bindAttr class="view.isReady:hide"}} > + <div id="{{unbound view.id}}-title" class="chart-title">{{view.title}}</div> +</div> +<div id="{{unbound view.id}}-container" class="chart-container hide" {{bindAttr class="view.isReady:show"}} {{action showGraphInPopup target="view"}} title="Click to zoom"> <div id="{{unbound view.id}}-yaxis" class="chart-y-axis"></div> <div id="{{unbound view.id}}-xaxis" class="chart-x-axis"></div> <div id="{{unbound view.id}}-legend" class="chart-legend"></div> @@ -23,4 +27,4 @@ <div id="{{unbound view.id}}-timeline" class="timeline"></div> <div id="{{unbound view.id}}-title" class="chart-title">{{view.title}}</div> -</div>
\ No newline at end of file +</div> diff --git a/ambari-web/app/templates/main/dashboard/service/hive.hbs b/ambari-web/app/templates/main/dashboard/service/hive.hbs index 13e0bc85d9..7bd2161d42 100644 --- a/ambari-web/app/templates/main/dashboard/service/hive.hbs +++ b/ambari-web/app/templates/main/dashboard/service/hive.hbs @@ -16,7 +16,7 @@ * limitations under the License. }} -<div class="clearfix like_pointer"> +<div class="clearfix"> <div class="name span2"> {{view App.MainDashboardServiceHealthView serviceBinding="view.service"}} <a {{action selectService view.service href=true}}>{{view.service.displayName}}</a> diff --git a/ambari-web/app/templates/main/dashboard/service/oozie.hbs b/ambari-web/app/templates/main/dashboard/service/oozie.hbs index 13e0bc85d9..123466102f 100644 --- a/ambari-web/app/templates/main/dashboard/service/oozie.hbs +++ b/ambari-web/app/templates/main/dashboard/service/oozie.hbs @@ -16,8 +16,9 @@ * limitations under the License. }} -<div class="clearfix like_pointer"> +<div class="clearfix"> <div class="name span2"> + <i class="pull-left icon-empty"></i> {{view App.MainDashboardServiceHealthView serviceBinding="view.service"}} <a {{action selectService view.service href=true}}>{{view.service.displayName}}</a> {{#if view.criticalAlertsCount}} diff --git a/ambari-web/app/templates/main/dashboard/service/zookeeper.hbs b/ambari-web/app/templates/main/dashboard/service/zookeeper.hbs index 13e0bc85d9..123466102f 100644 --- a/ambari-web/app/templates/main/dashboard/service/zookeeper.hbs +++ b/ambari-web/app/templates/main/dashboard/service/zookeeper.hbs @@ -16,8 +16,9 @@ * limitations under the License. }} -<div class="clearfix like_pointer"> +<div class="clearfix"> <div class="name span2"> + <i class="pull-left icon-empty"></i> {{view App.MainDashboardServiceHealthView serviceBinding="view.service"}} <a {{action selectService view.service href=true}}>{{view.service.displayName}}</a> {{#if view.criticalAlertsCount}} diff --git a/ambari-web/app/templates/main/service/info/configs.hbs b/ambari-web/app/templates/main/service/info/configs.hbs index a4d13cbcc0..b5e923e679 100644 --- a/ambari-web/app/templates/main/service/info/configs.hbs +++ b/ambari-web/app/templates/main/service/info/configs.hbs @@ -140,9 +140,9 @@ <div class="accordion-group"> <div class="accordion-heading"> {{#if category.isCollapsed}} - <i class='icon-caret-left pull-right accordion-toggle'></i> + <i class='icon-caret-right pull-left accordion-toggle'></i> {{else}} - <i class='icon-caret-down pull-right accordion-toggle'></i> + <i class='icon-caret-down pull-left accordion-toggle'></i> {{/if}} <a class="accordion-toggle" {{action "onToggleBlock" category target="view"}}> {{category.name}} diff --git a/ambari-web/app/templates/main/service/info/summary.hbs b/ambari-web/app/templates/main/service/info/summary.hbs index 8c663c72de..3f53e35b2c 100644 --- a/ambari-web/app/templates/main/service/info/summary.hbs +++ b/ambari-web/app/templates/main/service/info/summary.hbs @@ -137,6 +137,7 @@ </div> </div> <div class="span6"> + {{#if view.hasAlertsBox }} <div class="box"> <div class="box-header"> <h4>Alerts and Health Checks</h4> @@ -162,6 +163,7 @@ {{/if}} </ul> </div> + {{/if}} </div> </div> {{#if view.serviceMetricGraphs.length}} diff --git a/ambari-web/app/templates/wizard/step2.hbs b/ambari-web/app/templates/wizard/step2.hbs index ea2675714e..e33dbffd99 100644 --- a/ambari-web/app/templates/wizard/step2.hbs +++ b/ambari-web/app/templates/wizard/step2.hbs @@ -34,20 +34,20 @@ </p> {{#if view.parentView.controller.hideBackButton}} - {{#if content.oldHostNames }} + {{#if content.hosts.oldHostNames }} <p class="alert alert-info"> {{t hosts.add.step2.warning}} <br/> - {{{content.oldHostNames}}} - {{#if content.showMoreHostsText}} - <a href="" {{action showMoreHosts target="view.parentView.controller"}}>{{content.showMoreHostsText}}</a> + {{{content.hosts.oldHostNames}}} + {{#if content.hosts.showMoreHostsText}} + <a href="" {{action showMoreHosts target="view.parentView.controller"}}>{{content.hosts.showMoreHostsText}}</a> {{/if}} </p> {{/if}} {{/if}} <div class="controls"> - {{view Ember.TextArea class="span6" valueBinding="content.hostNames" rows="5" placeholder="host names"}} + {{view Ember.TextArea class="span6" valueBinding="content.hosts.hostNames" rows="5" placeholder="host names"}} {{#if hostsError}} <p class="help-inline">{{hostsError}}</p> {{/if}} @@ -64,10 +64,11 @@ <div {{bindAttr class="sshKeyError:error :control-group"}}> {{#if view.isFileApi}} {{view App.SshKeyFileUploader}} - <pre {{bindAttr class="view.sshKeyPreviewClass"}}>{{content.sshKey}}</pre> + <pre {{bindAttr class="view.sshKeyPreviewClass"}}>{{content.hosts.sshKey}}</pre> {{/if}} <div class="controls"> - {{view Ember.TextArea class="span6" rows="4" classBinding="view.sshKeyClass" id="sshKey" placeholder="ssh private key" disabledBinding="view.sshKeyState" valueBinding="content.sshKey"}} + {{view Ember.TextArea class="span6" rows="4" classBinding="view.sshKeyClass" id="sshKey" + placeholder="ssh private key" disabledBinding="view.sshKeyState" valueBinding="content.hosts.sshKey"}} {{#if sshKeyError}} <span class="help-inline">{{sshKeyError}}</span> {{/if}} @@ -81,7 +82,7 @@ rel="popover" {{translateAttr title="installer.step2.manualInstall.tooltip.title" data-content="installer.step2.manualInstall.tooltip.content"}}> Learn more</a> - {{view Ember.Checkbox checkedBinding="content.manualInstall"}} + {{view Ember.Checkbox checkedBinding="content.hosts.manualInstall"}} </label> </div> @@ -92,11 +93,11 @@ {{/if}} <!-- - {{view Ember.TextField type="text" placeholder="passphrase" valueBinding="content.passphrase"}} + {{view Ember.TextField type="text" placeholder="passphrase" valueBinding="content.hosts.passphrase"}} <div {{bindAttr class="passphraseMatchErr:error :control-group :ambari-agents"}}> <div class="controls"> - {{view Ember.TextField type="text" placeholder="confirm passphrase" valueBinding="content.confirmPassphrase"}} + {{view Ember.TextField type="text" placeholder="confirm passphrase" valueBinding="content.hosts.confirmPassphrase"}} {{#if passphraseMatchErr}} <p class="help-inline">{{t installer.step2.passphrase.error.match}}</p> @@ -115,7 +116,7 @@ rel="popover" {{translateAttr title="installer.step2.localRepo.tooltip.title" data-content="installer.step2.localRepo.tooltip.content"}}> Learn more</a> - {{view Ember.Checkbox checkedBinding="content.localRepo"}} + {{view Ember.Checkbox checkedBinding="content.hosts.localRepo"}} </label> {{#if "localRepo"}} @@ -131,7 +132,7 @@ <a class="btn pull-left" {{action back}}>← Back</a> {{/unless}} <a class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}} {{action evaluateStep}}> - Discover and Validate →</a> + Register and Confirm →</a> </div> </div>
\ No newline at end of file diff --git a/ambari-web/app/templates/wizard/step3.hbs b/ambari-web/app/templates/wizard/step3.hbs index c0ed52b007..461e32ada2 100644 --- a/ambari-web/app/templates/wizard/step3.hbs +++ b/ambari-web/app/templates/wizard/step3.hbs @@ -20,20 +20,22 @@ <h2>{{t installer.step3.header}}</h2> <p class="alert alert-info">{{t installer.step3.body}}</p> - + <div>{{controller.hostStatusSummary}}</div> <div class="box"> <div class="box-header"> <div class="button-section"> - <a class="btn btn-primary decommission" {{bindAttr disabled="isRetryDisabled"}} - href="#" {{action retrySelectedHosts target="controller"}}><i - class="icon-repeat icon-white"></i> - Retry - </a> <a class="btn btn-primary" {{bindAttr disabled="noHostsSelected"}} href="#" {{action removeSelectedHosts target="controller" }}><i class="icon-trash icon-white"></i> - Remove + Remove Selected </a> + {{#unless isRetryDisabled}} + <a class="btn btn-primary decommission" + href="#" {{action retrySelectedHosts target="controller"}}><i + class="icon-repeat icon-white"></i> + Retry Failed + </a> + {{/unless}} {{#if App.testMode}} <a class="btn btn-info" href="#" {{action mockBtn target="controller" }}> @@ -47,12 +49,13 @@ <div id="host-filter" class="dropdown pull-right"> {{view Ember.Select class="pull-right" - contentBinding="controller.categories" - selectionBinding="controller.category" - }} + contentBinding="controller.categories" + optionValuePath="content.value" + optionLabelPath="content.label" + selectionBinding="controller.category" + }} <h5 class="pull-right">Show:</h5> </div> - </div> </div> diff --git a/ambari-web/app/templates/wizard/step7.hbs b/ambari-web/app/templates/wizard/step7.hbs index f29b0bf3d8..0682f15273 100644 --- a/ambari-web/app/templates/wizard/step7.hbs +++ b/ambari-web/app/templates/wizard/step7.hbs @@ -39,9 +39,9 @@ <div class="accordion-group {{unbound category.name}}"> <div class="accordion-heading" {{action "onToggleBlock" category target="view"}}> {{#if category.isCollapsed}} - <i class='icon-caret-left pull-right accordion-toggle'></i> + <i class='icon-caret-right pull-left accordion-toggle'></i> {{else}} - <i class='icon-caret-down pull-right accordion-toggle'></i> + <i class='icon-caret-down pull-left accordion-toggle'></i> {{/if}} <a class="accordion-toggle"> {{category.name}} diff --git a/ambari-web/app/utils/data_table.js b/ambari-web/app/utils/data_table.js index cd35beef49..dff63f3e80 100644 --- a/ambari-web/app/utils/data_table.js +++ b/ambari-web/app/utils/data_table.js @@ -58,9 +58,11 @@ jQuery.extend(jQuery.fn.dataTableExt.oSort, { * Custom methods for correct bandwidth sorting */ "ambari-bandwidth-pre": function (bandwidth_string) { - bandwidth_string = (jQuery(bandwidth_string).text()) ? jQuery(bandwidth_string).text() : bandwidth_string; var convertedRowValue; - if (bandwidth_string === '<1KB') { + if (Boolean(bandwidth_string.match(/<.*>/g))) { + bandwidth_string = jQuery(bandwidth_string).text(); + } + if (bandwidth_string === '<1KB' || bandwidth_string === '<1KB') { convertedRowValue = 1; } else { var rowValueScale = bandwidth_string.substr(bandwidth_string.length - 2, 2); @@ -252,7 +254,7 @@ jQuery.extend($.fn.dataTableExt.afnFiltering.push( } function bandwidthFilter(rangeExp, rowValue) { - rowValue = $(rowValue).text(); + //rowValue = $(rowValue).text(); var compareChar = rangeExp.charAt(0); var compareScale = rangeExp.charAt(rangeExp.length - 1); var compareValue = isNaN(parseFloat(compareScale)) ? parseFloat(rangeExp.substr(1, rangeExp.length - 2)) : parseFloat(rangeExp.substr(1, rangeExp.length - 1)); @@ -264,6 +266,7 @@ jQuery.extend($.fn.dataTableExt.afnFiltering.push( compareValue *= 1024; } rowValue = (jQuery(rowValue).text()) ? jQuery(rowValue).text() : rowValue; + var convertedRowValue; if (rowValue === '<1KB') { convertedRowValue = 1; diff --git a/ambari-web/app/utils/db.js b/ambari-web/app/utils/db.js index a1247a54e4..47db810b3d 100644 --- a/ambari-web/app/utils/db.js +++ b/ambari-web/app/utils/db.js @@ -106,17 +106,17 @@ App.db.setAuthenticated = function (authenticated) { console.log('Now present value of authentication is: ' + App.db.data.app.authenticated); }; -App.db.setClusterName = function (name) { - console.log('TRACE: Entering db:setClusterName function'); +App.db.setAllHostNames = function (hostNames) { + console.log('TRACE: Entering db:setAllHostNames function'); App.db.data = localStorage.getObject('ambari'); - App.db.data.Installer.ClusterName = name; + App.db.data.Installer.hostNames = hostNames; localStorage.setObject('ambari', App.db.data); }; -App.db.setAllHostNames = function (hostNames) { - console.log('TRACE: Entering db:setAllHostNames function'); +App.db.setAllHostNamesPattern = function (hostNames) { + console.log('TRACE: Entering db:setAllHostNamesPattern function'); App.db.data = localStorage.getObject('ambari'); - App.db.data.Installer.hostNames = hostNames; + App.db.data.Installer.hostNamesPattern = hostNames; localStorage.setObject('ambari', App.db.data); }; @@ -225,7 +225,7 @@ App.db.setServiceConfigProperties = function (configProperties) { localStorage.setObject('ambari', App.db.data); }; -App.db.setClusterStatus = function (status) { +App.db.setCluster = function (status) { App.db.data = localStorage.getObject('ambari'); App.db.data.Installer.clusterStatus = status; console.log('db.setClusterStatus called: ' + JSON.stringify(status)); @@ -236,13 +236,11 @@ App.db.setClusterStatus = function (status) { * Set current step value for specified Wizard Type * @param wizardType * @param currentStep - * @param completed */ -App.db.setWizardCurrentStep = function (wizardType, currentStep, completed) { +App.db.setWizardCurrentStep = function (wizardType, currentStep) { console.log('TRACE: Entering db:setWizardCurrentStep function'); App.db.data[wizardType.capitalize()].currentStep = currentStep; - App.db.data[wizardType.capitalize()].completed = completed; localStorage.setObject('ambari', App.db.data); }; @@ -274,12 +272,6 @@ App.db.getAuthenticated = function () { return App.db.data.app.authenticated; }; -App.db.getClusterName = function () { - console.log('Trace: Entering db:getClusterName function'); - App.db.data = localStorage.getObject('ambari'); - return App.db.data.Installer.ClusterName; -}; - App.db.getAmbariStacks = function () { console.log('TRACE: Entering db:setAmbariStacks function'); App.db.data = localStorage.getObject('ambari'); @@ -305,6 +297,12 @@ App.db.getAllHostNames = function () { return App.db.data.Installer.hostNames; }; +App.db.getAllHostNamesPattern = function () { + console.log('TRACE: Entering db:getHostNamesPattern function'); + App.db.data = localStorage.getObject('ambari'); + return App.db.data.Installer.hostNamesPattern; +}; + App.db.getInstallType = function () { console.log('TRACE: Entering db:getHostNames function'); App.db.data = localStorage.getObject('ambari'); @@ -390,7 +388,7 @@ App.db.getSlaveProperties = function () { return App.db.data.Installer.slaveProperties; }; -App.db.getClusterStatus = function () { +App.db.getCluster = function () { console.log('TRACE: Entering db:getClusterStatus function'); App.db.data = localStorage.getObject('ambari'); return App.db.data.Installer.clusterStatus; diff --git a/ambari-web/app/utils/graph.js b/ambari-web/app/utils/graph.js index 438b1e89a7..736c6e9bcc 100644 --- a/ambari-web/app/utils/graph.js +++ b/ambari-web/app/utils/graph.js @@ -169,7 +169,8 @@ module.exports = { var yAxis = new Rickshaw.Graph.Axis.Y({ graph:graph, - ticksTreatment:ticksTreatment + ticksTreatment:ticksTreatment, + tickFormat: function(y) { return y / 1000 + 's' } }); yAxis.render(); diff --git a/ambari-web/app/utils/helper.js b/ambari-web/app/utils/helper.js index 5b62093c53..94d289e82c 100644 --- a/ambari-web/app/utils/helper.js +++ b/ambari-web/app/utils/helper.js @@ -243,11 +243,11 @@ App.format = { case 'NAMENODE': return 'NameNode'; case 'NAMENODE_SERVICE_CHECK': - return 'NameNode Service Check'; + return 'NameNode Check'; case 'DATANODE': return 'DataNode'; case 'HDFS_SERVICE_CHECK': - return 'HDFS Service Check'; + return 'HDFS Check'; case 'SECONDARY_NAMENODE': return 'SNameNode'; case 'HDFS_CLIENT': @@ -275,15 +275,15 @@ App.format = { case 'HADOOP_CLIENT': return 'Hadoop Client'; case 'JOBTRACKER_SERVICE_CHECK': - return 'JobTracker Service Check'; + return 'JobTracker Check'; case 'MAPREDUCE_SERVICE_CHECK': - return 'MapReduce Service Check'; + return 'MapReduce Check'; case 'ZOOKEEPER_SERVICE_CHECK': - return 'ZooKeeper Service Check'; + return 'ZooKeeper Check'; case 'ZOOKEEPER_QUORUM_SERVICE_CHECK': - return 'ZooKeeper Quorum Service Check'; + return 'ZK Quorum Check'; case 'HBASE_SERVICE_CHECK': - return 'HBase Service Check'; + return 'HBase Check'; case 'MYSQL_SERVER': return 'MySQL Server'; case 'HIVE_SERVER': @@ -291,31 +291,31 @@ App.format = { case 'HIVE_CLIENT': return 'Hive Client'; case 'HIVE_SERVICE_CHECK': - return 'Hive Service Check'; + return 'Hive Check'; case 'HCAT': return 'HCat'; case 'HCAT_SERVICE_CHECK': - return 'HCat Service Check'; + return 'HCat Check'; case 'OOZIE_CLIENT': return 'Oozie Client'; case 'OOZIE_SERVER': return 'Oozie Server'; case 'OOZIE_SERVICE_CHECK': - return 'Oozie Service Check'; + return 'Oozie Check'; case 'PIG': return 'Pig'; case 'PIG_SERVICE_CHECK': - return 'Pig Service Check'; + return 'Pig Check'; case 'SQOOP': return 'Sqoop'; case 'SQOOP_SERVICE_CHECK': - return 'Sqoop Service Check'; + return 'Sqoop Check'; case 'TEMPLETON_CLIENT': return 'Templeton Client'; case 'TEMPLETON_SERVER': return 'Templeton Server'; case 'TEMPLETON_SERVICE_CHECK': - return 'Templeton Service Check'; + return 'Templeton Check'; case 'NAGIOS_SERVER': return 'Nagios Server'; case 'GANGLIA_SERVER': @@ -323,9 +323,9 @@ App.format = { case 'GANGLIA_MONITOR': return 'Ganglia Monitor'; case 'GMOND_SERVICE_CHECK': - return 'Gmond Service Check' + return 'Gmond Check' case 'GMETAD_SERVICE_CHECK': - return 'Gmetad Service Check'; + return 'Gmetad Check'; case 'DECOMMISSION_DATANODE': return 'Decommission DataNode'; } @@ -343,4 +343,12 @@ App.format = { taskStatus:function (_taskStatus) { return _taskStatus.replace('_', ' ').toLowerCase(); } -};
\ No newline at end of file +}; + +Array.prototype.removeAll = function(array){ + var temp = array; + for(var i = 0 ; i < array.length ; i++ ){ + temp = temp.without(array[i]); + } + return temp; +}; diff --git a/ambari-web/app/views/common/chart/linear_time.js b/ambari-web/app/views/common/chart/linear_time.js index e10a0a6515..88c7153365 100644 --- a/ambari-web/app/views/common/chart/linear_time.js +++ b/ambari-web/app/views/common/chart/linear_time.js @@ -92,17 +92,23 @@ App.ChartLinearTimeView = Ember.View.extend({ isPopup: false, + isReady: false, + + isPopupReady: false, + /** * Color palette used for this chart - * + * * @private * @type String[] */ + /* _paletteScheme: [ 'rgba(181,182,169,0.4)', 'rgba(133,135,114,0.4)', 'rgba(120,95,67,0.4)', 'rgba(150,85,126,0.4)', 'rgba(70,130,180,0.4)', 'rgba(0,255,204,0.4)', 'rgba(255,105,180,0.4)', 'rgba(101,185,172,0.4)', 'rgba(115,192,58,0.4)', 'rgba(203,81,58,0.4)' ].reverse(), + */ init: function () { this._super(); @@ -135,7 +141,7 @@ App.ChartLinearTimeView = Ember.View.extend({ hash.dataType = 'json'; hash.contentType = 'application/json; charset=utf-8'; hash.context = this; - hash.success = this._refreshGraph; + hash.success = this._refreshGraph, hash.error = function (xhr, textStatus, errorThrown) { this._showMessage('warn', 'Error', 'There was a problem getting data for the chart (' + textStatus + ': ' + errorThrown + ')'); } @@ -267,6 +273,7 @@ App.ChartLinearTimeView = Ember.View.extend({ this.draw(seriesData); } else { + this.set('isReady', true); this._showMessage('info', 'No Data', 'There was no data available.'); } }, @@ -315,13 +322,21 @@ App.ChartLinearTimeView = Ember.View.extend({ if (isPopup) { p = this.get('popupSuffix'); } - var palette = new Rickshaw.Color.Palette({ - scheme: this._paletteScheme - }); + var palette = new Rickshaw.Color.Palette({ scheme: 'munin'}); + + // var palette = new Rickshaw.Color.Palette({ + // scheme: this._paletteScheme + // }); + var self = this; var series_min_length = 100000000; seriesData.forEach(function (series, index) { - series.color = /*this.colorForSeries(series) ||*/ palette.color(); + // Don't draw empty graph + if (series.data.length == 0) { + this.set('isPopup', false); + return; + } + series.color = palette.color(); series.stroke = 'rgba(0,0,0,0.3)'; if (isPopup) { // calculate statistic data for popup legend @@ -355,22 +370,27 @@ App.ChartLinearTimeView = Ember.View.extend({ var xaxisElementId = "#" + this.id + "-xaxis" + p; var yaxisElementId = "#" + this.id + "-yaxis" + p; var legendElementId = "#" + this.id + "-legend" + p; - var timelineElementId = "#" + this.id + "-timeline" + p; var chartElement = document.querySelector(chartId); var overlayElement = document.querySelector(chartOverlayId); var xaxisElement = document.querySelector(xaxisElementId); var yaxisElement = document.querySelector(yaxisElementId); var legendElement = document.querySelector(legendElementId); - var timelineElement = document.querySelector(timelineElementId); var strokeWidth = 1; if (this.get('renderer') != 'area') { strokeWidth = 2; } + var height = 150; + var width = 400; + if (isPopup) { + height = 180; + width = 670; + } var _graph = new Rickshaw.Graph({ - height: 150, + height: height, + width: width, element: chartElement, series: seriesData, interpolation: 'step-after', @@ -378,16 +398,23 @@ App.ChartLinearTimeView = Ember.View.extend({ renderer: this.get('renderer'), strokeWidth: strokeWidth }); - _graph.renderer.unstack = false; + if (this.get('renderer') === 'area') { + _graph.renderer.unstack = false; + } xAxis = new Rickshaw.Graph.Axis.Time({ graph: _graph, timeUnit: this.localeTimeUnit() }); + var orientation = 'right'; + if (isPopup) { + orientation = 'left'; + } yAxis = new Rickshaw.Graph.Axis.Y({ tickFormat: this.yAxisFormatter, element: yaxisElement, + orientation: orientation, graph: _graph }); @@ -419,13 +446,12 @@ App.ChartLinearTimeView = Ember.View.extend({ graph: _graph, legend: legend }); - - var annotator = new Rickshaw.Graph.Annotate({ - graph: _graph, - element: timelineElement + //show the graph when it's loaded + _graph.onUpdate(function(){ + self.set('isReady', true); }); - _graph.render(); + if (isPopup) { var self = this; var hoverDetail = new Rickshaw.Graph.HoverDetail({ @@ -453,17 +479,20 @@ App.ChartLinearTimeView = Ember.View.extend({ } } }); + //show the graph when it's loaded + _graph.onUpdate(function(){ + self.set('isPopupReady', true); + }); _graph.update(); - $('#'+self.get('id')+'-container'+self.get('popupSuffix')+' a.action').click(function() { - var series = new Array(); + $('li.line').click(function() { + var series = []; $('#'+self.get('id')+'-container'+self.get('popupSuffix')+' a.action').each(function(index, v) { series[index] = v.parentNode.classList; }); self.set('_seriesProperties', series); }); - this.set('_popupGraph', _graph); } else { @@ -488,15 +517,15 @@ App.ChartLinearTimeView = Ember.View.extend({ '</div>', '<div class="modal-body">', '{{#if bodyClass}}{{view bodyClass}}', - '{{else}}'+ - '<div id="'+this.get('id')+'-container'+this.get('popupSuffix')+'" class="chart-container chart-container'+this.get('popupSuffix')+'">'+ - '<div id="'+this.get('id')+'-yaxis'+this.get('popupSuffix')+'" class="'+this.get('id')+'-yaxis chart-y-axis"></div>'+ - '<div id="'+this.get('id')+'-xaxis'+this.get('popupSuffix')+'" class="'+this.get('id')+'-xaxis chart-x-axis"></div>'+ - '<div id="'+this.get('id')+'-legend'+this.get('popupSuffix')+'" class="'+this.get('id')+'-legend chart-legend"></div>'+ - '<div id="'+this.get('id')+'-chart'+this.get('popupSuffix')+'" class="'+this.get('id')+'-chart chart"></div>'+ + '{{else}}', + '<div class="screensaver no-borders chart-container" {{bindAttr class="view.isReady:hide"}} ></div>', + '<div id="'+this.get('id')+'-container'+this.get('popupSuffix')+'" class="chart-container chart-container'+this.get('popupSuffix')+' hide" {{bindAttr class="view.isReady:show"}} >', + '<div id="'+this.get('id')+'-yaxis'+this.get('popupSuffix')+'" class="'+this.get('id')+'-yaxis chart-y-axis"></div>', + '<div id="'+this.get('id')+'-xaxis'+this.get('popupSuffix')+'" class="'+this.get('id')+'-xaxis chart-x-axis"></div>', + '<div id="'+this.get('id')+'-legend'+this.get('popupSuffix')+'" class="'+this.get('id')+'-legend chart-legend"></div>', + '<div id="'+this.get('id')+'-chart'+this.get('popupSuffix')+'" class="'+this.get('id')+'-chart chart"></div>', '<div id="'+this.get('id')+'-title'+this.get('popupSuffix')+'" class="'+this.get('id')+'-title chart-title">{{view.title}}</div>'+ - '<div id="'+this.get('id')+'-timeline'+this.get('popupSuffix')+'" class="'+this.get('id')+'-timeline timeline"></div>'+ - '</div>'+ + '</div>', '{{/if}}', '</div>', '<div class="modal-footer">', @@ -506,6 +535,10 @@ App.ChartLinearTimeView = Ember.View.extend({ ].join('\n')), header: this.get('title'), + self: self, + isReady: function(){ + return this.get('self.isPopupReady'); + }.property('self.isPopupReady'), primary: 'OK', onPrimary: function() { this.hide(); @@ -514,6 +547,7 @@ App.ChartLinearTimeView = Ember.View.extend({ }); Ember.run.next(function() { self.loadData(); + self.set('isPopupReady', false); }); } }); diff --git a/ambari-web/app/views/common/modal_popup.js b/ambari-web/app/views/common/modal_popup.js index 02e3626ec8..b7b15a5623 100644 --- a/ambari-web/app/views/common/modal_popup.js +++ b/ambari-web/app/views/common/modal_popup.js @@ -33,10 +33,12 @@ App.ModalPopup = Ember.View.extend({ '{{#if bodyClass}}{{view bodyClass}}', '{{else}}{{#if encodeBody}}{{body}}{{else}}{{{body}}}{{/if}}{{/if}}', '</div>', + '{{#if showFooter}}', '<div class="modal-footer">', '{{#if view.secondary}}<a class="btn" {{action onSecondary target="view"}}>{{view.secondary}}</a>{{/if}}', '{{#if view.primary}}<a class="btn btn-success" {{action onPrimary target="view"}}>{{view.primary}}</a>{{/if}}', '</div>', + '{{/if}}', '</div>' ].join('\n')), @@ -60,8 +62,15 @@ App.ModalPopup = Ember.View.extend({ hide: function() { this.destroy(); - } + }, + showFooter: true, + + didInsertElement: function(){ + this._super(); + var block = this.$().find('#modal').first(); + block.css('max-height', $(window).height()-20); // fix popup height + } }); App.ModalPopup.reopenClass({ diff --git a/ambari-web/app/views/login.js b/ambari-web/app/views/login.js index 6f9faef1a5..3c3c9fd11f 100644 --- a/ambari-web/app/views/login.js +++ b/ambari-web/app/views/login.js @@ -22,6 +22,12 @@ var App = require('app'); App.LoginView = Em.View.extend({ templateName: require('templates/login'), + loginTextField: Em.TextField.extend({ + didInsertElement: function(){ + this._super(); + this.$().focus(); + } + }), passTextField : Em.TextField.extend({ insertNewline: function(){ this.get("controller").submit(); diff --git a/ambari-web/app/views/main.js b/ambari-web/app/views/main.js index ebd648204e..0e0da78f98 100644 --- a/ambari-web/app/views/main.js +++ b/ambari-web/app/views/main.js @@ -27,14 +27,31 @@ App.MainBackgroundOperation = Em.View.extend({ content: null, classNames: ['background-operations'], classNameBindings: ['isOpen'], - isOpen: false, + isOpen: function () { + return this.get('content.isOpen'); + }.property('content.isOpen'), iconClass: function(){ return this.get('isOpen') ? 'icon-minus' : 'icon-plus'; }.property('isOpen'), showOperationLog:function(){ - this.set('isOpen', !this.get('isOpen')); + this.set('content.isOpen', !this.get('content.isOpen')); this.set('isTextArea', false); }, + hasProgressBar: function () { + return this.get('content.command') == 'EXECUTE'; + }.property('content.command'), + isInProgress: function () { + var status = this.get('content.status'); + return status == 'IN_PROGRESS' || status == 'QUEUED' || status == 'PENDING'; + }.property('content.status'), + barColor: function () { + if (this.get('isInProgress')) { + return 'progress-info'; + } else { + if (this.get('content.status') == 'COMPLETED') return 'progress-success'; + return 'progress-danger'; + } + }.property('isInProgress'), buttonLabel:function(){ var button = $(this.get('element')).find('.textTrigger'); if(this.get('isTextArea')){ diff --git a/ambari-web/app/views/main/dashboard/cluster_metrics/cpu.js b/ambari-web/app/views/main/dashboard/cluster_metrics/cpu.js index b9afa0e001..e89c0b86d5 100644 --- a/ambari-web/app/views/main/dashboard/cluster_metrics/cpu.js +++ b/ambari-web/app/views/main/dashboard/cluster_metrics/cpu.js @@ -40,6 +40,7 @@ App.ChartClusterMetricsCPU = App.ChartLinearTimeView.extend({ transformToSeries: function (jsonData) { var seriesArray = []; if (jsonData && jsonData.metrics && jsonData.metrics.cpu) { + var cpu_idle; for ( var name in jsonData.metrics.cpu) { var displayName = name; var seriesData = jsonData.metrics.cpu[name]; @@ -58,9 +59,15 @@ App.ChartClusterMetricsCPU = App.ChartLinearTimeView.extend({ y: seriesData[index][0] }); } - seriesArray.push(series); + if (name != 'Idle') { + seriesArray.push(series); + } + else { + cpu_idle = series; + } } } + seriesArray.push(cpu_idle); } return seriesArray; }, diff --git a/ambari-web/app/views/main/host.js b/ambari-web/app/views/main/host.js index b6193de227..3c70e6b3bb 100644 --- a/ambari-web/app/views/main/host.js +++ b/ambari-web/app/views/main/host.js @@ -305,7 +305,6 @@ App.MainHostView = Em.View.extend({ self.get('parentView').get('oTable').fnFilter('', 6); jQuery('#components_filter').closest('th').addClass('notActive'); }, - closeFilters:function () { $(document).unbind('click'); this.clickFilterButton(); @@ -333,12 +332,10 @@ App.MainHostView = Em.View.extend({ }); } }, - /*closeFilter: function(){ - this.set('open', false); - },*/ applyFilter:function() { var chosenComponents = new Array(); - this.set('open', !this.get('open')); + + this.set('isFilterOpen', !this.get('isFilterOpen')); this.get('masterComponents').forEach(function(item){ if(item.get('checkedForHostFilter')) chosenComponents.push(item.get('displayName')); }); diff --git a/ambari-web/app/views/main/host/metrics/cpu.js b/ambari-web/app/views/main/host/metrics/cpu.js index 111ac642fc..0b56af5f6d 100644 --- a/ambari-web/app/views/main/host/metrics/cpu.js +++ b/ambari-web/app/views/main/host/metrics/cpu.js @@ -31,6 +31,7 @@ App.ChartHostMetricsCPU = App.ChartLinearTimeView.extend({ title: "CPU Usage", yAxisFormatter: App.ChartLinearTimeView.PercentageFormatter, + url: function () { return App.formatUrl(App.apiPrefix + "/clusters/{clusterName}/hosts/{hostName}?fields=metrics/cpu/cpu_user[{fromSeconds},{toSeconds},{stepSeconds}],metrics/cpu/cpu_wio[{fromSeconds},{toSeconds},{stepSeconds}],metrics/cpu/cpu_nice[{fromSeconds},{toSeconds},{stepSeconds}],metrics/cpu/cpu_aidle[{fromSeconds},{toSeconds},{stepSeconds}],metrics/cpu/cpu_system[{fromSeconds},{toSeconds},{stepSeconds}],metrics/cpu/cpu_idle[{fromSeconds},{toSeconds},{stepSeconds}]", { clusterName: App.router.get('clusterController.clusterName'), @@ -41,6 +42,7 @@ App.ChartHostMetricsCPU = App.ChartLinearTimeView.extend({ transformToSeries: function (jsonData) { var seriesArray = []; if (jsonData && jsonData.metrics && jsonData.metrics.cpu) { + var cpu_idle; for ( var name in jsonData.metrics.cpu) { var displayName; var seriesData = jsonData.metrics.cpu[name]; @@ -81,9 +83,15 @@ App.ChartHostMetricsCPU = App.ChartLinearTimeView.extend({ y: seriesData[index][0] }); } - seriesArray.push(series); + if (name != 'cpu_idle') { + seriesArray.push(series); + } + else { + cpu_idle = series; + } } } + seriesArray.push(cpu_idle); } return seriesArray; }, diff --git a/ambari-web/app/views/main/menu.js b/ambari-web/app/views/main/menu.js index f2c7777e1d..ab1bcda4d9 100644 --- a/ambari-web/app/views/main/menu.js +++ b/ambari-web/app/views/main/menu.js @@ -31,7 +31,7 @@ App.MainMenuView = Em.CollectionView.extend({ { label:'Charts', routing:'charts'}, { label:'Services', routing:'services'}, { label:'Hosts', routing:'hosts'}, - { label:'Apps', routing:'apps'} + { label:'Jobs', routing:'apps'} ]; if(App.db.getUser().admin) result.push({ label:'Admin', routing:'admin'}); diff --git a/ambari-web/app/views/main/service/info/metrics/mapreduce/jvm_heap.js b/ambari-web/app/views/main/service/info/metrics/mapreduce/jvm_heap.js index 968ecb979e..3cf12f084f 100644 --- a/ambari-web/app/views/main/service/info/metrics/mapreduce/jvm_heap.js +++ b/ambari-web/app/views/main/service/info/metrics/mapreduce/jvm_heap.js @@ -30,7 +30,7 @@ App.ChartServiceMetricsMapReduce_JVMHeap = App.ChartLinearTimeView.extend({ id: "service-metrics-mapreduce-jvm-heap", title: "JVM Memory Status", yAxisFormatter: App.ChartLinearTimeView.BytesFormatter, - + renderer: 'line', url: function () { var mrService = App.MapReduceService.find().objectAt(0); var jtHostName = mrService.get('jobTracker').get('hostName'); diff --git a/ambari-web/app/views/main/service/info/metrics/mapreduce/jvm_threads.js b/ambari-web/app/views/main/service/info/metrics/mapreduce/jvm_threads.js index 21cda67f9b..db220afccd 100644 --- a/ambari-web/app/views/main/service/info/metrics/mapreduce/jvm_threads.js +++ b/ambari-web/app/views/main/service/info/metrics/mapreduce/jvm_threads.js @@ -29,7 +29,7 @@ var App = require('app'); App.ChartServiceMetricsMapReduce_JVMThreads = App.ChartLinearTimeView.extend({ id: "service-metrics-mapreduce-jvm-threads", title: "JVM Thread Status", - + renderer: 'line', url: function () { var mrService = App.MapReduceService.find().objectAt(0); var jtHostName = mrService.get('jobTracker').get('hostName'); diff --git a/ambari-web/app/views/main/service/info/summary.js b/ambari-web/app/views/main/service/info/summary.js index c6eb6cac25..e1839e496f 100644 --- a/ambari-web/app/views/main/service/info/summary.js +++ b/ambari-web/app/views/main/service/info/summary.js @@ -239,5 +239,11 @@ App.MainServiceInfoSummaryView = Em.View.extend({ }); return names.length ? names.join(', ') : false; - }.property('clientComponents') + }.property('clientComponents'), + hasAlertsBox: function(){ + var services = [ + 'NAGIOS' + ]; + return -1 === services.indexOf(this.get('controller.content.serviceName')); + }.property('controller.content.serviceName') });
\ No newline at end of file diff --git a/ambari-web/app/views/main/service/item.js b/ambari-web/app/views/main/service/item.js index 7e63427f6b..f6dd4ba1ba 100644 --- a/ambari-web/app/views/main/service/item.js +++ b/ambari-web/app/views/main/service/item.js @@ -27,9 +27,9 @@ App.MainServiceItemView = Em.View.extend({ // case 'HDFS': // options.push({action: 'runRebalancer', 'label': Em.I18n.t('services.service.actions.run.rebalancer')}); // break; - case 'HBASE': - options.push({action: 'runCompaction', 'label': Em.I18n.t('services.service.actions.run.compaction')}); - break; +// case 'HBASE': +// options.push({action: 'runCompaction', 'label': Em.I18n.t('services.service.actions.run.compaction')}); +// break; default: options.push({action: 'runSmokeTest', 'label': Em.I18n.t('services.service.actions.run.smoke')}); } diff --git a/ambari-web/app/views/wizard/step1_view.js b/ambari-web/app/views/wizard/step1_view.js index e633cee739..955eb5c3bb 100644 --- a/ambari-web/app/views/wizard/step1_view.js +++ b/ambari-web/app/views/wizard/step1_view.js @@ -35,7 +35,8 @@ App.WizardStep1View = Em.View.extend({ }.property('controller.clusterNameError'), submit: function(event) { - App.router.wizardStep1Controller.submit(); + this.get('controller').submit(); + return false; } }); diff --git a/ambari-web/app/views/wizard/step2_view.js b/ambari-web/app/views/wizard/step2_view.js index 0479af1ebf..a41e6477ee 100644 --- a/ambari-web/app/views/wizard/step2_view.js +++ b/ambari-web/app/views/wizard/step2_view.js @@ -32,7 +32,7 @@ App.SshKeyFileUploader = Ember.View.extend({ return function(e) { $('#sshKey').html(e.target.result); //$('.sshKey-file-view').html(e.target.result); - self.set("controller.content.sshKey", e.target.result); + self.set("controller.content.hosts.sshKey", e.target.result); }; })(file); reader.readAsText(file); @@ -62,8 +62,8 @@ App.WizardStep2View = Em.View.extend({ }.observes('controller.hostNameEmptyError', 'controller.hostNameNotRequiredErr', 'controller.hostNameErr'), sshKeyState: function(){ - return this.get("controller").get("content.manualInstall"); - }.property("controller.content.manualInstall"), + return this.get("controller.content.hosts.manualInstall"); + }.property("controller.content.hosts.manualInstall"), sshKeyClass:function() { //alert(this.get("isFileApi")) @@ -75,8 +75,8 @@ App.WizardStep2View = Em.View.extend({ }.property(), sshKeyPreviewClass: function() { - if (this.get('controller.content.sshKey').trim() != '') { - if (this.get('controller.content.manualInstall')) { + if (this.get('controller.content.hosts.sshKey').trim() != '') { + if (this.get('controller.content.hosts.manualInstall')) { return 'sshKey-file-view disabled'; } else { return 'sshKey-file-view'; @@ -84,7 +84,7 @@ App.WizardStep2View = Em.View.extend({ } else { return 'hidden'; } - }.property('controller.content.sshKey', 'controller.content.manualInstall') + }.property('controller.content.hosts.sshKey', 'controller.content.hosts.manualInstall') }); diff --git a/ambari-web/app/views/wizard/step9_view.js b/ambari-web/app/views/wizard/step9_view.js index bd12895638..ae3935b024 100644 --- a/ambari-web/app/views/wizard/step9_view.js +++ b/ambari-web/app/views/wizard/step9_view.js @@ -198,7 +198,7 @@ App.HostStatusView = Em.View.extend({ return roleArr; }.property('startedTasks.@each'), - didInsertElement: function () {debugger; + didInsertElement: function () { console.log('The value of event context is: ' + host.name); this.get('roles').forEach(function (role) { role.taskInfos.forEach(function (task) { |