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 2014/11/25 17:55:29 UTC

ambari git commit: AMBARI-8445. Resource management should support working under sudo (aonishuk)

Repository: ambari
Updated Branches:
  refs/heads/trunk b35464a7f -> 68c557281


AMBARI-8445. Resource management should support working under sudo (aonishuk)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/68c55728
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/68c55728
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/68c55728

Branch: refs/heads/trunk
Commit: 68c5572817afab19c6aa7ce628c77ffc82efae15
Parents: b35464a
Author: Andrew Onishuk <ao...@hortonworks.com>
Authored: Tue Nov 25 18:55:15 2014 +0200
Committer: Andrew Onishuk <ao...@hortonworks.com>
Committed: Tue Nov 25 18:55:15 2014 +0200

----------------------------------------------------------------------
 .../TestDirectoryResource.py                    | 25 ++++---
 .../resource_management/TestExecuteResource.py  | 10 ++-
 .../resource_management/TestFileResource.py     | 67 ++++++++-----------
 .../resource_management/TestGroupResource.py    |  6 +-
 .../resource_management/TestLinkResource.py     | 11 ++--
 .../resource_management/TestPackageResource.py  | 18 ++---
 .../TestPropertiesFileResource.py               | 69 +++++++++-----------
 .../resource_management/TestUserResource.py     | 20 +++---
 .../TestXmlConfigResource.py                    | 42 ++++--------
 .../core/providers/accounts.py                  |  4 +-
 .../core/providers/package/apt.py               |  8 +--
 .../core/providers/package/yumrpm.py            |  4 +-
 .../core/providers/package/zypper.py            |  4 +-
 .../core/providers/system.py                    | 62 +++++++++++-------
 .../core/resources/system.py                    |  3 +-
 .../python/resource_management/core/shell.py    | 37 +++++------
 .../python/resource_management/core/sudo.py     | 62 ++++++++++++++++++
 .../libraries/providers/hdfs_directory.py       |  4 +-
 .../ambari/server/bootstrap/SshHostInfo.java    |  3 -
 .../HIVE/package/scripts/hive_service.py        |  4 +-
 .../stacks/2.0.6/HIVE/test_hive_server.py       | 12 ++--
 21 files changed, 254 insertions(+), 221 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/68c55728/ambari-agent/src/test/python/resource_management/TestDirectoryResource.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/resource_management/TestDirectoryResource.py b/ambari-agent/src/test/python/resource_management/TestDirectoryResource.py
index 5a63891..0705922 100644
--- a/ambari-agent/src/test/python/resource_management/TestDirectoryResource.py
+++ b/ambari-agent/src/test/python/resource_management/TestDirectoryResource.py
@@ -16,24 +16,23 @@ See the License for the specific language governing permissions and
 limitations under the License.
 '''
 
-from stacks.utils.RMFTestCase import *
 from unittest import TestCase
 from mock.mock import patch, MagicMock
 import os
 import shutil
 from resource_management.core.system import System
-from resource_management.core import Environment, Fail
+from resource_management.core import Environment, Fail, sudo
 from resource_management.core.resources import Directory
 
 @patch.object(System, "os_family", new = 'redhat')
-class TestFileResource(TestCase):
+class TestDirectoryResource(TestCase):
   
   @patch.object(os.path, "exists")
-  @patch.object(os, "makedirs")
+  @patch.object(sudo, "makedirs")
   @patch.object(os.path, "isdir")
   @patch.object(os, "stat")
-  @patch.object(os,"chmod")
-  @patch.object(os,"chown")
+  @patch.object(sudo,"chmod")
+  @patch.object(sudo,"chown")
   @patch("resource_management.core.providers.system._coerce_uid")
   @patch("resource_management.core.providers.system._coerce_gid")
   def test_create_directory_recursive(self, _coerce_gid_mock, _coerce_uid_mock,
@@ -57,16 +56,16 @@ class TestFileResource(TestCase):
       
     os_makedirs_mock.assert_called_with('/a/b/c/d', 0777)
     os_chmod_mock.assert_called_with('/a/b/c/d', 0777)
-    os_chown_mock.assert_any_call('/a/b/c/d', 66, -1)
-    os_chown_mock.assert_any_call('/a/b/c/d', -1, 77)
+    os_chown_mock.assert_any_call('/a/b/c/d', 'hdfs', None)
+    os_chown_mock.assert_any_call('/a/b/c/d', None, 'hadoop')
   
   @patch.object(os.path, "exists")
   @patch.object(os.path, "dirname")
   @patch.object(os.path, "isdir")
-  @patch.object(os, "mkdir")
+  @patch.object(sudo, "makedir")
   @patch.object(os, "stat")
-  @patch.object(os,"chmod")
-  @patch.object(os,"chown")
+  @patch.object(sudo,"chmod")
+  @patch.object(sudo,"chown")
   @patch("resource_management.core.providers.system._coerce_uid")
   @patch("resource_management.core.providers.system._coerce_gid")
   def test_create_directory_not_recursive(self, _coerce_gid_mock, _coerce_uid_mock,
@@ -90,8 +89,8 @@ class TestFileResource(TestCase):
       
     mkdir_mock.assert_called_with('/a/b/c/d', 0777)
     os_chmod_mock.assert_called_with('/a/b/c/d', 0777)
-    os_chown_mock.assert_any_call('/a/b/c/d', 66, -1)
-    os_chown_mock.assert_any_call('/a/b/c/d', -1, 77)
+    os_chown_mock.assert_any_call('/a/b/c/d', 'hdfs', None)
+    os_chown_mock.assert_any_call('/a/b/c/d', None, 'hadoop')
     
   @patch.object(os.path, "exists")
   @patch.object(os.path, "dirname")

http://git-wip-us.apache.org/repos/asf/ambari/blob/68c55728/ambari-agent/src/test/python/resource_management/TestExecuteResource.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/resource_management/TestExecuteResource.py b/ambari-agent/src/test/python/resource_management/TestExecuteResource.py
index 8423eec..7820e47 100644
--- a/ambari-agent/src/test/python/resource_management/TestExecuteResource.py
+++ b/ambari-agent/src/test/python/resource_management/TestExecuteResource.py
@@ -16,7 +16,6 @@ See the License for the specific language governing permissions and
 limitations under the License.
 '''
 
-from stacks.utils.RMFTestCase import *
 from unittest import TestCase
 from mock.mock import patch, MagicMock, call
 
@@ -91,8 +90,8 @@ class TestExecuteResource(TestCase):
       execute_resource = Execute('echo "1"',
                                  path=["/test/one", "test/two"]
       )
-    expected_command = 'export PATH=$PATH:/test/one:test/two ; echo "1"'
-    self.assertEqual(popen_mock.call_args_list[0][0][0][3], expected_command)
+    expected_command = ['/bin/bash', '--login', '-c', 'echo "1"']
+    self.assertEqual(popen_mock.call_args_list[0][0][0], expected_command)
 
   @patch('time.sleep')
   @patch.object(subprocess, "Popen")
@@ -177,9 +176,8 @@ class TestExecuteResource(TestCase):
                                  environment={'JAVA_HOME': '/test/java/home',
                                               'PATH': "/bin"}
       )
-    expected_command = 'export  PATH=$PATH:/bin JAVA_HOME=/test/java/home ; echo "1"'
-    self.assertEqual(popen_mock.call_args_list[0][0][0][4], expected_user)
-    self.assertEqual(popen_mock.call_args_list[0][0][0][6], expected_command)
+    expected_command = '/usr/bin/sudo -Hsu test_user <<< \'export PATH=' + os.environ['PATH'] + ':/bin JAVA_HOME=/test/java/home; echo "1"\'' 
+    self.assertEqual(popen_mock.call_args_list[0][0][0][3], expected_command)
 
 
   @patch.object(subprocess, "Popen")

http://git-wip-us.apache.org/repos/asf/ambari/blob/68c55728/ambari-agent/src/test/python/resource_management/TestFileResource.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/resource_management/TestFileResource.py b/ambari-agent/src/test/python/resource_management/TestFileResource.py
index be6c6e7..063de19 100644
--- a/ambari-agent/src/test/python/resource_management/TestFileResource.py
+++ b/ambari-agent/src/test/python/resource_management/TestFileResource.py
@@ -24,6 +24,7 @@ import sys
 from resource_management.core import Environment, Fail
 from resource_management.core.resources import File
 from resource_management.core.system import System
+from resource_management.core import sudo
 import resource_management.core.providers.system
 import resource_management
 
@@ -76,17 +77,16 @@ class TestFileResource(TestCase):
     self.assertTrue(dirname_mock.called)
 
   @patch("resource_management.core.providers.system._ensure_metadata")
-  @patch("__builtin__.open")
+  @patch.object(sudo, "read_file")
+  @patch.object(sudo, "create_file")
   @patch.object(os.path, "exists")
   @patch.object(os.path, "isdir")
-  def test_action_create_non_existent_file(self, isdir_mock, exists_mock, open_mock, ensure_mock):
+  def test_action_create_non_existent_file(self, isdir_mock, exists_mock, create_file_mock, read_file_mock, ensure_mock):
     """
     Tests if 'create' action create new non existent file and write proper data
     """
     isdir_mock.side_effect = [False, True]
     exists_mock.return_value = False
-    new_file = MagicMock()
-    open_mock.return_value = new_file
     with Environment('/') as env:
       File('/directory/file',
            action='create',
@@ -95,24 +95,21 @@ class TestFileResource(TestCase):
       )
     
 
-    open_mock.assert_called_with('/directory/file', 'wb')
-    new_file.__enter__().write.assert_called_with('file-content')
-    self.assertEqual(open_mock.call_count, 1)
+    create_file_mock.assert_called_with('/directory/file', 'file-content')
+    self.assertEqual(create_file_mock.call_count, 1)
     ensure_mock.assert_called()
 
 
   @patch("resource_management.core.providers.system._ensure_metadata")
-  @patch("__builtin__.open")
+  @patch.object(sudo, "read_file")
+  @patch.object(sudo, "create_file")
   @patch.object(os.path, "exists")
   @patch.object(os.path, "isdir")
-  def test_action_create_replace(self, isdir_mock, exists_mock, open_mock, ensure_mock):
+  def test_action_create_replace(self, isdir_mock, exists_mock, create_file_mock, read_file_mock, ensure_mock):
     """
     Tests if 'create' action rewrite existent file with new data
     """
     isdir_mock.side_effect = [False, True]
-    old_file, new_file = MagicMock(), MagicMock()
-    open_mock.side_effect = [old_file, new_file]
-    old_file.read.return_value = 'old-content'
     exists_mock.return_value = True
 
     with Environment('/') as env:
@@ -123,16 +120,11 @@ class TestFileResource(TestCase):
            content='new-content'
       )
 
-    
-    old_file.read.assert_called()
-    new_file.__enter__().write.assert_called_with('new-content')
-    ensure_mock.assert_called()
-    self.assertEqual(open_mock.call_count, 2)
-    open_mock.assert_any_call('/directory/file', 'rb')
-    open_mock.assert_any_call('/directory/file', 'wb')
+    read_file_mock.assert_called_with('/directory/file')    
+    create_file_mock.assert_called_with('/directory/file', 'new-content')
 
 
-  @patch.object(os, "unlink")
+  @patch.object(sudo, "unlink")
   @patch.object(os.path, "exists")
   @patch.object(os.path, "isdir")
   def test_action_delete_is_directory(self, isdir_mock, exist_mock, unlink_mock):
@@ -158,7 +150,7 @@ class TestFileResource(TestCase):
     self.assertEqual(exist_mock.call_count, 0)
     self.assertEqual(unlink_mock.call_count, 0)
 
-  @patch.object(os, "unlink")
+  @patch.object(sudo, "unlink")
   @patch.object(os.path, "exists")
   @patch.object(os.path, "isdir")
   def test_action_delete(self, isdir_mock, exist_mock, unlink_mock):
@@ -204,15 +196,15 @@ class TestFileResource(TestCase):
 
   @patch.object(resource_management.core.Environment, "backup_file")
   @patch("resource_management.core.providers.system._ensure_metadata")
-  @patch("__builtin__.open")
+  @patch.object(sudo, "read_file")
+  @patch.object(sudo, "create_file")
   @patch.object(os.path, "exists")
   @patch.object(os.path, "isdir")
-  def test_attribute_backup(self, isdir_mock, exists_mock, open_mock, ensure_mock, backup_file_mock):
+  def test_attribute_backup(self, isdir_mock, exists_mock, create_file_mock,  read_file_mock, ensure_mock, backup_file_mock):
     """
     Tests 'backup' attribute
     """
     isdir_mock.side_effect = [False, True, False, True]
-    open_mock.return_value = MagicMock()
     exists_mock.return_value = True
 
     with Environment('/') as env:
@@ -271,13 +263,13 @@ class TestFileResource(TestCase):
 
   @patch("resource_management.core.providers.system._coerce_uid")
   @patch("resource_management.core.providers.system._coerce_gid")
-  @patch.object(os, "chown")
-  @patch.object(os, "chmod")
+  @patch.object(sudo, "chown")
+  @patch.object(sudo, "chmod")
   @patch.object(os, "stat")
-  @patch("__builtin__.open")
+  @patch.object(sudo, "create_file")
   @patch.object(os.path, "exists")
   @patch.object(os.path, "isdir")
-  def test_ensure_metadata(self, isdir_mock, exists_mock, open_mock, stat_mock, chmod_mock, chown_mock, gid_mock,
+  def test_ensure_metadata(self, isdir_mock, exists_mock, create_file_mock, stat_mock, chmod_mock, chown_mock, gid_mock,
                            uid_mock):
     """
     Tests if _ensure_metadata changes owner, usergroup and permissions of file to proper values
@@ -305,8 +297,8 @@ class TestFileResource(TestCase):
       )
     
 
-    open_mock.assert_called_with('/directory/file', 'wb')
-    self.assertEqual(open_mock.call_count, 1)
+    create_file_mock.assert_called_with('/directory/file', 'file-content')
+    self.assertEqual(create_file_mock.call_count, 1)
     stat_mock.assert_called_with('/directory/file')
     self.assertEqual(chmod_mock.call_count, 1)
     self.assertEqual(chown_mock.call_count, 2)
@@ -333,21 +325,18 @@ class TestFileResource(TestCase):
 
   @patch("resource_management.core.providers.system._ensure_metadata")
   @patch("resource_management.core.providers.system.FileProvider._get_content")
-  @patch("__builtin__.open")
+  @patch.object(sudo, "read_file")
+  @patch.object(sudo, "create_file")
   @patch.object(os.path, "exists")
   @patch.object(os.path, "isdir")
-  def test_action_create_encoding(self, isdir_mock, exists_mock, open_mock, get_content_mock ,ensure_mock):
+  def test_action_create_encoding(self, isdir_mock, exists_mock, create_file_mock, read_file_mock, get_content_mock ,ensure_mock):
 
     isdir_mock.side_effect = [False, True]
-    exists_mock.return_value = True
     content_mock = MagicMock()
     old_content_mock = MagicMock()
     get_content_mock.return_value = content_mock
-    new_file = MagicMock()
-    open_mock.return_value = new_file
-    enter_file_mock = MagicMock()
-    enter_file_mock.read = MagicMock(return_value=old_content_mock)
-    new_file.__enter__ = MagicMock(return_value=enter_file_mock)
+    read_file_mock.return_value = old_content_mock
+    exists_mock.return_value = True
     with Environment('/') as env:
       File('/directory/file',
            action='create',
@@ -357,7 +346,7 @@ class TestFileResource(TestCase):
       )
 
 
-    open_mock.assert_called_with('/directory/file', 'wb')
+    read_file_mock.assert_called_with('/directory/file')
     content_mock.encode.assert_called_with('UTF-8')
     old_content_mock.decode.assert_called_with('UTF-8')
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/68c55728/ambari-agent/src/test/python/resource_management/TestGroupResource.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/resource_management/TestGroupResource.py b/ambari-agent/src/test/python/resource_management/TestGroupResource.py
index ac25073..4245fdf 100644
--- a/ambari-agent/src/test/python/resource_management/TestGroupResource.py
+++ b/ambari-agent/src/test/python/resource_management/TestGroupResource.py
@@ -45,7 +45,7 @@ class TestGroupResource(TestCase):
     
 
     self.assertEqual(popen_mock.call_count, 1)
-    popen_mock.assert_called_with(['/bin/bash', '--login', '-c', 'groupadd -p secure hadoop'], shell=False, preexec_fn=None, stderr=-2, stdout=-1, env=None, cwd=None)
+    popen_mock.assert_called_with(['/bin/bash', '--login', '-c', "/usr/bin/sudo -s <<< 'groupadd -p secure hadoop'"], shell=False, preexec_fn=None, stderr=-2, stdout=-1, env=None, cwd=None)
     getgrnam_mock.assert_called_with('hadoop')
 
 
@@ -66,7 +66,7 @@ class TestGroupResource(TestCase):
     
 
     self.assertEqual(popen_mock.call_count, 1)
-    popen_mock.assert_called_with(['/bin/bash', '--login', '-c', 'groupmod -p secure -g 2 mapred'], shell=False, preexec_fn=None, stderr=-2, stdout=-1, env=None, cwd=None)
+    popen_mock.assert_called_with(['/bin/bash', '--login', '-c', "/usr/bin/sudo -s <<< 'groupmod -p secure -g 2 mapred'"], shell=False, preexec_fn=None, stderr=-2, stdout=-1, env=None, cwd=None)
     getgrnam_mock.assert_called_with('mapred')
 
 
@@ -90,7 +90,7 @@ class TestGroupResource(TestCase):
     except Fail:
       pass
     self.assertEqual(popen_mock.call_count, 1)
-    popen_mock.assert_called_with(['/bin/bash', '--login', '-c', 'groupmod -p secure -g 2 mapred'], shell=False, preexec_fn=None, stderr=-2, stdout=-1, env=None, cwd=None)
+    popen_mock.assert_called_with(['/bin/bash', '--login', '-c', "/usr/bin/sudo -s <<< 'groupmod -p secure -g 2 mapred'"], shell=False, preexec_fn=None, stderr=-2, stdout=-1, env=None, cwd=None)
     getgrnam_mock.assert_called_with('mapred')
 
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/68c55728/ambari-agent/src/test/python/resource_management/TestLinkResource.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/resource_management/TestLinkResource.py b/ambari-agent/src/test/python/resource_management/TestLinkResource.py
index 87af645..6a428b6 100644
--- a/ambari-agent/src/test/python/resource_management/TestLinkResource.py
+++ b/ambari-agent/src/test/python/resource_management/TestLinkResource.py
@@ -20,6 +20,7 @@ from unittest import TestCase
 from mock.mock import patch, MagicMock
 
 from resource_management.core import Environment, Fail
+from resource_management.core import sudo
 from resource_management.core.system import System
 from resource_management.core.resources.system import Link
 
@@ -31,8 +32,8 @@ class TestLinkResource(TestCase):
   @patch.object(os.path, "realpath")
   @patch.object(os.path, "lexists")
   @patch.object(os.path, "islink")
-  @patch.object(os, "unlink")
-  @patch.object(os, "symlink")
+  @patch.object(sudo, "unlink")
+  @patch.object(sudo, "symlink")
   def test_action_create_relink(self, symlink_mock, unlink_mock, 
                          islink_mock, lexists_mock,
                          realmock):
@@ -67,7 +68,7 @@ class TestLinkResource(TestCase):
                        str(e))
         
   @patch.object(os.path, "lexists")
-  @patch.object(os, "symlink")
+  @patch.object(sudo, "symlink")
   def test_action_create_symlink_clean_create(self, symlink_mock, lexists_mock):
     lexists_mock.return_value = False
     
@@ -81,7 +82,7 @@ class TestLinkResource(TestCase):
   @patch.object(os.path, "isdir")
   @patch.object(os.path, "exists")  
   @patch.object(os.path, "lexists")
-  @patch.object(os, "link")
+  @patch.object(sudo, "link")
   def test_action_create_hardlink_clean_create(self, link_mock, lexists_mock,
                                         exists_mock, isdir_mock):
     lexists_mock.return_value = False
@@ -134,7 +135,7 @@ class TestLinkResource(TestCase):
         self.assertEqual("Failed to apply Link['/some_path'], cannot create hard link to a directory (/a/b/link_to_path)",
                        str(e)) 
         
-  @patch.object(os, "unlink")
+  @patch.object(sudo, "unlink")
   @patch.object(os.path, "exists")
   def test_action_delete(self, exists_mock, unlink_mock):     
     exists_mock.return_value = True

http://git-wip-us.apache.org/repos/asf/ambari/blob/68c55728/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 faa89d0..c762355 100644
--- a/ambari-agent/src/test/python/resource_management/TestPackageResource.py
+++ b/ambari-agent/src/test/python/resource_management/TestPackageResource.py
@@ -37,11 +37,11 @@ class TestPackageResource(TestCase):
       )
     call_mock.assert_has_calls([call("dpkg --get-selections | grep ^some-package$ | grep -v deinstall"),
                                 call("DEBIAN_FRONTEND=noninteractive /usr/bin/apt-get -q -o Dpkg::Options::='--force-confdef'"
-                                      " --allow-unauthenticated --assume-yes install some-package"),
-                                call("apt-get update -qq")
+                                      " --allow-unauthenticated --assume-yes install some-package", sudo=True),
+                                call("apt-get update -qq", sudo=True)
                               ])
     
-    shell_mock.assert_has_calls([call("DEBIAN_FRONTEND=noninteractive /usr/bin/apt-get -q -o Dpkg::Options::='--force-confdef' --allow-unauthenticated --assume-yes install some-package")
+    shell_mock.assert_has_calls([call("DEBIAN_FRONTEND=noninteractive /usr/bin/apt-get -q -o Dpkg::Options::='--force-confdef' --allow-unauthenticated --assume-yes install some-package", sudo=True)
                               ])
   
   @patch.object(shell, "call")
@@ -54,7 +54,7 @@ class TestPackageResource(TestCase):
       )
     call_mock.assert_has_calls([call("dpkg --get-selections | grep ^some-package$ | grep -v deinstall"),
                                 call("DEBIAN_FRONTEND=noninteractive /usr/bin/apt-get -q -o Dpkg::Options::='--force-confdef'"
-                                      " --allow-unauthenticated --assume-yes install some-package")
+                                      " --allow-unauthenticated --assume-yes install some-package", sudo=True)
                               ])
     
     self.assertEqual(shell_mock.call_count, 0, "shell.checked_call shouldn't be called")
@@ -70,7 +70,7 @@ class TestPackageResource(TestCase):
       Package("some_package",
       )
     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")
+    shell_mock.assert_called_with("/usr/bin/yum -d 0 -e 0 -y install some_package", sudo=True)
 
   @patch.object(shell, "call")
   @patch.object(shell, "checked_call")
@@ -81,7 +81,7 @@ class TestPackageResource(TestCase):
       Package("some_package",
       )
     call_mock.assert_called_with('rpm -qa | grep ^some_package')
-    shell_mock.assert_called_with("/usr/bin/zypper --quiet install --auto-agree-with-licenses --no-confirm some_package")
+    shell_mock.assert_called_with("/usr/bin/zypper --quiet install --auto-agree-with-licenses --no-confirm some_package", sudo=True)
 
   @patch.object(shell, "call", new = MagicMock(return_value=(0, None)))
   @patch.object(shell, "checked_call")
@@ -109,7 +109,7 @@ class TestPackageResource(TestCase):
       Package("some_package",
               action = "remove"
       )
-    shell_mock.assert_called_with("/usr/bin/yum -d 0 -e 0 -y erase some_package")
+    shell_mock.assert_called_with("/usr/bin/yum -d 0 -e 0 -y erase some_package", sudo=True)
 
   @patch.object(shell, "call", new = MagicMock(return_value=(0, None)))
   @patch.object(shell, "checked_call")
@@ -119,7 +119,7 @@ class TestPackageResource(TestCase):
       Package("some_package",
               action = "remove"
       )
-    shell_mock.assert_called_with("/usr/bin/zypper --quiet remove --no-confirm some_package")
+    shell_mock.assert_called_with("/usr/bin/zypper --quiet remove --no-confirm some_package", sudo=True)
 
   @patch.object(shell, "call", new = MagicMock(return_value=(1, None)))
   @patch.object(shell, "checked_call")
@@ -129,7 +129,7 @@ class TestPackageResource(TestCase):
       Package("some_package",
               version = "3.5.0"
       )
-    shell_mock.assert_called_with("/usr/bin/yum -d 0 -e 0 -y install some_package-3.5.0")
+    shell_mock.assert_called_with("/usr/bin/yum -d 0 -e 0 -y install some_package-3.5.0", sudo=True)
 
   @replace_underscores
   def func_to_test(self, name):

http://git-wip-us.apache.org/repos/asf/ambari/blob/68c55728/ambari-agent/src/test/python/resource_management/TestPropertiesFileResource.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/resource_management/TestPropertiesFileResource.py b/ambari-agent/src/test/python/resource_management/TestPropertiesFileResource.py
index 1f7581b..bdb64de 100644
--- a/ambari-agent/src/test/python/resource_management/TestPropertiesFileResource.py
+++ b/ambari-agent/src/test/python/resource_management/TestPropertiesFileResource.py
@@ -24,7 +24,7 @@ import os
 import time
 from unittest import TestCase
 from mock.mock import patch, MagicMock
-from resource_management.core import Environment
+from resource_management.core import Environment, sudo
 from resource_management.core.system import System
 from resource_management.libraries import PropertiesFile
 
@@ -37,7 +37,7 @@ class TestPropertiesFIleResource(TestCase):
 
 
   @patch("resource_management.core.providers.system._ensure_metadata")
-  @patch("__builtin__.open")
+  @patch.object(sudo, "create_file")
   @patch.object(os.path, "exists")
   @patch.object(os.path, "isdir")
   @patch.object(time, "asctime")
@@ -45,7 +45,7 @@ class TestPropertiesFIleResource(TestCase):
                                                       time_asctime_mock,
                                                       os_path_isdir_mock,
                                                       os_path_exists_mock,
-                                                      open_mock,
+                                                      create_file_mock,
                                                       ensure_mock):
     """
     Tests if 'action_create' - creates new non existent file and write proper data
@@ -56,8 +56,8 @@ class TestPropertiesFIleResource(TestCase):
     os_path_exists_mock.return_value = False
     time_asctime_mock.return_value = 'Today is Wednesday'
 
-    result_file = MagicMock()
-    open_mock.return_value = result_file
+    
+    
 
     with Environment('/') as env:
       PropertiesFile('/somewhere_in_system/one_file.properties',
@@ -65,14 +65,12 @@ class TestPropertiesFIleResource(TestCase):
                      properties={}
       )
 
-    open_mock.assert_called_with('/somewhere_in_system/one_file.properties', 'wb')
-    result_file.__enter__().write.assert_called_with( u'# Generated by Apache Ambari. Today is Wednesday\n    \n    \n')
-    self.assertEqual(open_mock.call_count, 1)
+    create_file_mock.assert_called_with('/somewhere_in_system/one_file.properties', u'# Generated by Apache Ambari. Today is Wednesday\n    \n    \n')
     ensure_mock.assert_called()
 
 
   @patch("resource_management.core.providers.system._ensure_metadata")
-  @patch("__builtin__.open")
+  @patch.object(sudo, "create_file")
   @patch.object(os.path, "exists")
   @patch.object(os.path, "isdir")
   @patch.object(time, "asctime")
@@ -80,7 +78,7 @@ class TestPropertiesFIleResource(TestCase):
                                                    time_asctime_mock,
                                                    os_path_isdir_mock,
                                                    os_path_exists_mock,
-                                                   open_mock,
+                                                   create_file_mock,
                                                    ensure_mock):
     """
     Tests if 'action_create' - creates new non existent file and write proper data
@@ -91,8 +89,8 @@ class TestPropertiesFIleResource(TestCase):
     os_path_exists_mock.return_value = False
     time_asctime_mock.return_value = 'Some other day'
 
-    result_file = MagicMock()
-    open_mock.return_value = result_file
+    
+    
 
     with Environment('/') as env:
       PropertiesFile('file.txt',
@@ -100,14 +98,12 @@ class TestPropertiesFIleResource(TestCase):
                      properties={},
       )
 
-    open_mock.assert_called_with('/dir/and/dir/file.txt', 'wb')
-    result_file.__enter__().write.assert_called_with(u'# Generated by Apache Ambari. Some other day\n    \n    \n')
-    self.assertEqual(open_mock.call_count, 1)
+    create_file_mock.assert_called_with('/dir/and/dir/file.txt', u'# Generated by Apache Ambari. Some other day\n    \n    \n')
     ensure_mock.assert_called()
 
 
   @patch("resource_management.core.providers.system._ensure_metadata")
-  @patch("__builtin__.open")
+  @patch.object(sudo, "create_file")
   @patch.object(os.path, "exists")
   @patch.object(os.path, "isdir")
   @patch.object(time, "asctime")
@@ -115,7 +111,7 @@ class TestPropertiesFIleResource(TestCase):
                                            time_asctime_mock,
                                            os_path_isdir_mock,
                                            os_path_exists_mock,
-                                           open_mock,
+                                           create_file_mock,
                                            ensure_mock):
     """
     Tests if 'action_create' - creates new non existent file and write proper data
@@ -127,23 +123,20 @@ class TestPropertiesFIleResource(TestCase):
     os_path_exists_mock.return_value = False
     time_asctime_mock.return_value = 777
 
-    result_file = MagicMock()
-    open_mock.return_value = result_file
+    
+    
 
     with Environment('/') as env:
       PropertiesFile('/dir/new_file',
                      properties={'property1': 'value1'},
       )
 
-    open_mock.assert_called_with('/dir/new_file',
-                                 'wb')
-    result_file.__enter__().write.assert_called_with(u'# Generated by Apache Ambari. 777\n    \nproperty1=value1\n    \n')
-    self.assertEqual(open_mock.call_count, 1)
+    create_file_mock.assert_called_with('/dir/new_file', u'# Generated by Apache Ambari. 777\n    \nproperty1=value1\n    \n')
     ensure_mock.assert_called()
 
 
   @patch("resource_management.core.providers.system._ensure_metadata")
-  @patch("__builtin__.open")
+  @patch.object(sudo, "create_file")
   @patch.object(os.path, "exists")
   @patch.object(os.path, "isdir")
   @patch.object(time, "asctime")
@@ -151,7 +144,7 @@ class TestPropertiesFIleResource(TestCase):
                                                         time_asctime_mock,
                                                         os_path_isdir_mock,
                                                         os_path_exists_mock,
-                                                        open_mock,
+                                                        create_file_mock,
                                                         ensure_mock):
     """
     Tests if 'action_create' - creates new non existent file and write proper data
@@ -162,8 +155,8 @@ class TestPropertiesFIleResource(TestCase):
     os_path_exists_mock.return_value = False
     time_asctime_mock.return_value = 777
 
-    result_file = MagicMock()
-    open_mock.return_value = result_file
+    
+    
 
     with Environment('/') as env:
       PropertiesFile('/dir/new_file',
@@ -176,14 +169,13 @@ class TestPropertiesFIleResource(TestCase):
                      },
       )
 
-    open_mock.assert_called_with('/dir/new_file','wb')
-    result_file.__enter__().write.assert_called_with(u"# Generated by Apache Ambari. 777\n    \n=\nprop.1='.'yyyy-MM-dd-HH\nprop.2=INFO, openjpa\nprop.3=%d{ISO8601} %5p %c{1}:%L - %m%n\nprop.4=${oozie.log.dir}/oozie.log\nprop.empty=\n    \n")
-    self.assertEqual(open_mock.call_count, 1)
+    create_file_mock.assert_called_with('/dir/new_file', u"# Generated by Apache Ambari. 777\n    \n=\nprop.1='.'yyyy-MM-dd-HH\nprop.2=INFO, openjpa\nprop.3=%d{ISO8601} %5p %c{1}:%L - %m%n\nprop.4=${oozie.log.dir}/oozie.log\nprop.empty=\n    \n")
     ensure_mock.assert_called()
 
 
   @patch("resource_management.core.providers.system._ensure_metadata")
-  @patch("__builtin__.open")
+  @patch.object(sudo, "read_file")
+  @patch.object(sudo, "create_file")
   @patch.object(os.path, "exists")
   @patch.object(os.path, "isdir")
   @patch.object(time, "asctime")
@@ -191,7 +183,8 @@ class TestPropertiesFIleResource(TestCase):
                                                     time_asctime_mock,
                                                     os_path_isdir_mock,
                                                     os_path_exists_mock,
-                                                    open_mock,
+                                                    create_file_mock,
+                                                    read_file_mock,
                                                     ensure_mock):
     """
     Tests if 'action_create' - rewrite file that exist
@@ -202,9 +195,9 @@ class TestPropertiesFIleResource(TestCase):
     os_path_exists_mock.return_value = True
     time_asctime_mock.return_value = 777
 
-    result_file = MagicMock()
-    result_file.read.return_value = 'old-content'
-    open_mock.return_value = result_file
+    
+    read_file_mock.return_value = 'old-content'
+    
 
     with Environment('/') as env:
       PropertiesFile('new_file',
@@ -212,8 +205,6 @@ class TestPropertiesFIleResource(TestCase):
                      properties={'property_1': 'value1'},
       )
 
-    result_file.read.assert_called()
-    open_mock.assert_called_with('/dir1/new_file', 'wb')
-    result_file.__enter__().write.assert_called_with(u'# Generated by Apache Ambari. 777\n    \nproperty_1=value1\n    \n')
-    self.assertEqual(open_mock.call_count, 2)
+    read_file_mock.assert_called()
+    create_file_mock.assert_called_with('/dir1/new_file', u'# Generated by Apache Ambari. 777\n    \nproperty_1=value1\n    \n')
     ensure_mock.assert_called()

http://git-wip-us.apache.org/repos/asf/ambari/blob/68c55728/ambari-agent/src/test/python/resource_management/TestUserResource.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/resource_management/TestUserResource.py b/ambari-agent/src/test/python/resource_management/TestUserResource.py
index b0eb972..f1d22e6 100644
--- a/ambari-agent/src/test/python/resource_management/TestUserResource.py
+++ b/ambari-agent/src/test/python/resource_management/TestUserResource.py
@@ -38,7 +38,7 @@ class TestUserResource(TestCase):
     with Environment('/') as env:
       user = User("mapred", action = "create", shell = "/bin/bash")
 
-    popen_mock.assert_called_with(['/bin/bash', '--login', '-c', 'useradd -m -s /bin/bash mapred'], shell=False, preexec_fn=None, stderr=-2, stdout=-1, env=None, cwd=None)
+    popen_mock.assert_called_with(['/bin/bash', '--login', '-c', "/usr/bin/sudo -s <<< 'useradd -m -s /bin/bash mapred'"], shell=False, preexec_fn=None, stderr=-2, stdout=-1, env=None, cwd=None)
     self.assertEqual(popen_mock.call_count, 1)
 
   @patch.object(subprocess, "Popen")
@@ -52,7 +52,7 @@ class TestUserResource(TestCase):
     with Environment('/') as env:
       user = User("mapred", action = "create", shell = "/bin/bash")
 
-    popen_mock.assert_called_with(['/bin/bash', '--login', '-c', 'usermod -s /bin/bash mapred'], shell=False, preexec_fn=None, stderr=-2, stdout=-1, env=None, cwd=None)
+    popen_mock.assert_called_with(['/bin/bash', '--login', '-c', "/usr/bin/sudo -s <<< 'usermod -s /bin/bash mapred'"], shell=False, preexec_fn=None, stderr=-2, stdout=-1, env=None, cwd=None)
     self.assertEqual(popen_mock.call_count, 1)
 
   @patch.object(subprocess, "Popen")
@@ -81,7 +81,7 @@ class TestUserResource(TestCase):
       user = User("mapred", action = "create", comment = "testComment", 
           shell = "/bin/bash")
 
-    popen_mock.assert_called_with(['/bin/bash', '--login', '-c', 'usermod -c testComment -s /bin/bash mapred'], shell=False, preexec_fn=None, stderr=-2, stdout=-1, env=None, cwd=None)
+    popen_mock.assert_called_with(['/bin/bash', '--login', '-c', "/usr/bin/sudo -s <<< 'usermod -c testComment -s /bin/bash mapred'"], shell=False, preexec_fn=None, stderr=-2, stdout=-1, env=None, cwd=None)
     self.assertEqual(popen_mock.call_count, 1)
 
   @patch.object(subprocess, "Popen")
@@ -96,7 +96,7 @@ class TestUserResource(TestCase):
       user = User("mapred", action = "create", home = "/test/home", 
           shell = "/bin/bash")
 
-    popen_mock.assert_called_with(['/bin/bash', '--login', '-c', 'usermod -s /bin/bash -d /test/home mapred'], shell=False, preexec_fn=None, stderr=-2, stdout=-1, env=None, cwd=None)
+    popen_mock.assert_called_with(['/bin/bash', '--login', '-c', "/usr/bin/sudo -s <<< 'usermod -s /bin/bash -d /test/home mapred'"], shell=False, preexec_fn=None, stderr=-2, stdout=-1, env=None, cwd=None)
     self.assertEqual(popen_mock.call_count, 1)
 
   @patch.object(subprocess, "Popen")
@@ -111,7 +111,7 @@ class TestUserResource(TestCase):
       user = User("mapred", action = "create", password = "secure", 
           shell = "/bin/bash")    
 
-    popen_mock.assert_called_with(['/bin/bash', '--login', '-c', 'usermod -s /bin/bash -p secure mapred'], shell=False, preexec_fn=None, stderr=-2, stdout=-1, env=None, cwd=None)
+    popen_mock.assert_called_with(['/bin/bash', '--login', '-c', "/usr/bin/sudo -s <<< 'usermod -s /bin/bash -p secure mapred'"], shell=False, preexec_fn=None, stderr=-2, stdout=-1, env=None, cwd=None)
     self.assertEqual(popen_mock.call_count, 1)
 
   @patch.object(subprocess, "Popen")
@@ -125,7 +125,7 @@ class TestUserResource(TestCase):
     with Environment('/') as env:
       user = User("mapred", action = "create", shell = "/bin/sh")
 
-    popen_mock.assert_called_with(['/bin/bash', '--login', '-c', 'usermod -s /bin/sh mapred'], shell=False, preexec_fn=None, stderr=-2, stdout=-1, env=None, cwd=None)
+    popen_mock.assert_called_with(['/bin/bash', '--login', '-c', "/usr/bin/sudo -s <<< 'usermod -s /bin/sh mapred'"], shell=False, preexec_fn=None, stderr=-2, stdout=-1, env=None, cwd=None)
     self.assertEqual(popen_mock.call_count, 1)
 
   @patch.object(subprocess, "Popen")
@@ -139,7 +139,7 @@ class TestUserResource(TestCase):
     with Environment('/') as env:
       user = User("mapred", action = "create", uid = "1", shell = "/bin/bash")
 
-    popen_mock.assert_called_with(['/bin/bash', '--login', '-c', 'usermod -s /bin/bash -u 1 mapred'], shell=False, preexec_fn=None, stderr=-2, stdout=-1, env=None, cwd=None)
+    popen_mock.assert_called_with(['/bin/bash', '--login', '-c', "/usr/bin/sudo -s <<< 'usermod -s /bin/bash -u 1 mapred'"], shell=False, preexec_fn=None, stderr=-2, stdout=-1, env=None, cwd=None)
     self.assertEqual(popen_mock.call_count, 1)
 
   @patch.object(subprocess, "Popen")
@@ -153,7 +153,7 @@ class TestUserResource(TestCase):
     with Environment('/') as env:
       user = User("mapred", action = "create", gid = "1", shell = "/bin/bash")
 
-    popen_mock.assert_called_with(['/bin/bash', '--login', '-c', 'usermod -s /bin/bash -g 1 mapred'], shell=False, preexec_fn=None, stderr=-2, stdout=-1, env=None, cwd=None)
+    popen_mock.assert_called_with(['/bin/bash', '--login', '-c', "/usr/bin/sudo -s <<< 'usermod -s /bin/bash -g 1 mapred'"], shell=False, preexec_fn=None, stderr=-2, stdout=-1, env=None, cwd=None)
     self.assertEqual(popen_mock.call_count, 1)
 
   @patch.object(subprocess, "Popen")
@@ -168,7 +168,7 @@ class TestUserResource(TestCase):
       user = User("mapred", action = "create", groups = ['1','2','3'], 
           shell = "/bin/bash")
 
-    popen_mock.assert_called_with(['/bin/bash', '--login', '-c', 'usermod -G 1,2,3 -s /bin/bash mapred'], shell=False, preexec_fn=None, stderr=-2, stdout=-1, env=None, cwd=None)
+    popen_mock.assert_called_with(['/bin/bash', '--login', '-c', "/usr/bin/sudo -s <<< 'usermod -G 1,2,3 -s /bin/bash mapred'"], shell=False, preexec_fn=None, stderr=-2, stdout=-1, env=None, cwd=None)
     self.assertEqual(popen_mock.call_count, 1)
 
   @patch.object(subprocess, "Popen")
@@ -181,5 +181,5 @@ class TestUserResource(TestCase):
     with Environment('/') as env:
       user = User("mapred", action = "create")
 
-    popen_mock.assert_called_with(['/bin/bash', '--login', '-c', 'useradd -m mapred'], shell=False, preexec_fn=None, stderr=-2, stdout=-1, env=None, cwd=None)
+    popen_mock.assert_called_with(['/bin/bash', '--login', '-c', "/usr/bin/sudo -s <<< 'useradd -m mapred'"], shell=False, preexec_fn=None, stderr=-2, stdout=-1, env=None, cwd=None)
     self.assertEqual(popen_mock.call_count, 1)

http://git-wip-us.apache.org/repos/asf/ambari/blob/68c55728/ambari-agent/src/test/python/resource_management/TestXmlConfigResource.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/resource_management/TestXmlConfigResource.py b/ambari-agent/src/test/python/resource_management/TestXmlConfigResource.py
index e7a61e4..4affd31 100644
--- a/ambari-agent/src/test/python/resource_management/TestXmlConfigResource.py
+++ b/ambari-agent/src/test/python/resource_management/TestXmlConfigResource.py
@@ -24,7 +24,7 @@ import os
 import time
 from unittest import TestCase
 from mock.mock import patch, MagicMock
-from resource_management.core import Environment
+from resource_management.core import Environment, sudo
 from resource_management.core.system import System
 from resource_management.libraries import XmlConfig
 
@@ -37,7 +37,7 @@ class TestXmlConfigResource(TestCase):
   """
 
   @patch("resource_management.core.providers.system._ensure_metadata")
-  @patch("__builtin__.open")
+  @patch.object(sudo, "create_file")
   @patch.object(os.path, "exists")
   @patch.object(os.path, "isdir")
   @patch.object(time, "asctime")
@@ -45,7 +45,7 @@ class TestXmlConfigResource(TestCase):
                                           time_asctime_mock,
                                           os_path_isdir_mock,
                                           os_path_exists_mock,
-                                          open_mock,
+                                          create_file_mock,
                                           ensure_mock):
     """
     Tests if 'create' action - creates new non existent xml file and write proper data
@@ -55,9 +55,6 @@ class TestXmlConfigResource(TestCase):
     os_path_exists_mock.return_value = False
     time_asctime_mock.return_value = 'Wed 2014-02'
 
-    result_file = MagicMock()
-    open_mock.return_value = result_file
-
     with Environment('/') as env:
       XmlConfig('file.xml',
                 conf_dir='/dir/conf',
@@ -65,12 +62,11 @@ class TestXmlConfigResource(TestCase):
                 configuration_attributes={}
                 )
 
-    open_mock.assert_called_with('/dir/conf/file.xml', 'wb')
-    result_file.__enter__().write.assert_called_with(u'<!--Wed 2014-02-->\n    <configuration>\n    \n  </configuration>\n')
+    create_file_mock.assert_called_with('/dir/conf/file.xml', u'<!--Wed 2014-02-->\n    <configuration>\n    \n  </configuration>\n')
 
 
   @patch("resource_management.core.providers.system._ensure_metadata")
-  @patch("__builtin__.open")
+  @patch.object(sudo, "create_file")
   @patch.object(os.path, "exists")
   @patch.object(os.path, "isdir")
   @patch.object(time, "asctime")
@@ -78,7 +74,7 @@ class TestXmlConfigResource(TestCase):
                                            time_asctime_mock,
                                            os_path_isdir_mock,
                                            os_path_exists_mock,
-                                           open_mock,
+                                           create_file_mock,
                                            ensure_mock):
     """
     Tests if 'create' action - creates new non existent xml file and write proper data
@@ -88,9 +84,6 @@ class TestXmlConfigResource(TestCase):
     os_path_exists_mock.return_value = False
     time_asctime_mock.return_value = 'Wed 2014-02'
 
-    result_file = MagicMock()
-    open_mock.return_value = result_file
-
     with Environment('/') as env:
       XmlConfig('file.xml',
                 conf_dir='/dir/conf',
@@ -98,12 +91,11 @@ class TestXmlConfigResource(TestCase):
                 configuration_attributes={'attr': {'property1': 'attr_value'}}
                 )
 
-    open_mock.assert_called_with('/dir/conf/file.xml', 'wb')
-    result_file.__enter__().write.assert_called_with(u'<!--Wed 2014-02-->\n    <configuration>\n    \n    <property>\n      <name>property1</name>\n      <value>value1</value>\n      <attr>attr_value</attr>\n    </property>\n    \n  </configuration>\n')
+    create_file_mock.assert_called_with('/dir/conf/file.xml', u'<!--Wed 2014-02-->\n    <configuration>\n    \n    <property>\n      <name>property1</name>\n      <value>value1</value>\n      <attr>attr_value</attr>\n    </property>\n    \n  </configuration>\n')
 
 
   @patch("resource_management.core.providers.system._ensure_metadata")
-  @patch("__builtin__.open")
+  @patch.object(sudo, "create_file")
   @patch.object(os.path, "exists")
   @patch.object(os.path, "isdir")
   @patch.object(time, "asctime")
@@ -111,7 +103,7 @@ class TestXmlConfigResource(TestCase):
                                                         time_asctime_mock,
                                                         os_path_isdir_mock,
                                                         os_path_exists_mock,
-                                                        open_mock,
+                                                        create_file_mock,
                                                         ensure_mock):
     """
     Tests if 'create' action - creates new non existent xml file and write proper data
@@ -121,9 +113,6 @@ class TestXmlConfigResource(TestCase):
     os_path_exists_mock.return_value = False
     time_asctime_mock.return_value = 'Wed 2014-02'
 
-    result_file = MagicMock()
-    open_mock.return_value = result_file
-
     with Environment('/') as env:
       XmlConfig('file.xml',
                 conf_dir='/dir/conf',
@@ -155,11 +144,10 @@ class TestXmlConfigResource(TestCase):
                     }
                 })
 
-    open_mock.assert_called_with('/dir/conf/file.xml', 'wb')
-    result_file.__enter__().write.assert_called_with(u'<!--Wed 2014-02-->\n    <configuration>\n    \n    <property>\n      <name></name>\n      <value></value>\n    </property>\n    \n    <property>\n      <name>prop.1</name>\n      <value>&#39;.&#39;yyyy-MM-dd-HH</value>\n      <attr1>x</attr1>\n    </property>\n    \n    <property>\n      <name>prop.2</name>\n      <value>INFO, openjpa</value>\n    </property>\n    \n    <property>\n      <name>prop.3</name>\n      <value>%d{ISO8601} %5p %c{1}:%L - %m%n</value>\n      <attr2>value3</attr2>\n    </property>\n    \n    <property>\n      <name>prop.4</name>\n      <value>${oozie.log.dir}/oozie.log</value>\n      <attr_value_empty></attr_value_empty>\n      <attr2>value4</attr2>\n    </property>\n    \n    <property>\n      <name>prop.empty</name>\n      <value></value>\n      <attr_value_empty></attr_value_empty>\n    </property>\n    \n  </configuration>\n')
+    create_file_mock.assert_called_with('/dir/conf/file.xml', u'<!--Wed 2014-02-->\n    <configuration>\n    \n    <property>\n      <name></name>\n      <value></value>\n    </property>\n    \n    <property>\n      <name>prop.1</name>\n      <value>&#39;.&#39;yyyy-MM-dd-HH</value>\n      <attr1>x</attr1>\n    </property>\n    \n    <property>\n      <name>prop.2</name>\n      <value>INFO, openjpa</value>\n    </property>\n    \n    <property>\n      <name>prop.3</name>\n      <value>%d{ISO8601} %5p %c{1}:%L - %m%n</value>\n      <attr2>value3</attr2>\n    </property>\n    \n    <property>\n      <name>prop.4</name>\n      <value>${oozie.log.dir}/oozie.log</value>\n      <attr_value_empty></attr_value_empty>\n      <attr2>value4</attr2>\n    </property>\n    \n    <property>\n      <name>prop.empty</name>\n      <value></value>\n      <attr_value_empty></attr_value_empty>\n    </property>\n    \n  </configuration>\n')
 
   @patch("resource_management.core.providers.system._ensure_metadata")
-  @patch("__builtin__.open")
+  @patch.object(sudo, "create_file")
   @patch.object(os.path, "exists")
   @patch.object(os.path, "isdir")
   @patch.object(time, "asctime")
@@ -167,7 +155,7 @@ class TestXmlConfigResource(TestCase):
                                                   time_asctime_mock,
                                                   os_path_isdir_mock,
                                                   os_path_exists_mock,
-                                                  open_mock,
+                                                  create_file_mock,
                                                   ensure_mock):
     """
     Tests if 'create' action - creates new non existent xml file and writes proper data
@@ -177,9 +165,6 @@ class TestXmlConfigResource(TestCase):
     os_path_exists_mock.return_value = False
     time_asctime_mock.return_value = 'Wed 2014-02'
 
-    result_file = MagicMock()
-    open_mock.return_value = result_file
-
     with Environment('/') as env:
       XmlConfig('file.xml',
                 conf_dir='/dir/conf',
@@ -192,8 +177,7 @@ class TestXmlConfigResource(TestCase):
                 configuration_attributes={}
                 )
 
-    open_mock.assert_called_with('/dir/conf/file.xml', 'wb')
-    result_file.__enter__().write.assert_called_with(u'<!--Wed 2014-02-->\n    <configuration>\n    \n    <property>\n      <name></name>\n      <value></value>\n    </property>\n    \n    <property>\n      <name>first</name>\n      <value>should be first</value>\n    </property>\n    \n    <property>\n      <name>second</name>\n      <value>should be second</value>\n    </property>\n    \n    <property>\n      <name>third</name>\n      <value>should be third</value>\n    </property>\n    \n    <property>\n      <name>z_last</name>\n      <value>should be last</value>\n    </property>\n    \n  </configuration>\n')
+    create_file_mock.assert_called_with('/dir/conf/file.xml', u'<!--Wed 2014-02-->\n    <configuration>\n    \n    <property>\n      <name></name>\n      <value></value>\n    </property>\n    \n    <property>\n      <name>first</name>\n      <value>should be first</value>\n    </property>\n    \n    <property>\n      <name>second</name>\n      <value>should be second</value>\n    </property>\n    \n    <property>\n      <name>third</name>\n      <value>should be third</value>\n    </property>\n    \n    <property>\n      <name>z_last</name>\n      <value>should be last</value>\n    </property>\n    \n  </configuration>\n')
 
   @patch("resource_management.libraries.providers.xml_config.File")
   @patch.object(os.path, "exists")

http://git-wip-us.apache.org/repos/asf/ambari/blob/68c55728/ambari-common/src/main/python/resource_management/core/providers/accounts.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/resource_management/core/providers/accounts.py b/ambari-common/src/main/python/resource_management/core/providers/accounts.py
index 92a528b..c99b775 100644
--- a/ambari-common/src/main/python/resource_management/core/providers/accounts.py
+++ b/ambari-common/src/main/python/resource_management/core/providers/accounts.py
@@ -60,7 +60,7 @@ class UserProvider(Provider):
 
     command.append(self.resource.username)
 
-    shell.checked_call(command)
+    shell.checked_call(command, sudo=True)
 
   def action_remove(self):
     if self.user:
@@ -98,7 +98,7 @@ class GroupProvider(Provider):
         
     command.append(self.resource.group_name)
 
-    shell.checked_call(command)
+    shell.checked_call(command, sudo=True)
 
     group = self.group
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/68c55728/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 9346b3e..0ad6ca5 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
@@ -42,19 +42,19 @@ class AptProvider(PackageProvider):
     if not self._check_existence(name):
       cmd = INSTALL_CMD % (name)
       Logger.info("Installing package %s ('%s')" % (name, cmd))
-      code, out = shell.call(cmd)
+      code, out = shell.call(cmd, sudo=True)
       
       # apt-get update wasn't done too long
       if code:
         Logger.info("Execution of '%s' returned %d. %s" % (cmd, code, out))
         Logger.info("Failed to install package %s. Executing `%s`" % (name, REPO_UPDATE_CMD))
-        code, out = shell.call(REPO_UPDATE_CMD)
+        code, out = shell.call(REPO_UPDATE_CMD, sudo=True)
         
         if code:
           Logger.info("Execution of '%s' returned %d. %s" % (REPO_UPDATE_CMD, code, out))
           
         Logger.info("Retrying to install package %s" % (name))
-        shell.checked_call(cmd)
+        shell.checked_call(cmd, sudo=True)
     else:
       Logger.info("Skipping installing existent package %s" % (name))
 
@@ -67,7 +67,7 @@ class AptProvider(PackageProvider):
     if self._check_existence(name):
       cmd = REMOVE_CMD % (name)
       Logger.info("Removing package %s ('%s')" % (name, cmd))
-      shell.checked_call(cmd)
+      shell.checked_call(cmd, sudo=True)
     else:
       Logger.info("Skipping removing non-existent package %s" % (name))
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/68c55728/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 0b26e76..b026ab4 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
@@ -33,7 +33,7 @@ class YumProvider(PackageProvider):
     if not self._check_existence(name):
       cmd = INSTALL_CMD % (name)
       Logger.info("Installing package %s ('%s')" % (name, cmd))
-      shell.checked_call(cmd)
+      shell.checked_call(cmd, sudo=True)
     else:
       Logger.info("Skipping installing existent package %s" % (name))
 
@@ -44,7 +44,7 @@ class YumProvider(PackageProvider):
     if self._check_existence(name):
       cmd = REMOVE_CMD % (name)
       Logger.info("Removing package %s ('%s')" % (name, cmd))
-      shell.checked_call(cmd)
+      shell.checked_call(cmd, sudo=True)
     else:
       Logger.info("Skipping removing non-existent package %s" % (name))
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/68c55728/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 4364cef..293a454 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,7 @@ class ZypperProvider(PackageProvider):
     if not self._check_existence(name):
       cmd = INSTALL_CMD % (name)
       Logger.info("Installing package %s ('%s')" % (name, cmd))
-      shell.checked_call(cmd)
+      shell.checked_call(cmd, sudo=True)
     else:
       Logger.info("Skipping installing existent package %s" % (name))
 
@@ -44,7 +44,7 @@ class ZypperProvider(PackageProvider):
     if self._check_existence(name):
       cmd = REMOVE_CMD % (name)
       Logger.info("Removing package %s ('%s')" % (name, cmd))
-      shell.checked_call(cmd)
+      shell.checked_call(cmd, sudo=True)
     else:
       Logger.info("Skipping removing non-existent package %s" % (name))
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/68c55728/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 0844775..6ec5bb5 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
@@ -28,6 +28,7 @@ import pwd
 import time
 import shutil
 from resource_management.core import shell
+from resource_management.core import sudo
 from resource_management.core.base import Fail
 from resource_management.core import ExecuteTimeoutException
 from resource_management.core.providers import Provider
@@ -58,27 +59,29 @@ def _coerce_gid(group):
 
 def _ensure_metadata(path, user, group, mode=None):
   stat = os.stat(path)
-
+  
   if mode:
     existing_mode = stat.st_mode & 07777
     if existing_mode != mode:
       Logger.info("Changing permission for %s from %o to %o" % (
       path, existing_mode, mode))
-      os.chmod(path, mode)
-
+      sudo.chmod(path, mode)
+  
   if user:
     uid = _coerce_uid(user)
     if stat.st_uid != uid:
       Logger.info(
         "Changing owner for %s from %d to %s" % (path, stat.st_uid, user))
-      os.chown(path, uid, -1)
+      
+      sudo.chown(path, user, None)
+      
 
   if group:
     gid = _coerce_gid(group)
     if stat.st_gid != gid:
       Logger.info(
         "Changing group for %s from %d to %s" % (path, stat.st_gid, group))
-      os.chown(path, -1, gid)
+      sudo.chown(path, None, group)
 
 
 class FileProvider(Provider):
@@ -99,9 +102,8 @@ class FileProvider(Provider):
       reason = "it doesn't exist"
     elif self.resource.replace:
       if content is not None:
-        with open(path, "rb") as fp:
-          old_content = fp.read()
-          old_content = old_content.decode(self.resource.encoding) if self.resource.encoding else old_content
+        old_content = sudo.read_file(path)
+        old_content = old_content.decode(self.resource.encoding) if self.resource.encoding else old_content
         if content != old_content:
           write = True
           reason = "contents don't match"
@@ -110,10 +112,11 @@ class FileProvider(Provider):
 
     if write:
       Logger.info("Writing %s because %s" % (self.resource, reason))
-      with open(path, "wb") as fp:
-        if content:
-          content = content.encode(self.resource.encoding) if self.resource.encoding else content
-          fp.write(content)
+
+      if content:
+        content = content.encode(self.resource.encoding) if self.resource.encoding else content
+        
+      sudo.create_file(path, content)
 
     _ensure_metadata(self.resource.path, self.resource.owner,
                         self.resource.group, mode=self.resource.mode)
@@ -126,7 +129,7 @@ class FileProvider(Provider):
     
     if os.path.exists(path):
       Logger.info("Deleting %s" % self.resource)
-      os.unlink(path)
+      sudo.unlink(path)
 
   def _get_content(self):
     content = self.resource.content
@@ -142,20 +145,21 @@ class FileProvider(Provider):
 class DirectoryProvider(Provider):
   def action_create(self):
     path = self.resource.path
+
     if not os.path.exists(path):
       Logger.info("Creating directory %s" % self.resource)
       if self.resource.recursive:
-        os.makedirs(path, self.resource.mode or 0755)
+        sudo.makedirs(path, self.resource.mode or 0755)
       else:
         dirname = os.path.dirname(path)
         if not os.path.isdir(dirname):
           raise Fail("Applying %s failed, parent directory %s doesn't exist" % (self.resource, dirname))
         
-        os.mkdir(path, self.resource.mode or 0755)
+        sudo.makedir(path, self.resource.mode or 0755)
       
     if not os.path.isdir(path):
       raise Fail("Applying %s failed, file %s already exists" % (self.resource, path))
-
+    
     _ensure_metadata(path, self.resource.owner, self.resource.group,
                         mode=self.resource.mode)
 
@@ -181,7 +185,7 @@ class LinkProvider(Provider):
         raise Fail(
           "%s trying to create a symlink with the same name as an existing file or directory" % self)
       Logger.info("%s replacing old symlink to %s" % (self.resource, oldpath))
-      os.unlink(path)
+      sudo.unlink(path)
       
     if self.resource.hard:
       if not os.path.exists(self.resource.to):
@@ -190,19 +194,19 @@ class LinkProvider(Provider):
         raise Fail("Failed to apply %s, cannot create hard link to a directory (%s)" % (self.resource, self.resource.to))
       
       Logger.info("Creating hard %s" % self.resource)
-      os.link(self.resource.to, path)
+      sudo.link(self.resource.to, path)
     else:
       if not os.path.exists(self.resource.to):
         Logger.info("Warning: linking to nonexistent location %s" % self.resource.to)
         
       Logger.info("Creating symbolic %s" % self.resource)
-      os.symlink(self.resource.to, path)
+      sudo.symlink(self.resource.to, path)
 
   def action_delete(self):
     path = self.resource.path
     if os.path.exists(path):
       Logger.info("Deleting %s" % self.resource)
-      os.unlink(path)
+      sudo.unlink(path)
 
 
 def _preexec_fn(resource):
@@ -223,18 +227,26 @@ class ExecuteProvider(Provider):
 
     Logger.debug("Executing %s" % self.resource)
 
+    env = self.resource.environment
+    
+    # append current PATH, to self.resource.environment['PATH'] and self.resource.path
+    if 'PATH' in env:
+      env['PATH'] = os.pathsep.join([os.environ['PATH'], env['PATH']])
+    if self.resource.path:
+      if not 'PATH' in env:
+        env['PATH'] = ''
+      path = os.pathsep.join(self.resource.path) if isinstance(self.resource.path, (list, tuple)) else self.resource.path
+      env['PATH'] = os.pathsep.join([os.environ['PATH'], path])
+          
     for i in range (0, self.resource.tries):
       try:
-        env=self.resource.environment
-        if env and 'PATH' in env.keys():
-          env['PATH'] = "$PATH" + os.pathsep + env['PATH']
-
         shell.checked_call(self.resource.command, logoutput=self.resource.logoutput,
                             cwd=self.resource.cwd, env=env,
                             preexec_fn=_preexec_fn(self.resource), user=self.resource.user,
                             wait_for_finish=self.resource.wait_for_finish,
                             timeout=self.resource.timeout,
-                            path=self.resource.path)
+                            path=self.resource.path,
+                            sudo=self.resource.sudo)
         break
       except Fail as ex:
         if i == self.resource.tries-1: # last try

http://git-wip-us.apache.org/repos/asf/ambari/blob/68c55728/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 4fe8440..49e3a7b 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
@@ -76,7 +76,7 @@ class Execute(Resource):
   creates = ResourceArgument()
   cwd = ResourceArgument()
   # this runs command with a specific env variables, env={'JAVA_HOME': '/usr/jdk'}
-  environment = ResourceArgument()
+  environment = ResourceArgument(default={})
   user = ResourceArgument()
   group = ResourceArgument()
   returns = ForcedListArgument(default=0)
@@ -102,6 +102,7 @@ class Execute(Resource):
   - try_sleep
   """
   wait_for_finish = BooleanArgument(default=True)
+  sudo = BooleanArgument(default=False)
 
 
 class ExecuteScript(Resource):

http://git-wip-us.apache.org/repos/asf/ambari/blob/68c55728/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 3f5b8bc..2a472f2 100644
--- a/ambari-common/src/main/python/resource_management/core/shell.py
+++ b/ambari-common/src/main/python/resource_management/core/shell.py
@@ -32,15 +32,15 @@ from exceptions import ExecuteTimeoutException
 from resource_management.core.logger import Logger
 
 def checked_call(command, logoutput=False, 
-         cwd=None, env=None, preexec_fn=None, user=None, wait_for_finish=True, timeout=None, path=None):
-  return _call(command, logoutput, True, cwd, env, preexec_fn, user, wait_for_finish, timeout, path)
+         cwd=None, env=None, preexec_fn=None, user=None, wait_for_finish=True, timeout=None, path=None, sudo=False):
+  return _call(command, logoutput, True, cwd, env, preexec_fn, user, wait_for_finish, timeout, path, sudo)
 
 def call(command, logoutput=False, 
-         cwd=None, env=None, preexec_fn=None, user=None, wait_for_finish=True, timeout=None, path=None):
-  return _call(command, logoutput, False, cwd, env, preexec_fn, user, wait_for_finish, timeout, path)
+         cwd=None, env=None, preexec_fn=None, user=None, wait_for_finish=True, timeout=None, path=None, sudo=False):
+  return _call(command, logoutput, False, cwd, env, preexec_fn, user, wait_for_finish, timeout, path, sudo)
             
 def _call(command, logoutput=False, throw_on_failure=True, 
-         cwd=None, env=None, preexec_fn=None, user=None, wait_for_finish=True, timeout=None, path=None):
+         cwd=None, env=None, preexec_fn=None, user=None, wait_for_finish=True, timeout=None, path=None, sudo=False):
   """
   Execute shell command
   
@@ -55,22 +55,21 @@ def _call(command, logoutput=False, throw_on_failure=True,
   if isinstance(command, (list, tuple)):
     command = ' '.join(quote_bash_args(x) for x in command)
 
-  if path:
-    export_path_command = "export PATH=$PATH" + os.pathsep + os.pathsep.join(path) + " ; "
-  else:
-    export_path_command = ""
-
+  # In case we will use sudo, we have to put all the environment inside the command, 
+  # since Popen environment gets reset within sudo.
+  export_command = reduce(lambda str,x: '{0} {1}={2}'.format(str,x,quote_bash_args(env[x])), env, 'export') + '; ' if env else ''
+      
   if user:
-    if env:
-      export_path_command += "export "
-      for var in env:
-        export_path_command += " " + var + "=" + env[var]
-      export_path_command += " ; "
-
-    subprocess_command = ["su", "-s", "/bin/bash", "-", user, "-c", export_path_command + command]
+    bash_run_command = "/usr/bin/sudo -Hsu {0} <<< {1}".format(quote_bash_args(user), quote_bash_args(export_command + command))
+    # Go to home directory. In case we are in folder, which user cannot open, we might run into troubles with some utils
+    cwd = os.path.expanduser('~'+user) if not cwd and os.path.exists(os.path.expanduser('~'+user)) else cwd
+  elif sudo:
+    bash_run_command = "/usr/bin/sudo -s <<< {0}".format(quote_bash_args(export_command + command))
   else:
-    subprocess_command = ["/bin/bash","--login","-c", export_path_command + command]
-
+    bash_run_command = command
+    
+  subprocess_command = ["/bin/bash","--login","-c", bash_run_command]
+    
   proc = subprocess.Popen(subprocess_command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
                           cwd=cwd, env=env, shell=False,
                           preexec_fn=preexec_fn)

http://git-wip-us.apache.org/repos/asf/ambari/blob/68c55728/ambari-common/src/main/python/resource_management/core/sudo.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/resource_management/core/sudo.py b/ambari-common/src/main/python/resource_management/core/sudo.py
new file mode 100644
index 0000000..b36aba7
--- /dev/null
+++ b/ambari-common/src/main/python/resource_management/core/sudo.py
@@ -0,0 +1,62 @@
+import os
+import tempfile
+from resource_management.core import shell
+
+# os.chown replacement
+def chown(path, owner, group):
+  if owner:
+    shell.checked_call(["chown", owner, path], sudo=True)
+  if group:
+    shell.checked_call(["chgrp", owner, path], sudo=True)
+    
+# os.chmod replacement
+def chmod(path, mode):
+  shell.checked_call(["chmod", oct(mode), path], sudo=True)
+  
+# os.makedirs replacement
+def makedirs(path, mode):
+  shell.checked_call(["mkdir", "-p", path], sudo=True)
+  chmod(path, mode)
+  
+# os.makedir replacement
+def makedir(path, mode):
+  shell.checked_call(["mkdir", path], sudo=True)
+  chmod(path, mode)
+  
+# os.symlink replacement
+def symlink(source, link_name):
+  shell.checked_call(["ln","-sf", source, link_name], sudo=True)
+  
+# os.link replacement
+def link(source, link_name):
+  shell.checked_call(["ln", "-f", source, link_name], sudo=True)
+  
+# os unlink
+def unlink(path):
+  shell.checked_call(["rm","-f", path], sudo=True)
+  
+# fp.write replacement
+def create_file(filename, content):
+  """
+  if content is None, create empty file
+  """
+  tmpf = tempfile.NamedTemporaryFile()
+  
+  if content:
+    with open(tmpf.name, "wb") as fp:
+      fp.write(content)
+  
+  with tmpf:    
+    shell.checked_call(["cp", "-f", tmpf.name, filename], sudo=True)
+    
+  # set default files mode
+  chmod(filename, 0644)
+    
+# fp.read replacement
+def read_file(filename):
+  tmpf = tempfile.NamedTemporaryFile()
+  shell.checked_call(["cp", "-f", filename, tmpf.name], sudo=True)
+  
+  with tmpf:
+    with open(tmpf.name, "rb") as fp:
+      return fp.read()

http://git-wip-us.apache.org/repos/asf/ambari/blob/68c55728/ambari-common/src/main/python/resource_management/libraries/providers/hdfs_directory.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/resource_management/libraries/providers/hdfs_directory.py b/ambari-common/src/main/python/resource_management/libraries/providers/hdfs_directory.py
index d14968e..e09308d 100644
--- a/ambari-common/src/main/python/resource_management/libraries/providers/hdfs_directory.py
+++ b/ambari-common/src/main/python/resource_management/libraries/providers/hdfs_directory.py
@@ -104,8 +104,8 @@ class HdfsDirectoryProvider(Provider):
                    chown_cmd=' && '.join(chown_commands)),
             user=hdp_hdfs_user,
             path=bin_dir,
-            not_if=format("su - {hdp_hdfs_user} -c 'export PATH=$PATH:{bin_dir} ; "
-                          "hadoop --config {hdp_conf_dir} fs -ls {dir_list_str}'")
+            not_if=format("sudo -Hsu {hdp_hdfs_user} <<< "
+                          "'export PATH=$PATH:{bin_dir} ; hadoop --config {hdp_conf_dir} fs -ls {dir_list_str}'")
     )
 
     directories_list[:] = []

http://git-wip-us.apache.org/repos/asf/ambari/blob/68c55728/ambari-server/src/main/java/org/apache/ambari/server/bootstrap/SshHostInfo.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/bootstrap/SshHostInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/bootstrap/SshHostInfo.java
index 50ac257..822e972 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/bootstrap/SshHostInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/bootstrap/SshHostInfo.java
@@ -95,9 +95,6 @@ public class SshHostInfo {
   }
   
   public String getUserRunAs() {
-    // TODO: remove this once UI supports customizing ambari run-as-user
-    if(userRunAs == null)
-      return "root";
     return userRunAs;
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/68c55728/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HIVE/package/scripts/hive_service.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HIVE/package/scripts/hive_service.py b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HIVE/package/scripts/hive_service.py
index 42a1d69..ae64c35 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HIVE/package/scripts/hive_service.py
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HIVE/package/scripts/hive_service.py
@@ -21,7 +21,7 @@ limitations under the License.
 from resource_management import *
 import sys
 import time
-from resource_management.core.shell import call
+from resource_management.core import shell
 
 def hive_service(
     name,
@@ -98,7 +98,7 @@ def check_fs_root():
   import params  
   fs_root_url = format("{fs_root}{hive_apps_whs_dir}")
   cmd = format("metatool -listFSRoot 2>/dev/null | grep hdfs:// | grep -v '.db$'")
-  code, out = call(cmd, user=params.hive_user)
+  code, out = shell.call(cmd, user=params.hive_user)
   if code == 0 and fs_root_url.strip() != out.strip():
     cmd = format("metatool -updateLocation {fs_root}{hive_apps_whs_dir} {out}")
     Execute(cmd,

http://git-wip-us.apache.org/repos/asf/ambari/blob/68c55728/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_hive_server.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_hive_server.py b/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_hive_server.py
index 94382f6..2e37162 100644
--- a/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_hive_server.py
+++ b/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_hive_server.py
@@ -20,6 +20,7 @@ limitations under the License.
 import os
 import subprocess
 from mock.mock import MagicMock, call, patch
+from resource_management.core import shell
 from stacks.utils.RMFTestCase import *
 
 import socket
@@ -35,6 +36,7 @@ class TestHiveServer(RMFTestCase):
     self.assert_configure_default()
     self.assertNoMoreResources()
 
+  @patch.object(shell, "call", new=MagicMock(return_value=(0, '')))
   @patch.object(subprocess,"Popen")
   @patch("socket.socket")
   def test_start_default(self, socket_mock, popen_mock):
@@ -47,7 +49,10 @@ class TestHiveServer(RMFTestCase):
     )
 
     self.assert_configure_default()
-
+    self.assertResourceCalled('Execute', 'metatool -updateLocation hdfs://c6401.ambari.apache.org:8020/apps/hive/warehouse ',
+        environment = {'PATH' : os.environ['PATH'] + os.pathsep + "/usr/lib/hive/bin" + os.pathsep + "/usr/bin"},
+        user = 'hive',
+    )
     self.assertResourceCalled('Execute', 'env JAVA_HOME=/usr/jdk64/jdk1.7.0_45 /tmp/start_hiveserver2_script /var/log/hive/hive-server2.out /var/log/hive/hive-server2.log /var/run/hive/hive-server.pid /etc/hive/conf.server /var/log/hive',
                               not_if = 'ls /var/run/hive/hive-server.pid >/dev/null 2>&1 && ps -p `cat /var/run/hive/hive-server.pid` >/dev/null 2>&1',
                               environment = {'HADOOP_HOME' : '/usr'},
@@ -60,11 +65,6 @@ class TestHiveServer(RMFTestCase):
     )
 
     self.assertNoMoreResources()
-    self.assertTrue(popen_mock.called)
-    popen_mock.assert_called_with(
-      ['su', '-s', '/bin/bash', '-', u'hive', '-c', "metatool -listFSRoot 2>/dev/null | grep hdfs:// | grep -v '.db$'"],
-      shell=False, preexec_fn=None, stderr=-2, stdout=-1, env=None, cwd=None
-    )
     self.assertTrue(socket_mock.called)
     self.assertTrue(s.close.called)