瀏覽代碼

AMBARI-890. Add client library option to step6 (Assign slaves) of installer wizard. Also add indicator and popovers for hosts with master component. (Jaimin Jetly via yusaku)

git-svn-id: https://svn.apache.org/repos/asf/incubator/ambari/branches/AMBARI-666@1400492 13f79535-47bb-0310-9956-ffa450edef68
Yusaku Sako 12 年之前
父節點
當前提交
83fb0a2bb0

+ 5 - 1
AMBARI-666-CHANGES.txt

@@ -12,8 +12,12 @@ AMBARI-666 branch (unreleased changes)
 
 
   NEW FEATURES
   NEW FEATURES
 
 
+  AMBARI-890. Add client library option to step6 (Assign slaves) of
+  installer wizard. Also add indicator and popovers for hosts with
+  master component. (Jaimin Jetly via yusaku)  
+
   AMBARI-889. Provide cluster metric graphs on Ambari main dashboard.
   AMBARI-889. Provide cluster metric graphs on Ambari main dashboard.
-  (yusaku)
+  (Srimanth Gunturi via yusaku)
 
 
   AMBARI-886. Support filters in controller get* apis. (hitesh)
   AMBARI-886. Support filters in controller get* apis. (hitesh)
 
 

+ 19 - 0
ambari-web/app/controllers/installer/step5_controller.js

@@ -576,9 +576,28 @@ App.InstallerStep5Controller = Em.Controller.extend({
     });
     });
 
 
     App.db.setMasterComponentHosts(masterComponentHosts);
     App.db.setMasterComponentHosts(masterComponentHosts);
+    this.saveHostToMasterComponents();
 
 
   },
   },
 
 
+  saveHostToMasterComponents: function () {
+    var hostMasterComponents = App.db.getMasterComponentHosts();
+    var hosts = hostMasterComponents.mapProperty('hostName').uniq();
+    var hostsMasterServicesMapping = [];
+    hosts.forEach(function (_host) {
+      var componentsOnHost = hostMasterComponents.filterProperty('hostName', _host).mapProperty('component');
+      hostsMasterServicesMapping.push({
+        hostname: _host,
+        components: componentsOnHost
+      });
+    }, this);
+    App.db.setHostToMasterComponent(hostsMasterServicesMapping);
+    App.db.getHostToMasterComponent().forEach(function (_hostcomponent) {
+      console.log("INFO: the name of this thimg is: " + _hostcomponent.hostname);
+      console.log("INFO: the name of this thimg is: " + _hostcomponent.components);
+    }, this);
+  },
+
   submit: function () {
   submit: function () {
     this.saveComponentHostsToDb();
     this.saveComponentHostsToDb();
     App.router.send('next');
     App.router.send('next');

+ 273 - 237
ambari-web/app/controllers/installer/step6_controller.js

@@ -34,240 +34,276 @@ var db = require('utils/db');
  */
  */
 App.InstallerStep6Controller = Em.Controller.extend({
 App.InstallerStep6Controller = Em.Controller.extend({
 
 
-	hosts: [],
-	// TODO: hook up with user host selection
-	rawHosts: [],
-	selectedServiceNames: [],
-	masterComponentHosts: require('data/mock/master_component_hosts'),
-	showHbase: false,
-	showTaskTracker: false,
-
-
-	hasMasterComponents: function (hostname) {
-		var hasMaster = false;
-		var masterComponentHosts = db.getMasterComponentHosts();
-		return masterComponentHosts.someProperty('hostName', hostname);
-	},
-
-
-	isAllDataNodes: function () {
-		return this.get('hosts').everyProperty('isDataNode', true);
-	}.property('hosts.@each.isDataNode'),
-
-	isAllTaskTrackers: function () {
-		return this.get('hosts').everyProperty('isTaskTracker', true);
-	}.property('hosts.@each.isTaskTracker'),
-
-	isAllRegionServers: function () {
-		return this.get('hosts').everyProperty('isRegionServer', true);
-	}.property('hosts.@each.isRegionServer'),
-
-	isNoDataNodes: function () {
-		return this.get('hosts').everyProperty('isDataNode', false);
-	}.property('hosts.@each.isDataNode'),
-
-	isNoTaskTrackers: function () {
-		return this.get('hosts').everyProperty('isTaskTracker', false);
-	}.property('hosts.@each.isTaskTracker'),
-
-	isNoRegionServers: function () {
-		return this.get('hosts').everyProperty('isRegionServer', false);
-	}.property('hosts.@each.isRegionServer'),
-
-	isHbaseSelected: function () {
-		var services = db.getSelectedServiceNames();
-		return this.get('selectedServiceNames').contains('HBASE');
-	},
-
-	isMrSelected: function () {
-		return this.get('selectedServiceNames').contains('MAPREDUCE');
-	}.property('selectedServiceNames'),
-
-	clearError: function () {
-		if (this.get('isNoDataNodes') === false && this.get('isNoTaskTrackers') === false && this.get('isNoRegionServers') === false) {
-			this.set('errorMessage', '');
-		}
-	}.observes('isNoDataNodes', 'isNoTaskTrackers', 'isNoRegionServers'),
-
-	selectAllDataNodes: function () {
-		this.get('hosts').setEach('isDataNode', true);
-	},
-
-	selectAllTaskTrackers: function () {
-		this.get('hosts').setEach('isTaskTracker', true);
-	},
-
-	selectAllRegionServers: function () {
-		this.get('hosts').setEach('isRegionServer', true);
-	},
-
-	deselectAllDataNodes: function () {
-		this.get('hosts').setEach('isDataNode', false);
-	},
-
-	deselectAllTaskTrackers: function () {
-		this.get('hosts').setEach('isTaskTracker', false);
-	},
-
-	deselectAllRegionServers: function () {
-		this.get('hosts').setEach('isRegionServer', false);
-	},
-
-
-	clearStep: function () {
-		this.set('hosts', []);
-		this.set('selectedServiceNames', []);
-		this.clearError();
-	},
-
-	loadStep: function () {
-		console.log("TRACE: Loading step6: Assign Slaves");
-		this.clearStep();
-		this.set('selectedServiceNames', db.getSelectedServiceNames());
-		this.set('showHbase', this.isHbaseSelected());
-		this.set('showTaskTracker', this.get('isMrSelected'));
-		this.setSlaveHost(this.getSlaveHosts());
-	},
-
-	getHostNames: function () {
-		var hostInfo = db.getHosts();
-		var hostNames = [];
-		for (var index in hostInfo) {
-			if (hostInfo[index].bootStatus === 'success')
-				hostNames.push(hostInfo[index].name);
-		}
-		return hostNames;
-	},
-
-	getSlaveHosts: function () {
-		var hostObjs = new Ember.Set();
-		var allHosts = this.getHostNames();
-		var slaveHosts = App.db.getSlaveComponentHosts();
-		if (slaveHosts === undefined || slaveHosts === null) {
-			allHosts.forEach(function (_hostname) {
-				var hostObj = {};
-				hostObj.hostname = _hostname;
-				hostObj.isDataNode = !this.hasMasterComponents(_hostname);
-				hostObj.isTaskTracker = !this.hasMasterComponents(_hostname);
-				hostObj.isRegionServer = !this.hasMasterComponents(_hostname);
-				hostObjs.add(hostObj);
-			}, this);
-			return hostObjs;
-		} else {
-			allHosts.forEach(function (_hostName) {
-				hostObjs.add({
-					hostname: _hostName
-				});
-			});
-			var datanodes = slaveHosts.findProperty('componentName', 'DATANODE');
-			datanodes.hosts.forEach(function (_datanode) {
-				var datanode = hostObjs.findProperty('hostname', _datanode.hostname);
-				if (datanode !== null) {
-					datanode.isDataNode = true;
-				}
-			});
-			if (this.get('isMrSelected')) {
-				var taskTrackers = slaveHosts.findProperty('componentName', 'TASKTRACKER');
-				taskTrackers.hosts.forEach(function (_taskTracker) {
-					var taskTracker = hostObjs.findProperty('hostname', _taskTracker.hostname);
-					if (taskTracker !== null) {
-						taskTracker.isTaskTracker = true;
-					}
-				});
-			}
-			if (this.isHbaseSelected()) {
-				var regionServers = slaveHosts.findProperty('componentName', 'HBASE_REGIONSERVER');
-				regionServers.hosts.forEach(function (_regionServer) {
-					var regionServer = hostObjs.findProperty('hostname', _regionServer.hostname);
-					if (regionServer !== null) {
-						regionServer.isRegionServer = true;
-					}
-				});
-			}
-			return hostObjs;
-		}
-	},
-
-	setSlaveHost: function (hostObj) {
-		hostObj.forEach(function (_hostObj) {
-			this.get('hosts').pushObject(Ember.Object.create(_hostObj));
-		}, this);
-	},
-
-	loadSlaveHost: function (hostNames) {
-
-		hostNames.forEach(function (_hostName) {
-			this.get('hosts').pushObject(Ember.Object.create({
-				hostname: _hostName,
-				isDataNode: !this.hasMasterComponents(_hostName),
-				isTaskTracker: !this.hasMasterComponents(_hostName),
-				isRegionServer: !this.hasMasterComponents(_hostName)
-			}));
-		}, this);
-	},
-
-
-	validate: function () {
-		return !(this.get('isNoDataNodes') || this.get('isNoTaskTrackers') || this.get('isNoRegionServers'));
-	},
-
-	submit: function () {
-		if (!this.validate()) {
-			this.set('errorMessage', Ember.I18n.t('installer.step6.error.mustSelectOne'));
-			return;
-		}
-		App.db.setHostSlaveComponents(this.get('host'));
-
-		var dataNodeHosts = [];
-		var taskTrackerHosts = [];
-		var regionServerHosts = [];
-
-		this.get('hosts').forEach(function (host) {
-			if (host.get('isDataNode')) {
-				dataNodeHosts.push({
-					hostname: host.hostname,
-					group: 'Default'
-				});
-			}
-			if (this.get('isMrSelected') && host.get('isRegionServer')) {
-				taskTrackerHosts.push({
-					hostname: host.hostname,
-					group: 'Default'
-				});
-			}
-			if (this.isHbaseSelected() && host.get('isRegionServer')) {
-				regionServerHosts.push({
-					hostname: host.hostname,
-					group: 'Default'
-				});
-			}
-		}, this);
-
-		var slaveComponentHosts = [];
-		slaveComponentHosts.push({
-			componentName: 'DATANODE',
-			displayName: 'DataNode',
-			hosts: dataNodeHosts
-		});
-		if (this.get('isMrSelected')) {
-			slaveComponentHosts.push({
-				componentName: 'TASKTRACKER',
-				displayName: 'TaskTracker',
-				hosts: taskTrackerHosts
-			});
-		}
-		if (this.isHbaseSelected()) {
-			slaveComponentHosts.push({
-				componentName: 'HBASE_REGIONSERVER',
-				displayName: 'RegionServer',
-				hosts: regionServerHosts
-			});
-		}
-
-		App.db.setSlaveComponentHosts(slaveComponentHosts);
-
-		App.router.send('next');
-
-	}
-})
-;
+  hosts: [],
+  // TODO: hook up with user host selection
+  rawHosts: [],
+  selectedServiceNames: [],
+  showHbase: false,
+  showTaskTracker: false,
+
+  hasMasterComponents: function (hostname) {
+    var hasMaster = false;
+    var masterComponentHosts = db.getMasterComponentHosts();
+    return masterComponentHosts.someProperty('hostName', hostname);
+  },
+
+  isAllDataNodes: function () {
+    return this.get('hosts').everyProperty('isDataNode', true);
+  }.property('hosts.@each.isDataNode'),
+
+  isAllTaskTrackers: function () {
+    return this.get('hosts').everyProperty('isTaskTracker', true);
+  }.property('hosts.@each.isTaskTracker'),
+
+  isAllRegionServers: function () {
+    return this.get('hosts').everyProperty('isRegionServer', true);
+  }.property('hosts.@each.isRegionServer'),
+
+  isAllClients: function () {
+    return this.get('hosts').everyProperty('isClient', true);
+  }.property('hosts.@each.isAllClient'),
+
+  isNoDataNodes: function () {
+    return this.get('hosts').everyProperty('isDataNode', false);
+  }.property('hosts.@each.isDataNode'),
+
+  isNoTaskTrackers: function () {
+    return this.get('hosts').everyProperty('isTaskTracker', false);
+  }.property('hosts.@each.isTaskTracker'),
+
+  isNoRegionServers: function () {
+    return this.get('hosts').everyProperty('isRegionServer', false);
+  }.property('hosts.@each.isRegionServer'),
+
+  isNoClients: function () {
+    return this.get('hosts').everyProperty('isClient', false);
+  }.property('hosts.@each.isClient'),
+
+  isHbaseSelected: function () {
+    var services = db.getSelectedServiceNames();
+    return this.get('selectedServiceNames').contains('HBASE');
+  },
+
+  isMrSelected: function () {
+    return this.get('selectedServiceNames').contains('MAPREDUCE');
+  }.property('selectedServiceNames'),
+
+  clearError: function () {
+    if (this.get('isNoDataNodes') === false && this.get('isNoTaskTrackers') === false && this.get('isNoRegionServers') === false && this.get('isNoClients') === false) {
+      this.set('errorMessage', '');
+    }
+  }.observes('isNoDataNodes', 'isNoTaskTrackers', 'isNoRegionServers', 'isNoClients'),
+
+  selectAllDataNodes: function () {
+    this.get('hosts').setEach('isDataNode', true);
+  },
+
+  selectAllTaskTrackers: function () {
+    this.get('hosts').setEach('isTaskTracker', true);
+  },
+
+  selectAllRegionServers: function () {
+    this.get('hosts').setEach('isRegionServer', true);
+  },
+
+  selectAllClients: function () {
+    this.get('hosts').setEach('isClient', true);
+  },
+
+  deselectAllDataNodes: function () {
+    this.get('hosts').setEach('isDataNode', false);
+  },
+
+  deselectAllTaskTrackers: function () {
+    this.get('hosts').setEach('isTaskTracker', false);
+  },
+
+  deselectAllRegionServers: function () {
+    this.get('hosts').setEach('isRegionServer', false);
+  },
+
+  deselectAllClients: function () {
+    this.get('hosts').setEach('isClient', false);
+  },
+
+  clearStep: function () {
+    this.set('hosts', []);
+    this.set('selectedServiceNames', []);
+    this.clearError();
+  },
+
+  loadStep: function () {
+    console.log("TRACE: Loading step6: Assign Slaves");
+    this.clearStep();
+    this.set('selectedServiceNames', db.getSelectedServiceNames());
+    this.set('showHbase', this.isHbaseSelected());
+    this.set('showTaskTracker', this.get('isMrSelected'));
+    this.setSlaveHost(this.getSlaveHosts());
+  },
+
+  getHostNames: function () {
+    var hostInfo = db.getHosts();
+    var hostNames = [];
+    for (var index in hostInfo) {
+      if (hostInfo[index].bootStatus === 'success')
+        hostNames.push(hostInfo[index].name);
+    }
+    return hostNames;
+  },
+
+  getSlaveHosts: function () {
+    var hostObjs = new Ember.Set();
+    var allHosts = this.getHostNames();
+    var slaveHosts = App.db.getSlaveComponentHosts();
+    if (slaveHosts === undefined || slaveHosts === null) {
+      allHosts.forEach(function (_hostname) {
+        var hostObj = {};
+        hostObj.hostname = _hostname;
+        hostObj.isMaster = this.hasMasterComponents(_hostname);
+        hostObj.isDataNode = !this.hasMasterComponents(_hostname);
+        hostObj.isTaskTracker = !this.hasMasterComponents(_hostname);
+        hostObj.isRegionServer = !this.hasMasterComponents(_hostname);
+        hostObj.isClient = false;
+        hostObjs.add(hostObj);
+      }, this);
+      hostObjs.findProperty('isDataNode', true).isClient = true;
+
+      return hostObjs;
+    } else {
+      allHosts.forEach(function (_hostName) {
+        hostObjs.add({
+          hostname: _hostName
+        });
+      }, this);
+      var datanodes = slaveHosts.findProperty('componentName', 'DATANODE');
+      datanodes.hosts.forEach(function (_datanode) {
+        var datanode = hostObjs.findProperty('hostname', _datanode.hostname);
+        if (datanode !== null) {
+          datanode.isDataNode = true;
+        }
+      }, this);
+      if (this.get('isMrSelected')) {
+        var taskTrackers = slaveHosts.findProperty('componentName', 'TASKTRACKER');
+        taskTrackers.hosts.forEach(function (_taskTracker) {
+          var taskTracker = hostObjs.findProperty('hostname', _taskTracker.hostname);
+          if (taskTracker !== null) {
+            taskTracker.isTaskTracker = true;
+          }
+        }, this);
+      }
+      if (this.isHbaseSelected()) {
+        var regionServers = slaveHosts.findProperty('componentName', 'HBASE_REGIONSERVER');
+        regionServers.hosts.forEach(function (_regionServer) {
+          var regionServer = hostObjs.findProperty('hostname', _regionServer.hostname);
+          if (regionServer !== null) {
+            regionServer.isRegionServer = true;
+          }
+        }, this);
+      }
+      var clients = slaveHosts.findProperty('componentName', 'CLIENT');
+      clients.hosts.forEach(function (_client) {
+        var client = hostObjs.findProperty('hostname', _client.hostname);
+        if (client !== null) {
+          client.isClient = true;
+        }
+      }, this);
+      allHosts.forEach(function (_hostname) {
+        var host = hostObjs.findProperty('hostname', _hostname);
+        if (host !== null) {
+          host.isMaster = this.hasMasterComponents(_hostname);
+        }
+      }, this);
+
+      return hostObjs;
+    }
+  },
+
+  getMasterComponentsforHost: function (hostname) {
+    if (App.db.getHostToMasterComponent().someProperty('hostname', hostname)) {
+      return App.db.getHostToMasterComponent().findProperty('hostname', hostname).components;
+    } else {
+      return false;
+    }
+  },
+
+  setSlaveHost: function (hostObj) {
+    hostObj.forEach(function (_hostObj) {
+      this.get('hosts').pushObject(Ember.Object.create(_hostObj));
+    }, this);
+  },
+
+  validate: function () {
+    return !(this.get('isNoDataNodes') || this.get('isNoTaskTrackers') || this.get('isNoRegionServers') || this.get('isNoClients'));
+  },
+
+  submit: function () {
+    if (!this.validate()) {
+      this.set('errorMessage', Ember.I18n.t('installer.step6.error.mustSelectOne'));
+      return;
+    }
+    App.db.setHostSlaveComponents(this.get('host'));
+
+    var dataNodeHosts = [];
+    var taskTrackerHosts = [];
+    var regionServerHosts = [];
+    var clientHosts = [];
+
+    this.get('hosts').forEach(function (host) {
+      if (host.get('isDataNode')) {
+        dataNodeHosts.push({
+          hostname: host.hostname,
+          group: 'Default'
+        });
+      }
+      if (this.get('isMrSelected') && host.get('isRegionServer')) {
+        taskTrackerHosts.push({
+          hostname: host.hostname,
+          group: 'Default'
+        });
+      }
+      if (this.isHbaseSelected() && host.get('isRegionServer')) {
+        regionServerHosts.push({
+          hostname: host.hostname,
+          group: 'Default'
+        });
+      }
+      if (host.get('isClient')) {
+        clientHosts.push({
+          hostname: host.hostname,
+          group: 'Default'
+        });
+      }
+    }, this);
+
+    var slaveComponentHosts = [];
+    slaveComponentHosts.push({
+      componentName: 'DATANODE',
+      displayName: 'DataNode',
+      hosts: dataNodeHosts
+    });
+    if (this.get('isMrSelected')) {
+      slaveComponentHosts.push({
+        componentName: 'TASKTRACKER',
+        displayName: 'TaskTracker',
+        hosts: taskTrackerHosts
+      });
+    }
+    if (this.isHbaseSelected()) {
+      slaveComponentHosts.push({
+        componentName: 'HBASE_REGIONSERVER',
+        displayName: 'RegionServer',
+        hosts: regionServerHosts
+      });
+    }
+    slaveComponentHosts.push({
+      componentName: 'CLIENT',
+      displayName: 'client',
+      hosts: clientHosts
+    });
+
+    App.db.setSlaveComponentHosts(slaveComponentHosts);
+
+    App.router.send('next');
+
+  }
+});

+ 267 - 268
ambari-web/app/messages.js

@@ -18,286 +18,285 @@
 
 
 Em.I18n.translations = {
 Em.I18n.translations = {
 
 
-  'app.name':'Ambari',
-
-  'login.header':'Sign in',
-  'login.username':'Username',
-  'login.password':'Password',
-  'login.loginButton':'Sign in',
-  'login.error':'Invalid username/password combination.',
-
-  'services.nagios.description':'Nagios desc',
-  'services.ganglia.description':'Ganglia desc',
-  'services.hdfs.description':'HDFS desc',
-  'services.mapreduce.description':'MapReduce desc',
-  'services.sqoop.description':'Sqoop desc',
-  'services.pig.description':'Pig desc',
-  'services.hive.description':'Hive/HCat desc',
-  'services.oozie.description':'Oozie desc',
-  'services.zookeeper.description':'ZooKeeper desc',
-  'services.hbase.description':'HBase desc',
-
-  'topnav.help.href':'http://incubator.apache.org/ambari/install.html',
-
-  'installer.header':'Cluster Install Wizard',
-  'installer.step1.header':'Welcome',
-  'installer.step1.body.header':'Welcome to Apache Ambari!',
-  'installer.step1.body':'Ambari makes it easy to install, manage, and monitor Hadoop clusters.<br>' +
+  'app.name': 'Ambari',
+
+  'login.header': 'Sign in',
+  'login.username': 'Username',
+  'login.password': 'Password',
+  'login.loginButton': 'Sign in',
+  'login.error': 'Invalid username/password combination.',
+
+  'services.nagios.description': 'Nagios desc',
+  'services.ganglia.description': 'Ganglia desc',
+  'services.hdfs.description': 'HDFS desc',
+  'services.mapreduce.description': 'MapReduce desc',
+  'services.sqoop.description': 'Sqoop desc',
+  'services.pig.description': 'Pig desc',
+  'services.hive.description': 'Hive/HCat desc',
+  'services.oozie.description': 'Oozie desc',
+  'services.zookeeper.description': 'ZooKeeper desc',
+  'services.hbase.description': 'HBase desc',
+
+  'topnav.help.href': 'http://incubator.apache.org/ambari/install.html',
+
+  'installer.header': 'Cluster Install Wizard',
+  'installer.step1.header': 'Welcome',
+  'installer.step1.body.header': 'Welcome to Apache Ambari!',
+  'installer.step1.body': 'Ambari makes it easy to install, manage, and monitor Hadoop clusters.<br>' +
     'We will walk you through the cluster installation process with this step-by-step wizard.',
     'We will walk you through the cluster installation process with this step-by-step wizard.',
-  'installer.step1.clusterName':'Name your cluster',
-  'installer.step1.clusterName.tooltip.title':'Cluster Name',
-  'installer.step1.clusterName.tooltip.content':'Enter a unique cluster name. Cluster name cannot be changed later.',
-  'installer.step1.clusterName.error.required':'Cluster Name is required',
-  'installer.step1.clusterName.error.whitespaces':'Cluster Name cannot contain white spaces',
-  'installer.step1.clusterName.error.specialChar':'Cluster Name cannot contain special characters',
-
-  'installer.step2.header':'Install Options',
-  'installer.step2.body':'Enter the list of hosts to be included in the cluster, provide your SSH key, and optionally specify a local repository.',
-  'installer.step2.targetHosts':'Target Hosts',
-  'installer.step2.targetHosts.info':'Enter a list of host names, one per line',
-  'installer.step2.hostPattern.tooltip.title':'Pattern Expressions',
-  'installer.step2.hostPattern.tooltip.content':'You can use pattern expressions to specify a number of target hosts.  Explain brackets.',
-  'installer.step2.hostName.error.required':'Host Names cannot be left empty',
-  'installer.step2.hostName.error.notRequired':'Host Names will be ignored if not using SSH to automatically configure hosts',
-  'installer.step2.hostName.error.invalid':'Invalid Host Name(s) - cannot start or end with a hyphen',
-  'installer.step2.sshKey':'Host Connectivity Information',
-  'installer.step2.sshKey.info':'Provide your SSH Private Key (<b>id_rsa</b> for <b>root</b>)',
-  'installer.step2.sshKey.error.required':'SSH Private Key is required',
-  'installer.step2.passphrase.error.match':'Passphrases do not match',
-  'installer.step2.manualInstall.label':'Do not use SSH to automatically configure hosts ',
-  'installer.step2.manualInstall.info':'By not using SSH to connect to the target hosts, you must manually install and start the ' +
+  'installer.step1.clusterName': 'Name your cluster',
+  'installer.step1.clusterName.tooltip.title': 'Cluster Name',
+  'installer.step1.clusterName.tooltip.content': 'Enter a unique cluster name. Cluster name cannot be changed later.',
+  'installer.step1.clusterName.error.required': 'Cluster Name is required',
+  'installer.step1.clusterName.error.whitespaces': 'Cluster Name cannot contain white spaces',
+  'installer.step1.clusterName.error.specialChar': 'Cluster Name cannot contain special characters',
+
+  'installer.step2.header': 'Install Options',
+  'installer.step2.body': 'Enter the list of hosts to be included in the cluster, provide your SSH key, and optionally specify a local repository.',
+  'installer.step2.targetHosts': 'Target Hosts',
+  'installer.step2.targetHosts.info': 'Enter a list of host names, one per line',
+  'installer.step2.hostPattern.tooltip.title': 'Pattern Expressions',
+  'installer.step2.hostPattern.tooltip.content': 'You can use pattern expressions to specify a number of target hosts.  Explain brackets.',
+  'installer.step2.hostName.error.required': 'Host Names cannot be left empty',
+  'installer.step2.hostName.error.notRequired': 'Host Names will be ignored if not using SSH to automatically configure hosts',
+  'installer.step2.hostName.error.invalid': 'Invalid Host Name(s) - cannot start or end with a hyphen',
+  'installer.step2.sshKey': 'Host Connectivity Information',
+  'installer.step2.sshKey.info': 'Provide your SSH Private Key (<b>id_rsa</b> for <b>root</b>)',
+  'installer.step2.sshKey.error.required': 'SSH Private Key is required',
+  'installer.step2.passphrase.error.match': 'Passphrases do not match',
+  'installer.step2.manualInstall.label': 'Do not use SSH to automatically configure hosts ',
+  'installer.step2.manualInstall.info': 'By not using SSH to connect to the target hosts, you must manually install and start the ' +
     'Ambari Agent on each host in order for the wizard to perform the necessary configurations and software installs.',
     'Ambari Agent on each host in order for the wizard to perform the necessary configurations and software installs.',
-  'installer.step2.advancedOption':'Advanced Options',
-  'installer.step2.repoConf':'Software Repository Configuration File Path',
-  'installer.step2.localRepo.header':'Software repository',
-  'installer.step2.localRepo.label':'Use a local software repository',
-  'installer.step2.localRepo.error.required':'Local repository file path is required',
-  'installer.step2.localRepo.info':'The repository configuration file should be installed on each host in your cluster. ' +
+  'installer.step2.advancedOption': 'Advanced Options',
+  'installer.step2.repoConf': 'Software Repository Configuration File Path',
+  'installer.step2.localRepo.header': 'Software repository',
+  'installer.step2.localRepo.label': 'Use a local software repository',
+  'installer.step2.localRepo.error.required': 'Local repository file path is required',
+  'installer.step2.localRepo.info': 'The repository configuration file should be installed on each host in your cluster. ' +
     'This file instructs the package manager to use your local software repository to retrieve software packages, instead of ' +
     'This file instructs the package manager to use your local software repository to retrieve software packages, instead of ' +
     'downloading them from the internet.',
     'downloading them from the internet.',
-  'installer.step2.localRepo.tooltip.title':'Local Software Repository',
-  'installer.step2.localRepo.tooltip.content':'The repository configuration file should be installed on each host ' +
+  'installer.step2.localRepo.tooltip.title': 'Local Software Repository',
+  'installer.step2.localRepo.tooltip.content': 'The repository configuration file should be installed on each host ' +
     'in your cluster. This file instructs package manager to use your local' +
     'in your cluster. This file instructs package manager to use your local' +
     'software repository to retrieve software packages, instead of using the internet.',
     'software repository to retrieve software packages, instead of using the internet.',
-  'installer.step2.manualInstall.tooltip.title':'Not Using SSH (Manual Install)',
-  'installer.step2.manualInstall.tooltip.content':'If you do not wish Ambari to automatically configure the target hosts via SSH,' +
+  'installer.step2.manualInstall.tooltip.title': 'Not Using SSH (Manual Install)',
+  'installer.step2.manualInstall.tooltip.content': 'If you do not wish Ambari to automatically configure the target hosts via SSH,' +
     ' you have the option of configuring them yourself.  This involves installing and starting Ambari Agent on each of your target hosts.',
     ' you have the option of configuring them yourself.  This involves installing and starting Ambari Agent on each of your target hosts.',
-  'installer.step2.manualInstall.popup.header':'Before You Proceed',
-  'installer.step2.manualInstall.popup.body':'You must install Ambari Agents on each host you want to manage before you proceed.  <a href="#" target="_blank">Learn more</a>',
+  'installer.step2.manualInstall.popup.header': 'Before You Proceed',
+  'installer.step2.manualInstall.popup.body': 'You must install Ambari Agents on each host you want to manage before you proceed.  <a href="#" target="_blank">Learn more</a>',
 
 
-  'installer.step3.header':'Confirm Hosts',
-  'installer.step3.body':'Here are the results of the host discovery process.<br>' +
+  'installer.step3.header': 'Confirm Hosts',
+  'installer.step3.body': 'Here are the results of the host discovery process.<br>' +
     'Please verify and remove the ones that you do not want to be part of the cluster.',
     'Please verify and remove the ones that you do not want to be part of the cluster.',
-  'installer.step3.hostLog.popup.header':'Log file for the host',
-  'installer.step3.hostLog.popup.body':'Placeholder for the log file',
-  'installer.step3.hosts.remove.popup.header':'Remove Hosts',
-  'installer.step3.hosts.remove.popup.body':'Are you sure you want to remove the selected host(s)?',
-  'installer.step3.hosts.retry.popup.header':'Retry Host Discovery',
-  'installer.step3.hosts.retry.popup.body':'Are you sure you want to retry discovery of the selected host(s)?',
-
-  'installer.step4.header':'Choose Services',
-  'installer.step4.body':'Choose which services you want to install on your cluster.<br>Note that some services have dependencies (e.g., HBase requires ZooKeeper.)',
-  'installer.step4.mapreduceCheck.popup.header':'MapReduce Needed',
-  'installer.step4.mapreduceCheck.popup.body':'You did not select MapReduce, but it is needed by other services you selected.  We will automatically add MapReduce.  Is this OK?',
-  'installer.step4.monitoringCheck.popup.header':'Limited Functionality Warning',
-  'installer.step4.monitoringCheck.popup.body':'You did not select Nagios and/or Ganglia.  If both are not selected, monitoring and alerts will not function properly.  Is this OK?',
-
-  'installer.step5.header':'Assign Masters',
-  'installer.step5.attention':' hosts not running master services',
-  'installer.step5.body':'Assign master components to hosts you want to run them on.',
-
-  'installer.step6.header':'Assign Slaves',
-  'installer.step6.body':'Assign slave components to hosts you want to run them on.',
-  'installer.step6.error.mustSelectOne':'You must assign at least one host to each.',
-
-  'installer.step7.header':'Customize Services',
-  'installer.step7.body':'We have come up with recommended configurations for the services you selected.  Customize them as you see fit.',
-  'installer.step7.attentionNeeded':'<strong>Attention:</strong> Some configurations need your attention before you can proceed.',
-
-  'installer.step8.header':'Review',
-  'installer.step8.body':'Please review the cluster configuration before installation',
-
-  'installer.step9.header':'Install, Start and Test',
-  'installer.step9.body':'Wait to complete the cluster installation. Installing, Starting and Testing selected services',
-  'installer.step9.status.success':'Successfully installed the cluster',
-  'installer.step9.status.failed':'Failure in installation',
-  'installer.step9.host.status.success':'success',
-  'installer.step9.host.status.warning':'tolerable failures encountered',
-  'installer.step9.host.status.failed':'failures encountered',
-
-  'installer.step10.header':'Summary',
-
-  'form.create':'Create',
-  'form.save':'Save',
-  'form.cancel':'Cancel',
-  'form.password':'Password',
-  'form.passwordRetype':'Retype Password',
-  'form.saveSuccess':'Successfully saved.',
-  'form.saveError':'Sorry, errors occured.',
-
-  'form.validator.invalidIp':'Please enter valid ip address',
-
-  'admin.advanced.title':'Advanced',
-  'admin.advanced.caution':'This section is for advanced user only.<br/>Proceed with caution.',
-  'admin.advanced.button.uninstallIncludingData':'Uninstall cluster including all data.',
-  'admin.advanced.button.uninstallKeepData':'Uninstall cluster but keep data.',
-
-  'admin.advanced.popup.header':'Uninstall Cluster',
+  'installer.step3.hostLog.popup.header': 'Log file for the host',
+  'installer.step3.hostLog.popup.body': 'Placeholder for the log file',
+  'installer.step3.hosts.remove.popup.header': 'Remove Hosts',
+  'installer.step3.hosts.remove.popup.body': 'Are you sure you want to remove the selected host(s)?',
+  'installer.step3.hosts.retry.popup.header': 'Retry Host Discovery',
+  'installer.step3.hosts.retry.popup.body': 'Are you sure you want to retry discovery of the selected host(s)?',
+
+  'installer.step4.header': 'Choose Services',
+  'installer.step4.body': 'Choose which services you want to install on your cluster.<br>Note that some services have dependencies (e.g., HBase requires ZooKeeper.)',
+  'installer.step4.mapreduceCheck.popup.header': 'MapReduce Needed',
+  'installer.step4.mapreduceCheck.popup.body': 'You did not select MapReduce, but it is needed by other services you selected.  We will automatically add MapReduce.  Is this OK?',
+  'installer.step4.monitoringCheck.popup.header': 'Limited Functionality Warning',
+  'installer.step4.monitoringCheck.popup.body': 'You did not select Nagios and/or Ganglia.  If both are not selected, monitoring and alerts will not function properly.  Is this OK?',
+
+  'installer.step5.header': 'Assign Masters',
+  'installer.step5.attention': ' hosts not running master services',
+  'installer.step5.body': 'Assign master components to hosts you want to run them on.',
+
+  'installer.step6.header': 'Assign Slaves and Clients',
+  'installer.step6.body': 'Assign slave and client components to hosts you want to run them on. <br/>Client component will install Hadoop client, HBase client and Pig client on the machine.',
+  'installer.step6.error.mustSelectOne': 'You must assign at least one host to each.',
+
+  'installer.step7.header': 'Customize Services',
+  'installer.step7.body': 'We have come up with recommended configurations for the services you selected.  Customize them as you see fit.',
+  'installer.step7.attentionNeeded': '<strong>Attention:</strong> Some configurations need your attention before you can proceed.',
+
+  'installer.step8.header': 'Review',
+  'installer.step8.body': 'Please review the cluster configuration before installation',
+
+  'installer.step9.header': 'Install, Start and Test',
+  'installer.step9.body': 'Wait to complete the cluster installation. Installing, Starting and Testing selected services',
+  'installer.step9.status.success': 'Successfully installed the cluster',
+  'installer.step9.status.failed': 'Failure in installation',
+  'installer.step9.host.status.success': 'success',
+  'installer.step9.host.status.warning': 'tolerable failures encountered',
+  'installer.step9.host.status.failed': 'failures encountered',
+  'installer.step10.header': 'Summary',
+  'form.create': 'Create',
+  'form.save': 'Save',
+  'form.cancel': 'Cancel',
+  'form.password': 'Password',
+  'form.passwordRetype': 'Retype Password',
+  'form.saveSuccess': 'Successfully saved.',
+  'form.saveError': 'Sorry, errors occured.',
+
+  'form.validator.invalidIp': 'Please enter valid ip address',
+
+  'admin.advanced.title': 'Advanced',
+  'admin.advanced.caution': 'This section is for advanced user only.<br/>Proceed with caution.',
+  'admin.advanced.button.uninstallIncludingData': 'Uninstall cluster including all data.',
+  'admin.advanced.button.uninstallKeepData': 'Uninstall cluster but keep data.',
+
+  'admin.advanced.popup.header': 'Uninstall Cluster',
+
   /*'admin.advanced.popup.text':'Uninstall Cluster',*/
   /*'admin.advanced.popup.text':'Uninstall Cluster',*/
 
 
-  'admin.audit.grid.date':"Date/Time",
-  'admin.audit.grid.category':"Category",
-  'admin.audit.grid.operationName':"Operation",
-  'admin.audit.grid.performedBy':"Performed By",
-  'admin.audit.grid.service':"Category",
-
-  'admin.authentication.form.method.database':'Use Ambari Database to authenticate users',
-  'admin.authentication.form.method.ldap':'Use LDAP/Active Directory to authenticate',
-  'admin.authentication.form.primaryServer':'Primary Server',
-  'admin.authentication.form.secondaryServer':'Secondary Server',
-  'admin.authentication.form.useSsl':'Use SSL',
-  'admin.authentication.form.bind.anonymously':"Bind Anonymously",
-  'admin.authentication.form.bind.useCrenedtials':"Use Credentials To Bind",
-  'admin.authentication.form.bindUserDN':'Bind User DN',
-  'admin.authentication.form.searchBaseDN':'Search Base DN',
-  'admin.authentication.form.usernameAttribute':'Username Attribute',
-
-  'admin.authentication.form.userDN':'User DN',
-  'admin.authentication.form.password':'Password',
-  'admin.authentication.form.configurationTest':'Configuration Test',
-  'admin.authentication.form.testConfiguration':'Test Configuration',
-
-  'admin.authentication.form.test.success':'The configuration passes the test',
-  'admin.authentication.form.test.fail':'The configuration fails the test',
-
-  'admin.security.title':'Kerberos Security has not been enabled on this cluster.',
-  'admin.security.button.enable':'Enable Kerberos Security on this cluster',
-
-  'admin.users.ldapAuthentionUsed':'LDAP Authentication is being used to authenticate users',
-  'admin.users.deleteYourselfMessage':'You can\'t delete yourself',
-  'admin.users.addButton':'Add User',
-  'admin.users.delete':'delete',
-  'admin.users.edit':'edit',
-  'admin.users.privileges':'Admin',
-  'admin.users.password':'Password',
-  'admin.users.passwordRetype':'Retype Password',
-  'admin.users.username':'Username',
-
-  'question.sure':'Are you sure?',
-
-  'services.service.start':'Start',
-  'services.service.stop':'Stop',
-  'services.service.start.popup.header':'Confirmation',
-  'services.service.stop.popup.header':'Confirmation',
-  'services.service.start.popup.body':'Are you sure?',
-  'services.service.stop.popup.body':'Are you sure?',
-  'services.service.summary.version':'Version',
-  'services.service.summary.nameNode':'NameNode Web UI',
-  'services.service.summary.nameNodeUptime':'NameNode Uptime',
-  'services.service.summary.nameNodeHeap':'NameNode Heap',
-  'services.service.summary.pendingUpgradeStatus':'Upgrade Status',
-  'services.service.summary.safeModeStatus':'Safe Mode Status',
-  'services.service.summary.dataNodes':'DataNodes',
-  'services.service.summary.diskCapacity':'HDFS Disk Capacity',
-  'services.service.summary.blocksTotal':'Blocks (total)',
-  'services.service.summary.blockErrors':'Block Errors',
-  'services.service.summary.totalFiles':'Total Files + Dirs',
-  'services.service.summary.jobTracker':'JobTracker Web UI',
-  'services.service.summary.jobTrackerUptime':'JobTracker Uptime',
-  'services.service.summary.trackersLiveTotal':'Trackers',
-  'services.service.summary.trackersBlacklistGraylist':'Trackers',
-  'services.service.summary.jobTrackerHeap':'JobTracker Heap',
-  'services.service.summary.totalSlotsCapacity':'Total Slots Capacity',
-  'services.service.summary.totalJobs':'Total Jobs',
-  'services.service.summary.currentSlotUtiliMaps':'Map Slots',
-  'services.service.summary.currentSlotUtiliReduces':'Reduce Slots',
-  'services.service.summary.tasksMaps':'Tasks: Maps',
-  'services.service.summary.tasksReduces':'Tasks: Reduces',
-  'services.service.summary.hbaseMaster':'HBase Master Web UI',
-  'services.service.summary.regionServerCount':'Region Server Count',
-  'services.service.summary.regionInTransition':'Region In Transition',
-  'services.service.summary.masterStarted':'Master Started',
-  'services.service.summary.masterActivated':'Master Activated',
-  'services.service.summary.averageLoad':'Average Load',
-  'services.service.summary.masterHeap':'Master Heap',
-  'services.service.summary.moreStats':'more stats here',
-
-  'hosts.host.start.popup.header':'Confirmation',
-  'hosts.host.stop.popup.header':'Confirmation',
-  'hosts.host.start.popup.body':'Are you sure?',
-  'hosts.host.stop.popup.body':'Are you sure?',
-  'hosts.assignedToRack.popup.body':'Are you sure?',
-  'hosts.assignedToRack.popup.header':'Confirmation',
-  'hosts.decommission.popup.body':'Are you sure?',
-  'hosts.decommission.popup.header':'Confirmation',
-  'hosts.delete.popup.body':'Are you sure?',
-  'hosts.delete.popup.header':'Confirmation',
-
-  'charts.horizon.chart.showText':'show',
-  'charts.horizon.chart.hideText':'hide',
-  'charts.horizon.chart.attributes.cpu':'CPU',
-  'charts.horizon.chart.attributes.memory':'Memory',
-  'charts.horizon.chart.attributes.network':'Network',
-  'charts.horizon.chart.attributes.io':'I/O',
-
-  'metric.default':'combined',
-  'metric.cpu':'cpu',
-  'metric.memory':'disk used',
-  'metric.network':'network',
-  'metric.io':'io',
-  'metric.more':'more',
-  'metric.more.cpu':'Cpu',
-
-  'metric.more.memory':'Memory',
+  'admin.audit.grid.date': "Date/Time",
+  'admin.audit.grid.category': "Category",
+  'admin.audit.grid.operationName': "Operation",
+  'admin.audit.grid.performedBy': "Performed By",
+  'admin.audit.grid.service': "Category",
+
+  'admin.authentication.form.method.database': 'Use Ambari Database to authenticate users',
+  'admin.authentication.form.method.ldap': 'Use LDAP/Active Directory to authenticate',
+  'admin.authentication.form.primaryServer': 'Primary Server',
+  'admin.authentication.form.secondaryServer': 'Secondary Server',
+  'admin.authentication.form.useSsl': 'Use SSL',
+  'admin.authentication.form.bind.anonymously': "Bind Anonymously",
+  'admin.authentication.form.bind.useCrenedtials': "Use Credentials To Bind",
+  'admin.authentication.form.bindUserDN': 'Bind User DN',
+  'admin.authentication.form.searchBaseDN': 'Search Base DN',
+  'admin.authentication.form.usernameAttribute': 'Username Attribute',
+
+  'admin.authentication.form.userDN': 'User DN',
+  'admin.authentication.form.password': 'Password',
+  'admin.authentication.form.configurationTest': 'Configuration Test',
+  'admin.authentication.form.testConfiguration': 'Test Configuration',
+
+  'admin.authentication.form.test.success': 'The configuration passes the test',
+  'admin.authentication.form.test.fail': 'The configuration fails the test',
+
+  'admin.security.title': 'Kerberos Security has not been enabled on this cluster.',
+  'admin.security.button.enable': 'Enable Kerberos Security on this cluster',
+
+  'admin.users.ldapAuthentionUsed': 'LDAP Authentication is being used to authenticate users',
+  'admin.users.deleteYourselfMessage': 'You can\'t delete yourself',
+  'admin.users.addButton': 'Add User',
+  'admin.users.delete': 'delete',
+  'admin.users.edit': 'edit',
+  'admin.users.privileges': 'Admin',
+  'admin.users.password': 'Password',
+  'admin.users.passwordRetype': 'Retype Password',
+  'admin.users.username': 'Username',
+
+  'question.sure': 'Are you sure?',
+
+  'services.service.start': 'Start',
+  'services.service.stop': 'Stop',
+  'services.service.start.popup.header': 'Confirmation',
+  'services.service.stop.popup.header': 'Confirmation',
+  'services.service.start.popup.body': 'Are you sure?',
+  'services.service.stop.popup.body': 'Are you sure?',
+  'services.service.summary.version': 'Version',
+  'services.service.summary.nameNode': 'NameNode Web UI',
+  'services.service.summary.nameNodeUptime': 'NameNode Uptime',
+  'services.service.summary.nameNodeHeap': 'NameNode Heap',
+  'services.service.summary.pendingUpgradeStatus': 'Upgrade Status',
+  'services.service.summary.safeModeStatus': 'Safe Mode Status',
+  'services.service.summary.dataNodes': 'DataNodes',
+  'services.service.summary.diskCapacity': 'HDFS Disk Capacity',
+  'services.service.summary.blocksTotal': 'Blocks (total)',
+  'services.service.summary.blockErrors': 'Block Errors',
+  'services.service.summary.totalFiles': 'Total Files + Dirs',
+  'services.service.summary.jobTracker': 'JobTracker Web UI',
+  'services.service.summary.jobTrackerUptime': 'JobTracker Uptime',
+  'services.service.summary.trackersLiveTotal': 'Trackers',
+  'services.service.summary.trackersBlacklistGraylist': 'Trackers',
+  'services.service.summary.jobTrackerHeap': 'JobTracker Heap',
+  'services.service.summary.totalSlotsCapacity': 'Total Slots Capacity',
+  'services.service.summary.totalJobs': 'Total Jobs',
+  'services.service.summary.currentSlotUtiliMaps': 'Map Slots',
+  'services.service.summary.currentSlotUtiliReduces': 'Reduce Slots',
+  'services.service.summary.tasksMaps': 'Tasks: Maps',
+  'services.service.summary.tasksReduces': 'Tasks: Reduces',
+  'services.service.summary.hbaseMaster': 'HBase Master Web UI',
+  'services.service.summary.regionServerCount': 'Region Server Count',
+  'services.service.summary.regionInTransition': 'Region In Transition',
+  'services.service.summary.masterStarted': 'Master Started',
+  'services.service.summary.masterActivated': 'Master Activated',
+  'services.service.summary.averageLoad': 'Average Load',
+  'services.service.summary.masterHeap': 'Master Heap',
+  'services.service.summary.moreStats': 'more stats here',
+
+  'hosts.host.start.popup.header': 'Confirmation',
+  'hosts.host.stop.popup.header': 'Confirmation',
+  'hosts.host.start.popup.body': 'Are you sure?',
+  'hosts.host.stop.popup.body': 'Are you sure?',
+  'hosts.assignedToRack.popup.body': 'Are you sure?',
+  'hosts.assignedToRack.popup.header': 'Confirmation',
+  'hosts.decommission.popup.body': 'Are you sure?',
+  'hosts.decommission.popup.header': 'Confirmation',
+  'hosts.delete.popup.body': 'Are you sure?',
+  'hosts.delete.popup.header': 'Confirmation',
+
+  'charts.horizon.chart.showText': 'show',
+  'charts.horizon.chart.hideText': 'hide',
+  'charts.horizon.chart.attributes.cpu': 'CPU',
+  'charts.horizon.chart.attributes.memory': 'Memory',
+  'charts.horizon.chart.attributes.network': 'Network',
+  'charts.horizon.chart.attributes.io': 'I/O',
+
+  'metric.default': 'combined',
+  'metric.cpu': 'cpu',
+  'metric.memory': 'disk used',
+  'metric.network': 'network',
+  'metric.io': 'io',
+  'metric.more': 'more',
+  'metric.more.cpu': 'Cpu',
+
+  'metric.more.memory': 'Memory',
   'metric.more.memory.swapFree': 'swap_free',
   'metric.more.memory.swapFree': 'swap_free',
   'metric.more.memory.memCached': 'mem_cached',
   'metric.more.memory.memCached': 'mem_cached',
 
 
-  'hosts.add.header':'Add Host Wizard',
-  'hosts.add.step2.warning':'Hosts are already part of the cluster and will be ignored',
-
-  'dashboard.services':'Services',
-  'dashboard.services.hosts':'Hosts',
-  'dashboard.services.uptime':'{0} days {1} hrs {2} mins',
-  'dashboard.services.hdfs.summary':'{0} of {1} nodes live, {2}% capacity free',
-  'dashboard.services.hdfs.capacity':'HDFS Capacity',
-  'dashboard.services.hdfs.capacityUsed':'{0} of {1} ({2}% used)',
-  'dashboard.services.hdfs.totalFilesAndDirs':'Total Files + Directories',
-  'dashboard.services.hdfs.nodes':'Data Nodes',
-  'dashboard.services.hdfs.nodes.live':'live',
-  'dashboard.services.hdfs.nodes.dead':'dead',
-  'dashboard.services.hdfs.nodes.decom':'decom',
-  'dashboard.services.hdfs.nodes.uptime':'NameNode Uptime',
-  'dashboard.services.hdfs.nodes.heap':'NameNode Heap',
-  'dashboard.services.hdfs.nodes.heapUsed':'{0} of {1}, {2}% used',
-  'dashboard.services.hdfs.chart.label':'Capacity (Free/Used)',
-
-  'dashboard.services.mapreduce.summary':'{0} of {1} trackers live, {2} jobs running',
-  'dashboard.services.mapreduce.trackers':'Trackers',
-  'dashboard.services.mapreduce.trackersSummary':'{0} live / {1} total',
-  'dashboard.services.mapreduce.jobs':'Jobs',
-  'dashboard.services.mapreduce.jobsSummary':'{0} running / {1} completed / {2} failed',
-  'dashboard.services.mapreduce.mapSlots':'Map Slots',
-  'dashboard.services.mapreduce.mapSlotsSummary':'{0} occuped / {1} reserved / {2} total',
-  'dashboard.services.mapreduce.reduceSlots':'Reduce Slots',
-  'dashboard.services.mapreduce.reduceSlotsSummary':'{0} occuped / {1} reserved / {2} total',
-  'dashboard.services.mapreduce.jobTrackerHeap':'JobTracker Heap',
-  'dashboard.services.mapreduce.jobTrackerHeapSummary':'{0} of {1} ({2}% used)',
-  'dashboard.services.mapreduce.jobTrackerUptime':'Job Trackers Uptime',
-  'dashboard.services.mapreduce.chart.label':'Jobs Running',
-
-  'dashboard.services.hbase.summary':'{0} of {1} region servers up, {2} average load',
-  'dashboard.services.hbase.masterServerHeap':'Master Server Heap',
-  'dashboard.services.hbase.masterServerHeap.summary':'{0} of {1} ({2}% used)',
-  'dashboard.services.hbase.masterServerUptime':'Master Server Uptime',
-  'dashboard.services.hbase.averageLoad':'Average Load',
-  'dashboard.services.hbase.regionServers':'Region Servers',
-  'dashboard.services.hbase.regionServersSummary':'{0} live / {1} total',
-  'dashboard.services.hbase.chart.label':'Request Count',
-
-  'timeRange.presets.1hour':'1h',
-  'timeRange.presets.12hour':'12h',
-  'timeRange.presets.1day':'1d',
-  'timeRange.presets.1week':'1wk',
-  'timeRange.presets.1month':'1mo',
-  'timeRange.presets.1year':'1yr'
+  'hosts.add.header': 'Add Host Wizard',
+  'hosts.add.step2.warning': 'Hosts are already part of the cluster and will be ignored',
+
+  'dashboard.services': 'Services',
+  'dashboard.services.hosts': 'Hosts',
+  'dashboard.services.uptime': '{0} days {1} hrs {2} mins',
+  'dashboard.services.hdfs.summary': '{0} of {1} nodes live, {2}% capacity free',
+  'dashboard.services.hdfs.capacity': 'HDFS Capacity',
+  'dashboard.services.hdfs.capacityUsed': '{0} of {1} ({2}% used)',
+  'dashboard.services.hdfs.totalFilesAndDirs': 'Total Files + Directories',
+  'dashboard.services.hdfs.nodes': 'Data Nodes',
+  'dashboard.services.hdfs.nodes.live': 'live',
+  'dashboard.services.hdfs.nodes.dead': 'dead',
+  'dashboard.services.hdfs.nodes.decom': 'decom',
+  'dashboard.services.hdfs.nodes.uptime': 'NameNode Uptime',
+  'dashboard.services.hdfs.nodes.heap': 'NameNode Heap',
+  'dashboard.services.hdfs.nodes.heapUsed': '{0} of {1}, {2}% used',
+  'dashboard.services.hdfs.chart.label': 'Capacity (Free/Used)',
+
+  'dashboard.services.mapreduce.summary': '{0} of {1} trackers live, {2} jobs running',
+  'dashboard.services.mapreduce.trackers': 'Trackers',
+  'dashboard.services.mapreduce.trackersSummary': '{0} live / {1} total',
+  'dashboard.services.mapreduce.jobs': 'Jobs',
+  'dashboard.services.mapreduce.jobsSummary': '{0} running / {1} completed / {2} failed',
+  'dashboard.services.mapreduce.mapSlots': 'Map Slots',
+  'dashboard.services.mapreduce.mapSlotsSummary': '{0} occuped / {1} reserved / {2} total',
+  'dashboard.services.mapreduce.reduceSlots': 'Reduce Slots',
+  'dashboard.services.mapreduce.reduceSlotsSummary': '{0} occuped / {1} reserved / {2} total',
+  'dashboard.services.mapreduce.jobTrackerHeap': 'JobTracker Heap',
+  'dashboard.services.mapreduce.jobTrackerHeapSummary': '{0} of {1} ({2}% used)',
+  'dashboard.services.mapreduce.jobTrackerUptime': 'Job Trackers Uptime',
+  'dashboard.services.mapreduce.chart.label': 'Jobs Running',
+
+  'dashboard.services.hbase.summary': '{0} of {1} region servers up, {2} average load',
+  'dashboard.services.hbase.masterServerHeap': 'Master Server Heap',
+  'dashboard.services.hbase.masterServerHeap.summary': '{0} of {1} ({2}% used)',
+  'dashboard.services.hbase.masterServerUptime': 'Master Server Uptime',
+  'dashboard.services.hbase.averageLoad': 'Average Load',
+  'dashboard.services.hbase.regionServers': 'Region Servers',
+  'dashboard.services.hbase.regionServersSummary': '{0} live / {1} total',
+  'dashboard.services.hbase.chart.label': 'Request Count',
+
+  'timeRange.presets.1hour': '1h',
+  'timeRange.presets.12hour': '12h',
+  'timeRange.presets.1day': '1d',
+  'timeRange.presets.1week': '1wk',
+  'timeRange.presets.1month': '1mo',
+  'timeRange.presets.1year': '1yr'
 };
 };

+ 6 - 5
ambari-web/app/routes/installer.js

@@ -26,7 +26,7 @@ module.exports = Em.Route.extend({
 
 
     if (router.getAuthenticated()) {
     if (router.getAuthenticated()) {
       console.log('In installer with successful authenticated');
       console.log('In installer with successful authenticated');
-     // router.loadAllPriorSteps(router.getInstallerCurrentStep());
+      // router.loadAllPriorSteps(router.getInstallerCurrentStep());
       Ember.run.next(function () {
       Ember.run.next(function () {
         router.transitionTo('step' + router.getInstallerCurrentStep());
         router.transitionTo('step' + router.getInstallerCurrentStep());
       });
       });
@@ -68,10 +68,10 @@ module.exports = Em.Route.extend({
       router.get('installerController').connectOutlet('installerStep1');
       router.get('installerController').connectOutlet('installerStep1');
     },
     },
     next: function (router, context) {
     next: function (router, context) {
-	   // App.db.setAllHostNames(undefined);
-	   // App.db.setInstallType(undefined);
-	   //App.db.setSoftRepo(undefined);
-	    router.transitionTo('step2');
+      // App.db.setAllHostNames(undefined);
+      // App.db.setInstallType(undefined);
+      //App.db.setSoftRepo(undefined);
+      router.transitionTo('step2');
     }
     }
   }),
   }),
 
 
@@ -124,6 +124,7 @@ module.exports = Em.Route.extend({
     back: Em.Router.transitionTo('step3'),
     back: Em.Router.transitionTo('step3'),
     next: function (router, context) {
     next: function (router, context) {
       App.db.setMasterComponentHosts(undefined);
       App.db.setMasterComponentHosts(undefined);
+      App.db.setHostToMasterComponent(undefined);
       router.transitionTo('step5');
       router.transitionTo('step5');
     }
     }
   }),
   }),

+ 60 - 23
ambari-web/app/styles/application.less

@@ -16,7 +16,7 @@
  * limitations under the License.
  * limitations under the License.
  */
  */
 
 
-.gradient(@color: #FAFAFA, @start: #FFFFFF, @stop: #F2F2F2) {
+.gradient(@color: #FAFAFA, @start: #FFFFFF, @stop: #F2F2F2){
   background: @color;
   background: @color;
   background: -webkit-gradient(linear, left top, left bottom, color-stop(0, @start), color-stop(1, @stop));
   background: -webkit-gradient(linear, left top, left bottom, color-stop(0, @start), color-stop(1, @stop));
   background: -ms-linear-gradient(top, @start, @stop);
   background: -ms-linear-gradient(top, @start, @stop);
@@ -49,7 +49,7 @@ footer {
 }
 }
 
 
 #content {
 #content {
-  padding: 30px 0;
+  padding: 20px 0;
 }
 }
 
 
 #top-nav {
 #top-nav {
@@ -139,7 +139,11 @@ footer {
     margin: 0;
     margin: 0;
   }
   }
 
 
-  margin-bottom: 30px;
+  margin-bottom: 20px;
+}
+
+.pre-scrollable {
+  overflow-y: auto;
 }
 }
 
 
 @green: #69BE28;
 @green: #69BE28;
@@ -164,11 +168,11 @@ h1 {
   }
   }
 }
 }
 
 
-.hide{
+.hide {
   visibility: hidden;
   visibility: hidden;
 }
 }
 
 
-.show{
+.show {
   visibility: visible;
   visibility: visible;
 }
 }
 
 
@@ -231,6 +235,9 @@ h1 {
     }
     }
     a.deselected {
     a.deselected {
     }
     }
+    i.icon-asterisks {
+      color: #FF4B4B;
+    }
   }
   }
   #serviceConfig {
   #serviceConfig {
     .accordion-heading {
     .accordion-heading {
@@ -553,18 +560,18 @@ a:focus {
 /*end alerts summary*/
 /*end alerts summary*/
 
 
 /*start cluster metrics*/
 /*start cluster metrics*/
-.cluster-metrics{
-  .chart-container{
+.cluster-metrics {
+  .chart-container {
     position: relative;
     position: relative;
     margin: 20px 15px 0px 15px;
     margin: 20px 15px 0px 15px;
   }
   }
-  .chart{
+  .chart {
     padding-bottom: 0px !important;
     padding-bottom: 0px !important;
     position: relative;
     position: relative;
     height: 160px;
     height: 160px;
     z-index: 1;
     z-index: 1;
   }
   }
-  .chart-y-axis{
+  .chart-y-axis {
     position: absolute;
     position: absolute;
     top: 0;
     top: 0;
     bottom: 0px;
     bottom: 0px;
@@ -572,28 +579,29 @@ a:focus {
     z-index: 2;
     z-index: 2;
     margin-top: 15px;
     margin-top: 15px;
   }
   }
-  .chart-x-axis{
+  .chart-x-axis {
     position: absolute;
     position: absolute;
     top: 180px;
     top: 180px;
     left: 35%;
     left: 35%;
     width: 30%;
     width: 30%;
     z-index: 2;
     z-index: 2;
   }
   }
-  .rickshaw_legend{
+  .rickshaw_legend {
     background-color: #999999 !important;
     background-color: #999999 !important;
   }
   }
-  .chart-overlay{
+  .chart-overlay {
     position: absolute;
     position: absolute;
     top: 0;
     top: 0;
     bottom: 0;
     bottom: 0;
     width: 100%;
     width: 100%;
     z-index: 5;
     z-index: 5;
   }
   }
-  .chart-title{
+  .chart-title {
     text-align: center;
     text-align: center;
     font-size: small;
     font-size: small;
   }
   }
 }
 }
+
 /*end cluster metrics*/
 /*end cluster metrics*/
 
 
 /*****end styles for dashboard page*****/
 /*****end styles for dashboard page*****/
@@ -1209,15 +1217,44 @@ ul.inline li {
 /* TIME RANGE WIDGET */
 /* TIME RANGE WIDGET */
 
 
 /* css for timepicker */
 /* css for timepicker */
-.ui-timepicker-div .ui-widget-header { margin-bottom: 8px; }
-.ui-timepicker-div dl { text-align: left; }
-.ui-timepicker-div dl dt { height: 25px; margin-bottom: -25px; }
-.ui-timepicker-div dl dd { margin: 0 10px 10px 65px; }
-.ui-timepicker-div td { font-size: 90%; }
-.ui-tpicker-grid-label { background: none; border: none; margin: 0; padding: 0; }
-
-.ui-timepicker-rtl{ direction: rtl; }
-.ui-timepicker-rtl dl { text-align: right; }
-.ui-timepicker-rtl dl dd { margin: 0 65px 10px 10px; }
+.ui-timepicker-div .ui-widget-header {
+  margin-bottom: 8px;
+}
+
+.ui-timepicker-div dl {
+  text-align: left;
+}
+
+.ui-timepicker-div dl dt {
+  height: 25px;
+  margin-bottom: -25px;
+}
+
+.ui-timepicker-div dl dd {
+  margin: 0 10px 10px 65px;
+}
+
+.ui-timepicker-div td {
+  font-size: 90%;
+}
+
+.ui-tpicker-grid-label {
+  background: none;
+  border: none;
+  margin: 0;
+  padding: 0;
+}
+
+.ui-timepicker-rtl {
+  direction: rtl;
+}
+
+.ui-timepicker-rtl dl {
+  text-align: right;
+}
+
+.ui-timepicker-rtl dl dd {
+  margin: 0 65px 10px 10px;
+}
 
 
 /* TIME RANGE WIDGET END */
 /* TIME RANGE WIDGET END */

+ 58 - 34
ambari-web/app/templates/installer/step6.hbs

@@ -23,41 +23,65 @@
   {{#if errorMessage}}
   {{#if errorMessage}}
   <div class="alert alert-error">{{errorMessage}}</div>
   <div class="alert alert-error">{{errorMessage}}</div>
   {{/if}}
   {{/if}}
-  <table class="table table-striped">
-    <thead>
-    <tr>
-      <th>Host</th>
-      <th>
-        <a href="#" {{bindAttr class="isAllDataNodes:selected:deselected"}} {{action selectAllDataNodes target="controller"}}>all</a> | <a href="#" {{bindAttr class="isNoDataNodes:selected:deselected"}} {{action deselectAllDataNodes target="controller"}}>none</a>
-      </th>
-      {{#if controller.isMrSelected}}
-      <th>
-        <a href="#" {{bindAttr class="isAllTaskTrackers:selected:deselected"}} {{action selectAllTaskTrackers target="controller"}}>all</a> | <a href="#" {{bindAttr class="isNoTaskTrackers:selected:deselected"}} {{action deselectAllTaskTrackers target="controller"}}>none</a>
-      </th>
-      {{/if}}
-      {{#if showHbase}}
-      <th>
-        <a href="#" {{bindAttr class="isAllRegionServers:selected:deselected"}} {{action selectAllRegionServers target="controller"}}>all</a> | <a href="#" {{bindAttr class="isNoRegionServers:selected:deselected"}} {{action deselectAllRegionServers target="controller"}}>none</a>
-      </th>
-      {{/if}}
-    </tr>
-    </thead>
-    <tbody>
 
 
-    {{#each hosts}}
-    <tr>
-      <td>{{hostname}}</td>
-      <td><label class="checkbox">{{view Ember.Checkbox checkedBinding="isDataNode"}}DataNode</label></td>
-      {{#if controller.isMrSelected}}
-      <td><label class="checkbox">{{view Ember.Checkbox checkedBinding="isTaskTracker"}}TaskTracker</label></td>
-      {{/if}}
-      {{#if controller.showHbase}}
-      <td><label class="checkbox">{{view Ember.Checkbox checkedBinding="isRegionServer"}}RegionServer</label></td>
-      {{/if}}
-    </tr>
-    {{/each}}
-    </tbody>
-  </table>
+  <div class="pre-scrollable" style="max-height: 440px;">
+    <table class="table table-striped">
+      <thead>
+      <tr>
+        <th>Host</th>
+        <th>
+          <a
+            href="#" {{bindAttr class="isAllDataNodes:selected:deselected"}} {{action selectAllDataNodes target="controller"}}>all</a>
+          |
+          <a
+            href="#" {{bindAttr class="isNoDataNodes:selected:deselected"}} {{action deselectAllDataNodes target="controller"}}>none</a>
+        </th>
+        {{#if controller.isMrSelected}}
+        <th>
+          <a
+            href="#" {{bindAttr class="isAllTaskTrackers:selected:deselected"}} {{action selectAllTaskTrackers target="controller"}}>all</a>
+          |
+          <a
+            href="#" {{bindAttr class="isNoTaskTrackers:selected:deselected"}} {{action deselectAllTaskTrackers target="controller"}}>none</a>
+        </th>
+        {{/if}}
+        {{#if showHbase}}
+        <th>
+          <a
+            href="#" {{bindAttr class="isAllRegionServers:selected:deselected"}} {{action selectAllRegionServers target="controller"}}>all</a>
+          |
+          <a
+            href="#" {{bindAttr class="isNoRegionServers:selected:deselected"}} {{action deselectAllRegionServers target="controller"}}>none</a>
+        </th>
+        {{/if}}
+        <th>
+          <a
+            href="#" {{bindAttr class="isAllClients:selected:deselected"}} {{action selectAllClients target="controller"}}>all</a>
+          |
+          <a
+            href="#" {{bindAttr class="isNoClients:selected:deselected"}} {{action deselectAllClients target="controller"}}>none</a>
+        </th>
+      </tr>
+      </thead>
+      <tbody>
+
+      {{#each hosts}}
+      <tr>
+        <td>{{#view App.InstallerStep6HostView hostBinding = "this" }} {{hostname}} {{#if isMaster}}<i
+          class=icon-asterisks>&#10037</i>{{/if}}{{/view}} </td>
+        <td><label class="checkbox">{{view Ember.Checkbox checkedBinding="isDataNode"}}DataNode</label></td>
+        {{#if controller.isMrSelected}}
+        <td><label class="checkbox">{{view Ember.Checkbox checkedBinding="isTaskTracker"}}TaskTracker</label></td>
+        {{/if}}
+        {{#if controller.showHbase}}
+        <td><label class="checkbox">{{view Ember.Checkbox checkedBinding="isRegionServer"}}RegionServer</label></td>
+        {{/if}}
+        <td><label class="checkbox">{{view Ember.Checkbox checkedBinding="isClient"}}Client</label></td>
+      </tr>
+      {{/each}}
+      </tbody>
+    </table>
+  </div>
   <div class="btn-area">
   <div class="btn-area">
     <a class="btn" {{action back}}>&larr; Back</a>
     <a class="btn" {{action back}}>&larr; Back</a>
     <a class="btn btn-success" style="float:right" {{action submit target="controller"}}>Next &rarr;</a>
     <a class="btn btn-success" style="float:right" {{action submit target="controller"}}>Next &rarr;</a>

+ 19 - 11
ambari-web/app/utils/db.js

@@ -61,12 +61,10 @@ if (localStorage.getObject('ambari') == null) {
   App.db.cleanUp();
   App.db.cleanUp();
 }
 }
 
 
-
 /*
 /*
  * setter methods
  * setter methods
  */
  */
 
 
-
 App.db.setLoginName = function (name) {
 App.db.setLoginName = function (name) {
   console.log('TRACE: Entering db:setLoginName function');
   console.log('TRACE: Entering db:setLoginName function');
   App.db.data = localStorage.getObject('ambari');
   App.db.data = localStorage.getObject('ambari');
@@ -189,7 +187,7 @@ App.db.setSoftRepo = function (softRepo) {
   localStorage.setObject('ambari', App.db.data);
   localStorage.setObject('ambari', App.db.data);
 }
 }
 
 
-App.db.setBootStatus = function(status) {
+App.db.setBootStatus = function (status) {
   console.log('TRACE: Entering db:setService function');
   console.log('TRACE: Entering db:setService function');
   App.db.data = localStorage.getObject('ambari');
   App.db.data = localStorage.getObject('ambari');
   var user = App.db.data.app.loginName;
   var user = App.db.data.app.loginName;
@@ -207,7 +205,7 @@ App.db.removeHosts = function (hostInfo) {
   App.db.setHosts(hostList);
   App.db.setHosts(hostList);
 }
 }
 
 
-App.db.setService = function(serviceInfo) {
+App.db.setService = function (serviceInfo) {
   console.log('TRACE: Entering db:setService function');
   console.log('TRACE: Entering db:setService function');
   App.db.data = localStorage.getObject('ambari');
   App.db.data = localStorage.getObject('ambari');
   var user = App.db.data.app.loginName;
   var user = App.db.data.app.loginName;
@@ -229,6 +227,12 @@ App.db.setMasterComponentHosts = function (masterComponentHosts) {
   localStorage.setObject('ambari', App.db.data);
   localStorage.setObject('ambari', App.db.data);
 }
 }
 
 
+App.db.setHostToMasterComponent = function (hostToMasterComponent) {
+  App.db.data = localStorage.getObject('ambari');
+  var user = App.db.data.app.loginName;
+  App.db.data[user].Installer.hostToMasterComponent = hostToMasterComponent;
+  localStorage.setObject('ambari', App.db.data);
+}
 
 
 App.db.setHostSlaveComponents = function (hostSlaveComponents) {
 App.db.setHostSlaveComponents = function (hostSlaveComponents) {
   App.db.data = localStorage.getObject('ambari');
   App.db.data = localStorage.getObject('ambari');
@@ -244,7 +248,7 @@ App.db.setSlaveComponentHosts = function (slaveComponentHosts) {
   localStorage.setObject('ambari', App.db.data);
   localStorage.setObject('ambari', App.db.data);
 }
 }
 
 
-App.db.setServiceConfigs = function(serviceConfigs) {
+App.db.setServiceConfigs = function (serviceConfigs) {
   App.db.data = localStorage.getObject('ambari');
   App.db.data = localStorage.getObject('ambari');
   var user = App.db.data.app.loginName;
   var user = App.db.data.app.loginName;
   App.db.data[user].Installer.serviceConfigs = serviceConfigs;
   App.db.data[user].Installer.serviceConfigs = serviceConfigs;
@@ -265,7 +269,6 @@ App.db.setClusterStatus = function (status) {
   localStorage.setObject('ambari', App.db.data);
   localStorage.setObject('ambari', App.db.data);
 }
 }
 
 
-
 /*
 /*
  *  getter methods
  *  getter methods
  */
  */
@@ -391,14 +394,14 @@ App.db.getHosts = function () {
   return App.db.data[user].Installer.hostInfo;
   return App.db.data[user].Installer.hostInfo;
 }
 }
 
 
-App.db.getBootStatus = function() {
+App.db.getBootStatus = function () {
   console.log('TRACE: Entering db:setService function');
   console.log('TRACE: Entering db:setService function');
   App.db.data = localStorage.getObject('ambari');
   App.db.data = localStorage.getObject('ambari');
   var user = App.db.data.app.loginName;
   var user = App.db.data.app.loginName;
   return App.db.data[user].Installer.bootStatus;
   return App.db.data[user].Installer.bootStatus;
 }
 }
 
 
-App.db.getService = function() {
+App.db.getService = function () {
   console.log('TRACE: Entering db:getService function');
   console.log('TRACE: Entering db:getService function');
   App.db.data = localStorage.getObject('ambari');
   App.db.data = localStorage.getObject('ambari');
   var user = App.db.data.app.loginName;
   var user = App.db.data.app.loginName;
@@ -417,6 +420,12 @@ App.db.getMasterComponentHosts = function () {
   return App.db.data[user].Installer.masterComponentHosts;
   return App.db.data[user].Installer.masterComponentHosts;
 }
 }
 
 
+App.db.getHostToMasterComponent = function () {
+  App.db.data = localStorage.getObject('ambari');
+  var user = App.db.data.app.loginName;
+  return App.db.data[user].Installer.hostToMasterComponent;
+}
+
 App.db.getHostSlaveComponents = function () {
 App.db.getHostSlaveComponents = function () {
   App.db.data = localStorage.getObject('ambari');
   App.db.data = localStorage.getObject('ambari');
   var user = App.db.data.app.loginName;
   var user = App.db.data.app.loginName;
@@ -429,7 +438,7 @@ App.db.getSlaveComponentHosts = function () {
   return App.db.data[user].Installer.slaveComponentHosts;
   return App.db.data[user].Installer.slaveComponentHosts;
 }
 }
 
 
-App.db.getServiceConfigs = function() {
+App.db.getServiceConfigs = function () {
   App.db.data = localStorage.getObject('ambari');
   App.db.data = localStorage.getObject('ambari');
   var user = App.db.data.app.loginName;
   var user = App.db.data.app.loginName;
   return App.db.data[user].Installer.serviceConfigs;
   return App.db.data[user].Installer.serviceConfigs;
@@ -441,12 +450,11 @@ App.db.getServiceConfigProperties = function () {
   return App.db.data[user].Installer.configProperties;
   return App.db.data[user].Installer.configProperties;
 }
 }
 
 
-App.db.getClusterStatus = function() {
+App.db.getClusterStatus = function () {
   console.log('TRACE: Entering db:setService function');
   console.log('TRACE: Entering db:setService function');
   App.db.data = localStorage.getObject('ambari');
   App.db.data = localStorage.getObject('ambari');
   var user = App.db.data.app.loginName;
   var user = App.db.data.app.loginName;
   return App.db.data[user].Installer.clusterStatus;
   return App.db.data[user].Installer.clusterStatus;
 }
 }
 
 
-
 module.exports = App.db;
 module.exports = App.db;

+ 20 - 1
ambari-web/app/views/installer/step6_view.js

@@ -22,10 +22,29 @@ var App = require('app');
 App.InstallerStep6View = Em.View.extend({
 App.InstallerStep6View = Em.View.extend({
 
 
   templateName: require('templates/installer/step6'),
   templateName: require('templates/installer/step6'),
-
   didInsertElement: function () {
   didInsertElement: function () {
     var controller = this.get('controller');
     var controller = this.get('controller');
     controller.loadStep();
     controller.loadStep();
   }
   }
 
 
+});
+
+App.InstallerStep6HostView = Em.View.extend({
+
+  host: null,
+  didInsertElement: function (event, context) {
+    var self = this;
+    var components = this.get('controller').getMasterComponentsforHost(this.get('host.hostname')).toString();
+    components = components.replace(/,/g, " /\n");
+    if (components === 'false') {
+      return;
+    } else {
+      this.$().popover({
+        title: 'master components hosted on ' + self.get('host.hostname'),
+        content: components,
+        placement: 'right',
+        trigger: 'hover'
+      });
+    }
+  }
 });
 });