Ejemplo n.º 1
0
def add_device(lib_env,
               model,
               model_options,
               generic_options,
               force_model=False,
               force_options=False,
               skip_offline_nodes=False):
    """
    Add quorum device to cluster, distribute and reload configs if live
    model quorum device model
    model_options model specific options dict
    generic_options generic quorum device options dict
    force_model continue even if the model is not valid
    force_options continue even if options are not valid
    skip_offline_nodes continue even if not all nodes are accessible
    """
    __ensure_not_cman(lib_env)

    cfg = lib_env.get_corosync_conf()
    # Try adding qdevice to corosync.conf. This validates all the options and
    # makes sure qdevice is not defined in corosync.conf yet.
    cfg.add_quorum_device(lib_env.report_processor, model, model_options,
                          generic_options, force_model, force_options)
    target_list = lib_env.get_node_target_factory().get_target_list(
        cfg.get_nodes())

    # First setup certificates for qdevice, then send corosync.conf to nodes.
    # If anything fails, nodes will not have corosync.conf with qdevice in it,
    # so there is no effect on the cluster.
    if lib_env.is_corosync_conf_live:
        # do model specific configuration
        # if model is not known to pcs and was forced, do not configure antyhing
        # else but corosync.conf, as we do not know what to do anyways
        if model == "net":
            _add_device_model_net(
                lib_env,
                # we are sure it's there, it was validated in add_quorum_device
                model_options["host"],
                cfg.get_cluster_name(),
                cfg.get_nodes(),
                skip_offline_nodes)

        lib_env.report_processor.process(
            reports.service_enable_started("corosync-qdevice"))
        com_cmd = qdevice_com.Enable(lib_env.report_processor,
                                     skip_offline_nodes)
        com_cmd.set_targets(target_list)
        run_and_raise(lib_env.get_node_communicator(), com_cmd)

    # everything set up, it's safe to tell the nodes to use qdevice
    lib_env.push_corosync_conf(cfg, skip_offline_nodes)

    # Now, when corosync.conf has been reloaded, we can start qdevice service.
    if lib_env.is_corosync_conf_live:
        lib_env.report_processor.process(
            reports.service_start_started("corosync-qdevice"))
        com_cmd = qdevice_com.Start(lib_env.report_processor,
                                    skip_offline_nodes)
        com_cmd.set_targets(target_list)
        run_and_raise(lib_env.get_node_communicator(), com_cmd)
Ejemplo n.º 2
0
Archivo: env.py Proyecto: junaruga/pcs
 def _push_corosync_conf_live(
     self, target_list, corosync_conf_data, need_stopped_cluster,
     need_qdevice_reload, skip_offline_nodes
 ):
     if need_stopped_cluster:
         com_cmd = CheckCorosyncOffline(
             self.report_processor, skip_offline_nodes
         )
         com_cmd.set_targets(target_list)
         run_and_raise(self.get_node_communicator(), com_cmd)
     com_cmd = DistributeCorosyncConf(
         self.report_processor, corosync_conf_data, skip_offline_nodes
     )
     com_cmd.set_targets(target_list)
     run_and_raise(self.get_node_communicator(), com_cmd)
     if is_service_running(self.cmd_runner(), "corosync"):
         reload_corosync_config(self.cmd_runner())
         self.report_processor.process(
             reports.corosync_config_reloaded()
         )
     if need_qdevice_reload:
         self.report_processor.process(
             reports.qdevice_client_reload_started()
         )
         com_cmd = qdevice.Stop(self.report_processor, skip_offline_nodes)
         com_cmd.set_targets(target_list)
         run(self.get_node_communicator(), com_cmd)
         report_list = com_cmd.error_list
         com_cmd = qdevice.Start(self.report_processor, skip_offline_nodes)
         com_cmd.set_targets(target_list)
         run(self.get_node_communicator(), com_cmd)
         report_list += com_cmd.error_list
         if report_list:
             raise LibraryError()
Ejemplo n.º 3
0
    def _push_corosync_conf_live(
        self,
        target_list,
        corosync_conf_data,
        need_stopped_cluster,
        need_qdevice_reload,
        skip_offline_nodes,
    ):
        # TODO
        # * check for online nodes and run all commands on them only
        # * if those commands fail, exit with an error
        # * add support for allow_skip_offline=False
        # * use simple report procesor
        # Correct reloading is done in pcs.lib.cluster.remove_nodes for example.

        # Check if the cluster is stopped when needed
        if need_stopped_cluster:
            com_cmd = CheckCorosyncOffline(
                self.report_processor, skip_offline_nodes
            )
            com_cmd.set_targets(target_list)
            run_and_raise(self.get_node_communicator(), com_cmd)
        # Distribute corosync.conf
        com_cmd = DistributeCorosyncConf(
            self.report_processor, corosync_conf_data, skip_offline_nodes
        )
        com_cmd.set_targets(target_list)
        run_and_raise(self.get_node_communicator(), com_cmd)
        # Reload corosync
        if not need_stopped_cluster:
            # If cluster must be stopped then we cannot reload corosync because
            # the cluster is stopped. If it is not stopped, we do not even get
            # here.
            com_cmd = ReloadCorosyncConf(self.report_processor)
            com_cmd.set_targets(target_list)
            run_and_raise(self.get_node_communicator(), com_cmd)
        # Reload qdevice if needed
        if need_qdevice_reload:
            self.report_processor.report(
                ReportItem.info(reports.messages.QdeviceClientReloadStarted())
            )
            com_cmd = qdevice.Stop(self.report_processor, skip_offline_nodes)
            com_cmd.set_targets(target_list)
            run(self.get_node_communicator(), com_cmd)
            has_errors = com_cmd.has_errors
            com_cmd = qdevice.Start(self.report_processor, skip_offline_nodes)
            com_cmd.set_targets(target_list)
            run(self.get_node_communicator(), com_cmd)
            has_errors = has_errors or com_cmd.has_errors
            if has_errors:
                raise LibraryError()
Ejemplo n.º 4
0
 def _push_corosync_conf_live(
     self,
     target_list,
     corosync_conf_data,
     need_stopped_cluster,
     need_qdevice_reload,
     skip_offline_nodes,
 ):
     # Check if the cluster is stopped when needed
     if need_stopped_cluster:
         com_cmd = CheckCorosyncOffline(self.report_processor,
                                        skip_offline_nodes)
         com_cmd.set_targets(target_list)
         run_and_raise(self.get_node_communicator(), com_cmd)
     # Distribute corosync.conf
     com_cmd = DistributeCorosyncConf(self.report_processor,
                                      corosync_conf_data,
                                      skip_offline_nodes)
     com_cmd.set_targets(target_list)
     run_and_raise(self.get_node_communicator(), com_cmd)
     # Reload corosync
     if not need_stopped_cluster:
         # If cluster must be stopped then we cannot reload corosync because
         # the cluster is stopped. If it is not stopped, we do not even get
         # here.
         com_cmd = ReloadCorosyncConf(self.report_processor)
         com_cmd.set_targets(target_list)
         run_and_raise(self.get_node_communicator(), com_cmd)
     # Reload qdevice if needed
     if need_qdevice_reload:
         self.report_processor.report(
             ReportItem.info(reports.messages.QdeviceClientReloadStarted()))
         com_cmd = qdevice.Stop(self.report_processor, skip_offline_nodes)
         com_cmd.set_targets(target_list)
         run(self.get_node_communicator(), com_cmd)
         has_errors = com_cmd.has_errors
         com_cmd = qdevice.Start(self.report_processor, skip_offline_nodes)
         com_cmd.set_targets(target_list)
         run(self.get_node_communicator(), com_cmd)
         has_errors = has_errors or com_cmd.has_errors
         if has_errors:
             raise LibraryError()
Ejemplo n.º 5
0
def add_device(lib_env,
               model,
               model_options,
               generic_options,
               heuristics_options,
               force_model=False,
               force_options=False,
               skip_offline_nodes=False):
    """
    Add a quorum device to a cluster, distribute and reload configs if live

    string model -- quorum device model
    dict model_options -- model specific options
    dict generic_options -- generic quorum device options
    dict heuristics_options -- heuristics options
    bool force_model -- continue even if the model is not valid
    bool force_options -- continue even if options are not valid
    bool skip_offline_nodes -- continue even if not all nodes are accessible
    """
    cfg = lib_env.get_corosync_conf()
    if cfg.has_quorum_device():
        raise LibraryError(reports.qdevice_already_defined())
    lib_env.report_processor.process_list(
        corosync_conf_validators.add_quorum_device(
            model,
            model_options,
            generic_options,
            heuristics_options, [node.nodeid for node in cfg.get_nodes()],
            force_model=force_model,
            force_options=force_options))
    cfg.add_quorum_device(
        model,
        model_options,
        generic_options,
        heuristics_options,
    )
    if cfg.is_quorum_device_heuristics_enabled_with_no_exec():
        lib_env.report_processor.process(
            reports.corosync_quorum_heuristics_enabled_with_no_exec())

    # First setup certificates for qdevice, then send corosync.conf to nodes.
    # If anything fails, nodes will not have corosync.conf with qdevice in it,
    # so there is no effect on the cluster.
    if lib_env.is_corosync_conf_live:
        target_factory = lib_env.get_node_target_factory()
        target_list = target_factory.get_target_list(
            cfg.get_nodes_names(),
            skip_non_existing=skip_offline_nodes,
        )
        # Do model specific configuration.
        # If the model is not known to pcs and was forced, do not configure
        # anything else than corosync.conf, as we do not know what to do
        # anyway.
        if model == "net":
            qdevice_net.set_up_client_certificates(
                lib_env.cmd_runner(),
                lib_env.report_processor,
                lib_env.communicator_factory,
                # We are sure the "host" key is there, it has been validated
                # above.
                target_factory.get_target_from_hostname(model_options["host"]),
                cfg.get_cluster_name(),
                target_list,
                skip_offline_nodes)

        lib_env.report_processor.process(
            reports.service_enable_started("corosync-qdevice"))
        com_cmd = qdevice_com.Enable(lib_env.report_processor,
                                     skip_offline_nodes)
        com_cmd.set_targets(target_list)
        run_and_raise(lib_env.get_node_communicator(), com_cmd)

    # everything set up, it's safe to tell the nodes to use qdevice
    lib_env.push_corosync_conf(cfg, skip_offline_nodes)

    # Now, when corosync.conf has been reloaded, we can start qdevice service.
    if lib_env.is_corosync_conf_live:
        lib_env.report_processor.process(
            reports.service_start_started("corosync-qdevice"))
        com_cmd = qdevice_com.Start(lib_env.report_processor,
                                    skip_offline_nodes)
        com_cmd.set_targets(target_list)
        run_and_raise(lib_env.get_node_communicator(), com_cmd)
Ejemplo n.º 6
0
def add_device(
    lib_env: LibraryEnvironment,
    model,
    model_options,
    generic_options,
    heuristics_options,
    force_model=False,
    force_options=False,
    skip_offline_nodes=False,
):
    # pylint: disable=too-many-locals
    """
    Add a quorum device to a cluster, distribute and reload configs if live

    string model -- quorum device model
    dict model_options -- model specific options
    dict generic_options -- generic quorum device options
    dict heuristics_options -- heuristics options
    bool force_model -- continue even if the model is not valid
    bool force_options -- continue even if options are not valid
    bool skip_offline_nodes -- continue even if not all nodes are accessible
    """
    cfg = lib_env.get_corosync_conf()
    if cfg.has_quorum_device():
        raise LibraryError(
            ReportItem.error(reports.messages.QdeviceAlreadyDefined()))

    report_processor = lib_env.report_processor
    report_processor.report_list(
        corosync_conf_validators.add_quorum_device(
            model,
            model_options,
            generic_options,
            heuristics_options,
            [node.nodeid for node in cfg.get_nodes()],
            force_model=force_model,
            force_options=force_options,
        ))

    if lib_env.is_corosync_conf_live:
        cluster_nodes_names, report_list = get_existing_nodes_names(
            cfg,
            # Pcs is unable to communicate with nodes missing names. It cannot
            # send new corosync.conf to them. That might break the cluster.
            # Hence we error out.
            error_on_missing_name=True,
        )
        report_processor.report_list(report_list)

    if report_processor.has_errors:
        raise LibraryError()

    cfg.add_quorum_device(
        model,
        model_options,
        generic_options,
        heuristics_options,
    )
    if cfg.is_quorum_device_heuristics_enabled_with_no_exec():
        lib_env.report_processor.report(
            ReportItem.warning(
                reports.messages.CorosyncQuorumHeuristicsEnabledWithNoExec()))

    # First setup certificates for qdevice, then send corosync.conf to nodes.
    # If anything fails, nodes will not have corosync.conf with qdevice in it,
    # so there is no effect on the cluster.
    if lib_env.is_corosync_conf_live:
        target_factory = lib_env.get_node_target_factory()
        target_list = target_factory.get_target_list(
            cluster_nodes_names,
            skip_non_existing=skip_offline_nodes,
        )
        # Do model specific configuration.
        # If the model is not known to pcs and was forced, do not configure
        # anything else than corosync.conf, as we do not know what to do
        # anyway.
        if model == "net":
            qdevice_net.set_up_client_certificates(
                lib_env.cmd_runner(),
                lib_env.report_processor,
                lib_env.communicator_factory,
                # We are sure the "host" key is there, it has been validated
                # above.
                target_factory.get_target_from_hostname(model_options["host"]),
                cfg.get_cluster_name(),
                target_list,
                skip_offline_nodes,
            )

        lib_env.report_processor.report(
            ReportItem.info(
                reports.messages.ServiceActionStarted(
                    reports.const.SERVICE_ACTION_ENABLE, "corosync-qdevice")))
        com_cmd = qdevice_com.Enable(lib_env.report_processor,
                                     skip_offline_nodes)
        com_cmd.set_targets(target_list)
        run_and_raise(lib_env.get_node_communicator(), com_cmd)

    # everything set up, it's safe to tell the nodes to use qdevice
    lib_env.push_corosync_conf(cfg, skip_offline_nodes)

    # Now, when corosync.conf has been reloaded, we can start qdevice service.
    if lib_env.is_corosync_conf_live:
        lib_env.report_processor.report(
            ReportItem.info(
                reports.messages.ServiceActionStarted(
                    reports.const.SERVICE_ACTION_START, "corosync-qdevice")))
        com_cmd_start = qdevice_com.Start(lib_env.report_processor,
                                          skip_offline_nodes)
        com_cmd_start.set_targets(target_list)
        run_and_raise(lib_env.get_node_communicator(), com_cmd_start)