瀏覽代碼

AMBARI-9772. Ranger doesn't support non-root install (aonishuk)

Andrew Onishuk 10 年之前
父節點
當前提交
a5c7e2e7ff

+ 11 - 15
ambari-agent/src/test/python/resource_management/TestContentSources.py

@@ -25,6 +25,7 @@ from resource_management.core.source import StaticFile
 from resource_management.core.source import DownloadSource
 from resource_management.core.source import Template
 from resource_management.core.source import InlineTemplate
+from resource_management.core import sudo
 
 from ambari_jinja2 import UndefinedError, TemplateNotFound
 import urllib2
@@ -34,46 +35,41 @@ import os
 @patch.object(System, "os_family", new = 'redhat')
 class TestContentSources(TestCase):
 
-  @patch("__builtin__.open")
+  @patch.object(os.path, "isfile")
   @patch.object(os.path, "join")
-  def test_static_file_absolute_path(self, join_mock, open_mock):
+  def test_static_file_absolute_path(self, join_mock, is_file_mock):
     """
     Testing StaticFile source with absolute path
     """
-    file_mock = MagicMock(name = 'file_mock')
-    file_mock.__enter__.return_value = file_mock
-    file_mock.read.return_value = 'content'
-    open_mock.return_value = file_mock
+    sudo.read_file = lambda path: 'content'
+    is_file_mock.return_value = True
 
     with Environment("/base") as env:
       static_file = StaticFile("/absolute/path/file")
       content = static_file.get_content()
 
     self.assertEqual('content', content)
-    self.assertEqual(file_mock.read.call_count, 1)
+    self.assertEqual(is_file_mock.call_count, 1)
     self.assertEqual(join_mock.call_count, 0)
 
 
-  @patch("__builtin__.open")
+  @patch.object(os.path, "isfile")
   @patch.object(os.path, "join")
-  def test_static_file_relative_path(self, join_mock, open_mock):
+  def test_static_file_relative_path(self, join_mock, is_file_mock):
     """
     Testing StaticFile source with relative path
     """
-    file_mock = MagicMock(name = 'file_mock')
-    file_mock.__enter__.return_value = file_mock
-    file_mock.read.return_value = 'content'
-    open_mock.return_value = file_mock
+    sudo.read_file = lambda path: 'content'
+    is_file_mock.return_value = True
 
     with Environment("/base") as env:
       static_file = StaticFile("relative/path/file")
       content = static_file.get_content()
 
     self.assertEqual('content', content)
-    self.assertEqual(file_mock.read.call_count, 1)
+    self.assertEqual(is_file_mock.call_count, 1)
     self.assertEqual(join_mock.call_count, 1)
     join_mock.assert_called_with('/base', 'files', 'relative/path/file')
-    self.assertEqual(open_mock.call_count, 1)
 
   @patch.object(urllib2, "build_opener")
   @patch.object(urllib2, "Request")

+ 6 - 2
ambari-common/src/main/python/resource_management/core/source.py

@@ -25,6 +25,7 @@ from resource_management.core.environment import Environment
 from resource_management.core.logger import Logger
 from resource_management.core.exceptions import Fail
 from resource_management.core.utils import checked_unite
+from resource_management.core import sudo
 
 __all__ = ["Source", "Template", "InlineTemplate", "StaticFile", "DownloadSource"]
 
@@ -69,8 +70,11 @@ class StaticFile(Source):
       basedir = self.env.config.basedir
       path = os.path.join(basedir, "files", self.name)
       
-    with open(path, "rb") as fp:
-      return fp.read()
+    if not os.path.isfile(path) and not os.path.islink(path):
+      raise Fail("{0} Source file {1} is not found".format(repr(self), path))
+    
+    return sudo.read_file(path)
+    
 
 
 try:

+ 7 - 6
ambari-server/src/main/resources/common-services/RANGER/0.4.0/package/scripts/ranger_admin.py

@@ -24,6 +24,7 @@ from resource_management.libraries.functions.format import format
 from resource_management.core.logger import Logger
 from resource_management.core import shell
 from setup_ranger import setup_ranger
+from ranger_service import ranger_service
 import upgrade
 
 class RangerAdmin(Script):
@@ -33,7 +34,7 @@ class RangerAdmin(Script):
 
   def install(self, env):
     self.install_packages(env)
-    setup_ranger()
+    self.configure(env)
 
   def stop(self, env, rolling_restart=False):
     import params
@@ -48,11 +49,10 @@ class RangerAdmin(Script):
 
   def start(self, env, rolling_restart=False):
     import params
-    
     env.set_params(params)
-    setup_ranger()
-    no_op_test = format('ps -ef | grep proc_rangeradmin | grep -v grep')
-    Execute(format('{params.ranger_start}'), user=params.unix_user, not_if=no_op_test)
+    self.configure(env)
+    ranger_service('ranger_admin')
+
 
   def status(self, env):
     cmd = 'ps -ef | grep proc_rangeradmin | grep -v grep'
@@ -65,8 +65,9 @@ class RangerAdmin(Script):
 
   def configure(self, env):
     import params
-
     env.set_params(params)
+    
+    setup_ranger()
 
 
 if __name__ == "__main__":

+ 33 - 0
ambari-server/src/main/resources/common-services/RANGER/0.4.0/package/scripts/ranger_service.py

@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+"""
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+"""
+from resource_management import *
+
+def ranger_service(name):
+  import params
+  
+  if name == 'ranger_admin':
+    no_op_test = format('ps -ef | grep proc_rangeradmin | grep -v grep')
+    Execute(format('{params.ranger_start}'), user=params.unix_user, not_if=no_op_test)
+  elif name == 'ranger_usersync':
+    no_op_test = format('ps -ef | grep proc_rangerusersync | grep -v grep')
+    Execute(params.usersync_start, 
+            not_if=no_op_test,
+            user=params.unix_user,
+    )

+ 6 - 6
ambari-server/src/main/resources/common-services/RANGER/0.4.0/package/scripts/ranger_usersync.py

@@ -24,6 +24,7 @@ from resource_management.libraries.functions.format import format
 from resource_management.core.logger import Logger
 from resource_management.core import shell
 from setup_ranger import setup_usersync
+from ranger_service import ranger_service
 import upgrade
 
 class RangerUsersync(Script):
@@ -33,7 +34,7 @@ class RangerUsersync(Script):
 
   def install(self, env):
     self.install_packages(env)
-    setup_usersync()
+    self.configure(env)
 
   def stop(self, env, rolling_restart=False):
     import params
@@ -48,11 +49,10 @@ class RangerUsersync(Script):
 
   def start(self, env, rolling_restart=False):
     import params
-
     env.set_params(params)
-    setup_usersync()
-    no_op_test = format('ps -ef | grep proc_rangerusersync | grep -v grep')
-    Execute(format('{params.usersync_start}'), not_if=no_op_test)
+    self.configure(env)
+    ranger_service('ranger_usersync')
+
 
   def status(self, env):
     cmd = 'ps -ef | grep proc_rangerusersync | grep -v grep'
@@ -65,8 +65,8 @@ class RangerUsersync(Script):
 
   def configure(self, env):
     import params
-
     env.set_params(params)
+    setup_usersync()
 
 
 if __name__ == "__main__":

+ 50 - 24
ambari-server/src/main/resources/common-services/RANGER/0.4.0/package/scripts/setup_ranger.py

@@ -19,7 +19,6 @@ limitations under the License.
 """
 import sys
 import fileinput
-import shutil
 import os
 from resource_management import *
 from resource_management.core.logger import Logger
@@ -37,12 +36,12 @@ def setup_ranger():
               path=["/bin", "/usr/bin/"],
               sudo=True)                        
 
-    file_path = params.ranger_home + '/install.properties'
-
-    if os.path.isfile(file_path):
-      shutil.copyfile(file_path, params.ranger_home + '/install-bk.properties')
-    else:
-      raise Fail('Ranger admin {0} file does not exist'.format(file_path))
+    file_path = format("{ranger_home}/install.properties")
+    bk_file_path = format("{ranger_home}/install-bk.properties")
+    
+    File(bk_file_path,
+         content = StaticFile(file_path),
+    )
 
     write_properties_to_file(file_path, admin_properties())
     ##if db flavor == oracle - set oracle home env variable
@@ -50,21 +49,32 @@ def setup_ranger():
       env_dict = {'JAVA_HOME': params.java_home, 'ORACLE_HOME':params.oracle_home, 'LD_LIBRARY_PATH':params.oracle_home} 
     else: 
       env_dict = {'JAVA_HOME': params.java_home}
-    cmd = format('cd {params.ranger_home} && {params.ranger_home}/setup.sh')
+    setup_sh = format("cd {ranger_home} && ") + as_sudo([format('{ranger_home}/setup.sh')])
     
     try:
-      Execute(cmd, environment=env_dict, logoutput=True)
-    except Exception, e:
-      if os.path.isfile(params.ranger_home + '/install-bk.properties'):
-        os.remove(file_path)
-        os.rename(params.ranger_home + '/install-bk.properties', file_path)
+      Execute(setup_sh, 
+              environment=env_dict, 
+              logoutput=True,
+      )
+    except Fail, e:
+      if os.path.isfile(bk_file_path):
+        File(file_path,
+          action = "delete",
+        )
+        Execute(('mv', bk_file_path, file_path),
+          sudo = True,
+        )
       raise Fail('Ranger installation Failed, {0}'.format(str(e)))
 
     do_post_installation()
 
-    if os.path.isfile(params.ranger_home + '/install-bk.properties'):
-      os.remove(file_path)
-      os.rename(params.ranger_home + '/install-bk.properties', file_path)
+    if os.path.isfile(bk_file_path):
+      File(file_path,
+        action = "delete",
+      )
+      Execute(('mv', bk_file_path, file_path),
+        sudo = True,
+      )
     else:
       raise Fail('Ranger admin install.properties backup file doesnot exist')
 
@@ -73,7 +83,7 @@ def do_post_installation():
 
   Logger.info('Performing Ranger post installation')
 
-  file_path = params.ranger_conf + '/ranger_webserver.properties'
+  file_path = format("{ranger_conf}/ranger_webserver.properties")
   ranger_site = dict()
   ranger_site['http.service.port'] = params.http_service_port
   ranger_site['https.service.port'] = params.https_service_port
@@ -85,7 +95,7 @@ def do_post_installation():
 
   ranger_site.clear()
 
-  file_path = params.ranger_conf + '/xa_system.properties'
+  file_path = format("{ranger_conf}/xa_system.properties")
   ranger_site['http.enabled'] = params.http_enabled
   write_properties_to_file(file_path, ranger_site)
   Logger.info('Performing Ranger post installation DONE')
@@ -94,11 +104,17 @@ def do_post_installation():
 def setup_usersync():
   import params
 
-  file_path = params.usersync_home + '/install.properties'
+  file_path = format("{usersync_home}/install.properties")
   write_properties_to_file(file_path, usersync_properties())
 
-  cmd = format('cd {params.usersync_home} && {params.usersync_home}/setup.sh')
+  cmd = format("cd {usersync_home} && ") + as_sudo([format('{usersync_home}/setup.sh')])
   Execute(cmd, environment={'JAVA_HOME': params.java_home}, logoutput=True)
+  Execute(('chown', params.unix_user, params.usersync_start),
+    sudo = True,
+  )
+  Execute(('chown', params.unix_user, params.usersync_stop),
+    sudo = True,
+  )
 
 def write_properties_to_file(file_path, value):
   for key in value:
@@ -112,8 +128,14 @@ def modify_config(filepath, variable, setting):
 
   if ' ' in S:
     S = '%s' % S
+    
+  tmp_filepath = format("{tmp_dir}/temporary_ranger_config.properties")
+  # we need to copy so non-root user is able to read it.
+  File(tmp_filepath,
+    content = StaticFile(filepath),
+  )
 
-  for line in fileinput.input(filepath, inplace=1):
+  for line in fileinput.input(tmp_filepath, inplace=1):
     if not line.lstrip(' ').startswith('#') and '=' in line:
       _infile_var = str(line.split('=')[0].rstrip(' '))
       _infile_set = str(line.split('=')[1].lstrip(' ').rstrip())
@@ -122,13 +144,17 @@ def modify_config(filepath, variable, setting):
         if _infile_set.lstrip(' ') == S:
           already_set = True
         else:
-          line = "%s=%s\n" % (V, S)
+          line = format("{V}={S}\n")
 
     sys.stdout.write(line)
+    
+  # copy it back
+  File(filepath,
+    content = StaticFile(tmp_filepath),
+  )
 
   if not var_found:
-    with open(filepath, "a") as f:
-      f.write("%s=%s\n" % (V, S))
+    Execute(format("echo '{V}={S}\\n' | ") + as_sudo(['tee', '-a', filepath]))
   elif already_set == True:
     pass
   else:

+ 2 - 0
ambari-server/src/test/python/stacks/utils/RMFTestCase.py

@@ -238,6 +238,8 @@ def Template(name, **kwargs):
 def StaticFile(name, **kwargs):
   with RMFTestCase.env:
     from resource_management.core.source import StaticFile
+    from resource_management.core import sudo
+    sudo.read_file = lambda path: 'dummy_output'
     return StaticFile(name, **kwargs)
   
 def InlineTemplate(name, **kwargs):