浏览代码

AMBARI-13568. RU - Downgrade from 2.3 to 2.2 may fail if configs were not back'ed up (dlysnichenko)

Lisnichenko Dmitro 9 年之前
父节点
当前提交
6d662b17a7

+ 10 - 12
ambari-server/src/main/resources/custom_actions/scripts/ru_set_all.py

@@ -128,21 +128,19 @@ class UpgradeSetAll(Script):
 
 
     :original_conf_directory: the original conf directory that was made into a symlink (/etc/component/conf)
     :original_conf_directory: the original conf directory that was made into a symlink (/etc/component/conf)
     """
     """
-    if not os.path.islink(original_conf_directory):
-      Logger.info("Skipping the unlink of {0}; it is not a symlink or does not exist".format(original_conf_directory))
-      return
-
     # calculate the parent and backup directories
     # calculate the parent and backup directories
     original_conf_parent_directory = os.path.abspath(os.path.join(original_conf_directory, os.pardir))
     original_conf_parent_directory = os.path.abspath(os.path.join(original_conf_directory, os.pardir))
     backup_conf_directory = os.path.join(original_conf_parent_directory, "conf.backup")
     backup_conf_directory = os.path.join(original_conf_parent_directory, "conf.backup")
-
-    Logger.info("Unlinking {0} and restoring {1}".format(original_conf_directory, backup_conf_directory))
-
-    # remove the old symlink
-    Execute(("rm", original_conf_directory), sudo=True)
-
-    # rename the backup to the original name
-    Execute(("mv", backup_conf_directory, original_conf_directory), sudo=True)
+    if not os.path.isdir(backup_conf_directory):
+      Logger.info("Skipping restoring config from backup {0} since it does not exist".format(backup_conf_directory))
+    elif not os.path.islink(original_conf_directory):
+      Logger.info("Skipping the unlink of {0}; it is not a symlink or does not exist".format(original_conf_directory))
+    else:
+      Logger.info("Unlinking {0} and restoring {1}".format(original_conf_directory, backup_conf_directory))
+      # remove the old symlink
+      Execute(("rm", original_conf_directory), sudo=True)
+      # rename the backup to the original name
+      Execute(("mv", backup_conf_directory, original_conf_directory), sudo=True)
 
 
 
 
 def link_config(old_conf, link_conf):
 def link_config(old_conf, link_conf):

+ 42 - 1
ambari-server/src/test/python/custom_actions/test_ru_set_all.py

@@ -26,6 +26,7 @@ from mock.mock import patch
 from mock.mock import MagicMock
 from mock.mock import MagicMock
 
 
 # Module imports
 # Module imports
+import subprocess
 from stacks.utils.RMFTestCase import *
 from stacks.utils.RMFTestCase import *
 from resource_management import Script, ConfigDictionary
 from resource_management import Script, ConfigDictionary
 from resource_management.libraries.functions.default import default
 from resource_management.libraries.functions.default import default
@@ -34,6 +35,8 @@ from resource_management.core.logger import Logger
 from ambari_agent.AmbariConfig import AmbariConfig
 from ambari_agent.AmbariConfig import AmbariConfig
 from ambari_agent.FileCache import FileCache
 from ambari_agent.FileCache import FileCache
 from ambari_commons.os_check import OSCheck
 from ambari_commons.os_check import OSCheck
+from resource_management.core import shell
+import pprint
 
 
 
 
 def fake_call(command, **kwargs):
 def fake_call(command, **kwargs):
@@ -133,15 +136,19 @@ class TestRUSetAll(RMFTestCase):
 
 
 
 
   @patch("os.path.islink")
   @patch("os.path.islink")
+  @patch("os.path.isdir")
   @patch("resource_management.core.shell.call")
   @patch("resource_management.core.shell.call")
   @patch.object(Script, 'get_config')
   @patch.object(Script, 'get_config')
   @patch.object(OSCheck, 'is_redhat_family')
   @patch.object(OSCheck, 'is_redhat_family')
-  def test_downgrade_unlink_configs(self, family_mock, get_config_mock, call_mock, islink_mock):
+  def test_downgrade_unlink_configs(self, family_mock, get_config_mock, call_mock,
+                                    isdir_mock, islink_mock):
     """
     """
     Tests downgrading from 2.3 to 2.2 to ensure that conf symlinks are removed and the backup
     Tests downgrading from 2.3 to 2.2 to ensure that conf symlinks are removed and the backup
     directories restored.
     directories restored.
     """
     """
 
 
+    isdir_mock.return_value = True
+
     # required for the test to run since the Execute calls need this
     # required for the test to run since the Execute calls need this
     from resource_management.core.environment import Environment
     from resource_management.core.environment import Environment
     env = Environment(test_mode=True)
     env = Environment(test_mode=True)
@@ -237,3 +244,37 @@ class TestRUSetAll(RMFTestCase):
 
 
     # ensure it wasn't called this time
     # ensure it wasn't called this time
     self.assertFalse(islink_mock.called)
     self.assertFalse(islink_mock.called)
+
+
+  @patch("os.path.isdir")
+  @patch("os.path.islink")
+  def test_unlink_configs_missing_backup(self, islink_mock, isdir_mock):
+
+    # required for the test to run since the Execute calls need this
+    from resource_management.core.environment import Environment
+    env = Environment(test_mode=True)
+    env._instances.append(env)
+
+    # Case: missing backup directory
+    isdir_mock.return_value = False
+    ru_execute = UpgradeSetAll()
+    self.assertEqual(len(env.resource_list), 0)
+    # Case: missing symlink
+    isdir_mock.reset_mock()
+    isdir_mock.return_value = True
+    islink_mock.return_value = False
+    ru_execute._unlink_config("/fake/config")
+    self.assertEqual(len(env.resource_list), 0)
+    # Case: missing symlink
+    isdir_mock.reset_mock()
+    isdir_mock.return_value = True
+    islink_mock.reset_mock()
+    islink_mock.return_value = True
+
+    ru_execute._unlink_config("/fake/config")
+    self.assertEqual(pprint.pformat(env.resource_list),
+                     "[Execute[('rm', '/fake/config')],\n"
+                     " Execute[('mv', '/fake/conf.backup', "
+                     "'/fake/config')]]")
+
+