Repository: ambari Updated Branches: refs/heads/trunk fcd6a94be -> 77a7b8266
AMBARI-5086 Provide better error message if agent host cannot reach repo during registration (Dmytro Shkvyra via dsen) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/77a7b826 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/77a7b826 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/77a7b826 Branch: refs/heads/trunk Commit: 77a7b826669627f1dd447c6c26bd170ac8a317f6 Parents: fcd6a94 Author: Dmitry Sen <[email protected]> Authored: Tue Mar 18 15:52:08 2014 +0200 Committer: Dmitry Sen <[email protected]> Committed: Tue Mar 18 15:52:08 2014 +0200 ---------------------------------------------------------------------- ambari-server/src/main/python/bootstrap.py | 20 ++++--- ambari-server/src/test/python/TestBootstrap.py | 60 ++++++++++----------- 2 files changed, 42 insertions(+), 38 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/77a7b826/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 27747c5..33c9d47 100755 --- a/ambari-server/src/main/python/bootstrap.py +++ b/ambari-server/src/main/python/bootstrap.py @@ -84,12 +84,13 @@ class SCP: scpstat = subprocess.Popen(scpcommand, stdout=subprocess.PIPE, stderr=subprocess.PIPE) log = scpstat.communicate() + errorMsg = log[1] log = log[0] + "\n" + log[1] self.host_log.write("==========================") self.host_log.write(log) self.host_log.write("scp " + self.inputFile) self.host_log.write("host=" + self.host + ", exitcode=" + str(scpstat.returncode) ) - return scpstat.returncode + return {"exitstatus": scpstat.returncode, "log": log, "errormsg": errorMsg} @@ -127,7 +128,7 @@ class SSH: self.host_log.write(log) self.host_log.write("SSH command execution finished") self.host_log.write("host=" + self.host + ", exitcode=" + str(sshstat.returncode)) - return sshstat.returncode + return {"exitstatus": sshstat.returncode, "log": log, "errormsg": errorMsg} @@ -274,7 +275,7 @@ class Bootstrap(threading.Thread): retcode3 = scp.run() self.host_log.write("\n") - return max(retcode1, retcode2, retcode3) + return max(retcode1["exitstatus"], retcode2["exitstatus"], retcode3["exitstatus"]) def getAmbariVersion(self): @@ -392,7 +393,7 @@ class Bootstrap(threading.Thread): retcode2 = ssh.run() self.host_log.write("Copying password file finished") - return max(retcode1, retcode2) + return max(retcode1["exitstatus"], retcode2["exitstatus"]) def changePasswordFileModeOnHost(self): @@ -419,11 +420,11 @@ class Bootstrap(threading.Thread): return retcode def try_to_execute(self, action): + last_retcode = {"exitstatus": 177, "log":"Try to execute '{0}'".format(str(action)), "errormsg":"Execute of '{0}' failed".format(str(action))} try: last_retcode = action() except Exception, e: self.host_log.write("Traceback: " + traceback.format_exc()) - last_retcode = 177 return last_retcode def run(self): @@ -446,17 +447,20 @@ class Bootstrap(threading.Thread): last_retcode = 0 while action_queue and last_retcode == 0: action = action_queue.pop(0) - last_retcode = self.try_to_execute(action) + ret = self.try_to_execute(action) + last_retcode = ret["exitstatus"] + err_msg = ret["errormsg"] + std_out = ret["log"] # Checking execution result if last_retcode != 0: message = "ERROR: Bootstrap of host {0} fails because previous action " \ - "finished with non-zero exit code ({1})".format(self.host, last_retcode) + "finished with non-zero exit code ({1})\nERROR MESSAGE: {2}\nSTDOUT: {3}".format(self.host, last_retcode, err_msg, std_out) self.host_log.write(message) logging.error(message) # Try to delete password file if self.hasPassword() and self.copied_password_file: retcode = self.try_to_execute(self.deletePasswordFile) - if retcode != 0: + if retcode["exitstatus"] != 0: message = "WARNING: failed to delete password file " \ "at {0}. Please delete it manually".format(self.getPasswordFile()) self.host_log.write(message) http://git-wip-us.apache.org/repos/asf/ambari/blob/77a7b826/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 638971a..ee4d81d 100644 --- a/ambari-server/src/test/python/TestBootstrap.py +++ b/ambari-server/src/test/python/TestBootstrap.py @@ -241,7 +241,7 @@ class TestBootstrap(TestCase): self.assertEquals(command_str, "['scp', '-o', 'ConnectTimeout=60', '-o', " "'BatchMode=yes', '-o', 'StrictHostKeyChecking=no', '-i', 'sshkey_file'," " 'src/file', 'root@dummy-host:dst/file']") - self.assertEqual(retcode, 0) + self.assertEqual(retcode["exitstatus"], 0) log['text'] = "" #unsuccessfull run @@ -251,7 +251,7 @@ class TestBootstrap(TestCase): self.assertTrue(log_sample in log['text']) self.assertTrue(error_sample in log['text']) - self.assertEqual(retcode, 1) + self.assertEqual(retcode["exitstatus"], 1) @patch("subprocess.Popen") @@ -284,7 +284,7 @@ class TestBootstrap(TestCase): self.assertEquals(command_str, "['ssh', '-o', 'ConnectTimeOut=60', '-o', " "'StrictHostKeyChecking=no', '-o', 'BatchMode=yes', '-tt', '-i', " "'sshkey_file', 'root@dummy-host', 'dummy-command']") - self.assertEqual(retcode, 0) + self.assertEqual(retcode["exitstatus"], 0) log['text'] = "" #unsuccessfull run @@ -294,7 +294,7 @@ class TestBootstrap(TestCase): self.assertTrue(log_sample in log['text']) self.assertTrue(error_sample in log['text']) - self.assertEqual(retcode, 1) + self.assertEqual(retcode["exitstatus"], 1) log['text'] = "" # unsuccessful run with error message @@ -308,7 +308,7 @@ class TestBootstrap(TestCase): self.assertTrue(log_sample in log['text']) self.assertTrue(error_sample in log['text']) self.assertTrue(dummy_error_message in log['text']) - self.assertEqual(retcode, 1) + self.assertEqual(retcode["exitstatus"], 1) def test_getOsCheckScript(self): @@ -407,16 +407,16 @@ class TestBootstrap(TestCase): getRepoDir.return_value = "RepoDir" getRemoteName_mock.return_value = "RemoteName" getRepoFile_mock.return_value = "RepoFile" - expected1 = 42 - expected2 = 17 - expected3 = 1 + expected1 = {"exitstatus": 42, "log": "log42", "errormsg": "errorMsg"} + expected2 = {"exitstatus": 17, "log": "log17", "errormsg": "errorMsg"} + expected3 = {"exitstatus": 1, "log": "log1", "errormsg": "errorMsg"} scp_init_mock.return_value = None ssh_init_mock.return_value = None # Testing max retcode return scp_run_mock.side_effect = [expected1, expected3] ssh_run_mock.side_effect = [expected2] res = bootstrap_obj.copyNeededFiles() - self.assertEquals(res, expected1) + 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]) self.assertEqual(input_file, "setupAgentFile") @@ -424,21 +424,21 @@ class TestBootstrap(TestCase): command = str(ssh_init_mock.call_args[0][3]) self.assertEqual(command, "MoveRepoFileCommand") # Another order - expected1 = 0 - expected2 = 17 - expected3 = 1 + expected1 = {"exitstatus": 0, "log": "log0", "errormsg": "errorMsg"} + expected2 = {"exitstatus": 17, "log": "log17", "errormsg": "errorMsg"} + expected3 = {"exitstatus": 1, "log": "log1", "errormsg": "errorMsg"} scp_run_mock.side_effect = [expected1, expected3] ssh_run_mock.side_effect = [expected2] res = bootstrap_obj.copyNeededFiles() - self.assertEquals(res, expected2) + self.assertEquals(res, expected2["exitstatus"]) # yet another order - expected1 = 33 - expected2 = 17 - expected3 = 42 + expected1 = {"exitstatus": 33, "log": "log33", "errormsg": "errorMsg"} + expected2 = {"exitstatus": 17, "log": "log17", "errormsg": "errorMsg"} + expected3 = {"exitstatus": 42, "log": "log42", "errormsg": "errorMsg"} scp_run_mock.side_effect = [expected1, expected3] ssh_run_mock.side_effect = [expected2] res = bootstrap_obj.copyNeededFiles() - self.assertEquals(res, expected3) + self.assertEquals(res, expected3["exitstatus"]) @patch.object(Bootstrap, "getOsCheckScriptRemoteLocation") @@ -571,14 +571,14 @@ class TestBootstrap(TestCase): bootstrap_obj = Bootstrap("hostname", shared_state) getPasswordFile_mock.return_value = "PasswordFile" # Testing max retcode return - expected1 = 42 - expected2 = 17 + expected1 = {"exitstatus": 42, "log": "log42", "errormsg": "errorMsg"} + expected2 = {"exitstatus": 17, "log": "log17", "errormsg": "errorMsg"} scp_init_mock.return_value = None scp_run_mock.return_value = expected1 ssh_init_mock.return_value = None ssh_run_mock.return_value = expected2 res = bootstrap_obj.copyPasswordFile() - self.assertEquals(res, expected1) + 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]) self.assertEqual(input_file, "PasswordFile") @@ -586,8 +586,8 @@ class TestBootstrap(TestCase): command = str(ssh_init_mock.call_args[0][3]) self.assertEqual(command, "chmod 600 PasswordFile") # Another order - expected1 = 0 - expected2 = 17 + expected1 = {"exitstatus": 0, "log": "log0", "errormsg": "errorMsg"} + expected2 = {"exitstatus": 17, "log": "log17", "errormsg": "errorMsg"} scp_run_mock.return_value = expected1 ssh_run_mock.return_value = expected2 @@ -620,8 +620,8 @@ class TestBootstrap(TestCase): None, "8440") bootstrap_obj = Bootstrap("hostname", shared_state) # Normal case - ret = bootstrap_obj.try_to_execute(lambda : expected) - self.assertEqual(ret, expected) + ret = bootstrap_obj.try_to_execute(lambda : {"exitstatus": expected}) + self.assertEqual(ret["exitstatus"], expected) self.assertFalse(write_mock.called) write_mock.reset_mock() @@ -629,7 +629,7 @@ class TestBootstrap(TestCase): def act(): raise IOError() ret = bootstrap_obj.try_to_execute(act) - self.assertEqual(ret, 177) + self.assertEqual(ret["exitstatus"], 177) self.assertTrue(write_mock.called) @@ -648,7 +648,7 @@ class TestBootstrap(TestCase): # Testing workflow without password bootstrap_obj.copied_password_file = False hasPassword_mock.return_value = False - try_to_execute_mock.return_value = 0 + try_to_execute_mock.return_value = {"exitstatus": 0, "log":"log0", "errormsg":"errormsg0"} bootstrap_obj.run() self.assertEqual(try_to_execute_mock.call_count, 5) # <- Adjust if changed self.assertTrue(createDoneFile_mock.called) @@ -659,7 +659,7 @@ class TestBootstrap(TestCase): # Testing workflow with password bootstrap_obj.copied_password_file = True hasPassword_mock.return_value = True - try_to_execute_mock.return_value = 0 + try_to_execute_mock.return_value = {"exitstatus": 0, "log":"log0", "errormsg":"errormsg0"} bootstrap_obj.run() self.assertEqual(try_to_execute_mock.call_count, 8) # <- Adjust if changed self.assertTrue(createDoneFile_mock.called) @@ -672,7 +672,7 @@ class TestBootstrap(TestCase): # Testing workflow when some action failed before copying password bootstrap_obj.copied_password_file = False hasPassword_mock.return_value = False - try_to_execute_mock.side_effect = [0, 1] + try_to_execute_mock.side_effect = [{"exitstatus": 0, "log":"log0", "errormsg":"errormsg0"}, {"exitstatus": 1, "log":"log1", "errormsg":"errormsg1"}] bootstrap_obj.run() self.assertEqual(try_to_execute_mock.call_count, 2) # <- Adjust if changed self.assertTrue("ERROR" in error_mock.call_args[0][0]) @@ -685,7 +685,7 @@ class TestBootstrap(TestCase): # Testing workflow when some action failed after copying password bootstrap_obj.copied_password_file = True hasPassword_mock.return_value = True - try_to_execute_mock.side_effect = [0, 42, 0] + try_to_execute_mock.side_effect = [{"exitstatus": 0, "log":"log0", "errormsg":"errormsg0"}, {"exitstatus": 42, "log":"log42", "errormsg":"errormsg42"}, {"exitstatus": 0, "log":"log0", "errormsg":"errormsg0"}] bootstrap_obj.run() self.assertEqual(try_to_execute_mock.call_count, 3) # <- Adjust if changed self.assertTrue(createDoneFile_mock.called) @@ -699,7 +699,7 @@ class TestBootstrap(TestCase): # removing password failed too bootstrap_obj.copied_password_file = True hasPassword_mock.return_value = True - try_to_execute_mock.side_effect = [0, 17, 19] + try_to_execute_mock.side_effect = [{"exitstatus": 0, "log":"log0", "errormsg":"errormsg0"}, {"exitstatus": 17, "log":"log17", "errormsg":"errormsg17"}, {"exitstatus": 19, "log":"log19", "errormsg":"errormsg19"}] bootstrap_obj.run() self.assertEqual(try_to_execute_mock.call_count, 3) # <- Adjust if changed self.assertTrue("ERROR" in write_mock.call_args_list[0][0][0])
