http://git-wip-us.apache.org/repos/asf/ambari/blob/fad56746/ambari-server/src/main/python/ambari_server/dbConfiguration_linux.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/python/ambari_server/dbConfiguration_linux.py b/ambari-server/src/main/python/ambari_server/dbConfiguration_linux.py index a4295f7..ce47fae 100644 --- a/ambari-server/src/main/python/ambari_server/dbConfiguration_linux.py +++ b/ambari-server/src/main/python/ambari_server/dbConfiguration_linux.py @@ -17,177 +17,204 @@ 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 fileinput -import glob -import os -import re + import shutil -import socket -import subprocess -import sys -import time - -from ambari_commons import OSCheck, OSConst -from ambari_commons.logging_utils import print_error_msg, print_info_msg, print_warning_msg, VERBOSE -from ambari_commons.exceptions import NonFatalException, FatalException -from ambari_commons.os_utils import copy_files, remove_file, run_os_command -from ambari_server.dbConfiguration import DBMSConfig, USERNAME_PATTERN, SETUP_DB_CONNECT_ATTEMPTS, \ - SETUP_DB_CONNECT_TIMEOUT -from ambari_server.serverConfiguration import get_ambari_properties, get_value_from_properties, configDefaults, \ - OS_TYPE, AMBARI_PROPERTIES_FILE, BLIND_PASSWORD, RESOURCES_DIR_PROPERTY, \ - JDBC_DATABASE_PROPERTY, JDBC_DATABASE_NAME_PROPERTY, JDBC_POSTGRES_SCHEMA_PROPERTY, \ - JDBC_HOSTNAME_PROPERTY, JDBC_PORT_PROPERTY, \ - JDBC_USER_NAME_PROPERTY, JDBC_PASSWORD_PROPERTY, JDBC_PASSWORD_FILENAME, \ - JDBC_DRIVER_PROPERTY, JDBC_URL_PROPERTY, \ - JDBC_RCA_USER_NAME_PROPERTY, JDBC_RCA_PASSWORD_ALIAS, JDBC_RCA_PASSWORD_FILE_PROPERTY, \ - JDBC_RCA_DRIVER_PROPERTY, JDBC_RCA_URL_PROPERTY, \ - PERSISTENCE_TYPE_PROPERTY -from ambari_server.setupSecurity import read_password, store_password_file, encrypt_password -from ambari_server.userInput import get_YN_input, get_validated_string_input -from ambari_server.utils import get_postgre_hba_dir, get_postgre_running_status - -_DEFAULT_PASSWORD = "bigdata" - -ORACLE_DB_ID_TYPES = ["Service Name", "SID"] - -JDBC_PROPERTIES_PREFIX = "server.jdbc.properties." - -class LinuxDBMSConfig(DBMSConfig): - def __init__(self, options, properties, storage_type): - super(LinuxDBMSConfig, self).__init__(options, properties, storage_type) - #Init the database configuration data here, if any - self.dbms_full_name = "" - self.driver_file_name = "" - - # The values from options supersede the values from properties - self.database_host = DBMSConfig._init_member_with_prop_default(options, "database_host", - properties, JDBC_HOSTNAME_PROPERTY, "localhost") - #self.database_port is set in the subclasses - self.database_name = DBMSConfig._init_member_with_prop_default(options, "database_name", - properties, JDBC_DATABASE_NAME_PROPERTY, configDefaults.DEFAULT_DB_NAME) - - self.database_username = DBMSConfig._init_member_with_prop_default(options, "database_username", - properties, JDBC_USER_NAME_PROPERTY, "ambari") - self.database_password = DBMSConfig._init_member_with_default(options, "database_password", _DEFAULT_PASSWORD) - self.password_file = get_value_from_properties(properties, JDBC_PASSWORD_PROPERTY, None) - - self.database_url_pattern = "" - self.database_url_pattern_alt = "" - - self.database_storage_name = "" - self.sid_or_sname = "sname" - - self.init_script_file = "" - self.drop_tables_script_file = "" - self.client_tool_usage_pattern = "" - - self.jdbc_extra_params = [] - - def _prompt_db_properties(self): - if not self.silent == True: - if self.persistence_type != 'local': - self.database_host = get_validated_string_input( - "Hostname (" + self.database_host + "): ", - self.database_host, +from ambari_commons import OSConst +from ambari_commons.logging_utils import * +from exceptions import * +from dbConfiguration import * +from utils import * + +import utils + +# PostgreSQL settings +PG_JDBC_CONNECTION_STRING = "jdbc:postgresql://{0}:{1}/{2}" +PG_JDBC_CONNECTION_STRING_ALT = "jdbc:postgresql://{0}:{1}/{2}" + +UBUNTU_PG_HBA_ROOT = "/etc/postgresql" +PG_HBA_ROOT_DEFAULT = "/var/lib/pgsql/data" + +SETUP_DB_CMD = ['su', '-', 'postgres', + '--command=psql -f {0} -v username=\'"{1}"\' -v password="\'{2}\'" -v dbname="{3}"'] +UPGRADE_STACK_CMD = ['su', 'postgres', + '--command=psql -f {0} -v stack_name="\'{1}\'" -v stack_version="\'{2}\'" -v dbname="{3}"'] + +CHANGE_OWNER_COMMAND = ['su', '-', 'postgres', + '--command=/var/lib/ambari-server/resources/scripts/change_owner.sh -d {0} -s {1} -o {2}'] + +PG_ERROR_BLOCKED = "is being accessed by other users" +PG_STATUS_RUNNING = get_running_status() +PG_DEFAULT_PASSWORD = "bigdata" +SERVICE_CMD = "/usr/bin/env service" +PG_SERVICE_NAME = "postgresql" +PG_HBA_DIR = utils.get_postgre_hba_dir() + +PG_ST_CMD = "%s %s status" % (SERVICE_CMD, PG_SERVICE_NAME) +if os.path.isfile("/usr/bin/postgresql-setup"): + PG_INITDB_CMD = "/usr/bin/postgresql-setup initdb" +else: + PG_INITDB_CMD = "%s %s initdb" % (SERVICE_CMD, PG_SERVICE_NAME) + +PG_START_CMD = "%s %s start" % (SERVICE_CMD, PG_SERVICE_NAME) +PG_RESTART_CMD = "%s %s restart" % (SERVICE_CMD, PG_SERVICE_NAME) +PG_HBA_RELOAD_CMD = "%s %s reload" % (SERVICE_CMD, PG_SERVICE_NAME) + +PG_HBA_CONF_FILE = os.path.join(PG_HBA_DIR, "pg_hba.conf") +PG_HBA_CONF_FILE_BACKUP = os.path.join(PG_HBA_DIR, "pg_hba_bak.conf.old") +POSTGRESQL_CONF_FILE = os.path.join(PG_HBA_DIR, "postgresql.conf") + + +# Set database properties to default values +def load_default_db_properties(args): + args.persistence_type = 'local' + args.dbms = DATABASE_NAMES[DATABASE_INDEX] + args.database_host = "localhost" + args.database_port = DATABASE_PORTS[DATABASE_INDEX] + args.database_name = DEFAULT_DB_NAME + args.database_username = "ambari" + args.database_password = "bigdata" + args.sid_or_sname = "sname" + pass + +def configure_database_password(showDefault=True): + passwordDefault = PG_DEFAULT_PASSWORD + if showDefault: + passwordPrompt = 'Enter Database Password (' + passwordDefault + '): ' + else: + passwordPrompt = 'Enter Database Password: ' + passwordPattern = "^[a-zA-Z0-9_-]*$" + passwordDescr = "Invalid characters in password. Use only alphanumeric or "\ + "_ or - characters" + + password = read_password(passwordDefault, passwordPattern, passwordPrompt, + passwordDescr) + + return password + +# Ask user for database connection properties +def prompt_linux_db_properties(args): + global DATABASE_INDEX + + if args.must_set_database_options: + load_default_db_properties(args) + ok = get_YN_input("Enter advanced database configuration [y/n] (n)? ", False) + if ok: + + print "==============================================================================" + print "Choose one of the following options:" + + database_num = str(DATABASE_INDEX + 1) + database_num = get_validated_string_input( + "[1] - PostgreSQL (Embedded)\n[2] - Oracle\n[3] - MySQL\n[4] - PostgreSQL\n" + "==============================================================================\n" + "Enter choice (" + database_num + "): ", + database_num, + "^[1234]$", + "Invalid number.", + False + ) + + if int(database_num) == 1: + args.persistence_type = 'local' + args.database_index = 0 + else: + args.persistence_type = 'remote' + selected_db_option = int(database_num) + + if selected_db_option == 2: + args.database_index = 1 + elif selected_db_option == 3: + args.database_index = 2 + elif selected_db_option == 4: + args.database_index = 0 + else: + print_info_msg('Unknown db option, default to embbeded postgres.') + args.database_index = 0 + pass + pass + + DATABASE_INDEX = args.database_index + args.dbms = DATABASE_NAMES[args.database_index] + + if args.persistence_type != 'local': + args.database_host = get_validated_string_input( + "Hostname (" + args.database_host + "): ", + args.database_host, "^[a-zA-Z0-9.\-]*$", "Invalid hostname.", False ) - self.database_port = get_validated_string_input( - "Port (" + self.database_port + "): ", - self.database_port, + args.database_port = DATABASE_PORTS[DATABASE_INDEX] + args.database_port = get_validated_string_input( + "Port (" + args.database_port + "): ", + args.database_port, "^([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$", "Invalid port.", False ) - if not self._configure_database_name(): - return False + if args.dbms == "oracle": + # Oracle uses service name or service id + idType = "1" + idType = get_validated_string_input( + "Select Oracle identifier type:\n1 - " + ORACLE_DB_ID_TYPES[0] + + "\n2 - " + ORACLE_DB_ID_TYPES[1] + "\n(" + idType + "): ", + idType, + "^[12]$", + "Invalid number.", + False + ) + + if idType == "2": + args.sid_or_sname = "sid" + + IDTYPE_INDEX = int(idType) - 1 + args.database_name = get_validated_service_name(args.database_name, + IDTYPE_INDEX) + elif args.dbms in ["mysql", "postgres"]: + args.database_name = get_validated_db_name(args.database_name) + + else: + # other DB types + pass + pass + else: + args.database_host = "localhost" + args.database_port = DATABASE_PORTS[DATABASE_INDEX] + + args.database_name = get_validated_db_name(args.database_name) + pass # Username is common for Oracle/MySQL/Postgres - self.database_username = get_validated_string_input( - 'Username (' + self.database_username + '): ', - self.database_username, + args.database_username = get_validated_string_input( + 'Username (' + args.database_username + '): ', + args.database_username, USERNAME_PATTERN, "Invalid characters in username. Start with _ or alpha " "followed by alphanumeric or _ or - characters", False ) - self.database_password = LinuxDBMSConfig._configure_database_password(True) - - self._display_db_properties() - return True - - # Supporting remote server for all the DB types. Supporting local server only for PostgreSQL. - def _setup_remote_server(self, args): - self._store_remote_properties(args) - - def _setup_remote_database(self): - properties = get_ambari_properties() - if properties == -1: - err = 'Error getting ambari properties' - print_error_msg(err) - raise FatalException(-1, err) - - if self.ensure_jdbc_driver_installed(properties): - print 'Configuring remote database connection properties...' - retcode = self._setup_remote_db() - if retcode == -1: - err = "Remote database setup aborted." - raise NonFatalException(err) - if not retcode == 0: - err = 'Error while configuring connection properties. Exiting' - raise FatalException(retcode, err) - - def _reset_remote_database(self): - client_usage_cmd_drop = self.client_tool_usage_pattern.format(self.drop_tables_script_file, self.database_username, - BLIND_PASSWORD, self.database_name) - client_usage_cmd_init = self.client_tool_usage_pattern.format(self.init_script_file, self.database_username, - BLIND_PASSWORD, self.database_name) - - print_warning_msg('To reset Ambari Server schema ' + - 'you must run the following DDL against the database to ' - + 'drop the schema:' + os.linesep + client_usage_cmd_drop - + os.linesep + 'Then you must run the following DDL ' + - 'against the database to create the schema: ' + os.linesep + - client_usage_cmd_init + os.linesep) - - def _install_jdbc_driver(self, properties, files_list): - if type(files_list) is not int: - print 'Copying JDBC drivers to server resources...' - try: - resources_dir = properties[RESOURCES_DIR_PROPERTY] - except KeyError: - print_error_msg("There is no value for " + RESOURCES_DIR_PROPERTY + "in " + AMBARI_PROPERTIES_FILE) - return False - - db_name = self.dbms_full_name.lower() - jdbc_symlink = os.path.join(resources_dir, db_name + "-jdbc-driver.jar") - db_default_driver_path = os.path.join(configDefaults.JAVA_SHARE_PATH, self.driver_file_name) + args.database_password = configure_database_password(True) - if os.path.lexists(jdbc_symlink): - os.remove(jdbc_symlink) - - copy_status = copy_files(files_list, resources_dir) - - if not copy_status == 0: - raise FatalException(-1, "Failed to copy JDBC drivers to server resources") - - if db_default_driver_path in files_list: - os.symlink(os.path.join(resources_dir, self.driver_file_name), jdbc_symlink) - else: - if files_list != -1: - return False - return True + print_info_msg('Using database options: {database},{host},{port},{schema},{user},{password}'.format( + database=args.dbms, + host=args.database_host, + port=args.database_port, + schema=args.database_name, + user=args.database_username, + password=args.database_password + )) - def _configure_database_name(self): - return True +# PostgreSQL configuration and setup +class PGConfig(DBMSConfig): + def __init__(self): + #Init the database configuration data here, if any + pass - @staticmethod - def _configure_database_password(showDefault=True): - passwordDefault = _DEFAULT_PASSWORD + def configure_database_password(showDefault=True): + passwordDefault = PG_DEFAULT_PASSWORD if showDefault: passwordPrompt = 'Enter Database Password (' + passwordDefault + '): ' else: @@ -201,334 +228,229 @@ class LinuxDBMSConfig(DBMSConfig): return password - @staticmethod - def _get_validated_db_name(database_storage_name, database_name): - return get_validated_string_input( - database_storage_name + " Name (" - + database_name + "): ", - database_name, - ".*", - "Invalid " + database_storage_name + " name.", - False - ) - - def _display_db_properties(self): - print_info_msg('Using database options: {database},{host},{port},{schema},{user},{password}'.format( - database=self.dbms, - host=self.database_host, - port=self.database_port, - schema=self.database_name, - user=self.database_username, - password=self.database_password - )) + # + # Private implementation + # + def _change_db_files_owner(args): + print 'Fixing database objects owner' + database_name = args.database_name + new_owner = args.database_username + if '"' not in new_owner: + #wrap to allow old username "ambari-server", postgres only + new_owner = '\'"{0}"\''.format(new_owner) + pass - #Check if required jdbc drivers present - @staticmethod - def _find_jdbc_driver(jdbc_pattern): - drivers = [] - drivers.extend(glob.glob(configDefaults.JAVA_SHARE_PATH + os.sep + jdbc_pattern)) - if drivers: - return drivers - return -1 + command = CHANGE_OWNER_COMMAND[:] + command[-1] = command[-1].format(database_name, 'ambari', new_owner) + return run_os_command(command) - # Let the console user initialize the remote database schema - def _setup_remote_db(self): - setup_msg = "Before starting Ambari Server, you must run the following DDL " \ - "against the database to create the schema: {0}".format(self.init_script_file) + def _configure_pg_hba_ambaridb_users(self): + args = optparse.Values() + configure_database_username_password(args) - print_warning_msg(setup_msg) + with open(PG_HBA_CONF_FILE, "a") as pgHbaConf: + pgHbaConf.write("\n") + pgHbaConf.write("local all " + args.database_username + + ",mapred md5") + pgHbaConf.write("\n") + pgHbaConf.write("host all " + args.database_username + + ",mapred 0.0.0.0/0 md5") + pgHbaConf.write("\n") + pgHbaConf.write("host all " + args.database_username + + ",mapred ::/0 md5") + pgHbaConf.write("\n") + retcode, out, err = run_os_command(PG_HBA_RELOAD_CMD) + if not retcode == 0: + raise FatalException(retcode, err) - proceed = get_YN_input("Proceed with configuring remote database connection properties [y/n] (y)? ", True) - retCode = 0 if proceed else -1 + def _configure_pg_hba_postgres_user(self): + postgresString = "all postgres" + for line in fileinput.input(PG_HBA_CONF_FILE, inplace=1): + print re.sub('all\s*all', postgresString, line), + os.chmod(PG_HBA_CONF_FILE, 0644) - return retCode + def _configure_postgresql_conf(self): + listenAddress = "listen_addresses = '*' #" + for line in fileinput.input(POSTGRESQL_CONF_FILE, inplace=1): + print re.sub('#+listen_addresses.*?(#|$)', listenAddress, line), + os.chmod(POSTGRESQL_CONF_FILE, 0644) # Store set of properties for remote database connection - def _store_remote_properties(self, properties): - properties.process_pair(PERSISTENCE_TYPE_PROPERTY, self.persistence_type) + def _store_remote_properties(args): + properties = get_ambari_properties() + if properties == -1: + print_error_msg("Error getting ambari properties") + return -1 + + isSecure = get_is_secure(properties) + + properties.process_pair(PERSISTENCE_TYPE_PROPERTY, "remote") - properties.process_pair(JDBC_DATABASE_PROPERTY, self.dbms) - properties.process_pair(JDBC_HOSTNAME_PROPERTY, self.database_host) - properties.process_pair(JDBC_PORT_PROPERTY, self.database_port) - properties.process_pair(JDBC_DATABASE_NAME_PROPERTY, self.database_name) + properties.process_pair(JDBC_DATABASE_PROPERTY, args.dbms) + properties.process_pair(JDBC_HOSTNAME_PROPERTY, args.database_host) + properties.process_pair(JDBC_PORT_PROPERTY, args.database_port) + properties.process_pair(JDBC_SCHEMA_PROPERTY, args.database_name) - properties.process_pair(JDBC_DRIVER_PROPERTY, self.driver_class_name) + properties.process_pair(JDBC_DRIVER_PROPERTY, DBCN.get_driver_name()) # fully qualify the hostname to make sure all the other hosts can connect # to the jdbc hostname since its passed onto the agents for RCA - jdbc_hostname = self.database_host - if (self.database_host == "localhost"): + jdbc_hostname = args.database_host + if (args.database_host == "localhost"): jdbc_hostname = socket.getfqdn() - connectionStringFormat = self.database_url_pattern - if self.sid_or_sname == "sid": - connectionStringFormat = self.database_url_pattern_alt - properties.process_pair(JDBC_URL_PROPERTY, connectionStringFormat.format(jdbc_hostname, self.database_port, self.database_name)) - properties.process_pair(JDBC_USER_NAME_PROPERTY, self.database_username) + #TODO: Implement the DBCN connection string generation + #connectionStringFormat = DATABASE_CONNECTION_STRINGS + #if args.sid_or_sname == "sid": + # connectionStringFormat = DATABASE_CONNECTION_STRINGS_ALT + #properties.process_pair(JDBC_URL_PROPERTY, connectionStringFormat[DATABASE_INDEX].format(jdbc_hostname, args.database_port, args.database_name)) + properties.process_pair(JDBC_URL_PROPERTY, DBCN.get_connection_string()) + properties.process_pair(JDBC_USER_NAME_PROPERTY, args.database_username) properties.process_pair(JDBC_PASSWORD_PROPERTY, - store_password_file(self.database_password, JDBC_PASSWORD_FILENAME)) + store_password_file(args.database_password, JDBC_PASSWORD_FILENAME)) # save any other defined properties to pass to JDBC - for pair in self.jdbc_extra_params: - properties.process_pair(JDBC_PROPERTIES_PREFIX + pair[0], pair[1]) + if DATABASE_INDEX < len(DATABASE_JDBC_PROPERTIES): + for pair in DATABASE_JDBC_PROPERTIES[DATABASE_INDEX]: + properties.process_pair(JDBC_PROPERTIES_PREFIX + pair[0], pair[1]) - if self.isSecure: - encrypted_password = encrypt_password(JDBC_RCA_PASSWORD_ALIAS, self.database_password) - if encrypted_password != self.database_password: + if isSecure: + encrypted_password = encrypt_password(JDBC_RCA_PASSWORD_ALIAS, args.database_password) + if encrypted_password != args.database_password: properties.process_pair(JDBC_PASSWORD_PROPERTY, encrypted_password) pass - properties.process_pair(JDBC_RCA_DRIVER_PROPERTY, self.driver_class_name) - properties.process_pair(JDBC_RCA_URL_PROPERTY, self.database_url_pattern.format(jdbc_hostname, self.database_port, self.database_name)) - properties.process_pair(JDBC_RCA_USER_NAME_PROPERTY, self.database_username) + properties.process_pair(JDBC_RCA_DRIVER_PROPERTY, DBCN.get_driver_name()) + properties.process_pair(JDBC_RCA_URL_PROPERTY, DBCN.get_connection_string()) + properties.process_pair(JDBC_RCA_USER_NAME_PROPERTY, args.database_username) properties.process_pair(JDBC_RCA_PASSWORD_FILE_PROPERTY, - store_password_file(self.database_password, JDBC_PASSWORD_FILENAME)) - if self.isSecure: - encrypted_password = encrypt_password(JDBC_RCA_PASSWORD_ALIAS, self.database_password) - if encrypted_password != self.database_password: + store_password_file(args.database_password, JDBC_PASSWORD_FILENAME)) + if isSecure: + encrypted_password = encrypt_password(JDBC_RCA_PASSWORD_ALIAS, args.database_password) + if encrypted_password != args.database_password: properties.process_pair(JDBC_RCA_PASSWORD_FILE_PROPERTY, encrypted_password) + pass + conf_file = properties.fileName -# PostgreSQL configuration and setup -class PGConfig(LinuxDBMSConfig): - # PostgreSQL settings - SETUP_DB_CMD = ['su', '-', 'postgres', - '--command=psql -f {0} -v username=\'"{1}"\' -v password="\'{2}\'" -v dbname="{3}"'] - UPGRADE_STACK_CMD = ['su', 'postgres', - '--command=psql -f {0} -v stack_name="\'{1}\'" -v stack_version="\'{2}\'" -v dbname="{3}"'] - - CHANGE_OWNER_COMMAND = ['su', '-', 'postgres', - '--command=/var/lib/ambari-server/resources/scripts/change_owner.sh -d {0} -s {1} -o {2}'] - - PG_ERROR_BLOCKED = "is being accessed by other users" - PG_STATUS_RUNNING = get_postgre_running_status(OS_TYPE) - SERVICE_CMD = "/usr/bin/env service" - PG_SERVICE_NAME = "postgresql" - PG_HBA_DIR = get_postgre_hba_dir(OSCheck.get_os_family()) - - PG_ST_CMD = "%s %s status" % (SERVICE_CMD, PG_SERVICE_NAME) - if os.path.isfile("/usr/bin/postgresql-setup"): - PG_INITDB_CMD = "/usr/bin/postgresql-setup initdb" - else: - PG_INITDB_CMD = "%s %s initdb" % (SERVICE_CMD, PG_SERVICE_NAME) + try: + properties.store(open(conf_file, "w")) + except Exception, e: + print 'Could not write ambari config file "%s": %s' % (conf_file, e) + return -1 - PG_START_CMD = "%s %s start" % (SERVICE_CMD, PG_SERVICE_NAME) - PG_RESTART_CMD = "%s %s restart" % (SERVICE_CMD, PG_SERVICE_NAME) - PG_HBA_RELOAD_CMD = "%s %s reload" % (SERVICE_CMD, PG_SERVICE_NAME) + return 0 - PG_HBA_CONF_FILE = os.path.join(PG_HBA_DIR, "pg_hba.conf") - PG_HBA_CONF_FILE_BACKUP = os.path.join(PG_HBA_DIR, "pg_hba_bak.conf.old") - POSTGRESQL_CONF_FILE = os.path.join(PG_HBA_DIR, "postgresql.conf") - def __init__(self, options, properties, storage_type): - super(PGConfig, self).__init__(options, properties, storage_type) + # + # Public methods + # + def configure_postgres(self): + if os.path.isfile(PG_HBA_CONF_FILE): + if not os.path.isfile(PG_HBA_CONF_FILE_BACKUP): + shutil.copyfile(PG_HBA_CONF_FILE, PG_HBA_CONF_FILE_BACKUP) + else: + #Postgres has been configured before, must not override backup + print "Backup for pg_hba found, reconfiguration not required" + return 0 + self._configure_pg_hba_postgres_user() + self._configure_pg_hba_ambaridb_users() + os.chmod(PG_HBA_CONF_FILE, 0644) + self._configure_postgresql_conf() + #restart postgresql if already running + pg_status = get_postgre_status() + if pg_status == PG_STATUS_RUNNING: + retcode = restart_postgres() + return retcode + return 0 - #Init the database configuration data here, if any - self.dbms = "postgres" - self.dbms_full_name = "PostgreSQL" - self.driver_class_name = "org.postgresql.Driver" - self.driver_file_name = "postgresql-jdbc.jar" + def configure_database(self, args): + prompt_db_properties(args) - self.database_storage_name = "Database" + #DB setup should be done last after doing any setup. - # PostgreSQL seems to require additional schema coordinates - self.postgres_schema = get_value_from_properties(properties, JDBC_POSTGRES_SCHEMA_PROPERTY, self.database_name) - self.database_port = DBMSConfig._init_member_with_prop_default(options, "database_port", - properties, JDBC_PORT_PROPERTY, "5432") + if is_local_database(args): + #check if jdbc user is changed + is_user_changed = is_jdbc_user_changed(args) - self.database_url_pattern = "jdbc:postgresql://{0}:{1}/{2}" - self.database_url_pattern_alt = "jdbc:postgresql://{0}:{1}/{2}" + print 'Default properties detected. Using built-in database.' + store_local_properties(args) - self.JDBC_DRIVER_INSTALL_MSG = 'Before starting Ambari Server, ' \ - 'you must copy the {0} JDBC driver JAR file to {1}.'.format( - self.dbms_full_name, configDefaults.JAVA_SHARE_PATH) + print 'Checking PostgreSQL...' + retcode = check_postgre_up() + if not retcode == 0: + err = 'Unable to start PostgreSQL server. Exiting' + raise FatalException(retcode, err) - self._is_user_changed = False + print 'Configuring local database...' + retcode, outdata, errdata = setup_db(args) + if not retcode == 0: + err = 'Running database init script was failed. Exiting.' + raise FatalException(retcode, err) - self.init_script_file = "/var/lib/ambari-server/resources/Ambari-DDL-Postgres-CREATE.sql" - self.drop_tables_script_file = "/var/lib/ambari-server/resources/Ambari-DDL-Postgres-DROP.sql" - self.client_tool_usage_pattern = 'su -postgres --command=psql -f {0} -v username=\'"{1}"\' -v password="\'{2}\'"' + if is_user_changed: + #remove backup for pg_hba in order to reconfigure postgres + remove_file(PG_HBA_CONF_FILE_BACKUP) - # - # Public methods - # + print 'Configuring PostgreSQL...' + retcode = configure_postgres() + if not retcode == 0: + err = 'Unable to configure PostgreSQL server. Exiting' + raise FatalException(retcode, err) - # - # Private implementation - # - # Supporting remote server for all the DB types. Supporting local server only for PostgreSQL. - def _setup_local_server(self, properties): - # check if jdbc user is changed - self._is_user_changed = PGConfig._is_jdbc_user_changed(self.database_username) - print 'Default properties detected. Using built-in database.' - self._store_local_properties(properties) - - def _setup_local_database(self): - print 'Checking PostgreSQL...' - (pg_status, retcode, out, err) = self._check_postgre_up() - if not retcode == 0: - err = 'Unable to start PostgreSQL server. Exiting' - raise FatalException(retcode, err) - print 'Configuring local database...' - retcode, out, err = self._setup_db() - if not retcode == 0: - err = 'Running database init script was failed. Exiting.' - raise FatalException(retcode, err) - if self._is_user_changed: - #remove backup for pg_hba in order to reconfigure postgres - remove_file(PGConfig.PG_HBA_CONF_FILE_BACKUP) - print 'Configuring PostgreSQL...' - retcode, out, err = self._configure_postgres() - if not retcode == 0: - err = 'Unable to configure PostgreSQL server. Exiting' - raise FatalException(retcode, err) + else: + retcode = self._store_remote_properties(args) + if retcode != 0: + err = 'Unable to save config file' + raise FatalException(retcode, err) - def _reset_local_database(self): - dbname = self.database_name - filename = self.drop_script_file - username = self.database_username - password = self.database_password - command = PGConfig.SETUP_DB_CMD[:] - command[-1] = command[-1].format(filename, username, password, dbname) - drop_retcode, drop_outdata, drop_errdata = run_os_command(command) - if not drop_retcode == 0: - raise FatalException(1, drop_errdata) - if drop_errdata and PGConfig.PG_ERROR_BLOCKED in drop_errdata: - raise FatalException(1, "Database is in use. Please, make sure all connections to the database are closed") - if drop_errdata and VERBOSE: - print_warning_msg(drop_errdata) - print_info_msg("About to run database setup") - retcode, outdata, errdata = self._setup_db() - if errdata and VERBOSE: - print_warning_msg(errdata) - if (errdata and 'ERROR' in errdata.upper()) or (drop_errdata and 'ERROR' in drop_errdata.upper()): - if not VERBOSE: - raise NonFatalException("Non critical error in DDL, use --verbose for more information") - else: - raise NonFatalException("Non critical error in DDL") + check_jdbc_drivers(args) - def _is_jdbc_driver_installed(self, properties): - return 0 + print 'Configuring remote database connection properties...' + retcode = setup_remote_db(args) + if retcode == -1: + err = "Remote database setup aborted." + raise NonFatalException(err) - def _configure_database_name(self): - self.database_name = LinuxDBMSConfig._get_validated_db_name(self.database_storage_name, self.database_name) - self.postgres_schema = self._get_validated_db_schema(self.postgres_schema) - return True + if not retcode == 0: + err = 'Error while configuring connection properties. Exiting' + raise FatalException(retcode, err) + check_jdbc_drivers(args) - def _get_validated_db_schema(self, postgres_schema): - return get_validated_string_input( - "Postgres schema (" + postgres_schema + "): ", - postgres_schema, - "^[a-zA-Z0-9_\-]*$", - "Invalid schema name.", - False, allowEmpty=True - ) - - # Check if jdbc user is changed - @staticmethod - def _is_jdbc_user_changed(database_username): + + def configure_database_username_password(self, args): properties = get_ambari_properties() if properties == -1: print_error_msg("Error getting ambari properties") - return None - - previos_user = get_value_from_properties(properties, JDBC_USER_NAME_PROPERTY, "") - new_user = database_username - - if previos_user and new_user: - if previos_user != new_user: - return True + return -1 + + username = properties[JDBC_USER_NAME_PROPERTY] + passwordProp = properties[JDBC_PASSWORD_PROPERTY] + dbname = properties[JDBC_DATABASE_PROPERTY] + + if username and passwordProp and dbname: + print_info_msg("Database username + password already configured") + args.database_username = username + args.database_name = dbname + if is_alias_string(passwordProp): + args.database_password = decrypt_password_for_alias(JDBC_RCA_PASSWORD_ALIAS) else: - return False - - return None - - # Store local database connection properties - def _store_local_properties(self, properties): - properties.removeOldProp(JDBC_DATABASE_PROPERTY) - properties.removeOldProp(JDBC_DATABASE_NAME_PROPERTY) - properties.removeOldProp(JDBC_POSTGRES_SCHEMA_PROPERTY) - properties.removeOldProp(JDBC_HOSTNAME_PROPERTY) - properties.removeOldProp(JDBC_RCA_DRIVER_PROPERTY) - properties.removeOldProp(JDBC_RCA_URL_PROPERTY) - properties.removeOldProp(JDBC_PORT_PROPERTY) - properties.removeOldProp(JDBC_DRIVER_PROPERTY) - properties.removeOldProp(JDBC_URL_PROPERTY) - - # Store the properties - properties.process_pair(PERSISTENCE_TYPE_PROPERTY, self.persistence_type) - properties.process_pair(JDBC_DATABASE_PROPERTY, self.dbms) - properties.process_pair(JDBC_DATABASE_NAME_PROPERTY, self.database_name) - properties.process_pair(JDBC_POSTGRES_SCHEMA_PROPERTY, self.postgres_schema) - properties.process_pair(JDBC_USER_NAME_PROPERTY, self.database_username) - - if self.isSecure: - encrypted_password = encrypt_password(JDBC_RCA_PASSWORD_ALIAS, self.database_password) - if self.database_password != encrypted_password: - properties.process_pair(JDBC_PASSWORD_PROPERTY, encrypted_password) - - password_file = store_password_file(self.database_password, JDBC_PASSWORD_FILENAME) - properties.process_pair(JDBC_PASSWORD_PROPERTY, password_file) - - @staticmethod - def _get_postgre_status(): - retcode, out, err = run_os_command(PGConfig.PG_ST_CMD) - try: - pg_status = re.search('(stopped|running)', out, re.IGNORECASE).group(0).lower() - except AttributeError: - pg_status = None - return pg_status, retcode, out, err + if os.path.exists(passwordProp): + with open(passwordProp, 'r') as file: + args.database_password = file.read() - def _check_postgre_up(self): - pg_status, retcode, out, err = PGConfig._get_postgre_status() - if pg_status == PGConfig.PG_STATUS_RUNNING: - print_info_msg("PostgreSQL is running") - return pg_status, 0, out, err + return 1 else: - # run initdb only on non ubuntu systems as ubuntu does not have initdb cmd. - if OS_TYPE != OSConst.OS_UBUNTU: - print "Running initdb: This may take upto a minute." - retcode, out, err = run_os_command(PGConfig.PG_INITDB_CMD) - if retcode == 0: - print out - print "About to start PostgreSQL" - try: - process = subprocess.Popen(PGConfig.PG_START_CMD.split(' '), - stdout=subprocess.PIPE, - stdin=subprocess.PIPE, - stderr=subprocess.PIPE - ) - if OS_TYPE == OSConst.OS_SUSE: - time.sleep(20) - result = process.poll() - print_info_msg("Result of postgres start cmd: " + str(result)) - if result is None: - process.kill() - pg_status, retcode, out, err = PGConfig._get_postgre_status() - else: - retcode = result - else: - out, err = process.communicate() - retcode = process.returncode - pg_status, retcode, out, err = PGConfig._get_postgre_status() - if pg_status == PGConfig.PG_STATUS_RUNNING: - print_info_msg("Postgres process is running. Returning...") - return pg_status, 0, out, err - except (Exception), e: - pg_status, retcode, out, err = PGConfig._get_postgre_status() - if pg_status == PGConfig.PG_STATUS_RUNNING: - return pg_status, 0, out, err - else: - print_error_msg("Postgres start failed. " + str(e)) - return pg_status, retcode, out, err + print_error_msg("Connection properties not set in config file.") - def _setup_db(self): - #password access to ambari-server and mapred - dbname = self.database_name - scriptFile = self.init_script_file - username = self.database_username - password = self.database_password + def setup_db(self, args): + self.configure_database_username_password(args) + + dbname = args.database_name + scriptFile = args.init_script_file + username = args.database_username + password = args.database_password #setup DB - command = PGConfig.SETUP_DB_CMD[:] + command = SETUP_DB_CMD[:] command[-1] = command[-1].format(scriptFile, username, password, dbname) for i in range(SETUP_DB_CONNECT_ATTEMPTS): @@ -544,99 +466,21 @@ class PGConfig(LinuxDBMSConfig): time.sleep(SETUP_DB_CONNECT_TIMEOUT) print 'unable to connect to database' - print_error_msg(errdata) + utils.print_error_msg(errdata) return retcode, outdata, errdata - @staticmethod - def _configure_pg_hba_ambaridb_users(conf_file, database_username): - with open(conf_file, "a") as pgHbaConf: - pgHbaConf.write("\n") - pgHbaConf.write("local all " + database_username + - ",mapred md5") - pgHbaConf.write("\n") - pgHbaConf.write("host all " + database_username + - ",mapred 0.0.0.0/0 md5") - pgHbaConf.write("\n") - pgHbaConf.write("host all " + database_username + - ",mapred ::/0 md5") - pgHbaConf.write("\n") - retcode, out, err = run_os_command(PGConfig.PG_HBA_RELOAD_CMD) - if not retcode == 0: - raise FatalException(retcode, err) - - @staticmethod - def _configure_pg_hba_postgres_user(): - postgresString = "all postgres" - for line in fileinput.input(PGConfig.PG_HBA_CONF_FILE, inplace=1): - print re.sub('all\s*all', postgresString, line), - os.chmod(PGConfig.PG_HBA_CONF_FILE, 0644) - - @staticmethod - def _configure_postgresql_conf(): - listenAddress = "listen_addresses = '*' #" - for line in fileinput.input(PGConfig.POSTGRESQL_CONF_FILE, inplace=1): - print re.sub('#+listen_addresses.*?(#|$)', listenAddress, line), - os.chmod(PGConfig.POSTGRESQL_CONF_FILE, 0644) - - def _configure_postgres(self): - if os.path.isfile(PGConfig.PG_HBA_CONF_FILE): - if not os.path.isfile(PGConfig.PG_HBA_CONF_FILE_BACKUP): - shutil.copyfile(PGConfig.PG_HBA_CONF_FILE, PGConfig.PG_HBA_CONF_FILE_BACKUP) - else: - #Postgres has been configured before, must not override backup - print "Backup for pg_hba found, reconfiguration not required" - return 0, "", "" - PGConfig._configure_pg_hba_postgres_user() - PGConfig._configure_pg_hba_ambaridb_users(PGConfig.PG_HBA_CONF_FILE, self.database_username) - os.chmod(PGConfig.PG_HBA_CONF_FILE, 0644) - PGConfig._configure_postgresql_conf() - #restart postgresql if already running - pg_status, retcode, out, err = PGConfig._get_postgre_status() - if pg_status == PGConfig.PG_STATUS_RUNNING: - retcode, out, err = PGConfig._restart_postgres() - return retcode, out, err - return 0, "", "" - - @staticmethod - def _restart_postgres(): - print "Restarting PostgreSQL" - process = subprocess.Popen(PGConfig.PG_RESTART_CMD.split(' '), - stdout=subprocess.PIPE, - stdin=subprocess.PIPE, - stderr=subprocess.PIPE - ) - time.sleep(5) - result = process.poll() - if result is None: - print_info_msg("Killing restart PostgresSQL process") - process.kill() - pg_status, retcode, out, err = PGConfig._get_postgre_status() - # SUSE linux set status of stopped postgresql proc to unused - if pg_status == "unused" or pg_status == "stopped": - print_info_msg("PostgreSQL is stopped. Restarting ...") - retcode, out, err = run_os_command(PGConfig.PG_START_CMD) - return retcode, out, err - return 0, "", "" - - def _store_remote_properties(self, properties): - super(PGConfig, self)._store_remote_properties(properties) - - properties.process_pair(JDBC_POSTGRES_SCHEMA_PROPERTY, self.postgres_schema) + # Initialize remote database schema + def setup_remote_db(args): + setup_msg = "Before starting Ambari Server, you must run the following DDL " \ + "against the database to create the schema: {0}".format(DATABASE_INIT_SCRIPTS[DATABASE_INDEX]) - def _change_db_files_owner(args): - print 'Fixing database objects owner' - database_name = args.database_name - new_owner = args.database_username - if '"' not in new_owner: - #wrap to allow old username "ambari-server", postgres only - new_owner = '\'"{0}"\''.format(new_owner) - pass + print_warning_msg(setup_msg) - command = PGConfig.CHANGE_OWNER_COMMAND[:] - command[-1] = command[-1].format(database_name, 'ambari', new_owner) - return run_os_command(command) + proceed = get_YN_input("Proceed with configuring remote database connection properties [y/n] (y)? ", True) + retCode = 0 if proceed else -1 + return retCode def change_db_files_owner(self, args): if args.persistence_type == 'local': @@ -644,120 +488,253 @@ class PGConfig(LinuxDBMSConfig): if not retcode == 0: raise FatalException(20, 'Unable to change owner of database objects') -def createPGConfig(options, properties, storage_type, dbId): - return PGConfig(options, properties, storage_type) - + def reset_remote_db(self, args): + client_usage_cmd_drop = DATABASE_CLI_TOOLS_USAGE[DATABASE_INDEX].format(DATABASE_DROP_SCRIPTS[DATABASE_INDEX], args.database_username, + BLIND_PASSWORD, args.database_name) + client_usage_cmd_init = DATABASE_CLI_TOOLS_USAGE[DATABASE_INDEX].format(DATABASE_INIT_SCRIPTS[DATABASE_INDEX], args.database_username, + BLIND_PASSWORD, args.database_name) -class OracleConfig(LinuxDBMSConfig): - def __init__(self, options, properties, storage_type): - super(OracleConfig, self).__init__(options, properties, storage_type) - - #Init the database configuration data here, if any - self.dbms = "oracle" - self.dbms_full_name = "Oracle" - self.driver_class_name = "oracle.jdbc.driver.OracleDriver" - self.driver_file_name = "ojdbc6.jar" + print_warning_msg('To reset Ambari Server schema ' + + 'you must run the following DDL against the database to ' + + 'drop the schema:' + os.linesep + client_usage_cmd_drop + + os.linesep + 'Then you must run the following DDL ' + + 'against the database to create the schema: ' + os.linesep + + client_usage_cmd_init + os.linesep) - self.database_storage_name = "Service" + def reset_local_db(args): + dbname = args.database_name + filename = args.drop_script_file + username = args.database_username + password = args.database_password + command = SETUP_DB_CMD[:] + command[-1] = command[-1].format(filename, username, password, dbname) + drop_retcode, drop_outdata, drop_errdata = run_os_command(command) + if not drop_retcode == 0: + raise FatalException(1, drop_errdata) + if drop_errdata and PG_ERROR_BLOCKED in drop_errdata: + raise FatalException(1, "Database is in use. Please, make sure all connections to the database are closed") + if drop_errdata and VERBOSE: + print_warning_msg(drop_errdata) + print_info_msg("About to run database setup") + retcode, outdata, errdata = setup_db(args) + if errdata and VERBOSE: + print_warning_msg(errdata) + if (errdata and 'ERROR' in errdata.upper()) or (drop_errdata and 'ERROR' in drop_errdata.upper()): + if not VERBOSE: + raise NonFatalException("Non critical error in DDL, use --verbose for more information") + else: + raise NonFatalException("Non critical error in DDL") - self.database_port = DBMSConfig._init_member_with_prop_default(options, "database_port", - properties, JDBC_PORT_PROPERTY, "1521") +# PostgreSQL database +class PGDatabase: + _driverName = '' + _connectionString = '' - self.database_url_pattern = "jdbc:oracle:thin:@{0}:{1}/{2}" - self.database_url_pattern_alt = "jdbc:oracle:thin:@{0}:{1}:{2}" + def __init__(self): + #Init the database connection here, if any + pass - self.JDBC_DRIVER_INSTALL_MSG = 'Before starting Ambari Server, ' \ - 'you must copy the {0} JDBC driver JAR file to {1}.'.format( - self.dbms_full_name, configDefaults.JAVA_SHARE_PATH) + # + # Private implementation + # - self.init_script_file = "/var/lib/ambari-server/resources/Ambari-DDL-Oracle-CREATE.sql'" - self.drop_tables_script_file = "/var/lib/ambari-server/resources/Ambari-DDL-Oracle-DROP.sql" - self.client_tool_usage_pattern = 'sqlplus {1}/{2} < {0}' + # Get database client executable path + def get_db_cli_tool(self, args): + for tool in DATABASE_CLI_TOOLS[DATABASE_INDEX]: + cmd = CHECK_COMMAND_EXIST_CMD.format(tool) + ret, out, err = run_in_shell(cmd) + if ret == 0: + return get_exec_path(tool) - self.jdbc_extra_params = [ - ["oracle.net.CONNECT_TIMEOUT", "2000"], # socket level timeout - ["oracle.net.READ_TIMEOUT", "2000"], # socket level timeout - ["oracle.jdbc.ReadTimeout", "8000"] # query fetch timeout - ] + return None # - # Private implementation + # Public interface # - def _is_jdbc_driver_installed(self, properties): - return LinuxDBMSConfig._find_jdbc_driver("*ojdbc*.jar") - - def _configure_database_name(self): - if self.persistence_type != 'local': - # Oracle uses service name or service id - idType = "1" - idType = get_validated_string_input( - "Select Oracle identifier type:\n1 - " + ORACLE_DB_ID_TYPES[0] + - "\n2 - " + ORACLE_DB_ID_TYPES[1] + "\n(" + idType + "): ", - idType, - "^[12]$", - "Invalid number.", - False - ) + def get_driver_name(self): + return self._driverName - if idType == "2": - self.sid_or_sname = "sid" + def get_connection_string(self): + return self._connectionString - IDTYPE_INDEX = int(idType) - 1 - self.database_name = OracleConfig._get_validated_service_name(self.database_name, - IDTYPE_INDEX) + def connect(self, args): + if args.persistence_type == "local": + return self.check_postgre_up() else: - self.database_name = LinuxDBMSConfig._get_validated_db_name(self.database_storage_name, self.database_name) + return 0 - return True + def get_running_status(self): + """Return postgre running status indicator""" + if OS_TYPE == OSConst.OS_UBUNTU: + return "%s/main" % PGDatabase.get_ubuntu_db_version() + else: + return DB_STATUS_RUNNING_DEFAULT @staticmethod - def _get_validated_service_name(service_name, index): - return get_validated_string_input( - ORACLE_DB_ID_TYPES[index] + " (" + service_name + "): ", - service_name, - ".*", - "Invalid " + ORACLE_DB_ID_TYPES[index] + ".", - False - ) + def get_hba_dir(): + """Return postgre hba dir location depends on OS""" + if OS_TYPE == OSConst.OS_UBUNTU: + return "%s/%s/main" % (UBUNTU_PG_HBA_ROOT, PGDatabase.get_ubuntu_db_version()) + else: + return PG_HBA_ROOT_DEFAULT -def createOracleConfig(options, properties, storage_type, dbId): - return OracleConfig(options, properties, storage_type) + @staticmethod + def get_ubuntu_db_version(): + """Return installed version of postgre server. In case of several + installed versions will be returned a more new one. + """ + postgre_ver = "" + if os.path.isdir(UBUNTU_PG_HBA_ROOT): # detect actual installed versions of PG and select a more new one + postgre_ver = sorted( + [fld for fld in os.listdir(UBUNTU_PG_HBA_ROOT) if os.path.isdir(os.path.join(UBUNTU_PG_HBA_ROOT, fld))], reverse=True) + if len(postgre_ver) > 0: + return postgre_ver[0] + return postgre_ver -class MySQLConfig(LinuxDBMSConfig): - def __init__(self, options, properties, storage_type): - super(MySQLConfig, self).__init__(options, properties, storage_type) - #Init the database configuration data here, if any - self.dbms = "mysql" - self.dbms_full_name = "MySQL" - self.driver_class_name = "com.mysql.jdbc.Driver" - self.driver_file_name = "mysql-connector-java.jar" + def restart_postgres(): + print "Restarting PostgreSQL" + process = subprocess.Popen(PG_RESTART_CMD.split(' '), + stdout=subprocess.PIPE, + stdin=subprocess.PIPE, + stderr=subprocess.PIPE + ) + time.sleep(5) + result = process.poll() + if result is None: + print_info_msg("Killing restart PostgresSQL process") + process.kill() + pg_status = get_postgre_status() + # SUSE linux set status of stopped postgresql proc to unused + if pg_status == "unused" or pg_status == "stopped": + print_info_msg("PostgreSQL is stopped. Restarting ...") + retcode, out, err = run_os_command(PG_START_CMD) + return retcode + return 0 - self.database_storage_name = "Database" - self.database_port = DBMSConfig._init_member_with_prop_default(options, "database_port", - properties, JDBC_PORT_PROPERTY, "3306") + def execute_db_script(self, args, file): + #password access to ambari-server and mapred + configure_database_username_password(args) + dbname = args.database_name + username = args.database_username + password = args.database_password + command = SETUP_DB_CMD[:] + command[-1] = command[-1].format(file, username, password, dbname) + retcode, outdata, errdata = run_os_command(command) + if not retcode == 0: + print errdata + return retcode + + def execute_remote_script(self, args, scriptPath): + print_warning_msg("Deprecated method called.") + tool = get_db_cli_tool(args) + if not tool: + # args.warnings.append('{0} not found. Please, run DDL script manually'.format(DATABASE_CLI_TOOLS[DATABASE_INDEX])) + if VERBOSE: + print_warning_msg('{0} not found'.format(DATABASE_CLI_TOOLS[DATABASE_INDEX])) + return -1, "Client wasn't found", "Client wasn't found" + + os.environ["PGPASSWORD"] = args.database_password + retcode, out, err = run_in_shell('{0} {1}'.format(tool, POSTGRES_EXEC_ARGS.format( + args.database_host, + args.database_port, + args.database_name, + args.database_username, + scriptPath + ))) + return retcode, out, err + + def check_db_consistency(args, file): + #password access to ambari-server and mapred + configure_database_username_password(args) + dbname = args.database_name + username = args.database_username + password = args.database_password + command = SETUP_DB_CMD[:] + command[-1] = command[-1].format(file, username, password, dbname) + retcode, outdata, errdata = run_os_command(command) + if not retcode == 0: + print errdata + return retcode + else: + # Assumes that the output is of the form ...\n<count> + print_info_msg("Parsing output: " + outdata) + lines = outdata.splitlines() + if (lines[-1] == '3' or lines[-1] == '0'): + return 0 + return -1 - self.database_url_pattern = "jdbc:mysql://{0}:{1}/{2}" - self.database_url_pattern_alt = "jdbc:mysql://{0}:{1}/{2}" - self.JDBC_DRIVER_INSTALL_MSG = 'Before starting Ambari Server, ' \ - 'you must copy the {0} JDBC driver JAR file to {1}.'.format( - self.dbms_full_name, configDefaults.JAVA_SHARE_PATH) + def get_postgre_status(): + retcode, out, err = run_os_command(PG_ST_CMD) + try: + pg_status = re.search('(stopped|running)', out, re.IGNORECASE).group(0).lower() + except AttributeError: + pg_status = None + return pg_status - self.init_script_file = "/var/lib/ambari-server/resources/Ambari-DDL-MySQL-CREATE.sql" - self.drop_tables_script_file = "/var/lib/ambari-server/resources/Ambari-DDL-MySQL-DROP.sql" - self.client_tool_usage_pattern = 'mysql --user={1} --password={2} {3}<{0}' - # - # Private implementation - # - def _is_jdbc_driver_installed(self, properties): - return LinuxDBMSConfig._find_jdbc_driver("*mysql*.jar") + def check_postgre_up(): + pg_status = get_postgre_status() + if pg_status == PG_STATUS_RUNNING: + print_info_msg("PostgreSQL is running") + return 0 + else: + # run initdb only on non ubuntu systems as ubuntu does not have initdb cmd. + if OS_TYPE != OSConst.OS_UBUNTU: + print "Running initdb: This may take upto a minute." + retcode, out, err = run_os_command(PG_INITDB_CMD) + if retcode == 0: + print out + print "About to start PostgreSQL" + try: + process = subprocess.Popen(PG_START_CMD.split(' '), + stdout=subprocess.PIPE, + stdin=subprocess.PIPE, + stderr=subprocess.PIPE + ) + if OS_TYPE == OSConst.OS_SUSE: + time.sleep(20) + result = process.poll() + print_info_msg("Result of postgres start cmd: " + str(result)) + if result is None: + process.kill() + pg_status = get_postgre_status() + else: + retcode = result + else: + out, err = process.communicate() + retcode = process.returncode + if pg_status == PG_STATUS_RUNNING: + print_info_msg("Postgres process is running. Returning...") + return 0 + except (Exception), e: + pg_status = get_postgre_status() + if pg_status == PG_STATUS_RUNNING: + return 0 + else: + print_error_msg("Postgres start failed. " + str(e)) + return 1 + return retcode - def _configure_database_name(self): - self.database_name = LinuxDBMSConfig._get_validated_db_name(self.database_storage_name, self.database_name) - return True -def createMySQLConfig(options, properties, storage_type, dbId): - return MySQLConfig(options, properties, storage_type) + def get_validated_db_name(database_name): + return get_validated_string_input( + DATABASE_STORAGE_NAMES[DATABASE_INDEX] + " Name (" + + database_name + "): ", + database_name, + ".*", + "Invalid " + DATABASE_STORAGE_NAMES[DATABASE_INDEX] + " name.", + False + ) + + + def get_validated_service_name(service_name, index): + return get_validated_string_input( + ORACLE_DB_ID_TYPES[index] + " (" + service_name + "): ", + service_name, + ".*", + "Invalid " + ORACLE_DB_ID_TYPES[index] + ".", + False + )
http://git-wip-us.apache.org/repos/asf/ambari/blob/fad56746/ambari-server/src/main/python/ambari_server/dbConfiguration_windows.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/python/ambari_server/dbConfiguration_windows.py b/ambari-server/src/main/python/ambari_server/dbConfiguration_windows.py index ed986cb..647a940 100644 --- a/ambari-server/src/main/python/ambari_server/dbConfiguration_windows.py +++ b/ambari-server/src/main/python/ambari_server/dbConfiguration_windows.py @@ -18,59 +18,71 @@ See the License for the specific language governing permissions and limitations under the License. ''' -import os import socket import string -from ambari_commons.exceptions import FatalException -from ambari_commons.logging_utils import print_warning_msg, print_info_msg -from ambari_commons.os_utils import search_file, run_os_command -from ambari_commons.os_windows import WinServiceController, os_run_os_command +import win32api + +from ambari_commons.exceptions import * +from ambari_commons.logging_utils import print_warning_msg +from ambari_commons.os_utils import search_file +from ambari_commons.os_windows import * from ambari_commons.str_utils import compress_backslashes, ensure_double_backslashes -from ambari_server.dbConfiguration import AMBARI_DATABASE_NAME, DBMSConfig, DbPropKeys, DbAuthenticationKeys -from ambari_server.serverConfiguration import get_value_from_properties, configDefaults, \ - JDBC_DATABASE_PROPERTY, JDBC_DATABASE_NAME_PROPERTY, JDBC_RCA_SCHEMA_PROPERTY, \ - JDBC_HOSTNAME_PROPERTY, JDBC_PORT_PROPERTY, \ - JDBC_USE_INTEGRATED_AUTH_PROPERTY, JDBC_USER_NAME_PROPERTY, JDBC_PASSWORD_PROPERTY, JDBC_PASSWORD_FILENAME, \ - JDBC_DRIVER_PROPERTY, JDBC_URL_PROPERTY, \ - JDBC_RCA_HOSTNAME_PROPERTY, JDBC_RCA_PORT_PROPERTY, \ - JDBC_RCA_USE_INTEGRATED_AUTH_PROPERTY, JDBC_RCA_USER_NAME_PROPERTY, JDBC_RCA_PASSWORD_ALIAS, JDBC_RCA_PASSWORD_FILE_PROPERTY, \ - JDBC_RCA_DRIVER_PROPERTY, JDBC_RCA_URL_PROPERTY, \ - JDBC_DRIVER_PATH_PROPERTY, \ - JDBC_METRICS_DATABASE_PROPERTY, JDBC_METRICS_SCHEMA_PROPERTY, JDBC_METRICS_HOSTNAME_PROPERTY, JDBC_METRICS_PORT_PROPERTY, \ - JDBC_METRICS_DRIVER_PROPERTY, JDBC_METRICS_URL_PROPERTY, \ - JDBC_METRICS_USE_INTEGRATED_AUTH_PROPERTY, JDBC_METRICS_USER_NAME_PROPERTY, JDBC_METRICS_PASSWORD_PROPERTY, \ - JDBC_METRICS_PASSWORD_ALIAS, JDBC_METRICS_PASSWORD_FILENAME, \ - PERSISTENCE_TYPE_PROPERTY, METRICS_PERSISTENCE_TYPE_PROPERTY -from ambari_server.setupSecurity import encrypt_password, store_password_file -from ambari_server.userInput import get_validated_string_input +from ambari_server.setupSecurity import SECURITY_IS_ENCRYPTION_ENABLED, encrypt_password, store_password_file +from serverConfiguration import * +from dbConfiguration import * +from userInput import get_validated_string_input +#Import the SQL Server libraries # SQL Server settings -DATABASE_DBMS_SQLSERVER = "sqlserver" -DATABASE_DRIVER_NAME_SQLSERVER = "com.microsoft.sqlserver.jdbc.SQLServerDriver" -DATABASE_SERVER_SQLSERVER_DEFAULT = "localhost\\SQLEXPRESS" +DBPATH = 'C:\\Program Files\\Microsoft SQL Server\\MSSQL12.SQLEXPRESS\\MSSQL\\DATA\\' +# DBPATH = 'C:\\Program Files\\Microsoft SQL Server\\MSSQL10_50.MSSQLSERVER\\MSSQL\\DATA\\' + +DATABASE_DBMS = "sqlserver" +DATABASE_DRIVER_NAME = "com.microsoft.sqlserver.jdbc.SQLServerDriver" +LOCAL_DATABASE_SERVER = "localhost\\SQLEXPRESS" +AMBARI_DATABASE_NAME = "ambari" METRICS_DATABASE_NAME = "HadoopMetrics" -class SqlServerAuthenticationKeys(DbAuthenticationKeys): + +class DbPropKeys: + def __init__(self, i_dbms_key, i_driver_key, i_server_key, i_port_key, i_db_name_key, i_db_url_key): + self.reset(i_dbms_key, i_driver_key, i_server_key, i_port_key, i_db_name_key, i_db_url_key) + pass + + def reset(self, i_dbms_key, i_driver_key, i_server_key, i_port_key, i_db_name_key, i_db_url_key): + self.dbms_key = i_dbms_key + self.driver_key = i_driver_key + self.server_key = i_server_key + self.port_key = i_port_key + self.db_name_key = i_db_name_key + self.db_url_key = i_db_url_key + pass + +class AuthenticationKeys: def __init__(self, i_integrated_auth_key, i_user_name_key, i_password_key, i_password_alias, i_password_filename): + self.reset(i_integrated_auth_key, i_user_name_key, i_password_key, i_password_alias, i_password_filename) + pass + + def reset(self, i_integrated_auth_key, i_user_name_key, i_password_key, i_password_alias, i_password_filename): self.integrated_auth_key = i_integrated_auth_key - DbAuthenticationKeys.__init__(self, i_user_name_key, i_password_key, i_password_alias, i_password_filename) + self.user_name_key = i_user_name_key + self.password_key = i_password_key + self.password_alias = i_password_alias + self.password_filename = i_password_filename + pass -# # SQL Server configuration and setup -# class SQLServerConfig(DBMSConfig): - def __init__(self, options, properties, storage_type): - super(SQLServerConfig, self).__init__(options, properties, storage_type) + def __init__(self, options, properties): + super(SQLServerConfig, self).__init__(options, properties) """ #Just load the defaults. The derived classes will be able to modify them later """ - self.dbms = DATABASE_DBMS_SQLSERVER - self.driver_class_name = DATABASE_DRIVER_NAME_SQLSERVER - - self.JDBC_DRIVER_INSTALL_MSG = 'Before starting Ambari Server, you must install the SQL Server JDBC driver.' + self.dbms = DATABASE_DBMS + self.driver_name = DATABASE_DRIVER_NAME # The values from options supersede the values from properties self.database_host = options.database_host if options.database_host is not None and options.database_host is not "" else \ @@ -81,25 +93,27 @@ class SQLServerConfig(DBMSConfig): else: self.database_host = compress_backslashes(self.database_host) except: - self.database_host = DATABASE_SERVER_SQLSERVER_DEFAULT + self.database_host = "localhost\\SQLEXPRESS" pass - self.database_port = DBMSConfig._init_member_with_prop_default(options, "database_port", - properties, self.dbPropKeys.port_key, "1433") - self.database_name = DBMSConfig._init_member_with_prop_default(options, "database_name", - properties, self.dbPropKeys.db_name_key, configDefaults.DEFAULT_DB_NAME) + self.database_port = options.database_port if options.database_port is not None and options.database_port is not "" else \ + properties.get_property(self.dbPropKeys.port_key) + self.database_name = options.database_name if options.database_name is not None and options.database_name is not "" else \ + properties.get_property(self.dbPropKeys.db_name_key) self.use_windows_authentication = options.database_windows_auth if options.database_windows_auth is True else \ properties.get_property(self.dbAuthKeys.integrated_auth_key) - self.database_username = DBMSConfig._init_member_with_prop_default(options, "database_username", - properties, self.dbAuthKeys.user_name_key, "") + self.database_username = options.database_username if options.database_username is not None and options.database_username is not "" \ + else properties.get_property(self.dbAuthKeys.user_name_key) self.database_password = options.database_password if options.database_password is not None and options.database_password is not "" \ else "" - self.password_file = get_value_from_properties(properties, self.dbAuthKeys.password_key, None) + self.password_file = properties[self.dbAuthKeys.password_key] self.database_url = self._build_sql_server_connection_string() self.persistence_property = None + self.db_title = "" + self.env_var_db_name = "" self.env_var_db_log_name = "" self.env_var_db_owner = "" @@ -113,6 +127,40 @@ class SQLServerConfig(DBMSConfig): def _is_local_database(self): return False + def _is_jdbc_driver_installed(self, properties): + """ + #Attempt to load the sqljdbc4.jar and sqljdbc_auth.dll. This will automatically scan the PATH. + :param None + :rtype : bool + """ + paths = "." + os.pathsep + os.environ["PATH"] + + # Find the jar by attempting to load it as a resource dll + driver_path = search_file("sqljdbc4.jar", paths) + if not driver_path: + return 0 + + auth_dll_path = search_file("sqljdbc_auth.dll", paths) + if not auth_dll_path: + return 0 + + try: + driver_path = properties[JDBC_DRIVER_PATH_PROPERTY] + if driver_path is None or driver_path is "": + return 0 + except Exception: + # No such attribute set + return 0 + + return 1 + + def get_jdbc_driver_path(self): + paths = "." + os.pathsep + os.environ["PATH"] + + # Find the jar by attempting to load it as a resource dll + driver_path = search_file("sqljdbc4.jar", paths) + return driver_path + def configure_database_password(showDefault=True): #No password needed, using SQL Server integrated authentication pass @@ -123,7 +171,7 @@ class SQLServerConfig(DBMSConfig): return True #prompt for SQL Server host and instance name - hostname_prompt = "SQL Server host and instance for the {0} database: ({1}) ".format(self.db_title, self.database_host) + hostname_prompt = "SQL Server host and instance for the {} database: ({}) ".format(self.db_title, self.database_host) self.database_host = get_validated_string_input(hostname_prompt, self.database_host, None, None, False, True) #prompt for SQL Server authentication method @@ -135,7 +183,7 @@ class SQLServerConfig(DBMSConfig): user_prompt = \ "[1] - Use SQL Server integrated authentication\n[2] - Use username+password authentication\n" \ - "Enter choice ({0}): ".format(auth_option_default) + "Enter choice ({}): ".format(auth_option_default) auth_option = get_validated_string_input(user_prompt, auth_option_default, "^[12]$", @@ -148,12 +196,12 @@ class SQLServerConfig(DBMSConfig): else: self.use_windows_authentication = False - user_prompt = "SQL Server user name for the {0} database: ({1}) ".format(self.db_title, self.database_username) + user_prompt = "SQL Server user name for the {} database: ({}) ".format(self.db_title, self.database_username) username = get_validated_string_input(user_prompt, self.database_username, None, "User name", False, False) self.database_username = username - user_prompt = "SQL Server password for the {0} database: ".format(self.db_title) + user_prompt = "SQL Server password for the {} database: ".format(self.db_title) password = get_validated_string_input(user_prompt, "", None, "Password", True, False) self.database_password = password @@ -170,7 +218,7 @@ class SQLServerConfig(DBMSConfig): properties.process_pair(self.persistence_property, 'remote') properties.process_pair(self.dbPropKeys.dbms_key, self.dbms) - properties.process_pair(self.dbPropKeys.driver_key, self.driver_class_name) + properties.process_pair(self.dbPropKeys.driver_key, self.driver_name) properties.process_pair(self.dbPropKeys.server_key, ensure_double_backslashes(self.database_host)) if self.database_port is not None and self.database_port != "": properties.process_pair(self.dbPropKeys.port_key, self.database_port) @@ -182,46 +230,34 @@ class SQLServerConfig(DBMSConfig): pass def _setup_remote_database(self): - print 'Populating {0} database structure...'.format(self.db_title) + print 'Populating {} database structure...'.format(self.db_title) self._populate_database_structure() def _reset_remote_database(self): - print 'Resetting {0} database structure...'.format(self.db_title) + print 'Resetting {} database structure...'.format(self.db_title) self._populate_database_structure() - def _is_jdbc_driver_installed(self, properties): - """ - #Attempt to find the sqljdbc4.jar and sqljdbc_auth.dll by scanning the PATH. - :param None - :rtype : bool - """ - paths = "." + os.pathsep + os.environ["PATH"] + def _prompt_jdbc_driver_install(self, properties): + result = False + msg = 'Before starting Ambari Server, you must install the SQL Server JDBC driver.' - # Find the jar by attempting to load it as a resource dll - driver_path = search_file("sqljdbc4.jar", paths) - if not driver_path: - return 0 - - auth_dll_path = search_file("sqljdbc_auth.dll", paths) - if not auth_dll_path: - return 0 + if not self.silent: + print_warning_msg(msg) + raw_input(PRESS_ENTER_MSG) + result = self._is_jdbc_driver_installed(properties) + return (result, msg) + def _install_jdbc_driver(self, options, properties): try: driver_path = properties[JDBC_DRIVER_PATH_PROPERTY] - if driver_path is None or driver_path is "": - return 0 except Exception: # No such attribute set - return 0 + driver_path = None - return 1 - - def _install_jdbc_driver(self, properties, files_list): - driver_path = get_value_from_properties(properties, JDBC_DRIVER_PATH_PROPERTY, None) if driver_path is None or driver_path == "": - driver_path = self._get_jdbc_driver_path() + driver_path = self.get_jdbc_driver_path() properties.process_pair(JDBC_DRIVER_PATH_PROPERTY, driver_path) return True @@ -257,18 +293,11 @@ class SQLServerConfig(DBMSConfig): pass - def _get_jdbc_driver_path(self): - paths = "." + os.pathsep + os.environ["PATH"] - - # Find the jar by attempting to load it as a resource dll - driver_path = search_file("sqljdbc4.jar", paths) - return driver_path - def _build_sql_server_connection_string(self): - databaseUrl = "jdbc:sqlserver://{0}".format(ensure_double_backslashes(self.database_host)) + databaseUrl = "jdbc:sqlserver://{}".format(ensure_double_backslashes(self.database_host)) if self.database_port is not None and self.database_port != "": - databaseUrl += ":{0}".format(self.database_port) - databaseUrl += ";databaseName={0}".format(self.database_name) + databaseUrl += ":{}".format(self.database_port) + databaseUrl += ";databaseName={}".format(self.database_name) if(self.use_windows_authentication): databaseUrl += ";integratedSecurity=true" #No need to append the username and password, the Ambari server adds them by itself when connecting to the database @@ -306,28 +335,26 @@ class SQLServerConfig(DBMSConfig): @staticmethod def _execute_db_script(databaseHost, databaseScript): - dbCmd = 'sqlcmd -S {0} -i {1}'.format(databaseHost, databaseScript) + dbCmd = 'sqlcmd -S {} -i {}'.format(databaseHost, databaseScript) retCode, outData, errData = run_os_command(['cmd', '/C', dbCmd]) if not retCode == 0: - err = 'Running database create script failed. Error output: {0} Output: {1} Exiting.'.format(errData, outData) + err = 'Running database create script failed. Error output: {} Output: {} Exiting.'.format(errData, outData) raise FatalException(retCode, err) print_info_msg("sqlcmd output:") print_info_msg(outData) pass -# # SQL Server Ambari database configuration and setup -# class SQLServerAmbariDBConfig(SQLServerConfig): - def __init__(self, options, properties, storage_type): + def __init__(self, options, properties): self.dbPropKeys = DbPropKeys( JDBC_DATABASE_PROPERTY, JDBC_DRIVER_PROPERTY, JDBC_HOSTNAME_PROPERTY, JDBC_PORT_PROPERTY, - JDBC_DATABASE_NAME_PROPERTY, + JDBC_SCHEMA_PROPERTY, JDBC_URL_PROPERTY) - self.dbAuthKeys = SqlServerAuthenticationKeys( + self.dbAuthKeys = AuthenticationKeys( JDBC_USE_INTEGRATED_AUTH_PROPERTY, JDBC_USER_NAME_PROPERTY, JDBC_PASSWORD_PROPERTY, @@ -335,13 +362,15 @@ class SQLServerAmbariDBConfig(SQLServerConfig): JDBC_PASSWORD_FILENAME ) - super(SQLServerAmbariDBConfig, self).__init__(options, properties, storage_type) + super(SQLServerAmbariDBConfig, self).__init__(options, properties) if self.database_name is None or self.database_name is "": self.database_name = AMBARI_DATABASE_NAME self.persistence_property = PERSISTENCE_TYPE_PROPERTY + self.db_title = "ambari" + self.env_var_db_name ='AMBARIDBNAME' self.env_var_db_log_name = 'AMBARIDBLOGNAME' self.env_var_db_owner = 'AMBARIDBOWNER' @@ -360,13 +389,13 @@ class SQLServerAmbariDBConfig(SQLServerConfig): def _setup_remote_server(self, properties): super(SQLServerAmbariDBConfig, self)._setup_remote_server(properties) - properties.process_pair(JDBC_RCA_DRIVER_PROPERTY, self.driver_class_name) + properties.process_pair(JDBC_RCA_DRIVER_PROPERTY, self.driver_name) properties.process_pair(JDBC_RCA_HOSTNAME_PROPERTY, ensure_double_backslashes(self.database_host)) if self.database_port is not None and self.database_port != "": properties.process_pair(JDBC_RCA_PORT_PROPERTY, self.database_port) properties.process_pair(JDBC_RCA_SCHEMA_PROPERTY, self.database_name) - authKeys = SqlServerAuthenticationKeys( + authKeys = AuthenticationKeys( JDBC_RCA_USE_INTEGRATED_AUTH_PROPERTY, JDBC_RCA_USER_NAME_PROPERTY, JDBC_RCA_PASSWORD_FILE_PROPERTY, @@ -378,11 +407,10 @@ class SQLServerAmbariDBConfig(SQLServerConfig): properties.process_pair(JDBC_RCA_URL_PROPERTY, self.database_url) pass -# + # SQL Server Metrics database configuration and setup -# class SQLServerMetricsDBConfig(SQLServerConfig): - def __init__(self, options, properties, storage_type): + def __init__(self, options, properties): self.dbPropKeys = DbPropKeys( JDBC_METRICS_DATABASE_PROPERTY, JDBC_METRICS_DRIVER_PROPERTY, @@ -390,7 +418,7 @@ class SQLServerMetricsDBConfig(SQLServerConfig): JDBC_METRICS_PORT_PROPERTY, JDBC_METRICS_SCHEMA_PROPERTY, JDBC_METRICS_URL_PROPERTY) - self.dbAuthKeys = SqlServerAuthenticationKeys( + self.dbAuthKeys = AuthenticationKeys( JDBC_METRICS_USE_INTEGRATED_AUTH_PROPERTY, JDBC_METRICS_USER_NAME_PROPERTY, JDBC_METRICS_PASSWORD_PROPERTY, @@ -398,7 +426,7 @@ class SQLServerMetricsDBConfig(SQLServerConfig): JDBC_METRICS_PASSWORD_FILENAME ) - super(SQLServerMetricsDBConfig, self).__init__(options, properties, storage_type) + super(SQLServerMetricsDBConfig, self).__init__(options, properties) self.database_name = METRICS_DATABASE_NAME @@ -420,10 +448,14 @@ class SQLServerMetricsDBConfig(SQLServerConfig): self.drop_tables_script_file = "resources" + os.sep + "Hadoop-Metrics-SQLServer-DROP.sql" pass -def createSQLServerConfig(options, properties, storage_type, dbId): - if dbId == "Ambari": - return SQLServerAmbariDBConfig(options, properties, storage_type) - elif dbId == "Metrics": - return SQLServerMetricsDBConfig(options, properties, storage_type) - else: - raise FatalException(-1, "Invalid database requested: " + str(dbId)) + +# SQL Server database +class SQLServerDatabase: + def __init__(self): + #Init the database connection here + pass + + def get_running_status(self): + #if the connection is active, return running + #else return stopped + return DB_STATUS_RUNNING_DEFAULT http://git-wip-us.apache.org/repos/asf/ambari/blob/fad56746/ambari-server/src/main/python/ambari_server/properties.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/python/ambari_server/properties.py b/ambari-server/src/main/python/ambari_server/properties.py index ffdfe8d..8e00762 100644 --- a/ambari-server/src/main/python/ambari_server/properties.py +++ b/ambari-server/src/main/python/ambari_server/properties.py @@ -98,9 +98,6 @@ class Properties(object): self.process_pair(key, value) def process_pair(self, key, value): - """ - Adds or overrides the property with the given key. - """ oldkey = key oldvalue = value keyparts = self.bspacere.split(key) @@ -188,9 +185,7 @@ class Properties(object): def store(self, out, header=""): """ Write the properties list to the stream 'out' along - with the optional 'header' - This function will attempt to close the file handler once it's done. - """ + with the optional 'header' """ if out.mode[0] != 'w': raise ValueError, 'Steam should be opened in write mode!' try: @@ -203,11 +198,9 @@ class Properties(object): for prop, val in self._origprops.items(): if val is not None: out.write(''.join((prop, '=', val, '\n'))) + out.close() except IOError: raise - finally: - if out: - out.close() def store_ordered(self, out, header=""): """ Write the properties list to the stream 'out' along @@ -225,8 +218,6 @@ class Properties(object): val = self._origprops[key] if val is not None: out.write(''.join((key, '=', val, '\n'))) + out.close() except IOError: raise - finally: - if out: - out.close() http://git-wip-us.apache.org/repos/asf/ambari/blob/fad56746/ambari-server/src/main/python/ambari_server/resourceFilesKeeper.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/python/ambari_server/resourceFilesKeeper.py b/ambari-server/src/main/python/ambari_server/resourceFilesKeeper.py index 3589972..9d138a1 100644 --- a/ambari-server/src/main/python/ambari_server/resourceFilesKeeper.py +++ b/ambari-server/src/main/python/ambari_server/resourceFilesKeeper.py @@ -92,12 +92,12 @@ class ResourceFilesKeeper(): custom_actions_root = os.path.join(self.resources_dir,self.CUSTOM_ACTIONS_DIR) self.dbg_out("Updating archive for {0} dir at {1}...".format(self.CUSTOM_ACTIONS_DIR, custom_actions_root)) - + # agent host scripts host_scripts_root = os.path.join(self.resources_dir,self.HOST_SCRIPTS_DIR) self.dbg_out("Updating archive for {0} dir at {1}...".format(self.HOST_SCRIPTS_DIR, host_scripts_root)) - + # update the directories so that the .hash is generated self.update_directory_archive(custom_actions_root) self.update_directory_archive(host_scripts_root)
