You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by dm...@apache.org on 2015/01/13 20:12:30 UTC
ambari git commit: AMBARI-9106. RMF checks existence of hbase_2_2_*
packages incorrectly (dlysnichenko)
Repository: ambari
Updated Branches:
refs/heads/trunk 3d445e739 -> b3ff359ad
AMBARI-9106. RMF checks existence of hbase_2_2_* packages incorrectly (dlysnichenko)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/b3ff359a
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/b3ff359a
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/b3ff359a
Branch: refs/heads/trunk
Commit: b3ff359ad3ac00cbc045fb1d8fe2b9c3955ffd81
Parents: 3d445e7
Author: Lisnichenko Dmitro <dl...@hortonworks.com>
Authored: Tue Jan 13 21:11:33 2015 +0200
Committer: Lisnichenko Dmitro <dl...@hortonworks.com>
Committed: Tue Jan 13 21:11:33 2015 +0200
----------------------------------------------------------------------
.../resource_management/TestPackageResource.py | 92 +++++++++++++++++++-
.../core/providers/package/apt.py | 21 ++++-
.../core/providers/package/yumrpm.py | 11 ++-
.../core/providers/package/zypper.py | 14 ++-
4 files changed, 127 insertions(+), 11 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/b3ff359a/ambari-agent/src/test/python/resource_management/TestPackageResource.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/resource_management/TestPackageResource.py b/ambari-agent/src/test/python/resource_management/TestPackageResource.py
index 73f0a9d..e585826 100644
--- a/ambari-agent/src/test/python/resource_management/TestPackageResource.py
+++ b/ambari-agent/src/test/python/resource_management/TestPackageResource.py
@@ -35,7 +35,7 @@ class TestPackageResource(TestCase):
with Environment('/') as env:
Package("some_package",
)
- call_mock.assert_has_calls([call("dpkg --get-selections | grep -v deinstall | awk '{print $1}' | grep ^some-package$"),
+ call_mock.assert_has_calls([call("dpkg --get-selections | grep -v deinstall | awk '{print $1}' | grep '^some-package$'"),
call(['/usr/bin/apt-get', '-q', '-o', 'Dpkg::Options::=--force-confdef', '--allow-unauthenticated', '--assume-yes', 'install', 'some-package'], logoutput=False, sudo=True, env={'DEBIAN_FRONTEND': 'noninteractive'}),
call(['/usr/bin/apt-get', 'update', '-qq'], logoutput=False, sudo=True)])
@@ -50,12 +50,48 @@ class TestPackageResource(TestCase):
with Environment('/') as env:
Package("some_package",
)
- call_mock.assert_has_calls([call("dpkg --get-selections | grep -v deinstall | awk '{print $1}' | grep ^some-package$"),
+ call_mock.assert_has_calls([call("dpkg --get-selections | grep -v deinstall | awk '{print $1}' | grep '^some-package$'"),
call(['/usr/bin/apt-get', '-q', '-o', 'Dpkg::Options::=--force-confdef', '--allow-unauthenticated', '--assume-yes', 'install', 'some-package'], logoutput=False, sudo=True, env={'DEBIAN_FRONTEND': 'noninteractive'})])
self.assertEqual(shell_mock.call_count, 0, "shell.checked_call shouldn't be called")
+ @patch.object(shell, "call")
+ @patch.object(shell, "checked_call")
+ @patch.object(System, "os_family", new = 'ubuntu')
+ def test_action_install_regex_ubuntu(self, shell_mock, call_mock):
+ call_mock.side_effect = [(0, None),
+ (0, "some-package1\nsome-package2"),
+ (0, "Some text.\nStatus: install ok installed\nSome text"),
+ (0, "Some text.\nStatus: not installed\nSome text"),
+ (0, None)]
+ with Environment('/') as env:
+ Package("some_package.*",
+ )
+ call_mock.assert_has_calls([call("dpkg --get-selections | grep -v deinstall | awk '{print $1}' | grep '^some-package.*$'"),
+ call("apt-cache --names-only search '^some-package.*$' | awk '{print $1}'"),
+ call("dpkg --status 'some-package1'"),
+ call("dpkg --status 'some-package2'"),
+ call(['/usr/bin/apt-get', '-q', '-o', 'Dpkg::Options::=--force-confdef', '--allow-unauthenticated', '--assume-yes', 'install', 'some-package.*'], logoutput=False, sudo=True, env={'DEBIAN_FRONTEND': 'noninteractive'})])
+ self.assertEqual(shell_mock.call_count, 0, "shell.checked_call shouldn't be called")
+ @patch.object(shell, "call")
+ @patch.object(shell, "checked_call")
+ @patch.object(System, "os_family", new = 'ubuntu')
+ def test_action_install_regex_installed_ubuntu(self, shell_mock, call_mock):
+ call_mock.side_effect = [(0, None),
+ (0, "some-package1\nsome-package2"),
+ (0, "Some text.\nStatus: install ok installed\nSome text"),
+ (0, "Some text.\nStatus: install ok installed\nSome text"),
+ (0, None)]
+ with Environment('/') as env:
+ Package("some_package.*",
+ )
+ call_mock.assert_has_calls([call("dpkg --get-selections | grep -v deinstall | awk '{print $1}' | grep '^some-package.*$'"),
+ call("apt-cache --names-only search '^some-package.*$' | awk '{print $1}'"),
+ call("dpkg --status 'some-package1'"),
+ call("dpkg --status 'some-package2'")])
+ self.assertEqual(call_mock.call_count, 4, "Package should not be installed")
+ self.assertEqual(shell_mock.call_count, 0, "shell.checked_call shouldn't be called")
@patch.object(shell, "call")
@patch.object(shell, "checked_call")
@@ -65,20 +101,68 @@ class TestPackageResource(TestCase):
with Environment('/') as env:
Package("some_package",
)
- call_mock.assert_called_with('installed_pkgs=`rpm -qa some_package` ; [ ! -z "$installed_pkgs" ]')
+ call_mock.assert_called_with("installed_pkgs=`rpm -qa 'some_package'` ; [ ! -z \"$installed_pkgs\" ]")
shell_mock.assert_called_with(['/usr/bin/yum', '-d', '0', '-e', '0', '-y', 'install', 'some_package'], logoutput=False, sudo=True)
@patch.object(shell, "call")
@patch.object(shell, "checked_call")
+ @patch.object(System, "os_family", new = 'redhat')
+ def test_action_install_pattern_rhel(self, shell_mock, call_mock):
+ call_mock.side_effect=[(0, None), (1, "Some text")]
+ with Environment('/') as env:
+ Package("some_package*",
+ )
+ call_mock.assert_has_calls([call("installed_pkgs=`rpm -qa 'some_package*'` ; [ ! -z \"$installed_pkgs\" ]"),
+ call("! yum list available 'some_package*'")])
+ shell_mock.assert_called_with(['/usr/bin/yum', '-d', '0', '-e', '0', '-y', 'install', 'some_package*'], logoutput=False, sudo=True)
+
+ @patch.object(shell, "call")
+ @patch.object(shell, "checked_call")
+ @patch.object(System, "os_family", new = 'redhat')
+ def test_action_install_pattern_installed_rhel(self, shell_mock, call_mock):
+ call_mock.side_effect=[(0, None), (0, "Some text")]
+ with Environment('/') as env:
+ Package("some_package*",
+ )
+ call_mock.assert_has_calls([call("installed_pkgs=`rpm -qa 'some_package*'` ; [ ! -z \"$installed_pkgs\" ]"),
+ call("! yum list available 'some_package*'")])
+ self.assertEqual(shell_mock.call_count, 0, "shell.checked_call shouldn't be called")
+
+ @patch.object(shell, "call")
+ @patch.object(shell, "checked_call")
@patch.object(System, "os_family", new = 'suse')
def test_action_install_suse(self, shell_mock, call_mock):
call_mock.return_value= (1, None)
with Environment('/') as env:
Package("some_package",
)
- call_mock.assert_called_with('installed_pkgs=`rpm -qa some_package` ; [ ! -z "$installed_pkgs" ]')
+ call_mock.assert_called_with("installed_pkgs=`rpm -qa 'some_package'` ; [ ! -z \"$installed_pkgs\" ]")
shell_mock.assert_called_with(['/usr/bin/zypper', '--quiet', 'install', '--auto-agree-with-licenses', '--no-confirm', 'some_package'], logoutput=False, sudo=True)
+ @patch.object(shell, "call")
+ @patch.object(shell, "checked_call")
+ @patch.object(System, "os_family", new = 'suse')
+ def test_action_install_pattern_suse(self, shell_mock, call_mock):
+ call_mock.side_effect=[(0, None), (0, "Loading repository data...\nReading installed packages...\n\nS | Name\n--+-----\n | Pack")]
+ with Environment('/') as env:
+ Package("some_package*",
+ )
+ call_mock.assert_has_calls([call("installed_pkgs=`rpm -qa 'some_package*'` ; [ ! -z \"$installed_pkgs\" ]"),
+ call("zypper --non-interactive search --type package --uninstalled-only --match-exact 'some_package*'")])
+ shell_mock.assert_called_with(['/usr/bin/zypper', '--quiet', 'install', '--auto-agree-with-licenses', '--no-confirm', 'some_package*'], logoutput=False, sudo=True)
+
+ @patch.object(shell, "call")
+ @patch.object(shell, "checked_call")
+ @patch.object(System, "os_family", new = 'suse')
+ def test_action_install_pattern_suse(self, shell_mock, call_mock):
+ call_mock.side_effect=[(0, None), (0, "Loading repository data...\nReading installed packages...\nNo packages found.\n")]
+ with Environment('/') as env:
+ Package("some_package*",
+ )
+ call_mock.assert_has_calls([call("installed_pkgs=`rpm -qa 'some_package*'` ; [ ! -z \"$installed_pkgs\" ]"),
+ call("zypper --non-interactive search --type package --uninstalled-only --match-exact 'some_package*'")])
+ self.assertEqual(shell_mock.call_count, 0, "shell.checked_call shouldn't be called")
+
@patch.object(shell, "call", new = MagicMock(return_value=(0, None)))
@patch.object(shell, "checked_call")
@patch.object(System, "os_family", new = 'redhat')
http://git-wip-us.apache.org/repos/asf/ambari/blob/b3ff359a/ambari-common/src/main/python/resource_management/core/providers/package/apt.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/resource_management/core/providers/package/apt.py b/ambari-common/src/main/python/resource_management/core/providers/package/apt.py
index 44a67de..ae271f0 100644
--- a/ambari-common/src/main/python/resource_management/core/providers/package/apt.py
+++ b/ambari-common/src/main/python/resource_management/core/providers/package/apt.py
@@ -39,7 +39,11 @@ REMOVE_CMD = {
}
REPO_UPDATE_CMD = ['/usr/bin/apt-get', 'update','-qq']
-CHECK_CMD = "dpkg --get-selections | grep -v deinstall | awk '{print $1}' | grep ^%s$"
+CHECK_EXISTENCE_CMD = "dpkg --get-selections | grep -v deinstall | awk '{print $1}' | grep '^%s$'"
+GET_PACKAGES_BY_PATTERN_CMD = "apt-cache --names-only search '^%s$' | awk '{print $1}'"
+GET_PACKAGE_STATUS_CMD = "dpkg --status '%s'"
+
+PACKAGE_INSTALLED_STATUS = 'Status: install ok installed'
EMPTY_FILE = "/dev/null"
APT_SOURCES_LIST_DIR = "/etc/apt/sources.list.d"
@@ -51,6 +55,7 @@ def replace_underscores(function_to_decorate):
return function_to_decorate(self, name, *args[2:])
return wrapper
+
class AptProvider(PackageProvider):
@replace_underscores
@@ -113,5 +118,15 @@ class AptProvider(PackageProvider):
@replace_underscores
def _check_existence(self, name):
- code, out = shell.call(CHECK_CMD % name)
- return not bool(code)
+ code, out = shell.call(CHECK_EXISTENCE_CMD % name)
+ if bool(code):
+ return False
+ elif '*' in name or '.' in name: # Check if all packages matching regexp are installed
+ code1, out1 = shell.call(GET_PACKAGES_BY_PATTERN_CMD % name)
+ for package_name in out1.splitlines():
+ code2, out2 = shell.call(GET_PACKAGE_STATUS_CMD % package_name)
+ if PACKAGE_INSTALLED_STATUS not in out2.splitlines():
+ return False
+ return True
+ else:
+ return True
http://git-wip-us.apache.org/repos/asf/ambari/blob/b3ff359a/ambari-common/src/main/python/resource_management/core/providers/package/yumrpm.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/resource_management/core/providers/package/yumrpm.py b/ambari-common/src/main/python/resource_management/core/providers/package/yumrpm.py
index 82c8e82..7980de2 100644
--- a/ambari-common/src/main/python/resource_management/core/providers/package/yumrpm.py
+++ b/ambari-common/src/main/python/resource_management/core/providers/package/yumrpm.py
@@ -36,7 +36,8 @@ REMOVE_CMD = {
False: ['/usr/bin/yum', '-d', '0', '-e', '0', '-y', 'erase'],
}
-CHECK_CMD = "installed_pkgs=`rpm -qa %s` ; [ ! -z \"$installed_pkgs\" ]"
+CHECK_CMD = "installed_pkgs=`rpm -qa '%s'` ; [ ! -z \"$installed_pkgs\" ]"
+CHECK_AVAILABLE_PACKAGES_CMD = "! yum list available '%s'"
class YumProvider(PackageProvider):
def install_package(self, name, use_repos=[]):
@@ -66,4 +67,10 @@ class YumProvider(PackageProvider):
if '.' in name: # To work with names like 'zookeeper_2_2_1_0_2072.noarch'
name = os.path.splitext(name)[0]
code, out = shell.call(CHECK_CMD % name)
- return not bool(code)
+ if bool(code):
+ return False
+ elif '*' in name or '?' in name: # Check if all packages matching pattern are installed
+ code1, out1 = shell.call(CHECK_AVAILABLE_PACKAGES_CMD % name)
+ return not bool(code1)
+ else:
+ return True
http://git-wip-us.apache.org/repos/asf/ambari/blob/b3ff359a/ambari-common/src/main/python/resource_management/core/providers/package/zypper.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/resource_management/core/providers/package/zypper.py b/ambari-common/src/main/python/resource_management/core/providers/package/zypper.py
index e532c1a..bd21ed5 100644
--- a/ambari-common/src/main/python/resource_management/core/providers/package/zypper.py
+++ b/ambari-common/src/main/python/resource_management/core/providers/package/zypper.py
@@ -33,7 +33,11 @@ REMOVE_CMD = {
True: ['/usr/bin/zypper', 'remove', '--no-confirm'],
False: ['/usr/bin/zypper', '--quiet', 'remove', '--no-confirm'],
}
-CHECK_CMD = "installed_pkgs=`rpm -qa %s` ; [ ! -z \"$installed_pkgs\" ]"
+CHECK_CMD = "installed_pkgs=`rpm -qa '%s'` ; [ ! -z \"$installed_pkgs\" ]"
+GET_NOT_INSTALLED_CMD = "zypper --non-interactive search --type package --uninstalled-only --match-exact '%s'"
+
+NO_PACKAGES_FOUND_STATUS = 'No packages found.'
+
LIST_ACTIVE_REPOS_CMD = ['/usr/bin/zypper', 'repos']
def get_active_base_repos():
@@ -82,4 +86,10 @@ class ZypperProvider(PackageProvider):
def _check_existence(self, name):
code, out = shell.call(CHECK_CMD % name)
- return not bool(code)
+ if bool(code):
+ return False
+ elif '*' in name or '?' in name: # Check if all packages matching pattern are installed
+ code1, out1 = shell.call(GET_NOT_INSTALLED_CMD % name)
+ return NO_PACKAGES_FOUND_STATUS in out1.splitlines()
+ else:
+ return True