You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by vb...@apache.org on 2015/08/12 11:38:44 UTC

ambari git commit: AMBARI-12730. Ambari Server schema upgrade should prompt about backups.(vbrodetskyi)

Repository: ambari
Updated Branches:
  refs/heads/trunk b63ff52d7 -> e482d7c4e


AMBARI-12730. Ambari Server schema upgrade should prompt about backups.(vbrodetskyi)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/e482d7c4
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/e482d7c4
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/e482d7c4

Branch: refs/heads/trunk
Commit: e482d7c4eec310f4dba16eb4853b48c7f5b1cbe5
Parents: b63ff52
Author: Vitaly Brodetskyi <vb...@hortonworks.com>
Authored: Wed Aug 12 12:38:45 2015 +0300
Committer: Vitaly Brodetskyi <vb...@hortonworks.com>
Committed: Wed Aug 12 12:38:45 2015 +0300

----------------------------------------------------------------------
 .../python/ambari_server/serverConfiguration.py | 124 ++++++++++++++++---
 .../main/python/ambari_server/serverUpgrade.py  |  11 +-
 .../src/test/python/TestAmbariServer.py         |  10 +-
 3 files changed, 125 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/e482d7c4/ambari-server/src/main/python/ambari_server/serverConfiguration.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/python/ambari_server/serverConfiguration.py b/ambari-server/src/main/python/ambari_server/serverConfiguration.py
index d9fc0ba..7f4fe87 100644
--- a/ambari-server/src/main/python/ambari_server/serverConfiguration.py
+++ b/ambari-server/src/main/python/ambari_server/serverConfiguration.py
@@ -171,6 +171,87 @@ SETUP_OR_UPGRADE_MSG = "- If this is a new setup, then run the \"ambari-server s
 
 DEFAULT_DB_NAME = "ambari"
 
+class ServerDatabaseType(object):
+  internal = 0
+  remote = 1
+
+
+class ServerDatabaseEntry(object):
+  def __init__(self, name, title, db_type, aliases=None):
+    """
+    :type name str
+    :type title str
+    :type db_type int
+    :type aliases list
+    """
+    self.__name = name
+    self.__title = title
+    self.__type = db_type
+    if aliases is None:
+      aliases = []
+
+    self.__aliases = aliases
+
+  @property
+  def name(self):
+    return self.__name
+
+  @property
+  def title(self):
+    return self.__title
+
+  @property
+  def dbtype(self):
+    return self.__type
+
+  def __str__(self):
+    return self.name
+
+  def __eq__(self, other):
+    if other is None:
+      return False
+
+    if isinstance(other, ServerDatabaseEntry):
+      return self.name == other.name and self.dbtype == other.dbtype
+    elif isinstance(other, str):
+      return self.name == other or other in self.__aliases
+
+    raise RuntimeError("Not compatible type")
+
+
+class ServerDatabases(object):
+  postgres = ServerDatabaseEntry("postgres", "Postgres", ServerDatabaseType.remote)
+  oracle = ServerDatabaseEntry("oracle", "Oracle", ServerDatabaseType.remote)
+  mysql = ServerDatabaseEntry("mysql", "MySQL", ServerDatabaseType.remote)
+  mssql = ServerDatabaseEntry("mssql", "MSSQL", ServerDatabaseType.remote)
+  derby = ServerDatabaseEntry("derby", "Derby", ServerDatabaseType.remote)
+  postgres_internal = ServerDatabaseEntry("postgres", "Embedded Postgres", ServerDatabaseType.internal, aliases=['embedded'])
+
+  @staticmethod
+  def databases():
+    props = ServerDatabases.__dict__
+    r_props = []
+    for p in props:
+      if isinstance(props[p], ServerDatabaseEntry):
+        r_props.append(props[p].name)
+
+    return set(r_props)
+
+  @staticmethod
+  def match(name):
+    """
+    :type name str
+    :rtype ServerDatabaseEntry
+    """
+    props = ServerDatabases.__dict__
+
+    for p in props:
+      if isinstance(props[p], ServerDatabaseEntry):
+        if name == props[p]:
+          return props[p]
+
+    return None
+
 class ServerConfigDefaults(object):
   def __init__(self):
     self.JAVA_SHARE_PATH = "/usr/share/java"
@@ -501,19 +582,32 @@ def get_ambari_version(properties):
   return version
 
 def get_db_type(properties):
+  """
+  :rtype ServerDatabaseEntry
+  """
   db_type = None
-  if properties[JDBC_URL_PROPERTY]:
+  persistence_type = properties[PERSISTENCE_TYPE_PROPERTY]
+
+  if properties[JDBC_DATABASE_PROPERTY]:
+    db_type = ServerDatabases.match(properties[JDBC_DATABASE_PROPERTY])
+    if db_type == ServerDatabases.postgres and persistence_type == "local":
+      db_type = ServerDatabases.postgres_internal
+
+  if properties[JDBC_URL_PROPERTY] and db_type is None:
     jdbc_url = properties[JDBC_URL_PROPERTY].lower()
-    if "postgres" in jdbc_url:
-      db_type = "postgres"
-    elif "oracle" in jdbc_url:
-      db_type = "oracle"
-    elif "mysql" in jdbc_url:
-      db_type = "mysql"
-    elif "sqlserver" in jdbc_url:
-      db_type = "mssql"
-    elif "derby" in jdbc_url:
-      db_type = "derby"
+    if str(ServerDatabases.postgres) in jdbc_url:
+      db_type = ServerDatabases.postgres
+    elif str(ServerDatabases.oracle) in jdbc_url:
+      db_type = ServerDatabases.oracle
+    elif str(ServerDatabases.mysql) in jdbc_url:
+      db_type = ServerDatabases.mysql
+    elif str(ServerDatabases.mssql) in jdbc_url:
+      db_type = ServerDatabases.mssql
+    elif str(ServerDatabases.derby) in jdbc_url:
+      db_type = ServerDatabases.derby
+
+  if persistence_type == "local" and db_type is None:
+    db_type = ServerDatabases.postgres_internal
 
   return db_type
 
@@ -528,19 +622,19 @@ def check_database_name_property(upgrade=False):
     return -1
 
   version = get_ambari_version(properties)
-  if upgrade and (properties[JDBC_DATABASE_PROPERTY] not in ["postgres", "oracle", "mysql", "mssql", "derby"]
+  if upgrade and (properties[JDBC_DATABASE_PROPERTY] not in ServerDatabases.databases()
                     or properties.has_key(JDBC_RCA_SCHEMA_PROPERTY)):
     # This code exists for historic reasons in which property names changed from Ambari 1.6.1 to 1.7.0
     persistence_type = properties[PERSISTENCE_TYPE_PROPERTY]
     if persistence_type == "remote":
-      db_name = properties["server.jdbc.schema"]  # this was a property in Ambari 1.6.1, but not after 1.7.0
+      db_name = properties[JDBC_RCA_SCHEMA_PROPERTY]  # this was a property in Ambari 1.6.1, but not after 1.7.0
       if db_name:
         write_property(JDBC_DATABASE_NAME_PROPERTY, db_name)
 
       # If DB type is missing, attempt to reconstruct it from the JDBC URL
       db_type = properties[JDBC_DATABASE_PROPERTY]
-      if db_type is None or db_type.strip().lower() not in ["postgres", "oracle", "mysql", "mssql", "derby"]:
-        db_type = get_db_type(properties)
+      if db_type is None or db_type.strip().lower() not in ServerDatabases.databases():
+        db_type = get_db_type(properties).name
         if db_type:
           write_property(JDBC_DATABASE_PROPERTY, db_type)
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/e482d7c4/ambari-server/src/main/python/ambari_server/serverUpgrade.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/python/ambari_server/serverUpgrade.py b/ambari-server/src/main/python/ambari_server/serverUpgrade.py
index a4fa24e..2ab4c94 100644
--- a/ambari-server/src/main/python/ambari_server/serverUpgrade.py
+++ b/ambari-server/src/main/python/ambari_server/serverUpgrade.py
@@ -37,7 +37,7 @@ from ambari_server.serverConfiguration import configDefaults, \
   get_java_exe_path, get_stack_location, parse_properties_file, read_ambari_user, update_ambari_properties, \
   update_database_name_property, get_admin_views_dir, \
   AMBARI_PROPERTIES_FILE, IS_LDAP_CONFIGURED, LDAP_PRIMARY_URL_PROPERTY, RESOURCES_DIR_PROPERTY, \
-  SETUP_OR_UPGRADE_MSG, update_krb_jaas_login_properties, AMBARI_KRB_JAAS_LOGIN_FILE
+  SETUP_OR_UPGRADE_MSG, update_krb_jaas_login_properties, AMBARI_KRB_JAAS_LOGIN_FILE, get_db_type
 from ambari_server.setupSecurity import adjust_directory_permissions, \
   generate_env, ensure_can_start_under_current_user
 from ambari_server.utils import compare_versions
@@ -216,6 +216,14 @@ def upgrade_local_repo(args):
 #
 
 def run_schema_upgrade():
+  db_title = get_db_type(get_ambari_properties()).title
+  confirm = get_YN_input("Ambari Server configured for %s. Confirm "
+                        "you have made a backup of the Ambari Server database [y/n] (y)? " % db_title, True)
+
+  if not confirm:
+    print_error_msg("Database backup is not confirmed")
+    return 1
+
   jdk_path = get_java_exe_path()
   if jdk_path is None:
     print_error_msg("No JDK found, please run the \"setup\" "
@@ -278,7 +286,6 @@ def upgrade(args):
   if not is_root():
     err = configDefaults.MESSAGE_ERROR_UPGRADE_NOT_ROOT
     raise FatalException(4, err)
-
   print 'Updating properties in ' + AMBARI_PROPERTIES_FILE + ' ...'
   retcode = update_ambari_properties()
   if not retcode == 0:

http://git-wip-us.apache.org/repos/asf/ambari/blob/e482d7c4/ambari-server/src/test/python/TestAmbariServer.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/TestAmbariServer.py b/ambari-server/src/test/python/TestAmbariServer.py
index ee07597..cd90592 100644
--- a/ambari-server/src/test/python/TestAmbariServer.py
+++ b/ambari-server/src/test/python/TestAmbariServer.py
@@ -4630,7 +4630,9 @@ class TestAmbariServer(TestCase):
   @patch("ambari_server.serverConfiguration.get_ambari_classpath")
   @patch("ambari_server.serverUpgrade.run_os_command")
   @patch("ambari_server.serverUpgrade.get_java_exe_path")
-  def test_run_schema_upgrade(self, java_exe_path_mock, run_os_command_mock,
+  @patch("ambari_server.serverUpgrade.get_ambari_properties")
+  @patch("ambari_server.serverUpgrade.get_YN_input")
+  def test_run_schema_upgrade(self, get_YN_input_mock, get_ambari_properties_mock, java_exe_path_mock, run_os_command_mock,
                               get_ambari_classpath_mock, get_conf_dir_mock,
                               read_ambari_user_mock, generate_env_mock,
                               ensure_can_start_under_current_user_mock):
@@ -4645,6 +4647,10 @@ class TestAmbariServer(TestCase):
     generate_env_mock.return_value = environ
     ensure_can_start_under_current_user_mock.return_value = "root"
     read_ambari_user_mock.return_value = "ambari"
+    properties = Properties()
+    properties.process_pair(PERSISTENCE_TYPE_PROPERTY, "local")
+    get_ambari_properties_mock.return_value = properties
+    get_YN_input_mock.return_value = True
 
     run_schema_upgrade()
 
@@ -4656,8 +4662,6 @@ class TestAmbariServer(TestCase):
     self.assertTrue(get_conf_dir_mock.called)
     self.assertTrue(run_os_command_mock.called)
     run_os_command_mock.assert_called_with(command, env=environ)
-    pass
-
 
   @patch("ambari_server.serverConfiguration.get_conf_dir")
   @patch("ambari_server.serverConfiguration.get_ambari_classpath")