Просмотр исходного кода

AMBARI-3716. Reset server does not say if it's failed (Eugene Chekanskiy via dlysnichenko)

Lisnichenko Dmitro 11 лет назад
Родитель
Сommit
698cf78546

+ 22 - 10
ambari-server/src/main/python/ambari-server.py

@@ -226,6 +226,7 @@ UPGRADE_STACK_CMD = ['su', 'postgres',
         '--command=psql -f {0} -v stack_name="\'{1}\'"  -v stack_version="\'{2}\'" -v dbname="{3}"']
 UPDATE_METAINFO_CMD = 'curl -X PUT "http://{0}:{1}/api/v1/stacks2" -u "{2}":"{3}"'
 
+PG_ERROR_BLOCKED = "is being accessed by other users"
 PG_STATUS_RUNNING = "running"
 PG_DEFAULT_PASSWORD = "bigdata"
 SERVICE_CMD = "/sbin/service"
@@ -907,11 +908,11 @@ def setup_db(args):
     print 'Connecting to the database. Attempt %d...' % (i+1)
     retcode, outdata, errdata = run_os_command(command)
     if retcode == 0:
-      return retcode
+      return retcode, outdata, errdata
     time.sleep(SETUP_DB_CONNECT_TIMEOUT)
 
   print_error_msg(errdata)
-  return retcode
+  return retcode, outdata, errdata
 
 
 def store_password_file(password, filename):
@@ -2133,6 +2134,10 @@ def reset(args):
     err = 'Ambari-server reset should be run with ' \
           'root-level privileges'
     raise FatalException(4, err)
+  status, pid = is_server_runing()
+  if status:
+    err = 'Ambari-server must be stopped to reset'
+    raise FatalException(1, err)
   choice = get_YN_input("**** WARNING **** You are about to reset and clear the "
                      "Ambari Server database. This will remove all cluster "
                      "host and configuration information from the database. "
@@ -2209,15 +2214,22 @@ def reset(args):
     password = args.database_password
     command = SETUP_DB_CMD[:]
     command[-1] = command[-1].format(filename, username, password, dbname)
-    retcode, outdata, errdata = run_os_command(command)
-    if not retcode == 0:
-      raise FatalException(1, errdata)
-    if errdata:
-      print_warning_msg(errdata)
+    drop_retcode, drop_outdata, drop_errdata = run_os_command(command)
+    if not drop_retcode == 0:
+      raise FatalException(1, drop_errdata)
+    if drop_errdata and PG_ERROR_BLOCKED in drop_errdata:
+      raise FatalException(1, "Database is in use. Please, make sure all connections to the database are closed")
+    if drop_errdata and VERBOSE:
+      print_warning_msg(drop_errdata)
     print_info_msg ("About to run database setup")
-    setup_db(args)
-
-
+    retcode, outdata, errdata = setup_db(args)
+    if errdata and VERBOSE:
+      print_warning_msg(errdata)
+    if (errdata and 'ERROR' in errdata.upper()) or (drop_errdata and 'ERROR' in drop_errdata.upper()):
+      if not VERBOSE:
+        raise NonFatalException("Non critical error in DDL, use --verbose for more information")
+      else:
+        raise NonFatalException("Non critical error in DDL")
 
 #
 # Starts the Ambari Server.

+ 25 - 5
ambari-server/src/test/python/TestAmbariServer.py

@@ -573,7 +573,7 @@ class TestAmbariServer(TestCase):
     run_os_command_mock.return_value = (0, None, None)
     result = ambari_server.setup_db(MagicMock())
     self.assertTrue(configure_database_username_password_mock.called)
-    self.assertEqual(0, result)
+    self.assertEqual((0, None, None), result)
 
   @patch.object(ambari_server, "configure_database_username_password")
   @patch("time.sleep")
@@ -584,7 +584,7 @@ class TestAmbariServer(TestCase):
                                        (1, "error", "error")]
     result = ambari_server.setup_db(MagicMock())
     self.assertTrue(run_os_command_mock.called)
-    self.assertEqual(1, result)
+    self.assertEqual((1, 'error', 'error') , result)
     self.assertEqual(3, sleep_mock.call_count)
     pass
 
@@ -597,7 +597,7 @@ class TestAmbariServer(TestCase):
                                        (0, None, None)]
     result = ambari_server.setup_db(MagicMock())
     self.assertTrue(run_os_command_mock.called)
-    self.assertEqual(0, result)
+    self.assertEqual((0, None, None) , result)
     self.assertEqual(1, sleep_mock.call_count)
     pass
 
@@ -2240,7 +2240,7 @@ MIIFHjCCAwYCCQDpHKOBI+Lt0zANBgkqhkiG9w0BAQUFADBRMQswCQYDVQQGEwJV
     except NonFatalException as fe:
       self.assertTrue("cli was not found" in fe.reason)
 
-
+  @patch.object(ambari_server, 'is_server_runing')
   @patch.object(ambari_server, "get_YN_input")
   @patch.object(ambari_server, "setup_db")
   @patch.object(ambari_server, "print_info_msg")
@@ -2253,12 +2253,14 @@ MIIFHjCCAwYCCQDpHKOBI+Lt0zANBgkqhkiG9w0BAQUFADBRMQswCQYDVQQGEwJV
   def test_reset(self, check_database_name_property_mock, is_root_mock, execute_remote_script_mock,
                  parse_properties_file_mock, configure_database_username_password_mock,
                  run_os_command_mock, print_info_msg_mock,
-                 setup_db_mock, get_YN_inputMock):
+                 setup_db_mock, get_YN_inputMock, is_server_running_mock):
 
     parse_properties_file_mock.return_value = 0
     args = MagicMock()
     args.persistence_type = "local"
     get_YN_inputMock.return_value = False
+    is_server_running_mock.return_value = (False, 0)
+    setup_db_mock.side_effect = [(0,None, None),(0,None, "ERROR: database 'ambari' is being accessed by other users"), (0, None, "ERROR: user 'mapred' already exist")]
 
     # Testing call under non-root
     is_root_mock.return_value = False
@@ -2293,6 +2295,23 @@ MIIFHjCCAwYCCQDpHKOBI+Lt0zANBgkqhkiG9w0BAQUFADBRMQswCQYDVQQGEwJV
     ambari_server.reset(args)
     self.assertTrue(setup_db_mock.called)
 
+    # Database errors cases
+    is_server_running_mock.side_effect = [(True, 123), (False, 0), (False, 0)]
+
+    try:
+      ambari_server.reset(args)
+      self.fail("Should throw exception")
+    except FatalException:
+      # Expected
+      pass
+
+    try:
+      ambari_server.reset(args)
+      self.fail("Should throw exception")
+    except NonFatalException:
+      # Expected
+      pass
+
     #remote db case
     args.persistence_type = "remote"
     execute_remote_script_mock.return_value = (0, None, None)
@@ -2334,6 +2353,7 @@ MIIFHjCCAwYCCQDpHKOBI+Lt0zANBgkqhkiG9w0BAQUFADBRMQswCQYDVQQGEwJV
     args = MagicMock()
     ambari_server.SILENT = True
     self.assertTrue(ambari_server.SILENT)
+    setup_db_mock.return_value = (0, None, None)
     run_os_command_mock.return_value = (0, None, None)
 
     def signal_handler(signum, frame):