Repository: ambari Updated Branches: refs/heads/trunk 565dc0de8 -> 39c04ac9b
https://issues.apache.org/jira/browse/AMBARI-13450. AMBARI-13450 Bootstrap Cluster via different SSH Port Number (Selim Ozcan via aonishuk) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/39c04ac9 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/39c04ac9 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/39c04ac9 Branch: refs/heads/trunk Commit: 39c04ac9b44f4eb1035b378337d745d77ee83d53 Parents: 565dc0d Author: Andrew Onishuk <aonis...@hortonworks.com> Authored: Thu Oct 22 16:08:48 2015 +0300 Committer: Andrew Onishuk <aonis...@hortonworks.com> Committed: Thu Oct 22 16:08:48 2015 +0300 ---------------------------------------------------------------------- .../ambari/server/bootstrap/BSRunner.java | 28 +++-- .../ambari/server/bootstrap/SshHostInfo.java | 7 ++ ambari-server/src/main/python/bootstrap.py | 66 ++++++------ ambari-server/src/test/python/TestBootstrap.py | 102 +++++++++---------- ambari-web/app/controllers/wizard.js | 2 + .../app/controllers/wizard/step2_controller.js | 25 ++++- .../app/controllers/wizard/step3_controller.js | 2 + ambari-web/app/messages.js | 3 + ambari-web/app/styles/application.less | 4 + ambari-web/app/templates/wizard/step2.hbs | 12 +++ .../test/controllers/wizard/step2_test.js | 45 ++++++++ .../test/controllers/wizard/step3_test.js | 4 + 12 files changed, 205 insertions(+), 95 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/39c04ac9/ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BSRunner.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BSRunner.java b/ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BSRunner.java index 0a55131..44faa4f 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BSRunner.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BSRunner.java @@ -41,6 +41,7 @@ class BSRunner extends Thread { private static Log LOG = LogFactory.getLog(BSRunner.class); private static final String DEFAULT_USER = "root"; + private static final String DEFAULT_SSHPORT = "22"; private boolean finished = false; private SshHostInfo sshHostInfo; @@ -164,7 +165,13 @@ class BSRunner extends Thread { if (user == null || user.isEmpty()) { user = DEFAULT_USER; } - String command[] = new String[12]; + + String sshPort = sshHostInfo.getSshPort(); + if(sshPort == null || sshPort.isEmpty()){ + sshPort = DEFAULT_SSHPORT; + } + + String command[] = new String[13]; BSStat stat = BSStat.RUNNING; String scriptlog = ""; try { @@ -194,14 +201,15 @@ class BSRunner extends Thread { command[1] = hostString; command[2] = this.requestIdDir.toString(); command[3] = user; - command[4] = this.sshKeyFile.toString(); - command[5] = this.agentSetupScript.toString(); - command[6] = this.ambariHostname; - command[7] = this.clusterOsFamily; - command[8] = this.projectVersion; - command[9] = this.serverPort+""; - command[10] = userRunAs; - command[11] = (this.passwordFile==null) ? "null" : this.passwordFile.toString(); + command[4] = sshPort; + command[5] = this.sshKeyFile.toString(); + command[6] = this.agentSetupScript.toString(); + command[7] = this.ambariHostname; + command[8] = this.clusterOsFamily; + command[9] = this.projectVersion; + command[10] = this.serverPort+""; + command[11] = userRunAs; + command[12] = (this.passwordFile==null) ? "null" : this.passwordFile.toString(); Map<String, String> envVariables = new HashMap<String, String>(); @@ -218,7 +226,7 @@ class BSRunner extends Thread { } LOG.info("Host= " + hostString + " bs=" + this.bsScript + " requestDir=" + - requestIdDir + " user=" + user + " keyfile=" + this.sshKeyFile + + requestIdDir + " user=" + user + " sshPort=" + sshPort + " keyfile=" + this.sshKeyFile + " passwordFile " + this.passwordFile + " server=" + this.ambariHostname + " version=" + projectVersion + " serverPort=" + this.serverPort + " userRunAs=" + userRunAs); http://git-wip-us.apache.org/repos/asf/ambari/blob/39c04ac9/ambari-server/src/main/java/org/apache/ambari/server/bootstrap/SshHostInfo.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/bootstrap/SshHostInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/bootstrap/SshHostInfo.java index 822e972..9a7490f 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/bootstrap/SshHostInfo.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/bootstrap/SshHostInfo.java @@ -49,6 +49,9 @@ public class SshHostInfo { private String user; @XmlElement + private String sshPort; + + @XmlElement private String password; @XmlElement @@ -86,6 +89,10 @@ public class SshHostInfo { this.user = user; } + public String getSshPort(){ return sshPort; } + + public void setSshPort(String sshPort){ this.sshPort = sshPort; } + public String getPassword() { return password; } http://git-wip-us.apache.org/repos/asf/ambari/blob/39c04ac9/ambari-server/src/main/python/bootstrap.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/python/bootstrap.py b/ambari-server/src/main/python/bootstrap.py index 3eba75c..75bb26a 100755 --- a/ambari-server/src/main/python/bootstrap.py +++ b/ambari-server/src/main/python/bootstrap.py @@ -74,8 +74,9 @@ class HostLog: class SCP: """ SCP implementation that is thread based. The status can be returned using status val """ - def __init__(self, user, sshkey_file, host, inputFile, remote, bootdir, host_log): + def __init__(self, user, sshPort, sshkey_file, host, inputFile, remote, bootdir, host_log): self.user = user + self.sshPort = sshPort self.sshkey_file = sshkey_file self.host = host self.inputFile = inputFile @@ -90,7 +91,7 @@ class SCP: "-r", "-o", "ConnectTimeout=60", "-o", "BatchMode=yes", - "-o", "StrictHostKeyChecking=no", + "-o", "StrictHostKeyChecking=no", "-P", self.sshPort, "-i", self.sshkey_file, self.inputFile, self.user + "@" + self.host + ":" + self.remote] if DEBUG: @@ -111,8 +112,9 @@ class SCP: class SSH: """ Ssh implementation of this """ - def __init__(self, user, sshkey_file, host, command, bootdir, host_log, errorMessage = None): + def __init__(self, user, sshPort, sshkey_file, host, command, bootdir, host_log, errorMessage = None): self.user = user + self.sshPort = sshPort self.sshkey_file = sshkey_file self.host = host self.command = command @@ -128,7 +130,7 @@ class SSH: "-o", "StrictHostKeyChecking=no", "-o", "BatchMode=yes", "-tt", # Should prevent "tput: No value for $TERM and no -T specified" warning - "-i", self.sshkey_file, + "-i", self.sshkey_file, "-p", self.sshPort, self.user + "@" + self.host, self.command] if DEBUG: self.host_log.write("Running ssh command " + ' '.join(sshcommand)) @@ -454,7 +456,7 @@ class BootstrapDefault(Bootstrap): params = self.shared_state self.host_log.write("==========================\n") self.host_log.write("Copying OS type check script...") - scp = SCP(params.user, params.sshkey_file, self.host, fileToCopy, + scp = SCP(params.user, params.sshPort, params.sshkey_file, self.host, fileToCopy, target, params.bootdir, self.host_log) result = scp.run() self.host_log.write("\n") @@ -467,7 +469,7 @@ class BootstrapDefault(Bootstrap): params = self.shared_state self.host_log.write("==========================\n") self.host_log.write("Copying common functions script...") - scp = SCP(params.user, params.sshkey_file, self.host, fileToCopy, + scp = SCP(params.user, params.sshPort, params.sshkey_file, self.host, fileToCopy, target, params.bootdir, self.host_log) result = scp.run() self.host_log.write("\n") @@ -507,7 +509,7 @@ class BootstrapDefault(Bootstrap): if (os.path.exists(fileToCopy)): self.host_log.write("==========================\n") self.host_log.write("Copying repo file to 'tmp' folder...") - scp = SCP(params.user, params.sshkey_file, self.host, fileToCopy, + scp = SCP(params.user, params.sshPort, params.sshkey_file, self.host, fileToCopy, target, params.bootdir, self.host_log) retcode1 = scp.run() self.host_log.write("\n") @@ -517,7 +519,7 @@ class BootstrapDefault(Bootstrap): self.host_log.write("Moving file to repo dir...") targetDir = self.getRepoDir() command = self.getMoveRepoFileCommand(targetDir) - ssh = SSH(params.user, params.sshkey_file, self.host, command, + ssh = SSH(params.user, params.sshPort, params.sshkey_file, self.host, command, params.bootdir, self.host_log) retcode2 = ssh.run() self.host_log.write("\n") @@ -526,7 +528,7 @@ class BootstrapDefault(Bootstrap): self.host_log.write("==========================\n") self.host_log.write("Changing permissions for ambari.repo...") command = self.getRepoFileChmodCommand() - ssh = SSH(params.user, params.sshkey_file, self.host, command, + ssh = SSH(params.user, params.sshPort, params.sshkey_file, self.host, command, params.bootdir, self.host_log) retcode4 = ssh.run() self.host_log.write("\n") @@ -536,7 +538,7 @@ class BootstrapDefault(Bootstrap): self.host_log.write("==========================\n") self.host_log.write("Update apt cache of repository...") command = self.getAptUpdateCommand() - ssh = SSH(params.user, params.sshkey_file, self.host, command, + ssh = SSH(params.user, params.sshPort, params.sshkey_file, self.host, command, params.bootdir, self.host_log) retcode2 = ssh.run() self.host_log.write("\n") @@ -554,7 +556,7 @@ class BootstrapDefault(Bootstrap): self.host_log.write("Copying setup script file...") fileToCopy = params.setup_agent_file target = self.getRemoteName(self.SETUP_SCRIPT_FILENAME) - scp = SCP(params.user, params.sshkey_file, self.host, fileToCopy, + scp = SCP(params.user, params.sshPort, params.sshkey_file, self.host, fileToCopy, target, params.bootdir, self.host_log) retcode3 = scp.run() self.host_log.write("\n") @@ -600,7 +602,7 @@ class BootstrapDefault(Bootstrap): (self.getOsCheckScriptRemoteLocation(), PYTHON_ENV, self.getOsCheckScriptRemoteLocation(), params.cluster_os_type) - ssh = SSH(params.user, params.sshkey_file, self.host, command, + ssh = SSH(params.user, params.sshPort, params.sshkey_file, self.host, command, params.bootdir, self.host_log) retcode = ssh.run() self.host_log.write("\n") @@ -615,7 +617,7 @@ class BootstrapDefault(Bootstrap): command = "dpkg --get-selections|grep -e '^sudo\s*install'" else: command = "rpm -qa | grep -e '^sudo\-'" - ssh = SSH(params.user, params.sshkey_file, self.host, command, + ssh = SSH(params.user, params.sshPort, params.sshkey_file, self.host, command, params.bootdir, self.host_log, errorMessage="Error: Sudo command is not available. " "Please install the sudo command.") @@ -627,7 +629,7 @@ class BootstrapDefault(Bootstrap): # Copy the password file self.host_log.write("Copying password file to 'tmp' folder...") params = self.shared_state - scp = SCP(params.user, params.sshkey_file, self.host, params.password_file, + scp = SCP(params.user, params.sshPort, params.sshkey_file, self.host, params.password_file, self.getPasswordFile(), params.bootdir, self.host_log) retcode1 = scp.run() @@ -636,7 +638,7 @@ class BootstrapDefault(Bootstrap): # Change password file mode to 600 self.host_log.write("Changing password file mode...") command = "chmod 600 " + self.getPasswordFile() - ssh = SSH(params.user, params.sshkey_file, self.host, command, + ssh = SSH(params.user, params.sshPort, params.sshkey_file, self.host, command, params.bootdir, self.host_log) retcode2 = ssh.run() @@ -648,7 +650,7 @@ class BootstrapDefault(Bootstrap): self.host_log.write("Changing password file mode...") params = self.shared_state command = "chmod 600 " + self.getPasswordFile() - ssh = SSH(params.user, params.sshkey_file, self.host, command, + ssh = SSH(params.user, params.sshPort, params.sshkey_file, self.host, command, params.bootdir, self.host_log) retcode = ssh.run() self.host_log.write("Change password file mode on host finished") @@ -659,7 +661,7 @@ class BootstrapDefault(Bootstrap): self.host_log.write("Deleting password file...") params = self.shared_state command = "rm " + self.getPasswordFile() - ssh = SSH(params.user, params.sshkey_file, self.host, command, + ssh = SSH(params.user, params.sshPort, params.sshkey_file, self.host, command, params.bootdir, self.host_log) retcode = ssh.run() self.host_log.write("Deleting password file finished") @@ -675,7 +677,7 @@ class BootstrapDefault(Bootstrap): command = "sudo mkdir -p {0} ; sudo chown -R {1} {0} ; sudo chmod 755 {3} ; sudo chmod 755 {2} ; sudo chmod 777 {0}".format( self.TEMP_FOLDER, quote_bash_args(params.user), DEFAULT_AGENT_DATA_FOLDER, DEFAULT_AGENT_LIB_FOLDER) - ssh = SSH(params.user, params.sshkey_file, self.host, command, + ssh = SSH(params.user, params.sshPort, params.sshkey_file, self.host, command, params.bootdir, self.host_log) retcode = ssh.run() self.host_log.write("\n") @@ -692,7 +694,7 @@ class BootstrapDefault(Bootstrap): self.host_log.write("==========================\n") self.host_log.write("Running setup agent script...") command = self.getRunSetupCommand(self.host) - ssh = SSH(params.user, params.sshkey_file, self.host, command, + ssh = SSH(params.user, params.sshPort, params.sshkey_file, self.host, command, params.bootdir, self.host_log) retcode = ssh.run() self.host_log.write("\n") @@ -791,11 +793,12 @@ class PBootstrap: class SharedState: - def __init__(self, user, sshkey_file, script_dir, boottmpdir, setup_agent_file, + def __init__(self, user, sshPort, sshkey_file, script_dir, boottmpdir, setup_agent_file, ambari_server, cluster_os_type, ambari_version, server_port, user_run_as, password_file = None): self.hostlist_to_remove_password_file = None self.user = user + self.sshPort = sshPort self.sshkey_file = sshkey_file self.bootdir = boottmpdir self.script_dir = script_dir @@ -817,7 +820,7 @@ def main(argv=None): onlyargs = argv[1:] if len(onlyargs) < 3: sys.stderr.write("Usage: <comma separated hosts> " - "<tmpdir for storage> <user> <sshkey_file> <agent setup script>" + "<tmpdir for storage> <user> <sshPort> <sshkey_file> <agent setup script>" " <ambari-server name> <cluster os type> <ambari version> <ambari port> <user_run_as> <passwordFile>\n") sys.exit(2) pass @@ -827,14 +830,15 @@ def main(argv=None): hostList = onlyargs[0].split(",") bootdir = onlyargs[1] user = onlyargs[2] - sshkey_file = onlyargs[3] - setupAgentFile = onlyargs[4] - ambariServer = onlyargs[5] - cluster_os_type = onlyargs[6] - ambariVersion = onlyargs[7] - server_port = onlyargs[8] - user_run_as = onlyargs[9] - passwordFile = onlyargs[10] + sshPort = onlyargs[3] + sshkey_file = onlyargs[4] + setupAgentFile = onlyargs[5] + ambariServer = onlyargs[6] + cluster_os_type = onlyargs[7] + ambariVersion = onlyargs[8] + server_port = onlyargs[9] + user_run_as = onlyargs[10] + passwordFile = onlyargs[11] if not OSCheck.is_windows_family(): # ssh doesn't like open files @@ -845,10 +849,10 @@ def main(argv=None): logging.info("BootStrapping hosts " + pprint.pformat(hostList) + " using " + scriptDir + " cluster primary OS: " + cluster_os_type + - " with user '" + user + "' sshKey File " + sshkey_file + " password File " + passwordFile +\ + " with user '" + user + "'with ssh Port '" + sshPort + "' sshKey File " + sshkey_file + " password File " + passwordFile +\ " using tmp dir " + bootdir + " ambari: " + ambariServer +"; server_port: " + server_port +\ "; ambari version: " + ambariVersion+"; user_run_as: " + user_run_as) - sharedState = SharedState(user, sshkey_file, scriptDir, bootdir, setupAgentFile, + sharedState = SharedState(user, sshPort, sshkey_file, scriptDir, bootdir, setupAgentFile, ambariServer, cluster_os_type, ambariVersion, server_port, user_run_as, passwordFile) pbootstrap = PBootstrap(hostList, sharedState) http://git-wip-us.apache.org/repos/asf/ambari/blob/39c04ac9/ambari-server/src/test/python/TestBootstrap.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/python/TestBootstrap.py b/ambari-server/src/test/python/TestBootstrap.py index e143a68..b60c35d 100644 --- a/ambari-server/src/test/python/TestBootstrap.py +++ b/ambari-server/src/test/python/TestBootstrap.py @@ -43,7 +43,7 @@ class TestBootstrap(TestCase): def test_getRemoteName(self): - shared_state = SharedState("root", "sshkey_file", "scriptDir", "bootdir", + shared_state = SharedState("root", "123", "sshkey_file", "scriptDir", "bootdir", "setupAgentFile", "ambariServer", "centos6", None, "8440", "root") res = bootstrap_obj = Bootstrap("hostname", shared_state) utime1 = 1234 @@ -65,7 +65,7 @@ class TestBootstrap(TestCase): # TODO: test_return_error_message_for_missing_sudo_package def test_getAmbariPort(self): - shared_state = SharedState("root", "sshkey_file", "scriptDir", "bootdir", + shared_state = SharedState("root", "123", "sshkey_file", "scriptDir", "bootdir", "setupAgentFile", "ambariServer", "centos6", None, "8440", "root") bootstrap_obj = Bootstrap("hostname", shared_state) @@ -82,11 +82,11 @@ class TestBootstrap(TestCase): @patch("os.path.dirname") @patch("os.path.realpath") def test_bootstrap_main(self, dirname_mock, realpath_mock, run_mock, exit_mock, stderr_mock, subprocess_Popen_mock): - bootstrap.main(["bootstrap.py", "hostname,hostname2", "/tmp/bootstrap", "root", "sshkey_file", "setupAgent.py", "ambariServer", \ + bootstrap.main(["bootstrap.py", "hostname,hostname2", "/tmp/bootstrap", "root", "123", "sshkey_file", "setupAgent.py", "ambariServer", \ "centos6", "1.1.1", "8440", "root", "passwordfile"]) self.assertTrue(run_mock.called) run_mock.reset_mock() - bootstrap.main(["bootstrap.py", "hostname,hostname2", "/tmp/bootstrap", "root", "sshkey_file", "setupAgent.py", "ambariServer", \ + bootstrap.main(["bootstrap.py", "hostname,hostname2", "/tmp/bootstrap", "root", "123", "sshkey_file", "setupAgent.py", "ambariServer", \ "centos6", "1.1.1", "8440", "root", None]) self.assertTrue(run_mock.called) run_mock.reset_mock() @@ -104,7 +104,7 @@ class TestBootstrap(TestCase): @patch("os.environ") def test_getRunSetupWithPasswordCommand(self, environ_mock): - shared_state = SharedState("root", "sshkey_file", "scriptDir", "bootdir", + shared_state = SharedState("root", "123", "sshkey_file", "scriptDir", "bootdir", "setupAgentFile", "ambariServer", "centos6", None, "8440", "root") environ_mock.__getitem__.return_value = "TEST_PASSPHRASE" @@ -118,7 +118,7 @@ class TestBootstrap(TestCase): def test_generateRandomFileName(self): - shared_state = SharedState("root", "sshkey_file", "scriptDir", "bootdir", + shared_state = SharedState("root", "123", "sshkey_file", "scriptDir", "bootdir", "setupAgentFile", "ambariServer", "centos6", None, "8440", "root") bootstrap_obj = Bootstrap("hostname", shared_state) @@ -129,7 +129,7 @@ class TestBootstrap(TestCase): @patch.object(OSCheck, "is_redhat_family") @patch.object(OSCheck, "is_suse_family") def test_getRepoDir(self, is_suse_family, is_redhat_family): - shared_state = SharedState("root", "sshkey_file", "scriptDir", "bootdir", + shared_state = SharedState("root", "123", "sshkey_file", "scriptDir", "bootdir", "setupAgentFile", "ambariServer", "centos6", None, "8440", "root") bootstrap_obj = Bootstrap("hostname", shared_state) @@ -145,7 +145,7 @@ class TestBootstrap(TestCase): self.assertEquals(res, "/etc/yum.repos.d") def test_getSetupScript(self): - shared_state = SharedState("root", "sshkey_file", "scriptDir", "bootdir", + shared_state = SharedState("root", "123", "sshkey_file", "scriptDir", "bootdir", "setupAgentFile", "ambariServer", "centos6", None, "8440", "root") bootstrap_obj = Bootstrap("hostname", shared_state) @@ -155,7 +155,7 @@ class TestBootstrap(TestCase): def test_run_setup_agent_command_ends_with_project_version(self): os.environ[AMBARI_PASSPHRASE_VAR_NAME] = "" version = "1.1.1" - shared_state = SharedState("root", "sshkey_file", "scriptDir", "bootdir", + shared_state = SharedState("root", "123", "sshkey_file", "scriptDir", "bootdir", "setupAgentFile", "ambariServer", "centos6", version, "8440", "root") bootstrap_obj = Bootstrap("hostname", shared_state) @@ -166,7 +166,7 @@ class TestBootstrap(TestCase): def test_agent_setup_command_without_project_version(self): os.environ[AMBARI_PASSPHRASE_VAR_NAME] = "" version = None - shared_state = SharedState("root", "sshkey_file", "scriptDir", "bootdir", + shared_state = SharedState("root", "123", "sshkey_file", "scriptDir", "bootdir", "setupAgentFile", "ambariServer", "centos6", version, "8440", "root") bootstrap_obj = Bootstrap("hostname", shared_state) @@ -207,7 +207,7 @@ class TestBootstrap(TestCase): @patch("subprocess.Popen") def test_SCP(self, popenMock): - params = SharedState("root", "sshkey_file", "scriptDir", "bootdir", + params = SharedState("root", "123", "sshkey_file", "scriptDir", "bootdir", "setupAgentFile", "ambariServer", "centos6", "1.2.1", "8440", "root") host_log_mock = MagicMock() @@ -216,7 +216,7 @@ class TestBootstrap(TestCase): log['text'] = log['text'] + text host_log_mock.write.side_effect = write_side_effect - scp = SCP(params.user, params.sshkey_file, "dummy-host", "src/file", + scp = SCP(params.user, params.sshPort, params.sshkey_file, "dummy-host", "src/file", "dst/file", params.bootdir, host_log_mock) log_sample = "log_sample" error_sample = "error_sample" @@ -233,7 +233,7 @@ class TestBootstrap(TestCase): self.assertTrue(error_sample in log['text']) command_str = str(popenMock.call_args[0][0]) self.assertEquals(command_str, "['scp', '-r', '-o', 'ConnectTimeout=60', '-o', " - "'BatchMode=yes', '-o', 'StrictHostKeyChecking=no', '-i', 'sshkey_file'," + "'BatchMode=yes', '-o', 'StrictHostKeyChecking=no', '-P', '123', '-i', 'sshkey_file'," " 'src/file', 'root@dummy-host:dst/file']") self.assertEqual(retcode["exitstatus"], 0) @@ -250,7 +250,7 @@ class TestBootstrap(TestCase): @patch("subprocess.Popen") def test_SSH(self, popenMock): - params = SharedState("root", "sshkey_file", "scriptDir", "bootdir", + params = SharedState("root", "123", "sshkey_file", "scriptDir", "bootdir", "setupAgentFile", "ambariServer", "centos6", "1.2.1", "8440", "root") host_log_mock = MagicMock() @@ -259,7 +259,7 @@ class TestBootstrap(TestCase): log['text'] = log['text'] + text host_log_mock.write.side_effect = write_side_effect - ssh = SSH(params.user, params.sshkey_file, "dummy-host", "dummy-command", + ssh = SSH(params.user, params.sshPort, params.sshkey_file, "dummy-host", "dummy-command", params.bootdir, host_log_mock) log_sample = "log_sample" error_sample = "error_sample" @@ -277,7 +277,7 @@ class TestBootstrap(TestCase): command_str = str(popenMock.call_args[0][0]) self.assertEquals(command_str, "['ssh', '-o', 'ConnectTimeOut=60', '-o', " "'StrictHostKeyChecking=no', '-o', 'BatchMode=yes', '-tt', '-i', " - "'sshkey_file', 'root@dummy-host', 'dummy-command']") + "'sshkey_file', '-p', '123', 'root@dummy-host', 'dummy-command']") self.assertEqual(retcode["exitstatus"], 0) log['text'] = "" @@ -295,7 +295,7 @@ class TestBootstrap(TestCase): process.returncode = 1 dummy_error_message = "dummy_error_message" - ssh = SSH(params.user, params.sshkey_file, "dummy-host", "dummy-command", + ssh = SSH(params.user, params.sshPort, params.sshkey_file, "dummy-host", "dummy-command", params.bootdir, host_log_mock, errorMessage= dummy_error_message) retcode = ssh.run() @@ -306,7 +306,7 @@ class TestBootstrap(TestCase): def test_getOsCheckScript(self): - shared_state = SharedState("root", "sshkey_file", "scriptDir", "bootdir", + shared_state = SharedState("root", "123", "sshkey_file", "scriptDir", "bootdir", "setupAgentFile", "ambariServer", "centos6", None, "8440", "root") bootstrap_obj = Bootstrap("hostname", shared_state) @@ -316,7 +316,7 @@ class TestBootstrap(TestCase): @patch.object(BootstrapDefault, "getRemoteName") def test_getOsCheckScriptRemoteLocation(self, getRemoteName_mock): - shared_state = SharedState("root", "sshkey_file", "scriptDir", "bootdir", + shared_state = SharedState("root", "123", "sshkey_file", "scriptDir", "bootdir", "setupAgentFile", "ambariServer", "centos6", None, "8440", "root") bootstrap_obj = Bootstrap("hostname", shared_state) @@ -328,7 +328,7 @@ class TestBootstrap(TestCase): @patch.object(BootstrapDefault, "is_suse") def test_getRepoFile(self, is_suse_mock): - shared_state = SharedState("root", "sshkey_file", "scriptDir", "bootdir", + shared_state = SharedState("root", "123", "sshkey_file", "scriptDir", "bootdir", "setupAgentFile", "ambariServer", "centos6", None, "8440", "root") bootstrap_obj = Bootstrap("hostname", shared_state) @@ -342,7 +342,7 @@ class TestBootstrap(TestCase): @patch.object(HostLog, "write") def test_createTargetDir(self, write_mock, run_mock, init_mock): - shared_state = SharedState("root", "sshkey_file", "scriptDir", "bootdir", + shared_state = SharedState("root", "123", "sshkey_file", "scriptDir", "bootdir", "setupAgentFile", "ambariServer", "centos6", None, "8440", "root") bootstrap_obj = Bootstrap("hostname", shared_state) @@ -351,7 +351,7 @@ class TestBootstrap(TestCase): run_mock.return_value = expected res = bootstrap_obj.createTargetDir() self.assertEquals(res, expected) - command = str(init_mock.call_args[0][3]) + command = str(init_mock.call_args[0][4]) self.assertEqual(command, "sudo mkdir -p /var/lib/ambari-agent/tmp ; " "sudo chown -R root /var/lib/ambari-agent/tmp ; " @@ -366,7 +366,7 @@ class TestBootstrap(TestCase): @patch.object(HostLog, "write") def test_copyOsCheckScript(self, write_mock, run_mock, init_mock, getOsCheckScriptRemoteLocation_mock, getOsCheckScript_mock): - shared_state = SharedState("root", "sshkey_file", "scriptDir", "bootdir", + shared_state = SharedState("root", "123", "sshkey_file", "scriptDir", "bootdir", "setupAgentFile", "ambariServer", "centos6", None, "8440", "root") bootstrap_obj = Bootstrap("hostname", shared_state) @@ -377,8 +377,8 @@ class TestBootstrap(TestCase): run_mock.return_value = expected res = bootstrap_obj.copyOsCheckScript() self.assertEquals(res, expected) - input_file = str(init_mock.call_args[0][3]) - remote_file = str(init_mock.call_args[0][4]) + input_file = str(init_mock.call_args[0][4]) + remote_file = str(init_mock.call_args[0][5]) self.assertEqual(input_file, "OsCheckScript") self.assertEqual(remote_file, "OsCheckScriptRemoteLocation") @@ -389,7 +389,7 @@ class TestBootstrap(TestCase): @patch.object(OSCheck, "is_ubuntu_family") @patch.object(OSCheck, "is_redhat_family") def test_getRepoFile(self, is_redhat_family, is_ubuntu_family, is_suse_family, hasPassword_mock, getRemoteName_mock): - shared_state = SharedState("root", "sshkey_file", "scriptDir", "bootdir", + shared_state = SharedState("root", "123", "sshkey_file", "scriptDir", "bootdir", "setupAgentFile", "ambariServer", "centos6", None, "8440", "root") is_redhat_family.return_value = True @@ -437,7 +437,7 @@ class TestBootstrap(TestCase): os_path_exists_mock.side_effect = os_path_exists_side_effect os_path_exists_mock.return_value = None - shared_state = SharedState("root", "sshkey_file", "scriptDir", "bootdir", + shared_state = SharedState("root", "123", "sshkey_file", "scriptDir", "bootdir", "setupAgentFile", "ambariServer", "centos6", None, "8440", "root") is_redhat_family.return_value = True @@ -459,11 +459,11 @@ class TestBootstrap(TestCase): ssh_run_mock.side_effect = [expected2, expected4] res = bootstrap_obj.copyNeededFiles() self.assertEquals(res, expected1["exitstatus"]) - input_file = str(scp_init_mock.call_args[0][3]) - remote_file = str(scp_init_mock.call_args[0][4]) + input_file = str(scp_init_mock.call_args[0][4]) + remote_file = str(scp_init_mock.call_args[0][5]) self.assertEqual(input_file, "setupAgentFile") self.assertEqual(remote_file, "RemoteName") - command = str(ssh_init_mock.call_args[0][3]) + command = str(ssh_init_mock.call_args[0][4]) self.assertEqual(command, "sudo chmod 644 RepoFile") # Another order expected1 = {"exitstatus": 0, "log": "log0", "errormsg": "errorMsg"} @@ -507,7 +507,7 @@ class TestBootstrap(TestCase): @patch.object(HostLog, "write") def test_runOsCheckScript(self, write_mock, run_mock, init_mock, getOsCheckScriptRemoteLocation_mock): - shared_state = SharedState("root", "sshkey_file", "scriptDir", "bootdir", + shared_state = SharedState("root", "123", "sshkey_file", "scriptDir", "bootdir", "setupAgentFile", "ambariServer", "centos6", None, "8440", "root") bootstrap_obj = Bootstrap("hostname", shared_state) @@ -517,7 +517,7 @@ class TestBootstrap(TestCase): run_mock.return_value = expected res = bootstrap_obj.runOsCheckScript() self.assertEquals(res, expected) - command = str(init_mock.call_args[0][3]) + command = str(init_mock.call_args[0][4]) self.assertEqual(command, "chmod a+x OsCheckScriptRemoteLocation && " "env PYTHONPATH=$PYTHONPATH:/var/lib/ambari-agent/tmp OsCheckScriptRemoteLocation centos6") @@ -529,7 +529,7 @@ class TestBootstrap(TestCase): @patch.object(HostLog, "write") def test_runSetupAgent(self, write_mock, run_mock, getRunSetupCommand_mock, init_mock): - shared_state = SharedState("root", "sshkey_file", "scriptDir", "bootdir", + shared_state = SharedState("root", "123", "sshkey_file", "scriptDir", "bootdir", "setupAgentFile", "ambariServer", "centos6", None, "8440", "root") bootstrap_obj = Bootstrap("hostname", shared_state) @@ -539,7 +539,7 @@ class TestBootstrap(TestCase): run_mock.return_value = expected res = bootstrap_obj.runSetupAgent() self.assertEquals(res, expected) - command = str(init_mock.call_args[0][3]) + command = str(init_mock.call_args[0][4]) self.assertEqual(command, "RunSetupCommand") @@ -549,7 +549,7 @@ class TestBootstrap(TestCase): def test_getRunSetupCommand(self, getRunSetupWithoutPasswordCommand_mock, getRunSetupWithPasswordCommand_mock, hasPassword_mock): - shared_state = SharedState("root", "sshkey_file", "scriptDir", "bootdir", + shared_state = SharedState("root", "123", "sshkey_file", "scriptDir", "bootdir", "setupAgentFile", "ambariServer", "centos6", None, "8440", "root") bootstrap_obj = Bootstrap("hostname", shared_state) @@ -568,7 +568,7 @@ class TestBootstrap(TestCase): @patch.object(HostLog, "write") def test_createDoneFile(self, write_mock): tmp_dir = tempfile.gettempdir() - shared_state = SharedState("root", "sshkey_file", "scriptDir", tmp_dir, + shared_state = SharedState("root", "123", "sshkey_file", "scriptDir", tmp_dir, "setupAgentFile", "ambariServer", "centos6", None, "8440", "root") bootstrap_obj = Bootstrap("hostname", shared_state) @@ -587,7 +587,7 @@ class TestBootstrap(TestCase): @patch.object(SSH, "run") @patch.object(HostLog, "write") def test_checkSudoPackage(self, write_mock, run_mock, init_mock, is_redhat_family, is_ubuntu_family, is_suse_family): - shared_state = SharedState("root", "sshkey_file", "scriptDir", "bootdir", + shared_state = SharedState("root", "123", "sshkey_file", "scriptDir", "bootdir", "setupAgentFile", "ambariServer", "centos6", None, "8440", "root") bootstrap_obj = Bootstrap("hostname", shared_state) @@ -599,7 +599,7 @@ class TestBootstrap(TestCase): is_suse_family.return_value = False res = bootstrap_obj.checkSudoPackage() self.assertEquals(res, expected) - command = str(init_mock.call_args[0][3]) + command = str(init_mock.call_args[0][4]) self.assertEqual(command, "rpm -qa | grep -e '^sudo\-'") @patch.object(OSCheck, "is_suse_family") @@ -610,7 +610,7 @@ class TestBootstrap(TestCase): @patch.object(HostLog, "write") def test_checkSudoPackageUbuntu(self, write_mock, run_mock, init_mock, is_redhat_family, is_ubuntu_family, is_suse_family): - shared_state = SharedState("root", "sshkey_file", "scriptDir", "bootdir", + shared_state = SharedState("root", "123", "sshkey_file", "scriptDir", "bootdir", "setupAgentFile", "ambariServer", "ubuntu12", None, "8440", "root") is_redhat_family.return_value = False @@ -622,7 +622,7 @@ class TestBootstrap(TestCase): run_mock.return_value = expected res = bootstrap_obj.checkSudoPackage() self.assertEquals(res, expected) - command = str(init_mock.call_args[0][3]) + command = str(init_mock.call_args[0][4]) self.assertEqual(command, "dpkg --get-selections|grep -e '^sudo\s*install'") @@ -632,7 +632,7 @@ class TestBootstrap(TestCase): @patch.object(BootstrapDefault, "getPasswordFile") def test_deletePasswordFile(self, getPasswordFile_mock, write_mock, run_mock, init_mock): - shared_state = SharedState("root", "sshkey_file", "scriptDir", "bootdir", + shared_state = SharedState("root", "123", "sshkey_file", "scriptDir", "bootdir", "setupAgentFile", "ambariServer", "centos6", None, "8440", "root") bootstrap_obj = Bootstrap("hostname", shared_state) @@ -642,7 +642,7 @@ class TestBootstrap(TestCase): run_mock.return_value = expected res = bootstrap_obj.deletePasswordFile() self.assertEquals(res, expected) - command = str(init_mock.call_args[0][3]) + command = str(init_mock.call_args[0][4]) self.assertEqual(command, "rm PasswordFile") @@ -655,7 +655,7 @@ class TestBootstrap(TestCase): def test_copyPasswordFile(self, write_mock, ssh_run_mock, ssh_init_mock, scp_run_mock, scp_init_mock, getPasswordFile_mock): - shared_state = SharedState("root", "sshkey_file", "scriptDir", "bootdir", + shared_state = SharedState("root", "123", "sshkey_file", "scriptDir", "bootdir", "setupAgentFile", "ambariServer", "centos6", None, "8440", "root", password_file="PasswordFile") bootstrap_obj = Bootstrap("hostname", shared_state) @@ -669,11 +669,11 @@ class TestBootstrap(TestCase): ssh_run_mock.return_value = expected2 res = bootstrap_obj.copyPasswordFile() self.assertEquals(res, expected1["exitstatus"]) - input_file = str(scp_init_mock.call_args[0][3]) + input_file = str(scp_init_mock.call_args[0][4]) remote_file = str(scp_init_mock.call_args[0][4]) self.assertEqual(input_file, "PasswordFile") self.assertEqual(remote_file, "PasswordFile") - command = str(ssh_init_mock.call_args[0][3]) + command = str(ssh_init_mock.call_args[0][4]) self.assertEqual(command, "chmod 600 PasswordFile") # Another order expected1 = {"exitstatus": 0, "log": "log0", "errormsg": "errorMsg"} @@ -688,7 +688,7 @@ class TestBootstrap(TestCase): @patch.object(BootstrapDefault, "getPasswordFile") def test_changePasswordFileModeOnHost(self, getPasswordFile_mock, write_mock, run_mock, init_mock): - shared_state = SharedState("root", "sshkey_file", "scriptDir", "bootdir", + shared_state = SharedState("root", "123", "sshkey_file", "scriptDir", "bootdir", "setupAgentFile", "ambariServer", "centos6", None, "8440", "root") bootstrap_obj = Bootstrap("hostname", shared_state) @@ -698,14 +698,14 @@ class TestBootstrap(TestCase): run_mock.return_value = expected res = bootstrap_obj.changePasswordFileModeOnHost() self.assertEquals(res, expected) - command = str(init_mock.call_args[0][3]) + command = str(init_mock.call_args[0][4]) self.assertEqual(command, "chmod 600 PasswordFile") @patch.object(HostLog, "write") def test_try_to_execute(self, write_mock): expected = 43 - shared_state = SharedState("root", "sshkey_file", "scriptDir", "bootdir", + shared_state = SharedState("root", "123", "sshkey_file", "scriptDir", "bootdir", "setupAgentFile", "ambariServer", "centos6", None, "8440", "root") bootstrap_obj = Bootstrap("hostname", shared_state) @@ -738,7 +738,7 @@ class TestBootstrap(TestCase): @patch("logging.error") def test_run(self, error_mock, warn_mock, write_mock, createDoneFile_mock, hasPassword_mock, try_to_execute_mock): - shared_state = SharedState("root", "sshkey_file", "scriptDir", "bootdir", + shared_state = SharedState("root", "123", "sshkey_file", "scriptDir", "bootdir", "setupAgentFile", "ambariServer", "centos6", None, "8440", "root") bootstrap_obj = Bootstrap("hostname", shared_state) @@ -810,7 +810,7 @@ class TestBootstrap(TestCase): @patch.object(BootstrapDefault, "createDoneFile") @patch.object(HostLog, "write") def test_interruptBootstrap(self, write_mock, createDoneFile_mock): - shared_state = SharedState("root", "sshkey_file", "scriptDir", "bootdir", + shared_state = SharedState("root", "123", "sshkey_file", "scriptDir", "bootdir", "setupAgentFile", "ambariServer", "centos6", None, "8440", "root") bootstrap_obj = Bootstrap("hostname", shared_state) @@ -827,7 +827,7 @@ class TestBootstrap(TestCase): @patch.object(BootstrapDefault, "getStatus") def test_PBootstrap(self, getStatus_mock, interruptBootstrap_mock, start_mock, info_mock, warn_mock, time_mock, sleep_mock): - shared_state = SharedState("root", "sshkey_file", "scriptDir", "bootdir", + shared_state = SharedState("root", "123", "sshkey_file", "scriptDir", "bootdir", "setupAgentFile", "ambariServer", "centos6", None, "8440", "root") n = 180 http://git-wip-us.apache.org/repos/asf/ambari/blob/39c04ac9/ambari-web/app/controllers/wizard.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/wizard.js b/ambari-web/app/controllers/wizard.js index fdee580..517122f 100644 --- a/ambari-web/app/controllers/wizard.js +++ b/ambari-web/app/controllers/wizard.js @@ -616,6 +616,7 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, App.ThemesMappingM sshKey: "", //string bootRequestId: null, //string sshUser: "root", //string + sshPort: "22", agentUser: "root" //string }, @@ -628,6 +629,7 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, App.ThemesMappingM sshKey: "", //string bootRequestId: null, //string sshUser: "", //string + sshPort: "22", agentUser: "" //string }, http://git-wip-us.apache.org/repos/asf/ambari/blob/39c04ac9/ambari-web/app/controllers/wizard/step2_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/wizard/step2_controller.js b/ambari-web/app/controllers/wizard/step2_controller.js index 3b51761..d951102 100644 --- a/ambari-web/app/controllers/wizard/step2_controller.js +++ b/ambari-web/app/controllers/wizard/step2_controller.js @@ -94,6 +94,14 @@ App.WizardStep2Controller = Em.Controller.extend({ }.property('content.installOptions.sshUser'), /** + * "Shortcut" to <code>content.installOptions.sshPort</code> + * @type {string} + */ + sshPort: function () { + return this.get('content.installOptions.sshPort'); + }.property('content.installOptions.sshPort'), + + /** * "Shortcut" to <code>content.installOptions.agentUser</code> * @type {string} */ @@ -148,6 +156,17 @@ App.WizardStep2Controller = Em.Controller.extend({ }.property('sshUser', 'useSSH', 'hasSubmitted', 'manualInstall'), /** + * Error-message if <code>sshPort</code> is empty, null otherwise + * @type {string|null} + */ + sshPortError: function () { + if (this.get('manualInstall') === false && this.get('useSSH') && Em.isEmpty(this.get('sshPort').trim() )) { + return Em.I18n.t('installer.step2.sshPort.required'); + } + return null; + }.property('sshPort', 'useSSH', 'hasSubmitted', 'manualInstall'), + + /** * Error-message if <code>agentUser</code> is empty, null otherwise * @type {string|null} */ @@ -163,8 +182,8 @@ App.WizardStep2Controller = Em.Controller.extend({ * @type {bool} */ isSubmitDisabled: function () { - return (this.get('hostsError') || this.get('sshKeyError') || this.get('sshUserError') || this.get('agentUserError')); - }.property('hostsError', 'sshKeyError', 'sshUserError', 'agentUserError'), + return (this.get('hostsError') || this.get('sshKeyError') || this.get('sshUserError') || this.get('sshPortError') || this.get('agentUserError')); + }.property('hostsError', 'sshKeyError', 'sshUserError', 'sshPortError', 'agentUserError'), installedHostNames: function () { var installedHostsName = []; @@ -292,7 +311,7 @@ App.WizardStep2Controller = Em.Controller.extend({ this.set('hostsError', Em.I18n.t('installer.step2.hostName.error.already_installed')); } - if (this.get('hostsError') || this.get('sshUserError') || this.get('agentUserError') || this.get('sshKeyError')) { + if (this.get('hostsError') || this.get('sshUserError') || this.get('sshPortError') || this.get('agentUserError') || this.get('sshKeyError')) { return false; } http://git-wip-us.apache.org/repos/asf/ambari/blob/39c04ac9/ambari-web/app/controllers/wizard/step3_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/wizard/step3_controller.js b/ambari-web/app/controllers/wizard/step3_controller.js index b3645e9..efea446 100644 --- a/ambari-web/app/controllers/wizard/step3_controller.js +++ b/ambari-web/app/controllers/wizard/step3_controller.js @@ -278,6 +278,7 @@ App.WizardStep3Controller = Em.Controller.extend(App.ReloadPopupMixin, { 'sshKey': this.get('content.installOptions.sshKey'), 'hosts': this.getBootstrapHosts(), 'user': this.get('content.installOptions.sshUser'), + 'sshPort': this.get('content.installOptions.sshPort'), 'userRunAs': App.get('supports.customizeAgentUserAccount') ? this.get('content.installOptions.agentUser') : 'root' }); App.router.get(this.get('content.controllerName')).launchBootstrap(bootStrapData, function (requestId) { @@ -461,6 +462,7 @@ App.WizardStep3Controller = Em.Controller.extend(App.ReloadPopupMixin, { 'sshKey': this.get('content.installOptions.sshKey'), 'hosts': hosts.mapProperty('name'), 'user': this.get('content.installOptions.sshUser'), + 'sshPort': this.get('content.installOptions.sshPort'), 'userRunAs': App.get('supports.customizeAgentUserAccount') ? this.get('content.installOptions.agentUser') : 'root' }); this.set('numPolls', 0); http://git-wip-us.apache.org/repos/asf/ambari/blob/39c04ac9/ambari-web/app/messages.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js index 8ee266c..c12ba24 100644 --- a/ambari-web/app/messages.js +++ b/ambari-web/app/messages.js @@ -586,6 +586,9 @@ Em.I18n.translations = { 'installer.step2.sshUser.toolTip':'The user account used to install the Ambari Agent on the target host(s) via SSH. This user must be set up with passwordless SSH and sudo access on all the target host(s)', 'installer.step2.sshUser.placeholder':'Enter user name', 'installer.step2.sshUser.required':'User name is required', + 'installer.step2.sshPort':'SSH Port Number', + 'installer.step2.sshPort.toolTip':'SSH Port Number', + 'installer.step2.sshPort.required':'SSH Port Number is required.', 'installer.step2.agentUser':'Ambari Agent User Account', 'installer.step2.agentUser.toolTip':'The user account used to run the Ambari Agent daemon on the target host(s). This user must be set up with passwordless sudo access on all the target host(s)', 'installer.step2.bootStrap.error':'Errors were encountered while setting up Ambari Agents on the hosts.', http://git-wip-us.apache.org/repos/asf/ambari/blob/39c04ac9/ambari-web/app/styles/application.less ---------------------------------------------------------------------- diff --git a/ambari-web/app/styles/application.less b/ambari-web/app/styles/application.less index dae745ae..8486411 100644 --- a/ambari-web/app/styles/application.less +++ b/ambari-web/app/styles/application.less @@ -719,6 +719,10 @@ h1 { margin-right: 10px; padding-top: 5px; } + .ssh-port { + margin-right: 10px; + padding-top: 5px; + } #targetHosts { .target-hosts-input { padding-left: 18px; http://git-wip-us.apache.org/repos/asf/ambari/blob/39c04ac9/ambari-web/app/templates/wizard/step2.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/wizard/step2.hbs b/ambari-web/app/templates/wizard/step2.hbs index a194cc0..5aa4f89 100644 --- a/ambari-web/app/templates/wizard/step2.hbs +++ b/ambari-web/app/templates/wizard/step2.hbs @@ -90,6 +90,18 @@ {{/if}} </div> </div> + <div class="row-fluid"> + <label rel="tooltip" {{translateAttr title="installer.step2.sshPort.toolTip"}} class="ssh-port pull-left span4"> + {{t installer.step2.sshPort}} + </label> + + <div {{bindAttr class="sshPortError:error :control-group"}}> + {{view view.textFieldView valueBinding="content.installOptions.sshPort" isEnabledBinding="content.installOptions.useSsh" }} + {{#if sshPortError}} + <span class="help-inline">{{sshPortError}}</span> + {{/if}} + </div> + </div> {{#if App.supports.customizeAgentUserAccount}} <div class="row-fluid"> <label rel="tooltip" {{translateAttr title="installer.step2.agentUser.toolTip"}} class="ssh-user pull-left span4"> http://git-wip-us.apache.org/repos/asf/ambari/blob/39c04ac9/ambari-web/test/controllers/wizard/step2_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/wizard/step2_test.js b/ambari-web/test/controllers/wizard/step2_test.js index d62b247..8f0fc66 100644 --- a/ambari-web/test/controllers/wizard/step2_test.js +++ b/ambari-web/test/controllers/wizard/step2_test.js @@ -29,21 +29,25 @@ describe('App.WizardStep2Controller', function () { { manualInstall: false, user: '', + sshPort:'', e: '' }, { manualInstall: true, user: '', + sshPort:'', e: null }, { manualInstall: true, user: 'nobody', + sshPort:'123', e: null }, { manualInstall: false, user: 'nobody', + sshPort:'123', e: null } ]); @@ -100,6 +104,15 @@ describe('App.WizardStep2Controller', function () { }); }); + describe('#sshPort', function() { + it('should be equal to content.installOptions.sshPort', function() { + var controller = App.WizardStep2Controller.create({content: {installOptions: {sshPort: '123'}}}); + expect(controller.get('sshPort')).to.equal('123'); + controller.set('content.installOptions.sshPort', '321'); + expect(controller.get('sshPort')).to.equal('321'); + }); + }); + describe('#agentUser', function() { it('should be equal to content.installOptions.agentUser', function() { var controller = App.WizardStep2Controller.create({content: {installOptions: {agentUser: '123'}}}); @@ -285,6 +298,22 @@ describe('App.WizardStep2Controller', function () { }); + describe('#sshPortError', function () { + + userErrorTests.forEach(function(test) { + it('', function() { + var controller = App.WizardStep2Controller.create({content: {installOptions: {manualInstall: test.manualInstall, sshPort: test.sshPort}}}); + if(Em.isNone(test.e)) { + expect(controller.get('sshPortError')).to.equal(null); + } + else { + expect(controller.get('sshPortError').length).to.be.above(2); + } + }); + }); + + }); + describe('#agentUserError', function () { afterEach(function () { @@ -379,6 +408,15 @@ describe('App.WizardStep2Controller', function () { expect(controller.evaluateStep()).to.equal(false); }); + it('should return false if sshPortError is not empty', function () { + var controller = App.WizardStep2Controller.create({ + hostNames: 'apache.ambari', + parseHostNamesAsPatternExpression: Em.K + }); + controller.reopen({sshPortError: 'error'}); + expect(controller.evaluateStep()).to.equal(false); + }); + it('should return false if agentUserError is not empty', function () { var controller = App.WizardStep2Controller.create({ hostNames: 'apache.ambari', @@ -487,6 +525,7 @@ describe('App.WizardStep2Controller', function () { hostsError: '', sshKeyError: '', sshUserError: '', + sshPortError: '', agentUserError: '' }); @@ -512,6 +551,12 @@ describe('App.WizardStep2Controller', function () { controller.set('sshUserError', ''); expect(controller.get('isSubmitDisabled').length).to.above(0); }); + + it('should return value if sshPortError is not empty', function () { + controller.set('sshPortError', 'error'); + controller.set('agentUserError', ''); + expect(controller.get('isSubmitDisabled').length).to.above(0); + }); }); describe('#installedHostsPopup', function() { http://git-wip-us.apache.org/repos/asf/ambari/blob/39c04ac9/ambari-web/test/controllers/wizard/step3_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/wizard/step3_test.js b/ambari-web/test/controllers/wizard/step3_test.js index 74c62e6..f48514c 100644 --- a/ambari-web/test/controllers/wizard/step3_test.js +++ b/ambari-web/test/controllers/wizard/step3_test.js @@ -558,6 +558,7 @@ describe('App.WizardStep3Controller', function () { installOptions: { sshKey: 'key', sshUser: 'root', + sshPort: '123', agentUser: 'user' }, hosts: { "host0": { "name": "host0" }, "host1": { "name": "host1" } } @@ -571,6 +572,7 @@ describe('App.WizardStep3Controller', function () { sshKey: 'key', hosts: ['host0', 'host1'], user: 'root', + sshPort: '123', userRunAs: item.userRunAs })); }); @@ -2410,6 +2412,7 @@ describe('App.WizardStep3Controller', function () { installOptions: { sshKey: 'key', sshUser: 'root', + sshPort: '123', agentUser: 'user' }, hosts: { "host0": { "name": "host0" }, "host1": { "name": "host1" } }, @@ -2436,6 +2439,7 @@ describe('App.WizardStep3Controller', function () { sshKey: 'key', hosts: ['host0', 'host1'], user: 'root', + sshPort: '123', userRunAs: item.userRunAs })); });