def _remove_old_files(cwd, root_user, password, remote_host): """ Remove old files from SAP installation cwd folder. Only start_dir.cd must remain """ # TODO: check start_dir.cd exists remove_files_cmd = "printf '%q ' {}/*".format(cwd) remove_files = shell.execute_cmd( remove_files_cmd, root_user, password, remote_host) remove_files = remove_files.output.replace('{}/start_dir.cd'.format(cwd), '') cmd = 'rm -rf {}'.format(remove_files) shell.execute_cmd(cmd, root_user, password, remote_host)
def install( cls, software_path, conf_file, root_user, password, hdb_pwd_file=None, remote_host=None): """ Install SAP HANA platform providing a configuration file Args: software_path (str): Path where SAP HANA software is downloaded conf_file (str): Path to the configuration file root_user (str): Root user name password (str): Root user password hdb_pwd_file (str, opt): Path to the XML password file remote_host (str, opt): Remote host where the command will be executed """ # TODO: mount partition if needed # TODO: do some integrity check stuff if not os.path.isfile(conf_file): raise FileDoesNotExistError( 'The configuration file \'{}\' does not exist'.format(conf_file)) if hdb_pwd_file is not None and not os.path.isfile(hdb_pwd_file): raise FileDoesNotExistError( 'The XML password file \'{}\' does not exist'.format(hdb_pwd_file)) executable = cls.find_hana_hdblcm(software_path) if hdb_pwd_file: cmd = 'cat {hdb_pwd_file} | {executable} -b '\ '--read_password_from_stdin=xml --configfile={conf_file}'.format( hdb_pwd_file=hdb_pwd_file, executable=executable, conf_file=conf_file) else: cmd = '{executable} -b --configfile={conf_file}'.format( executable=executable, conf_file=conf_file) result = shell.execute_cmd(cmd, root_user, password, remote_host) if result.returncode: raise HanaError('SAP HANA installation failed')
def test_execute_cmd_user(self, logger, mock_popen, mock_process, mock_format): mock_format.return_value = 'updated command' mock_popen_inst = mock.Mock() mock_popen_inst.returncode = 5 mock_popen_inst.communicate.return_value = (b'out', b'err') mock_popen.return_value = mock_popen_inst mock_process_inst = mock.Mock() mock_process.return_value = mock_process_inst result = shell.execute_cmd('ls -la', 'test', 'pass') logger.assert_has_calls([ mock.call('Executing command "%s" with user %s', 'ls -la', 'test'), mock.call('Command updated to "%s"', 'updated command') ]) mock_popen.assert_called_once_with(['updated', 'command'], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) mock_popen_inst.communicate.assert_called_once_with(input=b'pass') mock_process.assert_called_once_with('updated command', 5, b'out', b'err') self.assertEqual(mock_process_inst, result)
def test_execute_cmd(self, logger, mock_popen, mock_process): mock_popen_inst = mock.Mock() mock_popen_inst.returncode = 5 mock_popen_inst.communicate.return_value = (b'out', b'err') mock_popen.return_value = mock_popen_inst mock_process_inst = mock.Mock() mock_process.return_value = mock_process_inst result = shell.execute_cmd('ls -la') logger.assert_called_once_with('Executing command "%s" with user %s', 'ls -la', None) mock_popen.assert_called_once_with(['ls', '-la'], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) mock_popen_inst.communicate.assert_called_once_with(input=None) mock_process.assert_called_once_with('ls -la', 5, b'out', b'err') self.assertEqual(mock_process_inst, result)
def install(cls, software_path, virtual_host, product_id, conf_file, root_user, password, **kwargs): """ Install SAP Netweaver instance Args: software_path (str): Path where SAP Netweaver 'sapinst' tool is located virtual_host (str): Virtual host name of the machine product_id (str): SAP instance product id conf_file (str): Path to the configuration file root_user (str): Root user name password (str): Root user password exception (bool, opt): Raise and exception in case of error if True, return result object otherwise remote_host (str, opt): Remote host where the command will be executed """ raise_exception = kwargs.get('exception', True) remote_host = kwargs.get('remote_host', None) cmd = '{software_path}/sapinst SAPINST_USE_HOSTNAME={virtual_host} '\ 'SAPINST_EXECUTE_PRODUCT_ID={product_id} '\ 'SAPINST_SKIP_SUCCESSFULLY_FINISHED_DIALOG=true SAPINST_START_GUISERVER=false '\ 'SAPINST_INPUT_PARAMETERS_URL={conf_file}'.format( software_path=software_path, virtual_host=virtual_host, product_id=product_id, conf_file=conf_file) result = shell.execute_cmd(cmd, root_user, password, remote_host) if result.returncode and raise_exception: raise NetweaverError('SAP Netweaver installation failed') return result
def create_conf_file(cls, software_path, conf_file, root_user, root_password, remote_host=None): """ Create SAP HANA configuration file Args: software_path (str): Path where SAP HANA software is downloaded conf_file (str): Path where configuration file will be created root_user (str): Root user name root_password (str): Root user password remote_host (str, opt): Remote host where the command will be executed """ executable = cls.find_hana_hdblcm(software_path) cmd = '{executable} --action=install '\ '--dump_configfile_template={conf_file}'.format( executable=executable, conf_file=conf_file) result = shell.execute_cmd(cmd, root_user, root_password, remote_host) if result.returncode: raise HanaError('SAP HANA configuration file creation failed') return conf_file
def uninstall(self, root_user, password, installation_folder='/hana/shared'): """ Uninstall SAP HANA platform """ cmd = '{installation_folder}/{sid}/hdblcm/hdblcm '\ '--uninstall -b'.format( installation_folder=installation_folder, sid=self.sid.upper()) result = shell.execute_cmd(cmd, root_user, password, self.remote_host) if result.returncode: raise HanaError('SAP HANA uninstallation failed')
def is_running(self): """ Check if SAP HANA daemon is running Returns: bool: True if running, False otherwise """ cmd = 'pidof hdb.sap{sid}_HDB{inst}'.format(sid=self.sid.upper(), inst=self.inst) result = shell.execute_cmd(cmd) return not result.returncode
def is_installed(self): """ Check if SAP HANA is installed Returns: bool: True if installed, False otherwise """ user = self.HANAUSER.format(sid=self.sid) try: result = shell.execute_cmd('HDB info', user, self._password) return not result.returncode except EnvironmentError as err: #FileNotFoundError is not compatible with python2 self._logger.error(err) return False
def install( cls, software_path, virtual_host, product_id, conf_file, root_user, password, **kwargs): """ Install SAP Netweaver instance Args: software_path (str): Path where SAP Netweaver 'sapinst' tool is located virtual_host (str): Virtual host name of the machine product_id (str): SAP instance product id conf_file (str): Path to the configuration file root_user (str): Root user name password (str): Root user password cwd (str, opt): New value for SAPINST_CWD parameter CAUTION: All of the files stored in this path will be removed except the start_dir.cd. This folder only will contain temporary files about the installation. exception (bool, opt): Raise and exception in case of error if True, return result object otherwise remote_host (str, opt): Remote host where the command will be executed """ cwd = kwargs.get('cwd', None) raise_exception = kwargs.get('exception', True) remote_host = kwargs.get('remote_host', None) if cwd: # This operation must be done in order to avoid incorrect files usage cls._remove_old_files(cwd, root_user, password, remote_host) cmd = '{software_path}/sapinst SAPINST_USE_HOSTNAME={virtual_host} '\ 'SAPINST_EXECUTE_PRODUCT_ID={product_id} '\ 'SAPINST_SKIP_SUCCESSFULLY_FINISHED_DIALOG=true SAPINST_START_GUISERVER=false '\ 'SAPINST_INPUT_PARAMETERS_URL={conf_file}{cwd}'.format( software_path=software_path, virtual_host=virtual_host, product_id=product_id, conf_file=conf_file, cwd=' SAPINST_CWD={}'.format(cwd) if cwd else '') result = shell.execute_cmd(cmd, root_user, password, remote_host) if result.returncode and raise_exception: if cwd: raise NetweaverError( 'SAP Netweaver installation failed. Please check swpm installation logs'\ '(sapinst_dev.log and sapinst.log) located at {0} for further '\ 'information'.format(cwd)) else: raise NetweaverError( 'SAP Netweaver installation failed.'\ ' Please check swpm installation logs'\ '(sapinst_dev.log and sapinst.log) located at'\ ' /tmp/sapinst_instdir default folder for further information') return result
def install(cls, software_path, conf_file, root_user, password): """ Install SAP HANA platform providing a configuration file Args: software_path (str): Path where SAP HANA software is downloaded conf_file (str): Path to the configuration file root_user (str): Root user name password (str): Root user password """ # TODO: mount partition if needed # TODO: do some integrity check stuff executable = cls.INSTALL_EXEC.format(software_path=software_path) cmd = '{executable} -b --configfile={conf_file}'.format( executable=executable, conf_file=conf_file) result = shell.execute_cmd(cmd, root_user, password) if result.returncode: raise HanaError('SAP HANA installation failed')
def extract_sapcar_file(sapcar_exe, sar_file, **kwargs): """ Execute SAPCAR command to decompress a SAP CAR or SAR archive files. If user and password are provided it will be executed with this user. Args: sapcar_exe(str): Path to the SAPCAR executable sar_file (str): Path to the sar file to be extracted options (str, opt): Additional options to SAPCAR command output_dir (str, opt): Directory where archive will be extracted. It creates the dir if the path doesn't exist. If it's not set the current dir is used user (str, opt): User to execute the SAPCAR command password (str, opt): User password remote_host (str, opt): Remote host where the command will be executed """ if not os.path.isfile(sapcar_exe): raise FileDoesNotExistError( 'SAPCAR executable \'{}\' does not exist'.format(sapcar_exe)) if not os.path.isfile(sar_file): raise FileDoesNotExistError( 'The SAR file \'{}\' does not exist'.format(sar_file)) options = kwargs.get('options', None) output_dir = kwargs.get('output_dir', None) user = kwargs.get('user', None) password = kwargs.get('password', None) remote_host = kwargs.get('remote_host', None) output_dir_str = ' -R {}'.format(output_dir) if output_dir else '' options_str = ' {}'.format(options) if options else '' cmd = '{sapcar_exe} -xvf {sar_file}{options_str}{output_dir_str}'.format( sapcar_exe=sapcar_exe, sar_file=sar_file, options_str=options_str, output_dir_str=output_dir_str) result = shell.execute_cmd(cmd, user=user, password=password, remote_host=remote_host) if result.returncode: raise SapUtilsError('Error running SAPCAR command') return result
def _execute_sapcontrol(self, sapcontrol_function, **kwargs): """ Execute sapcontrol commands and return result Args: sapcontrol_function (str): sapcontrol function exception (boolean): Raise NetweaverError non-zero return code (default true) host (str, optional): Host where the command will be executed inst (str, optional): Use a different instance number user (str, optional): Define a different user for the command password (str, optional): The new user password Returns: ProcessResult: ProcessResult instance storing subprocess returncode, stdout and stderr """ exception = kwargs.get('exception', True) # The -host and -user parameters are used in sapcontrol to authorize commands execution # in remote host Netweaver instances host = kwargs.get('host', None) inst = kwargs.get('inst', self.inst) user = kwargs.get('user', None) password = kwargs.get('password', None) if user and not password: raise NetweaverError( 'Password must be provided together with user') host_str = '-host {} '.format(host) if host else '' user_str = '-user {} {} '.format(user, password) if user else '' user = self.NETWEAVER_USER.format(sid=self.sid) cmd = 'sapcontrol {host}{user}-nr {instance} -function {sapcontrol_function}'.format( host=host_str, user=user_str, instance=inst, sapcontrol_function=sapcontrol_function) result = shell.execute_cmd(cmd, user, self._password, self.remote_host) if exception and result.returncode != 0: raise NetweaverError('Error running sapcontrol command: {}'.format( result.cmd)) return result
def create_conf_file(cls, software_path, conf_file, root_user, root_password): """ Create SAP HANA configuration file Args: software_path (str): Path where SAP HANA software is downloaded conf_file (str): Path where configuration file will be created root_user (str): Root user name root_password (str): Root user password """ executable = cls.INSTALL_EXEC.format(software_path=software_path) cmd = '{executable} --action=install '\ '--dump_configfile_template={conf_file}'.format( executable=executable, conf_file=conf_file) result = shell.execute_cmd(cmd, root_user, root_password) if result.returncode: raise HanaError('SAP HANA configuration file creation failed') return conf_file
def _run_hana_command(self, cmd, exception=True): """ Run hana command Args: cmd (str): HANA command exception (boolean): Raise HanaError non-zero return code (default true) Returns: ProcessResult: ProcessResult instance storing subprocess returncode, stdout and stderr """ #TODO: Add absolute paths to hana commands using sid and inst number user = self.HANAUSER.format(sid=self.sid) result = shell.execute_cmd(cmd, user, self._password, self.remote_host) if exception and result.returncode != 0: raise HanaError('Error running hana command: {}'.format(result.cmd)) return result
def test_execute_cmd_popen(self): # This test is used to check popen correct usage result = shell.execute_cmd('ls -la') self.assertEqual(result.returncode, 0)