Beispiel #1
0
 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')
Beispiel #2
0
 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")
Beispiel #3
0
    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)
Beispiel #4
0
    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)
Beispiel #5
0
    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)