示例#1
0
def replace_cib_configuration_xml(runner, xml):
    cmd = [
        __exec("cibadmin"),
        "--replace",
        "--verbose",
        "--xml-pipe",
        "--scope",
        "configuration",
    ]
    stdout, stderr, retval = runner.run(cmd, stdin_string=xml)
    if retval != 0:
        raise LibraryError(
            ReportItem.error(reports.messages.CibPushError(stderr, stdout)))
示例#2
0
def history_update(env: LibraryEnvironment):
    """
    Update fencing history in a cluster (sync with other nodes)

    env
    """
    runner = env.cmd_runner()
    if not is_fence_history_supported_management(runner):
        raise LibraryError(
            ReportItem.error(reports.messages.FenceHistoryNotSupported())
        )

    try:
        return fence_history_update(runner)
    except FenceHistoryCommandErrorException as e:
        raise LibraryError(
            ReportItem.error(
                reports.messages.FenceHistoryCommandError(
                    str(e), reports.const.FENCE_HISTORY_COMMAND_UPDATE
                )
            )
        ) from e
示例#3
0
 def remove_quorum_device_heuristics(self):
     """
     Remove quorum device heuristics configuration
     """
     if not self.has_quorum_device():
         raise LibraryError(
             ReportItem.error(reports.messages.QdeviceNotDefined()))
     for quorum in self.config.get_sections("quorum"):
         for device in quorum.get_sections("device"):
             for heuristics in device.get_sections("heuristics"):
                 device.del_section(heuristics)
     self.__remove_empty_sections(self.config)
     self._need_qdevice_reload = True
示例#4
0
def _get_cib_version(cib, attribute, regexp, none_if_missing=False):
    version = cib.get(attribute)
    if version is None:
        if none_if_missing:
            return None
        raise LibraryError(
            ReportItem.error(
                reports.messages.CibLoadErrorBadFormat(
                    f"the attribute '{attribute}' of the element 'cib' "
                    "is missing")))
    match = regexp.match(version)
    if not match:
        raise LibraryError(
            ReportItem.error(
                reports.messages.CibLoadErrorBadFormat(
                    f"the attribute '{attribute}' of the element 'cib' has "
                    f"an invalid value: '{version}'")))
    return Version(
        int(match.group("major")),
        int(match.group("minor")),
        int(match.group("rev")) if match.group("rev") else None,
    )
示例#5
0
文件: live.py 项目: simhaonline/pcs
def remove_node(runner, node_name):
    stdout, stderr, retval = runner.run(
        [__exec("crm_node"), "--force", "--remove", node_name,]
    )
    if retval != 0:
        raise LibraryError(
            ReportItem.error(
                reports.messages.NodeRemoveInPacemakerFailed(
                    node_list_to_remove=[node_name],
                    reason=join_multilines([stderr, stdout]),
                )
            )
        )
示例#6
0
def get_local_corosync_conf():
    """
    Read corosync.conf file from local machine
    """
    path = settings.corosync_conf_file
    try:
        with open(path, "r", encoding="utf-8") as a_file:
            return a_file.read()
    except EnvironmentError as e:
        raise LibraryError(
            ReportItem.error(
                reports.messages.UnableToReadCorosyncConfig(
                    path, e.strerror))) from e
示例#7
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
示例#8
0
def check_instance_name(name):
    """
    Check that specified booth instance name is valid

    string name -- booth instance name
    """
    report_list = []
    if "/" in name:
        report_list.append(
            ReportItem.error(
                report.messages.BoothInvalidName(name,
                                                 forbidden_characters="/")))
    return report_list
示例#9
0
文件: env.py 项目: simhaonline/pcs
    def get_wait_timeout(self, wait):
        if wait is False:
            return False

        if wait not in self.__timeout_cache:
            if not self.is_cib_live:
                raise LibraryError(
                    ReportItem.error(
                        reports.messages.WaitForIdleNotLiveCluster()
                    )
                )
            self.__timeout_cache[wait] = get_valid_timeout_seconds(wait)
        return self.__timeout_cache[wait]
示例#10
0
def prepare_options_with_set(cib, options, resource_set_list):
    options = constraint.prepare_options(
        tuple(SCORE_NAMES),
        options,
        partial(constraint.create_id, cib, "colocation", resource_set_list),
        partial(check_new_id_applicable, cib, DESCRIPTION),
    )

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

    score_attrs_count = len(
        [name for name in options.keys() if name in SCORE_NAMES])
    if score_attrs_count > 1:
        raise LibraryError(
            ReportItem.error(reports.messages.MultipleScoreOptions()))

    if score_attrs_count == 0:
        options["score"] = SCORE_INFINITY

    return options
示例#11
0
文件: sbd.py 项目: nrwahl2/pcs
def get_local_sbd_config():
    """
    Get local SBD configuration.
    Returns SBD configuration file as string.
    Raises LibraryError on any failure.
    """
    try:
        with open(settings.sbd_config, "r") as sbd_cfg:
            return sbd_cfg.read()
    except EnvironmentError as e:
        raise LibraryError(
            ReportItem.error(
                reports.messages.UnableToGetSbdConfig("local node", str(e))))
示例#12
0
def _validate_level_target_devices_does_not_exist(
    tree, level, target_type, target_value, devices
) -> ReportItemList:
    report_list: ReportItemList = []
    if _find_level_elements(tree, level, target_type, target_value, devices):
        report_list.append(
            ReportItem.error(
                reports.messages.CibFencingLevelAlreadyExists(
                    level, target_type, target_value, devices
                )
            )
        )
    return report_list
示例#13
0
def _get_output_certificate(cert_tool_output, report_message_func):
    regexp = re.compile(r"^Certificate( request)? stored in (?P<path>.+)$")
    filename = None
    for line in cert_tool_output.splitlines():
        match = regexp.search(line)
        if match:
            filename = match.group("path")
    if not filename:
        raise LibraryError(
            ReportItem.error(report_message_func(cert_tool_output))
        )
    try:
        with open(filename, "rb") as cert_file:
            return cert_file.read()
    except EnvironmentError as e:
        raise LibraryError(
            ReportItem.error(
                report_message_func(
                    "{path}: {error}".format(path=filename, error=e.strerror)
                )
            )
        ) from e
示例#14
0
def client_destroy():
    """
    delete qdevice client config files on local host
    """
    try:
        if client_initialized():
            shutil.rmtree(settings.corosync_qdevice_net_client_certs_dir)
    except EnvironmentError as e:
        raise LibraryError(
            ReportItem.error(
                reports.messages.QdeviceDestroyError(__model, e.strerror)
            )
        ) from e
示例#15
0
def remove_ticket(conf_facade, ticket_name):
    """
    Validate removing a ticket from an existing booth config

    pcs.lib.booth.config_facade.ConfigFacade conf_facade -- a booth config
    string ticket_name -- the name of the ticket
    """
    if not conf_facade.has_ticket(ticket_name):
        return [
            ReportItem.error(
                report.messages.BoothTicketDoesNotExist(ticket_name))
        ]
    return []
示例#16
0
def client_setup(runner, ca_certificate):
    """
    initialize qdevice client on local host
    ca_certificate qnetd CA certificate
    """
    client_destroy()
    # save CA certificate, corosync tool only works with files
    ca_file_path = os.path.join(
        settings.corosync_qdevice_net_client_certs_dir,
        settings.corosync_qdevice_net_client_ca_file_name,
    )
    try:
        if not os.path.exists(ca_file_path):
            os.makedirs(
                settings.corosync_qdevice_net_client_certs_dir, mode=0o700
            )
        with open(ca_file_path, "wb") as ca_file:
            ca_file.write(ca_certificate)
    except EnvironmentError as e:
        raise LibraryError(
            ReportItem.error(
                reports.messages.QdeviceInitializationError(
                    __model, e.strerror,
                )
            )
        ) from e
    # initialize client's certificate storage
    stdout, stderr, retval = runner.run(
        [__qdevice_certutil, "-i", "-c", ca_file_path]
    )
    if retval != 0:
        raise LibraryError(
            ReportItem.error(
                reports.messages.QdeviceInitializationError(
                    __model, join_multilines([stderr, stdout]),
                )
            )
        )
示例#17
0
def history_get_text(env: LibraryEnvironment, node: Optional[str] = None):
    """
    Get full fencing history in plain text

    env
    node -- get history for the specified node or all nodes if None
    """
    runner = env.cmd_runner()
    if not is_fence_history_supported_management(runner):
        raise LibraryError(
            ReportItem.error(reports.messages.FenceHistoryNotSupported())
        )

    try:
        return fence_history_text(runner, node)
    except FenceHistoryCommandErrorException as e:
        raise LibraryError(
            ReportItem.error(
                reports.messages.FenceHistoryCommandError(
                    str(e), reports.const.FENCE_HISTORY_COMMAND_SHOW
                )
            )
        ) from e
示例#18
0
def history_cleanup(env: LibraryEnvironment, node: Optional[str] = None):
    """
    Clear fencing history

    env
    node -- clear history for the specified node or all nodes if None
    """
    runner = env.cmd_runner()
    if not is_fence_history_supported_management(runner):
        raise LibraryError(
            ReportItem.error(reports.messages.FenceHistoryNotSupported())
        )

    try:
        return fence_history_cleanup(runner, node)
    except FenceHistoryCommandErrorException as e:
        raise LibraryError(
            ReportItem.error(
                reports.messages.FenceHistoryCommandError(
                    str(e), reports.const.FENCE_HISTORY_COMMAND_CLEANUP
                )
            )
        ) from e
示例#19
0
 def _process_response(self, response):
     report = self._get_response_report(response)
     if report is not None:
         self._report(report)
         return
     target = response.request.target
     try:
         self._output_data.append((target, base64.b64decode(response.data)))
     except (TypeError, binascii.Error):
         self._report(
             ReportItem.error(
                 reports.messages.InvalidResponseFormat(target.label)
             )
         )
示例#20
0
def _service_kill(lib_env: LibraryEnvironment, func):
    try:
        func(lib_env.cmd_runner())
    except external.KillServicesError as e:
        raise LibraryError(*[
            ReportItem.error(
                reports.messages.ServiceActionFailed(
                    reports.const.SERVICE_ACTION_KILL, service, e.message))
            for service in e.service
        ])
    lib_env.report_processor.report(
        ReportItem.info(
            reports.messages.ServiceActionSucceeded(
                reports.const.SERVICE_ACTION_KILL, "quorum device")))
示例#21
0
文件: booth.py 项目: simhaonline/pcs
 def _process_response(self, response):
     report = self._get_response_report(response)
     if report is not None:
         self._report(report)
         return
     target = response.request.target
     try:
         self._data.append((target, json.loads(response.data)))
     except ValueError:
         self._report(
             ReportItem.error(
                 reports.messages.InvalidResponseFormat(target.label)
             )
         )
示例#22
0
文件: values.py 项目: simhaonline/pcs
def get_valid_timeout_seconds(timeout_candidate):
    """
    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(timeout_candidate)))
    return wait_timeout
示例#23
0
def _validate_container(container_type,
                        container_options,
                        force_options=False):
    if container_type not in GENERIC_CONTAINER_TYPES:
        return [
            ReportItem.error(
                reports.messages.InvalidOptionValue(
                    "container type",
                    container_type,
                    GENERIC_CONTAINER_TYPES,
                ))
        ]
    return _validate_generic_container_options(container_options,
                                               force_options)
示例#24
0
def qdevice_start(lib_env: LibraryEnvironment, model):
    """
    start qdevice now on local host
    """
    _check_model(model)
    if not qdevice_net.qdevice_initialized():
        raise LibraryError(
            ReportItem.error(reports.messages.QdeviceNotInitialized(model))
        )
    _service_start(
        lib_env.report_processor,
        lib_env.service_manager,
        qdevice_net.SERVICE_NAME,
    )
示例#25
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
示例#26
0
文件: nodes.py 项目: vvidic/pcs
 def _process_response(self, response):
     report = self._get_response_report(response)
     if report:
         self._report(report)
         return
     host_name = response.request.target.label
     try:
         self._responses[host_name] = json.loads(response.data)
     except json.JSONDecodeError:
         self._report(
             ReportItem.error(
                 reports.messages.InvalidResponseFormat(host_name)
             )
         )
示例#27
0
文件: sbd.py 项目: zht750808/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
    ]
示例#28
0
文件: ticket.py 项目: kmalyjur/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
示例#29
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:
         raise LibraryError(
             ReportItem.error(
                 reports.messages.ParseErrorCorosyncConfMissingClosingBrace()
             )
         )
     except config_parser.UnexpectedClosingBraceException:
         # pylint: disable=line-too-long
         raise LibraryError(
             ReportItem.error(
                 reports.messages.ParseErrorCorosyncConfUnexpectedClosingBrace()
             )
         )
     except config_parser.MissingSectionNameBeforeOpeningBraceException:
         # pylint: disable=line-too-long
         raise LibraryError(
             ReportItem.error(
                 reports.messages.ParseErrorCorosyncConfMissingSectionNameBeforeOpeningBrace()
             )
         )
     except config_parser.ExtraCharactersAfterOpeningBraceException:
         # pylint: disable=line-too-long
         raise LibraryError(
             ReportItem.error(
                 reports.messages.ParseErrorCorosyncConfExtraCharactersAfterOpeningBrace()
             )
         )
     except config_parser.ExtraCharactersBeforeOrAfterClosingBraceException:
         # pylint: disable=line-too-long
         raise LibraryError(
             ReportItem.error(
                 reports.messages.ParseErrorCorosyncConfExtraCharactersBeforeOrAfterClosingBrace()
             )
         )
     except config_parser.LineIsNotSectionNorKeyValueException:
         # pylint: disable=line-too-long
         raise LibraryError(
             ReportItem.error(
                 reports.messages.ParseErrorCorosyncConfLineIsNotSectionNorKeyValue()
             )
         )
     except config_parser.CorosyncConfParserException:
         raise LibraryError(
             ReportItem.error(reports.messages.ParseErrorCorosyncConf())
         )
示例#30
0
def create(site_list, arbitrator_list):
    """
    Validate creating a minimal booth config

    iterable site_list -- list of booth sites' addresses
    iterable arbitrator_list -- list of arbitrators' addresses
    """
    report_list = []
    peer_list = site_list + arbitrator_list

    if len(site_list) < 2:
        report_list.append(
            ReportItem.error(
                report.messages.BoothLackOfSites(sorted(site_list))
            )
        )

    if len(peer_list) % 2 == 0:
        report_list.append(
            ReportItem.error(
                report.messages.BoothEvenPeersNumber(len(peer_list))
            )
        )

    duplicate_addresses = {
        address for address, count in Counter(peer_list).items() if count > 1
    }
    if duplicate_addresses:
        report_list.append(
            ReportItem.error(
                report.messages.BoothAddressDuplication(
                    sorted(duplicate_addresses)
                )
            )
        )

    return report_list