ambari-web/app/controllers/installer.js (948 lines of code) (raw):

/** * 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.InstallerController = App.WizardController.extend(App.Persist, { name: 'installerController', isCheckInProgress: false, totalSteps: 11, isInstallerWizard: true, content: Em.Object.create({ cluster: null, installOptions: null, hosts: null, services: null, slaveComponentHosts: null, masterComponentHosts: null, serviceConfigProperties: null, advancedServiceConfig: null, configGroups: [], slaveGroupProperties: null, stacks: null, clients: [], // list of components, that was added from configs page via AssignMasterOnStep7Controller componentsFromConfigs: [], /** * recommendations for host groups loaded from server */ recommendations: null, /** * recommendationsHostGroups - current component assignment after 5 and 6 steps, * or adding hiveserver2 interactive on "configure services" page * (uses for host groups validation and to load recommended configs) */ recommendationsHostGroups: null, controllerName: 'installerController' }), /** * Wizard properties in local storage, which should be cleaned right after wizard has been finished */ dbPropertiesToClean: [ 'service', 'hosts', 'masterComponentHosts', 'slaveComponentHosts', 'cluster', 'allHostNames', 'installOptions', 'allHostNamesPattern', 'serviceComponents', 'clientInfo', 'selectedServiceNames', 'serviceConfigGroups', 'serviceConfigProperties', 'fileNamesToUpdate', 'bootStatus', 'stacksVersions', 'currentStep', 'serviceInfo', 'hostInfo', 'recommendations', 'recommendationsHostGroups', 'recommendationsConfigs', 'componentsFromConfigs', 'operatingSystems', 'repositories' ], init: function () { this._super(); this.get('isStepDisabled').setEach('value', true); this.get('isStepDisabled').pushObject(Ember.Object.create({ step: 0, value: true })); }, /** * redefined connectOutlet method to avoid view loading by unauthorized user * @param view * @param content */ connectOutlet: function (view, content) { if (App.db.getAuthenticated()) { this._super(view, content); } }, getCluster: function () { return jQuery.extend({}, this.get('clusterStatusTemplate')); }, getHosts: function () { return []; }, /** * 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) { var dbHosts = this.getDBProperty('hosts'); hosts.forEach(function (_hostInfo) { var host = _hostInfo.name; delete dbHosts[host]; }); this.setDBProperty('hosts', dbHosts); }, cancelInstall: function() { return App.showConfirmationPopup(() => { App.router.get('applicationController').goToAdminView(); }); }, /** * Load services data. Will be used at <code>Select services(step4)</code> step */ loadServices: function () { var dfd = $.Deferred(); var self = this; var stackServices = App.StackService.find().mapProperty('serviceName'); if (!(stackServices.length && App.StackService.find().objectAt(0).get('stackVersion') === App.get('currentStackVersionNumber'))) { this.loadServiceComponents().then(function () { self.set('content.services', App.StackService.find().forEach(function (item) { // user the service version from VersionDefinition var serviceInStack = App.Stack.find().findProperty('isSelected').get('stackServices').findProperty('name', item.get('serviceName')); var serviceVersionDisplay = serviceInStack ? serviceInStack.get('latestVersion') : item.get('serviceVersion'); item.set('serviceVersionDisplay', serviceVersionDisplay); })); dfd.resolve(); }); } else { dfd.resolve(); } return dfd.promise(); }, /** * total set of hosts registered to cluster, analog of App.Host model, * used in Installer wizard until hosts are installed */ allHosts: function () { var rawHosts = this.get('content.hosts'); var masterComponents = this.get('content.masterComponentHosts'); var slaveComponents = this.get('content.slaveComponentHosts'); var hosts = []; masterComponents.forEach(function (component) { var host = rawHosts[component.hostName]; if (host.hostComponents) { host.hostComponents.push(Em.Object.create({ componentName: component.component, displayName: component.display_name })); } else { rawHosts[component.hostName].hostComponents = [ Em.Object.create({ componentName: component.component, displayName: component.display_name }) ] } }); slaveComponents.forEach(function (component) { component.hosts.forEach(function (rawHost) { var host = rawHosts[rawHost.hostName]; if (host.hostComponents) { host.hostComponents.push(Em.Object.create({ componentName: component.componentName, displayName: component.displayName })); } else { rawHosts[rawHost.hostName].hostComponents = [ Em.Object.create({ componentName: component.componentName, displayName: component.displayName }) ] } }); }); for (var hostName in rawHosts) { var host = rawHosts[hostName]; hosts.pushObject(Em.Object.create({ id: host.name, hostName: host.name, hostComponents: host.hostComponents || [] } )) } return hosts; }.property('content.hosts'), stacks: [], /** * stack names used as auxiliary data to query stacks by name */ stackNames: [], /** * Load stacks data from server or take exist data from in memory variable {{content.stacks}} * The series of API calls will be called When landing first time on Select Stacks page * or on hitting refresh post select stacks page in installer wizard */ loadStacks: function () { var stacks = this.get('content.stacks'); var dfd = $.Deferred(); if (stacks && stacks.get('length')) { App.set('currentStackVersion', App.Stack.find().findProperty('isSelected').get('stackNameVersion')); dfd.resolve(true); } else { App.ajax.send({ name: 'wizard.stacks', sender: this, success: 'loadStacksSuccessCallback', error: 'loadStacksErrorCallback' }).then(function () { dfd.resolve(false); }); } return dfd.promise(); }, /** * Send queries to load versions for each stack */ loadStacksSuccessCallback: function (data) { this.get('stacks').clear(); this.set('stackNames', data.items.mapProperty('Stacks.stack_name')); }, /** * onError callback for loading stacks data */ loadStacksErrorCallback: function () { }, /** * query every stack names from server * @return {Array} */ loadStacksVersions: function () { var requests = []; const dfd = $.Deferred(); this.get('stackNames').forEach(function (stackName) { requests.push(App.ajax.send({ name: 'wizard.stacks_versions_definitions', sender: this, data: { stackName: stackName, dfd: dfd }, success: 'loadStacksVersionsDefinitionsSuccessCallback', error: 'loadStacksVersionsErrorCallback' })); }, this); this.set('loadStacksRequestsCounter', requests.length); return dfd.promise(); }, /** * Counter for counting number of successful requests to load stack versions */ loadStacksRequestsCounter: 0, /** * Parse loaded data and create array of stacks objects */ loadStacksVersionsDefinitionsSuccessCallback: function (data, opt, params) { var stacks = App.db.getStacks(); var oses = App.db.getOses(); var repos = App.db.getRepos(); this.decrementProperty('loadStacksRequestsCounter'); var isStacksExistInDb = stacks && stacks.length; if (isStacksExistInDb) { stacks.forEach(function (_stack) { var stack = data.items.findProperty('VersionDefinition.id', _stack.id); if (stack) { stack.VersionDefinition.is_selected = _stack.is_selected; } }, this); } if (!data.items || !data.items.length) { this.setSelected(true, params.dfd); } // if data.items is empty, we show error modal end return to back step if (data.items && data.items.length) { data.items.sortProperty('VersionDefinition.stack_version').reverse().forEach(function (versionDefinition) { // to display repos panel, should map all available operating systems including empty ones var stackInfo = {}; stackInfo.isStacksExistInDb = isStacksExistInDb; stackInfo.stacks = stacks; stackInfo.oses = oses; stackInfo.repos = repos; this.getSupportedOSList(versionDefinition, stackInfo, params.dfd); }, this); } else { App.showAlertPopup(Em.I18n.t('common.error'), Em.I18n.t('installer.step1.noVersionDefinitions'), function() { App.router.send('back'); }); } }, mergeChanges: function (repos, oses, stacks) { var _repos = repos || []; var _oses = oses || []; var _stacks = stacks || []; _repos.forEach(function (repo) { if (App.Repository.find(repo.id).get('isLoaded')) { App.Repository.find(repo.id).set('baseUrl', repo.base_url); } }); _oses.forEach(function (os) { if (App.OperatingSystem.find().findProperty('id', os.id)) { App.OperatingSystem.find().findProperty('id', os.id).set('isSelected', os.is_selected); } }); //should delete the record on going to step 2, on going back to step 1, still need the record if (App.router.get('currentState.name') != "step1") { App.OperatingSystem.find().filterProperty('isSelected', false).forEach(function (os) { App.stackMapper.deleteRecord(os); }); } _stacks.forEach(function (_stack) { var stack = App.Stack.find().findProperty('id', _stack.id); if (stack) { stack.set('useRedhatSatellite', _stack.use_redhat_satellite); } }); }, setSelected: function (isStacksExistInDb, dfd) { if (!isStacksExistInDb) { var stacks = App.Stack.find(); stacks.setEach('isSelected', false); stacks.sortProperty('id').set('lastObject.isSelected', true); } this.set('content.stacks', App.Stack.find()); var selected = App.Stack.find().findProperty('isSelected'); App.set('currentStackVersion', selected ? selected.get('stackNameVersion') : null); dfd.resolve(); }, /** * Get the the repo version (to install) info, this data will be POST * @method startDeploy */ getSelectedRepoVersionData: function () { var vdfData = App.db.getLocalRepoVDFData(); var selectedStack = App.Stack.find().findProperty('isSelected', true); var isXMLdata = false; var data = {}; if (selectedStack && selectedStack.get('showAvailable')) { //meaning user selected a public repo data = { "VersionDefinition": { "available": selectedStack.get('id') } }; isXMLdata = false; } else if (vdfData && validator.isValidURL(vdfData)) { // meaning user uploaded a VDF via entering URL data = { "VersionDefinition": { "version_url": vdfData } }; isXMLdata = false; } else if (vdfData) { // meaning user uploaded a local VDF.xml file isXMLdata = true; data = vdfData; } else { return null; } return { isXMLdata: isXMLdata, data: data }; }, /** * onError callback for loading stacks data */ loadStacksVersionsErrorCallback: function () { }, /** * check server version and web client version */ checkServerClientVersion: function () { var dfd = $.Deferred(); var self = this; self.getServerVersion().done(function () { dfd.resolve(); }); return dfd.promise(); }, getServerVersion: function () { return App.ajax.send({ name: 'ambari.service', sender: this, data: { fields: '?fields=RootServiceComponents/component_version,RootServiceComponents/properties/server.os_family&minimal_response=true' }, success: 'getServerVersionSuccessCallback', error: 'getServerVersionErrorCallback' }); }, getServerVersionSuccessCallback: function (data) { var clientVersion = App.get('version'); var serverVersion = data.RootServiceComponents.component_version.toString(); this.set('ambariServerVersion', serverVersion); if (clientVersion) { this.set('versionConflictAlertBody', Em.I18n.t('app.versionMismatchAlert.body').format(serverVersion, clientVersion)); this.set('isServerClientVersionMismatch', clientVersion !== serverVersion); } else { this.set('isServerClientVersionMismatch', false); } App.set('isManagedMySQLForHiveEnabled', App.config.isManagedMySQLForHiveAllowed(data.RootServiceComponents.properties['server.os_family'])); }, getServerVersionErrorCallback: function () { }, /** * set stacks from server to content and local DB */ setStacks: function () { App.db.setStacks(App.Stack.find().slice()); this.set('content.stacks', App.Stack.find()); App.db.setOses(App.OperatingSystem.find().slice()); App.db.setRepos(App.Repository.find().slice()); }, /** * Save data to model * @param stepController App.WizardStep4Controller */ saveServices: function (stepController) { var selectedServiceNames = []; var installedServiceNames = []; stepController.filterProperty('isSelected').forEach(function (item) { selectedServiceNames.push(item.get('serviceName')); }); stepController.filterProperty('isInstalled').forEach(function (item) { installedServiceNames.push(item.get('serviceName')); }); this.set('content.services', App.StackService.find()); this.set('content.selectedServiceNames', selectedServiceNames); this.set('content.installedServiceNames', installedServiceNames); this.setDBProperties({ selectedServiceNames: selectedServiceNames, installedServiceNames: installedServiceNames }); }, /** * Save Master Component Hosts data to Main Controller * @param stepController App.WizardStep5Controller * @param skip {Boolean} */ saveMasterComponentHosts: function (stepController, skip) { var obj = stepController.get('selectedServicesMasters'), hosts = this.getDBProperty('hosts'); var masterComponentHosts = []; obj.forEach(function (_component) { masterComponentHosts.push({ display_name: _component.get('display_name'), component: _component.get('component_name'), serviceId: _component.get('serviceId'), isInstalled: false, host_id: hosts[_component.get('selectedHost')].id }); }); this.set('content.masterComponentHosts', masterComponentHosts); if (!skip) { this.setDBProperty('masterComponentHosts', masterComponentHosts); } }, /** * Load master component hosts data for using in required step controllers * @param inMemory {Boolean}: Load master component hosts from memory */ loadMasterComponentHosts: function (inMemory) { var props = this.getDBProperties(['masterComponentHosts', 'hosts']); var masterComponentHosts = !!inMemory ? this.get("content.masterComponentHosts") : props.masterComponentHosts, hosts = props.hosts || {}, hostNames = Em.keys(hosts); if (Em.isNone(masterComponentHosts)) { masterComponentHosts = []; } else { masterComponentHosts.forEach(function (component) { for (var i = 0; i < hostNames.length; i++) { if (hosts[hostNames[i]].id === component.host_id) { component.hostName = hostNames[i]; break; } } }); } this.set("content.masterComponentHosts", masterComponentHosts); }, loadCurrentHostGroups: function () { this.set("content.recommendationsHostGroups", this.getDBProperty('recommendationsHostGroups')); }, loadRecommendationsConfigs: function () { App.router.set("wizardStep7Controller.recommendationsConfigs", this.getDBProperty('recommendationsConfigs')); }, /** * Load master component hosts data for using in required step controllers */ loadSlaveComponentHosts: function () { var props = this.getDBProperties(['slaveComponentHosts', 'hosts']); var slaveComponentHosts = props.slaveComponentHosts, hosts = props.hosts || {}, hostNames = Em.keys(hosts); if (!Em.isNone(slaveComponentHosts)) { slaveComponentHosts.forEach(function (component) { component.hosts.forEach(function (host) { for (var i = 0; i < hostNames.length; i++) { if (hosts[hostNames[i]].id === host.host_id) { host.hostName = hostNames[i]; break; } } }); }); } this.set("content.slaveComponentHosts", slaveComponentHosts); }, /** * Generate clients list for selected services and save it to model * @param stepController step4WizardController */ saveClients: function (stepController) { var clients = []; stepController.get('content').filterProperty('isSelected', true).forEach(function (_service) { var client = _service.get('serviceComponents').filterProperty('isClient', true); client.forEach(function (clientComponent) { clients.pushObject({ component_name: clientComponent.get('componentName'), display_name: clientComponent.get('displayName'), isInstalled: false }); }, this); }, this); this.setDBProperty('clientInfo', clients); this.set('content.clients', clients); }, /* * Post version definition file (.xml) to server, DRY_RUN = TRUE */ postVersionDefinitionFile: function (isXMLdata, data) { var dfd = $.Deferred(); var name = isXMLdata? 'wizard.step1.post_version_definition_file.xml' : 'wizard.step1.post_version_definition_file.url'; App.ajax.send({ name: name, sender: this, data: { dfd: dfd, data: data }, success: 'postVersionDefinitionFileSuccessCallback', error: 'postVersionDefinitionFileErrorCallback' }); return dfd.promise(); }, /** * onSuccess callback for postVersionDefinitionFile. */ postVersionDefinitionFileSuccessCallback: function (_data, request, dataInfo) { if (_data.resources.length && _data.resources[0].VersionDefinition) { var data = _data.resources[0]; // load the data info to display for details and contents panel data.VersionDefinition.id = Em.get(dataInfo, 'data.VersionDefinition.available') || data.VersionDefinition.id; var response = { id : data.VersionDefinition.id, stackVersion : data.VersionDefinition.stack_version, stackName: data.VersionDefinition.stack_name, type: data.VersionDefinition.type, stackNameVersion: data.VersionDefinition.stack_name + '-' + data.VersionDefinition.stack_version, /// HDP-2.3 actualVersion: data.VersionDefinition.repository_version, /// 2.3.4.0-3846 version: data.VersionDefinition.release ? data.VersionDefinition.release.version: null, /// 2.3.4.0 releaseNotes: data.VersionDefinition.release ? data.VersionDefinition.release.notes: null, displayName: data.VersionDefinition.release ? data.VersionDefinition.stack_name + '-' + data.VersionDefinition.release.version : data.VersionDefinition.stack_name + '-' + data.VersionDefinition.repository_version, //HDP-2.3.4.0 repoVersionFullName : data.VersionDefinition.stack_name + '-' + data.VersionDefinition.repository_version, osList: data.operating_systems, updateObj: data }; var services = []; data.VersionDefinition.services.forEach(function (service) { services.push({ name: service.name, version: service.versions[0].version, components: service.versions[0].components }); }); response.services = services; // to display repos panel, should map all available operating systems including empty ones var stackInfo = {}; stackInfo.dfd = dataInfo.dfd; stackInfo.response = response; this.incrementProperty('loadStacksRequestsCounter'); this.getSupportedOSListSuccessCallback(data, null, { stackName: data.VersionDefinition.stack_name, stackVersion: data.VersionDefinition.stack_version, versionDefinition: data, stackInfo: stackInfo }); } }, /* * Post version definition file (.xml) to server in step 8 */ postVersionDefinitionFileStep8: function (isXMLdata, data) { var dfd = $.Deferred(); var name = isXMLdata == true? 'wizard.step8.post_version_definition_file.xml' : 'wizard.step8.post_version_definition_file'; App.ajax.send({ name: name, sender: this, data: { dfd: dfd, data: data }, success: 'postVersionDefinitionFileStep8SuccessCallback', error: 'postVersionDefinitionFileErrorCallback' }); return dfd.promise(); }, /** * onSuccess callback for postVersionDefinitionFile. */ postVersionDefinitionFileStep8SuccessCallback: function (response, request, data) { if (response.resources.length && response.resources[0].VersionDefinition) { data.dfd.resolve( { stackName: response.resources[0].VersionDefinition.stack_name, id: response.resources[0].VersionDefinition.id, stackVersion: response.resources[0].VersionDefinition.stack_version }); } }, /** * onError callback for postVersionDefinitionFile. */ postVersionDefinitionFileErrorCallback: function (request, ajaxOptions, error, data, params) { params.dfd.reject(data); var header = Em.I18n.t('installer.step1.useLocalRepo.uploadFile.error.title'); var body = ''; if(request && request.responseText) { try { var json = JSON.parse(request.responseText); body = json.message; } catch (err) {} } App.db.setLocalRepoVDFData(undefined); App.showAlertPopup(header, body); }, getSupportedOSList: function (versionDefinition, stackInfo, dfd) { this.incrementProperty('loadStacksRequestsCounter'); return App.ajax.send({ name: 'wizard.step1.get_supported_os_types', sender: this, data: { stackName: versionDefinition.VersionDefinition.stack_name, stackVersion: versionDefinition.VersionDefinition.stack_version, versionDefinition: versionDefinition, stackInfo: stackInfo, dfd: dfd }, success: 'getSupportedOSListSuccessCallback', error: 'getSupportedOSListErrorCallback' }); }, showStackErrorAndSkipStepIfNeeded: function (response) { var stackName = response.Versions.stack_name; var stackVersion = response.Versions.stack_version; var header = Em.I18n.t('installer.step1.useLocalRepo.getSurpottedOs.stackError.title').format(stackName, stackVersion); var body = response.Versions['stack-errors'].join('. '); this.decrementProperty('loadStacksRequestsCounter'); App.showAlertPopup(header, body); if (this.get('loadStacksRequestsCounter') === 0 && !App.Stack.find().toArray().length) { var wizardStep0Controller = App.router.get('wizardStep0Controller'); wizardStep0Controller.set('hasNotStacksAvailable', true); App.router.send('gotoStep' + 0); var installationErrorHeader = Em.I18n.t('installer.step1.useLocalRepo.getSurpottedOs.noStacksError.title'); var installationErrorBody = Em.I18n.t('installer.step1.useLocalRepo.getSurpottedOs.noStacksError.body'); App.showAlertPopup(installationErrorHeader, installationErrorBody); } }, /** * onSuccess callback for getSupportedOSList. */ getSupportedOSListSuccessCallback: function (response, request, data) { var self = this; var stack_default = data.versionDefinition.VersionDefinition.stack_default; var existedOS = data.versionDefinition.operating_systems; var existedMap = {}; existedOS.map(function (existedOS) { existedOS.isSelected = true; existedMap[existedOS.OperatingSystems.os_type] = existedOS; }); if (response.Versions && response.Versions['stack-errors'] && response.Versions['stack-errors'].length) { this.showStackErrorAndSkipStepIfNeeded(response); return; } response.operating_systems.forEach(function(supportedOS) { if(!existedMap[supportedOS.OperatingSystems.os_type]) { supportedOS.isSelected = false; existedOS.push(supportedOS); } else { if (stack_default) { // only overwrite if it is stack default, otherwise use url from /version_definition existedMap[supportedOS.OperatingSystems.os_type].repositories.forEach(function (repo) { supportedOS.repositories.forEach(function (supportedRepo) { if (supportedRepo.Repositories.repo_id == repo.Repositories.repo_id) { repo.Repositories.base_url = supportedRepo.Repositories.base_url; repo.Repositories.default_base_url = supportedRepo.Repositories.default_base_url; repo.Repositories.latest_base_url = supportedRepo.Repositories.latest_base_url; repo.Repositories.components = supportedRepo.Repositories.components; repo.Repositories.distribution = supportedRepo.Repositories.distribution; } }); }); } else{ existedMap[supportedOS.OperatingSystems.os_type].repositories.forEach(function (repo) { supportedOS.repositories.forEach(function (supportedRepo) { if (supportedRepo.Repositories.repo_id == repo.Repositories.repo_id) { repo.Repositories.components = supportedRepo.Repositories.components; repo.Repositories.distribution = supportedRepo.Repositories.distribution; } }); }); } } }); App.stackMapper.map(data.versionDefinition); if (!this.decrementProperty('loadStacksRequestsCounter')) { if (data.stackInfo.dfd) { data.stackInfo.dfd.resolve(data.stackInfo.response); } else { var versionData = this.getSelectedRepoVersionData(); if (versionData) { this.postVersionDefinitionFile(versionData.isXMLdata, versionData.data).done(function (versionInfo) { self.mergeChanges(data.stackInfo.repos, data.stackInfo.oses, data.stackInfo.stacks); App.Stack.find().setEach('isSelected', false); var stackId = Em.get(versionData, 'data.VersionDefinition.available') || versionInfo.stackNameVersion + "-" + versionInfo.actualVersion; App.Stack.find().findProperty('id', stackId).set('isSelected', true); self.setSelected(data.stackInfo.isStacksExistInDb, data.dfd); }).fail(function () { self.setSelected(data.stackInfo.isStacksExistInDb, data.dfd); }); } else { this.setSelected(data.stackInfo.isStacksExistInDb, data.dfd); } } } }, /** * onError callback for getSupportedOSList */ getSupportedOSListErrorCallback: function (request, ajaxOptions, error, data, params) { var header = Em.I18n.t('installer.step1.useLocalRepo.getSurpottedOs.error.title'); var body = ""; if(request && request.responseText){ try { var json = JSON.parse(request.responseText); body = json.message; } catch (err) {} } App.showAlertPopup(header, body); }, updateRepoOSInfo: function (repoToUpdate, repo) { var deferred = $.Deferred(); var repoVersion = this.prepareRepoForSaving(repo); App.ajax.send({ name: 'admin.stack_versions.edit.repo', sender: this, data: { stackName: repoToUpdate.stackName, stackVersion: repoToUpdate.stackVersion, repoVersionId: repoToUpdate.id, repoVersion: repoVersion } }).success(function() { deferred.resolve([]); }).error(function() { deferred.resolve([]); }); return deferred.promise(); }, /** * transform repo data into json for * saving changes to repository version * @param {Em.Object} repo * @returns {{operating_systems: Array}} */ prepareRepoForSaving: function(repo) { var repoVersion = { "operating_systems": [] }; var ambariManagedRepositories = !repo.get('useRedhatSatellite'); var k = 0; repo.get('operatingSystems').forEach(function (os) { if (os.get('isSelected')) { repoVersion.operating_systems.push({ "OperatingSystems": { "os_type": os.get("osType"), "ambari_managed_repositories": ambariManagedRepositories }, "repositories": [] }); os.get('repositories').forEach(function (repository) { if (!(repository.get('isGPL') && _.isEmpty(repository.get('baseUrl')))) { repoVersion.operating_systems[k].repositories.push({ "Repositories": { "base_url": repository.get('baseUrl'), "repo_id": repository.get('repoId'), "repo_name": repository.get('repoName'), "components": repository.get('components'), "tags": repository.get('tags'), "distribution": repository.get('distribution'), "applicable_services" : repository.get('applicable_services') } }); } }); k++; } }); return repoVersion; }, /** * Check validation of the customized local urls */ checkRepoURL: function (wizardStep1Controller) { var selectedStack = this.get('content.stacks').findProperty('isSelected', true); selectedStack.set('reload', true); var nameVersionCombo = selectedStack.get('stackNameVersion'); var stackName = nameVersionCombo.split('-')[0]; var stackVersion = nameVersionCombo.split('-')[1]; var dfd = $.Deferred(); if (selectedStack && selectedStack.get('operatingSystems')) { this.set('validationCnt', selectedStack.get('operatingSystems').filterProperty('isSelected').filterProperty('isEmpty', false).map(function (os) { return os.get('repositories').filterProperty('showRepo', true).length; }).reduce(Em.sum, 0)); var verifyBaseUrl = !wizardStep1Controller.get('skipValidationChecked') && !wizardStep1Controller.get('selectedStack.useRedhatSatellite'); if (!verifyBaseUrl) { dfd.resolve(); } //for redhat satellite/spacewalk the os urls will be empty var useRedhatSatellite = wizardStep1Controller.get('selectedStack.useRedhatSatellite'); selectedStack.get('operatingSystems').forEach(function (os) { if (os.get('isSelected') && (useRedhatSatellite || !os.get('isEmpty'))) { os.get('repositories').forEach(function (repo) { if (repo.get('showRepo')) { repo.setProperties({ errorTitle: '', errorContent: '', validation: 'INPROGRESS' }); this.set('content.isCheckInProgress', true); App.ajax.send({ name: 'wizard.advanced_repositories.valid_url', dataType:'text', sender: this, data: { stackName: stackName, stackVersion: stackVersion, repoId: repo.get('repoId'), osType: os.get('osType'), osId: os.get('id'), dfd: dfd, data: { 'Repositories': { 'base_url': repo.get('baseUrl'), 'repo_name': repo.get('repoName'), "verify_base_url": verifyBaseUrl } } }, success: 'checkRepoURLSuccessCallback', error: 'checkRepoURLErrorCallback' }); } }, this); } else if (os.get('isSelected') && os.get('isEmpty')) { os.set('isSelected', false); } }, this); } return dfd.promise(); }, /** * onSuccess callback for check Repo URL. */ checkRepoURLSuccessCallback: function (response, request, data) { var selectedStack = this.get('content.stacks').findProperty('isSelected'); if (selectedStack && selectedStack.get('operatingSystems')) { var os = selectedStack.get('operatingSystems').findProperty('id', data.osId); var repo = os.get('repositories').findProperty('repoId', data.repoId); if (repo) { repo.set('validation', 'OK'); } } this.set('validationCnt', this.get('validationCnt') - 1); if (!this.get('validationCnt')) { this.set('content.isCheckInProgress', false); data.dfd.resolve(); } }, /** * onError callback for check Repo URL. */ checkRepoURLErrorCallback: function (request, ajaxOptions, error, data, params) { var selectedStack = this.get('content.stacks').findProperty('isSelected', true); if (selectedStack && selectedStack.get('operatingSystems')) { var os = selectedStack.get('operatingSystems').findProperty('id', params.osId); var repo = os.get('repositories').findProperty('repoId', params.repoId); if (repo) { var title = Ember.Handlebars.Utils.escapeExpression(request.status + ":" + request.statusText); var content = ""; try { content = JSON.parse(request.responseText); } catch (error) {} repo.setProperties({ validation: 'INVALID', errorTitle: title, errorContent: content }); } } this.set('content.isCheckInProgress', false); params.dfd.reject(); }, loadMap: { '0': [ { type: 'sync', callback: function () { this.load('cluster'); } } ], '1': [ { type: 'async', callback: function () { var dfd = $.Deferred(); this.loadStacks().done(function(stacksLoaded) { App.router.get('clusterController').loadAmbariProperties().always(function() { dfd.resolve(stacksLoaded); }); }); return dfd.promise(); } }, { type: 'async', callback: function (stacksLoaded) { var dfd = $.Deferred(); if (!stacksLoaded) { this.loadStacksVersions().done(function () { dfd.resolve(true); }); } else { dfd.resolve(stacksLoaded); } return dfd.promise(); } } ], '2': [ { type: 'sync', callback: function () { this.load('installOptions'); } } ], '3': [ { type: 'sync', callback: function () { this.loadConfirmedHosts(); } } ], '4': [ { type: 'async', callback: function () { return this.loadServices(); } } ], '5': [ { type: 'sync', callback: function () { this.setSkipSlavesStep(App.StackService.find().filterProperty('isSelected'), 6); this.loadMasterComponentHosts(); this.loadConfirmedHosts(); this.loadComponentsFromConfigs(); this.loadRecommendations(); } } ], '6': [ { type: 'sync', callback: function () { this.loadSlaveComponentHosts(); this.loadClients(); this.loadComponentsFromConfigs(); this.loadRecommendations(); } } ], '7': [ { type: 'async', callback: function () { var dfd = $.Deferred(); var self = this; this.loadServiceConfigGroups(); this.loadCurrentHostGroups(); this.loadRecommendationsConfigs(); this.loadComponentsFromConfigs(); this.loadConfigThemes().done(function() { self.loadServiceConfigProperties(); dfd.resolve(); }); return dfd.promise(); } } ] }, clearConfigActionComponents: function() { var masterComponentHosts = this.get('content.masterComponentHosts'); var componentsAddedFromConfigAction = this.get('content.componentsFromConfigs'); if (componentsAddedFromConfigAction && componentsAddedFromConfigAction.length) { componentsAddedFromConfigAction.forEach(function(_masterComponent){ masterComponentHosts = masterComponentHosts.rejectProperty('component', _masterComponent); }); } this.set('content.masterComponentHosts', masterComponentHosts); this.setDBProperty('masterComponentHosts', masterComponentHosts); }, /** * Clear all temporary data */ finish: function () { this.setCurrentStep('0'); this.clearStorageData(); this.clearServiceConfigProperties(); App.router.get('userSettingsController').postUserPref('show_bg', true); App.themesMapper.resetModels(); }, /** * Save cluster provisioning state to the server * @param state cluster provisioning state */ setClusterProvisioningState: function (state) { return App.ajax.send({ name: 'cluster.save_provisioning_state', sender: this, data: { state: state } }); }, setStepsEnable: function () { for (var i = 0; i <= this.totalSteps; i++) { this.get('isStepDisabled').findProperty('step', i).set('value', i > this.get('currentStep')); } }.observes('currentStep'), setLowerStepsDisable: function (stepNo) { for (var i = 0; i < stepNo; i++) { var step = this.get('isStepDisabled').findProperty('step', i); step.set('value', true); } }, /** * Compare jdk versions used for ambari and selected stack. * Validation check will fire only for non-custom jdk configuration. * * @param {Function} successCallback * @param {Function} failCallback */ validateJDKVersion: function (successCallback, failCallback) { var selectedStack = App.Stack.find().findProperty('isSelected', true), currentJDKVersion = App.router.get('clusterController.ambariProperties')['java.version'], // use min as max, or max as min version, in case when some of them missed minJDKVersion = selectedStack.get('minJdkVersion') || selectedStack.get('maxJdkVersion'), maxJDKVersion = selectedStack.get('maxJdkVersion') || selectedStack.get('minJdkVersion'), t = Em.I18n.t, fCallback = failCallback || function() {}, sCallback = successCallback || function() {}; // Skip jdk check if min and max required version not set in stack definition. if (!minJDKVersion && !maxJDKVersion) { sCallback(); return; } if (currentJDKVersion) { if (stringUtils.compareVersions(currentJDKVersion, minJDKVersion) < 0 || stringUtils.compareVersions(maxJDKVersion, currentJDKVersion) < 0) { // checks and process only minor part for now var versionDistance = parseInt(maxJDKVersion.split('.')[1], 10) - parseInt(minJDKVersion.split('.')[1], 10); var versionsList = [minJDKVersion]; for (var i = 1; i < versionDistance + 1; i++) { versionsList.push("" + minJDKVersion.split('.')[0] + '.' + (+minJDKVersion.split('.')[1] + i)); } var versionsString = stringUtils.getFormattedStringFromArray(versionsList, t('or')); var popupBody = t('popup.jdkValidation.body').format(selectedStack.get('stackName') + ' ' + selectedStack.get('stackVersion'), versionsString, currentJDKVersion); App.showConfirmationPopup(sCallback, popupBody, fCallback, t('popup.jdkValidation.header'), t('common.proceedAnyway'), 'danger'); return; } } sCallback(); } });