You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ha...@apache.org on 2018/05/02 13:30:07 UTC

[ambari] branch trunk updated: AMBARI-23717 Stack installation command didn't fail properly when installed package didn't present in repository (dgrinenko)

This is an automated email from the ASF dual-hosted git repository.

hapylestat pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ambari.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 10e2c58  AMBARI-23717 Stack installation command didn't fail properly when installed package didn't present in repository (dgrinenko)
10e2c58 is described below

commit 10e2c58c47b4880c61df46c91ba9fc46a75f4374
Author: Dmitry Grinenko <ha...@gmail.com>
AuthorDate: Fri Apr 27 20:46:29 2018 +0300

    AMBARI-23717 Stack installation command didn't fail properly when installed package didn't present in repository (dgrinenko)
---
 .../ambari_commons/repo_manager/apt_manager.py     | 15 +++++++--
 .../ambari_commons/repo_manager/generic_manager.py |  6 ++++
 .../ambari_commons/repo_manager/yum_manager.py     | 13 +++++++-
 .../ambari_commons/repo_manager/zypper_manager.py  | 17 ++++++++--
 .../resource_management/libraries/script/script.py | 33 +++++++++++++------
 .../python/custom_actions/TestInstallPackages.py   | 37 +++++++++++-----------
 6 files changed, 88 insertions(+), 33 deletions(-)

diff --git a/ambari-common/src/main/python/ambari_commons/repo_manager/apt_manager.py b/ambari-common/src/main/python/ambari_commons/repo_manager/apt_manager.py
index 38cf602..9f4330a 100644
--- a/ambari-common/src/main/python/ambari_commons/repo_manager/apt_manager.py
+++ b/ambari-common/src/main/python/ambari_commons/repo_manager/apt_manager.py
@@ -215,12 +215,16 @@ class AptManager(GenericManager):
 
     :type name str
     :type context ambari_commons.shell.RepoCallContext
+
+    :raise ValueError if name is empty
     """
     from resource_management.core import sudo
 
     apt_sources_list_tmp_dir = None
 
-    if context.is_upgrade or context.use_repos or not self._check_existence(name):
+    if not name:
+      raise ValueError("Installation command was executed with no package name")
+    elif context.is_upgrade or context.use_repos or not self._check_existence(name):
       cmd = self.properties.install_cmd[context.log_output]
       copied_sources_files = []
       is_tmp_dir_created = False
@@ -264,6 +268,8 @@ class AptManager(GenericManager):
 
     :type name str
     :type context ambari_commons.shell.RepoCallContext
+
+    :raise ValueError if name is empty
     """
     context.is_upgrade = True
     return self.install_package(name, context)
@@ -276,8 +282,12 @@ class AptManager(GenericManager):
     :type name str
     :type context ambari_commons.shell.RepoCallContext
     :type ignore_dependencies bool
+
+    :raise ValueError if name is empty
     """
-    if self._check_existence(name):
+    if not name:
+      raise ValueError("Installation command were executed with no package name passed")
+    elif self._check_existence(name):
       cmd = self.properties.remove_cmd[context.log_output] + [name]
       Logger.info("Removing package {0} ('{1}')".format(name, shell.string_cmd_from_args_list(cmd)))
       shell.repository_manager_executor(cmd, self.properties, context)
@@ -304,5 +314,6 @@ class AptManager(GenericManager):
     apt-get in inconsistant state (locked, used, having invalid repo). Once packages are installed
     we should not rely on that.
     """
+
     r = shell.subprocess_executor(self.properties.check_cmd % name)
     return not bool(r.code)
diff --git a/ambari-common/src/main/python/ambari_commons/repo_manager/generic_manager.py b/ambari-common/src/main/python/ambari_commons/repo_manager/generic_manager.py
index d4e1e08..3b6056c 100644
--- a/ambari-common/src/main/python/ambari_commons/repo_manager/generic_manager.py
+++ b/ambari-common/src/main/python/ambari_commons/repo_manager/generic_manager.py
@@ -69,6 +69,8 @@ class GenericManager(object):
 
     :type name str
     :type context ambari_commons.shell.RepoCallContext
+
+    :raise ValueError if name is empty
     """
     raise NotImplementedError()
 
@@ -79,6 +81,8 @@ class GenericManager(object):
     :type name str
     :type context ambari_commons.shell.RepoCallContext
     :type ignore_dependencies bool
+
+    :raise ValueError if name is empty
     """
     raise NotImplementedError()
 
@@ -88,6 +92,8 @@ class GenericManager(object):
 
     :type name str
     :type context ambari_commons.shell.RepoCallContext
+
+    :raise ValueError if name is empty
     """
     raise NotImplementedError()
 
diff --git a/ambari-common/src/main/python/ambari_commons/repo_manager/yum_manager.py b/ambari-common/src/main/python/ambari_commons/repo_manager/yum_manager.py
index 5e404b1..7df4632 100644
--- a/ambari-common/src/main/python/ambari_commons/repo_manager/yum_manager.py
+++ b/ambari-common/src/main/python/ambari_commons/repo_manager/yum_manager.py
@@ -202,9 +202,13 @@ class YumManager(GenericManager):
 
     :type name str
     :type context ambari_commons.shell.RepoCallContext
+
+    :raise ValueError if name is empty
     """
 
-    if context.is_upgrade or context.use_repos or not self._check_existence(name):
+    if not name:
+      raise ValueError("Installation command was executed with no package name")
+    elif context.is_upgrade or context.use_repos or not self._check_existence(name):
       cmd = self.properties.install_cmd[context.log_output]
       if context.use_repos:
         enable_repo_option = '--enablerepo=' + ",".join(sorted(context.use_repos.keys()))
@@ -222,6 +226,8 @@ class YumManager(GenericManager):
 
     :type name str
     :type context ambari_commons.shell.RepoCallContext
+
+    :raise ValueError if name is empty
     """
     context.is_upgrade = True
     return self.install_package(name, context)
@@ -233,7 +239,11 @@ class YumManager(GenericManager):
     :type name str
     :type context ambari_commons.shell.RepoCallContext
     :type ignore_dependencies bool
+
+    :raise ValueError if name is empty
     """
+    if not name:
+      raise ValueError("Remove command were executed with no package name passed")
     if self._check_existence(name):
       if ignore_dependencies:
         cmd = self.properties.remove_without_dependencies_cmd + [name]
@@ -263,6 +273,7 @@ class YumManager(GenericManager):
     yum in inconsistant state (locked, used, having invalid repo). Once packages are installed
     we should not rely on that.
     """
+
     if os.geteuid() == 0:
       return self.yum_check_package_available(name)
     else:
diff --git a/ambari-common/src/main/python/ambari_commons/repo_manager/zypper_manager.py b/ambari-common/src/main/python/ambari_commons/repo_manager/zypper_manager.py
index 8617ef9..8d901c2 100644
--- a/ambari-common/src/main/python/ambari_commons/repo_manager/zypper_manager.py
+++ b/ambari-common/src/main/python/ambari_commons/repo_manager/zypper_manager.py
@@ -178,8 +178,12 @@ class ZypperManager(GenericManager):
 
     :type name str
     :type context ambari_commons.shell.RepoCallContext
+
+    :raise ValueError if name is empty
     """
-    if context.is_upgrade or context.use_repos or not self._check_existence(name):
+    if not name:
+      raise ValueError("Installation command was executed with no package name")
+    elif context.is_upgrade or context.use_repos or not self._check_existence(name):
       cmd = self.properties.install_cmd[context.log_output]
 
       if context.use_repos:
@@ -206,6 +210,8 @@ class ZypperManager(GenericManager):
 
     :type name str
     :type context ambari_commons.shell.RepoCallContext
+
+    :raise ValueError if name is empty
     """
     context.is_upgrade = True
     return self.install_package(name, context)
@@ -217,8 +223,12 @@ class ZypperManager(GenericManager):
     :type name str
     :type context ambari_commons.shell.RepoCallContext
     :type ignore_dependencies bool
+
+    :raise ValueError if name is empty
     """
-    if self._check_existence(name):
+    if not name:
+      raise ValueError("Installation command were executed with no package name passed")
+    elif self._check_existence(name):
       cmd = self.properties.remove_cmd[context.log_output] + [name]
       Logger.info("Removing package {0} ('{1}')".format(name, shell.string_cmd_from_args_list(cmd)))
       shell.repository_manager_executor(cmd, self.properties, context)
@@ -282,4 +292,7 @@ class ZypperManager(GenericManager):
     zypper in inconsistant state (locked, used, having invalid repo). Once packages are installed
     we should not rely on that.
     """
+    if not name:
+      raise ValueError("Package name can't be empty")
+
     return self.rpm_check_package_available(name)
diff --git a/ambari-common/src/main/python/resource_management/libraries/script/script.py b/ambari-common/src/main/python/resource_management/libraries/script/script.py
index 626aa19..1ddc49a 100644
--- a/ambari-common/src/main/python/resource_management/libraries/script/script.py
+++ b/ambari-common/src/main/python/resource_management/libraries/script/script.py
@@ -491,24 +491,41 @@ class Script(object):
 
     return Script.stack_version_from_distro_select
 
-
-  def get_package_from_available(self, name, available_packages_in_repos):
+  def get_package_from_available(self, name, available_packages_in_repos=None):
     """
     This function matches package names with ${stack_version} placeholder to actual package names from
     Ambari-managed repository.
     Package names without ${stack_version} placeholder are returned as is.
     """
+
     if STACK_VERSION_PLACEHOLDER not in name:
       return name
+
+    if not available_packages_in_repos:
+      available_packages_in_repos = self.load_available_packages()
+
+    from resource_management.libraries.functions.default import default
+
     package_delimiter = '-' if OSCheck.is_ubuntu_family() else '_'
     package_regex = name.replace(STACK_VERSION_PLACEHOLDER, '(\d|{0})+'.format(package_delimiter)) + "$"
+    repo = default('/repositoryFile', None)
+    name_with_version = None
+
+    if repo:
+      command_repo = CommandRepository(repo)
+      version_str = command_repo.version_string.replace('.', package_delimiter).replace("-", package_delimiter)
+      name_with_version = name.replace(STACK_VERSION_PLACEHOLDER, version_str)
+
     for package in available_packages_in_repos:
       if re.match(package_regex, package):
         return package
-    Logger.warning("No package found for {0}({1})".format(name, package_regex))
 
+    if name_with_version:
+      raise Fail("No package found for {0}(expected name: {1})".format(name, name_with_version))
+    else:
+      raise Fail("Cannot match package for regexp name {0}. Available packages: {1}".format(name, self.available_packages_in_repos))
 
-  def format_package_name(self, name, repo_version=None):
+  def format_package_name(self, name):
     from resource_management.libraries.functions.default import default
     """
     This function replaces ${stack_version} placeholder with actual version.  If the package
@@ -537,11 +554,7 @@ class Script(object):
       package_version = default("hostLevelParams/package_version", None)
 
     if (package_version is None or '-' not in package_version) and default('/repositoryFile', None):
-      self.load_available_packages()
-      package_name = self.get_package_from_available(name, self.available_packages_in_repos)
-      if package_name is None:
-        raise Fail("Cannot match package for regexp name {0}. Available packages: {1}".format(name, self.available_packages_in_repos))
-      return package_name
+      return self.get_package_from_available(name)
 
     if package_version is not None:
       package_version = package_version.replace('.', package_delimiter).replace('-', package_delimiter)
@@ -770,6 +783,8 @@ class Script(object):
       Logger.exception("Unable to load available packages")
       self.available_packages_in_repos = []
 
+    return self.available_packages_in_repos
+
 
   def install_packages(self, env):
     """
diff --git a/ambari-server/src/test/python/custom_actions/TestInstallPackages.py b/ambari-server/src/test/python/custom_actions/TestInstallPackages.py
index 7efe226..6e04938 100644
--- a/ambari-server/src/test/python/custom_actions/TestInstallPackages.py
+++ b/ambari-server/src/test/python/custom_actions/TestInstallPackages.py
@@ -49,14 +49,14 @@ class TestInstallPackages(RMFTestCase):
     self.maxDiff = None
 
   @staticmethod
-  def _add_packages(*args):
+  def _add_packages(*args, **kwargs):
     return [
       ["pkg1", "1.0", "repo"],
       ["pkg2", "2.0", "repo2"]
     ]
 
   @staticmethod
-  def _add_packages_available(*args):
+  def _add_packages_available(*args, **kwargs):
     return [
       ["hadoop_2_2_0_1_885", "1.0", "HDP-2.2"],
       ["hadooplzo_2_2_0_1_885", "1.0", "HDP-2.2"],
@@ -64,8 +64,8 @@ class TestInstallPackages(RMFTestCase):
     ]
 
   @staticmethod
-  def _add_packages_lookUpYum(*args):
-    return TestInstallPackages._add_packages_available(*args)
+  def _add_packages_lookUpYum(*args, **kwargs):
+    return TestInstallPackages._add_packages_available(*args, **kwargs)
 
   def test_get_installed_package_version(self):
     from ambari_commons.os_check import OSConst
@@ -185,18 +185,18 @@ class TestInstallPackages(RMFTestCase):
 
       get_provider.return_value = pkg_manager
 
-      self.executeScript("scripts/install_packages.py",
-                         classname="InstallPackages",
-                         command="actionexecute",
-                         config_dict = command_json,
-                         target=RMFTestCase.TARGET_CUSTOM_ACTIONS,
-                         os_type=('Redhat', '6.4', 'Final'),
-      )
-      self.assertTrue(put_structured_out_mock.called)
-      self.assertEquals(put_structured_out_mock.call_args[0][0],
-                        {'package_installation_result': 'SUCCESS',
-                         'repository_version_id': 1,
-                         'actual_version': VERSION_STUB})
+      try:
+        self.executeScript("scripts/install_packages.py",
+                           classname="InstallPackages",
+                           command="actionexecute",
+                           config_dict = command_json,
+                           target=RMFTestCase.TARGET_CUSTOM_ACTIONS,
+                           os_type=('Redhat', '6.4', 'Final'),
+        )
+      except Fail as e:
+        self.assertEquals(e.message, "Failed to distribute repositories/install packages")
+      else:
+        self.assertFalse("Packages can't be installed without repos")
 
       self.assertNoMoreResources()
 
@@ -339,7 +339,7 @@ class TestInstallPackages(RMFTestCase):
   _install_failed = False
 
   @staticmethod
-  def _add_packages_with_fail():
+  def _add_packages_with_fail(*args, **kwargs):
     arg = []
     arg.append(["pkg1_2_2_0_1_885_pack", "1.0", "repo"])
     arg.append(["pkg2_2_2_0_1_885_pack2", "2.0", "repo2"])
@@ -400,8 +400,7 @@ class TestInstallPackages(RMFTestCase):
       self.assertTrue(put_structured_out_mock.called)
       self.assertEquals(put_structured_out_mock.call_args[0][0],
                         {'repository_version_id': 1,
-                        'package_installation_result': 'FAIL',
-                         'actual_version': '2.2.0.1-885'})
+                        'package_installation_result': 'FAIL'})
       self.assertResourceCalled('Repository', 'HDP-UTILS-1.1.0.20',
                                 base_url=u'http://repo1/HDP/centos5/2.x/updates/2.2.0.0',
                                 action=['create'],

-- 
To stop receiving notification emails like this one, please contact
hapylestat@apache.org.