You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by jo...@apache.org on 2014/09/13 01:53:52 UTC

[24/30] git commit: AMBARI-7214. Upgrade to Ambari 1.7.0 requires updating server.jdbc.database_name property in ambari.properties (alejandro)

AMBARI-7214. Upgrade to Ambari 1.7.0 requires updating server.jdbc.database_name property in ambari.properties (alejandro)


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

Branch: refs/heads/branch-alerts-dev
Commit: bd28cd9e80dc6026e7c4dfa768b4f14318185644
Parents: 3cf2ee4
Author: Alejandro Fernandez <af...@hortonworks.com>
Authored: Thu Sep 11 16:21:42 2014 -0700
Committer: Alejandro Fernandez <af...@hortonworks.com>
Committed: Fri Sep 12 10:22:50 2014 -0700

----------------------------------------------------------------------
 .../server/configuration/Configuration.java     |  1 -
 ambari-server/src/main/python/ambari-server.py  | 71 +++++++++++++++-----
 .../src/test/python/TestAmbariServer.py         | 52 +++++++++++---
 3 files changed, 98 insertions(+), 26 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/bd28cd9e/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java b/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
index a3a07b0..78fd7b6 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
@@ -106,7 +106,6 @@ public class Configuration {
   public static final String CLIENT_API_SSL_CRT_PASS_FILE_NAME_KEY = "client.api.ssl.cert_pass_file";
   public static final String CLIENT_API_SSL_CRT_PASS_KEY = "client.api.ssl.crt_pass";
   public static final String CLIENT_API_SSL_KEY_NAME_KEY = "client.api.ssl.key_name";
-  public static final String SERVER_DB_TYPE_KEY = "server.jdbc.database";       // E.g., oracle|mysql|postgres
   public static final String SERVER_DB_NAME_KEY = "server.jdbc.database_name";
   public static final String SERVER_DB_NAME_DEFAULT = "ambari";
   public static final String SERVER_JDBC_POSTGRES_SCHEMA_NAME = "server.jdbc.postgres.schema";

http://git-wip-us.apache.org/repos/asf/ambari/blob/bd28cd9e/ambari-server/src/main/python/ambari-server.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/python/ambari-server.py b/ambari-server/src/main/python/ambari-server.py
index 35ba17b..50420b2 100755
--- a/ambari-server/src/main/python/ambari-server.py
+++ b/ambari-server/src/main/python/ambari-server.py
@@ -304,7 +304,7 @@ DATABASE_INDEX = 0
 PROMPT_DATABASE_OPTIONS = False
 USERNAME_PATTERN = "^[a-zA-Z_][a-zA-Z0-9_\-]*$"
 PASSWORD_PATTERN = "^[a-zA-Z0-9_-]*$"
-DATABASE_NAMES = ["postgres", "oracle", "mysql"]
+DATABASE_TYPES = ["postgres", "oracle", "mysql"]
 DATABASE_STORAGE_NAMES = ["Database", "Service", "Database"]
 DATABASE_PORTS = ["5432", "1521", "3306"]
 DATABASE_DRIVER_NAMES = ["org.postgresql.Driver", "oracle.jdbc.driver.OracleDriver", "com.mysql.jdbc.Driver"]
@@ -838,8 +838,6 @@ def restart_postgres():
   return 0, "", ""
 
 
-# todo: check if the scheme is already exist
-
 def write_property(key, value):
   conf_file = find_properties_file()
   properties = Properties()
@@ -1087,7 +1085,7 @@ def get_pass_file_path(conf_file):
 # Set database properties to default values
 def load_default_db_properties(args):
   args.persistence_type = 'local'
-  args.dbms = DATABASE_NAMES[DATABASE_INDEX]
+  args.dbms = DATABASE_TYPES[DATABASE_INDEX]
   args.database_host = "localhost"
   args.database_port = DATABASE_PORTS[DATABASE_INDEX]
   args.database_name = DEFAULT_DB_NAME
@@ -1141,7 +1139,7 @@ def prompt_db_properties(args):
       pass
 
       DATABASE_INDEX = args.database_index
-      args.dbms = DATABASE_NAMES[args.database_index]
+      args.dbms = DATABASE_TYPES[args.database_index]
 
       if args.persistence_type != 'local':
         args.database_host = get_validated_string_input(
@@ -1386,12 +1384,48 @@ def configure_database_password(showDefault=True):
   return password
 
 
-def check_database_name_property():
+def get_ambari_version(properties):
+  """
+  :param properties: Ambari properties
+  :return: Return a string of the ambari version. When comparing versions, please use "compare_versions" function.
+  """
+  version = None
+  try:
+    server_version_file_path = properties[SERVER_VERSION_FILE_PATH]
+    if server_version_file_path and os.path.exists(server_version_file_path):
+      with open(server_version_file_path, 'r') as file:
+        version = file.read().strip()
+  except:
+    print_error_msg("Error getting ambari version")
+  return version
+
+
+def check_database_name_property(args, upgrade=False):
+  """
+  :param upgrade: If Ambari is being upgraded.
+  :return:
+  """
   properties = get_ambari_properties()
   if properties == -1:
     print_error_msg("Error getting ambari properties")
     return -1
 
+  version = get_ambari_version(properties)
+  if upgrade and compare_versions(version, "1.7.0") >= 0:
+
+    expected_db_name = properties[JDBC_DATABASE_NAME_PROPERTY]
+    # The existing ambari config file is probably from an earlier version of Ambari, and needs to be transformed.
+    if expected_db_name is None or expected_db_name == "":
+      db_name = properties[JDBC_DATABASE_PROPERTY]
+
+      if db_name:
+        write_property(JDBC_DATABASE_NAME_PROPERTY, db_name)
+        remove_property(JDBC_DATABASE_PROPERTY)
+        properties = get_ambari_properties()
+      else:
+        err = "DB Name property not set in config file.\n" + SETUP_OR_UPGRADE_MSG
+        raise FatalException(-1, "Upgrade to version %s cannot transform config file." % str(version))
+
   dbname = properties[JDBC_DATABASE_NAME_PROPERTY]
   if dbname is None or dbname == "":
     err = "DB Name property not set in config file.\n" + SETUP_OR_UPGRADE_MSG
@@ -1523,7 +1557,7 @@ def parse_properties_file(args):
     args.database_port = properties[JDBC_PORT_PROPERTY]
     global DATABASE_INDEX
     try:
-      DATABASE_INDEX = DATABASE_NAMES.index(args.dbms)
+      DATABASE_INDEX = DATABASE_TYPES.index(args.dbms)
     except ValueError:
       pass
 
@@ -2297,7 +2331,7 @@ def reset(args):
     err = "Ambari Server 'reset' cancelled"
     raise FatalException(1, err)
 
-  check_database_name_property()
+  check_database_name_property(args)
   parse_properties_file(args)
 
   if args.persistence_type == "remote":
@@ -2370,7 +2404,7 @@ def start(args):
           "command as root, as sudo or as user \"{1}\"".format(current_user, ambari_user)
     raise FatalException(1, err)
 
-  check_database_name_property()
+  check_database_name_property(args)
   parse_properties_file(args)
 
   status, pid = is_server_runing()
@@ -2540,7 +2574,7 @@ def upgrade_stack(args, stack_id, repo_url=None, repo_url_os=None):
     err = 'Ambari-server upgradestack should be run with ' \
           'root-level privileges'
     raise FatalException(4, err)
-  check_database_name_property()
+  check_database_name_property(args)
 
   stack_name, stack_version = stack_id.split(STACK_NAME_VER_SEP)
   retcode = run_stack_upgrade(stack_name, stack_version, repo_url, repo_url_os)
@@ -2726,7 +2760,7 @@ def upgrade(args):
     raise FatalException(retcode, err)
 
   try:
-    check_database_name_property()
+    check_database_name_property(args, upgrade=True)
   except FatalException:
     properties = get_ambari_properties()
     if properties == -1:
@@ -4170,12 +4204,12 @@ def main():
     options.database_index = 0
     DATABASE_INDEX = 0
     pass
-  elif options.dbms is not None and options.dbms not in DATABASE_NAMES:
+  elif options.dbms is not None and options.dbms not in DATABASE_TYPES:
     parser.print_help()
     parser.error("Unsupported Database " + options.dbms)
   elif options.dbms is not None:
     options.dbms = options.dbms.lower()
-    DATABASE_INDEX = DATABASE_NAMES.index(options.dbms)
+    DATABASE_INDEX = DATABASE_TYPES.index(options.dbms)
 
   #correct port
   if options.database_port is not None:
@@ -4339,6 +4373,9 @@ class Properties(object):
       self.process_pair(key, value)
 
   def process_pair(self, key, value):
+    """
+    Adds or overrides the property with the given key.
+    """
     oldkey = key
     oldvalue = value
     keyparts = self.bspacere.split(key)
@@ -4407,7 +4444,9 @@ class Properties(object):
 
   def store(self, out, header=""):
     """ Write the properties list to the stream 'out' along
-    with the optional 'header' """
+    with the optional 'header'
+    This function will attempt to close the file handler once it's done.
+    """
     if out.mode[0] != 'w':
       raise ValueError, 'Steam should be opened in write mode!'
     try:
@@ -4420,9 +4459,11 @@ class Properties(object):
       for prop, val in self._origprops.items():
         if val is not None:
           out.write(''.join((prop, '=', val, '\n')))
-      out.close()
     except IOError:
       raise
+    finally:
+      if out:
+        out.close()
 
 if __name__ == "__main__":
   try:

http://git-wip-us.apache.org/repos/asf/ambari/blob/bd28cd9e/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 53f0ba1..ebd691d 100644
--- a/ambari-server/src/test/python/TestAmbariServer.py
+++ b/ambari-server/src/test/python/TestAmbariServer.py
@@ -27,6 +27,7 @@ import stat
 import datetime
 import operator
 import json
+from optparse import OptionParser
 import platform
 import shutil
 from pwd import getpwnam
@@ -43,7 +44,7 @@ with patch("platform.linux_distribution", return_value = ('Suse','11','Final')):
 
 FatalException = ambari_server.FatalException
 NonFatalException = ambari_server.NonFatalException
-
+CURR_AMBARI_VERSION = "1.7.0"
 
 class TestAmbariServer(TestCase):
   def setUp(self):
@@ -3176,6 +3177,32 @@ MIIFHjCCAwYCCQDpHKOBI+Lt0zANBgkqhkiG9w0BAQUFADBRMQswCQYDVQQGEwJV
     self.assertEquals(os_symlink_mock.call_args_list[0][0][1], os.path.join("somewhere","postgres-jdbc-driver.jar"))
 
 
+  @patch.object(ambari_server, "write_property")
+  @patch.object(ambari_server, "find_properties_file")
+  @patch.object(ambari_server, "is_root")
+  @patch.object(ambari_server, "get_ambari_version")
+  @patch.object(ambari_server, "get_ambari_properties")
+  def test_upgrade_from_161(self, get_ambari_properties_mock, get_ambari_version_mock, is_root_mock, find_properties_file_mock,
+                            write_property_mock):
+    args = MagicMock()
+    args.dbms = "postgres"
+    is_root_mock.return_value = True
+
+    # In Ambari 1.6.1, the DB name was actually stored in JDBC_DATABASE_PROPERTY, and the JDBC_DATABASE_NAME_PROPERTY
+    # property didn't exist. When upgrading to Ambari 1.7.0, the ambari.properties file should be transformed.
+    get_ambari_version_mock.return_value = "1.7.0"
+
+    properties = ambari_server.Properties()
+    properties.process_pair(ambari_server.JDBC_DATABASE_PROPERTY, "ambari")
+    get_ambari_properties_mock.return_value = properties
+
+    try:
+      ambari_server.upgrade(args)
+    except FatalException as fe:
+      self.fail("Did not expect failure: " + str(fe))
+    else:
+      self.assertTrue(write_property_mock.called)
+
 
   @patch("__builtin__.open")
   @patch("os.path.isfile")
@@ -3190,11 +3217,12 @@ MIIFHjCCAwYCCQDpHKOBI+Lt0zANBgkqhkiG9w0BAQUFADBRMQswCQYDVQQGEwJV
   @patch.object(ambari_server, "run_schema_upgrade")
   @patch.object(ambari_server, "update_ambari_properties")
   @patch.object(ambari_server, "parse_properties_file")
+  @patch.object(ambari_server, "get_ambari_version")
   @patch.object(ambari_server, "is_root")
   @patch.object(ambari_server, "get_ambari_properties")
   @patch.object(ambari_server, "upgrade_local_repo")
   def test_upgrade(self, upgrade_local_repo_mock,
-                   get_ambari_properties_mock, is_root_mock,
+                   get_ambari_properties_mock, is_root_mock, get_ambari_version_mock,
                    parse_properties_file_mock,
                    update_ambari_properties_mock, run_schema_upgrade_mock,
                    read_ambari_user_mock, print_warning_msg_mock,
@@ -3204,10 +3232,10 @@ MIIFHjCCAwYCCQDpHKOBI+Lt0zANBgkqhkiG9w0BAQUFADBRMQswCQYDVQQGEwJV
 
     args = MagicMock()
     check_database_name_property_mock = MagicMock()
-
     update_ambari_properties_mock.return_value = 0
     run_schema_upgrade_mock.return_value = 0
     isfile_mock.return_value = False
+    get_ambari_version_mock.return_value = CURR_AMBARI_VERSION
 
     # Testing call under non-root
     is_root_mock.return_value = False
@@ -3262,7 +3290,7 @@ MIIFHjCCAwYCCQDpHKOBI+Lt0zANBgkqhkiG9w0BAQUFADBRMQswCQYDVQQGEwJV
     p = MagicMock()
     get_ambari_properties_mock.reset_mock()
     get_ambari_properties_mock.return_value = p
-    p.__getitem__.side_effect = ["something", KeyError("test exception")]
+    p.__getitem__.side_effect = ["something", "something", KeyError("test exception")]
     fail = False
 
     try:
@@ -3271,9 +3299,9 @@ MIIFHjCCAwYCCQDpHKOBI+Lt0zANBgkqhkiG9w0BAQUFADBRMQswCQYDVQQGEwJV
       fail = True
     self.assertTrue(fail)
 
-    # test if some drivers are available in reources, and symlink available too
+    # test if some drivers are available in resources, and symlink available too
     p.reset_mock()
-    p.__getitem__.side_effect = ["something", "resources"]
+    p.__getitem__.side_effect = ["something", "something", "resources"]
     lexists_mock.return_value = True
     isfile_mock.side_effect = [True, False, False]
     ambari_server.upgrade(args)
@@ -3281,8 +3309,8 @@ MIIFHjCCAwYCCQDpHKOBI+Lt0zANBgkqhkiG9w0BAQUFADBRMQswCQYDVQQGEwJV
     self.assertEquals(os_remove_mock.call_count, 1)
     self.assertEquals(os_remove_mock.call_args[0][0], os.path.join("resources", "oracle-jdbc-driver.jar"))
     self.assertEquals(os_symlink_mock.call_count, 1)
-    self.assertEquals(os_symlink_mock.call_args[0][0], os.path.join("resources","ojdbc6.jar"))
-    self.assertEquals(os_symlink_mock.call_args[0][1], os.path.join("resources","oracle-jdbc-driver.jar"))
+    self.assertEquals(os_symlink_mock.call_args[0][0], os.path.join("resources", "ojdbc6.jar"))
+    self.assertEquals(os_symlink_mock.call_args[0][1], os.path.join("resources", "oracle-jdbc-driver.jar"))
 
 
   def test_print_info_msg(self):
@@ -4898,10 +4926,14 @@ MIIFHjCCAwYCCQDpHKOBI+Lt0zANBgkqhkiG9w0BAQUFADBRMQswCQYDVQQGEwJV
 
   @patch.object(ambari_server, "get_ambari_properties")
   def test_check_database_name_property(self, get_ambari_properties_mock):
+    parser = OptionParser()
+    parser.add_option('--database', default=None, help="Database to use embedded|oracle|mysql|postgres", dest="dbms")
+    args = parser.parse_args()
+
     # negative case
     get_ambari_properties_mock.return_value = {ambari_server.JDBC_DATABASE_NAME_PROPERTY: ""}
     try:
-      result = ambari_server.check_database_name_property()
+      result = ambari_server.check_database_name_property(args)
       self.fail("Should fail with exception")
     except FatalException as e:
       self.assertTrue('DB Name property not set in config file.' in e.reason)
@@ -4911,7 +4943,7 @@ MIIFHjCCAwYCCQDpHKOBI+Lt0zANBgkqhkiG9w0BAQUFADBRMQswCQYDVQQGEwJV
     get_ambari_properties_mock.reset_mock()
     get_ambari_properties_mock.return_value = {ambari_server.JDBC_DATABASE_NAME_PROPERTY: dbname}
     try:
-      result = ambari_server.check_database_name_property()
+      result = ambari_server.check_database_name_property(args)
     except FatalException:
       self.fail("Setup should be successful")