Author: smohanty
Date: Fri Jun 21 22:23:18 2013
New Revision: 1495625
URL: http://svn.apache.org/r1495625
Log:
AMBARI-2423. Improvements to running Ambari Server as non-root. (Dmitry
Lysnichenko via smohanty)
Modified:
incubator/ambari/trunk/ambari-server/src/main/python/ambari-server.py
incubator/ambari/trunk/ambari-server/src/test/python/TestAmbaryServer.py
Modified: incubator/ambari/trunk/ambari-server/src/main/python/ambari-server.py
URL:
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/python/ambari-server.py?rev=1495625&r1=1495624&r2=1495625&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/python/ambari-server.py
(original)
+++ incubator/ambari/trunk/ambari-server/src/main/python/ambari-server.py Fri
Jun 21 22:23:18 2013
@@ -78,7 +78,7 @@ ambari_provider_module_option = ""
ambari_provider_module = os.environ.get('AMBARI_PROVIDER_MODULE')
# Non-root user setup commands
-NR_USER_PROPERTY = "ambari.user"
+NR_USER_PROPERTY = "ambari-server.user"
NR_USER_COMMENT = "Ambari user"
NR_GET_OWNER_CMD = 'stat -c "%U" {0}'
NR_USERADD_CMD = 'useradd -M -g {0} --comment "{1}" ' \
@@ -634,8 +634,6 @@ def create_custom_user():
"finished with {2}: \n{3}".format(user, command,
retcode, err))
return retcode, None
-
-
print_info_msg("User/group configuration is done.")
return 0, user
@@ -643,18 +641,27 @@ def create_custom_user():
def check_ambari_user():
try:
user = read_ambari_user()
+ create_user = False
+ update_user_setting = False
if user is not None:
- print_info_msg("Detected custom user {0}".format(user))
- else: # user is not configured yet or server is running under root
- ok = get_YN_input("Create a separate user for ambari-server "
+ create_user = get_YN_input("Ambari-server process is configured run
under user {0}."
+ " Change this setting [y/n] (n)? ".format(user), False)
+ update_user_setting = create_user # Only if we will create another user
+ else: # user is not configured yet
+ update_user_setting = True # Write configuration anyway
+ create_user = get_YN_input("Create a separate user for ambari-server "
"daemon [y/n] (n)? ", False)
- if ok:
- (retcode, user) = create_custom_user()
- if retcode != 0:
- return retcode
- else:
+ if not create_user:
user = "root"
+
+ if create_user:
+ (retcode, user) = create_custom_user()
+ if retcode != 0:
+ return retcode
+
+ if update_user_setting:
write_property(NR_USER_PROPERTY, user)
+
adjust_directory_permissions(user)
except OSError:
print_error_msg("Failed: %s" % OSError.message)
@@ -666,8 +673,6 @@ def check_ambari_user():
-
-
#
# Checks iptables
#
@@ -1922,6 +1927,17 @@ def reset(args):
# Starts the Ambari Server.
#
def start(args):
+ current_user = getpass.getuser()
+ ambari_user = read_ambari_user()
+ if ambari_user is None:
+ err = "Can not detect a system user for Ambari. " \
+ "Please run \"setup\" command to create such user "
+ raise FatalException(1, err)
+ if current_user != ambari_user and not is_root():
+ err = "Can not start ambari-server as user {0}. Please either run
\"start\" " \
+ "command as root or as user {1}".format(current_user, ambari_user)
+ raise FatalException(1, err)
+
parse_properties_file(args)
if os.path.exists(PID_DIR + os.sep + PID_NAME):
f = open(PID_DIR + os.sep + PID_NAME, "r")
@@ -1934,17 +1950,6 @@ def start(args):
except OSError as e:
print_info_msg("Server is not running...")
- current_user = getpass.getuser()
- ambari_user = read_ambari_user()
- if ambari_user is None:
- err = "Can not detect a system user for Ambari. " \
- "Please run \"setup\" command to create such user "
- raise FatalException(1, err)
- if current_user != ambari_user and not is_root():
- err = "Can not start ambari-server as user {0}. Please either run
\"start\" " \
- "command as root or as user {1}".format(current_user, ambari_user)
- raise FatalException(1, err)
-
conf_dir = get_conf_dir()
jdk_path = find_jdk()
if jdk_path is None:
Modified:
incubator/ambari/trunk/ambari-server/src/test/python/TestAmbaryServer.py
URL:
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/test/python/TestAmbaryServer.py?rev=1495625&r1=1495624&r2=1495625&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/test/python/TestAmbaryServer.py
(original)
+++ incubator/ambari/trunk/ambari-server/src/test/python/TestAmbaryServer.py
Fri Jun 21 22:23:18 2013
@@ -743,17 +743,56 @@ class TestAmbariServer(TestCase):
adjust_directory_permissions_mock, write_property_mock,
create_custom_user_mock, get_YN_input_mock, read_ambari_user_mock):
- # Scenario: user is already defined
+ # Scenario: user is already defined, user does not want to reconfigure it
read_ambari_user_mock.return_value = "dummy-user"
+ get_YN_input_mock.return_value = False
result = ambari_server.check_ambari_user()
- self.assertFalse(get_YN_input_mock.called)
+ self.assertTrue(get_YN_input_mock.called)
self.assertFalse(write_property_mock.called)
+ self.assertFalse(create_custom_user_mock.called)
self.assertTrue(adjust_directory_permissions_mock.called)
self.assertEqual(result, 0)
get_YN_input_mock.reset_mock()
write_property_mock.reset_mock()
adjust_directory_permissions_mock.reset_mock()
+ create_custom_user_mock.reset_mock()
+
+ # Scenario: user is already defined, but user wants to reconfigure it
+
+ read_ambari_user_mock.return_value = "dummy-user"
+ create_custom_user_mock.return_value = (0, "new-dummy-user")
+ get_YN_input_mock.return_value = True
+ result = ambari_server.check_ambari_user()
+ self.assertTrue(get_YN_input_mock.called)
+ self.assertTrue(write_property_mock.called)
+ self.assertTrue(write_property_mock.call_args[0][1] == "new-dummy-user")
+ self.assertTrue(create_custom_user_mock.called)
+ self.assertTrue(adjust_directory_permissions_mock.called)
+ self.assertEqual(result, 0)
+
+ get_YN_input_mock.reset_mock()
+ write_property_mock.reset_mock()
+ adjust_directory_permissions_mock.reset_mock()
+ create_custom_user_mock.reset_mock()
+
+ # Negative scenario: user is already defined, but user wants
+ # to reconfigure it, user creation failed
+
+ read_ambari_user_mock.return_value = "dummy-user"
+ create_custom_user_mock.return_value = (1, None)
+ get_YN_input_mock.return_value = True
+ result = ambari_server.check_ambari_user()
+ self.assertTrue(get_YN_input_mock.called)
+ self.assertTrue(create_custom_user_mock.called)
+ self.assertFalse(write_property_mock.called)
+ self.assertFalse(adjust_directory_permissions_mock.called)
+ self.assertEqual(result, 1)
+
+ get_YN_input_mock.reset_mock()
+ create_custom_user_mock.reset_mock()
+ write_property_mock.reset_mock()
+ adjust_directory_permissions_mock.reset_mock()
# Scenario: user is not defined (setup process)
read_ambari_user_mock.return_value = None
@@ -789,6 +828,23 @@ class TestAmbariServer(TestCase):
write_property_mock.reset_mock()
adjust_directory_permissions_mock.reset_mock()
+ # negative scenario: user is not defined (setup process), user creation
failed
+
+ read_ambari_user_mock.return_value = None
+ get_YN_input_mock.return_value = True
+ create_custom_user_mock.return_value = (1, None)
+ result = ambari_server.check_ambari_user()
+ self.assertTrue(get_YN_input_mock.called)
+ self.assertTrue(create_custom_user_mock.called)
+ self.assertFalse(write_property_mock.called)
+ self.assertFalse(adjust_directory_permissions_mock.called)
+ self.assertEqual(result, 1)
+
+ get_YN_input_mock.reset_mock()
+ create_custom_user_mock.reset_mock()
+ write_property_mock.reset_mock()
+ adjust_directory_permissions_mock.reset_mock()
+
# Scenario: user is not defined and left to be root
read_ambari_user_mock.return_value = None
get_YN_input_mock.return_value = False
@@ -1549,6 +1605,9 @@ class TestAmbariServer(TestCase):
pass
self.assertTrue(killMock.called)
+ killMock.reset_mock()
+ parse_properties_file_mock.reset_mock()
+
pexistsMock.return_value = False
# Checking situation when ambari user is not set up
@@ -1560,6 +1619,8 @@ class TestAmbariServer(TestCase):
# Expected
self.assertTrue('Can not detect a system user' in e.reason)
+ parse_properties_file_mock.reset_mock()
+
# Checking start from non-root when current user is not the same as a
# custom user
read_ambari_user_mock.return_value = "dummy-user"
@@ -1571,6 +1632,9 @@ class TestAmbariServer(TestCase):
except FatalException as e:
# Expected
self.assertTrue('Can not start ambari-server as user' in e.reason)
+ self.assertFalse(parse_properties_file_mock.called)
+
+ parse_properties_file_mock.reset_mock()
# Checking "jdk not found"
is_root_mock.return_value = True
@@ -1584,6 +1648,7 @@ class TestAmbariServer(TestCase):
find_jdk_mock.return_value = "somewhere"
+ parse_properties_file_mock.reset_mock()
## Testing workflow under root
is_root_mock.return_value = True
@@ -1601,6 +1666,7 @@ class TestAmbariServer(TestCase):
self.assertFalse(check_postgre_up_mock.called)
check_postgre_up_mock.reset_mock()
+ parse_properties_file_mock.reset_mock()
# Local DB
args.persistence_type="local"
@@ -1615,6 +1681,8 @@ class TestAmbariServer(TestCase):
self.assertTrue('Unable to start PostgreSQL server' in e.reason)
self.assertTrue(check_postgre_up_mock.called)
+ parse_properties_file_mock.reset_mock()
+
# case: iptables failed to stop
check_postgre_up_mock.return_value = 0
check_iptables_mock.return_value = (1, ambari_server.IP_TBLS_ENABLED)
@@ -1625,6 +1693,8 @@ class TestAmbariServer(TestCase):
# Expected
self.assertTrue('Failed to stop iptables' in e.reason)
+ parse_properties_file_mock.reset_mock()
+
check_iptables_mock.return_value = (0, None)
# Case: custom user is "root"
read_ambari_user_mock.return_value = "root"
@@ -1633,6 +1703,9 @@ class TestAmbariServer(TestCase):
popen_arg = popenMock.call_args[0][0]
self.assertTrue(popen_arg[0] == "/bin/sh")
popenMock.reset_mock()
+
+ parse_properties_file_mock.reset_mock()
+
# Case: custom user is not "root"
read_ambari_user_mock.return_value = "not-root-user"
ambari_server.start(args)
@@ -1643,11 +1716,15 @@ class TestAmbariServer(TestCase):
check_postgre_up_mock.reset_mock()
popenMock.reset_mock()
+ parse_properties_file_mock.reset_mock()
## Testing workflow under non-root
is_root_mock.return_value = False
read_ambari_user_mock.return_value = "not-root-user"
getuser_mock.return_value = read_ambari_user_mock.return_value
+
+ parse_properties_file_mock.reset_mock()
+
# Local DB
args.persistence_type="local"
@@ -1655,6 +1732,8 @@ class TestAmbariServer(TestCase):
self.assertFalse(check_postgre_up_mock.called)
+ parse_properties_file_mock.reset_mock()
+
# Remote DB
args.persistence_type="remote"
@@ -1662,6 +1741,8 @@ class TestAmbariServer(TestCase):
self.assertFalse(check_postgre_up_mock.called)
+ parse_properties_file_mock.reset_mock()
+
# Checking call
check_iptables_mock.reset_mock()
check_iptables_mock.return_value = (0, None)
@@ -1671,6 +1752,8 @@ class TestAmbariServer(TestCase):
self.assertTrue(popen_arg[0] == "/bin/sh")
self.assertFalse(check_iptables_mock.called)
+ parse_properties_file_mock.reset_mock()
+
# Test start under wrong user
read_ambari_user_mock.return_value = "not-root-user"
getuser_mock.return_value = "non_custom_user"
@@ -1681,6 +1764,8 @@ class TestAmbariServer(TestCase):
# Expected
self.assertTrue('Can not start ambari-server as user' in e.reason)
+ parse_properties_file_mock.reset_mock()
+
# Check environ master key is set
popenMock.reset_mock()
get_ambari_properties_mock.return_value = \
@@ -1698,6 +1783,8 @@ class TestAmbariServer(TestCase):
popen_arg = popenMock.call_args[1]['env']
self.assertEquals(os_environ_mock.copy.return_value, popen_arg)
+ parse_properties_file_mock.reset_mock()
+
# Check environ master key is not set
popenMock.reset_mock()
os_environ_mock.reset_mock()
@@ -2100,7 +2187,7 @@ class TestAmbariServer(TestCase):
"server.jdbc.user.passwd=/etc/ambari-server/conf/password.dat\n",
"java.home=/usr/jdk64/jdk1.6.0_31\n",
"server.os_type=redhat6\n",
- "ambari.user=ambari\n"]
+ "ambari-server.user=ambari\n"]
NEW_PROPERTY = 'some_new_property=some_value\n'
CHANGED_VALUE_PROPERTY = 'server.os_type=should_not_overwrite_value\n'