You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ao...@apache.org on 2015/06/03 17:09:35 UTC
ambari git commit: AMBARI-11657. Unable to install with non-root
Agent (aonishuk)
Repository: ambari
Updated Branches:
refs/heads/trunk 692c3a8c4 -> b549e35d4
AMBARI-11657. Unable to install with non-root Agent (aonishuk)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/b549e35d
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/b549e35d
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/b549e35d
Branch: refs/heads/trunk
Commit: b549e35d4dea2c57a4eb297faabb25d66f6a76fc
Parents: 692c3a8
Author: Andrew Onishuk <ao...@hortonworks.com>
Authored: Wed Jun 3 18:09:28 2015 +0300
Committer: Andrew Onishuk <ao...@hortonworks.com>
Committed: Wed Jun 3 18:09:28 2015 +0300
----------------------------------------------------------------------
.../resource_management/TestPackageResource.py | 32 +++++++++-----------
.../core/providers/package/__init__.py | 32 ++++++++++++++++++++
.../core/providers/package/yumrpm.py | 17 +++--------
.../core/providers/package/zypper.py | 14 +--------
.../core/providers/system.py | 11 ++++++-
.../core/resources/system.py | 1 +
.../python/resource_management/core/shell.py | 4 +++
7 files changed, 67 insertions(+), 44 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/b549e35d/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 d69f278..c67745d 100644
--- a/ambari-agent/src/test/python/resource_management/TestPackageResource.py
+++ b/ambari-agent/src/test/python/resource_management/TestPackageResource.py
@@ -16,6 +16,7 @@ See the License for the specific language governing permissions and
limitations under the License.
'''
+import os
import sys
from unittest import TestCase
from mock.mock import patch, MagicMock, call
@@ -27,6 +28,7 @@ from resource_management.core.resources import Package
from resource_management.core import shell
from resource_management.core.providers.package.apt import replace_underscores
+@patch.object(os, "geteuid", new=MagicMock(return_value=1234))
class TestPackageResource(TestCase):
@patch.object(shell, "call")
@patch.object(shell, "checked_call")
@@ -87,23 +89,21 @@ class TestPackageResource(TestCase):
@patch.object(shell, "checked_call")
@patch.object(System, "os_family", new = 'redhat')
def test_action_install_rhel(self, shell_mock):
- sys.modules['yum'] = MagicMock()
- sys.modules['yum'].YumBase.return_value = MagicMock()
- sys.modules['yum'].YumBase.return_value.rpmdb = MagicMock()
- sys.modules['yum'].YumBase.return_value.rpmdb.simplePkgList.return_value = [('some_packag',)]
+ sys.modules['rpm'] = MagicMock()
+ sys.modules['rpm'].TransactionSet.return_value = MagicMock()
+ sys.modules['rpm'].TransactionSet.return_value.dbMatch.return_value = [{'name':'some_packag'}]
with Environment('/') as env:
Package("some_package",
)
- self.assertTrue(sys.modules['yum'].YumBase.return_value.rpmdb.simplePkgList.called)
+ self.assertTrue(sys.modules['rpm'].TransactionSet.return_value.dbMatch.called)
shell_mock.assert_called_with(['/usr/bin/yum', '-d', '0', '-e', '0', '-y', 'install', 'some_package'], logoutput=False, sudo=True)
@patch.object(shell, "checked_call")
@patch.object(System, "os_family", new = 'redhat')
def test_action_install_pattern_rhel(self, shell_mock):
- sys.modules['yum'] = MagicMock()
- sys.modules['yum'].YumBase.return_value = MagicMock()
- sys.modules['yum'].YumBase.return_value.rpmdb = MagicMock()
- sys.modules['yum'].YumBase.return_value.rpmdb.simplePkgList.return_value = [('some_packag',)]
+ sys.modules['rpm'] = MagicMock()
+ sys.modules['rpm'].TransactionSet.return_value = MagicMock()
+ sys.modules['rpm'].TransactionSet.return_value.dbMatch.return_value = [{'name':'some_packag'}]
with Environment('/') as env:
Package("some_package*",
)
@@ -159,10 +159,9 @@ class TestPackageResource(TestCase):
@patch.object(shell, "checked_call")
@patch.object(System, "os_family", new = 'redhat')
def test_action_install_existent_rhel(self, shell_mock):
- sys.modules['yum'] = MagicMock()
- sys.modules['yum'].YumBase.return_value = MagicMock()
- sys.modules['yum'].YumBase.return_value.rpmdb = MagicMock()
- sys.modules['yum'].YumBase.return_value.rpmdb.simplePkgList.return_value = [('some_package',)]
+ sys.modules['rpm'] = MagicMock()
+ sys.modules['rpm'].TransactionSet.return_value = MagicMock()
+ sys.modules['rpm'].TransactionSet.return_value.dbMatch.return_value = [{'name':'some_package'}]
with Environment('/') as env:
Package("some_package",
)
@@ -196,10 +195,9 @@ class TestPackageResource(TestCase):
@patch.object(shell, "checked_call")
@patch.object(System, "os_family", new = 'redhat')
def test_action_remove_rhel(self, shell_mock):
- sys.modules['yum'] = MagicMock()
- sys.modules['yum'].YumBase.return_value = MagicMock()
- sys.modules['yum'].YumBase.return_value.rpmdb = MagicMock()
- sys.modules['yum'].YumBase.return_value.rpmdb.simplePkgList.return_value = [('some_package',)]
+ sys.modules['rpm'] = MagicMock()
+ sys.modules['rpm'].TransactionSet.return_value = MagicMock()
+ sys.modules['rpm'].TransactionSet.return_value.dbMatch.return_value = [{'name':'some_package'}]
with Environment('/') as env:
Package("some_package",
action = "remove"
http://git-wip-us.apache.org/repos/asf/ambari/blob/b549e35d/ambari-common/src/main/python/resource_management/core/providers/package/__init__.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/resource_management/core/providers/package/__init__.py b/ambari-common/src/main/python/resource_management/core/providers/package/__init__.py
index 2358e86..ad48b43 100644
--- a/ambari-common/src/main/python/resource_management/core/providers/package/__init__.py
+++ b/ambari-common/src/main/python/resource_management/core/providers/package/__init__.py
@@ -20,11 +20,13 @@ Ambari Agent
"""
+import re
import logging
from resource_management.core.base import Fail
from resource_management.core.providers import Provider
from resource_management.core.logger import Logger
+from resource_management.core.utils import suppress_stdout
class PackageProvider(Provider):
@@ -59,4 +61,34 @@ class PackageProvider(Provider):
def get_logoutput(self):
return self.resource.logoutput==True and Logger.logger.isEnabledFor(logging.INFO) or self.resource.logoutput==None and Logger.logger.isEnabledFor(logging.DEBUG)
+ def yum_check_package_available(self, name):
+ """
+ Does the same as rpm_check_package_avaiable, but faster.
+ However need root permissions.
+ """
+ import yum # Python Yum API is much faster then other check methods. (even then "import rpm")
+ yb = yum.YumBase()
+ name_regex = re.escape(name).replace("\\?", ".").replace("\\*", ".*") + '$'
+ regex = re.compile(name_regex)
+ with suppress_stdout():
+ package_list = yb.rpmdb.simplePkgList()
+
+ for package in package_list:
+ if regex.match(package[0]):
+ return True
+
+ return False
+
+ def rpm_check_package_available(self, name):
+ import rpm # this is faster then calling 'rpm'-binary externally.
+ ts = rpm.TransactionSet()
+ packages = ts.dbMatch()
+
+ name_regex = re.escape(name).replace("\\?", ".").replace("\\*", ".*") + '$'
+ regex = re.compile(name_regex)
+
+ for package in packages:
+ if regex.match(package['name']):
+ return True
+ return False
http://git-wip-us.apache.org/repos/asf/ambari/blob/b549e35d/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 2d39c4d..c17b7f0 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
@@ -26,7 +26,6 @@ from resource_management.core.shell import string_cmd_from_args_list
from resource_management.core.logger import Logger
from resource_management.core.utils import suppress_stdout
import os
-import re
INSTALL_CMD = {
True: ['/usr/bin/yum', '-y', 'install'],
@@ -81,16 +80,8 @@ class YumProvider(PackageProvider):
yum in inconsistant state (locked, used, having invalid repo). Once packages are installed
we should not rely on that.
"""
- import yum # Python Yum API is much faster then other check methods. (even then "import rpm")
- yb = yum.YumBase()
- name_regex = re.escape(name).replace("\\?", ".").replace("\\*", ".*") + '$'
- regex = re.compile(name_regex)
-
- with suppress_stdout():
- package_list = yb.rpmdb.simplePkgList()
-
- for package in package_list:
- if regex.match(package[0]):
- return True
+ if os.geteuid() == 0:
+ return self.yum_check_package_available(name)
+ else:
+ return self.rpm_check_package_available(name)
- return False
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/b549e35d/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 b7f33f4..dd16ce0 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
@@ -26,8 +26,6 @@ from resource_management.core.shell import string_cmd_from_args_list
from resource_management.core.logger import Logger
from resource_management.core.utils import suppress_stdout
-import re
-
INSTALL_CMD = {
True: ['/usr/bin/zypper', 'install', '--auto-agree-with-licenses', '--no-confirm'],
False: ['/usr/bin/zypper', '--quiet', 'install', '--auto-agree-with-licenses', '--no-confirm'],
@@ -102,14 +100,4 @@ class ZypperProvider(PackageProvider):
zypper in inconsistant state (locked, used, having invalid repo). Once packages are installed
we should not rely on that.
"""
- import rpm # this is faster then calling 'rpm'-binary externally.
- ts = rpm.TransactionSet()
- packages = ts.dbMatch()
-
- name_regex = re.escape(name).replace("\\?", ".").replace("\\*", ".*") + '$'
- regex = re.compile(name_regex)
-
- for package in packages:
- if regex.match(package['name']):
- return True
- return False
+ return self.rpm_check_package_available(name)
http://git-wip-us.apache.org/repos/asf/ambari/blob/b549e35d/ambari-common/src/main/python/resource_management/core/providers/system.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/resource_management/core/providers/system.py b/ambari-common/src/main/python/resource_management/core/providers/system.py
index 43044db..3a1b218 100644
--- a/ambari-common/src/main/python/resource_management/core/providers/system.py
+++ b/ambari-common/src/main/python/resource_management/core/providers/system.py
@@ -131,9 +131,18 @@ class FileProvider(Provider):
class DirectoryProvider(Provider):
def action_create(self):
path = self.resource.path
-
+
if not sudo.path_exists(path):
Logger.info("Creating directory %s" % self.resource)
+
+ # dead links should be followed, else we gonna have failures on trying to create directories on top of them.
+ if self.resource.follow:
+ while sudo.path_lexists(path):
+ path = sudo.readlink(path)
+
+ if path != self.resource.path:
+ Logger.info("Following the link {0} to {1} to create the directory".format(self.resource.path, path))
+
if self.resource.recursive:
if self.resource.recursive_permission:
DirectoryProvider.makedirs_and_set_permission_recursively(path, self.resource.owner,
http://git-wip-us.apache.org/repos/asf/ambari/blob/b549e35d/ambari-common/src/main/python/resource_management/core/resources/system.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/resource_management/core/resources/system.py b/ambari-common/src/main/python/resource_management/core/resources/system.py
index bf10c43..1f00da1 100644
--- a/ambari-common/src/main/python/resource_management/core/resources/system.py
+++ b/ambari-common/src/main/python/resource_management/core/resources/system.py
@@ -57,6 +57,7 @@ class Directory(Resource):
mode = ResourceArgument()
owner = ResourceArgument()
group = ResourceArgument()
+ follow = BooleanArgument(default=True) # follow links?
recursive = BooleanArgument(default=False) # this work for 'create', 'delete' is anyway recursive
recursive_permission = BooleanArgument(default=False) # sets given perms to all non-existent folders which are created recursively
"""
http://git-wip-us.apache.org/repos/asf/ambari/blob/b549e35d/ambari-common/src/main/python/resource_management/core/shell.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/resource_management/core/shell.py b/ambari-common/src/main/python/resource_management/core/shell.py
index 2ddc9eb..2e5a1b0 100644
--- a/ambari-common/src/main/python/resource_management/core/shell.py
+++ b/ambari-common/src/main/python/resource_management/core/shell.py
@@ -236,6 +236,10 @@ def as_user(command, user, env=None, auto_escape=True):
def quote_bash_args(command):
if not command:
return "''"
+
+ if not isinstance(command, basestring):
+ raise Fail("Command should be a list of strings, found '{0}' in command list elements".format(str(command)))
+
valid = set(string.ascii_letters + string.digits + '@%_-+=:,./')
for char in command:
if char not in valid: