You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by yu...@apache.org on 2012/10/18 02:17:20 UTC
svn commit: r1399489 [1/2] - in /incubator/ambari/branches/AMBARI-666: ./
ambari-web/app/ ambari-web/app/controllers/installer/
ambari-web/app/controllers/main/host/ ambari-web/app/controllers/wizard/
ambari-web/app/routes/ ambari-web/app/styles/ ambar...
Author: yusaku
Date: Thu Oct 18 00:17:19 2012
New Revision: 1399489
URL: http://svn.apache.org/viewvc?rev=1399489&view=rev
Log:
AMBARI-881. Implement Add Hosts Wizard. (yusaku)
Added:
incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/main/host/add_controller.js
incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/wizard/
incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/wizard/step2_controller.js
incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/wizard/step3_controller.js
incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/wizard/step4_controller.js
incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/wizard/step5_controller.js
incubator/ambari/branches/AMBARI-666/ambari-web/app/routes/add_host_routes.js
incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/main/host/add.hbs
incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/wizard/
incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/wizard/step2.hbs
incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/wizard/step2ManualInstallPopup.hbs
incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/wizard/step3.hbs
incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/wizard/step3HostLogPopup.hbs
incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/wizard/step4.hbs
incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/wizard/step5.hbs
incubator/ambari/branches/AMBARI-666/ambari-web/app/views/main/host/add_view.js
incubator/ambari/branches/AMBARI-666/ambari-web/app/views/wizard/
incubator/ambari/branches/AMBARI-666/ambari-web/app/views/wizard/step2_view.js
incubator/ambari/branches/AMBARI-666/ambari-web/app/views/wizard/step3_view.js
incubator/ambari/branches/AMBARI-666/ambari-web/app/views/wizard/step4_view.js
incubator/ambari/branches/AMBARI-666/ambari-web/app/views/wizard/step5_view.js
Modified:
incubator/ambari/branches/AMBARI-666/AMBARI-666-CHANGES.txt
incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers.js
incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/installer/step5_controller.js
incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/installer/step7_controller.js
incubator/ambari/branches/AMBARI-666/ambari-web/app/messages.js
incubator/ambari/branches/AMBARI-666/ambari-web/app/router.js
incubator/ambari/branches/AMBARI-666/ambari-web/app/routes/installer.js
incubator/ambari/branches/AMBARI-666/ambari-web/app/routes/main.js
incubator/ambari/branches/AMBARI-666/ambari-web/app/styles/app.css
incubator/ambari/branches/AMBARI-666/ambari-web/app/styles/application.less
incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/installer/step7.hbs
incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/main/host.hbs
incubator/ambari/branches/AMBARI-666/ambari-web/app/utils/db.js
incubator/ambari/branches/AMBARI-666/ambari-web/app/views.js
incubator/ambari/branches/AMBARI-666/ambari-web/app/views/installer/step5_view.js
incubator/ambari/branches/AMBARI-666/ambari-web/app/views/installer/step7_view.js
Modified: incubator/ambari/branches/AMBARI-666/AMBARI-666-CHANGES.txt
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/AMBARI-666-CHANGES.txt?rev=1399489&r1=1399488&r2=1399489&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/AMBARI-666-CHANGES.txt (original)
+++ incubator/ambari/branches/AMBARI-666/AMBARI-666-CHANGES.txt Thu Oct 18 00:17:19 2012
@@ -12,6 +12,8 @@ AMBARI-666 branch (unreleased changes)
NEW FEATURES
+ AMBARI-881. Implement Add Hosts Wizard. (yusaku)
+
AMBARI-869. Util to deserialize ExecutionCommand. (jitendra)
AMBARI-874. Fix hostinfo reporting at the server and add a unit test for
Modified: incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers.js?rev=1399489&r1=1399488&r2=1399489&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers.js (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers.js Thu Oct 18 00:17:19 2012
@@ -49,9 +49,14 @@ require('controllers/main/service/info/a
require('controllers/main/alert');
require('controllers/main/host');
require('controllers/main/host/details');
+require('controllers/main/host/add_controller');
require('controllers/main/dashboard');
require('controllers/main/charts');
require('controllers/main/charts/heatmap');
require('controllers/main/charts/horizon_chart');
require('controllers/main/charts/horizon_chart');
require('controllers/main/rack');
+require('controllers/wizard/step2_controller');
+require('controllers/wizard/step3_controller');
+require('controllers/wizard/step4_controller');
+require('controllers/wizard/step5_controller');
\ No newline at end of file
Modified: incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/installer/step5_controller.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/installer/step5_controller.js?rev=1399489&r1=1399488&r2=1399489&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/installer/step5_controller.js (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/installer/step5_controller.js Thu Oct 18 00:17:19 2012
@@ -404,21 +404,19 @@ App.InstallerStep5Controller = Em.Contro
return this.get("hosts");
}
},
- /*
assignHostToMaster: function (masterService, selectedHost, zId) {
- if (selectedHost && masterService) {
- if ((masterService === "ZooKeeper") && zId) {
- this.get('selectedServicesMasters').findProperty("zId", zId).set("selectedHost", selectedHost);
- this.rebalanceZookeeperHosts();
- }
- else {
- this.get('selectedServicesMasters').findProperty("component_name", masterService).set("selectedHost", selectedHost);
- }
+ if (selectedHost && masterService) {
+ if ((masterService === "ZooKeeper") && zId) {
+ this.get('selectedServicesMasters').findProperty("zId", zId).set("selectedHost", selectedHost);
+ this.rebalanceZookeeperHosts();
+ }
+ else {
+ this.get('selectedServicesMasters').findProperty("component_name", masterService).set("selectedHost", selectedHost);
+ }
- }
+ }
},
- */
lastZooKeeper: function () {
var currentZooKeepers = this.get("selectedServicesMasters").filterProperty("component_name", "ZooKeeper");
Modified: incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/installer/step7_controller.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/installer/step7_controller.js?rev=1399489&r1=1399488&r2=1399489&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/installer/step7_controller.js (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/installer/step7_controller.js Thu Oct 18 00:17:19 2012
@@ -187,6 +187,8 @@ App.SlaveComponentGroupsController = Emb
contentBinding: 'App.router.installerStep7Controller.slaveComponentHosts',
+ slaveComponentGroups: [],
+
selectedComponentName: function () {
switch (App.router.get('installerStep7Controller.selectedService.serviceName')) {
case 'HDFS':
@@ -214,6 +216,22 @@ App.SlaveComponentGroupsController = Emb
});
},
+ addSlaveComponentGroup: function (event) {
+ var componentName = event.context;
+ var component = this.findProperty('componentName', componentName);
+ var slaveGroups = this.get('slaveComponentGroups');
+ var newGroupName;
+ console.log(slaveGroups);
+ slaveGroups.forEach(function(group) {
+
+ });
+ var newGroup = {
+ groupName: "New Group"
+ };
+ slaveGroups.pushObject(newGroup);
+ console.log(slaveGroups);
+ },
+
showEditSlaveComponentGroups: function (event) {
this.showAddSlaveComponentGroup(event);
},
@@ -234,6 +252,18 @@ App.SlaveComponentGroupsController = Emb
return component.hosts.mapProperty('group').uniq();
}
}
- }.property('@each.hosts', 'selectedComponentName')
+ }.property('@each.hosts', 'selectedComponentName'),
+
+ getHostsGroups: function () {
+ var slaveGroups = this.get('slaveComponentGroups');
+ if (slaveGroups.length == 0){
+ var defaultGroup = {
+ groupName: "Default",
+ label: "default"
+ };
+ slaveGroups.pushObject(defaultGroup);
+ }
+ return slaveGroups;
+ }.property('slaveComponentGroups')
});
Added: incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/main/host/add_controller.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/main/host/add_controller.js?rev=1399489&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/main/host/add_controller.js (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/main/host/add_controller.js Thu Oct 18 00:17:19 2012
@@ -0,0 +1,364 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+var App = require('app');
+
+App.AddHostController = Em.Controller.extend({
+
+ name: 'addHostController',
+
+ /**
+ * All wizards data will be stored in this variable
+ */
+ content: Em.Object.create(),
+
+ /**
+ * Used for hiding back button in wizard
+ */
+ hideBackButton: true,
+
+ isStepDisabled: [],
+
+ totalSteps: 9,
+
+ init: function () {
+ this.isStepDisabled.pushObject(Ember.Object.create({
+ step: 1,
+ value: false
+ }));
+ for (var i = 2; i <= this.totalSteps; i++) {
+ this.isStepDisabled.pushObject(Ember.Object.create({
+ step: i,
+ value: true
+ }));
+ }
+ },
+
+ setStepsEnable: function () {
+ for (var i = 2; i <= this.totalSteps; i++) {
+ var step = this.get('isStepDisabled').findProperty('step', i);
+ if (i <= this.get('currentStep')) {
+ step.set('value', false);
+ } else {
+ step.set('value', true);
+ }
+ }
+ }.observes('currentStep'),
+
+ /**
+ * Return current step of Add Host Wizard
+ */
+ currentStep: function () {
+ return App.get('router').getWizardCurrentStep('addHost');
+ }.property(),
+
+ /**
+ * Set current step to new value.
+ * Method moved from App.router.setInstallerCurrentStep
+ * @param currentStep
+ * @param completed
+ */
+ setCurrentStep: function (currentStep, completed) {
+ App.db.setWizardCurrentStep('addHost', currentStep, completed);
+ this.set('currentStep', currentStep);
+ },
+
+ isStep1: function () {
+ return this.get('currentStep') == 1;
+ }.property('currentStep'),
+
+ isStep2: function () {
+ return this.get('currentStep') == 2;
+ }.property('currentStep'),
+
+ isStep3: function () {
+ return this.get('currentStep') == 3;
+ }.property('currentStep'),
+
+ isStep4: function () {
+ return this.get('currentStep') == 4;
+ }.property('currentStep'),
+
+ isStep5: function () {
+ return this.get('currentStep') == 5;
+ }.property('currentStep'),
+
+ isStep6: function () {
+ return this.get('currentStep') == 6;
+ }.property('currentStep'),
+
+ isStep7: function () {
+ return this.get('currentStep') == 7;
+ }.property('currentStep'),
+
+ isStep8: function () {
+ return this.get('currentStep') == 8;
+ }.property('currentStep'),
+
+ isStep9: function () {
+ return this.get('currentStep') == 9;
+ }.property('currentStep'),
+
+ isStep10: function () {
+ return this.get('currentStep') == 10;
+ }.property('currentStep'),
+
+ gotoStep: function (step) {
+ if (this.get('isStepDisabled').findProperty('step', step).get('value') === false) {
+ App.router.send('gotoStep' + step);
+ }
+ },
+
+ gotoStep1: function () {
+ this.gotoStep(1);
+ },
+
+ gotoStep2: function () {
+ this.gotoStep(2);
+ },
+
+ gotoStep3: function () {
+ this.gotoStep(3);
+ },
+
+ gotoStep4: function () {
+ this.gotoStep(4);
+ },
+
+ gotoStep5: function () {
+ this.gotoStep(5);
+ },
+
+ gotoStep6: function () {
+ this.gotoStep(6);
+ },
+
+ gotoStep7: function () {
+ this.gotoStep(7);
+ },
+
+ gotoStep8: function () {
+ this.gotoStep(8);
+ },
+
+ gotoStep9: function () {
+ this.gotoStep(9);
+ },
+
+ gotoStep10: function () {
+ this.gotoStep(10);
+ },
+
+ /**
+ * Load all data for <code>Specify Host(install step2)</code> step
+ * Data Example:
+ * {
+ * hostNames: '',
+ * manualInstall: false,
+ * sshKey: '',
+ * passphrase: '',
+ * confirmPassphrase: '',
+ * localRepo: false,
+ * localRepoPath: ''
+ * }
+ */
+ loadHosts: function () {
+
+ if (!this.content.hosts) {
+ this.content.hosts = Em.Object.create();
+ }
+
+ //TODO : rewire it as model. or not :)
+ var hostsInfo = Em.Object.create();
+
+ hostsInfo.hostNames = App.db.getAllHostNames() || ''; //empty string if undefined
+
+ //TODO : should we check installType for add host wizard????
+ var installType = App.db.getInstallType();
+ //false if installType not equals 'manual'
+ hostsInfo.manualInstall = installType && installType.installType === 'manual' || false;
+
+ var softRepo = App.db.getSoftRepo();
+ if (softRepo && softRepo.repoType === 'local') {
+ hostsInfo.localRepo = true;
+ hostsInfo.localRepopath = softRepo.repoPath;
+ } else {
+ hostsInfo.localRepo = false;
+ hostsInfo.localRepoPath = '';
+ }
+
+ hostsInfo.sshKey = 'random';
+ hostsInfo.passphrase = '';
+ hostsInfo.confirmPassphrase = '';
+
+ this.set('content.hosts', hostsInfo);
+ console.log("AddHostController:loadHosts: loaded data ", hostsInfo);
+ },
+
+ /**
+ * Save data, which user filled, to main controller
+ * @param stepController App.WizardStep2Controller
+ */
+ saveHosts: function (stepController) {
+ //TODO: put data to content.hosts and only then save it)
+
+ //App.db.setBootStatus(false);
+ App.db.setAllHostNames(stepController.get('hostNames'));
+ App.db.setHosts(stepController.getHostInfo());
+ if (stepController.get('manualInstall') === false) {
+ App.db.setInstallType({installType: 'ambari' });
+ } else {
+ App.db.setInstallType({installType: 'manual' });
+ }
+ if (stepController.get('localRepo') === false) {
+ App.db.setSoftRepo({ 'repoType': 'remote', 'repoPath': null});
+ } else {
+ App.db.setSoftRepo({ 'repoType': 'local', 'repoPath': stepController.get('localRepoPath') });
+ }
+ },
+
+ /**
+ * Return hosts, which were add at <code>Specify Host(step2)</code> step
+ * @paramm isNew whether return all hosts or only new ones
+ */
+ getHostList: function (isNew) {
+ var hosts = [];
+ var hostArray = App.db.getHosts()
+ console.log('in addHostController.getHostList: host names is ', hostArray);
+
+ for (var i in hostArray) {
+ var hostInfo = App.HostInfo.create({
+ name: hostArray[i].name,
+ bootStatus: hostArray[i].bootStatus
+ });
+
+ hosts.pushObject(hostInfo);
+ }
+ ;
+
+ console.log('TRACE: pushing ' + hosts);
+ return hosts;
+ },
+
+ /**
+ * Remove host from model. Used at <code>Confirm hosts(step2)</code> step
+ * @param hosts Array of hosts, which we want to delete
+ */
+ removeHosts: function (hosts) {
+ //todo Replace this code with real logic
+ App.db.removeHosts(hosts);
+ },
+
+ /**
+ * Save data, which user filled, to main controller
+ * @param stepController App.WizardStep3Controller
+ */
+ saveConfirmedHosts: function (stepController) {
+ var hostInfo = {};
+ stepController.get('content').forEach(function (_host) {
+ hostInfo[_host.name] = {
+ name: _host.name,
+ cpu: _host.cpu,
+ memory: _host.memory,
+ bootStatus: _host.bootStatus
+ };
+ });
+ console.log('addHostController:saveConfirmedHosts: save hosts ', hostInfo);
+ App.db.setHosts(hostInfo);
+ },
+
+ /**
+ * Remove all data for hosts
+ */
+ clearHosts: function () {
+ var hosts = this.get('content').get('hosts');
+ if (hosts) {
+ hosts.hostNames = '';
+ hosts.manualInstall = false;
+ hosts.localRepo = '';
+ hosts.localRepopath = '';
+ hosts.sshKey = '';
+ hosts.passphrase = '';
+ hosts.confirmPassphrase = '';
+ }
+ },
+
+ /**
+ * Load services data. Will be used at <code>Select services(step4)</code> step
+ */
+ loadServices: function () {
+ var servicesInfo = App.db.getService();
+ servicesInfo.forEach(function (item, index) {
+ servicesInfo[index] = Em.Object.create(item);
+ });
+ this.set('content.services', servicesInfo);
+ console.log('addHostController.loadServices: loaded data ', servicesInfo);
+ },
+
+ /**
+ * Save data to model
+ * @param stepController App.WizardStep4Controller
+ */
+ saveServices: function (stepController) {
+ var serviceNames = [];
+ App.db.setService(stepController.get('content'));
+ stepController.filterProperty('isSelected', true).forEach(function (item) {
+ serviceNames.push(item.serviceName);
+ });
+ App.db.setSelectedServiceNames(serviceNames);
+ console.log('addHostController.saveServices: saved data ', serviceNames);
+ },
+
+ /**
+ * Load data for all steps until <code>current step</code>
+ */
+ loadAllPriorSteps: function () {
+ var step = this.get('currentStep');
+ switch (step) {
+ /*case '10':
+ this.get('installerStep9Controller').loadStep();
+ case '9':
+ this.get('installerStep8Controller').loadStep();
+ case '8':
+ this.get('installerStep7Controller').loadStep();
+ case '7':
+ this.get('installerStep6Controller').loadStep();
+ case '6':
+ this.get('installerStep5Controller').loadStep();
+ case '5':
+ this.get('installerStep4Controller').loadStep();*/
+ case '4':
+ //this.get('installerStep3Controller').loadStep();
+ case '3':
+ this.loadServices();
+ case '2':
+ case '1':
+ this.loadHosts();
+ }
+ },
+
+ /**
+ * Remove all loaded data.
+ * Created as copy for App.router.clearAllSteps
+ */
+ clearAllSteps: function () {
+ this.clearHosts();
+ }
+
+});
Added: incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/wizard/step2_controller.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/wizard/step2_controller.js?rev=1399489&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/wizard/step2_controller.js (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/wizard/step2_controller.js Thu Oct 18 00:17:19 2012
@@ -0,0 +1,185 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.WizardStep2Controller = Em.Controller.extend({
+ name: 'wizardStep2Controller',
+ hostNameArr: [],
+ hasSubmitted: false,
+
+ hostNames: function () {
+ return this.get('content.hostNames');
+ }.property('content.hostNames'),
+
+ manualInstall: function () {
+ return this.get('content.manualInstall');
+ }.property('content.manualInstall'),
+
+ localRepo: function () {
+ return this.get('content.localRepo');
+ }.property('content.localRepo'),
+
+ localRepoPath: function () {
+ return this.get('content.localRepoPath');
+ }.property('content.localRepoPath'),
+
+ sshKey: function () {
+ return this.get('content.sshKey');
+ }.property('content.sshKey'),
+
+ passphrase: function () {
+ return this.get('content.passphrase');
+ }.property('content.passphrase'),
+
+ confirmPassphrase: function () {
+ return this.get('content.confirmPassphrase');
+ }.property('content.confirmPassphrase'),
+
+ installType: function () {
+ if (this.get('manualInstall') === true) {
+ return 'manualDriven';
+ } else {
+ return 'ambariDriven';
+ }
+ }.property('manualInstall'),
+
+ isHostNameValid: function (hostname) {
+ // For now hostnames that start or end with '-' are not allowed
+ return !(/^\-/.test(hostname) || /\-$/.test(hostname));
+ },
+
+ isAllHostNamesValid: function () {
+ this.hostNameArr = this.get('hostNames').trim().split(new RegExp("\\s+", "g"));
+ for (var index in this.hostNameArr) {
+ if (!this.isHostNameValid(this.hostNameArr[index])) {
+ return false;
+ }
+ }
+ return true;
+ },
+
+ hostsError: function () {
+ if (this.get('hasSubmitted') && this.get('hostNames').trim() === '') {
+ return Em.I18n.t('installer.step2.hostName.error.required');
+ } else if (this.isAllHostNamesValid() === false) {
+ return Em.I18n.t('installer.step2.hostName.error.invalid');
+ }
+ return null;
+ }.property('hostNames', 'manualInstall', 'hasSubmitted'),
+
+ sshKeyError: function () {
+ if (this.get('hasSubmitted') && this.get('manualInstall') === false && this.get('sshKey').trim() === '') {
+ return Em.I18n.t('installer.step2.sshKey.error.required');
+ }
+ return null;
+ }.property('sshKey', 'manualInstall', 'hasSubmitted'),
+
+ localRepoError: function () {
+ if (this.get('hasSubmitted') && this.get('localRepo') && this.get('localRepoPath').trim() === '') {
+ return Em.I18n.t('installer.step2.localRepo.error.required');
+ }
+ return null;
+ }.property('localRepo', 'localRepoPath', 'hasSubmitted'),
+
+ /**
+ * Get host info, which will be saved in parent controller
+ */
+ getHostInfo: function () {
+
+ var hostNameArr = this.get('hostNameArr');
+ var hostInfo = {};
+ for (var i = 0; i < hostNameArr.length; i++) {
+ hostInfo[hostNameArr[i]] = {
+ name: hostNameArr[i],
+ installType: this.get('installType'),
+ bootStatus: 'pending'
+ };
+ }
+
+ return hostInfo;
+ },
+
+ /**
+ * Onclick handler for <code>next button</code>. Do all UI work except data saving.
+ * This work is doing by router.
+ * @return {Boolean}
+ */
+ evaluateStep: function () {
+ console.log('TRACE: Entering controller:WizardStep2:evaluateStep function');
+
+ if (this.get('isSubmitDisabled')) {
+ return false;
+ }
+
+ if (this.get('manualInstall') === true) {
+ this.manualInstallPopup();
+ return false;
+ }
+
+ // For now using mock jquery call
+ //TODO: hook up with bootstrap call
+ var bootStrapData = {'sshKey': this.get('sshKey'), hosts: this.get('hostNameArr')}.stringify;
+ $.ajax({
+ type: 'POST',
+ url: '/api/bootstrap',
+ data: bootStrapData,
+ async: false,
+ timeout: 2000,
+ success: function () {
+ console.log("TRACE: In success function for the post bootstrap function");
+ App.router.send('next');
+ },
+ error: function () {
+ console.log("ERROR: bootstrap post call failed");
+ return false;
+ },
+ complete: function () {
+ // TODO: remove this function. this is just to force navigating to the next step before bootstrap integration
+ App.router.send('next');
+ },
+ statusCode: {
+ 404: function () {
+ console.log("URI not found.");
+ //After the bootstrap call hook up change the below return statement to "return false"
+ console.log("TRACE: In faliure function for the post bootstrap function");
+ return false;
+ }
+ },
+ dataType: 'application/json'
+ });
+ },
+
+ manualInstallPopup: function (event) {
+ App.ModalPopup.show({
+ header: Em.I18n.t('installer.step2.manualInstall.popup.header'),
+ onPrimary: function () {
+ this.hide();
+ App.router.send('next');
+ },
+ bodyClass: Ember.View.extend({
+ templateName: require('templates/wizard/step2ManualInstallPopup')
+ })
+ });
+ },
+
+ isSubmitDisabled: function () {
+ return (this.get('hostsError') || this.get('sshKeyError') || this.get('localRepoError'));
+ }.property('hostsError', 'sshKeyError', 'localRepoError')
+
+});
\ No newline at end of file
Added: incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/wizard/step3_controller.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/wizard/step3_controller.js?rev=1399489&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/wizard/step3_controller.js (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/wizard/step3_controller.js Thu Oct 18 00:17:19 2012
@@ -0,0 +1,223 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.WizardStep3Controller = Em.ArrayController.extend({
+ name: 'wizardStep3Controller',
+ content: [],
+ bootHosts: [],
+ isSubmitDisabled: false,
+ categories: ['Hosts', 'Succeeded', 'Failed'],
+ category: 'Hosts',
+ allChecked: true,
+
+ onAllChecked: function () {
+ var hosts = this.visibleHosts();
+ if (this.get('allChecked') === true) {
+ hosts.setEach('isChecked', true);
+ } else {
+ hosts.setEach('isChecked', false);
+ }
+ }.observes('allChecked'),
+
+ mockData: require('data/mock/step3_hosts'),
+ mockRetryData: require('data/mock/step3_pollData'),
+
+ /**
+ * Provide some initialisation work. Start bootstrap if needed
+ */
+ navigateStep: function () {
+ if (App.db.getBootStatus() === false) {
+ this.startBootstrap();
+ }
+ },
+
+ /**
+ * Onclick handler for <code>Retry</code> button.
+ */
+ retry: function () {
+ if (this.get('isSubmitDisabled')) {
+ return;
+ }
+ var hosts = this.visibleHosts();
+ var selectedHosts = hosts.filterProperty('isChecked', true);
+ selectedHosts.forEach(function (_host) {
+ console.log('Retrying: ' + _host.name);
+ });
+
+ //TODO: uncomment below code to hookup with @GET bootstrap API
+ /*
+ this.set('bootHosts',selectedHosts);
+ this.doBootstrap();
+ */
+ },
+
+ /**
+ * Below function returns the current set of visible hosts on view (All, succeded, failed)
+ */
+ visibleHosts: function () {
+ if (this.get('category') === 'Succeeded') {
+ return (this.filterProperty('bootStatus', 'success'));
+ } else if (this.get('category') === 'Failed') {
+ return (this.filterProperty('bootStatus', 'error'));
+ } else if (this.get('category') === 'Hosts') {
+ return this.content;
+ }
+ },
+
+ /**
+ * Onclick handler for <code>Remove</code> button
+ */
+ removeBtn: function () {
+ if (this.get('isSubmitDisabled')) {
+ return;
+ }
+ var hostResult = this.visibleHosts();
+ var selectedHosts = hostResult.filterProperty('isChecked', true);
+ selectedHosts.forEach(function (_hostInfo) {
+ console.log('Removing: ' + _hostInfo.name);
+ });
+
+ this.removeHosts(selectedHosts);
+ },
+
+ /**
+ * Do remove hosts logic: remove host info from UI and save it to model
+ * @param hosts
+ */
+ removeHosts: function (hosts) {
+ this.removeObjects(hosts);
+ App.router.send('removeHosts', hosts);
+ },
+
+ startBootstrap: function () {
+ this.set('isSubmitDisabled', true);
+ this.set('bootHosts', this.get('content'));
+ this.doBootstrap();
+ },
+
+ /**
+ * Below function parses and updates the content, and governs
+ * the possibility of the next doBootstrap (polling) call
+ *
+ * @param hostsFrmServer
+ * @param hostsFrmContent
+ * @return {Boolean}
+ */
+ parseHostInfo: function (hostsFrmServer, hostsFrmContent) {
+ var result = true; // default value as true implies if the data rendered by REST API has no hosts, polling will stop
+ hostsFrmServer.forEach(function (_hostFrmServer) {
+ var host = hostsFrmContent.findProperty('name', _hostFrmServer.name);
+ if (host !== null && host !== undefined) { // check if hostname extracted from REST API data matches any hostname in content
+ host.set('bootStatus', _hostFrmServer.status);
+ host.set('cpu', _hostFrmServer.cpu);
+ host.set('memory', _hostFrmServer.memory);
+ }
+ });
+ result = !this.content.someProperty('bootStatus', 'pending');
+ return result;
+ },
+
+ doBootstrap: function () {
+ var self = this;
+ $.ajax({
+ type: 'GET',
+ url: '/ambari_server/api/bootstrap',
+ async: false,
+ timeout: 5000,
+ success: function (data) {
+ console.log("TRACE: In success function for the GET bootstrap call");
+ var result = self.parseHostInfo(data, this.get('bootHosts'));
+ if (result !== true && App.router.getInstallerCurrentStep() === '3') {
+ window.setTimeout(self.doBootstrap, 3000);
+ } else {
+ self.stopBootstrap();
+ }
+ },
+
+ error: function () {
+ console.log("ERROR");
+ self.stopBootstrap();
+ },
+
+ statusCode: {
+ 404: function () {
+ console.log("URI not found.");
+ }
+ },
+
+ dataType: 'application/json'
+ });
+
+ },
+
+ stopBootstrap: function () {
+ //TODO: uncomment following line after the hook up with the API call
+ // this.set('isSubmitDisabled',false);
+ },
+
+ hostLogPopup: function (event) {
+ App.ModalPopup.show({
+ header: Em.I18n.t('installer.step3.hostLog.popup.header'),
+ onPrimary: function () {
+ this.hide();
+ },
+ bodyClass: Ember.View.extend({
+ templateName: require('templates/installer/step3HostLogPopup')
+ })
+ });
+ },
+
+ // TODO: dummy button. Remove this after the hook up with actual REST API.
+ mockBtn: function () {
+ this.set('isSubmitDisabled', false);
+ this.clear();
+ var hostInfo = this.mockData;
+ this.renderHosts(hostInfo);
+ },
+
+ renderHosts: function (hostsInfo) {
+ var self = this;
+ hostsInfo.forEach(function (_hostInfo) {
+ var hostInfo = App.HostInfo.create({
+ name: _hostInfo.name,
+ bootStatus: _hostInfo.bootStatus
+ });
+
+ console.log('pushing ' + hostInfo.name);
+ self.content.pushObject(hostInfo);
+ });
+ },
+
+ pollBtn: function () {
+ if (this.get('isSubmitDisabled')) {
+ return;
+ }
+ var hosts = this.visibleHosts();
+ var selectedHosts = hosts.filterProperty('isChecked', true);
+
+ var mockHosts = this.mockRetryData;
+
+ if (this.parseHostInfo(mockHosts, selectedHosts)) {
+ // this.saveHostInfoToDb();
+ }
+ }
+
+});
+
Added: incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/wizard/step4_controller.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/wizard/step4_controller.js?rev=1399489&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/wizard/step4_controller.js (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/wizard/step4_controller.js Thu Oct 18 00:17:19 2012
@@ -0,0 +1,136 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.WizardStep4Controller = Em.ArrayController.extend({
+
+ name: 'wizardStep4Controller',
+ content: [],
+
+ /**
+ * Check whether all properties are selected
+ */
+ isAll: function () {
+ return this.everyProperty('isSelected', true);
+ }.property('@each.isSelected'),
+
+ /**
+ * Check whether none properties(minimum) are selected
+ */
+ isMinimum: function () {
+ return this.filterProperty('isDisabled', false).everyProperty('isSelected', false);
+ }.property('@each.isSelected'),
+
+ /**
+ * Update hidden services. Make them to have the same status as master ones.
+ */
+ checkDependencies: function () {
+ var hbase = this.findProperty('serviceName', 'HBASE');
+ var zookeeper = this.findProperty('serviceName', 'ZOOKEEPER');
+ if (hbase && zookeeper) {
+ zookeeper.set('isSelected', hbase.get('isSelected'));
+ }
+ var hive = this.findProperty('serviceName', 'HIVE');
+ var hcatalog = this.findProperty('serviceName', 'HCATALOG');
+ if (hive && hcatalog) {
+ hcatalog.set('isSelected', hive.get('isSelected'));
+ }
+ }.observes('@each.isSelected'),
+
+ /**
+ * Onclick handler for <code>select all</code> link
+ */
+ selectAll: function () {
+ this.setEach('isSelected', true);
+ },
+
+ /**
+ * onclick handler for <code>select minimum</code> link
+ */
+ selectMinimum: function () {
+ this.filterProperty('isDisabled', false).setEach('isSelected', false);
+ },
+
+ /**
+ * Check whether we should turn on <code>MapReduce</code> service
+ * @return {Boolean}
+ */
+ needToAddMapReduce: function () {
+ if (this.findProperty('serviceName', 'MAPREDUCE').get('isSelected') === false) {
+ var mapreduceDependentServices = this.filter(function (item) {
+ return ['PIG', 'OOZIE', 'HIVE'].contains(item.get('serviceName')) && item.get('isSelected', true);
+ });
+ return (mapreduceDependentServices.get('length') > 0);
+ }
+
+ return false;
+ },
+
+ /**
+ * Check do we have any monitoring service turned on
+ * @return {Boolean}
+ */
+ gangliaOrNagiosNotSelected: function () {
+ return (this.findProperty('serviceName', 'GANGLIA').get('isSelected') === false || this.findProperty('serviceName', 'NAGIOS').get('isSelected') === false);
+ },
+
+ /**
+ * Check whether user turned on monitoring service and go to next step
+ */
+ validateMonitoring: function () {
+ if (this.gangliaOrNagiosNotSelected()) {
+ App.ModalPopup.show({
+ header: Em.I18n.t('installer.step4.monitoringCheck.popup.header'),
+ body: Em.I18n.t('installer.step4.monitoringCheck.popup.body'),
+ onPrimary: function () {
+ this.hide();
+ App.router.send('next');
+ },
+ onSecondary: function () {
+ this.hide();
+ }
+ });
+ } else {
+ App.router.send('next');
+ }
+ },
+
+ /**
+ * Onlick handler for <code>Next</code> button
+ */
+ submit: function () {
+ var self = this;
+ if (this.needToAddMapReduce()) {
+ App.ModalPopup.show({
+ header: Em.I18n.t('installer.step4.mapreduceCheck.popup.header'),
+ body: Em.I18n.t('installer.step4.mapreduceCheck.popup.body'),
+ onPrimary: function () {
+ self.findProperty('serviceName', 'MAPREDUCE').set('isSelected', true);
+ this.hide();
+ self.validateMonitoring();
+ },
+ onSecondary: function () {
+ this.hide();
+ }
+ });
+ } else {
+ self.validateMonitoring();
+ }
+ }
+})
\ No newline at end of file
Added: incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/wizard/step5_controller.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/wizard/step5_controller.js?rev=1399489&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/wizard/step5_controller.js (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/wizard/step5_controller.js Thu Oct 18 00:17:19 2012
@@ -0,0 +1,592 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.WizardStep5Controller = Em.Controller.extend({
+ //properties
+ name: "wizardStep5Controller",
+ hosts: [],
+ selectedServices: [],
+ selectedServicesMasters: [],
+ zId: 0,
+ components: require('data/service_components'),
+
+ /*
+ Below function retrieves host information from local storage
+ */
+
+ clearStep: function () {
+ this.set('hosts', []);
+ this.set('selectedServices', []);
+ this.set('selectedServicesMasters', []);
+ this.set('zId', 0);
+ },
+
+ loadStep: function () {
+ console.log("TRACE: Loading step5: Assign Masters");
+ this.clearStep();
+ this.renderHostInfo(this.loadHostInfo());
+ this.renderComponents(this.loadComponents(this.loadServices()));
+ },
+
+ loadHostInfo: function () {
+ var hostInfo = [];
+ hostInfo = App.db.getHosts();
+ var hosts = new Ember.Set();
+ for (var index in hostInfo) {
+ hosts.add(hostInfo[index]);
+ console.log("TRACE: host name is: " + hostInfo[index].name);
+ }
+ return hosts.filterProperty('bootStatus', 'success');
+ },
+
+
+ renderHostInfo: function (hostsInfo) {
+
+ //wrap the model data into
+
+ hostsInfo.forEach(function (_host) {
+ var hostObj = Ember.Object.create({
+ host_name: _host.name,
+ cpu: _host.cpu,
+ memory: _host.memory
+ });
+ console.log('pushing ' + hostObj.host_name);
+ hostObj.set("host_info", "" + hostObj.get("host_name") + " ( " + hostObj.get("memory") + "GB" + " " + hostObj.get("cpu") + "cores )");
+ this.get("hosts").pushObject(hostObj);
+ }, this);
+
+
+ },
+
+ loadServices: function () {
+ var serviceInfo = App.db.getService();
+ var services = serviceInfo.filterProperty('isSelected', true).mapProperty('serviceName');
+ services.forEach(function (item) {
+ console.log("TRACE: service name is: " + item);
+ this.get("selectedServices").pushObject(Ember.Object.create({service_name: item}));
+ }, this);
+
+ return services;
+
+ },
+
+ loadComponents: function (services) {
+ var components = new Ember.Set();
+ if (App.db.getMasterComponentHosts() === undefined) {
+ var masterComponents = this.components.filterProperty('isMaster', true);
+ for (var index in services) {
+ var componentInfo = masterComponents.filterProperty('service_name', services[index]);
+ componentInfo.forEach(function (_componentInfo) {
+ console.log("TRACE: master component name is: " + _componentInfo.display_name);
+ var componentObj = {};
+ componentObj.component_name = _componentInfo.display_name;
+ componentObj.selectedHost = this.selectHost(_componentInfo.component_name); // call the method that plays selectNode algorithm or fetches from server
+ componentObj.availableHosts = [];
+ components.add(componentObj);
+ }, this);
+ }
+ } else {
+ var masterComponentHosts = App.db.getMasterComponentHosts();
+ masterComponentHosts.forEach(function (_masterComponentHost) {
+ var componentObj = {};
+ componentObj.component_name = _masterComponentHost.component;
+ componentObj.selectedHost = _masterComponentHost.hostName; // call the method that plays selectNode algorithm or fetches from server
+ componentObj.availableHosts = [];
+ components.add(componentObj);
+ }, this);
+ }
+ return components;
+ },
+
+ getMasterComponents: function () {
+ return (this.get('selectedServicesMasters').slice(0));
+ },
+
+ renderComponents: function (masterComponents) {
+ var zookeeperComponent = null, componentObj = null;
+ var services = [];
+ services = this.getMasterComponents();
+ if (services.length) {
+ this.set('selectedServicesMasters', []);
+ }
+
+
+ masterComponents.forEach(function (item) {
+ //add the zookeeper component at the end if exists
+ if (item.component_name === "ZooKeeper") {
+ if (services.length) {
+ services.forEach(function (_service) {
+ this.get('selectedServicesMasters').pushObject(_service);
+ }, this);
+ }
+ this.set('zId', parseInt(this.get('zId')) + 1);
+ zookeeperComponent = Ember.Object.create(item);
+ zookeeperComponent.set('zId', this.get('zId'));
+ zookeeperComponent.set("showRemoveControl", true);
+ zookeeperComponent.set("availableHosts", this.get("hosts").slice(0));
+ this.get("selectedServicesMasters").pushObject(Ember.Object.create(zookeeperComponent));
+
+ } else {
+ componentObj = Ember.Object.create(item);
+ componentObj.set("availableHosts", this.get("hosts").slice(0));
+ this.get("selectedServicesMasters").pushObject(componentObj);
+ }
+ }, this);
+ },
+
+ getKerberosServer: function (noOfHosts) {
+ var hosts = this.get('hosts');
+ if (noOfHosts === 1) {
+ return hosts[0];
+ } else if (noOfHosts < 3) {
+ return hosts[1];
+ } else if (noOfHosts <= 5) {
+ return hosts[1];
+ } else if (noOfHosts <= 30) {
+ return hosts[3];
+ } else {
+ return hosts[5];
+ }
+ },
+
+ getNameNode: function (noOfHosts) {
+ var hosts = this.get('hosts');
+ return hosts[0];
+ },
+
+ getSNameNode: function (noOfHosts) {
+ var hosts = this.get('hosts');
+ if (noOfHosts === 1) {
+ return hosts[0];
+ } else {
+ return hosts[1];
+ }
+ },
+
+ getJobTracker: function (noOfHosts) {
+ var hosts = this.get('hosts');
+ if (noOfHosts === 1) {
+ return hosts[0];
+ } else if (noOfHosts < 3) {
+ return hosts[1];
+ } else if (noOfHosts <= 5) {
+ return hosts[1];
+ } else if (noOfHosts <= 30) {
+ return hosts[1];
+ } else {
+ return hosts[2];
+ }
+ },
+
+ getHBaseMaster: function (noOfHosts) {
+ var hosts = this.get('hosts');
+ if (noOfHosts === 1) {
+ return hosts[0];
+ } else if (noOfHosts < 3) {
+ return hosts[0];
+ } else if (noOfHosts <= 5) {
+ return hosts[0];
+ } else if (noOfHosts <= 30) {
+ return hosts[2];
+ } else {
+ return hosts[3];
+ }
+ },
+
+ getOozieServer: function (noOfHosts) {
+ var hosts = this.get('hosts');
+ if (noOfHosts === 1) {
+ return hosts[0];
+ } else if (noOfHosts < 3) {
+ return hosts[1];
+ } else if (noOfHosts <= 5) {
+ return hosts[1];
+ } else if (noOfHosts <= 30) {
+ return hosts[2];
+ } else {
+ return hosts[3];
+ }
+ },
+
+ getOozieServer: function (noOfHosts) {
+ var hosts = this.get('hosts');
+ if (noOfHosts === 1) {
+ return hosts[0];
+ } else if (noOfHosts < 3) {
+ return hosts[1];
+ } else if (noOfHosts <= 5) {
+ return hosts[1];
+ } else if (noOfHosts <= 30) {
+ return hosts[2];
+ } else {
+ return hosts[3];
+ }
+ },
+
+ getHiveServer: function (noOfHosts) {
+ var hosts = this.get('hosts');
+ if (noOfHosts === 1) {
+ return hosts[0];
+ } else if (noOfHosts < 3) {
+ return hosts[1];
+ } else if (noOfHosts <= 5) {
+ return hosts[1];
+ } else if (noOfHosts <= 30) {
+ return hosts[2];
+ } else {
+ return hosts[4];
+ }
+ },
+
+ getTempletonServer: function (noOfHosts) {
+ var hosts = this.get('hosts');
+ if (noOfHosts === 1) {
+ return hosts[0];
+ } else if (noOfHosts < 3) {
+ return hosts[1];
+ } else if (noOfHosts <= 5) {
+ return hosts[1];
+ } else if (noOfHosts <= 30) {
+ return hosts[2];
+ } else {
+ return hosts[4];
+ }
+ },
+
+ getZooKeeperServer: function (noOfHosts) {
+ var hosts = this.get('hosts');
+ if (noOfHosts < 3) {
+ return [hosts[0].host_name];
+ } else {
+ return [hosts[0].host_name, hosts[1].host_name, hosts[2].host_name];
+ }
+ },
+
+ getGangliaServer: function (noOfHosts) {
+ var hosts = this.get('hosts');
+ var hostnames = [];
+ var inc = 0;
+ hosts.forEach(function (_hostname) {
+ hostnames[inc] = _hostname.host_name;
+ inc++;
+ });
+ var hostExcAmbari = hostnames.without(location.hostname);
+ if (hostExcAmbari !== null || hostExcAmbari !== undefined || hostExcAmbari.length !== 0) {
+ return hostExcAmbari[0];
+ } else {
+ return hostnames[0];
+ }
+ },
+
+ getNagiosServer: function (noOfHosts) {
+ var hosts = this.get('hosts');
+ var hostnames = [];
+ var inc = 0;
+ hosts.forEach(function (_hostname) {
+ hostnames[inc] = _hostname.host_name;
+ inc++;
+ });
+ var hostExcAmbari = hostnames.without(location.hostname);
+ if (hostExcAmbari !== null || hostExcAmbari !== undefined || hostExcAmbari.length !== 0) {
+ return hostExcAmbari[0];
+ } else {
+ return hostnames[0];
+ }
+ },
+
+
+ selectHost: function (componentName) {
+ var noOfHosts = this.get('hosts').length;
+ if (componentName === 'KERBEROS_SERVER') {
+ return this.getKerberosServer(noOfHosts).host_name;
+ } else if (componentName === 'NAMENODE') {
+ return this.getNameNode(noOfHosts).host_name;
+ } else if (componentName === 'SNAMENODE') {
+ return this.getSNameNode(noOfHosts).host_name;
+ } else if (componentName === 'JOBTRACKER') {
+ return this.getJobTracker(noOfHosts).host_name;
+ } else if (componentName === 'HBASE_MASTER') {
+ return this.getHBaseMaster(noOfHosts).host_name;
+ } else if (componentName === 'OOZIE_SERVER') {
+ return this.getOozieServer(noOfHosts).host_name;
+ } else if (componentName === 'HIVE_SERVER') {
+ return this.getHiveServer(noOfHosts).host_name;
+ } else if (componentName === 'TEMPLETON_SERVER') {
+ return this.getTempletonServer(noOfHosts).host_name;
+ } else if (componentName === 'ZOOKEEPER_SERVER') {
+ var zhosts = this.getZooKeeperServer(noOfHosts);
+ var extraHosts = zhosts.slice(0, zhosts.length - 1);
+ var zooKeeperHosts = new Ember.Set();
+ extraHosts.forEach(function (_host) {
+ var zooKeeperHost = {};
+ zooKeeperHost.component_name = 'ZooKeeper';
+ zooKeeperHost.selectedHost = _host;
+ zooKeeperHost.availableHosts = [];
+ zooKeeperHosts.add(zooKeeperHost);
+ });
+ this.renderComponents(zooKeeperHosts);
+ var lastHost = zhosts[zhosts.length - 1];
+ return lastHost;
+ } else if (componentName === 'GANGLIA_MONITOR_SERVER') {
+ return this.getGangliaServer(noOfHosts);
+ } else if (componentName === 'NAGIOS_SERVER') {
+ return this.getNagiosServer(noOfHosts);
+ }
+ },
+
+
+ masterHostMapping: function () {
+ var mapping = [], mappingObject, self = this, mappedHosts, hostObj, hostInfo;
+ //get the unique assigned hosts and find the master services assigned to them
+
+ mappedHosts = this.get("selectedServicesMasters").mapProperty("selectedHost").uniq();
+
+ mappedHosts.forEach(function (item) {
+ hostObj = self.get("hosts").findProperty("host_name", item);
+ console.log("Name of the host is: " + hostObj.host_name);
+ hostInfo = " ( " + hostObj.get("memory") + "GB" + " " + hostObj.get("cpu") + "cores )";
+
+ mappingObject = Ember.Object.create({
+ host_name: item,
+ hostInfo: hostInfo,
+ masterServices: self.get("selectedServicesMasters").filterProperty("selectedHost", item)
+ });
+
+ mapping.pushObject(mappingObject);
+ }, this);
+
+ mapping.sort(this.sortHostsByName);
+
+ return mapping;
+
+ }.property("selectedServicesMasters.@each.selectedHost"),
+
+ remainingHosts: function () {
+ return (this.get("hosts.length") - this.get("masterHostMapping.length"));
+ }.property("selectedServicesMasters.@each.selectedHost"),
+
+ hasZookeeper: function () {
+ return this.selectedServices.findProperty("service_name", "ZooKeeper");
+ }.property("selectedServices"),
+
+ //methods
+ getAvailableHosts: function (componentName) {
+ var assignableHosts = [],
+ zookeeperHosts = null;
+
+ if (componentName === "ZooKeeper") {
+ zookeeperHosts = this.get("selectedServicesMasters").filterProperty("component_name", "ZooKeeper").mapProperty("selectedHost").uniq();
+ this.get("hosts").forEach(function (item) {
+ if (!(zookeeperHosts.contains(item.get("host_name")))) {
+ assignableHosts.pushObject(item);
+ }
+ }, this);
+ return assignableHosts;
+
+ } else {
+ return this.get("hosts");
+ }
+ },
+
+ assignHostToMaster: function (masterService, selectedHost, zId) {
+ if (selectedHost && masterService) {
+ if ((masterService === "ZooKeeper") && zId) {
+ this.get('selectedServicesMasters').findProperty("zId", zId).set("selectedHost", selectedHost);
+ this.rebalanceZookeeperHosts();
+ }
+ else {
+ this.get('selectedServicesMasters').findProperty("component_name", masterService).set("selectedHost", selectedHost);
+ }
+
+ }
+ },
+
+ lastZooKeeper: function () {
+ var currentZooKeepers = this.get("selectedServicesMasters").filterProperty("component_name", "ZooKeeper");
+ var lastZooKeeper = currentZooKeepers.get("lastObject");
+ return lastZooKeeper;
+ },
+
+ addZookeepers: function () {
+ /*
+ *Logic: If ZooKeeper service is selected then there can be
+ * minimum 1 ZooKeeper master in total, and
+ * maximum 1 ZooKeeper on every host
+ */
+
+ var maxNumZooKeepers = this.get("hosts.length"),
+ currentZooKeepers = this.get("selectedServicesMasters").filterProperty("component_name", "ZooKeeper"),
+ newZookeeper = null,
+ zookeeperHosts = null,
+ suggestedHost = null,
+ i = 0,
+ lastZoo = null;
+ console.log('hosts legth is: ' + maxNumZooKeepers);
+ //work only if the Zookeeper service is selected in previous step
+ if (!this.get("selectedServices").mapProperty("service_name").contains("ZOOKEEPER")) {
+ console.log('ALERT: Zookeeper service was not selected');
+ return false;
+ }
+
+ if (currentZooKeepers.get("length") < maxNumZooKeepers) {
+ console.log('currentZookeeper length less than maximum. Its: ' + currentZooKeepers.get("length"))
+ currentZooKeepers.set("lastObject.showAddControl", false);
+ if (currentZooKeepers.get("length") >= 1) {
+ currentZooKeepers.set("lastObject.showRemoveControl", true);
+ }
+
+ //create a new zookeeper based on an existing one
+ newZookeeper = Ember.Object.create({});
+ lastZoo = currentZooKeepers.get("lastObject");
+ newZookeeper.set("component_name", lastZoo.get("component_name"));
+ newZookeeper.set("selectedHost", lastZoo.get("selectedHost"));
+ newZookeeper.set("availableHosts", this.getAvailableHosts("ZooKeeper"));
+
+ if (currentZooKeepers.get("length") === (maxNumZooKeepers - 1)) {
+ newZookeeper.set("showAddControl", false);
+ } else {
+ newZookeeper.set("showAddControl", true);
+ }
+ newZookeeper.set("showRemoveControl", true);
+
+ //get recommended host for the new Zookeeper server
+ zookeeperHosts = currentZooKeepers.mapProperty("selectedHost").uniq();
+
+ for (i = 0; i < this.get("hosts.length"); i++) {
+ if (!(zookeeperHosts.contains(this.get("hosts")[i].get("host_name")))) {
+ suggestedHost = this.get("hosts")[i].get("host_name");
+ break;
+ }
+ }
+
+ newZookeeper.set("selectedHost", suggestedHost);
+ newZookeeper.set("zId", (currentZooKeepers.get("lastObject.zId") + 1));
+ this.set('zId', parseInt(this.get('zId')) + 1);
+
+ this.get("selectedServicesMasters").pushObject(newZookeeper);
+
+ this.rebalanceZookeeperHosts();
+
+ return true;
+ }
+ return false;//if no more zookeepers can be added
+ },
+
+ removeZookeepers: function (zId) {
+ var currentZooKeepers;
+
+ //work only if the Zookeeper service is selected in previous step
+ if (!this.get("selectedServices").mapProperty("service_name").contains("ZOOKEEPER")) {
+ return false;
+ }
+
+ currentZooKeepers = this.get("selectedServicesMasters").filterProperty("component_name", "ZooKeeper");
+
+ if (currentZooKeepers.get("length") > 1) {
+ this.get("selectedServicesMasters").removeAt(this.get("selectedServicesMasters").indexOf(this.get("selectedServicesMasters").findProperty("zId", zId)));
+
+ currentZooKeepers = this.get("selectedServicesMasters").filterProperty("component_name", "ZooKeeper");
+ if (currentZooKeepers.get("length") < this.get("hosts.length")) {
+ currentZooKeepers.set("lastObject.showAddControl", true);
+ }
+
+ if (currentZooKeepers.get("length") === 1) {
+ currentZooKeepers.set("lastObject.showRemoveControl", false);
+ }
+ this.set('zId', parseInt(this.get('zId')) - 1);
+ this.rebalanceZookeeperHosts();
+
+ return true;
+ }
+
+ return false;
+
+ },
+
+ rebalanceZookeeperHosts: function () {
+ //for a zookeeper update the available hosts for the other zookeepers
+
+ var currentZooKeepers = this.get("selectedServicesMasters").filterProperty("component_name", "ZooKeeper"),
+ zooHosts = currentZooKeepers.mapProperty("selectedHost"),
+ availableZooHosts = [],
+ preparedAvailableHosts = null;
+
+ //get all hosts available for zookeepers
+ this.get("hosts").forEach(function (item) {
+ if (!zooHosts.contains(item.get("host_name"))) {
+ availableZooHosts.pushObject(item);
+ }
+ }, this);
+
+ currentZooKeepers.forEach(function (item) {
+ preparedAvailableHosts = availableZooHosts.slice(0);
+ preparedAvailableHosts.pushObject(this.get("hosts").findProperty("host_name", item.get("selectedHost")))
+ preparedAvailableHosts.sort(this.sortHostsByConfig, this);
+ item.set("availableHosts", preparedAvailableHosts);
+ }, this);
+
+ },
+
+ sortHostsByConfig: function (a, b) {
+ //currently handling only total memory on the host
+ if (a.memory < b.memory) {
+ return 1;
+ }
+ else {
+ return -1;
+ }
+ },
+
+ sortHostsByName: function (a, b) {
+ if (a.host_name > b.host_name) {
+ return 1;
+ }
+ else {
+ return -1;
+ }
+ },
+
+ saveComponentHostsToDb: function () {
+ var obj = this.get('selectedServicesMasters');
+ var masterComponentHosts = [];
+ var inc = 0;
+ var array = [];
+ obj.forEach(function (_component) {
+ var hostArr = [];
+ masterComponentHosts.push({
+ component: _component.component_name,
+ hostName: _component.selectedHost
+ });
+ });
+
+ App.db.setMasterComponentHosts(masterComponentHosts);
+
+ },
+
+ submit: function () {
+ this.saveComponentHostsToDb();
+ App.router.send('next');
+ }
+
+
+});
+
+
+
Modified: incubator/ambari/branches/AMBARI-666/ambari-web/app/messages.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/messages.js?rev=1399489&r1=1399488&r2=1399489&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/messages.js (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/messages.js Thu Oct 18 00:17:19 2012
@@ -221,5 +221,7 @@ Em.I18n.translations = {
'metric.cpu': 'cpu',
'metric.memory': 'disk used',
'metric.network': 'network',
- 'metric.io': 'io'
+ 'metric.io': 'io',
+ 'hosts.add.header' : 'Add Host Wizard',
+ 'hosts.add.step2.warning' : 'Hosts are already part of the cluster and will be ignored'
};
\ No newline at end of file
Modified: incubator/ambari/branches/AMBARI-666/ambari-web/app/router.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/router.js?rev=1399489&r1=1399488&r2=1399489&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/router.js (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/router.js Thu Oct 18 00:17:19 2012
@@ -73,7 +73,6 @@ App.Router = Em.Router.extend({
*/
setInstallerCurrentStep: function (currentStep, completed) {
- var loginName = this.getLoginName();
App.db.setInstallerCurrentStep(currentStep, completed);
this.set('installerController.currentStep', currentStep);
},
@@ -89,6 +88,21 @@ App.Router = Em.Router.extend({
return currentStep;
},
+ /**
+ * Get current step for <code>wizardType</code> wizard
+ * @param wizardType one of <code>installer</code>, <code>addHost</code>, <code>addServices</code>
+ */
+ getWizardCurrentStep: function (wizardType) {
+ var loginName = this.getLoginName();
+ var currentStep = App.db.getWizardCurrentStep(wizardType);
+ console.log('getInstallerCurrentStep: loginName=' + loginName + ", currentStep=" + currentStep);
+ if (!currentStep) {
+ currentStep = '1';
+ }
+ console.log('returning currentStep=' + currentStep);
+ return currentStep;
+ },
+
loggedIn: false,
getAuthenticated: function () {
@@ -154,7 +168,7 @@ App.Router = Em.Router.extend({
authenticated: function () {
var authenticated = false;
var controller = this.get('loginController');
- var hash = window.btoa(controller.get('loginName') + ":" + controller.get('password'));
+ var hash = ''; //window.btoa(controller.get('loginName') + ":" + controller.get('password'));
$.ajax({
url : '/api/check',
dataType : 'json',
Added: incubator/ambari/branches/AMBARI-666/ambari-web/app/routes/add_host_routes.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/routes/add_host_routes.js?rev=1399489&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/routes/add_host_routes.js (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/routes/add_host_routes.js Thu Oct 18 00:17:19 2012
@@ -0,0 +1,181 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module.exports = Em.Route.extend({
+ route: '/hosts/add',
+
+ enter: function (router) {
+ console.log('in /hosts/add:enter');
+
+ Ember.run.next(function () {
+ var addHostController = router.get('addHostController');
+ addHostController.loadAllPriorSteps();
+ router.transitionTo('step' + addHostController.get('currentStep'));
+ });
+
+ },
+
+ connectOutlets: function (router, context) {
+ console.log('in /hosts/add:connectOutlets');
+ router.get('mainController').connectOutlet('addHost');
+ },
+
+ step1: Em.Route.extend({
+ route: '/step1',
+ connectOutlets: function (router) {
+ console.log('in addHost.step1:connectOutlets');
+ var controller = router.get('addHostController');
+ controller.setCurrentStep('1', false);
+ controller.set('hideBackButton', true);
+ controller.loadAllPriorSteps();
+ controller.connectOutlet('wizardStep2', controller.get('content.hosts'));
+ },
+
+ next: Em.Router.transitionTo('step2'),
+ evaluateStep: function (router) {
+ console.log('in addHost.step1:evaluateStep');
+ var addHostController = router.get('addHostController');
+ var wizardStep2Controller = router.get('wizardStep2Controller');
+
+ wizardStep2Controller.set('hasSubmitted', true);
+
+ if (!wizardStep2Controller.get('isSubmitDisabled')) {
+ addHostController.saveHosts(wizardStep2Controller);
+ wizardStep2Controller.evaluateStep();
+ }
+ }
+ }),
+
+ step2: Em.Route.extend({
+ route: '/step2',
+ connectOutlets: function (router) {
+ console.log('in addHost.step2:connectOutlets');
+ var controller = router.get('addHostController');
+ controller.setCurrentStep('2', false);
+ controller.loadAllPriorSteps();
+ router.get('wizardStep3Controller').set('data', controller.getHostList(true)); // workaround
+ controller.connectOutlet('wizardStep3', controller.getHostList(true));
+ },
+ back: Em.Router.transitionTo('step1'),
+ next: function (router) {
+ console.log('in addHost.step2:next');
+ var addHostController = router.get('addHostController');
+ var wizardStep3Controller = router.get('wizardStep3Controller');
+
+ if (wizardStep3Controller.get('isSubmitDisabled') === false) {
+ addHostController.saveConfirmedHosts(wizardStep3Controller);
+ router.transitionTo('step3');
+ }
+ },
+
+ /**
+ * Wrapper for remove host action.
+ * Since saving data stored in addHostController, we should call this from router
+ * @param router
+ * @param context Array of hosts to delete
+ */
+ removeHosts: function (router, context) {
+ console.log('in addHost.step2.removeHosts:hosts to delete ', context);
+ var controller = router.get('addHostController');
+ controller.removeHosts(context);
+ }
+ }),
+
+ step3: Em.Route.extend({
+ route: '/step3',
+ connectOutlets: function (router, context) {
+ console.log('in addHost.step3:connectOutlets');
+ var controller = router.get('addHostController');
+ controller.setCurrentStep('3', false);
+ controller.set('hideBackButton', false);
+ controller.loadAllPriorSteps();
+ controller.connectOutlet('wizardStep4', controller.get('content.services'));
+ },
+ back: Em.Router.transitionTo('step2'),
+ next: function (router, context) {
+ var addHostController = router.get('addHostController');
+ var wizardStep4Controller = router.get('wizardStep4Controller');
+ addHostController.saveServices(wizardStep4Controller);
+ router.transitionTo('step4');
+ }
+ }),
+
+ step4: Em.Route.extend({
+ route: '/step4',
+ connectOutlets: function (router, context) {
+ console.log('in addHost.step4:connectOutlets');
+ var controller = router.get('addHostController');
+ controller.setCurrentStep('4', false);
+ controller.loadAllPriorSteps();
+ controller.connectOutlet('wizardStep5' /*, controller.get('content.services')*/);
+
+ },
+ back: Em.Router.transitionTo('step3'),
+ next: function (router, context) {
+ console.warn('next is not ready now');
+ }
+ }),
+
+// step5: Em.Route.extend({
+// route: '/step5',
+// connectOutlets: function (router, context) {
+// router.setNavigationFlow('step5');
+// router.setInstallerCurrentStep('5', false);
+// router.get('installerController').connectOutlet('installerStep5');
+// },
+// back: Em.Router.transitionTo('step4'),
+// next: Em.Router.transitionTo('step6')
+// }),
+//
+// step6: Em.Route.extend({
+// route: '/step6',
+// connectOutlets: function (router, context) {
+// router.setNavigationFlow('step6');
+// router.setInstallerCurrentStep('6', false);
+// router.get('installerController').connectOutlet('installerStep6');
+// },
+// back: Em.Router.transitionTo('step5'),
+// next: Em.Router.transitionTo('step7')
+// }),
+//
+
+ backToHostsList: function (router, event) {
+ router.transitionTo('hosts');
+ },
+
+ gotoStep1: Em.Router.transitionTo('step1'),
+
+ gotoStep2: Em.Router.transitionTo('step2'),
+
+ gotoStep3: Em.Router.transitionTo('step3'),
+
+ gotoStep4: Em.Router.transitionTo('step4'),
+
+ gotoStep5: Em.Router.transitionTo('step5'),
+
+ gotoStep6: Em.Router.transitionTo('step6'),
+
+ gotoStep7: Em.Router.transitionTo('step7'),
+
+ gotoStep8: Em.Router.transitionTo('step8'),
+
+ gotoStep9: Em.Router.transitionTo('step9'),
+
+ gotoStep10: Em.Router.transitionTo('step10')
+
+});
Modified: incubator/ambari/branches/AMBARI-666/ambari-web/app/routes/installer.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/routes/installer.js?rev=1399489&r1=1399488&r2=1399489&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/routes/installer.js (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/routes/installer.js Thu Oct 18 00:17:19 2012
@@ -160,6 +160,14 @@ module.exports = Em.Route.extend({
},
back: Em.Router.transitionTo('step6'),
next: Em.Router.transitionTo('step8')
+// showSlaveComponentGroup:Em.Router.transitionTo('slaveComponentGroup'),
+// slaveComponentGroup:Em.Route.extend({
+// route:'/',
+// connectOutlets:function (router, group) {
+// router.get('installerController').connectOutlet('slaveComponentGroup', group);
+// }
+// })
+
}),
step8: Em.Route.extend({
Modified: incubator/ambari/branches/AMBARI-666/ambari-web/app/routes/main.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/routes/main.js?rev=1399489&r1=1399488&r2=1399489&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/routes/main.js (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/routes/main.js Thu Oct 18 00:17:19 2012
@@ -86,10 +86,16 @@ module.exports = Em.Route.extend({
showDetails:function (router, event) {
router.get('mainHostDetailsController').setBack(true);
router.transitionTo('hostDetails.index', event.context)
+ },
+
+ addHost: function (router) {
+ router.transitionTo('hostAdd');
}
}),
+ hostAdd: require('routes/add_host_routes'),
+
hostDetails:Em.Route.extend({
route:'/hosts/:host_id',
connectOutlets:function (router, host) {
Modified: incubator/ambari/branches/AMBARI-666/ambari-web/app/styles/app.css
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/styles/app.css?rev=1399489&r1=1399488&r2=1399489&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/styles/app.css (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/styles/app.css Thu Oct 18 00:17:19 2012
@@ -163,3 +163,8 @@
}
/*End Carousel*//*End Hosts*/
+#add-host .back{
+ display: block;
+ width: 105px;
+ margin-bottom: 10px;
+}
\ No newline at end of file
Modified: incubator/ambari/branches/AMBARI-666/ambari-web/app/styles/application.less
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/styles/application.less?rev=1399489&r1=1399488&r2=1399489&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/styles/application.less (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/styles/application.less Thu Oct 18 00:17:19 2012
@@ -221,6 +221,9 @@ h1 {
.badge {
margin-left: 4px;
}
+ .slave-component-group-menu {
+ float: left;
+ }
.add-slave-component-group {
margin-bottom: 20px;
}
Modified: incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/installer/step7.hbs
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/installer/step7.hbs?rev=1399489&r1=1399488&r2=1399489&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/installer/step7.hbs (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/installer/step7.hbs Thu Oct 18 00:17:19 2012
@@ -42,6 +42,16 @@
{{#view App.ServiceConfigsByCategoryView categoryBinding="category" serviceConfigsBinding="selectedService.configs"}}
<div class="accordion-body collapse in">
<div class="accordion-inner">
+ {{#if category.isForSlaveComponent}}
+ <div class="slave-component-group-menu">
+ {{view App.SlaveComponentGroupsMenu}}
+ </div>
+ {{#view App.AddSlaveComponentGroupButton slaveComponentNameBinding="category.name"}}
+ <a
+ class="btn add-slave-component-group btn-large" {{action addSlaveComponentGroup category.name target="App.router.slaveComponentGroupsController"}}><i
+ class="icon-plus"></i></a>
+ {{/view}}
+ {{/if}}
<form class="form-horizontal">
{{#each view.categoryConfigs}}
<div {{bindAttr class="errorMessage:error: :control-group"}}>
@@ -57,13 +67,6 @@
</div>
{{/view}}
</div>
- {{#if category.isForSlaveComponent}}
- {{#view App.AddSlaveComponentGroupButton slaveComponentNameBinding="category.name"}}
- <a
- class="btn add-slave-component-group" {{action showAddSlaveComponentGroup category.name target="App.router.slaveComponentGroupsController"}}><i
- class="icon-plus-sign"></i> Add a {{category.name}} Group</a>
- {{/view}}
- {{/if}}
{{/each}}
</div>
{{#if isSubmitDisabled}}
Modified: incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/main/host.hbs
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/main/host.hbs?rev=1399489&r1=1399488&r2=1399489&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/main/host.hbs (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/main/host.hbs Thu Oct 18 00:17:19 2012
@@ -39,7 +39,7 @@
<button {{bindAttr disabled="controller.isDisabled"}} class="btn btn-primary" data-toggle="modal" {{action "deleteButtonPopup" target="controller"}}>
Delete
</button>
- <button class="btn btn-inverse add-host-button" disabled="disabled">
+ <button class="btn btn-inverse add-host-button" {{action addHost}}>
<i class="icon-plus icon-white"></i>
Add New Host
</button>
Added: incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/main/host/add.hbs
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/main/host/add.hbs?rev=1399489&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/main/host/add.hbs (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/main/host/add.hbs Thu Oct 18 00:17:19 2012
@@ -0,0 +1,49 @@
+<!--
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+-->
+
+<div id="add-host">
+ <div class="container">
+ <div class="container-fluid">
+
+ <a class="btn back" {{action backToHostsList}}>â Back to Hosts</a>
+
+ <div class="row-fluid">
+ <div class="span3">
+ <!--Sidebar content-->
+ <div class="well">
+ <ul class="nav nav-pills nav-stacked">
+ <li class="nav-header">{{t hosts.add.header}}</li>
+ <li {{bindAttr class="isStep1:active view.isStep1Disabled:disabled"}}><a href="javascript:void(null);" {{action gotoStep1 target="controller"}}>{{t installer.step2.header}}</a></li>
+ <li {{bindAttr class="isStep2:active view.isStep2Disabled:disabled"}}><a href="javascript:void(null);" {{action gotoStep2 target="controller"}}>{{t installer.step3.header}}</a></li>
+ <li {{bindAttr class="isStep3:active view.isStep3Disabled:disabled"}}><a href="javascript:void(null);" {{action gotoStep3 target="controller"}}>{{t installer.step4.header}}</a></li>
+ <li {{bindAttr class="isStep4:active view.isStep4Disabled:disabled"}}><a href="javascript:void(null);" {{action gotoStep4 target="controller"}}>{{t installer.step5.header}}</a></li>
+ <li {{bindAttr class="isStep5:active view.isStep5Disabled:disabled"}}><a href="javascript:void(null);" {{action gotoStep5 target="controller"}}>{{t installer.step6.header}}</a></li>
+ <li {{bindAttr class="isStep6:active view.isStep6Disabled:disabled"}}><a href="javascript:void(null);" {{action gotoStep6 target="controller"}}>{{t installer.step7.header}}</a></li>
+ <li {{bindAttr class="isStep7:active view.isStep7Disabled:disabled"}}><a href="javascript:void(null);" {{action gotoStep7 target="controller"}}>{{t installer.step8.header}}</a></li>
+ <li {{bindAttr class="isStep8:active view.isStep8Disabled:disabled"}}><a href="javascript:void(null);" {{action gotoStep8 target="controller"}}>{{t installer.step9.header}}</a></li>
+ <li {{bindAttr class="isStep9:active view.isStep9Disabled:disabled"}}><a href="javascript:void(null);" {{action gotoStep9 target="controller"}}>{{t installer.step10.header}}</a></li>
+ </ul>
+ </div>
+ </div>
+ <div id="add-host-content" class="well span9">
+ {{outlet}}
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
Added: incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/wizard/step2.hbs
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/wizard/step2.hbs?rev=1399489&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/wizard/step2.hbs (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/wizard/step2.hbs Thu Oct 18 00:17:19 2012
@@ -0,0 +1,130 @@
+<!--
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+-->
+<div id="installOptions">
+ <h2>{{t installer.step2.header}}</h2>
+
+ <p class="alert alert-info">{{t installer.step2.body}}</p>
+
+ <div id="targetHosts">
+ <h5>{{t installer.step2.targetHosts}}</h5>
+
+ <div {{bindAttr class="hostsError:error :control-group"}}>
+ <p>{{t installer.step2.targetHosts.info}}. Or use
+ <a href="javascript:void(null)"
+ rel="popover"
+ {{translateAttr title="installer.step2.hostPattern.tooltip.title" data-content="installer.step2.hostPattern.tooltip.content"}}>
+ {{t installer.step2.hostPattern.tooltip.title}}
+ </a>
+ </p>
+
+ {{#if view.parentView.controller.hideBackButton}}
+ {{#if content.hostNames }}
+ <p class="alert alert-info">{{t hosts.add.step2.warning}}</p>
+ {{/if}}
+ {{/if}}
+
+ <div class="controls">
+ {{view Ember.TextArea class="span6" valueBinding="content.hostNames" rows="5" placeholder="host names"}}
+ {{#if hostsError}}
+ <p class="help-inline">{{hostsError}}</p>
+ {{/if}}
+ </div>
+ </div>
+ </div>
+
+ <div id="hostConnectivity">
+ <div class="ambari-agents">
+ <h5>{{t installer.step2.sshKey}}</h5>
+
+ <p>{{t installer.step2.sshKey.info}}</p>
+
+ <div {{bindAttr class="sshKeyError:error :control-group"}}>
+ <div class="controls">
+ {{view Ember.TextArea class="span6" rows="4" placeholder="ssh private key" valueBinding="content.sshKey"}}
+ {{#if sshKeyError}}
+ <span
+ class="help-inline">{{sshKeyError}}</span>
+ {{/if}}
+ </div>
+ </div>
+
+ <label class="checkbox">
+ {{t installer.step2.manualInstall.label}}
+ <a href="javascript:void(null)"
+ 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"}}
+ </label>
+
+ {{#if "manualInstall"}}
+ <div class="alert">
+ {{t installer.step2.manualInstall.info}}
+ </div>
+ {{/if}}
+
+ <!--
+ {{view Ember.TextField type="text" placeholder="passphrase" valueBinding="content.passphrase"}}
+
+ <div {{bindAttr class="passphraseMatchErr:error :control-group :ambari-agents"}}>
+ <div class="controls">
+ {{view Ember.TextField type="text" placeholder="confirm passphrase" valueBinding="content.confirmPassphrase"}}
+
+ {{#if passphraseMatchErr}}
+ <p class="help-inline">{{t installer.step2.passphrase.error.match}}</p>
+ {{/if}}
+ </div>
+ </div>
+ -->
+ </div>
+ </div>
+
+ <div id="localRepo">
+ <h5>{{t installer.step2.localRepo.header}}</h5>
+ <label class="checkbox">
+ {{t installer.step2.localRepo.label}}
+ <a href="javascript:void(null)"
+ 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"}}
+ </label>
+
+ {{#if "localRepo"}}
+ <div {{bindAttr class="localRepoError:error :control-group"}}>
+ <div class="alert alert-info">
+ {{t installer.step2.localRepo.info}}
+ </div>
+ <div class="controls">
+ {{view Ember.TextField type="text" class="span6" placeholder="Local repo file path (e.g., /etc/yum/repos.d/hdp)" valueBinding="content.localRepoPath"}}
+ {{#if localRepoError}}
+ <p class="help-inline">{{localRepoError}}</p>
+ {{/if}}
+ </div>
+ </div>
+ {{/if}}
+ </div>
+ <div class="btn-area">
+ {{#unless view.parentView.controller.hideBackButton }}
+ <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>
+ </div>
+
+</div>
\ No newline at end of file
Added: incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/wizard/step2ManualInstallPopup.hbs
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/wizard/step2ManualInstallPopup.hbs?rev=1399489&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/wizard/step2ManualInstallPopup.hbs (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/wizard/step2ManualInstallPopup.hbs Thu Oct 18 00:17:19 2012
@@ -0,0 +1 @@
+<p>{{t installer.step2.manualInstall.popup.body}}</p>
Added: incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/wizard/step3.hbs
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/wizard/step3.hbs?rev=1399489&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/wizard/step3.hbs (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/wizard/step3.hbs Thu Oct 18 00:17:19 2012
@@ -0,0 +1,113 @@
+<!--
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+-->
+
+<h2>{{t installer.step3.header}}</h2>
+<p class="alert alert-info">{{t installer.step3.body}}</p>
+<div class="box">
+ <div class="box-header">
+ <div class="button-section">
+ <a class="btn btn-primary decommission" {{bindAttr disabled="isSubmitDisabled"}}
+ href="#" {{action retry target="controller"}}><i
+ class="icon-repeat icon-white"></i>
+ Retry
+ </a>
+ <a class="btn btn-primary" {{bindAttr disabled="isSubmitDisabled"}}
+ href="#" {{action removeBtn target="controller" }}><i
+ class="icon-trash icon-white"></i>
+ Remove
+ </a>
+ <a class="btn btn-info"
+ href="#" {{action mockBtn target="controller" }}>
+ mockData
+ </a>
+ <a class="btn btn-info"
+ href="#" {{action pollBtn target="controller" }}>
+ pollData
+ </a>
+
+ <div class="dropdown pull-right">
+ {{view Ember.Select class="pull-right"
+ contentBinding="controller.categories"
+ selectionBinding="controller.category"}}
+ <h5 class="pull-right text-info">Filter By:  </h5>
+ </div>
+
+ </div>
+ </div>
+
+
+ <table class="table table-bordered table-striped">
+ <thead>
+ <tr>
+ <th>
+ {{view Ember.Checkbox checkedBinding="allChecked"}}
+ </th>
+ <th>Status</th>
+ <!-- given by the parsing function that parses data from bootstrap call -->
+ <th>Host</th>
+ <!-- retrieved from local storage initially -->
+ <th>Message</th>
+ <!-- given by the parsing function that parses data from bootstrap call, dynamically assign the color -->
+ <th>Action</th>
+ <!-- trash icon -->
+ <!-- retry icon -->
+ </tr>
+ </thead>
+
+ <tbody>
+
+ {{#each host in controller}}
+ {{#view App.HostView categoryBinding="controller.category" hostInfoBinding="host"}}
+ {{#if view.isVisible}}
+ <tr {{bindAttr class = "host.bootStatus"}}>
+ <td>
+ {{view Ember.Checkbox checkedBinding="host.isChecked"}}
+ </td>
+ <td>
+ {{host.bootStatus}}
+ </td>
+
+ <td>
+ {{host.name}}
+ </td>
+ <td>
+ <a href="javascript:void(null)"
+ data-toggle="modal" {{action "hostLogPopup" target="controller"}}>{{host.message}}</a>
+ </td>
+ <td>
+ <a href="javascript:void(null)" {{action removeItem target="view"}}><i
+ class="icon-trash"></i></a>
+ </td>
+ </tr>
+ {{/if}}
+ {{/view}}
+ {{/each}}
+
+ </tbody>
+
+ </table>
+ <div class="box-footer">
+ <hr/>
+ <div class="footer-pagination">
+ </div>
+ </div>
+</div>
+<div class="btn-area">
+ <a class="btn pull-left" {{action back}}>← Back</a>
+ <a class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}} {{action next}}>Next →</a>
+</div>
Added: incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/wizard/step3HostLogPopup.hbs
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/wizard/step3HostLogPopup.hbs?rev=1399489&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/wizard/step3HostLogPopup.hbs (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/wizard/step3HostLogPopup.hbs Thu Oct 18 00:17:19 2012
@@ -0,0 +1 @@
+<p>{{t installer.step3.hostLog.popup.body}}</p>