Ver Fonte

AMBARI-3527. NameNode HA Rollback: Create routes for new steps, change layout, save information from NN HA wizard for rollback tips (alexantonenko)

Alex Antonenko há 11 anos atrás
pai
commit
65ba892aef
25 ficheiros alterados com 808 adições e 73 exclusões
  1. 1 1
      ambari-web/app/config.js
  2. 4 0
      ambari-web/app/controllers.js
  3. 0 5
      ambari-web/app/controllers/main/admin/highAvailability/wizard_controller.js
  4. 4 0
      ambari-web/app/controllers/main/admin/highAvailability_controller.js
  5. 227 0
      ambari-web/app/controllers/main/admin/rollbackHA/rollback_wizard_controller.js
  6. 24 0
      ambari-web/app/controllers/main/admin/rollbackHA/step1_controller.js
  7. 24 0
      ambari-web/app/controllers/main/admin/rollbackHA/step2_controller.js
  8. 23 0
      ambari-web/app/controllers/main/admin/rollbackHA/step3_controller.js
  9. 5 0
      ambari-web/app/messages.js
  10. 2 1
      ambari-web/app/models/cluster_states.js
  11. 2 2
      ambari-web/app/router.js
  12. 15 0
      ambari-web/app/routes/high_availability_routes.js
  13. 2 55
      ambari-web/app/routes/main.js
  14. 160 0
      ambari-web/app/routes/rollbackHA_routes.js
  15. 11 3
      ambari-web/app/templates/main/admin/highAvailability.hbs
  16. 40 0
      ambari-web/app/templates/main/admin/rollbackHA/rollback_wizard.hbs
  17. 24 0
      ambari-web/app/templates/main/admin/rollbackHA/step1.hbs
  18. 25 0
      ambari-web/app/templates/main/admin/rollbackHA/step2.hbs
  19. 24 0
      ambari-web/app/templates/main/admin/rollbackHA/step3.hbs
  20. 48 6
      ambari-web/app/utils/db.js
  21. 4 0
      ambari-web/app/views.js
  22. 49 0
      ambari-web/app/views/main/admin/rollbackHA/rollback_wizard_view.js
  23. 30 0
      ambari-web/app/views/main/admin/rollbackHA/step1_view.js
  24. 30 0
      ambari-web/app/views/main/admin/rollbackHA/step2_view.js
  25. 30 0
      ambari-web/app/views/main/admin/rollbackHA/step3_view.js

+ 1 - 1
ambari-web/app/config.js

@@ -60,7 +60,7 @@ App.supports = {
   localRepositories: true,
   highAvailability: true,
   deleteHost: false,
-  autoRollbackHA: true
+  autoRollbackHA: false
 };
 
 if (App.enableExperimental) {

+ 4 - 0
ambari-web/app/controllers.js

@@ -39,6 +39,10 @@ require('controllers/main/admin/highAvailability/step6_controller');
 require('controllers/main/admin/highAvailability/step7_controller');
 require('controllers/main/admin/highAvailability/step8_controller');
 require('controllers/main/admin/highAvailability/step9_controller');
+require('controllers/main/admin/rollbackHA/step1_controller');
+require('controllers/main/admin/rollbackHA/step2_controller');
+require('controllers/main/admin/rollbackHA/step3_controller');
+require('controllers/main/admin/rollbackHA/rollback_wizard_controller');
 require('controllers/main/admin/cluster');
 require('controllers/main/admin/stack_upgrade_controller');
 require('controllers/main/admin/user');

+ 0 - 5
ambari-web/app/controllers/main/admin/highAvailability/wizard_controller.js

@@ -159,11 +159,6 @@ App.HighAvailabilityWizardController = App.WizardController.extend({
     this.set('content.tasksStatuses', statuses);
   },
 
-  saveFailedTask: function(task){
-    App.db.setHighAvailabilityWizardFailedTask(task);
-    this.set('content.failedTask', task);
-  },
-
   saveConfigTag: function(tag){
     App.db.setHighAvailabilityWizardConfigTag(tag);
     this.set('content.'+[tag.name], tag.value);

+ 4 - 0
ambari-web/app/controllers/main/admin/highAvailability_controller.js

@@ -51,6 +51,10 @@ App.MainAdminHighAvailabilityController = Em.Controller.extend({
     App.router.transitionTo('enableHighAvailability');
   },
 
+  disableHighAvailability: function () {
+    App.router.transitionTo('rollbackHighAvailability');
+  },
+
   setSecurityStatus: function () {
     if (App.testMode) {
       this.set('securityEnabled', !App.testEnableSecurity);

+ 227 - 0
ambari-web/app/controllers/main/admin/rollbackHA/rollback_wizard_controller.js

@@ -0,0 +1,227 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+var App = require('app');
+
+App.RollbackHighAvailabilityWizardController = App.WizardController.extend({
+
+  name: 'rollbackHighAvailabilityWizardController',
+
+  totalSteps: 3,
+
+  /**
+   * Used for hiding back button in wizard
+   */
+  hideBackButton: true,
+
+  content: Em.Object.create({
+    controllerName: 'RollbackHighAvailabilityWizardController',
+    cluster: null,
+    hosts: null,
+    services: null,
+    slaveComponentHosts: null,
+    masterComponentHosts: null,
+    serviceName: 'MISC',
+    hdfsUser:"hdfs",
+    nameServiceId: '',
+    failedTask : null
+  }),
+
+  /**
+   * return new object extended from clusterStatusTemplate
+   * @return Object
+   */
+  getCluster: function(){
+    return jQuery.extend({}, this.get('clusterStatusTemplate'), {name: App.router.getClusterName()});
+  },
+
+  /**
+   * Load services data from server.
+   */
+  loadServicesFromServer: function() {
+    var displayOrderConfig = require('data/services');
+    var apiUrl = App.get('stack2VersionURL');
+    var apiService = this.loadServiceComponents(displayOrderConfig, apiUrl);
+    //
+    apiService.forEach(function(item, index){
+      apiService[index].isSelected = App.Service.find().someProperty('id', item.serviceName);
+      apiService[index].isDisabled = apiService[index].isSelected;
+      apiService[index].isInstalled = apiService[index].isSelected;
+    });
+    this.set('content.services', apiService);
+    App.db.setService(apiService);
+  },
+
+  /**
+   * Load confirmed hosts.
+   * Will be used at <code>Assign Masters(step5)</code> step
+   */
+  loadConfirmedHosts: function(){
+    var hosts = App.db.getHosts();
+    if(!hosts || !hosts.length){
+      var hosts = {};
+
+      App.Host.find().forEach(function(item){
+        hosts[item.get('id')] = {
+          name: item.get('id'),
+          cpu: item.get('cpu'),
+          memory: item.get('memory'),
+          disk_info: item.get('diskInfo'),
+          bootStatus: "REGISTERED",
+          isInstalled: true
+        };
+      });
+      App.db.setHosts(hosts);
+    }
+
+    this.set('content.hosts', hosts);
+    console.log('ReassignMasterController.loadConfirmedHosts: loaded hosts', hosts);
+  },
+
+  /**
+   * Load master component hosts data for using in required step controllers
+   */
+  loadMasterComponentHosts: function () {
+    var masterComponentHosts = App.db.getMasterComponentHosts();
+    if(!masterComponentHosts){
+      masterComponentHosts = [];
+      App.HostComponent.find().filterProperty('isMaster', true).forEach(function(item){
+        masterComponentHosts.push({
+          component: item.get('componentName'),
+          hostName: item.get('host.hostName'),
+          isInstalled: true
+        })
+      });
+
+    }
+    this.set("content.masterComponentHosts", masterComponentHosts);
+    console.log("ReassignMasterController.loadMasterComponentHosts: loaded hosts ", masterComponentHosts);
+  },
+
+  /**
+   * save status of the cluster.
+   * @param clusterStatus object with status,requestId fields.
+   */
+  saveClusterStatus: function (clusterStatus) {
+    var oldStatus = this.toObject(this.get('content.cluster'));
+    clusterStatus = jQuery.extend(oldStatus, clusterStatus);
+    if (clusterStatus.requestId) {
+      clusterStatus.requestId.forEach(function (requestId) {
+        if (clusterStatus.oldRequestsId.indexOf(requestId) === -1) {
+          clusterStatus.oldRequestsId.push(requestId)
+        }
+      }, this);
+    }
+    this.set('content.cluster', clusterStatus);
+    this.save('cluster');
+  },
+
+  /**
+   * Save Master Component Hosts data to Main Controller
+   * @param stepController App.WizardStep5Controller
+   */
+  saveMasterComponentHosts: function (stepController) {
+    var obj = stepController.get('selectedServicesMasters');
+    var masterComponentHosts = [];
+    obj.forEach(function (_component) {
+      masterComponentHosts.push({
+        display_name: _component.get('display_name'),
+        component: _component.get('component_name'),
+        hostName: _component.get('selectedHost'),
+        serviceId: _component.get('serviceId'),
+        isCurNameNode: _component.get('isCurNameNode'),
+        isAddNameNode: _component.get('isAddNameNode'),
+        isInstalled: true
+      });
+    });
+    App.db.setMasterComponentHosts(masterComponentHosts);
+    this.set('content.masterComponentHosts', masterComponentHosts);
+  },
+
+  saveTasksStatuses: function(statuses){
+    App.db.setRollbackHighAvailabilityWizardTasksStatuses(statuses);
+    this.set('content.tasksStatuses', statuses);
+  },
+
+  loadTasksStatuses: function(){
+    var statuses = App.db.getRollbackHighAvailabilityWizardTasksStatuses();
+    this.set('content.tasksStatuses', statuses);
+  },
+
+  saveRequestIds: function(requestIds){
+    App.db.setRollbackHighAvailabilityWizardRequestIds(requestIds);
+    this.set('content.requestIds', requestIds);
+  },
+
+  saveLogs: function(logs){
+    App.db.setRollbackHighAvailabilityWizardLogs(logs);
+    this.set('content.logs', logs);
+  },
+
+  loadRequestIds: function(){
+    var requestIds = App.db.getRollbackHighAvailabilityWizardRequestIds();
+    this.set('content.requestIds', requestIds);
+  },
+
+  loadLogs: function(){
+    var logs = App.db.getRollbackHighAvailabilityWizardLogs();
+    this.set('content.logs', logs);
+  },
+
+  /**
+   * Load data for all steps until <code>current step</code>
+   */
+  loadAllPriorSteps: function () {
+    var step = this.get('currentStep');
+    switch (step) {
+      case '3':
+      case '2':
+        //this.loadServicesFromServer();
+        //this.loadMasterComponentHosts();
+        //this.loadConfirmedHosts();
+      case '1':
+        this.load('cluster');
+    }
+  },
+
+  /**
+   * Remove all loaded data.
+   * Created as copy for App.router.clearAllSteps
+   */
+  clearAllSteps: function () {
+    this.clearInstallOptions();
+    // clear temporary information stored during the install
+    this.set('content.cluster', this.getCluster());
+  },
+
+  clearTasksData: function () {
+    this.saveTasksStatuses(undefined);
+    this.saveRequestIds(undefined);
+    this.saveLogs(undefined);
+  },
+
+  /**
+   * Clear all temporary data
+   */
+  finish: function () {
+    this.setCurrentStep('1');
+    this.clearAllSteps();
+    App.router.get('updateController').updateAll();
+  }
+});

+ 24 - 0
ambari-web/app/controllers/main/admin/rollbackHA/step1_controller.js

@@ -0,0 +1,24 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.RollbackHighAvailabilityWizardStep1Controller = Em.Controller.extend({
+  name:"rollbackHighAvailabilityWizardStep1Controller"
+});
+

+ 24 - 0
ambari-web/app/controllers/main/admin/rollbackHA/step2_controller.js

@@ -0,0 +1,24 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.RollbackHighAvailabilityWizardStep2Controller = Em.Controller.extend({
+  name:"rollbackHighAvailabilityWizardStep2Controller"
+});
+

+ 23 - 0
ambari-web/app/controllers/main/admin/rollbackHA/step3_controller.js

@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.RollbackHighAvailabilityWizardStep3Controller = Em.Controller.extend({
+  name:"rollbackHighAvailabilityWizardStep3Controller"
+});

+ 5 - 0
ambari-web/app/messages.js

@@ -634,6 +634,7 @@ Em.I18n.translations = {
 
   'admin.highAvailability':' High Availability',
   'admin.highAvailability.button.enable':'Enable NameNode HA',
+  'admin.highAvailability.button.disable':'Disable NameNode HA',
   'admin.highAvailability.disabled':'NameNode HA is disabled',
   'admin.highAvailability.enabled':'NameNode HA is enabled',
   'admin.highAvailability.confirmRollbackHeader':'Confirm Rollback',
@@ -665,6 +666,10 @@ Em.I18n.translations = {
   'admin.highAvailability.wizard.step6.bodyHeader':'Manual Steps Required: Initialize JournalNodes',
   'admin.highAvailability.wizard.step8.bodyHeader':'Manual Steps Required: Initialize NameNode HA Metadata',
 
+  'admin.rollbackHighAvailability.wizard.step1.header':'Select Hosts page',
+  'admin.rollbackHighAvailability.wizard.step2.header':'Create Checkpoint page',
+  'admin.rollbackHighAvailability.wizard.step3.header':'Progress page',
+
   'admin.highAvailability.wizard.step5.notice.inProgress':'Please wait while the wizard configures the components.',
   'admin.highAvailability.wizard.step7.notice.inProgress':'Please wait while the wizard starts the components.',
   'admin.highAvailability.wizard.step9.notice.inProgress':'Please wait while the wizard finalizes the HA setup.',

+ 2 - 1
ambari-web/app/models/cluster_states.js

@@ -23,7 +23,8 @@ App.clusterStatus = Ember.Object.create({
     'ADD_HOSTS_DEPLOY_PREP_2', 'ADD_HOSTS_INSTALLING_3', 'ADD_HOSTS_INSTALLED_4', 'ADD_HOSTS_COMPLETED_5',
     'ADD_SERVICES_DEPLOY_PREP_2', 'ADD_SERVICES_INSTALLING_3', 'ADD_SERVICES_INSTALLED_4', 'ADD_SERVICES_COMPLETED_5',
     'STOPPING_SERVICES', 'STACK_UPGRADING', 'STACK_UPGRADE_FAILED', 'STACK_UPGRADED', 'STACK_UPGRADE_COMPLETED', 'ADD_SECURITY_STEP_1',
-    'ADD_SECURITY_STEP_2', 'ADD_SECURITY_STEP_3', 'ADD_SECURITY_STEP_4', 'DISABLE_SECURITY', 'SECURITY_COMPLETED', 'HIGH_AVAILABILITY_DEPLOY'],
+    'ADD_SECURITY_STEP_2', 'ADD_SECURITY_STEP_3', 'ADD_SECURITY_STEP_4', 'DISABLE_SECURITY', 'SECURITY_COMPLETED', 'HIGH_AVAILABILITY_DEPLOY',
+    'HIGH_AVAILABILITY_DISABLED', 'ROLLBACK_HIGH_AVAILABILITY'],
   clusterState: 'CLUSTER_NOT_CREATED_1',
   wizardControllerName: null,
   localdb: null,

+ 2 - 2
ambari-web/app/router.js

@@ -292,9 +292,9 @@ App.Router = Em.Router.extend({
     } else if (clusterStatusOnServer && clusterStatusOnServer.wizardControllerName === App.router.get('highAvailabilityWizardController.name')) {
       // if wizardControllerName == "highAvailabilityWizardController", then it means someone closed the browser or the browser was crashed when we were last in NameNode High Availability wizard
       return 'main.admin.enableHighAvailability';
-    }else if (clusterStatusOnServer && clusterStatusOnServer.wizardControllerName === App.router.get('highAvailabilityRollbackController.name')) {
+    }else if (clusterStatusOnServer && clusterStatusOnServer.wizardControllerName === App.router.get('rollbackHighAvailabilityWizardController.name')) {
       // if wizardControllerName == "highAvailabilityRollbackController", then it means someone closed the browser or the browser was crashed when we were last in NameNode High Availability Rollback wizard
-      return 'main.admin.highAvailabilityRollback';
+      return 'main.admin.rollbackHighAvailability';
     } else {
       // if wizardControllerName == "installerController", then it means someone closed the browser or the browser was crashed when we were last in Installer wizard
       return 'installer';

+ 15 - 0
ambari-web/app/routes/high_availability_routes.js

@@ -136,6 +136,21 @@ module.exports = Em.Route.extend({
     next: function (router) {
       var controller = router.get('highAvailabilityWizardController');
       var highAvailabilityWizardStep2Controller = router.get('highAvailabilityWizardStep2Controller');
+      var addNN = highAvailabilityWizardStep2Controller.get('selectedServicesMasters').findProperty('isAddNameNode', true).get('selectedHost');
+      var sNN = highAvailabilityWizardStep2Controller.get('selectedServicesMasters').findProperty('component_name','SECONDARY_NAMENODE').get('selectedHost')
+      debugger;
+      if(addNN){
+        App.db.setRollBackHighAvailabilityWizardAddNNHost(addNN);
+      }
+      if(sNN){
+        App.db.setRollBackHighAvailabilityWizardSNNHost(sNN);
+      }
+      App.clusterStatus.setClusterStatus({
+        clusterName: this.get('content.cluster.name'),
+        clusterState: 'HIGH_AVAILABILITY_DEPLOY',
+        wizardControllerName: this.get('content.controllerName'),
+        localdb: App.db.data
+      });
       controller.saveMasterComponentHosts(highAvailabilityWizardStep2Controller);
       router.transitionTo('step3');
     },

+ 2 - 55
ambari-web/app/routes/main.js

@@ -663,63 +663,10 @@ module.exports = Em.Route.extend({
       })
     }),
 
-    highAvailabilityRollback: Ember.Route.extend({
-      route: '/highAvailability/rollback',
-      enter: function (router) {
-        //after refresh check if the wizard is open then restore it
-        Ember.run.next(function () {
-          App.router.get('updateController').set('isWorking', false);
-
-          var highAvailabilityWizardController = router.get('highAvailabilityWizardController');
-          if(highAvailabilityWizardController.get('popup')){
-            highAvailabilityWizardController.finish();
-            highAvailabilityWizardController.get('popup').hide();
-          }
-          highAvailabilityWizardController.loadTasksStatuses();
-          highAvailabilityWizardController.loadRequestIds();
-          highAvailabilityWizardController.loadLogs();
-          var popup = App.ModalPopup.show({
-            classNames: ['full-width-modal'],
-            header: Em.I18n.t('admin.highAvailability.rollback.header'),
-            bodyClass: App.HighAvailabilityRollbackView.extend({
-              controllerBinding: 'App.router.highAvailabilityRollbackController'
-            }),
-            showCloseButton: false,
-            primary: Em.I18n.t('form.cancel'),
-            secondary: null,
-            showFooter: false,
-
-            proceedOnClose: function () {
-              var controller = router.get('highAvailabilityWizardController');
-              controller.clearTasksData();
-              controller.clearStorageData();
-              App.router.get('updateController').set('isWorking', true);
-              App.clusterStatus.setClusterStatus({
-                clusterName: router.get('content.cluster.name'),
-                clusterState: 'HIGH_AVAILABILITY_DISABLED',
-                wizardControllerName: router.get('highAvailabilityRollbackController.name'),
-                localdb: App.db.data
-              });
-              this.hide();
-              router.transitionTo('main.admin.index');
-              location.reload();
-            },
-            didInsertElement: function () {
-              this.fitHeight();
-            }
-          });
-          router.set('highAvailabilityRollbackController.popup', popup);
-        });
-
-      },
-
-      unroutePath: function () {
-        return false;
-      }
-    }),
-
     enableHighAvailability: require('routes/high_availability_routes'),
 
+    rollbackHighAvailability: require('routes/rollbackHA_routes'),
+
 
 
     adminSecurity: Em.Route.extend({

+ 160 - 0
ambari-web/app/routes/rollbackHA_routes.js

@@ -0,0 +1,160 @@
+/**
+ * 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');
+
+module.exports = Em.Route.extend({
+  route: '/highAvailability/rollbackHA',
+
+  enter: function (router) {
+    Em.run.next(function () {
+      var rollbackHighAvailabilityWizardController = router.get('rollbackHighAvailabilityWizardController');
+      App.router.get('updateController').set('isWorking', false);
+      var popup = App.ModalPopup.show({
+        classNames: ['full-width-modal'],
+        header: Em.I18n.t('admin.highAvailability.wizard.rollback.header.title'),
+        bodyClass: App.RollbackHighAvailabilityWizardView.extend({
+          controller: rollbackHighAvailabilityWizardController
+        }),
+        primary: Em.I18n.t('form.cancel'),
+        showFooter: false,
+        secondary: null,
+        hideCloseButton: function () {
+          this.set('showCloseButton', false);
+        }.observes('App.router.rollbackHighAvailabilityWizardController.currentStep'),
+
+        onClose: function () {
+          this.hide();
+          App.router.get('rollbackHighAvailabilityWizardController').setCurrentStep('1');
+          App.router.get('updateController').set('isWorking', true);
+          App.router.transitionTo('main.admin.adminHighAvailability');
+        },
+        didInsertElement: function () {
+          this.fitHeight();
+        }
+      });
+      rollbackHighAvailabilityWizardController.set('popup', popup);
+      App.clusterStatus.updateFromServer();
+      var currentClusterStatus = App.clusterStatus.get('value');
+      if (currentClusterStatus) {
+        switch (currentClusterStatus.clusterState) {
+          case 'ROLLBACK_HIGH_AVAILABILITY' :
+            App.db.data = currentClusterStatus.localdb;
+            rollbackHighAvailabilityWizardController.setCurrentStep(currentClusterStatus.localdb.RollbackHighAvailabilityWizard.currentStep);
+            break;
+          default:
+            var currStep = App.router.get('rollbackHighAvailabilityWizardController.currentStep');
+            rollbackHighAvailabilityWizardController.setCurrentStep(currStep);
+            break;
+        }
+      }
+      router.transitionTo('step' + rollbackHighAvailabilityWizardController.get('currentStep'));
+    });
+  },
+
+  step1: Em.Route.extend({
+    route: '/step1',
+    connectOutlets: function (router) {
+      var controller = router.get('rollbackHighAvailabilityWizardController');
+      controller.setCurrentStep('1');
+      controller.dataLoading().done(function () {
+        controller.loadAllPriorSteps();
+        controller.connectOutlet('rollbackHighAvailabilityWizardStep1', controller.get('content'));
+      })
+    },
+    unroutePath: function () {
+      return false;
+    },
+    next: function (router) {
+      router.transitionTo('step2');
+    }
+  }),
+
+  step2: Em.Route.extend({
+    route: '/step2',
+    connectOutlets: function (router) {
+      var controller = router.get('rollbackHighAvailabilityWizardController');
+      controller.setCurrentStep('2');
+      App.clusterStatus.setClusterStatus({
+        clusterName: router.get('content.cluster.name'),
+        clusterState: 'ROLLBACK_HIGH_AVAILABILITY',
+        wizardControllerName: 'rollbackHighAvailabilityWizardController',
+        localdb: App.db.data
+      });
+      controller.setCurrentStep('2');
+      controller.dataLoading().done(function () {
+        controller.loadAllPriorSteps();
+        controller.connectOutlet('rollbackHighAvailabilityWizardStep2', controller.get('content'));
+      })
+    },
+    unroutePath: function () {
+      return false;
+    },
+    next: function (router) {
+      router.transitionTo('step3');
+    },
+    back: function (router) {
+      router.transitionTo('step1');
+    }
+  }),
+
+  step3: Em.Route.extend({
+    route: '/step3',
+    connectOutlets: function (router) {
+      var controller = router.get('rollbackHighAvailabilityWizardController');
+      controller.setCurrentStep('3');
+      controller.setLowerStepsDisable(3);
+      App.clusterStatus.setClusterStatus({
+        clusterName: router.get('content.cluster.name'),
+        clusterState: 'ROLLBACK_HIGH_AVAILABILITY',
+        wizardControllerName: 'rollbackHighAvailabilityWizardController',
+        localdb: App.db.data
+      });
+      controller.dataLoading().done(function () {
+        controller.loadAllPriorSteps();
+        controller.connectOutlet('rollbackHighAvailabilityWizardStep3',  controller.get('content'));
+      })
+    },
+    unroutePath: function () {
+      return false;
+    },
+    next: function (router) {
+      var controller = router.get('rollbackHighAvailabilityWizardController');
+      controller.clearTasksData();
+      controller.clearStorageData();
+      controller.finish();
+      controller.get('popup').hide();
+      App.router.get('updateController').set('isWorking', true);
+      App.clusterStatus.setClusterStatus({
+        clusterName: router.get('content.cluster.name'),
+        clusterState: 'HIGH_AVAILABILITY_DISABLED',
+        wizardControllerName: 'rollbackHighAvailabilityWizardController',
+        localdb: App.db.data
+      });
+      router.transitionTo('main.index');
+      location.reload();
+    }
+  }),
+
+  gotoStep1: Em.Router.transitionTo('step1'),
+
+  gotoStep2: Em.Router.transitionTo('step2'),
+
+  gotoStep3: Em.Router.transitionTo('step3')
+
+});

+ 11 - 3
ambari-web/app/templates/main/admin/highAvailability.hbs

@@ -18,9 +18,17 @@
 
 <div>
   {{#if view.isHighAvailabilityEnabled}}
-    <p class="text-success">
-      {{t admin.highAvailability.enabled}}
-    </p>
+    {{#if App.supports.autoRollbackHA}}
+      <p class="text-success">
+        {{t admin.highAvailability.enabled}}
+        <a class="btn btn-padding btn-success" {{action disableHighAvailability target="controller"}}>{{t admin.highAvailability.button.disable}}</a>
+      </p>
+    {{else}}
+       <p class="text-success">
+        {{t admin.highAvailability.enabled}}
+       </p>
+    {{/if}}
+
   {{else}}
     {{#if controller.dataIsLoaded}}
       <p class="muted">

+ 40 - 0
ambari-web/app/templates/main/admin/rollbackHA/rollback_wizard.hbs

@@ -0,0 +1,40 @@
+{{!
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements.  See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership.  The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+}}
+
+<div class="wizard">
+  <div class="container">
+    <div class="container-fluid">
+      <div class="row-fluid">
+        <div class="span3">
+          <!--Sidebar content-->
+          <div class="well">
+            <ul class="nav nav-pills nav-stacked">
+              <li class="nav-header">{{t admin.highAvailability.wizard.rollback.header.title}}</li>
+              <li {{bindAttr class="isStep1:active view.isStep1Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep1 target="controller"}}>{{t admin.rollbackHighAvailability.wizard.step1.header}}</a></li>
+              <li {{bindAttr class="isStep2:active view.isStep2Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep2 target="controller"}}>{{t admin.rollbackHighAvailability.wizard.step2.header}}</a></li>
+              <li {{bindAttr class="isStep3:active view.isStep3Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep3 target="controller"}}>{{t admin.rollbackHighAvailability.wizard.step3.header}}</a></li>
+            </ul>
+          </div>
+        </div>
+        <div class="wizard-content well span9">
+          {{outlet}}
+        </div>
+      </div>
+    </div>
+  </div>
+</div>

+ 24 - 0
ambari-web/app/templates/main/admin/rollbackHA/step1.hbs

@@ -0,0 +1,24 @@
+{{!
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements.  See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership.  The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+}}
+<div id="ha-step1">
+  <h2>{{t admin.rollbackHighAvailability.wizard.step1.header}}</h2>
+
+  <div class="btn-area">
+    <a {{bindAttr class=":btn controller.isNameServiceIdValid::disabled :btn-success :pull-right"}} {{action next}}>{{t common.next}} &rarr;</a>
+  </div>
+</div>

+ 25 - 0
ambari-web/app/templates/main/admin/rollbackHA/step2.hbs

@@ -0,0 +1,25 @@
+{{!
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements.  See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership.  The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+}}
+<div id="ha-step1">
+  <h2>{{t admin.rollbackHighAvailability.wizard.step2.header}}</h2>
+
+
+  <div class="btn-area">
+    <a {{bindAttr class=":btn controller.isNameServiceIdValid::disabled :btn-success :pull-right"}} {{action next}}>{{t common.next}} &rarr;</a>
+  </div>
+</div>

+ 24 - 0
ambari-web/app/templates/main/admin/rollbackHA/step3.hbs

@@ -0,0 +1,24 @@
+{{!
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements.  See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership.  The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+}}
+<div id="ha-step1">
+  <h2>{{t admin.rollbackHighAvailability.wizard.step3.header}}</h2>
+
+  <div class="btn-area">
+    <a {{bindAttr class=":btn controller.isNameServiceIdValid::disabled :btn-success :pull-right"}} {{action next}}>{{t common.next}} &rarr;</a>
+  </div>
+</div>

+ 48 - 6
ambari-web/app/utils/db.js

@@ -65,7 +65,8 @@ App.db.cleanUp = function () {
     'StackUpgrade' : {},
     'ReassignMaster' : {},
     'AddSecurity': {},
-    'HighAvailabilityWizard': {}
+    'HighAvailabilityWizard': {},
+    'RollbackHighAvailabilityWizard': {}
 
   };
   console.log("In cleanup./..");
@@ -372,11 +373,6 @@ App.db.setHighAvailabilityWizardConfigTag = function (tag) {
   localStorage.setObject('ambari', App.db.data);
 };
 
-App.db.setHighAvailabilityWizardFailedTask = function (task) {
-  App.db.data = localStorage.getObject('ambari');
-  App.db.data.HighAvailabilityWizard.failedTask = task;
-  localStorage.setObject('ambari', App.db.data);
-};
 App.db.setHighAvailabilityWizardHdfsClientHosts = function (hostNames) {
   App.db.data = localStorage.getObject('ambari');
   App.db.data.HighAvailabilityWizard.hdfsClientHostNames = hostNames;
@@ -407,6 +403,37 @@ App.db.setHighAvailabilityWizardNameServiceId = function (nameServiceId) {
   localStorage.setObject('ambari', App.db.data);
 };
 
+
+App.db.setRollBackHighAvailabilityWizardAddNNHost = function (host) {
+  App.db.data = localStorage.getObject('ambari');
+  App.db.data.RollbackHighAvailabilityWizard.addNNHost = host;
+  localStorage.setObject('ambari', App.db.data);
+};
+
+App.db.setRollBackHighAvailabilityWizardSNNHost = function (host) {
+  App.db.data = localStorage.getObject('ambari');
+  App.db.data.RollbackHighAvailabilityWizard.sNNHost = host;
+  localStorage.setObject('ambari', App.db.data);
+};
+
+App.db.setRollbackHighAvailabilityWizardTasksStatuses = function (tasksStatuses) {
+  App.db.data = localStorage.getObject('ambari');
+  App.db.data.RollbackHighAvailabilityWizard.tasksStatuses = tasksStatuses;
+  localStorage.setObject('ambari', App.db.data);
+};
+
+App.db.setRollbackHighAvailabilityWizardRequestIds = function (requestIds) {
+  App.db.data = localStorage.getObject('ambari');
+  App.db.data.RollbackHighAvailabilityWizard.requestIds = requestIds;
+  localStorage.setObject('ambari', App.db.data);
+};
+
+App.db.setRollbackHighAvailabilityWizardLogs = function (logs) {
+  App.db.data = localStorage.getObject('ambari');
+  App.db.data.RollbackHighAvailabilityWizard.logs = logs;
+  localStorage.setObject('ambari', App.db.data);
+};
+
 App.db.setReassignMasterWizardRequestIds = function (requestIds) {
   App.db.data = localStorage.getObject('ambari');
   App.db.data.ReassignMaster.requestIds = requestIds;
@@ -684,6 +711,21 @@ App.db.getHighAvailabilityWizardNameServiceId = function () {
   return App.db.data.HighAvailabilityWizard.nameServiceId;
 };
 
+App.db.getRollbackHighAvailabilityWizardTasksStatuses = function () {
+  App.db.data = localStorage.getObject('ambari');
+  return App.db.data.RollbackHighAvailabilityWizard.tasksStatuses;
+};
+
+App.db.getRollbackHighAvailabilityWizardRequestIds = function () {
+  App.db.data = localStorage.getObject('ambari');
+  return App.db.data.RollbackHighAvailabilityWizard.requestIds;
+};
+
+App.db.getRollbackHighAvailabilityWizardLogs = function () {
+  App.db.data = localStorage.getObject('ambari');
+  return App.db.data.RollbackHighAvailabilityWizard.logs;
+};
+
 App.db.getReassignMasterWizardRequestIds = function () {
   App.db.data = localStorage.getObject('ambari');
   return App.db.data.ReassignMaster.requestIds;

+ 4 - 0
ambari-web/app/views.js

@@ -66,6 +66,10 @@ require('views/main/admin/highAvailability/step6_view');
 require('views/main/admin/highAvailability/step7_view');
 require('views/main/admin/highAvailability/step8_view');
 require('views/main/admin/highAvailability/step9_view');
+require('views/main/admin/rollbackHA/step1_view');
+require('views/main/admin/rollbackHA/step2_view');
+require('views/main/admin/rollbackHA/step3_view');
+require('views/main/admin/rollbackHA/rollback_wizard_view');
 require('views/main/admin/cluster');
 require('views/main/admin/misc_view');
 require('views/main/admin/stack_upgrade');

+ 49 - 0
ambari-web/app/views/main/admin/rollbackHA/rollback_wizard_view.js

@@ -0,0 +1,49 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+var App = require('app');
+
+App.RollbackHighAvailabilityWizardView = Em.View.extend({
+
+  didInsertElement: function() {
+    var currentStep = this.get('controller.currentStep');
+    if (currentStep > 4) {
+      this.get('controller').setLowerStepsDisable(currentStep);
+    }
+  },
+
+  templateName: require('templates/main/admin/rollbackHA/rollback_wizard'),
+
+  isStep1Disabled: function () {
+    return this.isStepDisabled(1);
+  }.property('controller.isStepDisabled.@each.value').cacheable(),
+
+  isStep2Disabled: function () {
+    return this.isStepDisabled(2);
+  }.property('controller.isStepDisabled.@each.value').cacheable(),
+
+  isStep3Disabled: function () {
+    return this.isStepDisabled(3);
+  }.property('controller.isStepDisabled.@each.value').cacheable(),
+
+  isStepDisabled: function (index) {
+    return this.get('controller.isStepDisabled').findProperty('step', index).get('value');
+  }
+
+});

+ 30 - 0
ambari-web/app/views/main/admin/rollbackHA/step1_view.js

@@ -0,0 +1,30 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+var App = require('app');
+
+App.RollbackHighAvailabilityWizardStep1View = Em.View.extend({
+
+  templateName: require('templates/main/admin/rollbackHA/step1'),
+
+  didInsertElement: function() {
+
+  }
+
+});

+ 30 - 0
ambari-web/app/views/main/admin/rollbackHA/step2_view.js

@@ -0,0 +1,30 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+var App = require('app');
+
+App.RollbackHighAvailabilityWizardStep2View = Em.View.extend({
+
+  templateName: require('templates/main/admin/rollbackHA/step2'),
+
+  didInsertElement: function() {
+
+  }
+
+});

+ 30 - 0
ambari-web/app/views/main/admin/rollbackHA/step3_view.js

@@ -0,0 +1,30 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+var App = require('app');
+
+App.RollbackHighAvailabilityWizardStep3View = Em.View.extend({
+
+  templateName: require('templates/main/admin/rollbackHA/step3'),
+
+  didInsertElement: function() {
+
+  }
+
+});