Ejemplo n.º 1
0
Archivo: env.py Proyecto: vvidic/pcs
 def get_corosync_conf(self) -> CorosyncConfigFacade:
     # TODO The architecture of working with corosync.conf needs to be
     # overhauled to match the new file framework. The code below is
     # complicated, because we read corosync.conf data at one place outside
     # of the file framework or get it from outside (from CLI) and then we
     # put them back into the framework.
     corosync_instance = FileInstance.for_corosync_conf()
     try:
         facade = cast(
             CorosyncConfigFacade,
             corosync_instance.raw_to_facade(
                 self.get_corosync_conf_data().encode("utf-8")),
         )
     except ParserErrorException as e:
         if self.report_processor.report_list(
                 corosync_instance.toolbox.parser.exception_to_report_list(
                     e,
                     corosync_instance.toolbox.file_type_code,
                     (corosync_instance.raw_file.metadata.path
                      if self.is_corosync_conf_live else None),
                     force_code=None,
                     is_forced_or_warning=False,
                 )).has_errors:
             raise LibraryError() from e
     return facade
Ejemplo n.º 2
0
def get_local_corosync_conf():
    """
    Read corosync.conf file from local machine
    """
    # TODO The architecture of working with corosync.conf needs to be
    # overhauled to match the new file framework.
    instance = FileInstance.for_corosync_conf()
    try:
        return instance.read_raw().decode("utf-8")
    except RawFileError as e:
        raise LibraryError(raw_file_error_report(e)) from e
Ejemplo n.º 3
0
def set_recovery_site(env: LibraryEnvironment, node_name: str) -> None:
    """
    Set up disaster recovery with the local cluster being the primary site

    env
    node_name -- a known host from the recovery site
    """
    # pylint: disable=too-many-locals
    if env.ghost_file_codes:
        raise LibraryError(
            ReportItem.error(
                reports.messages.LiveEnvironmentRequired(
                    env.ghost_file_codes)))
    report_processor = env.report_processor
    dr_env = env.get_dr_env()
    if dr_env.config.raw_file.exists():
        report_processor.report(
            ReportItem.error(reports.messages.DrConfigAlreadyExist()))
    target_factory = env.get_node_target_factory()

    local_nodes, report_list = get_existing_nodes_names(
        env.get_corosync_conf(), error_on_missing_name=True)
    report_processor.report_list(report_list)

    if node_name in local_nodes:
        report_processor.report(
            ReportItem.error(reports.messages.NodeInLocalCluster(node_name)))

    report_list, local_targets = target_factory.get_target_list_with_reports(
        local_nodes, allow_skip=False, report_none_host_found=False)
    report_processor.report_list(report_list)

    report_list, remote_targets = target_factory.get_target_list_with_reports(
        [node_name], allow_skip=False, report_none_host_found=False)
    report_processor.report_list(report_list)

    if report_processor.has_errors:
        raise LibraryError()

    # TODO The new file framework doesn't support network communication yet.
    com_cmd = GetCorosyncConf(env.report_processor)
    com_cmd.set_targets(remote_targets)
    corosync_conf_instance = FileInstance.for_corosync_conf()
    try:
        remote_cluster_nodes, report_list = get_existing_nodes_names(
            cast(
                CorosyncConfigFacade,
                corosync_conf_instance.raw_to_facade(
                    run_and_raise(env.get_node_communicator(),
                                  com_cmd).encode("utf-8")),
            ),
            error_on_missing_name=True,
        )
    except ParserErrorException as e:
        report_processor.report_list(
            corosync_conf_instance.toolbox.parser.exception_to_report_list(
                e,
                file_type_codes.COROSYNC_CONF,
                None,
                force_code=None,
                is_forced_or_warning=False,
            ))

    if report_processor.report_list(report_list).has_errors:
        raise LibraryError()

    # ensure we have tokens for all nodes of remote cluster
    report_list, remote_targets = target_factory.get_target_list_with_reports(
        remote_cluster_nodes, allow_skip=False, report_none_host_found=False)
    if report_processor.report_list(report_list).has_errors:
        raise LibraryError()
    dr_config_exporter = get_file_toolbox(
        file_type_codes.PCS_DR_CONFIG).exporter
    # create dr config for remote cluster
    remote_dr_cfg = dr_env.create_facade(DrRole.RECOVERY)
    remote_dr_cfg.add_site(DrRole.PRIMARY, local_nodes)
    # send config to all node of remote cluster
    distribute_file_cmd = DistributeFilesWithoutForces(
        env.report_processor,
        node_communication_format.pcs_dr_config_file(
            dr_config_exporter.export(remote_dr_cfg.config)),
    )
    distribute_file_cmd.set_targets(remote_targets)
    run_and_raise(env.get_node_communicator(), distribute_file_cmd)
    # create new dr config, with local cluster as primary site
    local_dr_cfg = dr_env.create_facade(DrRole.PRIMARY)
    local_dr_cfg.add_site(DrRole.RECOVERY, remote_cluster_nodes)
    distribute_file_cmd = DistributeFilesWithoutForces(
        env.report_processor,
        node_communication_format.pcs_dr_config_file(
            dr_config_exporter.export(local_dr_cfg.config)),
    )
    distribute_file_cmd.set_targets(local_targets)
    run_and_raise(env.get_node_communicator(), distribute_file_cmd)