Exemplo n.º 1
0
def node_remove_guest(
    env: LibraryEnvironment,
    node_identifier,
    skip_offline_nodes=False,
    allow_remove_multiple_nodes=False,
    allow_pacemaker_remote_service_fail=False,
    wait: WaitType = False,
):
    """
    remove a resource representing remote node and destroy remote node

    LibraryEnvironment env provides all for communication with externals
    string node_identifier -- node name, hostname or resource id
    bool skip_offline_nodes -- a flag for ignoring when some nodes are offline
    bool allow_remove_multiple_nodes -- is a flag for allowing
        remove unexpected multiple occurrence of remote node for node_identifier
    bool allow_pacemaker_remote_service_fail -- is a flag for allowing
        successfully finish this command even if stoping/disabling
        pacemaker_remote not succeeded
    """
    wait_timeout = env.ensure_wait_satisfiable(wait)
    cib = env.get_cib()

    resource_element_list = _find_resources_to_remove(
        cib,
        env.report_processor,
        "guest",
        node_identifier,
        allow_remove_multiple_nodes,
        guest_node.find_node_resources,
    )

    node_names_list = sorted(
        {
            guest_node.get_node_name_from_resource(node_element)
            for node_element in resource_element_list
        }
    )

    if not env.is_cib_live:
        env.report_processor.report_list(
            _report_skip_live_parts_in_remove(node_names_list)
        )
    else:
        _destroy_pcmk_remote_env(
            env,
            node_names_list,
            skip_offline_nodes,
            allow_pacemaker_remote_service_fail,
        )

    for resource_element in resource_element_list:
        guest_node.unset_guest(resource_element)

    env.push_cib(wait_timeout=wait_timeout)

    # remove node from pcmk caches
    if env.is_cib_live:
        for node_name in node_names_list:
            remove_node(env.cmd_runner(), node_name)
Exemplo n.º 2
0
def node_clear(env, node_name, allow_clear_cluster_node=False):
    """
    Remove specified node from various cluster caches.

    LibraryEnvironment env provides all for communication with externals
    string node_name
    bool allow_clear_cluster_node -- flag allows to clear node even if it's
        still in a cluster
    """
    mocked_envs = []
    if not env.is_cib_live:
        mocked_envs.append("CIB")
    if not env.is_corosync_conf_live:
        mocked_envs.append("COROSYNC_CONF")
    if mocked_envs:
        raise LibraryError(reports.live_environment_required(mocked_envs))

    current_nodes = get_nodes(env.get_corosync_conf(), env.get_cib())
    if (node_addresses_contain_name(current_nodes, node_name)
            or node_addresses_contain_host(current_nodes, node_name)):
        env.report_processor.process(
            reports.get_problem_creator(
                report_codes.FORCE_CLEAR_CLUSTER_NODE,
                allow_clear_cluster_node)(
                    reports.node_to_clear_is_still_in_cluster, node_name))

    remove_node(env.cmd_runner(), node_name)
Exemplo n.º 3
0
 def test_success(self):
     mock_runner = get_runner("", "", 0)
     lib.remove_node(mock_runner, "NODE_NAME")
     mock_runner.run.assert_called_once_with([
         self.path("crm_node"),
         "--force",
         "--remove",
         "NODE_NAME",
     ])
Exemplo n.º 4
0
def node_remove_guest(
    env, node_identifier,
    skip_offline_nodes=False,
    allow_remove_multiple_nodes=False,
    allow_pacemaker_remote_service_fail=False,
    wait=False,
):
    """
    remove a resource representing remote node and destroy remote node

    LibraryEnvironment env provides all for communication with externals
    string node_identifier -- node name, hostname or resource id
    bool skip_offline_nodes -- a flag for ignoring when some nodes are offline
    bool allow_remove_multiple_nodes -- is a flag for allowing
        remove unexpected multiple occurence of remote node for node_identifier
    bool allow_pacemaker_remote_service_fail -- is a flag for allowing
        successfully finish this command even if stoping/disabling
        pacemaker_remote not succeeded
    """
    env.ensure_wait_satisfiable(wait)
    cib = env.get_cib()

    resource_element_list = _find_resources_to_remove(
        cib,
        env.report_processor,
        "guest",
        node_identifier,
        allow_remove_multiple_nodes,
        guest_node.find_node_resources,
    )

    node_names_list = sorted({
        guest_node.get_node_name_from_resource(node_element)
        for node_element in resource_element_list
    })

    if not env.is_cib_live:
        env.report_processor.process_list(
            _report_skip_live_parts_in_remove(node_names_list)
        )
    else:
        _destroy_pcmk_remote_env(
            env,
            node_names_list,
            skip_offline_nodes,
            allow_pacemaker_remote_service_fail
        )

    for resource_element in resource_element_list:
        guest_node.unset_guest(resource_element)

    env.push_cib(wait=wait)

    #remove node from pcmk caches
    if env.is_cib_live:
        for node_name in node_names_list:
            remove_node(env.cmd_runner(), node_name)
Exemplo n.º 5
0
def node_remove_guest(
    env,
    node_identifier,
    allow_remove_multiple_nodes=False,
    allow_pacemaker_remote_service_fail=False,
    wait=False,
):
    """
    remove a resource representing remote node and destroy remote node

    LibraryEnvironment env provides all for communication with externals
    string node_identifier -- node name, hostname or resource id
    bool allow_remove_multiple_nodes -- is a flag for allowing
        remove unexpected multiple occurence of remote node for node_identifier
    bool allow_pacemaker_remote_service_fail -- is a flag for allowing
        successfully finish this command even if stoping/disabling
        pacemaker_remote not succeeded
    """
    _ensure_consistently_live_env(env)
    env.ensure_wait_satisfiable(wait)
    cib = env.get_cib()

    resource_element_list = _find_resources_to_remove(
        cib,
        env.report_processor,
        "guest",
        node_identifier,
        allow_remove_multiple_nodes,
        guest_node.find_node_resources,
    )

    node_addresses_list = _get_node_addresses_from_resources(
        get_nodes_guest(cib),
        resource_element_list,
        guest_node.get_host,
    )

    if not env.is_corosync_conf_live:
        env.report_processor.process_list(
            _report_skip_live_parts_in_remove(node_addresses_list))
    else:
        _destroy_pcmk_remote_env(env, node_addresses_list,
                                 allow_pacemaker_remote_service_fail)

    for resource_element in resource_element_list:
        guest_node.unset_guest(resource_element)

    env.push_cib(cib, wait)

    #remove node from pcmk caches
    if env.is_cib_live:
        for node_addresses in node_addresses_list:
            remove_node(env.cmd_runner(), node_addresses.name)
Exemplo n.º 6
0
 def test_success(self):
     mock_runner = get_runner("", "", 0)
     lib.remove_node(
         mock_runner,
         "NODE_NAME"
     )
     mock_runner.run.assert_called_once_with([
         self.path("crm_node"),
         "--force",
         "--remove",
         "NODE_NAME",
     ])
Exemplo n.º 7
0
 def test_error(self):
     expected_stderr = "expected stderr"
     mock_runner = get_runner("", expected_stderr, 1)
     assert_raise_library_error(
         lambda: lib.remove_node(mock_runner, "NODE_NAME"),
         (Severity.ERROR, report_codes.NODE_REMOVE_IN_PACEMAKER_FAILED, {
             "node_name": "NODE_NAME",
             "reason": expected_stderr,
         }))
Exemplo n.º 8
0
def remove_nodes_from_cib(env, node_list):
    """
    Remove specified nodes from CIB. When pcmk is running 'crm_node -R <node>'
    will be used. Otherwise nodes will be removed directly from CIB file.

    env LibraryEnvironment
    node_list iterable -- names of nodes to remove
    """
    # TODO: more advanced error handling
    # TODO: Tests
    if not env.is_cib_live:
        raise LibraryError(reports.live_environment_required(["CIB"]))

    if is_service_running(env.cmd_runner(), "pacemaker"):
        for node in node_list:
            # this may raise a LibraryError
            # NOTE: crm_node cannot remove multiple nodes at once
            remove_node(env.cmd_runner(), node)
        return

    # TODO: We need to remove nodes from the CIB file. We don't want to do it
    # using environment as this is a special case in which we have to edit CIB
    # file directly.
    for node in node_list:
        stdout, stderr, retval = env.cmd_runner().run(
            [
                settings.cibadmin,
                "--delete-all",
                "--force",
                f"--xpath=/cib/configuration/nodes/node[@uname='{node}']",
            ],
            env_extend={"CIB_file": os.path.join(settings.cib_dir, "cib.xml")}
        )
        if retval != 0:
            raise LibraryError(
                reports.node_remove_in_pacemaker_failed(
                    [node],
                    reason=join_multilines([stderr, stdout])
                )
            )
Exemplo n.º 9
0
 def test_error(self):
     expected_stderr = "expected stderr"
     mock_runner = get_runner("", expected_stderr, 1)
     assert_raise_library_error(
         lambda: lib.remove_node(mock_runner, "NODE_NAME"),
         (
             Severity.ERROR,
             report_codes.NODE_REMOVE_IN_PACEMAKER_FAILED,
             {
                 "node": None,
                 "node_list_to_remove": ["NODE_NAME"],
                 "reason": expected_stderr,
             }
         )
     )