ambari-server.py 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612
  1. #!/usr/bin/env python
  2. '''
  3. Licensed to the Apache Software Foundation (ASF) under one
  4. or more contributor license agreements. See the NOTICE file
  5. distributed with this work for additional information
  6. regarding copyright ownership. The ASF licenses this file
  7. to you under the Apache License, Version 2.0 (the
  8. "License"); you may not use this file except in compliance
  9. with the License. You may obtain a copy of the License at
  10. http://www.apache.org/licenses/LICENSE-2.0
  11. Unless required by applicable law or agreed to in writing, software
  12. distributed under the License is distributed on an "AS IS" BASIS,
  13. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. See the License for the specific language governing permissions and
  15. limitations under the License.
  16. '''
  17. import optparse
  18. import sys
  19. import os
  20. import signal
  21. from ambari_commons.exceptions import FatalException, NonFatalException
  22. from ambari_commons.logging_utils import set_verbose, set_silent, \
  23. print_info_msg, print_warning_msg, print_error_msg, set_debug_mode_from_options
  24. from ambari_commons.os_check import OSConst
  25. from ambari_commons.os_family_impl import OsFamilyFuncImpl, OsFamilyImpl
  26. from ambari_commons.os_utils import remove_file
  27. from ambari_server.BackupRestore import main as BackupRestore_main
  28. from ambari_server.dbConfiguration import DATABASE_NAMES
  29. from ambari_server.serverConfiguration import configDefaults, get_ambari_properties, PID_NAME
  30. from ambari_server.serverUtils import is_server_runing, refresh_stack_hash
  31. from ambari_server.serverSetup import reset, setup, setup_jce_policy
  32. from ambari_server.serverUpgrade import upgrade, upgrade_stack, set_current
  33. from ambari_server.setupHttps import setup_https
  34. from ambari_server.setupActions import BACKUP_ACTION, LDAP_SETUP_ACTION, LDAP_SYNC_ACTION, PSTART_ACTION, \
  35. REFRESH_STACK_HASH_ACTION, RESET_ACTION, RESTORE_ACTION, SETUP_ACTION, SETUP_SECURITY_ACTION, START_ACTION, \
  36. STATUS_ACTION, STOP_ACTION, UPGRADE_ACTION, UPGRADE_STACK_ACTION, SETUP_JCE_ACTION, SET_CURRENT
  37. from ambari_server.setupSecurity import setup_ldap, sync_ldap, setup_master_key, setup_ambari_krb5_jaas
  38. from ambari_server.userInput import get_validated_string_input
  39. from ambari_server_main import server_process_main
  40. class UserActionPossibleArgs(object):
  41. def __init__(self, i_fn, i_possible_args_numbers, *args, **kwargs):
  42. self.fn = i_fn
  43. self.possible_args_numbers = i_possible_args_numbers
  44. self.args = args
  45. self.kwargs = kwargs
  46. self.need_restart = False
  47. def execute(self):
  48. self.fn(*self.args, **self.kwargs)
  49. class UserAction(UserActionPossibleArgs):
  50. def __init__(self, i_fn, *args, **kwargs):
  51. super(UserAction, self).__init__(i_fn, [1], *args, **kwargs)
  52. class UserActionRestart(UserAction):
  53. def __init__(self, i_fn, *args, **kwargs):
  54. super(UserActionRestart, self).__init__(i_fn, *args, **kwargs)
  55. def execute(self):
  56. self.need_restart = self.fn(*self.args, **self.kwargs)
  57. def winsetup(options):
  58. from ambari_windows_service import svcsetup
  59. setup(options)
  60. svcsetup()
  61. #
  62. # Starts the Ambari Server as a standalone process.
  63. # Ensures only one instance of the process is running.
  64. # If this is the second instance of the process, the function fails.
  65. #
  66. @OsFamilyFuncImpl(OSConst.WINSRV_FAMILY)
  67. def start(options):
  68. from ambari_windows_service import AmbariServerService, ctrlHandler
  69. status, pid = is_server_runing()
  70. if status:
  71. err = "Ambari Server is already running."
  72. raise FatalException(1, err)
  73. AmbariServerService.set_ctrl_c_handler(ctrlHandler)
  74. #Run as a normal process. Invoke the ServiceMain directly.
  75. childProc = server_process_main(options)
  76. childProc.wait()
  77. pid_file_path = os.path.join(configDefaults.PID_DIR, PID_NAME)
  78. remove_file(pid_file_path)
  79. #
  80. # Starts the Ambari Server.
  81. # Ensures only one instance of the process is running.
  82. # If this is the second instance of the process, the function fails.
  83. #
  84. @OsFamilyFuncImpl(OsFamilyImpl.DEFAULT)
  85. def start(args):
  86. status, pid = is_server_runing()
  87. if status:
  88. err = "Ambari Server is already running."
  89. raise FatalException(1, err)
  90. server_process_main(args)
  91. #
  92. # Starts the Ambari Server as a service.
  93. # Start the server as a Windows service. If the Ambari server is
  94. # not registered as a service, the function fails. By default, only one instance of the service can
  95. # possibly run.
  96. #
  97. def svcstart():
  98. from ambari_windows_service import AmbariServerService
  99. AmbariServerService.Start()
  100. pass
  101. #
  102. # Stops the Ambari Server service.
  103. #
  104. @OsFamilyFuncImpl(OSConst.WINSRV_FAMILY)
  105. def stop():
  106. from ambari_windows_service import AmbariServerService
  107. AmbariServerService.Stop()
  108. #
  109. # Stops the Ambari Server.
  110. #
  111. @OsFamilyFuncImpl(OsFamilyImpl.DEFAULT)
  112. def stop(args):
  113. if (args != None):
  114. args.exit_message = None
  115. status, pid = is_server_runing()
  116. if status:
  117. try:
  118. os.killpg(os.getpgid(pid), signal.SIGKILL)
  119. except OSError, e:
  120. print_info_msg("Unable to stop Ambari Server - " + str(e))
  121. return
  122. pid_file_path = os.path.join(configDefaults.PID_DIR, PID_NAME)
  123. os.remove(pid_file_path)
  124. print "Ambari Server stopped"
  125. else:
  126. print "Ambari Server is not running"
  127. #
  128. # The Ambari Server status.
  129. #
  130. @OsFamilyFuncImpl(OSConst.WINSRV_FAMILY)
  131. def status(args):
  132. from ambari_windows_service import AmbariServerService
  133. args.exit_message = None
  134. statusStr = AmbariServerService.QueryStatus()
  135. print "Ambari Server is " + statusStr
  136. #
  137. # The Ambari Server status.
  138. #
  139. @OsFamilyFuncImpl(OsFamilyImpl.DEFAULT)
  140. def status(args):
  141. args.exit_message = None
  142. status, pid = is_server_runing()
  143. pid_file_path = os.path.join(configDefaults.PID_DIR, PID_NAME)
  144. if status:
  145. print "Ambari Server running"
  146. print "Found Ambari Server PID: " + str(pid) + " at: " + pid_file_path
  147. else:
  148. print "Ambari Server not running. Stale PID File at: " + pid_file_path
  149. def refresh_stack_hash_action():
  150. properties = get_ambari_properties()
  151. refresh_stack_hash(properties)
  152. @OsFamilyFuncImpl(OSConst.WINSRV_FAMILY)
  153. def create_setup_security_actions(args):
  154. action_list = [
  155. ['Enable HTTPS for Ambari server.', UserActionRestart(setup_https, args)],
  156. ['Encrypt passwords stored in ambari.properties file.', UserAction(setup_master_key)],
  157. ['Setup Ambari kerberos JAAS configuration.', UserAction(setup_ambari_krb5_jaas)],
  158. ]
  159. return action_list
  160. @OsFamilyFuncImpl(OsFamilyImpl.DEFAULT)
  161. def create_setup_security_actions(args):
  162. action_list = [
  163. ['Enable HTTPS for Ambari server.', UserActionRestart(setup_https, args)],
  164. ['Encrypt passwords stored in ambari.properties file.', UserAction(setup_master_key)],
  165. ['Setup Ambari kerberos JAAS configuration.', UserAction(setup_ambari_krb5_jaas)],
  166. ]
  167. return action_list
  168. def setup_security(args):
  169. actions = create_setup_security_actions(args)
  170. #Print menu options
  171. print '=' * 75
  172. print 'Choose one of the following options: '
  173. iAction = 0
  174. for actionDesc in actions:
  175. iAction += 1
  176. print ' [{0}] {1}'.format(iAction, actionDesc[0])
  177. print '=' * 75
  178. choice_prompt = 'Enter choice, (1-{0}): '.format(iAction)
  179. choice_re = '[1-{0}]'.format(iAction)
  180. choice = get_validated_string_input(choice_prompt, '0', choice_re,
  181. 'Invalid choice', False, False)
  182. try:
  183. actionDesc = actions[int(choice) - 1]
  184. except IndexError:
  185. raise FatalException('Unknown option for setup-security command.')
  186. action = actionDesc[1]
  187. action.execute()
  188. return action.need_restart
  189. #
  190. # Backup / Restore
  191. #
  192. def get_backup_path(args):
  193. if len(args) == 2:
  194. path = args[1]
  195. else:
  196. path = None
  197. return path
  198. def backup(args):
  199. print "Backup requested."
  200. backup_command = ["BackupRestore", 'backup']
  201. path = get_backup_path(args)
  202. if not path is None:
  203. backup_command.append(path)
  204. BackupRestore_main(backup_command)
  205. def restore(args):
  206. print "Restore requested."
  207. restore_command = ["BackupRestore", 'restore']
  208. path = get_backup_path(args)
  209. if not path is None:
  210. restore_command.append(path)
  211. BackupRestore_main(restore_command)
  212. @OsFamilyFuncImpl(OSConst.WINSRV_FAMILY)
  213. def init_parser_options(parser):
  214. parser.add_option('-f', '--init-script-file', dest="init_db_script_file",
  215. default="resources" + os.sep + "Ambari-DDL-SQLServer-CREATE.sql",
  216. help="File with database setup script")
  217. parser.add_option('-r', '--drop-script-file', dest="cleanup_db_script_file",
  218. default="resources" + os.sep + "Ambari-DDL-SQLServer-DROP.sql",
  219. help="File with database cleanup script")
  220. parser.add_option('-j', '--java-home', dest="java_home", default=None,
  221. help="Use specified java_home. Must be valid on all hosts")
  222. parser.add_option("-v", "--verbose",
  223. action="store_true", dest="verbose", default=False,
  224. help="Print verbose status messages")
  225. parser.add_option("-s", "--silent",
  226. action="store_true", dest="silent", default=False,
  227. help="Silently accepts default prompt values")
  228. parser.add_option('-g', '--debug', action="store_true", dest='debug', default=False,
  229. help="Start ambari-server in debug mode")
  230. parser.add_option('-y', '--suspend-start', action="store_true", dest='suspend_start', default=False,
  231. help="Freeze ambari-server Java process at startup in debug mode")
  232. parser.add_option('-a', '--databasehost', dest="database_host", default=None,
  233. help="Hostname of database server")
  234. parser.add_option('-n', '--databaseport', dest="database_port", default=None,
  235. help="Database server listening port")
  236. parser.add_option('-d', '--databasename', dest="database_name", default=None,
  237. help="Database/Schema/Service name or ServiceID")
  238. parser.add_option('-w', '--windowsauth', action="store_true", dest="database_windows_auth", default=None,
  239. help="Integrated Windows authentication")
  240. parser.add_option('-u', '--databaseusername', dest="database_username", default=None,
  241. help="Database user login")
  242. parser.add_option('-p', '--databasepassword', dest="database_password", default=None,
  243. help="Database user password")
  244. parser.add_option('--jdbc-driver', default=None, dest="jdbc_driver",
  245. help="Specifies the path to the JDBC driver JAR file")
  246. # -b, -i, -k and -x the remaining available short options
  247. # -h reserved for help
  248. @OsFamilyFuncImpl(OsFamilyImpl.DEFAULT)
  249. def init_parser_options(parser):
  250. parser.add_option('-f', '--init-script-file',
  251. default='/var/lib/ambari-server/'
  252. 'resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql',
  253. help="File with setup script")
  254. parser.add_option('-r', '--drop-script-file', default="/var/lib/"
  255. "ambari-server/resources/"
  256. "Ambari-DDL-Postgres-EMBEDDED-DROP.sql",
  257. help="File with drop script")
  258. parser.add_option('-u', '--upgrade-script-file', default="/var/lib/"
  259. "ambari-server/resources/upgrade/ddl/"
  260. "Ambari-DDL-Postgres-UPGRADE-1.3.0.sql",
  261. help="File with upgrade script")
  262. parser.add_option('-t', '--upgrade-stack-script-file', default="/var/lib/"
  263. "ambari-server/resources/upgrade/dml/"
  264. "Ambari-DML-Postgres-UPGRADE_STACK.sql",
  265. help="File with stack upgrade script")
  266. parser.add_option('-j', '--java-home', default=None,
  267. help="Use specified java_home. Must be valid on all hosts")
  268. parser.add_option("-v", "--verbose",
  269. action="store_true", dest="verbose", default=False,
  270. help="Print verbose status messages")
  271. parser.add_option("-s", "--silent",
  272. action="store_true", dest="silent", default=False,
  273. help="Silently accepts default prompt values")
  274. parser.add_option('-g', '--debug', action="store_true", dest='debug', default=False,
  275. help="Start ambari-server in debug mode")
  276. parser.add_option('-y', '--suspend-start', action="store_true", dest='suspend_start', default=False,
  277. help="Freeze ambari-server Java process at startup in debug mode")
  278. parser.add_option('--all', action="store_true", default=False, help="LDAP sync all option. Synchronize all LDAP users and groups.",
  279. dest="ldap_sync_all")
  280. parser.add_option('--existing', action="store_true", default=False,
  281. help="LDAP sync existing option. Synchronize existing Ambari users and groups only.", dest="ldap_sync_existing")
  282. parser.add_option('--users', default=None, help="LDAP sync users option. Specifies the path to a CSV file of user names to be synchronized.",
  283. dest="ldap_sync_users")
  284. parser.add_option('--groups', default=None, help="LDAP sync groups option. Specifies the path to a CSV file of group names to be synchronized.",
  285. dest="ldap_sync_groups")
  286. parser.add_option('--database', default=None, help="Database to use embedded|oracle|mysql|postgres", dest="dbms")
  287. parser.add_option('--databasehost', default=None, help="Hostname of database server", dest="database_host")
  288. parser.add_option('--databaseport', default=None, help="Database port", dest="database_port")
  289. parser.add_option('--databasename', default=None, help="Database/Service name or ServiceID",
  290. dest="database_name")
  291. parser.add_option('--postgresschema', default=None, help="Postgres database schema name",
  292. dest="postgres_schema")
  293. parser.add_option('--databaseusername', default=None, help="Database user login", dest="database_username")
  294. parser.add_option('--databasepassword', default=None, help="Database user password", dest="database_password")
  295. parser.add_option('--sidorsname', default="sname", help="Oracle database identifier type, Service ID/Service "
  296. "Name sid|sname", dest="sid_or_sname")
  297. parser.add_option('--jdbc-driver', default=None, help="Specifies the path to the JDBC driver JAR file for the " \
  298. "database type specified with the --jdbc-db option. Used only with --jdbc-db option.",
  299. dest="jdbc_driver")
  300. parser.add_option('--jdbc-db', default=None, help="Specifies the database type [postgres|mysql|oracle] for the " \
  301. "JDBC driver specified with the --jdbc-driver option. Used only with --jdbc-driver option.",
  302. dest="jdbc_db")
  303. parser.add_option('--cluster-name', default=None, help="Cluster name", dest="cluster_name")
  304. parser.add_option('--version-display-name', default=None, help="Display name of desired repo version", dest="desired_repo_version")
  305. @OsFamilyFuncImpl(OSConst.WINSRV_FAMILY)
  306. def are_cmd_line_db_args_blank(options):
  307. if (options.database_host is None \
  308. and options.database_name is None \
  309. and options.database_windows_auth is None \
  310. and options.database_username is None \
  311. and options.database_password is None):
  312. return True
  313. return False
  314. @OsFamilyFuncImpl(OsFamilyImpl.DEFAULT)
  315. def are_cmd_line_db_args_blank(options):
  316. if options.dbms is None \
  317. and options.database_host is None \
  318. and options.database_port is None \
  319. and options.database_name is None \
  320. and options.database_username is None \
  321. and options.database_password is None:
  322. return True
  323. return False
  324. def are_db_auth_options_ok(db_windows_auth, db_username, db_password):
  325. if db_windows_auth is True:
  326. return True
  327. else:
  328. if db_username is not None and db_username is not "" and db_password is not None and db_password is not "":
  329. return True
  330. return False
  331. @OsFamilyFuncImpl(OSConst.WINSRV_FAMILY)
  332. def are_cmd_line_db_args_valid(options):
  333. if (options.database_host is not None and options.database_host is not "" \
  334. #and options.database_name is not None \ # ambari by default is ok
  335. and are_db_auth_options_ok(options.database_windows_auth,
  336. options.database_username,
  337. options.database_password)):
  338. return True
  339. return False
  340. @OsFamilyFuncImpl(OsFamilyImpl.DEFAULT)
  341. def are_cmd_line_db_args_valid(options):
  342. if options.dbms is not None \
  343. and options.database_host is not None \
  344. and options.database_port is not None \
  345. and options.database_name is not None \
  346. and options.database_username is not None \
  347. and options.database_password is not None:
  348. return True
  349. return False
  350. @OsFamilyFuncImpl(OSConst.WINSRV_FAMILY)
  351. def init_debug(options):
  352. if options.debug:
  353. sys.frozen = 'windows_exe' # Fake py2exe so we can debug
  354. @OsFamilyFuncImpl(OsFamilyImpl.DEFAULT)
  355. def init_debug(options):
  356. pass
  357. @OsFamilyFuncImpl(OSConst.WINSRV_FAMILY)
  358. def fix_database_options(options, parser):
  359. pass
  360. @OsFamilyFuncImpl(OsFamilyImpl.DEFAULT)
  361. def fix_database_options(options, parser):
  362. if options.dbms == 'embedded':
  363. print "WARNING: HostName for postgres server " + options.database_host + \
  364. " will be ignored: using localhost."
  365. options.database_host = "localhost"
  366. options.dbms = 'postgres'
  367. options.persistence_type = 'local'
  368. options.database_index = 0
  369. elif options.dbms is not None and options.dbms not in DATABASE_NAMES:
  370. parser.print_help()
  371. parser.error("Unsupported Database " + options.dbms)
  372. elif options.dbms is not None:
  373. options.dbms = options.dbms.lower()
  374. # correct port
  375. if options.database_port is not None:
  376. correct = False
  377. try:
  378. port = int(options.database_port)
  379. if 65536 > port > 0:
  380. correct = True
  381. except ValueError:
  382. pass
  383. if not correct:
  384. parser.print_help()
  385. parser.error("Incorrect database port " + options.database_port)
  386. # jdbc driver and db options validation
  387. if options.jdbc_driver is None and options.jdbc_db is not None:
  388. parser.error("Option --jdbc-db is used only in pair with --jdbc-driver")
  389. elif options.jdbc_driver is not None and options.jdbc_db is None:
  390. parser.error("Option --jdbc-driver is used only in pair with --jdbc-db")
  391. if options.sid_or_sname.lower() not in ["sid", "sname"]:
  392. print "WARNING: Valid values for sid_or_sname are 'sid' or 'sname'. Use 'sid' if the db identifier type is " \
  393. "Service ID. Use 'sname' if the db identifier type is Service Name"
  394. parser.print_help()
  395. exit(-1)
  396. else:
  397. options.sid_or_sname = options.sid_or_sname.lower()
  398. @OsFamilyFuncImpl(OSConst.WINSRV_FAMILY)
  399. def create_user_action_map(args, options):
  400. action_map = {
  401. SETUP_ACTION: UserAction(winsetup, options),
  402. START_ACTION: UserAction(svcstart),
  403. PSTART_ACTION: UserAction(start, options),
  404. STOP_ACTION: UserAction(stop),
  405. RESET_ACTION: UserAction(reset, options),
  406. STATUS_ACTION: UserAction(status, options),
  407. UPGRADE_ACTION: UserAction(upgrade, options),
  408. LDAP_SETUP_ACTION: UserAction(setup_ldap),
  409. SETUP_SECURITY_ACTION: UserActionRestart(setup_security, options),
  410. REFRESH_STACK_HASH_ACTION: UserAction(refresh_stack_hash_action),
  411. }
  412. return action_map
  413. @OsFamilyFuncImpl(OsFamilyImpl.DEFAULT)
  414. def create_user_action_map(args, options):
  415. action_map = {
  416. SETUP_ACTION: UserAction(setup, options),
  417. SETUP_JCE_ACTION : UserActionPossibleArgs(setup_jce_policy, [2], args),
  418. START_ACTION: UserAction(start, options),
  419. STOP_ACTION: UserAction(stop, options),
  420. RESET_ACTION: UserAction(reset, options),
  421. STATUS_ACTION: UserAction(status, options),
  422. UPGRADE_ACTION: UserAction(upgrade, options),
  423. UPGRADE_STACK_ACTION: UserActionPossibleArgs(upgrade_stack, [2, 4], args),
  424. LDAP_SETUP_ACTION: UserAction(setup_ldap),
  425. LDAP_SYNC_ACTION: UserAction(sync_ldap, options),
  426. SET_CURRENT: UserAction(set_current, options),
  427. SETUP_SECURITY_ACTION: UserActionRestart(setup_security, options),
  428. REFRESH_STACK_HASH_ACTION: UserAction(refresh_stack_hash_action),
  429. BACKUP_ACTION: UserActionPossibleArgs(backup, [1, 2], args),
  430. RESTORE_ACTION: UserActionPossibleArgs(restore, [1, 2], args)
  431. }
  432. return action_map
  433. #
  434. # Main.
  435. #
  436. def main(options, args, parser):
  437. # set silent
  438. set_silent(options.silent)
  439. # debug mode
  440. set_debug_mode_from_options(options)
  441. init_debug(options)
  442. #perform checks
  443. options.warnings = []
  444. if are_cmd_line_db_args_blank(options):
  445. options.must_set_database_options = True
  446. elif not are_cmd_line_db_args_valid(options):
  447. parser.error('All database options should be set. Please see help for the options.')
  448. else:
  449. options.must_set_database_options = False
  450. #correct database
  451. fix_database_options(options, parser)
  452. if len(args) == 0:
  453. print parser.print_help()
  454. parser.error("No action entered")
  455. action_map = create_user_action_map(args, options)
  456. action = args[0]
  457. try:
  458. action_obj = action_map[action]
  459. except KeyError:
  460. parser.error("Invalid action: " + action)
  461. matches = 0
  462. for args_number_required in action_obj.possible_args_numbers:
  463. matches += int(len(args) == args_number_required)
  464. if matches == 0:
  465. print parser.print_help()
  466. possible_args = ' or '.join(str(x) for x in action_obj.possible_args_numbers)
  467. parser.error("Invalid number of arguments. Entered: " + str(len(args)) + ", required: " + possible_args)
  468. options.exit_message = "Ambari Server '%s' completed successfully." % action
  469. try:
  470. action_obj.execute()
  471. if action_obj.need_restart:
  472. pstatus, pid = is_server_runing()
  473. if pstatus:
  474. print 'NOTE: Restart Ambari Server to apply changes' + \
  475. ' ("ambari-server restart|stop+start")'
  476. if options.warnings:
  477. for warning in options.warnings:
  478. print_warning_msg(warning)
  479. pass
  480. options.exit_message = "Ambari Server '%s' completed with warnings." % action
  481. pass
  482. except FatalException as e:
  483. if e.reason is not None:
  484. print_error_msg("Exiting with exit code {0}. \nREASON: {1}".format(e.code, e.reason))
  485. sys.exit(e.code)
  486. except NonFatalException as e:
  487. options.exit_message = "Ambari Server '%s' completed with warnings." % action
  488. if e.reason is not None:
  489. print_warning_msg(e.reason)
  490. if options.exit_message is not None:
  491. print options.exit_message
  492. def mainBody():
  493. parser = optparse.OptionParser(usage="usage: %prog [options] action [stack_id os]",)
  494. init_parser_options(parser)
  495. (options, args) = parser.parse_args()
  496. # set verbose
  497. set_verbose(options.verbose)
  498. if options.verbose:
  499. main(options, args, parser)
  500. else:
  501. try:
  502. main(options, args, parser)
  503. except Exception as e:
  504. print_error_msg("Unexpected {0}: {1}".format((e).__class__.__name__, str(e)) +\
  505. "\nFor more info run ambari-server with -v or --verbose option")
  506. sys.exit(1)
  507. if __name__ == "__main__":
  508. try:
  509. mainBody()
  510. except (KeyboardInterrupt, EOFError):
  511. print("\nAborting ... Keyboard Interrupt.")
  512. sys.exit(1)