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 f277631 [AMBARI-24632] APT/DPKG existence check doesn't work for
system packages (dgrinenko) (#2366)
f277631 is described below
commit f277631dec36a442999327026a030e463e4c67e1
Author: Dmytro Grinenko <[email protected]>
AuthorDate: Thu Sep 27 12:00:07 2018 +0300
[AMBARI-24632] APT/DPKG existence check doesn't work for system packages
(dgrinenko) (#2366)
---
.../ambari_commons/repo_manager/apt_manager.py | 16 ++++--
.../ambari_commons/repo_manager/apt_parser.py | 2 +-
.../ambari_commons/repo_manager/yum_manager.py | 4 +-
.../ambari_commons/repo_manager/zypper_manager.py | 2 +-
.../src/main/python/ambari_commons/shell.py | 12 +++-
.../custom_actions/scripts/install_packages.py | 5 +-
.../python/custom_actions/TestInstallPackages.py | 64 +++++++++++++++++-----
7 files changed, 79 insertions(+), 26 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 0310af9..5882253 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
@@ -67,8 +67,6 @@ class AptManagerProperties(GenericManagerProperties):
install_cmd_env = {'DEBIAN_FRONTEND': 'noninteractive'}
- check_cmd = pkg_manager_bin + " --get-selections | grep -v deinstall | awk
'{print $1}' | grep ^%s$"
-
repo_url_exclude = "ubuntu.com"
configuration_dump_cmd = [AMBARI_SUDO_BINARY, "apt-config", "dump"]
@@ -237,7 +235,7 @@ class AptManager(GenericManager):
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):
+ elif not self._check_existence(name) or context.action_force:
cmd = self.properties.install_cmd[context.log_output]
copied_sources_files = []
is_tmp_dir_created = False
@@ -251,7 +249,7 @@ class AptManager(GenericManager):
if use_repos:
is_tmp_dir_created = True
apt_sources_list_tmp_dir =
tempfile.mkdtemp(suffix="-ambari-apt-sources-d")
- Logger.info("Temporary sources directory was created: %s" %
apt_sources_list_tmp_dir)
+ Logger.info("Temporary sources directory was created:
{}".format(apt_sources_list_tmp_dir))
for repo in use_repos:
new_sources_file = os.path.join(apt_sources_list_tmp_dir, repo +
'.list')
@@ -327,6 +325,12 @@ class AptManager(GenericManager):
apt-get in inconsistant state (locked, used, having invalid repo). Once
packages are installed
we should not rely on that.
"""
+ # this method is more optimised than #installed_packages, as here we do
not call available packages(as we do not
+ # interested in repository, from where package come)
+ cmd = self.properties.installed_packages_cmd + [name]
+
+ with shell.process_executor(cmd,
strategy=shell.ReaderStrategy.BufferedChunks, silent=True) as output:
+ for package, version in AptParser.packages_installed_reader(output):
+ return package == name
- r = shell.subprocess_executor(self.properties.check_cmd % name)
- return not bool(r.code)
+ return False
diff --git
a/ambari-common/src/main/python/ambari_commons/repo_manager/apt_parser.py
b/ambari-common/src/main/python/ambari_commons/repo_manager/apt_parser.py
index 03afb86..29f1a65 100644
--- a/ambari-common/src/main/python/ambari_commons/repo_manager/apt_parser.py
+++ b/ambari-common/src/main/python/ambari_commons/repo_manager/apt_parser.py
@@ -137,7 +137,7 @@ class AptParser(GenericParser):
line = line[2:].lstrip()
data = line.partition(" ")
- pkg_name = data[0]
+ pkg_name = data[0].partition(":")[0] # for system packages in format
"libuuid1:amd64"
version = data[2].strip().partition(" ")[0]
if pkg_name and version:
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 e3df80e..8e2931e 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
@@ -208,7 +208,7 @@ class YumManager(GenericManager):
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):
+ elif not self._check_existence(name) or context.action_force:
cmd = self.properties.install_cmd[context.log_output]
if context.use_repos:
enable_repo_option = '--enablerepo=' +
",".join(sorted(context.use_repos.keys()))
@@ -273,6 +273,8 @@ class YumManager(GenericManager):
yum 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")
if os.geteuid() == 0:
return self.yum_check_package_available(name)
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 789a3d0..7e1249f 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
@@ -183,7 +183,7 @@ class ZypperManager(GenericManager):
"""
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):
+ elif not self._check_existence(name) or context.action_force:
cmd = self.properties.install_cmd[context.log_output]
if context.use_repos:
diff --git a/ambari-common/src/main/python/ambari_commons/shell.py
b/ambari-common/src/main/python/ambari_commons/shell.py
index 9f3d463..fda1782 100644
--- a/ambari-common/src/main/python/ambari_commons/shell.py
+++ b/ambari-common/src/main/python/ambari_commons/shell.py
@@ -104,10 +104,11 @@ class RepoCallContext(object):
use_repos = None
skip_repos = None
is_upgrade = False
+ action_force = False # currently only for install action
def __init__(self, ignore_errors=True, retry_count=2, retry_sleep=30,
retry_on_repo_unavailability=False,
retry_on_locked=True, log_output=True, use_repos=None,
skip_repos=None,
- is_upgrade=False):
+ is_upgrade=False, action_force=False):
"""
:type ignore_errors bool
:type retry_count int
@@ -128,6 +129,7 @@ class RepoCallContext(object):
self.use_repos = use_repos
self.skip_repos = skip_repos
self.is_upgrade = is_upgrade
+ self.action_force = action_force
@property
def retry_count(self):
@@ -450,7 +452,8 @@ def subprocess_executor(command, timeout=__TIMEOUT_SECONDS,
strategy=ReaderStrat
@contextmanager
-def process_executor(command, timeout=__TIMEOUT_SECONDS, error_callback=None,
strategy=ReaderStrategy.BufferedQueue, env=None):
+def process_executor(command, timeout=__TIMEOUT_SECONDS, error_callback=None,
strategy=ReaderStrategy.BufferedQueue,
+ env=None, silent=False):
"""
Context manager for command execution
@@ -458,12 +461,14 @@ def process_executor(command, timeout=__TIMEOUT_SECONDS,
error_callback=None, st
:param timeout execution time limit in seconds. If None will default to
TIMEOUT_SECONDS, -1 disable feature
:param strategy the way how to process output. Available methods listed in
ReaderStrategy
:param env Environment variable for new spawned process
+ :param silent no error logging if command execution failed, do not affect
`error_callback` param
:type command list|str
:type timeout None|int
:type error_callback func
:type strategy int
:type env dict
+ :type silent bool
:rtype stdout collections.Iterable
@@ -515,7 +520,8 @@ def process_executor(command, timeout=__TIMEOUT_SECONDS,
error_callback=None, st
if error_callback and cmd.returncode and cmd.returncode > 0:
error_callback(command, cmd.stderr.readlines(), cmd.returncode)
except Exception as e:
- _logger.error("Exception during command '{0}' execution:
{1}".format(command, str(e)))
+ if not silent:
+ _logger.error("Exception during command '{0}' execution:
{1}".format(command, str(e)))
if error_callback:
error_callback(command, [str(e)], -1)
diff --git
a/ambari-server/src/main/resources/custom_actions/scripts/install_packages.py
b/ambari-server/src/main/resources/custom_actions/scripts/install_packages.py
index 800bb21..bc4c65a 100644
---
a/ambari-server/src/main/resources/custom_actions/scripts/install_packages.py
+++
b/ambari-server/src/main/resources/custom_actions/scripts/install_packages.py
@@ -389,9 +389,12 @@ class InstallPackages(Script):
# patches installed
repositories = config['repositoryFile']['repositories']
command_repos = CommandRepository(config['repositoryFile'])
- command_repos.items = [x for x in command_repos.items if not
x.applicable_services]
repository_ids = [repository['repoId'] for repository in repositories]
repos_to_use = {}
+
+ if not command_repos.items:
+ raise ValueError("No repositories passed with the command")
+
for repo_id in repository_ids:
if repo_id in self.repo_files:
repos_to_use[repo_id] = self.repo_files[repo_id]
diff --git
a/ambari-server/src/test/python/custom_actions/TestInstallPackages.py
b/ambari-server/src/test/python/custom_actions/TestInstallPackages.py
index a8840f0..018d561 100644
--- a/ambari-server/src/test/python/custom_actions/TestInstallPackages.py
+++ b/ambari-server/src/test/python/custom_actions/TestInstallPackages.py
@@ -106,10 +106,13 @@ class TestInstallPackages(RMFTestCase):
with patch.object(pkg_manager, "all_packages") as all_packages, \
patch.object(pkg_manager, "available_packages") as available_packages, \
- patch.object(pkg_manager, "installed_packages") as installed_packages:
+ patch.object(pkg_manager, "installed_packages") as installed_packages, \
+ patch.object(pkg_manager, "_check_existence") as check_existence:
+
all_packages.side_effect = TestInstallPackages._add_packages_lookUpYum
available_packages.side_effect =
TestInstallPackages._add_packages_lookUpYum
installed_packages.side_effect =
TestInstallPackages._add_packages_lookUpYum
+ check_existence.return_value = False
get_provider.return_value = pkg_manager
@@ -226,10 +229,13 @@ class TestInstallPackages(RMFTestCase):
with patch.object(pkg_manager, "all_packages") as all_packages, \
patch.object(pkg_manager, "available_packages") as available_packages, \
- patch.object(pkg_manager, "installed_packages") as installed_packages:
+ patch.object(pkg_manager, "installed_packages") as installed_packages, \
+ patch.object(pkg_manager, "_check_existence") as check_existence:
+
all_packages.side_effect = TestInstallPackages._add_packages_available
available_packages.side_effect =
TestInstallPackages._add_packages_available
installed_packages.side_effect =
TestInstallPackages._add_packages_available
+ check_existence.return_value = False
get_provider.return_value = pkg_manager
@@ -294,10 +300,13 @@ class TestInstallPackages(RMFTestCase):
with patch.object(pkg_manager, "all_packages") as all_packages, \
patch.object(pkg_manager, "available_packages") as available_packages, \
- patch.object(pkg_manager, "installed_packages") as installed_packages:
+ patch.object(pkg_manager, "installed_packages") as installed_packages, \
+ patch.object(pkg_manager, "_check_existence") as check_existence:
+
all_packages.side_effect = TestInstallPackages._add_packages_lookUpYum
available_packages.side_effect =
TestInstallPackages._add_packages_lookUpYum
installed_packages.side_effect =
TestInstallPackages._add_packages_lookUpYum
+ check_existence.return_value = False
get_provider.return_value = pkg_manager
list_ambari_managed_repos_mock.return_value=["HDP-UTILS-2.2.0.1-885"]
@@ -453,10 +462,12 @@ class TestInstallPackages(RMFTestCase):
with patch.object(pkg_manager, "all_packages") as all_packages, \
patch.object(pkg_manager, "available_packages") as available_packages, \
- patch.object(pkg_manager, "installed_packages") as installed_packages:
+ patch.object(pkg_manager, "installed_packages") as installed_packages, \
+ patch.object(pkg_manager, "_check_existence") as check_existence:
all_packages.side_effect = TestInstallPackages._add_packages_available
available_packages.side_effect =
TestInstallPackages._add_packages_available
installed_packages.side_effect =
TestInstallPackages._add_packages_available
+ check_existence.return_value = False
get_provider.return_value = pkg_manager
is_suse_family_mock.return_value = True
@@ -523,10 +534,12 @@ class TestInstallPackages(RMFTestCase):
with patch.object(pkg_manager, "all_packages") as all_packages, \
patch.object(pkg_manager, "available_packages") as available_packages, \
- patch.object(pkg_manager, "installed_packages") as installed_packages:
+ patch.object(pkg_manager, "installed_packages") as installed_packages, \
+ patch.object(pkg_manager, "_check_existence") as check_existence:
all_packages.side_effect = TestInstallPackages._add_packages_available
available_packages.side_effect =
TestInstallPackages._add_packages_available
installed_packages.side_effect =
TestInstallPackages._add_packages_available
+ check_existence.return_value = False
get_provider.return_value = pkg_manager
is_suse_family_mock.return_value = True
@@ -603,10 +616,13 @@ class TestInstallPackages(RMFTestCase):
with patch.object(pkg_manager, "all_packages") as all_packages, \
patch.object(pkg_manager, "available_packages") as available_packages, \
- patch.object(pkg_manager, "installed_packages") as installed_packages:
+ patch.object(pkg_manager, "installed_packages") as installed_packages, \
+ patch.object(pkg_manager, "_check_existence") as check_existence:
+
all_packages.side_effect = TestInstallPackages._add_packages_available
available_packages.side_effect =
TestInstallPackages._add_packages_available
installed_packages.side_effect =
TestInstallPackages._add_packages_available
+ check_existence.return_value = False
get_provider.return_value = pkg_manager
list_ambari_managed_repos_mock.return_value = []
@@ -688,6 +704,7 @@ class TestInstallPackages(RMFTestCase):
with open(config_file, "r") as f:
command_json = json.load(f)
+
command_json['roleParams']['repository_version'] =
VERSION_STUB_WITHOUT_BUILD_NUMBER
from ambari_commons.os_check import OSConst
@@ -697,10 +714,13 @@ class TestInstallPackages(RMFTestCase):
with patch.object(pkg_manager, "all_packages") as all_packages, \
patch.object(pkg_manager, "available_packages") as available_packages, \
- patch.object(pkg_manager, "installed_packages") as installed_packages:
+ patch.object(pkg_manager, "installed_packages") as installed_packages, \
+ patch.object(pkg_manager, "_check_existence") as check_existence:
+
all_packages.side_effect = TestInstallPackages._add_packages_available
available_packages.side_effect =
TestInstallPackages._add_packages_available
installed_packages.side_effect =
TestInstallPackages._add_packages_available
+ check_existence.return_value = False
get_provider.return_value = pkg_manager
list_ambari_managed_repos_mock.return_value = []
@@ -766,10 +786,13 @@ class TestInstallPackages(RMFTestCase):
with patch.object(pkg_manager, "all_packages") as all_packages, \
patch.object(pkg_manager, "available_packages") as available_packages, \
- patch.object(pkg_manager, "installed_packages") as installed_packages:
+ patch.object(pkg_manager, "installed_packages") as installed_packages, \
+ patch.object(pkg_manager, "_check_existence") as check_existence:
+
all_packages.side_effect = TestInstallPackages._add_packages
available_packages.side_effect = TestInstallPackages._add_packages
installed_packages.side_effect = TestInstallPackages._add_packages
+ check_existence.return_value = False
get_provider.return_value = pkg_manager
@@ -867,10 +890,13 @@ class TestInstallPackages(RMFTestCase):
with patch.object(pkg_manager, "all_packages") as all_packages, \
patch.object(pkg_manager, "available_packages") as available_packages, \
- patch.object(pkg_manager, "installed_packages") as installed_packages:
+ patch.object(pkg_manager, "installed_packages") as installed_packages, \
+ patch.object(pkg_manager, "_check_existence") as check_existence:
+
all_packages.side_effect = TestInstallPackages._add_packages_available
available_packages.side_effect =
TestInstallPackages._add_packages_available
installed_packages.side_effect =
TestInstallPackages._add_packages_available
+ check_existence.return_value = False
get_provider.return_value = pkg_manager
list_ambari_managed_repos_mock.return_value = []
@@ -957,10 +983,13 @@ class TestInstallPackages(RMFTestCase):
with patch.object(pkg_manager, "all_packages") as all_packages, \
patch.object(pkg_manager, "available_packages") as available_packages, \
- patch.object(pkg_manager, "installed_packages") as installed_packages:
+ patch.object(pkg_manager, "installed_packages") as installed_packages, \
+ patch.object(pkg_manager, "_check_existence") as check_existence:
+
all_packages.side_effect = TestInstallPackages._add_packages_available
available_packages.side_effect =
TestInstallPackages._add_packages_available
installed_packages.side_effect =
TestInstallPackages._add_packages_available
+ check_existence.return_value = False
get_provider.return_value = pkg_manager
list_ambari_managed_repos_mock.return_value = []
@@ -1051,10 +1080,13 @@ class TestInstallPackages(RMFTestCase):
with patch.object(pkg_manager, "all_packages") as all_packages, \
patch.object(pkg_manager, "available_packages") as available_packages, \
- patch.object(pkg_manager, "installed_packages") as installed_packages:
+ patch.object(pkg_manager, "installed_packages") as installed_packages, \
+ patch.object(pkg_manager, "_check_existence") as check_existence:
+
all_packages.side_effect = TestInstallPackages._add_packages_available
available_packages.side_effect =
TestInstallPackages._add_packages_available
installed_packages.side_effect =
TestInstallPackages._add_packages_available
+ check_existence.return_value = False
get_provider.return_value = pkg_manager
list_ambari_managed_repos_mock.return_value = []
@@ -1151,10 +1183,13 @@ class TestInstallPackages(RMFTestCase):
with patch.object(pkg_manager, "all_packages") as all_packages, \
patch.object(pkg_manager, "available_packages") as available_packages, \
- patch.object(pkg_manager, "installed_packages") as installed_packages:
+ patch.object(pkg_manager, "installed_packages") as installed_packages, \
+ patch.object(pkg_manager, "_check_existence") as check_existence:
+
all_packages.side_effect = TestInstallPackages._add_packages_available
available_packages.side_effect =
TestInstallPackages._add_packages_available
installed_packages.side_effect =
TestInstallPackages._add_packages_available
+ check_existence.return_value = False
get_provider.return_value = pkg_manager
list_ambari_managed_repos_mock.return_value = []
@@ -1237,10 +1272,13 @@ class TestInstallPackages(RMFTestCase):
with patch.object(pkg_manager, "all_packages") as all_packages, \
patch.object(pkg_manager, "available_packages") as available_packages, \
- patch.object(pkg_manager, "installed_packages") as installed_packages:
+ patch.object(pkg_manager, "installed_packages") as installed_packages, \
+ patch.object(pkg_manager, "_check_existence") as check_existence:
+
all_packages.side_effect = TestInstallPackages._add_packages_available
available_packages.side_effect =
TestInstallPackages._add_packages_available
installed_packages.side_effect =
TestInstallPackages._add_packages_available
+ check_existence.return_value = False
get_provider.return_value = pkg_manager
list_ambari_managed_repos_mock.return_value=[]