123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612 |
- #!/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.
- '''
- import optparse
- import sys
- import os
- import signal
- from ambari_commons.exceptions import FatalException, NonFatalException
- from ambari_commons.logging_utils import set_verbose, set_silent, \
- print_info_msg, print_warning_msg, print_error_msg, set_debug_mode_from_options
- from ambari_commons.os_check import OSConst
- from ambari_commons.os_family_impl import OsFamilyFuncImpl, OsFamilyImpl
- from ambari_commons.os_utils import remove_file
- from ambari_server.BackupRestore import main as BackupRestore_main
- from ambari_server.dbConfiguration import DATABASE_NAMES
- from ambari_server.serverConfiguration import configDefaults, get_ambari_properties, PID_NAME
- from ambari_server.serverUtils import is_server_runing, refresh_stack_hash
- from ambari_server.serverSetup import reset, setup, setup_jce_policy
- from ambari_server.serverUpgrade import upgrade, upgrade_stack, set_current
- from ambari_server.setupHttps import setup_https
- from ambari_server.setupActions import BACKUP_ACTION, LDAP_SETUP_ACTION, LDAP_SYNC_ACTION, PSTART_ACTION, \
- REFRESH_STACK_HASH_ACTION, RESET_ACTION, RESTORE_ACTION, SETUP_ACTION, SETUP_SECURITY_ACTION, START_ACTION, \
- STATUS_ACTION, STOP_ACTION, UPGRADE_ACTION, UPGRADE_STACK_ACTION, SETUP_JCE_ACTION, SET_CURRENT
- from ambari_server.setupSecurity import setup_ldap, sync_ldap, setup_master_key, setup_ambari_krb5_jaas
- from ambari_server.userInput import get_validated_string_input
- from ambari_server_main import server_process_main
- class UserActionPossibleArgs(object):
- def __init__(self, i_fn, i_possible_args_numbers, *args, **kwargs):
- self.fn = i_fn
- self.possible_args_numbers = i_possible_args_numbers
- self.args = args
- self.kwargs = kwargs
- self.need_restart = False
- def execute(self):
- self.fn(*self.args, **self.kwargs)
- class UserAction(UserActionPossibleArgs):
- def __init__(self, i_fn, *args, **kwargs):
- super(UserAction, self).__init__(i_fn, [1], *args, **kwargs)
- class UserActionRestart(UserAction):
- def __init__(self, i_fn, *args, **kwargs):
- super(UserActionRestart, self).__init__(i_fn, *args, **kwargs)
- def execute(self):
- self.need_restart = self.fn(*self.args, **self.kwargs)
- def winsetup(options):
- from ambari_windows_service import svcsetup
- setup(options)
- svcsetup()
- #
- # Starts the Ambari Server as a standalone process.
- # Ensures only one instance of the process is running.
- # If this is the second instance of the process, the function fails.
- #
- @OsFamilyFuncImpl(OSConst.WINSRV_FAMILY)
- def start(options):
- from ambari_windows_service import AmbariServerService, ctrlHandler
- status, pid = is_server_runing()
- if status:
- err = "Ambari Server is already running."
- raise FatalException(1, err)
- AmbariServerService.set_ctrl_c_handler(ctrlHandler)
- #Run as a normal process. Invoke the ServiceMain directly.
- childProc = server_process_main(options)
- childProc.wait()
- pid_file_path = os.path.join(configDefaults.PID_DIR, PID_NAME)
- remove_file(pid_file_path)
- #
- # Starts the Ambari Server.
- # Ensures only one instance of the process is running.
- # If this is the second instance of the process, the function fails.
- #
- @OsFamilyFuncImpl(OsFamilyImpl.DEFAULT)
- def start(args):
- status, pid = is_server_runing()
- if status:
- err = "Ambari Server is already running."
- raise FatalException(1, err)
- server_process_main(args)
- #
- # Starts the Ambari Server as a service.
- # Start the server as a Windows service. If the Ambari server is
- # not registered as a service, the function fails. By default, only one instance of the service can
- # possibly run.
- #
- def svcstart():
- from ambari_windows_service import AmbariServerService
- AmbariServerService.Start()
- pass
- #
- # Stops the Ambari Server service.
- #
- @OsFamilyFuncImpl(OSConst.WINSRV_FAMILY)
- def stop():
- from ambari_windows_service import AmbariServerService
- AmbariServerService.Stop()
- #
- # Stops the Ambari Server.
- #
- @OsFamilyFuncImpl(OsFamilyImpl.DEFAULT)
- def stop(args):
- if (args != None):
- args.exit_message = None
- status, pid = is_server_runing()
- if status:
- try:
- os.killpg(os.getpgid(pid), signal.SIGKILL)
- except OSError, e:
- print_info_msg("Unable to stop Ambari Server - " + str(e))
- return
- pid_file_path = os.path.join(configDefaults.PID_DIR, PID_NAME)
- os.remove(pid_file_path)
- print "Ambari Server stopped"
- else:
- print "Ambari Server is not running"
- #
- # The Ambari Server status.
- #
- @OsFamilyFuncImpl(OSConst.WINSRV_FAMILY)
- def status(args):
- from ambari_windows_service import AmbariServerService
- args.exit_message = None
- statusStr = AmbariServerService.QueryStatus()
- print "Ambari Server is " + statusStr
- #
- # The Ambari Server status.
- #
- @OsFamilyFuncImpl(OsFamilyImpl.DEFAULT)
- def status(args):
- args.exit_message = None
- status, pid = is_server_runing()
- pid_file_path = os.path.join(configDefaults.PID_DIR, PID_NAME)
- if status:
- print "Ambari Server running"
- print "Found Ambari Server PID: " + str(pid) + " at: " + pid_file_path
- else:
- print "Ambari Server not running. Stale PID File at: " + pid_file_path
- def refresh_stack_hash_action():
- properties = get_ambari_properties()
- refresh_stack_hash(properties)
- @OsFamilyFuncImpl(OSConst.WINSRV_FAMILY)
- def create_setup_security_actions(args):
- action_list = [
- ['Enable HTTPS for Ambari server.', UserActionRestart(setup_https, args)],
- ['Encrypt passwords stored in ambari.properties file.', UserAction(setup_master_key)],
- ['Setup Ambari kerberos JAAS configuration.', UserAction(setup_ambari_krb5_jaas)],
- ]
- return action_list
- @OsFamilyFuncImpl(OsFamilyImpl.DEFAULT)
- def create_setup_security_actions(args):
- action_list = [
- ['Enable HTTPS for Ambari server.', UserActionRestart(setup_https, args)],
- ['Encrypt passwords stored in ambari.properties file.', UserAction(setup_master_key)],
- ['Setup Ambari kerberos JAAS configuration.', UserAction(setup_ambari_krb5_jaas)],
- ]
- return action_list
- def setup_security(args):
- actions = create_setup_security_actions(args)
- #Print menu options
- print '=' * 75
- print 'Choose one of the following options: '
- iAction = 0
- for actionDesc in actions:
- iAction += 1
- print ' [{0}] {1}'.format(iAction, actionDesc[0])
- print '=' * 75
- choice_prompt = 'Enter choice, (1-{0}): '.format(iAction)
- choice_re = '[1-{0}]'.format(iAction)
- choice = get_validated_string_input(choice_prompt, '0', choice_re,
- 'Invalid choice', False, False)
- try:
- actionDesc = actions[int(choice) - 1]
- except IndexError:
- raise FatalException('Unknown option for setup-security command.')
- action = actionDesc[1]
- action.execute()
- return action.need_restart
- #
- # Backup / Restore
- #
- def get_backup_path(args):
- if len(args) == 2:
- path = args[1]
- else:
- path = None
- return path
- def backup(args):
- print "Backup requested."
- backup_command = ["BackupRestore", 'backup']
- path = get_backup_path(args)
- if not path is None:
- backup_command.append(path)
- BackupRestore_main(backup_command)
- def restore(args):
- print "Restore requested."
- restore_command = ["BackupRestore", 'restore']
- path = get_backup_path(args)
- if not path is None:
- restore_command.append(path)
- BackupRestore_main(restore_command)
- @OsFamilyFuncImpl(OSConst.WINSRV_FAMILY)
- def init_parser_options(parser):
- parser.add_option('-f', '--init-script-file', dest="init_db_script_file",
- default="resources" + os.sep + "Ambari-DDL-SQLServer-CREATE.sql",
- help="File with database setup script")
- parser.add_option('-r', '--drop-script-file', dest="cleanup_db_script_file",
- default="resources" + os.sep + "Ambari-DDL-SQLServer-DROP.sql",
- help="File with database cleanup script")
- parser.add_option('-j', '--java-home', dest="java_home", default=None,
- help="Use specified java_home. Must be valid on all hosts")
- parser.add_option("-v", "--verbose",
- action="store_true", dest="verbose", default=False,
- help="Print verbose status messages")
- parser.add_option("-s", "--silent",
- action="store_true", dest="silent", default=False,
- help="Silently accepts default prompt values")
- parser.add_option('-g', '--debug', action="store_true", dest='debug', default=False,
- help="Start ambari-server in debug mode")
- parser.add_option('-y', '--suspend-start', action="store_true", dest='suspend_start', default=False,
- help="Freeze ambari-server Java process at startup in debug mode")
- parser.add_option('-a', '--databasehost', dest="database_host", default=None,
- help="Hostname of database server")
- parser.add_option('-n', '--databaseport', dest="database_port", default=None,
- help="Database server listening port")
- parser.add_option('-d', '--databasename', dest="database_name", default=None,
- help="Database/Schema/Service name or ServiceID")
- parser.add_option('-w', '--windowsauth', action="store_true", dest="database_windows_auth", default=None,
- help="Integrated Windows authentication")
- parser.add_option('-u', '--databaseusername', dest="database_username", default=None,
- help="Database user login")
- parser.add_option('-p', '--databasepassword', dest="database_password", default=None,
- help="Database user password")
- parser.add_option('--jdbc-driver', default=None, dest="jdbc_driver",
- help="Specifies the path to the JDBC driver JAR file")
- # -b, -i, -k and -x the remaining available short options
- # -h reserved for help
- @OsFamilyFuncImpl(OsFamilyImpl.DEFAULT)
- def init_parser_options(parser):
- parser.add_option('-f', '--init-script-file',
- default='/var/lib/ambari-server/'
- 'resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql',
- help="File with setup script")
- parser.add_option('-r', '--drop-script-file', default="/var/lib/"
- "ambari-server/resources/"
- "Ambari-DDL-Postgres-EMBEDDED-DROP.sql",
- help="File with drop script")
- parser.add_option('-u', '--upgrade-script-file', default="/var/lib/"
- "ambari-server/resources/upgrade/ddl/"
- "Ambari-DDL-Postgres-UPGRADE-1.3.0.sql",
- help="File with upgrade script")
- parser.add_option('-t', '--upgrade-stack-script-file', default="/var/lib/"
- "ambari-server/resources/upgrade/dml/"
- "Ambari-DML-Postgres-UPGRADE_STACK.sql",
- help="File with stack upgrade script")
- parser.add_option('-j', '--java-home', default=None,
- help="Use specified java_home. Must be valid on all hosts")
- parser.add_option("-v", "--verbose",
- action="store_true", dest="verbose", default=False,
- help="Print verbose status messages")
- parser.add_option("-s", "--silent",
- action="store_true", dest="silent", default=False,
- help="Silently accepts default prompt values")
- parser.add_option('-g', '--debug', action="store_true", dest='debug', default=False,
- help="Start ambari-server in debug mode")
- parser.add_option('-y', '--suspend-start', action="store_true", dest='suspend_start', default=False,
- help="Freeze ambari-server Java process at startup in debug mode")
- parser.add_option('--all', action="store_true", default=False, help="LDAP sync all option. Synchronize all LDAP users and groups.",
- dest="ldap_sync_all")
- parser.add_option('--existing', action="store_true", default=False,
- help="LDAP sync existing option. Synchronize existing Ambari users and groups only.", dest="ldap_sync_existing")
- parser.add_option('--users', default=None, help="LDAP sync users option. Specifies the path to a CSV file of user names to be synchronized.",
- dest="ldap_sync_users")
- parser.add_option('--groups', default=None, help="LDAP sync groups option. Specifies the path to a CSV file of group names to be synchronized.",
- dest="ldap_sync_groups")
- parser.add_option('--database', default=None, help="Database to use embedded|oracle|mysql|postgres", dest="dbms")
- parser.add_option('--databasehost', default=None, help="Hostname of database server", dest="database_host")
- parser.add_option('--databaseport', default=None, help="Database port", dest="database_port")
- parser.add_option('--databasename', default=None, help="Database/Service name or ServiceID",
- dest="database_name")
- parser.add_option('--postgresschema', default=None, help="Postgres database schema name",
- dest="postgres_schema")
- parser.add_option('--databaseusername', default=None, help="Database user login", dest="database_username")
- parser.add_option('--databasepassword', default=None, help="Database user password", dest="database_password")
- parser.add_option('--sidorsname', default="sname", help="Oracle database identifier type, Service ID/Service "
- "Name sid|sname", dest="sid_or_sname")
- parser.add_option('--jdbc-driver', default=None, help="Specifies the path to the JDBC driver JAR file for the " \
- "database type specified with the --jdbc-db option. Used only with --jdbc-db option.",
- dest="jdbc_driver")
- parser.add_option('--jdbc-db', default=None, help="Specifies the database type [postgres|mysql|oracle] for the " \
- "JDBC driver specified with the --jdbc-driver option. Used only with --jdbc-driver option.",
- dest="jdbc_db")
- parser.add_option('--cluster-name', default=None, help="Cluster name", dest="cluster_name")
- parser.add_option('--version-display-name', default=None, help="Display name of desired repo version", dest="desired_repo_version")
- @OsFamilyFuncImpl(OSConst.WINSRV_FAMILY)
- def are_cmd_line_db_args_blank(options):
- if (options.database_host is None \
- and options.database_name is None \
- and options.database_windows_auth is None \
- and options.database_username is None \
- and options.database_password is None):
- return True
- return False
- @OsFamilyFuncImpl(OsFamilyImpl.DEFAULT)
- def are_cmd_line_db_args_blank(options):
- if options.dbms is None \
- and options.database_host is None \
- and options.database_port is None \
- and options.database_name is None \
- and options.database_username is None \
- and options.database_password is None:
- return True
- return False
- def are_db_auth_options_ok(db_windows_auth, db_username, db_password):
- if db_windows_auth is True:
- return True
- else:
- if db_username is not None and db_username is not "" and db_password is not None and db_password is not "":
- return True
- return False
- @OsFamilyFuncImpl(OSConst.WINSRV_FAMILY)
- def are_cmd_line_db_args_valid(options):
- if (options.database_host is not None and options.database_host is not "" \
- #and options.database_name is not None \ # ambari by default is ok
- and are_db_auth_options_ok(options.database_windows_auth,
- options.database_username,
- options.database_password)):
- return True
- return False
- @OsFamilyFuncImpl(OsFamilyImpl.DEFAULT)
- def are_cmd_line_db_args_valid(options):
- if options.dbms is not None \
- and options.database_host is not None \
- and options.database_port is not None \
- and options.database_name is not None \
- and options.database_username is not None \
- and options.database_password is not None:
- return True
- return False
- @OsFamilyFuncImpl(OSConst.WINSRV_FAMILY)
- def init_debug(options):
- if options.debug:
- sys.frozen = 'windows_exe' # Fake py2exe so we can debug
- @OsFamilyFuncImpl(OsFamilyImpl.DEFAULT)
- def init_debug(options):
- pass
- @OsFamilyFuncImpl(OSConst.WINSRV_FAMILY)
- def fix_database_options(options, parser):
- pass
- @OsFamilyFuncImpl(OsFamilyImpl.DEFAULT)
- def fix_database_options(options, parser):
- if options.dbms == 'embedded':
- print "WARNING: HostName for postgres server " + options.database_host + \
- " will be ignored: using localhost."
- options.database_host = "localhost"
- options.dbms = 'postgres'
- options.persistence_type = 'local'
- options.database_index = 0
- elif options.dbms is not None and options.dbms not in DATABASE_NAMES:
- parser.print_help()
- parser.error("Unsupported Database " + options.dbms)
- elif options.dbms is not None:
- options.dbms = options.dbms.lower()
- # correct port
- if options.database_port is not None:
- correct = False
- try:
- port = int(options.database_port)
- if 65536 > port > 0:
- correct = True
- except ValueError:
- pass
- if not correct:
- parser.print_help()
- parser.error("Incorrect database port " + options.database_port)
- # jdbc driver and db options validation
- if options.jdbc_driver is None and options.jdbc_db is not None:
- parser.error("Option --jdbc-db is used only in pair with --jdbc-driver")
- elif options.jdbc_driver is not None and options.jdbc_db is None:
- parser.error("Option --jdbc-driver is used only in pair with --jdbc-db")
- if options.sid_or_sname.lower() not in ["sid", "sname"]:
- print "WARNING: Valid values for sid_or_sname are 'sid' or 'sname'. Use 'sid' if the db identifier type is " \
- "Service ID. Use 'sname' if the db identifier type is Service Name"
- parser.print_help()
- exit(-1)
- else:
- options.sid_or_sname = options.sid_or_sname.lower()
- @OsFamilyFuncImpl(OSConst.WINSRV_FAMILY)
- def create_user_action_map(args, options):
- action_map = {
- SETUP_ACTION: UserAction(winsetup, options),
- START_ACTION: UserAction(svcstart),
- PSTART_ACTION: UserAction(start, options),
- STOP_ACTION: UserAction(stop),
- RESET_ACTION: UserAction(reset, options),
- STATUS_ACTION: UserAction(status, options),
- UPGRADE_ACTION: UserAction(upgrade, options),
- LDAP_SETUP_ACTION: UserAction(setup_ldap),
- SETUP_SECURITY_ACTION: UserActionRestart(setup_security, options),
- REFRESH_STACK_HASH_ACTION: UserAction(refresh_stack_hash_action),
- }
- return action_map
- @OsFamilyFuncImpl(OsFamilyImpl.DEFAULT)
- def create_user_action_map(args, options):
- action_map = {
- SETUP_ACTION: UserAction(setup, options),
- SETUP_JCE_ACTION : UserActionPossibleArgs(setup_jce_policy, [2], args),
- START_ACTION: UserAction(start, options),
- STOP_ACTION: UserAction(stop, options),
- RESET_ACTION: UserAction(reset, options),
- STATUS_ACTION: UserAction(status, options),
- UPGRADE_ACTION: UserAction(upgrade, options),
- UPGRADE_STACK_ACTION: UserActionPossibleArgs(upgrade_stack, [2, 4], args),
- LDAP_SETUP_ACTION: UserAction(setup_ldap),
- LDAP_SYNC_ACTION: UserAction(sync_ldap, options),
- SET_CURRENT: UserAction(set_current, options),
- SETUP_SECURITY_ACTION: UserActionRestart(setup_security, options),
- REFRESH_STACK_HASH_ACTION: UserAction(refresh_stack_hash_action),
- BACKUP_ACTION: UserActionPossibleArgs(backup, [1, 2], args),
- RESTORE_ACTION: UserActionPossibleArgs(restore, [1, 2], args)
- }
- return action_map
- #
- # Main.
- #
- def main(options, args, parser):
- # set silent
- set_silent(options.silent)
- # debug mode
- set_debug_mode_from_options(options)
- init_debug(options)
- #perform checks
- options.warnings = []
- if are_cmd_line_db_args_blank(options):
- options.must_set_database_options = True
- elif not are_cmd_line_db_args_valid(options):
- parser.error('All database options should be set. Please see help for the options.')
- else:
- options.must_set_database_options = False
- #correct database
- fix_database_options(options, parser)
- if len(args) == 0:
- print parser.print_help()
- parser.error("No action entered")
- action_map = create_user_action_map(args, options)
- action = args[0]
- try:
- action_obj = action_map[action]
- except KeyError:
- parser.error("Invalid action: " + action)
- matches = 0
- for args_number_required in action_obj.possible_args_numbers:
- matches += int(len(args) == args_number_required)
- if matches == 0:
- print parser.print_help()
- possible_args = ' or '.join(str(x) for x in action_obj.possible_args_numbers)
- parser.error("Invalid number of arguments. Entered: " + str(len(args)) + ", required: " + possible_args)
- options.exit_message = "Ambari Server '%s' completed successfully." % action
- try:
- action_obj.execute()
- if action_obj.need_restart:
- pstatus, pid = is_server_runing()
- if pstatus:
- print 'NOTE: Restart Ambari Server to apply changes' + \
- ' ("ambari-server restart|stop+start")'
- if options.warnings:
- for warning in options.warnings:
- print_warning_msg(warning)
- pass
- options.exit_message = "Ambari Server '%s' completed with warnings." % action
- pass
- except FatalException as e:
- if e.reason is not None:
- print_error_msg("Exiting with exit code {0}. \nREASON: {1}".format(e.code, e.reason))
- sys.exit(e.code)
- except NonFatalException as e:
- options.exit_message = "Ambari Server '%s' completed with warnings." % action
- if e.reason is not None:
- print_warning_msg(e.reason)
- if options.exit_message is not None:
- print options.exit_message
- def mainBody():
- parser = optparse.OptionParser(usage="usage: %prog [options] action [stack_id os]",)
- init_parser_options(parser)
- (options, args) = parser.parse_args()
- # set verbose
- set_verbose(options.verbose)
- if options.verbose:
- main(options, args, parser)
- else:
- try:
- main(options, args, parser)
- except Exception as e:
- print_error_msg("Unexpected {0}: {1}".format((e).__class__.__name__, str(e)) +\
- "\nFor more info run ambari-server with -v or --verbose option")
- sys.exit(1)
-
- if __name__ == "__main__":
- try:
- mainBody()
- except (KeyboardInterrupt, EOFError):
- print("\nAborting ... Keyboard Interrupt.")
- sys.exit(1)
|