| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| var App = require('app'); |
| var stringUtils = require('utils/string_utils'); |
| var validator = require('utils/validator'); |
| |
| App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, App.wizardDeployProgressControllerMixin, App.ConfigOverridable, App.ConfigsSaverMixin, { |
| |
| name: 'wizardStep8Controller', |
| |
| /** |
| * @type {boolean} |
| */ |
| isAddService: Em.computed.equal('content.controllerName', 'addServiceController'), |
| |
| /** |
| * @type {boolean} |
| */ |
| isAddHost: Em.computed.equal('content.controllerName', 'addHostController'), |
| |
| /** |
| * @type {boolean} |
| */ |
| isInstaller: Em.computed.equal('content.controllerName', 'installerController'), |
| |
| /** |
| * List of raw data about cluster that should be displayed |
| * @type {Array} |
| */ |
| rawContent: [ |
| { |
| config_name: 'Admin', |
| display_name: 'Admin Name', |
| config_value: '' |
| }, |
| { |
| config_name: 'cluster', |
| display_name: 'Cluster Name', |
| config_value: '' |
| }, |
| { |
| config_name: 'hosts', |
| display_name: 'Total Hosts', |
| config_value: '' |
| }, |
| { |
| config_name: 'Repo', |
| display_name: 'Local Repository', |
| config_value: '' |
| } |
| ], |
| |
| /** |
| * List of data about cluster (based on formatted <code>rawContent</code>) |
| * @type {Object[]} |
| */ |
| clusterInfo: [], |
| |
| /** |
| * List of services with components assigned to hosts |
| * @type {Object[]} |
| */ |
| services: [], |
| |
| /** |
| * @type {Object[]} |
| */ |
| configs: [], |
| |
| /** |
| * True if Kerberos is installed on the cluster and the kdc_type on the server is set to "none" |
| * @type {Boolean} |
| */ |
| isManualKerberos: Em.computed.equal('App.router.mainAdminKerberosController.kdc_type', 'none'), |
| |
| showDownloadCsv: function () { |
| return !!App.get('router.mainAdminKerberosController.kdc_type') |
| }.property('App.router.mainAdminKerberosController.kdc_type'), |
| |
| |
| /** |
| * Should Submit button be disabled |
| * @type {bool} |
| */ |
| isSubmitDisabled: false, |
| |
| /** |
| * Should Back button be disabled |
| * @type {bool} |
| */ |
| isBackBtnDisabled: false, |
| |
| /** |
| * Is error appears while <code>ajaxQueue</code> executes |
| * @type {bool} |
| */ |
| hasErrorOccurred: false, |
| |
| /** |
| * Are services installed |
| * Used to hide Deploy Progress Bar |
| * @type {bool} |
| */ |
| servicesInstalled: false, |
| |
| /** |
| * List of service config tags |
| * @type {Object[]} |
| */ |
| serviceConfigTags: [], |
| |
| /** |
| * Selected config group |
| * @type {Object} |
| */ |
| selectedConfigGroup: null, |
| |
| /** |
| * List of config groups |
| * @type {Object[]} |
| */ |
| configGroups: [], |
| |
| /** |
| * List of selected but not installed services |
| * @type {Object[]} |
| */ |
| selectedServices: function () { |
| return this.get('content.services').filterProperty('isSelected', true).filterProperty('isInstalled', false); |
| }.property('content.services.@each.isSelected','content.services.@each.isInstalled').cacheable(), |
| |
| /** |
| * List of installed services |
| * @type {Object[]} |
| */ |
| installedServices: Em.computed.filterBy('content.services', 'isInstalled', true), |
| |
| /** |
| * Current cluster name |
| * @type {string} |
| */ |
| clusterName: Em.computed.alias('content.cluster.name'), |
| |
| /** |
| * List of existing cluster names |
| * @type {string[]} |
| */ |
| clusterNames: [], |
| |
| /** |
| * Number of completed cluster delete requests |
| * @type {number} |
| */ |
| clusterDeleteRequestsCompleted: 0, |
| |
| /** |
| * Number of existing repo_versions |
| * @type {number} |
| */ |
| existingRepositoryVersions: 0, |
| |
| /** |
| * Indicates if all cluster delete requests are completed |
| * @type {boolean} |
| */ |
| isAllClusterDeleteRequestsCompleted: Em.computed.equalProperties('clusterDeleteRequestsCompleted', 'clusterNames.length'), |
| |
| /** |
| * Error popup body views for clusters that couldn't be deleted |
| * @type {App.AjaxDefaultErrorPopupBodyView[]} |
| */ |
| clusterDeleteErrorViews: [], |
| |
| /** |
| * Clear current step data |
| * @method clearStep |
| */ |
| clearStep: function () { |
| this.get('services').clear(); |
| this.get('configs').clear(); |
| this.get('clusterInfo').clear(); |
| this.get('serviceConfigTags').clear(); |
| this.set('servicesInstalled', false); |
| this.set('ajaxQueueLength', 0); |
| this.set('ajaxRequestsQueue', App.ajaxQueue.create()); |
| this.set('ajaxRequestsQueue.finishedCallback', this.ajaxQueueFinished); |
| this.get('clusterDeleteErrorViews').clear(); |
| this.set('clusterDeleteRequestsCompleted', 0); |
| }, |
| |
| /** |
| * Load current step data |
| * @method loadStep |
| */ |
| loadStep: function () { |
| this.clearStep(); |
| if (this.get('content.serviceConfigProperties')) { |
| this.formatProperties(); |
| this.loadConfigs(); |
| } |
| this.loadClusterInfo(); |
| this.loadServices(); |
| this.set('isSubmitDisabled', false); |
| this.set('isBackBtnDisabled', false); |
| }, |
| |
| /** |
| * replace whitespace character with coma between directories |
| * @method formatProperties |
| */ |
| formatProperties: function () { |
| this.get('content.serviceConfigProperties').forEach(function (_configProperty) { |
| _configProperty.value = (typeof _configProperty.value === "boolean") |
| ? _configProperty.value.toString() : App.config.trimProperty(_configProperty, false); |
| }); |
| }, |
| |
| /** |
| * Load all site properties |
| * @method loadConfigs |
| */ |
| loadConfigs: function () { |
| this.set('configs', this.get('content.serviceConfigProperties').filter(function (config) { |
| return !config.group; |
| })); |
| }, |
| |
| /** |
| * Format <code>content.hosts</code> from Object to Array |
| * @returns {Array} |
| * @method getRegisteredHosts |
| */ |
| getRegisteredHosts: function () { |
| var allHosts = this.get('content.hosts'); |
| var hosts = []; |
| for (var hostName in allHosts) { |
| if (allHosts.hasOwnProperty(hostName)) { |
| if (allHosts[hostName].bootStatus == 'REGISTERED') { |
| allHosts[hostName].hostName = allHosts[hostName].name; |
| hosts.pushObject(allHosts[hostName]); |
| } |
| } |
| } |
| return hosts; |
| }, |
| |
| /** |
| * Load all info about cluster to <code>clusterInfo</code> variable |
| * @method loadClusterInfo |
| */ |
| loadClusterInfo: function () { |
| |
| //Admin name |
| var admin = this.rawContent.findProperty('config_name', 'Admin'); |
| admin.config_value = App.db.getLoginName(); |
| if (admin.config_value) { |
| this.get('clusterInfo').pushObject(Ember.Object.create(admin)); |
| } |
| |
| // cluster name |
| var cluster = this.rawContent.findProperty('config_name', 'cluster'); |
| cluster.config_value = this.get('content.cluster.name'); |
| this.get('clusterInfo').pushObject(Ember.Object.create(cluster)); |
| |
| //hosts |
| var newHostsCount = 0; |
| var totalHostsCount = 0; |
| var hosts = this.get('content.hosts'); |
| for (var hostName in hosts) { |
| newHostsCount += ~~(!hosts[hostName].isInstalled); |
| totalHostsCount++; |
| } |
| |
| var totalHostsObj = this.rawContent.findProperty('config_name', 'hosts'); |
| totalHostsObj.config_value = totalHostsCount + ' (' + newHostsCount + ' new)'; |
| this.get('clusterInfo').pushObject(Em.Object.create(totalHostsObj)); |
| |
| //repo |
| if (['addHostController', 'addServiceController'].contains(this.get('content.controllerName'))) { |
| // For some stacks there is no info regarding stack versions to upgrade, e.g. HDP-2.1 |
| if (App.StackVersion.find().get('content.length')) { |
| this.loadRepoInfo(); |
| } else { |
| this.loadDefaultRepoInfo(); |
| } |
| } else { |
| // from install wizard |
| var selectedStack = App.Stack.find().findProperty('isSelected'); |
| var allRepos = []; |
| if (selectedStack && selectedStack.get('operatingSystems')) { |
| selectedStack.get('operatingSystems').forEach(function (os) { |
| if (os.get('isSelected')) { |
| os.get('repositories').forEach(function(repo) { |
| if (repo.get('showRepo')) { |
| allRepos.push(Em.Object.create({ |
| base_url: repo.get('baseUrl'), |
| os_type: repo.get('osType'), |
| repo_id: repo.get('repoId') |
| })); |
| } |
| }, this); |
| } |
| }, this); |
| } |
| allRepos.set('display_name', Em.I18n.t("installer.step8.repoInfo.displayName")); |
| this.get('clusterInfo').set('useRedhatSatellite', selectedStack.get('useRedhatSatellite')); |
| this.get('clusterInfo').set('repoInfo', allRepos); |
| } |
| }, |
| |
| /** |
| * Load repo info for add Service/Host wizard review page |
| * @return {$.ajax|null} |
| * @method loadRepoInfo |
| */ |
| loadRepoInfo: function () { |
| var stackName = App.get('currentStackName'); |
| var currentStackVersionNumber = App.get('currentStackVersionNumber'); |
| var currentStackVersion = App.StackVersion.find().filterProperty('stack', stackName).findProperty('version', currentStackVersionNumber); |
| var currentRepoVersion = currentStackVersion.get('repositoryVersion.repositoryVersion'); |
| |
| return App.ajax.send({ |
| name: 'cluster.load_repo_version', |
| sender: this, |
| data: { |
| stackName: stackName, |
| repositoryVersion: currentRepoVersion |
| }, |
| success: 'loadRepoInfoSuccessCallback', |
| error: 'loadRepoInfoErrorCallback' |
| }); |
| }, |
| |
| /** |
| * Save all repo base URL of all OS type to <code>repoInfo<code> |
| * @param {object} data |
| * @method loadRepoInfoSuccessCallback |
| */ |
| loadRepoInfoSuccessCallback: function (data) { |
| Em.assert('Current repo-version may be only one', data.items.length === 1); |
| if (data.items.length) { |
| var allRepos = this.generateRepoInfo(Em.getWithDefault(data, 'items.0.repository_versions.0.operating_systems', [])); |
| allRepos.set('display_name', Em.I18n.t("installer.step8.repoInfo.displayName")); |
| this.get('clusterInfo').set('repoInfo', allRepos); |
| //if the property is missing, set as false |
| this.get('clusterInfo').set('useRedhatSatellite', data.items[0].repository_versions[0].operating_systems[0].OperatingSystems.ambari_managed_repositories === false); |
| } else { |
| this.loadDefaultRepoInfo(); |
| } |
| }, |
| |
| /** |
| * Generate list regarding info about OS versions and repositories. |
| * |
| * @param {Object{}} oses - OS array |
| * @returns {Em.Object[]} |
| */ |
| generateRepoInfo: function(oses) { |
| return oses.map(function(os) { |
| return os.repositories.map(function (repository) { |
| return Em.Object.create({ |
| base_url: repository.Repositories.base_url, |
| os_type: repository.Repositories.os_type, |
| repo_id: repository.Repositories.repo_id |
| }); |
| }); |
| }).reduce(function(p, c) { return p.concat(c); }); |
| }, |
| |
| /** |
| * Load repo info from stack. Used if installed stack doesn't have upgrade info. |
| * |
| * @returns {$.Deferred} |
| * @method loadDefaultRepoInfo |
| */ |
| loadDefaultRepoInfo: function() { |
| var nameVersionCombo = App.get('currentStackVersion').split('-'); |
| |
| return App.ajax.send({ |
| name: 'cluster.load_repositories', |
| sender: this, |
| data: { |
| stackName: nameVersionCombo[0], |
| stackVersion: nameVersionCombo[1] |
| }, |
| success: 'loadDefaultRepoInfoSuccessCallback', |
| error: 'loadRepoInfoErrorCallback' |
| }); |
| }, |
| |
| /** |
| * @param {Object} data - JSON data from server |
| * @method loadDefaultRepoInfoSuccessCallback |
| */ |
| loadDefaultRepoInfoSuccessCallback: function (data) { |
| var allRepos = this.generateRepoInfo(Em.getWithDefault(data, 'items', [])); |
| allRepos.set('display_name', Em.I18n.t("installer.step8.repoInfo.displayName")); |
| this.get('clusterInfo').set('repoInfo', allRepos); |
| //if the property is missing, set as false |
| this.get('clusterInfo').set('useRedhatSatellite', data.items[0].OperatingSystems.ambari_managed_repositories === false); |
| }, |
| |
| /** |
| * @param {object} request |
| * @method loadRepoInfoErrorCallback |
| */ |
| loadRepoInfoErrorCallback: function (request) { |
| var allRepos = []; |
| allRepos.set('display_name', Em.I18n.t("installer.step8.repoInfo.displayName")); |
| this.get('clusterInfo').set('repoInfo', allRepos); |
| }, |
| |
| /** |
| * Load all info about services to <code>services</code> variable |
| * @method loadServices |
| */ |
| loadServices: function () { |
| this.get('selectedServices').filterProperty('isHiddenOnSelectServicePage', false).forEach(function (service) { |
| var serviceObj = Em.Object.create({ |
| service_name: service.get('serviceName'), |
| display_name: service.get('displayNameOnSelectServicePage'), |
| service_components: Em.A([]) |
| }); |
| service.get('serviceComponents').forEach(function (component) { |
| // show clients for services that have only clients components |
| if ((component.get('isClient') || component.get('isRequiredOnAllHosts')) && !service.get('isClientOnlyService')) return; |
| // no HA component |
| if (component.get('isHAComponentOnly')) return; |
| // skip if component is not allowed on single node cluster |
| if (Object.keys(this.get('content.hosts')).length == 1 && component.get('isNotAllowedOnSingleNodeCluster')) return; |
| var displayName; |
| if (component.get('isClient')) { |
| displayName = Em.I18n.t('common.clients') |
| } else { |
| // remove service name from component display name |
| displayName = App.format.role(component.get('componentName'), false).replace(new RegExp('^' + service.get('serviceName') + '\\s', 'i'), ''); |
| } |
| |
| var componentName = component.get('componentName'); |
| var masterComponents = this.get('content.masterComponentHosts'); |
| var isMasterComponentSelected = masterComponents.someProperty('component', componentName); |
| var isMaster = component.get('isMaster'); |
| |
| if (!isMaster || isMasterComponentSelected) { |
| serviceObj.get('service_components').pushObject(Em.Object.create({ |
| component_name: component.get('isClient') ? Em.I18n.t('common.client').toUpperCase() : component.get('componentName'), |
| display_name: displayName, |
| component_value: this.assignComponentHosts(component) |
| })); |
| } |
| }, this); |
| if (service.get('customReviewHandler')) { |
| for (var displayName in service.get('customReviewHandler')) { |
| serviceObj.get('service_components').pushObject(Em.Object.create({ |
| display_name: displayName, |
| component_value: this.assignComponentHosts(Em.Object.create({ |
| customHandler: service.get('customReviewHandler.' + displayName) |
| })) |
| })); |
| } |
| } |
| this.get('services').pushObject(serviceObj); |
| }, this); |
| }, |
| |
| /** |
| * Set <code>component_value</code> property to <code>component</code> |
| * @param {Em.Object} component |
| * @return {String} |
| * @method assignComponentHosts |
| */ |
| assignComponentHosts: function (component) { |
| var componentValue; |
| if (component.get('customHandler')) { |
| componentValue = this[component.get('customHandler')].call(this, component); |
| } |
| else { |
| if (component.get('isMaster')) { |
| componentValue = this.getMasterComponentValue(component.get('componentName')); |
| } |
| else { |
| var componentName = component.get('isClient') ? Em.I18n.t('common.client').toUpperCase() : component.get('componentName'); |
| var hostsLength = this.get('content.slaveComponentHosts') |
| .findProperty('componentName', componentName).hosts.length; |
| componentValue = hostsLength + Em.I18n.t('installer.step8.host' + ((hostsLength > 1) ? 's' : '')); |
| } |
| } |
| return componentValue; |
| }, |
| |
| getMasterComponentValue: function (componentName) { |
| var masterComponents = this.get('content.masterComponentHosts'); |
| var hostsCount = masterComponents.filterProperty('component', componentName).length; |
| return stringUtils.pluralize(hostsCount, |
| masterComponents.findProperty('component', componentName).hostName, |
| hostsCount + ' ' + Em.I18n.t('installer.step8.hosts')); |
| }, |
| |
| loadHiveDbValue: function() { |
| return this.loadDbValue('HIVE'); |
| }, |
| |
| loadOozieDbValue: function() { |
| return this.loadDbValue('OOZIE'); |
| }, |
| |
| /** |
| * Set displayed Hive DB value based on DB type |
| * @method loadHiveDbValue |
| */ |
| loadDbValue: function (serviceName) { |
| var serviceConfigProperties = this.get('content.serviceConfigProperties'); |
| var dbFull = serviceConfigProperties.findProperty('name', serviceName.toLowerCase() + '_database'); |
| //db = serviceConfigProperties.findProperty('name', serviceName.toLowerCase() + '_ambari_database'); |
| //since db.value contains the intial default value of <service>_admin_database (MySQL) and not the actual db type selected, |
| //ignore the value when displaying the database name on the summary page |
| return dbFull ? dbFull.value : ''; |
| }, |
| |
| /** |
| * Set displayed HBase master value |
| * @param {Object} hbaseMaster |
| * @method loadHbaseMasterValue |
| */ |
| loadHbaseMasterValue: function (hbaseMaster) { |
| var hbaseHostName = this.get('content.masterComponentHosts').filterProperty('component', hbaseMaster.component_name); |
| if (hbaseHostName.length == 1) { |
| hbaseMaster.set('component_value', hbaseHostName[0].hostName); |
| } else { |
| hbaseMaster.set('component_value', hbaseHostName[0].hostName + " " + Em.I18n.t('installer.step8.other').format(hbaseHostName.length - 1)); |
| } |
| }, |
| |
| /** |
| * Set displayed ZooKeeper Server value |
| * @param {Object} serverComponent |
| * @method loadZkServerValue |
| */ |
| loadZkServerValue: function (serverComponent) { |
| var zkHostNames = this.get('content.masterComponentHosts').filterProperty('component', serverComponent.component_name).length; |
| var hostSuffix; |
| if (zkHostNames === 1) { |
| hostSuffix = Em.I18n.t('installer.step8.host'); |
| } else { |
| hostSuffix = Em.I18n.t('installer.step8.hosts'); |
| } |
| serverComponent.set('component_value', zkHostNames + hostSuffix); |
| }, |
| |
| /** |
| * Onclick handler for <code>next</code> button |
| * @method submit |
| * @return {void} |
| */ |
| submit: function () { |
| var wizardController; |
| if (!this.get('isSubmitDisabled')) { |
| wizardController = App.router.get(this.get('content.controllerName')); |
| wizardController.setLowerStepsDisable(wizardController.get('currentStep')); |
| this.set('isSubmitDisabled', true); |
| this.set('isBackBtnDisabled', true); |
| this.showRestartWarnings() |
| .then(this.checkKDCSession.bind(this)); |
| } |
| }, |
| |
| /** |
| * Warn user about services that will be restarted during installation. |
| * |
| * @returns {$.Deferred} |
| */ |
| showRestartWarnings: function() { |
| var self = this; |
| var dfd = $.Deferred(); |
| var wizardController = App.router.get(this.get('content.controllerName')); |
| var selectedServiceNames = this.get('selectedServices').mapProperty('serviceName'); |
| var installedServiceNames = this.get('installedServices').mapProperty('serviceName'); |
| |
| if (this.get('content.controllerName') === 'addServiceController' && selectedServiceNames.contains('OOZIE')) { |
| var affectedServices = ['HDFS', 'YARN'].filter(function(serviceName) { |
| return installedServiceNames.contains(serviceName); |
| }); |
| if (affectedServices.length) { |
| var serviceNames = affectedServices.length > 1 ? |
| '<b>{0}</b> {1} <b>{2}</b>'.format(affectedServices[0], Em.I18n.t('and'), affectedServices[1]) : '<b>' + affectedServices[0] + '</b> '; |
| App.ModalPopup.show({ |
| encodeBody: false, |
| header: Em.I18n.t('common.warning'), |
| body: Em.I18n.t('installer.step8.services.restart.required').format(serviceNames, stringUtils.pluralize(affectedServices.length, Em.I18n.t('common.service').toLowerCase())), |
| secondary: Em.I18n.t('common.cancel'), |
| primary: Em.I18n.t('common.proceedAnyway'), |
| onPrimary: function() { |
| this.hide(); |
| dfd.resolve(); |
| }, |
| onClose: function() { |
| this.hide(); |
| self.set('isSubmitDisabled', false); |
| self.set('isBackBtnDisabled', false); |
| wizardController.setStepsEnable(); |
| dfd.reject(); |
| }, |
| onSecondary: function() { |
| this.onClose(); |
| } |
| }); |
| } else { |
| dfd.resolve(); |
| } |
| } else { |
| dfd.resolve(); |
| } |
| return dfd.promise(); |
| }, |
| |
| checkKDCSession: function() { |
| var self = this; |
| var wizardController = App.router.get(this.get('content.controllerName')); |
| if (this.get('content.controllerName') != 'installerController') { |
| App.get('router.mainAdminKerberosController').getKDCSessionState(this.submitProceed.bind(this), function () { |
| self.set('isSubmitDisabled', false); |
| self.set('isBackBtnDisabled', false); |
| wizardController.setStepsEnable(); |
| if (self.get('content.controllerName') === 'addServiceController') { |
| wizardController.setSkipSlavesStep(wizardController.getDBProperty('selectedServiceNames'), 3); |
| } |
| }); |
| } else { |
| this.submitProceed(); |
| } |
| }, |
| |
| /** |
| * Prepare <code>ajaxQueue</code> and start to execute it |
| * @method submitProceed |
| */ |
| submitProceed: function () { |
| var self = this; |
| this.set('clusterDeleteRequestsCompleted', 0); |
| this.get('clusterDeleteErrorViews').clear(); |
| if (this.get('content.controllerName') == 'addHostController') { |
| App.router.get('addHostController').setLowerStepsDisable(4); |
| } |
| |
| // checkpoint the cluster status on the server so that the user can resume from where they left off |
| switch (this.get('content.controllerName')) { |
| case 'installerController': |
| App.clusterStatus.setClusterStatus({ |
| clusterName: this.get('clusterName'), |
| clusterState: 'CLUSTER_DEPLOY_PREP_2', |
| wizardControllerName: this.get('content.controllerName'), |
| localdb: App.db.data |
| }); |
| break; |
| case 'addHostController': |
| App.clusterStatus.setClusterStatus({ |
| clusterName: this.get('clusterName'), |
| clusterState: 'ADD_HOSTS_DEPLOY_PREP_2', |
| wizardControllerName: this.get('content.controllerName'), |
| localdb: App.db.data |
| }); |
| break; |
| case 'addServiceController': |
| App.clusterStatus.setClusterStatus({ |
| clusterName: this.get('clusterName'), |
| clusterState: 'ADD_SERVICES_DEPLOY_PREP_2', |
| wizardControllerName: this.get('content.controllerName'), |
| localdb: App.db.data |
| }); |
| break; |
| default: |
| break; |
| } |
| // delete any existing clusters to start from a clean slate |
| // before creating a new cluster in install wizard |
| // TODO: modify for multi-cluster support |
| this.getExistingClusterNames().complete(function () { |
| var clusterNames = self.get('clusterNames'); |
| if (self.get('content.controllerName') == 'installerController' && (!App.get('testMode')) && clusterNames.length) { |
| self.deleteClusters(clusterNames); |
| } else { |
| self.getExistingVersions(); |
| } |
| }); |
| }, |
| |
| /** |
| * Get list of existing cluster names |
| * @returns {object|null} |
| * returns an array of existing cluster names. |
| * returns an empty array if there are no existing clusters. |
| * @method getExistingClusterNames |
| */ |
| getExistingClusterNames: function () { |
| return App.ajax.send({ |
| name: 'wizard.step8.existing_cluster_names', |
| sender: this, |
| success: 'getExistingClusterNamesSuccessCallBack', |
| error: 'getExistingClusterNamesErrorCallback' |
| }); |
| }, |
| |
| /** |
| * Save received list to <code>clusterNames</code> |
| * @param {Object} data |
| * @method getExistingClusterNamesSuccessCallBack |
| */ |
| getExistingClusterNamesSuccessCallBack: function (data) { |
| var clusterNames = data.items.mapProperty('Clusters.cluster_name'); |
| this.set('clusterNames', clusterNames); |
| }, |
| |
| /** |
| * If error appears, set <code>clusterNames</code> to <code>[]</code> |
| * @method getExistingClusterNamesErrorCallback |
| */ |
| getExistingClusterNamesErrorCallback: function () { |
| this.set('clusterNames', []); |
| }, |
| |
| /** |
| * Delete cluster by name |
| * One request for one cluster! |
| * @param {string[]} clusterNames |
| * @method deleteClusters |
| */ |
| deleteClusters: function (clusterNames) { |
| this.get('clusterDeleteErrorViews').clear(); |
| clusterNames.forEach(function (clusterName, index) { |
| App.ajax.send({ |
| name: 'common.delete.cluster', |
| sender: this, |
| data: { |
| name: clusterName, |
| isLast: index == clusterNames.length - 1 |
| }, |
| success: 'deleteClusterSuccessCallback', |
| error: 'deleteClusterErrorCallback' |
| }); |
| }, this); |
| |
| }, |
| |
| /** |
| * Method to execute after successful cluster deletion |
| * @method deleteClusterSuccessCallback |
| */ |
| deleteClusterSuccessCallback: function () { |
| this.incrementProperty('clusterDeleteRequestsCompleted'); |
| if (this.get('isAllClusterDeleteRequestsCompleted')) { |
| if (this.get('clusterDeleteErrorViews.length')) { |
| this.showDeleteClustersErrorPopup(); |
| } else { |
| this.getExistingVersions(); |
| } |
| } |
| }, |
| |
| /** |
| * Method to execute after failed cluster deletion |
| * @param {object} request |
| * @param {string} ajaxOptions |
| * @param {string} error |
| * @param {object} opt |
| * @method deleteClusterErrorCallback |
| */ |
| deleteClusterErrorCallback: function (request, ajaxOptions, error, opt) { |
| this.incrementProperty('clusterDeleteRequestsCompleted'); |
| try { |
| var json = $.parseJSON(request.responseText); |
| var message = json.message; |
| } catch (err) { |
| } |
| this.get('clusterDeleteErrorViews').pushObject(App.AjaxDefaultErrorPopupBodyView.create({ |
| url: opt.url, |
| type: opt.type, |
| status: request.status, |
| message: message |
| })); |
| if (this.get('isAllClusterDeleteRequestsCompleted')) { |
| this.showDeleteClustersErrorPopup(); |
| } |
| }, |
| |
| /** |
| * Show error popup if cluster deletion failed |
| * @method showDeleteClustersErrorPopup |
| */ |
| showDeleteClustersErrorPopup: function () { |
| var self = this; |
| this.setProperties({ |
| isSubmitDisabled: false, |
| isBackBtnDisabled: false |
| }); |
| App.ModalPopup.show({ |
| header: Em.I18n.t('common.error'), |
| secondary: false, |
| onPrimary: function () { |
| this.hide(); |
| }, |
| bodyClass: Em.ContainerView.extend({ |
| childViews: self.get('clusterDeleteErrorViews') |
| }) |
| }); |
| }, |
| |
| /** |
| * Get existing repo_versions |
| * @method getExistingVersions |
| */ |
| getExistingVersions: function () { |
| return App.ajax.send({ |
| name: 'wizard.get_version_definitions', |
| sender: this, |
| success: 'getExistingVersionsSuccessCallback' |
| }); |
| }, |
| |
| /** |
| * @param {Object} data |
| * @method getExistingVersionsSuccessCallback |
| */ |
| getExistingVersionsSuccessCallback: function (data) { |
| if (this.get('content.controllerName') == 'installerController' && (!App.get('testMode')) && data.items.length) { |
| this.set('existingRepositoryVersions', data.items.length); |
| this.deleteExistingVersions(data.items); |
| } else { |
| this.startDeploy(); |
| } |
| }, |
| |
| /** |
| * Delete existing repo_versions |
| * @param {Array} versions |
| * @method deleteExistingVersions |
| */ |
| deleteExistingVersions: function (versions) { |
| versions.forEach(function (version) { |
| App.ajax.send({ |
| name: 'wizard.delete_repository_versions', |
| sender: this, |
| data: { |
| id: version.VersionDefinition.id, |
| stackName: version.VersionDefinition.stack_name, |
| stackVersion: version.VersionDefinition.stack_version |
| }, |
| success: 'deleteExistingVersionsSuccessCallback' |
| }); |
| }, this); |
| }, |
| |
| /** |
| * Method to execute after successful version deletion |
| * @method deleteExistingVersionsSuccessCallback |
| */ |
| deleteExistingVersionsSuccessCallback: function () { |
| this.decrementProperty('existingRepositoryVersions'); |
| if (this.get('existingRepositoryVersions') === 0) { |
| this.startDeploy(); |
| } |
| }, |
| |
| /** |
| * updates kerberosDescriptorConfigs |
| * @method updateKerberosDescriptor |
| */ |
| updateKerberosDescriptor: function(instant) { |
| var kerberosDescriptor = App.db.get('KerberosWizard', 'kerberosDescriptorConfigs'); |
| var descriptorExists = this.get('wizardController').getDBProperty('isClusterDescriptorExists') === true; |
| |
| var ajaxOpts = { |
| name: descriptorExists ? 'admin.kerberos.cluster.artifact.update' : 'admin.kerberos.cluster.artifact.create', |
| data: { |
| artifactName: 'kerberos_descriptor', |
| data: { |
| artifact_data: kerberosDescriptor |
| } |
| } |
| }; |
| if (instant) { |
| ajaxOpts.sender = this; |
| App.ajax.send(ajaxOpts); |
| } else { |
| this.addRequestToAjaxQueue(ajaxOpts); |
| } |
| }, |
| |
| /** |
| * To Start deploy process |
| * @method startDeploy |
| */ |
| startDeploy: function () { |
| if (this.get('content.controllerName') !== 'installerController') { |
| this._startDeploy(); |
| } else { |
| var installerController = App.router.get('installerController'); |
| var versionData = installerController.getSelectedRepoVersionData(); |
| if (versionData) { |
| var self = this; |
| installerController.postVersionDefinitionFileStep8(versionData.isXMLdata, versionData.data).done(function (versionInfo) { |
| if (versionInfo.id && versionInfo.stackName && versionInfo.stackVersion) { |
| var selectedStack = App.Stack.find().findProperty('isSelected', true); |
| if (selectedStack) { |
| selectedStack.set('versionInfoId', versionInfo.id); |
| } |
| installerController.updateRepoOSInfo(versionInfo, selectedStack).done(function() { |
| self._startDeploy(); |
| }); |
| } |
| }); |
| } else { |
| this._startDeploy(); |
| } |
| } |
| }, |
| |
| /** |
| * Start deploy process |
| * @method startDeploy |
| */ |
| _startDeploy: function () { |
| this.createCluster(); |
| this.createSelectedServices(); |
| if (this.get('content.controllerName') !== 'addHostController') { |
| if (this.get('content.controllerName') === 'addServiceController') { |
| // for manually enabled Kerberos descriptor was updated on transition to this step |
| if (App.get('isKerberosEnabled') && !this.get('isManualKerberos')) { |
| this.updateKerberosDescriptor(); |
| } |
| var fileNamesToUpdate = this.get('wizardController').getDBProperty('fileNamesToUpdate').uniq(); |
| if (fileNamesToUpdate && fileNamesToUpdate.length) { |
| this.applyConfigurationsToCluster(this.generateDesiredConfigsJSON(this.get('configs'), fileNamesToUpdate)); |
| } |
| } |
| this.createConfigurations(); |
| this.applyConfigurationsToCluster(this.get('serviceConfigTags')); |
| } |
| this.createComponents(); |
| this.registerHostsToCluster(); |
| this.createConfigurationGroups(); |
| this.createMasterHostComponents(); |
| this.createSlaveAndClientsHostComponents(); |
| if (this.get('content.controllerName') === 'addServiceController') { |
| this.createAdditionalClientComponents(); |
| } |
| this.createAdditionalHostComponents(); |
| |
| this.set('ajaxQueueLength', this.get('ajaxRequestsQueue.queue.length')); |
| this.get('ajaxRequestsQueue').start(); |
| this.showLoadingIndicator(); |
| }, |
| |
| /** |
| * ******************************************************************* |
| * The following create* functions are called upon submitting Step 8. |
| * ******************************************************************* |
| */ |
| |
| /** |
| * Create cluster using selected stack version |
| * Queued request |
| * @method createCluster |
| */ |
| createCluster: function () { |
| if (this.get('content.controllerName') !== 'installerController') return; |
| var stackVersion = (this.get('content.installOptions.localRepo')) ? App.currentStackVersion.replace(/(-\d+(\.\d)*)/ig, "Local$&") : App.currentStackVersion; |
| var selectedStack = App.Stack.find().findProperty('isSelected', true); |
| this.addRequestToAjaxQueue({ |
| name: 'wizard.step8.create_cluster', |
| data: { |
| data: JSON.stringify({ "Clusters": {"version": stackVersion, "repository_version": selectedStack.get('repositoryVersion')}}) |
| }, |
| success: 'createClusterSuccess' |
| }); |
| }, |
| |
| createClusterSuccess: function (data, xhr, params) { |
| App.set('clusterName', params.cluster); |
| }, |
| |
| /** |
| * Create selected to install services |
| * Queued request |
| * Skipped if no services where selected! |
| * @method createSelectedServices |
| */ |
| createSelectedServices: function () { |
| var data = this.createSelectedServicesData(); |
| if (!data.length) return; |
| this.addRequestToAjaxQueue({ |
| name: 'wizard.step8.create_selected_services', |
| data: { |
| data: JSON.stringify(data) |
| } |
| }); |
| }, |
| |
| /** |
| * Format data for <code>createSelectedServices</code> request |
| * @returns {Object[]} |
| * @method createSelectedServicesData |
| */ |
| createSelectedServicesData: function () { |
| var selectedStack; |
| if (this.get('isInstaller')) { |
| selectedStack = App.Stack.find().findProperty('isSelected', true); |
| } |
| return this.get('selectedServices').map(function(service) {return selectedStack ? |
| {"ServiceInfo": { "service_name": service.get('serviceName'), "desired_repository_version_id": selectedStack.get('versionInfoId') }} : |
| {"ServiceInfo": { "service_name": service.get('serviceName') }}}); |
| }, |
| |
| /** |
| * Create components for selected services |
| * Queued requests |
| * One request for each service! |
| * @method createComponents |
| */ |
| createComponents: function () { |
| var serviceComponents = App.StackServiceComponent.find(); |
| this.get('selectedServices').forEach(function (_service) { |
| var serviceName = _service.get('serviceName'); |
| var componentsData = serviceComponents.filterProperty('serviceName', serviceName).map(function (_component) { |
| return { "ServiceComponentInfo": { "component_name": _component.get('componentName') } }; |
| }); |
| |
| // Service must be specified in terms of a query for creating multiple components at the same time. |
| // See AMBARI-1018. |
| this.addRequestToCreateComponent(componentsData, serviceName); |
| }, this); |
| |
| if (this.get('content.controllerName') === 'addHostController') { |
| var allServiceComponents = []; |
| var services = App.Service.find().mapProperty('serviceName'); |
| services.forEach(function(_service){ |
| var _serviceComponents = App.Service.find(_service).get('serviceComponents'); |
| allServiceComponents = allServiceComponents.concat(_serviceComponents); |
| }, this); |
| this.get('content.slaveComponentHosts').forEach(function (component) { |
| if (component.componentName !== 'CLIENT' && !allServiceComponents.contains(component.componentName)) { |
| this.addRequestToCreateComponent( |
| [{"ServiceComponentInfo": {"component_name": component.componentName}}], |
| App.StackServiceComponent.find().findProperty('componentName', component.componentName).get('serviceName') |
| ); |
| } |
| }, this); |
| this.get('content.clients').forEach(function (component) { |
| if (!allServiceComponents.contains(component.component_name)) { |
| this.addRequestToCreateComponent( |
| [{"ServiceComponentInfo": {"component_name": component.component_name}}], |
| App.StackServiceComponent.find().findProperty('componentName', component.component_name).get('serviceName') |
| ); |
| } |
| }, this); |
| } |
| }, |
| |
| /** |
| * Add request to ajax queue to create service component |
| * @param componentsData |
| * @param serviceName |
| */ |
| addRequestToCreateComponent: function (componentsData, serviceName) { |
| this.addRequestToAjaxQueue({ |
| name: 'wizard.step8.create_components', |
| data: { |
| data: JSON.stringify({"components": componentsData}), |
| serviceName: serviceName |
| } |
| }); |
| }, |
| |
| /** |
| * Error callback for new service component request |
| * So, if component doesn't exist we should create it |
| * @param {object} request |
| * @param {object} ajaxOptions |
| * @param {string} error |
| * @param {object} opt |
| * @param {object} params |
| * @method newServiceComponentErrorCallback |
| */ |
| newServiceComponentErrorCallback: function (request, ajaxOptions, error, opt, params) { |
| this.addRequestToAjaxQueue({ |
| name: 'wizard.step8.create_components', |
| data: { |
| serviceName: params.serviceName, |
| data: JSON.stringify({ |
| "components": [ |
| { |
| "ServiceComponentInfo": { |
| "component_name": params.componentName |
| } |
| } |
| ] |
| }) |
| } |
| }); |
| }, |
| |
| /** |
| * Register hosts |
| * Queued request |
| * @method registerHostsToCluster |
| */ |
| registerHostsToCluster: function () { |
| var data = this.createRegisterHostData(); |
| if (!data.length) return; |
| this.addRequestToAjaxQueue({ |
| name: 'wizard.step8.register_host_to_cluster', |
| data: { |
| data: JSON.stringify(data) |
| } |
| }); |
| }, |
| |
| /** |
| * Format request-data for <code>registerHostsToCluster</code> |
| * @returns {Object} |
| * @method createRegisterHostData |
| */ |
| createRegisterHostData: function () { |
| return this.getRegisteredHosts().filterProperty('isInstalled', false).map(function (host) { |
| return {"Hosts": { "host_name": host.hostName}}; |
| }); |
| }, |
| |
| /** |
| * Register new master components |
| * @uses registerHostsToComponent |
| * @method createMasterHostComponents |
| */ |
| createMasterHostComponents: function () { |
| var masterOnAllHosts = []; |
| |
| this.get('content.services').filterProperty('isSelected').forEach(function (service) { |
| service.get('serviceComponents').filterProperty('isRequiredOnAllHosts').forEach(function (component) { |
| if (component.get('isMaster')) { |
| masterOnAllHosts.push(component.get('componentName')); |
| } |
| }, this); |
| }, this); |
| |
| // create master components for only selected services. |
| var selectedMasterComponents = this.get('content.masterComponentHosts').filter(function (_component) { |
| return this.get('selectedServices').mapProperty('serviceName').contains(_component.serviceId) |
| }, this); |
| selectedMasterComponents.mapProperty('component').uniq().forEach(function (component) { |
| if (masterOnAllHosts.length > 0) { |
| var compOnAllHosts = false; |
| for (var i=0; i < masterOnAllHosts.length; i++) { |
| if (component == masterOnAllHosts[i]) { |
| compOnAllHosts = true; |
| break; |
| } |
| } |
| if (!compOnAllHosts) { |
| var hostNames = selectedMasterComponents.filterProperty('component', component).filterProperty('isInstalled', false).mapProperty('hostName'); |
| this.registerHostsToComponent(hostNames, component); |
| } |
| } else { |
| var hostNames = selectedMasterComponents.filterProperty('component', component).filterProperty('isInstalled', false).mapProperty('hostName'); |
| this.registerHostsToComponent(hostNames, component); |
| } |
| }, this); |
| }, |
| |
| getClientsMap: function (flag) { |
| var clientNames = App.StackServiceComponent.find().filterProperty('isClient').mapProperty('componentName'), |
| clientsMap = {}, |
| dependedComponents = flag ? App.StackServiceComponent.find().filterProperty(flag) : App.StackServiceComponent.find(); |
| clientNames.forEach(function (clientName) { |
| clientsMap[clientName] = Em.A([]); |
| dependedComponents.forEach(function (component) { |
| if (component.get('dependencies').mapProperty('componentName').contains(clientName)) clientsMap[clientName].push(component.get('componentName')); |
| }); |
| if (!clientsMap[clientName].length) delete clientsMap[clientName]; |
| }); |
| return clientsMap; |
| }, |
| |
| /** |
| * Register slave components and clients |
| * @uses registerHostsToComponent |
| * @method createSlaveAndClientsHostComponents |
| */ |
| createSlaveAndClientsHostComponents: function () { |
| var masterHosts = this.get('content.masterComponentHosts'); |
| var slaveHosts = this.get('content.slaveComponentHosts'); |
| var clients = this.get('content.clients').filterProperty('isInstalled', false); |
| var slaveOnAllHosts = []; |
| var clientOnAllHosts = []; |
| |
| this.get('content.services').filterProperty('isSelected').forEach(function (service) { |
| service.get('serviceComponents').filterProperty('isRequiredOnAllHosts').forEach(function (component) { |
| if (component.get('isClient')) { |
| clientOnAllHosts.push(component.get('componentName')); |
| } else if (component.get('isSlave')) { |
| slaveOnAllHosts.push(component.get('componentName')); |
| } |
| }, this); |
| }, this); |
| |
| /** |
| * Determines on which hosts client should be installed (based on availability of master components on hosts) |
| * @type {Object} |
| * Format: |
| * <code> |
| * { |
| * CLIENT1: Em.A([MASTER1, MASTER2, ...]), |
| * CLIENT2: Em.A([MASTER3, MASTER1, ...]) |
| * ... |
| * } |
| * </code> |
| */ |
| var clientsToMasterMap = this.getClientsMap('isMaster'), |
| clientsToSlaveMap = this.getClientsMap('isSlave'); |
| |
| slaveHosts.forEach(function (_slave) { |
| if (_slave.componentName !== 'CLIENT') { |
| if (slaveOnAllHosts.length > 0) { |
| var compOnAllHosts = false; |
| for (var i=0; i < slaveOnAllHosts.length; i++) { |
| if (_slave.componentName == slaveOnAllHosts[i]) { |
| // component with ALL cardinality should not |
| // registerHostsToComponent in createSlaveAndClientsHostComponents |
| compOnAllHosts = true; |
| break; |
| } |
| } |
| if (!compOnAllHosts) { |
| var hostNames = _slave.hosts.filterProperty('isInstalled', false).mapProperty('hostName'); |
| this.registerHostsToComponent(hostNames, _slave.componentName); |
| } |
| } else { |
| var hostNames = _slave.hosts.filterProperty('isInstalled', false).mapProperty('hostName'); |
| this.registerHostsToComponent(hostNames, _slave.componentName); |
| } |
| } |
| else { |
| clients.forEach(function (_client) { |
| var hostNames = _slave.hosts.mapProperty('hostName'); |
| // The below logic to install clients to existing/New master hosts should not be applied to Add Host wizard. |
| // This is with the presumption that Add Host controller does not add any new Master component to the cluster |
| if (this.get('content.controllerName') !== 'addHostController') { |
| if (clientsToMasterMap[_client.component_name]) { |
| clientsToMasterMap[_client.component_name].forEach(function (componentName) { |
| masterHosts.filterProperty('component', componentName).forEach(function (_masterHost) { |
| hostNames.pushObject(_masterHost.hostName); |
| }); |
| }); |
| } |
| } |
| if (clientsToSlaveMap[_client.component_name]) { |
| clientsToSlaveMap[_client.component_name].forEach(function (componentName) { |
| slaveHosts.filterProperty('componentName', componentName).forEach(function (slaveHost) { |
| hostNames = hostNames.concat(slaveHost.hosts.mapProperty('hostName')).uniq(); |
| }); |
| }); |
| } |
| if (clientOnAllHosts.length > 0) { |
| var compOnAllHosts = false; |
| for (var i=0; i < clientOnAllHosts.length; i++) { |
| if (_client.component_name == clientOnAllHosts[i]) { |
| // component with ALL cardinality should not |
| // registerHostsToComponent in createSlaveAndClientsHostComponents |
| compOnAllHosts = true; |
| break; |
| } |
| } |
| if (!compOnAllHosts) { |
| hostNames = hostNames.uniq(); |
| this.registerHostsToComponent(hostNames, _client.component_name); |
| } |
| } else { |
| hostNames = hostNames.uniq(); |
| this.registerHostsToComponent(hostNames, _client.component_name); |
| } |
| }, this); |
| } |
| }, this); |
| }, |
| |
| /** |
| * This function is specific to addServiceController |
| * Newly introduced master components requires some existing client components to be hosted along with them |
| */ |
| createAdditionalClientComponents: function () { |
| var masterHosts = this.get('content.masterComponentHosts'); |
| var clientHosts = []; |
| if (this.get('content.slaveComponentHosts').someProperty('componentName', 'CLIENT')) { |
| clientHosts = this.get('content.slaveComponentHosts').findProperty('componentName', 'CLIENT').hosts; |
| } |
| var clients = this.get('content.clients').filterProperty('isInstalled', false); |
| var clientsToMasterMap = this.getClientsMap('isMaster'); |
| var clientsToClientMap = this.getClientsMap('isClient'); |
| var installedClients = []; |
| |
| // Get all the installed Client components |
| this.get('content.services').filterProperty('isInstalled').forEach(function (_service) { |
| var serviceClients = App.StackServiceComponent.find().filterProperty('serviceName', _service.get('serviceName')).filterProperty('isClient'); |
| serviceClients.forEach(function (client) { |
| installedClients.push(client.get('componentName')); |
| }, this); |
| }, this); |
| |
| // Check if there is a dependency for being co-hosted between existing client and selected new master |
| installedClients.forEach(function (_clientName) { |
| if (clientsToMasterMap[_clientName] || clientsToClientMap[_clientName]) { |
| var hostNames = []; |
| if (clientsToMasterMap[_clientName]) { |
| clientsToMasterMap[_clientName].forEach(function (componentName) { |
| masterHosts.filterProperty('component', componentName).filterProperty('isInstalled', false).forEach(function (_masterHost) { |
| hostNames.pushObject(_masterHost.hostName); |
| }, this); |
| }, this); |
| } |
| if (clientsToClientMap[_clientName]) { |
| clientsToClientMap[_clientName].forEach(function (componentName) { |
| clientHosts.forEach(function (_clientHost) { |
| var host = this.get('content.hosts')[_clientHost.hostName]; |
| var isClientSelected = clients.someProperty('component_name', componentName); |
| if (host.isInstalled && isClientSelected && !host.hostComponents.someProperty('HostRoles.component_name', componentName)) { |
| hostNames.pushObject(_clientHost.hostName); |
| } |
| }, this); |
| }, this); |
| } |
| hostNames = hostNames.uniq(); |
| if (hostNames.length > 0) { |
| // If a dependency for being co-hosted is derived between existing client and selected new master but that |
| // dependency is already satisfied in the cluster then disregard the derived dependency |
| this.removeClientsFromList(_clientName, hostNames); |
| this.registerHostsToComponent(hostNames, _clientName); |
| if(hostNames.length > 0) { |
| this.get('content.additionalClients').pushObject({hostNames: hostNames, componentName: _clientName}); |
| } |
| } |
| } |
| }, this); |
| }, |
| |
| /** |
| * |
| * @param clientName |
| * @param hostList |
| */ |
| removeClientsFromList: function (clientName, hostList) { |
| var clientHosts = []; |
| var installedHosts = this.get('content.hosts'); |
| for (var hostName in installedHosts) { |
| if (installedHosts[hostName].isInstalled) { |
| if (installedHosts[hostName].hostComponents.mapProperty('HostRoles.component_name').contains(clientName)) { |
| clientHosts.push(hostName); |
| } |
| } |
| } |
| |
| if (clientHosts.length > 0) { |
| clientHosts.forEach(function (hostName) { |
| if (hostList.contains(hostName)) { |
| hostList.splice(hostList.indexOf(hostName), 1); |
| } |
| }, this); |
| } |
| }, |
| |
| /** |
| * Register additional components |
| * Based on availability of some services |
| * @uses registerHostsToComponent |
| * @method createAdditionalHostComponents |
| */ |
| createAdditionalHostComponents: function () { |
| var masterHosts = this.get('content.masterComponentHosts'); |
| |
| // add all components with cardinality == ALL of selected services |
| var registeredHosts = this.getRegisteredHosts(); |
| var notInstalledHosts = registeredHosts.filterProperty('isInstalled', false); |
| this.get('content.services').filterProperty('isSelected').forEach(function (service) { |
| service.get('serviceComponents').filterProperty('isRequiredOnAllHosts').forEach(function (component) { |
| if (service.get('isInstalled') && notInstalledHosts.length) { |
| this.registerHostsToComponent(notInstalledHosts.mapProperty('hostName'), component.get('componentName')); |
| } else if (!service.get('isInstalled') && registeredHosts.length) { |
| this.registerHostsToComponent(registeredHosts.mapProperty('hostName'), component.get('componentName')); |
| } |
| }, this); |
| }, this); |
| |
| // add MySQL Server if Hive is selected |
| var hiveService = this.get('content.services').filterProperty('isSelected', true).filterProperty('isInstalled', false).findProperty('serviceName', 'HIVE'); |
| if (hiveService) { |
| var hiveDb = this.get('content.serviceConfigProperties').findProperty('name', 'hive_database'); |
| if (hiveDb.value == "New MySQL Database") { |
| this.registerHostsToComponent(masterHosts.filterProperty('component', 'HIVE_SERVER').mapProperty('hostName'), 'MYSQL_SERVER'); |
| } else if (hiveDb.value === "New PostgreSQL Database") { |
| this.registerHostsToComponent(masterHosts.filterProperty('component', 'HIVE_SERVER').mapProperty('hostName'), 'POSTGRESQL_SERVER'); |
| } |
| } |
| }, |
| |
| /** |
| * Register component to hosts |
| * Queued request |
| * @param {String[]} hostNames |
| * @param {String} componentName |
| * @method registerHostsToComponent |
| */ |
| registerHostsToComponent: function (hostNames, componentName) { |
| if (!hostNames.length) return; |
| |
| var queryStr = ''; |
| hostNames.forEach(function (hostName) { |
| queryStr += 'Hosts/host_name=' + hostName + '|'; |
| }); |
| //slice off last symbol '|' |
| queryStr = queryStr.slice(0, -1); |
| |
| var data = { |
| "RequestInfo": { |
| "query": queryStr |
| }, |
| "Body": { |
| "host_components": [ |
| { |
| "HostRoles": { |
| "component_name": componentName |
| } |
| } |
| ] |
| } |
| }; |
| |
| this.addRequestToAjaxQueue({ |
| name: 'wizard.step8.register_host_to_component', |
| data: { |
| data: JSON.stringify(data) |
| } |
| }); |
| }, |
| |
| /** |
| * Create config objects for cluster and services |
| * @method createConfigurations |
| */ |
| createConfigurations: function () { |
| var tag = this.getServiceConfigVersion(); |
| |
| if (this.get('isInstaller')) { |
| /** add cluster-env **/ |
| this.get('serviceConfigTags').pushObject(this.createDesiredConfig('cluster-env', tag, this.get('configs').filterProperty('filename', 'cluster-env.xml'))); |
| } |
| |
| this.get('selectedServices').forEach(function (service) { |
| Object.keys(service.get('configTypes')).forEach(function (type) { |
| if (!this.get('serviceConfigTags').someProperty('type', type)) { |
| var configs = this.get('configs').filterProperty('filename', App.config.getOriginalFileName(type)); |
| var serviceConfigNote = this.getServiceConfigNote(type, service.get('displayName')); |
| this.get('serviceConfigTags').pushObject(this.createDesiredConfig(type, tag, configs, serviceConfigNote)); |
| } |
| }, this); |
| }, this); |
| this.createNotification(); |
| }, |
| |
| /** |
| * Get config version tag |
| * |
| * @returns {string} |
| */ |
| getServiceConfigVersion: function() { |
| return 'version' + (this.get('isAddService') ? (new Date).getTime() : '1'); |
| }, |
| |
| /** |
| * Get config version message |
| * |
| * @param type |
| * @param serviceDisplayName |
| * @returns {*} |
| */ |
| getServiceConfigNote: function(type, serviceDisplayName) { |
| return (this.get('isAddService') && (type === 'core-site')) ? |
| Em.I18n.t('dashboard.configHistory.table.notes.addService') : Em.I18n.t('dashboard.configHistory.table.notes.default').format(serviceDisplayName); |
| }, |
| |
| /** |
| * Send <code>serviceConfigTags</code> to server |
| * Queued request |
| * One request for each service config tag |
| * @param serviceConfigTags |
| * @method applyConfigurationsToCluster |
| */ |
| applyConfigurationsToCluster: function (serviceConfigTags) { |
| var allServices = this.get('installedServices').concat(this.get('selectedServices')); |
| var allConfigData = []; |
| allServices.forEach(function (service) { |
| var serviceConfigData = []; |
| Object.keys(service.get('configTypesRendered')).forEach(function (type) { |
| var serviceConfigTag = serviceConfigTags.findProperty('type', type); |
| if (serviceConfigTag) { |
| serviceConfigData.pushObject(serviceConfigTag); |
| } |
| }, this); |
| if (serviceConfigData.length) { |
| allConfigData.pushObject(JSON.stringify({ |
| Clusters: { |
| desired_config: serviceConfigData.map(function(item) { |
| var props = {}; |
| Em.keys(item.properties).forEach(function(propName) { |
| if (item.properties[propName] !== null) { |
| props[propName] = item.properties[propName]; |
| } |
| }); |
| item.properties = props; |
| return item; |
| }) |
| } |
| })); |
| } |
| }, this); |
| var clusterConfig = serviceConfigTags.findProperty('type', 'cluster-env'); |
| if (clusterConfig) { |
| allConfigData.pushObject(JSON.stringify({ |
| Clusters: { |
| desired_config: [clusterConfig] |
| } |
| })); |
| } |
| |
| this.addRequestToAjaxQueue({ |
| name: 'common.across.services.configurations', |
| data: { |
| data: '[' + allConfigData.toString() + ']' |
| } |
| }); |
| }, |
| |
| /** |
| * Create and update config groups |
| * @method createConfigurationGroups |
| */ |
| createConfigurationGroups: function () { |
| var configGroups = this.get('content.configGroups').filterProperty('is_default', false); |
| var groupsToDelete = App.router.get(this.get('content.controllerName')).getDBProperty('groupsToDelete'); |
| if (groupsToDelete && groupsToDelete.length > 0) { |
| this.removeInstalledServicesConfigurationGroups(groupsToDelete); |
| } |
| configGroups.forEach(function (configGroup) { |
| if (configGroup.is_for_update || configGroup.is_temporary) { |
| this.saveGroup(configGroup.properties, configGroup, this.getServiceConfigNote('', configGroup.service_id)); |
| } |
| }, this); |
| App.ServiceConfigGroup.deleteTemporaryRecords(); |
| }, |
| |
| /** |
| * add request to create config group to queue |
| * |
| * @param data |
| * @method createConfigGroup |
| */ |
| createConfigGroup: function(data) { |
| this.addRequestToAjaxQueue({ |
| name: 'wizard.step8.apply_configuration_groups', |
| sender: this, |
| data: { |
| data: JSON.stringify(data) |
| } |
| }); |
| }, |
| |
| /** |
| * add request to update config group to queue |
| * |
| * @param data {Object} |
| * @method updateConfigGroup |
| */ |
| updateConfigGroup: function (data) { |
| this.addRequestToAjaxQueue({ |
| name: 'config_groups.update_config_group', |
| sender: this, |
| data: { |
| id: data.ConfigGroup.id, |
| configGroup: data |
| } |
| }); |
| }, |
| |
| /** |
| * Delete selected config groups |
| * @param {Object[]} groupsToDelete |
| * @method removeInstalledServicesConfigurationGroups |
| */ |
| removeInstalledServicesConfigurationGroups: function (groupsToDelete) { |
| var self = this; |
| groupsToDelete.forEach(function (item) { |
| self.deleteConfigurationGroup(Em.Object.create(item)); |
| }); |
| }, |
| |
| /** |
| * Selected and installed services |
| * @override |
| */ |
| currentServices: function() { |
| return this.get('installedServices').concat(this.get('selectedServices')); |
| }.property('installedServices.length', 'selectedServices.length'), |
| |
| /** |
| * Add handling GLUSTREFS properties |
| * @param property |
| * @returns {*} |
| * @override |
| */ |
| formatValueBeforeSave: function(property) { |
| if (this.formatGLUSTERFSProperties(Em.get(property, 'filename'))) { |
| switch (property.name) { |
| case "fs.default.name": |
| return this.get('configs').someProperty('name', 'fs_glusterfs_default_name') ? |
| this.get('configs').findProperty('name', 'fs_glusterfs_default_name').value : null; |
| case "fs.defaultFS": |
| return this.get('configs').someProperty('name', 'glusterfs_defaultFS_name') ? |
| this.get('configs').findProperty('name', 'glusterfs_defaultFS_name').value : null; |
| } |
| } |
| return this._super(property); |
| }, |
| |
| /** |
| * Defines if some GLUSTERFS properties should be changed |
| * |
| * @param {String} type |
| * @returns {boolean} |
| */ |
| formatGLUSTERFSProperties: function(type) { |
| return App.config.getConfigTagFromFileName(type) === 'core-site' |
| && this.get('installedServices').concat(this.get('selectedServices')).someProperty('serviceName', 'GLUSTERFS'); |
| }, |
| |
| |
| /** |
| * Create one Alert Notification (if user select this on step7) |
| * Only for Install Wizard and stack |
| * @method createNotification |
| */ |
| createNotification: function () { |
| if (this.get('content.controllerName') !== 'installerController') return; |
| var miscConfigs = this.get('configs').filterProperty('serviceName', 'MISC'), |
| createNotification = miscConfigs.findProperty('name', 'create_notification').value; |
| if (createNotification !== 'yes') return; |
| var predefinedNotificationConfigNames = require('data/HDP2/alert_notification').mapProperty('name'), |
| configsForNotification = this.get('configs').filterProperty('filename', 'alert_notification'); |
| var properties = {}, |
| names = [ |
| 'ambari.dispatch.recipients', |
| 'mail.smtp.host', |
| 'mail.smtp.port', |
| 'mail.smtp.from', |
| 'mail.smtp.starttls.enable', |
| 'mail.smtp.startssl.enable' |
| ]; |
| if (miscConfigs.findProperty('name', 'smtp_use_auth').value == 'true') { // yes, it's not converted to boolean |
| names.pushObjects(['ambari.dispatch.credential.username', 'ambari.dispatch.credential.password']); |
| } |
| |
| names.forEach(function (name) { |
| properties[name] = miscConfigs.findProperty('name', name).value; |
| }); |
| |
| properties['ambari.dispatch.recipients'] = properties['ambari.dispatch.recipients'].replace(/\s/g, '').split(','); |
| |
| configsForNotification.forEach(function (config) { |
| if (predefinedNotificationConfigNames.contains(config.name)) return; |
| properties[config.name] = config.value; |
| }); |
| |
| var apiObject = { |
| AlertTarget: { |
| name: 'Initial Notification', |
| description: 'Notification created during cluster installing', |
| global: true, |
| notification_type: 'EMAIL', |
| alert_states: ['OK', 'WARNING', 'CRITICAL', 'UNKNOWN'], |
| properties: properties |
| } |
| }; |
| this.addRequestToAjaxQueue({ |
| name: 'alerts.create_alert_notification', |
| data: { |
| urlParams: 'overwrite_existing=true', |
| data: apiObject |
| } |
| }); |
| }, |
| |
| /** |
| * Should ajax-queue progress bar be displayed |
| * @method showLoadingIndicator |
| */ |
| showLoadingIndicator: function () { |
| return App.ModalPopup.show({ |
| |
| header: '', |
| |
| showFooter: false, |
| |
| showCloseButton: false, |
| |
| bodyClass: Em.View.extend({ |
| |
| templateName: require('templates/wizard/step8/step8_log_popup'), |
| |
| controllerBinding: 'App.router.wizardStep8Controller', |
| |
| /** |
| * Css-property for progress-bar |
| * @type {string} |
| */ |
| barWidth: '', |
| progressBarClass: 'progress log_popup', |
| |
| /** |
| * Popup-message |
| * @type {string} |
| */ |
| message: '', |
| |
| /** |
| * Set progress bar width and popup message when ajax-queue requests are proccessed |
| * @method ajaxQueueChangeObs |
| */ |
| ajaxQueueChangeObs: function () { |
| var length = this.get('controller.ajaxQueueLength'); |
| var left = this.get('controller.ajaxRequestsQueue.queue.length'); |
| this.set('barWidth', 'width: ' + ((length - left) / length * 100) + '%;'); |
| this.set('message', Em.I18n.t('installer.step8.deployPopup.message').format((length - left), length)); |
| }.observes('controller.ajaxQueueLength', 'controller.ajaxRequestsQueue.queue.length'), |
| |
| /** |
| * Hide popup when ajax-queue is finished |
| * @method autoHide |
| */ |
| autoHide: function () { |
| if (this.get('controller.servicesInstalled')) { |
| this.get('parentView').hide(); |
| } |
| }.observes('controller.servicesInstalled') |
| }) |
| |
| }); |
| }, |
| |
| downloadCSV: function() { |
| App.router.get('kerberosWizardStep5Controller').getCSVData(false); |
| } |
| }); |