def _create_summary_file(bundle_id, node_name, comment, bundle_path): # Create Summary File for Tar. summary_file_path = os.path.join(bundle_path, "summary.yaml") Log.info(f"Adding summary file at {summary_file_path}") summary_data = { const.SB_BUNDLE_ID: str(bundle_id), const.SB_NODE_NAME: str(node_name), const.SB_COMMENT: repr(comment), "Generated Time": str(datetime.isoformat(datetime.now())) } try: Yaml(summary_file_path).dump(summary_data) except PermissionError as e: ComponentsBundle._publish_log( f"Permission denied for creating summary file {e}", ERROR, bundle_id, node_name, comment) return None except Exception as e: ComponentsBundle._publish_log(f"{e}", ERROR, bundle_id, node_name, comment) return None Log.debug('Summary file created')
def _create_summary_file(bundle_id, node_name, comment, bundle_path): # Create Summary File for Tar. summary_file_path = os.path.join(bundle_path, 'summary.yaml') Log.info(f"Adding summary file at {summary_file_path}") summary_data = { const.SB_BUNDLE_ID: str(bundle_id), const.SB_NODE_NAME: str(node_name), const.SB_COMMENT: repr(comment), "Generated Time": str(datetime.isoformat(datetime.now())) } try: Yaml(summary_file_path).dump(summary_data) except PermissionError as e: Log.error(f"Permission denied for creating " \ f"summary file {e}") Log.error(f"Permission denied for creating " \ f"summary file {e}", ERROR, bundle_id, node_name, comment) except Exception as e: Log.error(f"Permission denied for creating " \ f"summary file {e}") Log.error(f'{e}', ERROR, bundle_id, node_name, \ comment) Log.debug("Summary file created")
async def init(command: List): """ Initializes the Process of Support Bundle Generation for Every Component. :param command: Csm_cli Command Object :type: command :return: """ # Fetch Command Arguments. Log.init("support_bundle", syslog_server="localhost", syslog_port=514, log_path=Conf.get("cortx_conf", "support>support_bundle_path"), level="INFO") bundle_id = command.options.get(const.SB_BUNDLE_ID, "") node_name = command.options.get(const.SB_NODE_NAME, "") comment = command.options.get(const.SB_COMMENT, "") components = command.options.get(const.SB_COMPONENTS, []) Log.debug(( f"{const.SB_BUNDLE_ID}: {bundle_id}, {const.SB_NODE_NAME}: {node_name}, " f" {const.SB_COMMENT}: {comment}, {const.SB_COMPONENTS}: {components}," f" {const.SOS_COMP}")) # Read Commands.Yaml and Check's If It Exists. cmd_setup_file = os.path.join(Conf.get("cortx_conf", "install_path"), "cortx/utils/conf/support_bundle.yaml") support_bundle_config = Yaml(cmd_setup_file).load() if not support_bundle_config: ComponentsBundle._publish_log(f"No such file {cmd_setup_file}", ERROR, bundle_id, node_name, comment) return None # Path Location for creating Support Bundle. path = os.path.join( Conf.get("cortx_conf", "support>support_bundle_path")) if os.path.isdir(path): try: shutil.rmtree(path) except PermissionError: Log.warn(f"Incorrect permissions for path:{path}") bundle_path = os.path.join(path, bundle_id) os.makedirs(bundle_path) # Start Execution for each Component Command. threads = [] command_files_info = support_bundle_config.get("COMPONENTS") # OS Logs are specifically generated hence here Even When All is Selected O.S. Logs Will Be Skipped. if components: if "all" not in components: components_list = list( set(command_files_info.keys()).intersection( set(components))) else: components_list = list(command_files_info.keys()) components_list.remove(const.SOS_COMP) Log.debug( f"Generating for {const.SB_COMPONENTS} {' '.join(components_list)}" ) for each_component in components_list: components_commands = [] components_files = command_files_info[each_component] for file_path in components_files: file_data = Yaml(file_path).load() if file_data: components_commands = file_data.get( const.SUPPORT_BUNDLE.lower(), []) if components_commands: thread_obj = threading.Thread( ComponentsBundle._exc_components_cmd( components_commands, bundle_id, f"{bundle_path}{os.sep}", each_component, node_name, comment)) thread_obj.start() Log.debug( f"Started thread -> {thread_obj.ident} Component -> {each_component}" ) threads.append(thread_obj) directory_path = Conf.get("cortx_conf", "support>support_bundle_path") tar_file_name = os.path.join(directory_path, f"{bundle_id}_{node_name}.tar.gz") ComponentsBundle._create_summary_file(bundle_id, node_name, comment, bundle_path) symlink_path = const.SYMLINK_PATH if os.path.exists(symlink_path): try: shutil.rmtree(symlink_path) except PermissionError: Log.warn(const.PERMISSION_ERROR_MSG.format(path=symlink_path)) os.makedirs(symlink_path, exist_ok=True) # Wait Until all the Threads Execution is not Complete. for each_thread in threads: Log.debug( f"Waiting for thread - {each_thread.ident} to complete process" ) each_thread.join(timeout=1800) try: Log.debug( f"Generating tar.gz file on path {tar_file_name} from {bundle_path}" ) Tar(tar_file_name).dump([bundle_path]) except Exception as e: ComponentsBundle._publish_log(f"Could not generate tar file {e}", ERROR, bundle_id, node_name, comment) return None try: Log.debug("Create soft-link for generated tar.") os.symlink( tar_file_name, os.path.join(symlink_path, f"{const.SUPPORT_BUNDLE}.{bundle_id}")) ComponentsBundle._publish_log( f"Tar file linked at location - {symlink_path}", INFO, bundle_id, node_name, comment) except Exception as e: ComponentsBundle._publish_log(f"Linking failed {e}", ERROR, bundle_id, node_name, comment) finally: if os.path.isdir(bundle_path): shutil.rmtree(bundle_path) msg = "Support bundle generation completed." ComponentsBundle._publish_log(msg, INFO, bundle_id, node_name, comment)
async def init(bundle_obj, node_id, config_url, **kwargs): """ Initializes the Process of Support Bundle Generation for Every Component. command: cli Command Object :type: command return: None """ cluster_conf = MappedConf(config_url) log_path = os.path.join(cluster_conf.get(CLUSTER_CONF_LOG_KEY), \ f'utils/{Conf.machine_id}/support') log_level = cluster_conf.get('utils>log_level', 'INFO') Log.init('support_bundle_node', log_path, level=log_level, \ backup_count=5, file_size_in_mb=5) bundle_id = bundle_obj.bundle_id node_name = bundle_obj.node_name comment = bundle_obj.comment components_list = bundle_obj.components services_dict = bundle_obj.services Log.info(f"components:{components_list}") bundle_path = bundle_obj.bundle_path duration = kwargs.get('duration') size_limit = kwargs.get('size_limit') binlogs = kwargs.get('binlogs') coredumps = kwargs.get('coredumps') stacktrace = kwargs.get('stacktrace') Log.debug((f"{const.SB_BUNDLE_ID}: {bundle_id}, {const.SB_NODE_NAME}: " f"{node_name}, {const.SB_COMMENT}: {comment}, " f"{const.SB_COMPONENTS}: {components_list}, {const.SOS_COMP}")) # Read support_bundle.Yaml and Check's If It Exists. cmd_setup_file = os.path.join( cluster_conf.get('install_path', DEFAULT_INSTALL_PATH), const.SUPPORT_YAML) try: support_bundle_config = Yaml(cmd_setup_file).load() except Exception as e: Log.error(f"Internal error while parsing YAML file {cmd_setup_file}{e}") if not support_bundle_config: Log.error(f"No such file {cmd_setup_file}. ERROR:{ERROR}") # Start Execution for each Component Command. command_files_info = support_bundle_config.get('COMPONENTS') # OS Logs are specifically generated hence here Even # When All is Selected O.S. Logs Will Be Skipped. for each_component in components_list: services = services_dict[each_component] components_commands = [] components_files = command_files_info[each_component] for file_path in components_files: if not os.path.exists(file_path): Log.error(f"'{file_path}' file does not exist!") continue try: file_data = Yaml(file_path).load() except Exception as e: Log.error(f"Internal error while parsing YAML file {file_path}{e}") file_data = None break if file_data: components_commands = file_data.get( const.SUPPORT_BUNDLE.lower(), []) else: Log.error(f"Support.yaml file is empty: {file_path}") break if components_commands: component, return_code = await(\ ComponentsBundle._exc_components_cmd(\ components_commands, f'{bundle_id}_{node_id}_{each_component}', f'{bundle_path}{os.sep}', each_component, node_name, comment, config_url, services, binlogs, coredumps, stacktrace, duration, size_limit)) if return_code != 0: Log.error( f"Bundle generation failed for component - '{component}'") else: Log.info( f"Bundle generation started for component - '{component}'") tar_file_name = os.path.join(bundle_path, \ f'{bundle_id}_{node_id}.tar.gz') ComponentsBundle._create_summary_file(bundle_id, node_name, \ comment, bundle_path) try: Log.debug(f"Generating tar.gz file on path {tar_file_name} " f"from {bundle_path}") Tar(tar_file_name).dump([bundle_path]) bundle_status = f"Successfully generated SB at path:{bundle_path}" except Exception as e: bundle_status = f"Failed to generate tar file. ERROR:{e}" Log.error(f"Could not generate tar file {e}") finally: if os.path.exists(bundle_path): for each_dir in os.listdir(bundle_path): comp_dir = os.path.join(bundle_path, each_dir) if os.path.isdir(comp_dir): shutil.rmtree(comp_dir) if os.path.exists(os.path.join(bundle_path, 'summary.yaml')): os.remove(os.path.join(bundle_path, 'summary.yaml')) Log.info("Support bundle generation completed.") # Update Status in ConfStor Conf.load(const.SB_INDEX, 'json://' + const.FILESTORE_PATH, fail_reload=False) Conf.set(const.SB_INDEX, f'{node_id}>{bundle_id}>status', bundle_status) Conf.save(const.SB_INDEX)
async def init(command: List): """ Initializes the Process of Support Bundle Generation for Every Component. command: cli Command Object :type: command return: None """ bundle_id = command.options.get(const.SB_BUNDLE_ID, '') node_name = command.options.get(const.SB_NODE_NAME, '') comment = command.options.get(const.SB_COMMENT, '') components = command.options.get(const.SB_COMPONENTS, []) Log.debug((f"{const.SB_BUNDLE_ID}: {bundle_id}, {const.SB_NODE_NAME}: " f"{node_name}, {const.SB_COMMENT}: {comment}, " f"{const.SB_COMPONENTS}: {components}, {const.SOS_COMP}")) # Read Commands.Yaml and Check's If It Exists. Conf.load('cortx_conf', 'json:///etc/cortx/cortx.conf', \ skip_reload=True) cmd_setup_file = os.path.join(Conf.get('cortx_conf', 'install_path'),\ 'cortx/utils/conf/support_bundle.yaml') try: support_bundle_config = Yaml(cmd_setup_file).load() except Exception as e: Log.error( f"Internal error while parsing YAML file {cmd_setup_file}{e}") ComponentsBundle._publish_log(f"Internal error while parsing YAML file " \ f"{cmd_setup_file}{e}", ERROR, bundle_id, node_name, comment) if not support_bundle_config: ComponentsBundle._publish_log(f"No such file {cmd_setup_file}", \ ERROR, bundle_id, node_name, comment) # Shared/Local path Location for creating Support Bundle. from cortx.utils.shared_storage import Storage path = Storage.get_path('support_bundle') if not path: path = Conf.get('cortx_conf', 'support>local_path') bundle_path = os.path.join(path, bundle_id, node_name) try: os.makedirs(bundle_path, exist_ok=True) except PermissionError as e: Log.error(f"Incorrect permissions for path:{bundle_path} - {e}") ComponentsBundle._publish_log(f"Incorrect permissions for path: {bundle_path} - {e}", \ ERROR, bundle_id, node_name, comment) # Start Execution for each Component Command. threads = [] command_files_info = support_bundle_config.get('COMPONENTS') # OS Logs are specifically generated hence here Even # When All is Selected O.S. Logs Will Be Skipped. if components: if 'all' not in components: components_list = list(set(command_files_info.keys()\ ).intersection(set(components))) else: components_list = list(command_files_info.keys()) components_list.remove(const.SOS_COMP) Log.debug( f"Generating for manifest and {const.SB_COMPONENTS} {' '.join(components_list)}" ) thread_que = Queue() # Manifest component supportbundle generation try: thread_obj = threading.Thread( ManifestSupportBundle.generate(f'{bundle_id}_manifiest', f'{bundle_path}{os.sep}')) thread_obj.start() Log.debug(f"Started thread -> {thread_obj.ident} " \ f"Component -> manifest") threads.append(thread_obj) except Exception as e: Log.error(f"Internal error while calling ManifestSupportBundle"\ f" generate api {e}") ComponentsBundle._publish_log(f"Internal error at while bundling"\ f" Manifest component: {bundle_path} - {e}", ERROR, bundle_id, node_name, comment) for each_component in components_list: components_commands = [] components_files = command_files_info[each_component] for file_path in components_files: if not os.path.exists(file_path): ComponentsBundle._publish_log(f"'{file_path}' file does not exist!", \ ERROR, bundle_id, node_name, comment) continue try: file_data = Yaml(file_path).load() except Exception as e: Log.error( f"Internal error while parsing YAML file {file_path}{e}" ) file_data = None ComponentsBundle._publish_log(f"Internal error while parsing YAML file: " \ f"{file_path} - {e}", ERROR, bundle_id, node_name, comment) break if file_data: components_commands = file_data.get( const.SUPPORT_BUNDLE.lower(), []) else: ComponentsBundle._publish_log(f"Support.yaml file is empty: " \ f"{file_path}", ERROR, bundle_id, node_name, comment) break if components_commands: thread_obj = threading.Thread(\ ComponentsBundle._exc_components_cmd(\ components_commands, f'{bundle_id}_{each_component}', f'{bundle_path}{os.sep}', each_component, node_name, comment, thread_que)) thread_obj.start() Log.debug(f"Started thread -> {thread_obj.ident} " \ f"Component -> {each_component}") threads.append(thread_obj) # directory_path = Conf.get('cortx_conf', 'support') tar_file_name = os.path.join(bundle_path, \ f'{bundle_id}_{node_name}.tar.gz') ComponentsBundle._create_summary_file(bundle_id, node_name, \ comment, bundle_path) # Wait Until all the Threads Execution is not Complete. for each_thread in threads: Log.debug( f"Waiting for thread - {each_thread.ident} to complete process" ) each_thread.join(timeout=1800) if not thread_que.empty(): component, return_code = thread_que.get() if return_code != 0: ComponentsBundle._publish_log( f"Bundle generation failed for component - '{component}'", ERROR, bundle_id, node_name, comment) else: ComponentsBundle._publish_log( f"Bundle generation started for component - '{component}'", INFO, bundle_id, node_name, comment) try: Log.debug(f"Generating tar.gz file on path {tar_file_name} " f"from {bundle_path}") Tar(tar_file_name).dump([bundle_path]) except Exception as e: ComponentsBundle._publish_log(f"Could not generate tar file {e}", \ ERROR, bundle_id, node_name, comment) finally: if os.path.exists(bundle_path): for each_dir in os.listdir(bundle_path): comp_dir = os.path.join(bundle_path, each_dir) if os.path.isdir(comp_dir): shutil.rmtree(comp_dir) msg = "Support bundle generation completed." ComponentsBundle._publish_log(msg, INFO, bundle_id, node_name, comment)