示例#1
0
def prepare_options_with_set(cib, options, resource_set_list):
    options = constraint.prepare_options(
        tuple(ATTRIB.keys()),
        options,
        create_id_fn=partial(constraint.create_id, cib, "ticket",
                             resource_set_list),
        validate_id=partial(tools.check_new_id_applicable, cib, DESCRIPTION),
    )
    report_list = _validate_options_common(options)
    if "ticket" not in options or not options["ticket"].strip():
        report_list.append(
            ReportItem.error(
                reports.messages.RequiredOptionsAreMissing(["ticket"])))
    if report_list:
        raise LibraryError(*report_list)
    return options
示例#2
0
文件: nodes.py 项目: vvidic/pcs
 def _process_response(self, response):
     report = response_to_report_item(response)
     if report is None:
         self._online_target_list.append(response.request.target)
         return
     if not response.was_connected:
         report = (
             ReportItem.warning(
                 reports.messages.OmittingNode(response.request.target.label)
             )
             if self._ignore_offline_targets
             else response_to_report_item(
                 response, forceable=report_codes.SKIP_OFFLINE_NODES
             )
         )
     self._report(report)
示例#3
0
def _validate_level(level) -> Tuple[ReportItemList, Optional[int]]:
    report_list: ReportItemList = []
    try:
        candidate = int(level)
        if candidate > 0:
            return report_list, candidate
    except ValueError:
        pass
    report_list.append(
        ReportItem.error(
            reports.messages.InvalidOptionValue(
                "level", level, "a positive integer"
            )
        )
    )
    return report_list, None
示例#4
0
 def _log_response_successful(self, response):
     url = response.request.url
     msg = (
         "Finished calling: {url}\nResponse Code: {code}" +
         "\n--Debug Response Start--\n{response}\n--Debug Response End--")
     self._logger.debug(
         msg.format(url=url,
                    code=response.response_code,
                    response=response.data))
     self._reporter.report(
         ReportItem.debug(
             reports.messages.NodeCommunicationFinished(
                 url,
                 response.response_code,
                 response.data,
             )))
示例#5
0
 def from_string(cls, config_string):
     """
     Parse corosync config and create a facade around it
     config_string corosync config text
     """
     try:
         return cls(config_parser.parse_string(config_string))
     except config_parser.MissingClosingBraceException as e:
         raise LibraryError(
             ReportItem.error(
                 reports.messages.ParseErrorCorosyncConfMissingClosingBrace(
                 ))) from e
     except config_parser.UnexpectedClosingBraceException as e:
         # pylint: disable=line-too-long
         raise LibraryError(
             ReportItem.error(
                 reports.messages.
                 ParseErrorCorosyncConfUnexpectedClosingBrace())) from e
     except config_parser.MissingSectionNameBeforeOpeningBraceException as e:
         # pylint: disable=line-too-long
         raise LibraryError(
             ReportItem.error(
                 reports.messages.
                 ParseErrorCorosyncConfMissingSectionNameBeforeOpeningBrace(
                 ))) from e
     except config_parser.ExtraCharactersAfterOpeningBraceException as e:
         # pylint: disable=line-too-long
         raise LibraryError(
             ReportItem.error(
                 reports.messages.
                 ParseErrorCorosyncConfExtraCharactersAfterOpeningBrace())
         ) from e
     except config_parser.ExtraCharactersBeforeOrAfterClosingBraceException as e:
         # pylint: disable=line-too-long
         raise LibraryError(
             ReportItem.error(
                 reports.messages.
                 ParseErrorCorosyncConfExtraCharactersBeforeOrAfterClosingBrace(
                 ))) from e
     except config_parser.LineIsNotSectionNorKeyValueException as e:
         # pylint: disable=line-too-long
         raise LibraryError(
             ReportItem.error(
                 reports.
                 messages.ParseErrorCorosyncConfLineIsNotSectionNorKeyValue(
                 ))) from e
     except config_parser.CorosyncConfParserException as e:
         raise LibraryError(
             ReportItem.error(
                 reports.messages.ParseErrorCorosyncConf())) from e
示例#6
0
 def _log_debug(self, response):
     url = response.request.url
     debug_data = response.debug
     self._logger.debug(
         (
             "Communication debug info for calling: {url}\n"
             "--Debug Communication Info Start--\n"
             "{data}\n"
             "--Debug Communication Info End--"
         ).format(url=url, data=debug_data)
     )
     self._reporter.report(
         ReportItem.debug(
             reports.messages.NodeCommunicationDebugInfo(url, debug_data)
         )
     )
示例#7
0
文件: sbd.py 项目: zht750808/pcs
def get_available_watchdogs(cmd_runner):
    regex = (r"\[\d+\] (?P<watchdog>.+)$\n"
             r"Identity: (?P<identity>.+)$\n"
             r"Driver: (?P<driver>.+)$"
             r"(\nCAUTION: (?P<caution>.+)$)?")
    std_out, std_err, ret_val = cmd_runner.run(
        [settings.sbd_binary, "query-watchdog"])
    if ret_val != 0:
        raise LibraryError(
            ReportItem.error(reports.messages.SbdListWatchdogError(std_err)))
    return {
        match.group("watchdog"):
        {key: match.group(key)
         for key in ["identity", "driver", "caution"]}
        for match in re.finditer(regex, std_out, re.MULTILINE)
    }
示例#8
0
def _validate_target_typewise(target_type) -> ReportItemList:
    report_list: ReportItemList = []
    if target_type not in [
        TARGET_TYPE_NODE,
        TARGET_TYPE_ATTRIBUTE,
        TARGET_TYPE_REGEXP,
    ]:
        report_list.append(
            ReportItem.error(
                reports.messages.InvalidOptionType(
                    "target",
                    ["node", "regular expression", "attribute_name=value"],
                )
            )
        )
    return report_list
示例#9
0
def create_target(acl_section, target_id):
    """
    Creates new acl_target element with id target_id.
    Raises LibraryError if target with wpecified id aleready exists.

    acl_section -- etree node
    target_id -- id of new target
    """
    # id of element acl_target is not type ID in CIB ACL schema so we don't need
    # to check if it is unique ID in whole CIB
    if acl_section.xpath(f"./{TAG_TARGET}[@id=$target_id]",
                         target_id=target_id):
        raise LibraryError(
            ReportItem.error(
                reports.messages.CibAclTargetAlreadyExists(target_id)))
    return etree.SubElement(acl_section, TAG_TARGET, id=target_id)
示例#10
0
文件: sbd.py 项目: zht750808/pcs
def set_message(cmd_runner, device, node_name, message):
    """
    Set message of specified type 'message' on SBD device for node.

    cmd_runner -- CommandRunner
    device -- string, device path
    node_name -- string, nae of node for which message should be set
    message -- string, message type
    """
    dummy_std_out, std_err, ret_val = cmd_runner.run(
        [settings.sbd_binary, "-d", device, "message", node_name, message])
    if ret_val != 0:
        raise LibraryError(
            ReportItem.error(
                reports.messages.SbdDeviceMessageError(device, node_name,
                                                       message, std_err)))
示例#11
0
文件: node.py 项目: zht750808/pcs
def _set_instance_attrs_local_node(lib_env, attrs, wait):
    if not lib_env.is_cib_live:
        # If we are not working with a live cluster we cannot get the local node
        # name.
        raise LibraryError(
            ReportItem.error(
                reports.messages.LiveEnvironmentRequiredForLocalNode()))

    with cib_runner_nodes(lib_env, wait) as (cib, runner, state_nodes):
        update_node_instance_attrs(
            cib,
            IdProvider(cib),
            get_local_node_name(runner),
            attrs,
            state_nodes=state_nodes,
        )
示例#12
0
文件: ticket.py 项目: zht750808/pcs
def _validate_options_common(options):
    report_list = []
    if "loss-policy" in options:
        loss_policy = options["loss-policy"].lower()
        if options["loss-policy"] not in ATTRIB["loss-policy"]:
            report_list.append(
                ReportItem.error(
                    reports.messages.InvalidOptionValue(
                        "loss-policy",
                        options["loss-policy"],
                        ATTRIB["loss-policy"],
                    )
                )
            )
        options["loss-policy"] = loss_policy
    return report_list
示例#13
0
文件: sbd.py 项目: simhaonline/pcs
    def _process_response(self, response):
        report_item = response_to_report_item(response)
        if report_item:
            self._report(report_item)
            return
        report_list = []
        node_label = response.request.target.label
        try:
            data = json.loads(response.data)
            if not data["sbd"]["installed"]:
                report_list.append(
                    ReportItem.error(
                        reports.messages.SbdNotInstalled(node_label)))
            if "watchdog" in data:
                if data["watchdog"]["exist"]:
                    if not data["watchdog"].get("is_supported", True):
                        report_list.append(
                            ReportItem.error(
                                reports.messages.SbdWatchdogNotSupported(
                                    node_label, data["watchdog"]["path"])))
                else:
                    report_list.append(
                        ReportItem.error(
                            reports.messages.WatchdogNotFound(
                                node_label, data["watchdog"]["path"])))

            for device in data.get("device_list", []):
                if not device["exist"]:
                    report_list.append(
                        ReportItem.error(
                            reports.messages.SbdDeviceDoesNotExist(
                                device["path"], node_label)))
                elif not device["block_device"]:
                    report_list.append(
                        ReportItem.error(
                            reports.messages.SbdDeviceIsNotBlockDevice(
                                device["path"], node_label)))
                # TODO maybe we can check whenever device is initialized by sbd
                # (by running 'sbd -d <dev> dump;')
        except (ValueError, KeyError, TypeError):
            report_list.append(
                ReportItem.error(
                    reports.messages.InvalidResponseFormat(node_label)))
        if report_list:
            self._report_list(report_list)
        else:
            self._report(
                ReportItem.info(
                    reports.messages.SbdCheckSuccess(
                        response.request.target.label)))
示例#14
0
文件: qdevice.py 项目: zht750808/pcs
def qdevice_destroy(lib_env: LibraryEnvironment, model, proceed_if_used=False):
    """
    Stop and disable qdevice on local host and remove its configuration
    string model qdevice model to destroy
    bool procced_if_used destroy qdevice even if it is used by clusters
    """
    _check_model(model)
    _check_qdevice_not_used(
        lib_env.report_processor, lib_env.cmd_runner(), model, proceed_if_used
    )
    _service_stop(lib_env, qdevice_net.qdevice_stop)
    _service_disable(lib_env, qdevice_net.qdevice_disable)
    qdevice_net.qdevice_destroy()
    lib_env.report_processor.report(
        ReportItem.info(reports.messages.QdeviceDestroySuccess(model))
    )
示例#15
0
文件: qdevice.py 项目: zht750808/pcs
def qdevice_setup(lib_env: LibraryEnvironment, model, enable, start):
    """
    Initialize qdevice on local host with specified model
    string model qdevice model to initialize
    bool enable make qdevice service start on boot
    bool start start qdevice now
    """
    _check_model(model)
    qdevice_net.qdevice_setup(lib_env.cmd_runner())
    lib_env.report_processor.report(
        ReportItem.info(reports.messages.QdeviceInitializationSuccess(model))
    )
    if enable:
        _service_enable(lib_env, qdevice_net.qdevice_enable)
    if start:
        _service_start(lib_env, qdevice_net.qdevice_start)
示例#16
0
文件: tools.py 项目: kmalyjur/pcs
 def book_ids(self, *id_list: str) -> ReportItemList:
     """
     Check if the ids are not already used and reserve them for future use
     """
     reported_ids = set()
     report_list = []
     for _id in id_list:
         if _id in reported_ids:
             continue
         if _id in self._booked_ids or does_id_exist(self._cib, _id):
             report_list.append(
                 ReportItem.error(reports.messages.IdAlreadyExists(_id)))
             reported_ids.add(_id)
             continue
         self._booked_ids.add(_id)
     return report_list
示例#17
0
def _service_disable(
    report_processor: ReportProcessor,
    service_manager: ServiceManagerInterface,
    service: str,
) -> None:
    try:
        service_manager.disable(service)
    except ManageServiceError as e:
        raise LibraryError(service_exception_to_report(e)) from e
    report_processor.report(
        ReportItem.info(
            reports.messages.ServiceActionSucceeded(
                reports.const.SERVICE_ACTION_DISABLE, "quorum device"
            )
        )
    )
示例#18
0
文件: node.py 项目: zht750808/pcs
def _set_instance_attrs_node_list(lib_env, attrs, node_names, wait):
    with cib_runner_nodes(lib_env, wait) as (cib, dummy_runner, state_nodes):
        known_nodes = [node.attrs.name for node in state_nodes]
        report_list = []
        for node in node_names:
            if node not in known_nodes:
                report_list.append(
                    ReportItem.error(reports.messages.NodeNotFound(node)))
        if report_list:
            raise LibraryError(*report_list)

        for node in node_names:
            update_node_instance_attrs(cib,
                                       IdProvider(cib),
                                       node,
                                       attrs,
                                       state_nodes=state_nodes)
示例#19
0
def is_resource_in_same_group(cib, resource_id_list):
    # We don't care about not found elements here, that is a job of another
    # validator. We do not care if the id doesn't belong to a resource either
    # for the same reason.
    element_list, _ = get_elements_by_ids(cib, set(resource_id_list))

    parent_list = []
    for element in element_list:
        parent = get_parent_resource(element)
        if parent is not None and group.is_group(parent):
            parent_list.append(parent)

    if len(set(parent_list)) != len(parent_list):
        raise LibraryError(
            ReportItem.error(
                reports.messages.
                CannotSetOrderConstraintsForResourcesInTheSameGroup()))
示例#20
0
def client_net_import_certificate(lib_env: LibraryEnvironment, certificate):
    """
    Import qnetd client certificate to local node certificate storage
    certificate base64 encoded qnetd client certificate
    """
    try:
        certificate_data = base64.b64decode(certificate)
    except (TypeError, binascii.Error):
        raise LibraryError(
            ReportItem.error(
                reports.messages.InvalidOptionValue(
                    "qnetd client certificate",
                    certificate,
                    ["base64 encoded certificate"],
                )))
    qdevice_net.client_import_certificate_and_key(lib_env.cmd_runner(),
                                                  certificate_data)
示例#21
0
文件: sbd.py 项目: vvidic/pcs
def validate_new_nodes_devices(nodes_devices):
    """
    Validate if SBD devices are set for new nodes when they should be

    dict nodes_devices -- name: node name, key: list of SBD devices
    """
    if is_device_set_local():
        return validate_nodes_devices(
            nodes_devices, adding_nodes_to_sbd_enabled_cluster=True
        )
    return [
        ReportItem.error(
            reports.messages.SbdWithDevicesNotUsedCannotSetDevice(node)
        )
        for node, devices in nodes_devices.items()
        if devices
    ]
示例#22
0
def prepare_options_with_set(cib, options, resource_set_list):
    options = constraint.prepare_options(
        ("score", ),
        options,
        partial(constraint.create_id, cib, "colocation", resource_set_list),
        partial(check_new_id_applicable, cib, DESCRIPTION),
    )

    if "score" in options:
        if not is_score(options["score"]):
            raise LibraryError(
                ReportItem.error(
                    reports.messages.InvalidScore(options["score"])))
    else:
        options["score"] = SCORE_INFINITY

    return options
示例#23
0
def client_net_setup(lib_env: LibraryEnvironment, ca_certificate):
    """
    Initialize qdevice net client on local host

    ca_certificate -- base64 encoded qnetd CA certificate
    """
    try:
        ca_certificate_data = base64.b64decode(ca_certificate)
    except (TypeError, binascii.Error) as e:
        raise LibraryError(
            ReportItem.error(
                reports.messages.InvalidOptionValue(
                    "qnetd CA certificate",
                    ca_certificate,
                    ["base64 encoded certificate"],
                ))) from e
    qdevice_net.client_setup(lib_env.cmd_runner(), ca_certificate_data)
示例#24
0
def remove_levels_by_params(
    topology_el,
    level=None,
    target_type=None,
    target_value=None,
    devices=None,
    ignore_if_missing=False,
) -> ReportItemList:
    """
    Remove specified fencing level(s)

    etree topology_el -- etree element to remove the levels from
    int|string level -- level (index) of the fencing level to remove
    constant target_type -- the removed fencing level target value type
    mixed target_value -- the removed fencing level target value
    Iterable devices -- list of stonith devices of the removed fencing level
    bool ignore_if_missing -- when True, do not report if level not found
    """
    # Do not ever remove a fencing-topology element, even if it is empty. There
    # may be ACLs set in pacemaker which allow "write" for fencing-level
    # elements (adding, changing and removing) but not fencing-topology
    # elements. In such a case, removing a fencing-topology element would cause
    # the whole change to be rejected by pacemaker with a "permission denied"
    # message.
    # https://bugzilla.redhat.com/show_bug.cgi?id=1642514
    report_list: ReportItemList = []
    if target_type:
        report_list.extend(_validate_target_typewise(target_type))
        if has_errors(report_list):
            return report_list

    level_el_list = _find_level_elements(topology_el, level, target_type,
                                         target_value, devices)

    if not level_el_list:
        if ignore_if_missing:
            return report_list
        report_list.append(
            ReportItem.error(
                reports.messages.CibFencingLevelDoesNotExist(
                    level, target_type, target_value, devices or [])))
    if has_errors(report_list):
        return report_list
    for el in level_el_list:
        el.getparent().remove(el)
    return report_list
示例#25
0
def qdevice_status_generic_text(runner, verbose=False):
    """
    get qdevice runtime status in plain text
    bool verbose get more detailed output
    """
    args = ["-s"]
    if verbose:
        args.append("-v")
    stdout, stderr, retval = _qdevice_run_tool(runner, args)
    if retval != 0:
        raise LibraryError(
            ReportItem.error(
                reports.messages.QdeviceGetStatusError(
                    __model,
                    join_multilines([stderr, stdout]),
                )))
    return stdout
示例#26
0
文件: quorum.py 项目: kmalyjur/pcs
def set_expected_votes_live(lib_env, expected_votes):
    """
    set expected votes in live cluster to specified value
    numeric expected_votes desired value of expected votes
    """
    try:
        votes_int = int(expected_votes)
        if votes_int < 1:
            raise ValueError()
    except ValueError:
        raise LibraryError(
            ReportItem.error(
                reports.messages.InvalidOptionValue(
                    "expected votes", expected_votes,
                    "positive integer"))) from None

    corosync_live.set_expected_votes(lib_env.cmd_runner(), votes_int)
示例#27
0
    def update_quorum_device(
        self, model_options, generic_options, heuristics_options
    ):
        """
        Update existing quorum device configuration

        dict model_options -- model specific options
        dict generic_options -- generic quorum device options
        dict heuristics_options -- heuristics options
        """
        if not self.has_quorum_device():
            raise LibraryError(
                ReportItem.error(reports.messages.QdeviceNotDefined())
            )
        model = self.get_quorum_device_model()

        # set new configuration
        device_sections = []
        model_sections = []
        heuristics_sections = []

        for quorum in self.config.get_sections("quorum"):
            device_sections.extend(quorum.get_sections("device"))
            for device in quorum.get_sections("device"):
                model_sections.extend(device.get_sections(model))
                heuristics_sections.extend(device.get_sections("heuristics"))
        # we know device sections exist, otherwise the function would exit at
        # has_quorum_device line above
        if not model_sections:
            new_model = config_parser.Section(model)
            device_sections[-1].add_section(new_model)
            model_sections.append(new_model)
        if not heuristics_sections:
            new_heuristics = config_parser.Section("heuristics")
            device_sections[-1].add_section(new_heuristics)
            heuristics_sections.append(new_heuristics)

        self.__set_section_options(device_sections, generic_options)
        self.__set_section_options(model_sections, model_options)
        self.__set_section_options(heuristics_sections, heuristics_options)

        self.__update_qdevice_votes()
        self.__update_two_node()
        self.__remove_empty_sections(self.config)
        self._need_qdevice_reload = True
示例#28
0
def add_resource(bundle_element, primitive_element):
    """
    Add an existing resource to an existing bundle

    etree bundle_element -- where to add the resource to
    etree primitive_element -- the resource to be added to the bundle
    """
    # TODO possibly split to 'validate' and 'do' functions
    # a bundle may currently contain at most one primitive resource
    inner_primitive = bundle_element.find(TAG_PRIMITIVE)
    if inner_primitive is not None:
        raise LibraryError(
            ReportItem.error(
                reports.messages.ResourceBundleAlreadyContainsAResource(
                    bundle_element.get("id"),
                    inner_primitive.get("id"),
                )))
    bundle_element.append(primitive_element)
示例#29
0
 def _process_response(self, response):
     report_item = response_to_report_item(
         response, severity=ReportItemSeverity.WARNING)
     node_label = response.request.target.label
     if report_item is not None:
         if not response.was_connected:
             self._report(report_item)
         self._report(
             ReportItem.warning(
                 reports.messages.UnableToGetSbdConfig(node_label, "")))
         return
     self._config_list.append({
         "node":
         node_label,
         "config":
         environment_file_to_dict(response.data),
     })
     self._successful_target_list.append(node_label)
示例#30
0
def get_valid_timeout_seconds(
    timeout_candidate: Union[str, int, None],
) -> Optional[int]:
    """
    Transform pacemaker style timeout to number of seconds, raise LibraryError
        on invalid timeout
    timeout_candidate timeout string or None
    """
    if timeout_candidate is None:
        return None
    wait_timeout = timeout_to_seconds(timeout_candidate)
    if wait_timeout is None:
        raise LibraryError(
            ReportItem.error(
                reports.messages.InvalidTimeoutValue(str(timeout_candidate))
            )
        )
    return wait_timeout