Esempio n. 1
0
def process_library_reports(report_item_list):
    """
    report_item_list list of ReportItem
    """
    if not report_item_list:
        raise error(
            "Errors have occurred, therefore pcs is unable to continue")

    critical_error = False
    for report_item in report_item_list:
        if report_item.severity == ReportItemSeverity.WARNING:
            warn(build_report_message(report_item))
            continue

        if report_item.severity != ReportItemSeverity.ERROR:
            print(build_report_message(report_item))
            continue

        error(
            build_report_message(report_item,
                                 _prepare_force_text(report_item)))
        critical_error = True

    if critical_error:
        sys.exit(1)
Esempio n. 2
0
    def apply(next_in_line, env, *args, **kwargs):
        if filename:
            touch_cib_file(filename)
            try:
                with open(filename, mode="r") as cib_file:
                    original_content = cib_file.read()
            except EnvironmentError as e:
                raise error(
                    "Cannot read cib file '{0}': '{1}'"
                    .format(filename, str(e))
                )
            env.cib_data = original_content

        result_of_next = next_in_line(env, *args, **kwargs)

        if filename and env.cib_data != original_content:
            try:
                with open(filename, mode="w") as cib_file:
                    cib_file.write(env.cib_data)
            except EnvironmentError as e:
                raise error(
                    "Cannot write cib file '{0}': '{1}'"
                    .format(filename, str(e))
                )

        return result_of_next
Esempio n. 3
0
def stonith_create(lib, argv, modifiers):
    if modifiers["before"] and modifiers["after"]:
        raise error("you cannot specify both --before and --after{0}".format(
            "" if modifiers["group"] else " and you have to specify --group"
        ))

    if not modifiers["group"]:
        if modifiers["before"]:
            raise error("you cannot use --before without --group")
        elif modifiers["after"]:
            raise error("you cannot use --after without --group")

    if len(argv) < 2:
        usage.stonith(["create"])
        sys.exit(1)

    stonith_id = argv[0]
    stonith_type = argv[1]

    parts = parse_create_args(argv[2:])

    settings = dict(
        allow_absent_agent=modifiers["force"],
        allow_invalid_operation=modifiers["force"],
        allow_invalid_instance_attributes=modifiers["force"],
        ensure_disabled=modifiers["disabled"],
        use_default_operations=not modifiers["no-default-ops"],
        wait=modifiers["wait"],
    )

    if not modifiers["group"]:
        lib.stonith.create(
            stonith_id, stonith_type, parts["op"],
            parts["meta"],
            parts["options"],
            **settings
        )
    else:
        adjacent_resource_id = None
        put_after_adjacent = False
        if modifiers["after"]:
            adjacent_resource_id = modifiers["after"]
            put_after_adjacent = True
        if modifiers["before"]:
            adjacent_resource_id = modifiers["before"]
            put_after_adjacent = False

        lib.stonith.create_in_group(
            stonith_id, stonith_type, modifiers["group"], parts["op"],
            parts["meta"],
            parts["options"],
            adjacent_resource_id=adjacent_resource_id,
            put_after_adjacent=put_after_adjacent,
            **settings
        )
Esempio n. 4
0
def stonith_create(lib, argv, modifiers):
    if modifiers["before"] and modifiers["after"]:
        raise error("you cannot specify both --before and --after{0}".format(
            "" if modifiers["group"] else " and you have to specify --group"
        ))

    if not modifiers["group"]:
        if modifiers["before"]:
            raise error("you cannot use --before without --group")
        elif modifiers["after"]:
            raise error("you cannot use --after without --group")

    if len(argv) < 2:
        usage.stonith(["create"])
        sys.exit(1)

    stonith_id = argv[0]
    stonith_type = argv[1]

    parts = parse_create_args(argv[2:])

    settings = dict(
        allow_absent_agent=modifiers["force"],
        allow_invalid_operation=modifiers["force"],
        allow_invalid_instance_attributes=modifiers["force"],
        ensure_disabled=modifiers["disabled"],
        use_default_operations=not modifiers["no-default-ops"],
        wait=modifiers["wait"],
    )

    if not modifiers["group"]:
        lib.stonith.create(
            stonith_id, stonith_type, parts["op"],
            parts["meta"],
            parts["options"],
            **settings
        )
    else:
        adjacent_resource_id = None
        put_after_adjacent = False
        if modifiers["after"]:
            adjacent_resource_id = modifiers["after"]
            put_after_adjacent = True
        if modifiers["before"]:
            adjacent_resource_id = modifiers["before"]
            put_after_adjacent = False

        lib.stonith.create_in_group(
            stonith_id, stonith_type, modifiers["group"], parts["op"],
            parts["meta"],
            parts["options"],
            adjacent_resource_id=adjacent_resource_id,
            put_after_adjacent=put_after_adjacent,
            **settings
        )
Esempio n. 5
0
File: env.py Progetto: junaruga/pcs
def middleware_config(name, config_path, key_path):
    if config_path and not key_path:
        raise console_report.error(
            "With --booth-conf must be specified --booth-key as well")

    if key_path and not config_path:
        raise console_report.error(
            "With --booth-key must be specified --booth-conf as well")

    is_mocked_environment = config_path and key_path

    def create_booth_env():
        if not is_mocked_environment:
            return {"name": name}
        return {
            "name": name,
            "config_file": env_file.read(config_path),
            "key_file": env_file.read(key_path, is_binary=True),
            "key_path": key_path,
        }

    def flush(modified_env):
        if not is_mocked_environment:
            return
        if not modified_env:
            #TODO now this would not happen
            #for more information see comment in
            #pcs.cli.common.lib_wrapper.lib_env_to_cli_env
            raise console_report.error("Error during library communication")

        env_file.process_no_existing_file_expectation(
            "booth config file", modified_env["config_file"], config_path)
        env_file.process_no_existing_file_expectation("booth key file",
                                                      modified_env["key_file"],
                                                      key_path)
        env_file.write(modified_env["key_file"], key_path)
        env_file.write(modified_env["config_file"], config_path)

    def apply(next_in_line, env, *args, **kwargs):
        env.booth = create_booth_env()
        try:
            result_of_next = next_in_line(env, *args, **kwargs)
        except LibraryEnvError as e:
            missing_file = env_file.MissingFileCandidateInfo

            env_file.evaluate_for_missing_files(e, [
                missing_file(BOOTH_CONFIG, "Booth config file", config_path),
                missing_file(BOOTH_KEY, "Booth key file", key_path),
            ])
            raise e
        flush(env.booth["modified_env"])
        return result_of_next

    return apply
Esempio n. 6
0
 def _do_report(self, report_item: ReportItem) -> None:
     if report_item.severity == ReportItemSeverity.ERROR:
         error(
             build_report_message(report_item,
                                  _prepare_force_text(report_item)))
     elif report_item.severity == ReportItemSeverity.WARNING:
         warn(build_report_message(report_item))
     elif self.debug or report_item.severity != ReportItemSeverity.DEBUG:
         msg = build_report_message(report_item)
         if msg:
             print(msg)
Esempio n. 7
0
 def _send(self, report_item_list, print_errors=True):
     errors = []
     for report_item in report_item_list:
         if report_item.severity == ReportItemSeverity.ERROR:
             if print_errors:
                 error(build_report_message(report_item))
             errors.append(report_item)
         elif report_item.severity == ReportItemSeverity.WARNING:
             warn(build_report_message(report_item))
         elif self.debug or report_item.severity != ReportItemSeverity.DEBUG:
             print(build_report_message(report_item))
     return errors
Esempio n. 8
0
def status(
    lib: Any,
    argv: Sequence[str],
    modifiers: InputModifiers,
) -> None:
    """
    Options:
      * --full - show full details, node attributes and failcount
      * --hide-inactive - hide inactive resources
      * --request-timeout - HTTP timeout for node authorization check
    """
    modifiers.ensure_only_supported(
        "--full",
        "--hide-inactive",
        "--request-timeout",
    )
    if argv:
        raise CmdLineInputError()

    status_list_raw = lib.dr.status_all_sites_plaintext(
        hide_inactive_resources=modifiers.get("--hide-inactive"),
        verbose=modifiers.get("--full"),
    )
    try:
        status_list = [
            dto.from_dict(DrSiteStatusDto, status_raw)
            for status_raw in status_list_raw
        ]
    except (KeyError, TypeError, ValueError):
        raise error("Unable to communicate with pcsd, received response:\n"
                    f"{status_list_raw}")

    has_errors = False
    plaintext_parts = []
    for site_status in status_list:
        plaintext_parts.append(
            "--- {local_remote} cluster - {role} site ---".format(
                local_remote=("Local" if site_status.local_site else "Remote"),
                role=site_status.site_role.capitalize()))
        if site_status.status_successfully_obtained:
            plaintext_parts.append(site_status.status_plaintext.strip())
            plaintext_parts.extend(["", ""])
        else:
            has_errors = True
            plaintext_parts.extend([
                "Error: Unable to get status of the cluster from any node", ""
            ])
    print("\n".join(plaintext_parts).strip())
    if has_errors:
        raise error("Unable to get status of all sites")
Esempio n. 9
0
def process_library_reports(report_item_list):
    """
    report_item_list list of ReportItem
    """
    if not report_item_list:
        raise error("Errors have occurred, therefore pcs is unable to continue")

    critical_error = False
    for report_item in report_item_list:
        if report_item.severity == ReportItemSeverity.WARNING:
            print("Warning: " + build_report_message(report_item))
            continue

        if report_item.severity != ReportItemSeverity.ERROR:
            print(build_report_message(report_item))
            continue

        sys.stderr.write('Error: {0}\n'.format(build_report_message(
            report_item,
            _prepare_force_text(report_item)
        )))
        critical_error = True

    if critical_error:
        sys.exit(1)
Esempio n. 10
0
 def flush(modified_env):
     if not is_mocked_environment:
         return
     if not modified_env:
         #TODO now this would not happen
         #for more information see comment in
         #pcs.cli.common.lib_wrapper.lib_env_to_cli_env
         raise console_report.error("Error during library communication")
     try:
         key_file.write(
             modified_env["key_file"]["content"],
             can_overwrite=True
         )
         config_file.write(
             modified_env["config_file"]["content"],
             can_overwrite=True
         )
     # TODO write custom error handling, do not use pcs.lib specific code
     # and LibraryError
     except pcs_file.RawFileError as e:
         raise LibraryError(
             reports.file_io_error(
                 e.metadata.file_type_code,
                 e.action,
                 e.reason,
                 file_path=e.metadata.path,
             )
         )
Esempio n. 11
0
def process_no_existing_file_expectation(file_role, env_file, file_path):
    if (env_file["no_existing_file_expected"] and os.path.exists(file_path)):
        msg = "{0} {1} already exists".format(file_role, file_path)
        if not env_file["can_overwrite_existing_file"]:
            raise console_report.error(
                "{0}, use --force to override".format(msg))
        console_report.warn(msg)
Esempio n. 12
0
 def _send(self, report_item_list, print_errors=True):
     errors = []
     for report_item in report_item_list:
         if report_item.severity == ReportItemSeverity.ERROR:
             if print_errors:
                 error(build_report_message(
                     report_item,
                     _prepare_force_text(report_item)
                 ))
             errors.append(report_item)
         elif report_item.severity == ReportItemSeverity.WARNING:
             warn(build_report_message(report_item))
         elif self.debug or report_item.severity != ReportItemSeverity.DEBUG:
             msg = build_report_message(report_item)
             if msg:
                 print(msg)
     return errors
Esempio n. 13
0
    def apply(next_in_line, env, *args, **kwargs):
        if local_file_path:
            try:
                env.cluster_conf_data = open(local_file_path).read()
            except EnvironmentError as e:
                raise console_report.error("Unable to read {0}: {1}".format(local_file_path, e.strerror))

        return next_in_line(env, *args, **kwargs)
Esempio n. 14
0
def write(env_file, file_path):
    try:
        f = open(file_path, "wb" if env_file.get("is_binary", False) else "w")
        f.write(env_file["content"])
        f.close()
    except EnvironmentError as e:
        raise console_report.error("Unable to write {0}: {1}".format(
            file_path, e.strerror))
Esempio n. 15
0
    def apply(next_in_line, env, *args, **kwargs):
        if local_file_path:
            try:
                env.corosync_conf_data = open(local_file_path).read()
            except EnvironmentError as e:
                raise console_report.error("Unable to read {0}: {1}".format(local_file_path, e.strerror))

        result_of_next = next_in_line(env, *args, **kwargs)

        if local_file_path:
            try:
                f = open(local_file_path, "w")
                f.write(env.corosync_conf_data)
                f.close()
            except EnvironmentError as e:
                raise console_report.error("Unable to write {0}: {1}".format(local_file_path, e.strerror))
        return result_of_next
Esempio n. 16
0
def read_env_file(path):
    try:
        return {
            "content": open(path).read() if os.path.isfile(path) else None
        }
    except EnvironmentError as e:
        raise console_report.error(
            "Unable to read {0}: {1}".format(path, e.strerror)
        )
Esempio n. 17
0
def write_env_file(env_file, file_path):
    try:
        f = open(file_path, "wb" if env_file.get("is_binary", False) else "w")
        f.write(env_file["content"])
        f.close()
    except EnvironmentError as e:
        raise console_report.error(
            "Unable to write {0}: {1}".format(file_path, e.strerror)
        )
Esempio n. 18
0
    def apply(next_in_line, env, *args, **kwargs):
        if local_file_path:
            try:
                env.cluster_conf_data = open(local_file_path).read()
            except EnvironmentError as e:
                raise error("Unable to read {0}: {1}".format(
                    local_file_path, e.strerror))

        return next_in_line(env, *args, **kwargs)
Esempio n. 19
0
    def apply(next_in_line, env, *args, **kwargs):
        if local_file_path:
            try:
                env.corosync_conf_data = open(local_file_path).read()
            except EnvironmentError as e:
                raise error("Unable to read {0}: {1}".format(
                    local_file_path, e.strerror))

        result_of_next = next_in_line(env, *args, **kwargs)

        if local_file_path:
            try:
                f = open(local_file_path, "w")
                f.write(env.corosync_conf_data)
                f.close()
            except EnvironmentError as e:
                raise error("Unable to write {0}: {1}".format(
                    local_file_path, e.strerror))
        return result_of_next
Esempio n. 20
0
def read(path, is_binary=False):
    try:
        mode = "rb" if is_binary else "r"
        return {
            "content":
            open(path, mode).read() if os.path.isfile(path) else None
        }
    except EnvironmentError as e:
        raise console_report.error("Unable to read {0}: {1}".format(
            path, e.strerror))
Esempio n. 21
0
def read(path, is_binary=False):
    try:
        mode = "rb" if is_binary else "r"
        return {
            "content": open(path, mode).read() if os.path.isfile(path) else None
        }
    except EnvironmentError as e:
        raise console_report.error(
            "Unable to read {0}: {1}".format(path, e.strerror)
        )
Esempio n. 22
0
def remove(lib, argv, modifiers):
    """
    Options:
      * -f - CIB file
    """
    modifiers.ensure_only_supported("-f")
    if len(argv) != 2:
        raise CmdLineInputError()
    ticket, resource_id = argv
    if not lib.constraint_ticket.remove(ticket, resource_id):
        raise error("no matching ticket constraint found")
Esempio n. 23
0
def remove(lib, argv, modifiers):
    """
    Options:
      * -f - CIB file
    """
    modifiers.ensure_only_supported("-f")
    if len(argv) != 2:
        raise CmdLineInputError()
    ticket, resource_id = argv
    if not lib.constraint_ticket.remove(ticket, resource_id):
        raise error("no matching ticket constraint found")
Esempio n. 24
0
def process_no_existing_file_expectation(file_role, env_file, file_path):
    if(
        env_file["no_existing_file_expected"]
        and
        os.path.exists(file_path)
    ):
        msg = "{0} {1} already exists".format(file_role, file_path)
        if not env_file["can_overwrite_existing_file"]:
            raise console_report.error(
                "{0}, use --force to override".format(msg)
            )
        console_report.warn(msg)
Esempio n. 25
0
File: env.py Progetto: junaruga/pcs
    def flush(modified_env):
        if not is_mocked_environment:
            return
        if not modified_env:
            #TODO now this would not happen
            #for more information see comment in
            #pcs.cli.common.lib_wrapper.lib_env_to_cli_env
            raise console_report.error("Error during library communication")

        env_file.process_no_existing_file_expectation(
            "booth config file", modified_env["config_file"], config_path)
        env_file.process_no_existing_file_expectation("booth key file",
                                                      modified_env["key_file"],
                                                      key_path)
        env_file.write(modified_env["key_file"], key_path)
        env_file.write(modified_env["config_file"], config_path)
Esempio n. 26
0
    def flush(modified_env):
        if not is_mocked_environment:
            return
        if not modified_env:
            #TODO now this would not happen
            #for more information see comment in
            #pcs.cli.common.lib_wrapper.lib_env_to_cli_env
            raise console_report.error("Error during library communication")

        process_no_existing_file_expectation(
            "booth config file",
            modified_env["config_file"],
            config_path
        )
        process_no_existing_file_expectation(
            "booth key file",
            modified_env["key_file"],
            key_path
        )
        write_env_file(modified_env["key_file"], key_path)
        write_env_file(modified_env["config_file"], config_path)
Esempio n. 27
0
def get_capabilities_definition():
    """
    Read and parse capabilities file

    The point is to return all data in python structures for further processing.
    """
    filename = os.path.join(settings.pcsd_exec_location, "capabilities.xml")
    try:
        with open(filename, mode="r") as file_:
            capabilities_xml = xml_fromstring(file_.read())
    except (EnvironmentError, etree.XMLSyntaxError, etree.DocumentInvalid) as e:
        raise error(
            "Cannot read capabilities definition file '{0}': '{1}'"
            .format(filename, str(e))
        )
    capabilities = []
    for feat_xml in capabilities_xml.findall(".//capability"):
        feat = dict(feat_xml.attrib)
        desc = feat_xml.find("./description")
        # dedent and strip remove indentation in the XML file
        feat["description"] = "" if desc is None else dedent(desc.text).strip()
        capabilities.append(feat)
    return capabilities
Esempio n. 28
0
def get_capabilities_definition():
    """
    Read and parse capabilities file

    The point is to return all data in python structures for further processing.
    """
    filename = os.path.join(get_pcsd_dir(), "capabilities.xml")
    try:
        with open(filename, mode="r") as file_:
            capabilities_xml = xml_fromstring(file_.read())
    except (EnvironmentError, etree.XMLSyntaxError,
            etree.DocumentInvalid) as e:
        raise error(
            "Cannot read capabilities definition file '{0}': '{1}'".format(
                filename, str(e)))
    capabilities = []
    for feat_xml in capabilities_xml.findall(".//capability"):
        feat = dict(feat_xml.attrib)
        desc = feat_xml.find("./description")
        # dedent and strip remove indentation in the XML file
        feat["description"] = "" if desc is None else dedent(desc.text).strip()
        capabilities.append(feat)
    return capabilities
Esempio n. 29
0
def config(
    lib: Any,
    argv: Sequence[str],
    modifiers: InputModifiers,
) -> None:
    """
    Options: None
    """
    modifiers.ensure_only_supported()
    if argv:
        raise CmdLineInputError()
    config_raw = lib.dr.get_config()
    try:
        config_dto = dto.from_dict(DrConfigDto, config_raw)
    except (KeyError, TypeError, ValueError):
        raise error("Unable to communicate with pcsd, received response:\n"
                    f"{config_raw}")

    lines = ["Local site:"]
    lines.extend(indent(_config_site_lines(config_dto.local_site)))
    for site_dto in config_dto.remote_site_list:
        lines.append("Remote site:")
        lines.extend(indent(_config_site_lines(site_dto)))
    print("\n".join(lines))
Esempio n. 30
0
def cluster_verify(argv):
    if len(argv) > 1:
        usage.cluster("verify")
        raise SystemExit(1)

    if argv:
        filename = argv[0]
        if not utils.usefile:
            #We must operate on given cib everywhere.
            utils.usefile = True
            utils.filename = filename
        elif os.path.abspath(filename) == os.path.abspath(utils.filename):
            warn("File '{0}' specified twice".format(
                os.path.abspath(filename)))
        else:
            raise error(
                "Ambiguous cib filename specification: '{0}' vs  -f '{1}'".
                format(filename, utils.filename))

    lib = utils.get_library_wrapper()
    try:
        lib.cluster.verify(verbose="-V" in utils.pcs_options)
    except LibraryError as e:
        utils.process_library_reports(e.args)
Esempio n. 31
0
def report_missing_file(file_role, file_path):
    console_report.error(
        "{0} '{1}' does not exist".format(file_role, file_path)
    )
Esempio n. 32
0
def middleware_config(config_path, key_path):
    if config_path and not key_path:
        raise console_report.error(
            "When --booth-conf is specified, "
            "--booth-key must be specified as well"
        )
    if key_path and not config_path:
        raise console_report.error(
            "When --booth-key is specified, "
            "--booth-conf must be specified as well"
        )
    is_mocked_environment = config_path and key_path

    if is_mocked_environment:
        config_file = pcs_file.RawFile(
            metadata.for_file_type(
                file_type_codes.BOOTH_CONFIG, config_path
            )
        )
        key_file = pcs_file.RawFile(
            metadata.for_file_type(
                file_type_codes.BOOTH_KEY, key_path
            )
        )

    def create_booth_env():
        try:
            config_data = config_file.read() if config_file.exists() else None
            key_data = key_file.read() if key_file.exists() else None
        # TODO write custom error handling, do not use pcs.lib specific code
        # and LibraryError
        except pcs_file.RawFileError as e:
            raise LibraryError(
                reports.file_io_error(
                    e.metadata.file_type_code,
                    e.action,
                    e.reason,
                    file_path=e.metadata.path,
                )
            )
        return {
            "config_data": config_data,
            "key_data": key_data,
            "key_path": key_path,
        }

    def flush(modified_env):
        if not is_mocked_environment:
            return
        if not modified_env:
            #TODO now this would not happen
            #for more information see comment in
            #pcs.cli.common.lib_wrapper.lib_env_to_cli_env
            raise console_report.error("Error during library communication")
        try:
            key_file.write(
                modified_env["key_file"]["content"],
                can_overwrite=True
            )
            config_file.write(
                modified_env["config_file"]["content"],
                can_overwrite=True
            )
        # TODO write custom error handling, do not use pcs.lib specific code
        # and LibraryError
        except pcs_file.RawFileError as e:
            raise LibraryError(
                reports.file_io_error(
                    e.metadata.file_type_code,
                    e.action,
                    e.reason,
                    file_path=e.metadata.path,
                )
            )

    def apply(next_in_line, env, *args, **kwargs):
        env.booth = create_booth_env() if is_mocked_environment else {}
        result_of_next = next_in_line(env, *args, **kwargs)
        if is_mocked_environment:
            flush(env.booth["modified_env"])
        return result_of_next

    return apply
Esempio n. 33
0
def remove(lib, argv, modificators):
    if len(argv) != 2:
        raise CmdLineInputError()
    ticket, resource_id = argv
    if not lib.constraint_ticket.remove(ticket, resource_id):
        raise error("no matching ticket constraint found")
Esempio n. 34
0
def middleware_config(name, config_path, key_path):
    if config_path and not key_path:
        raise console_report.error(
            "With --booth-conf must be specified --booth-key as well"
        )

    if key_path and not config_path:
        raise console_report.error(
            "With --booth-key must be specified --booth-conf as well"
        )

    is_mocked_environment = config_path and key_path

    def create_booth_env():
        if not is_mocked_environment:
            return {"name": name}
        return {
            "name": name,
            "config_file": env_file.read(config_path),
            "key_file": env_file.read(key_path, is_binary=True),
            "key_path": key_path,
        }

    def flush(modified_env):
        if not is_mocked_environment:
            return
        if not modified_env:
            #TODO now this would not happen
            #for more information see comment in
            #pcs.cli.common.lib_wrapper.lib_env_to_cli_env
            raise console_report.error("Error during library communication")

        env_file.process_no_existing_file_expectation(
            "booth config file",
            modified_env["config_file"],
            config_path
        )
        env_file.process_no_existing_file_expectation(
            "booth key file",
            modified_env["key_file"],
            key_path
        )
        env_file.write(modified_env["key_file"], key_path)
        env_file.write(modified_env["config_file"], config_path)

    def apply(next_in_line, env, *args, **kwargs):
        env.booth = create_booth_env()
        try:
            result_of_next = next_in_line(env, *args, **kwargs)
        except LibraryEnvError as err:
            missing_file = env_file.MissingFileCandidateInfo

            env_file.evaluate_for_missing_files(err, [
                missing_file(BOOTH_CONFIG, "Booth config file", config_path),
                missing_file(BOOTH_KEY, "Booth key file", key_path),
            ])
            raise err
        flush(env.booth["modified_env"])
        return result_of_next

    return apply
Esempio n. 35
0
def cluster_remote_node(argv):
    usage_add = """\
    remote-node add <hostname> <resource id> [options]
        Enables the specified resource as a remote-node resource on the
        specified hostname (hostname should be the same as 'uname -n')."""
    usage_remove = """\
    remote-node remove <hostname>
        Disables any resources configured to be remote-node resource on the
        specified hostname (hostname should be the same as 'uname -n')."""

    if len(argv) < 1:
        print("\nUsage: pcs cluster remote-node...")
        print(usage_add)
        print()
        print(usage_remove)
        print()
        sys.exit(1)

    command = argv.pop(0)
    if command == "add":
        if len(argv) < 2:
            print("\nUsage: pcs cluster remote-node add...")
            print(usage_add)
            print()
            sys.exit(1)
        if "--force" in utils.pcs_options:
            warn(
                "this command is deprecated, use 'pcs cluster node add-guest'")
        else:
            raise error(
                "this command is deprecated, use 'pcs cluster node add-guest'"
                ", use --force to override")
        hostname = argv.pop(0)
        rsc = argv.pop(0)
        if not utils.dom_get_resource(utils.get_cib_dom(), rsc):
            utils.err("unable to find resource '%s'" % rsc)
        resource.resource_update(rsc,
                                 ["meta", "remote-node=" + hostname] + argv,
                                 deal_with_guest_change=False)

    elif command in ["remove", "delete"]:
        if len(argv) < 1:
            print("\nUsage: pcs cluster remote-node remove...")
            print(usage_remove)
            print()
            sys.exit(1)
        if "--force" in utils.pcs_options:
            warn("this command is deprecated, use"
                 " 'pcs cluster node remove-guest'")
        else:
            raise error("this command is deprecated, use 'pcs cluster node"
                        " remove-guest', use --force to override")
        hostname = argv.pop(0)
        dom = utils.get_cib_dom()
        nvpairs = dom.getElementsByTagName("nvpair")
        nvpairs_to_remove = []
        for nvpair in nvpairs:
            if nvpair.getAttribute(
                    "name") == "remote-node" and nvpair.getAttribute(
                        "value") == hostname:
                for np in nvpair.parentNode.getElementsByTagName("nvpair"):
                    if np.getAttribute("name").startswith("remote-"):
                        nvpairs_to_remove.append(np)

        if len(nvpairs_to_remove) == 0:
            utils.err("unable to remove: cannot find remote-node '%s'" %
                      hostname)

        for nvpair in nvpairs_to_remove[:]:
            nvpair.parentNode.removeChild(nvpair)
        dom = constraint.remove_constraints_containing_node(dom, hostname)
        utils.replace_cib_configuration(dom)
        if not utils.usefile:
            output, retval = utils.run(
                ["crm_node", "--force", "--remove", hostname])
            if retval != 0:
                utils.err("unable to remove: {0}".format(output))
    else:
        print("\nUsage: pcs cluster remote-node...")
        print(usage_add)
        print()
        print(usage_remove)
        print()
        sys.exit(1)
Esempio n. 36
0
def stonith_create(lib, argv, modifiers):
    """
    Options:
      * --before - specified resource inside a group before which new resource
        will be placed inside the group
      * --after - specified resource inside a group after which new resource
        will be placed inside the group
      * --group - specifies group in which resource will be created
      * --force - allow not existing agent, invalid operations or invalid
        instance attributes
      * --disabled - created reource will be disabled
      * --no-default-ops - do not add default operations
      * --wait
      * -f - CIB file
    """
    modifiers.ensure_only_supported(
        "--before",
        "--after",
        "--group",
        "--force",
        "--disabled",
        "--no-default-ops",
        "--wait",
        "-f",
    )
    if modifiers.is_specified("--before") and modifiers.is_specified(
            "--after"):
        raise error("you cannot specify both --before and --after{0}".format(
            "" if modifiers.
            is_specified("--group") else " and you have to specify --group"))

    if not modifiers.is_specified("--group"):
        if modifiers.is_specified("--before"):
            raise error("you cannot use --before without --group")
        elif modifiers.is_specified("--after"):
            raise error("you cannot use --after without --group")

    if len(argv) < 2:
        raise CmdLineInputError()

    stonith_id = argv[0]
    stonith_type = argv[1]

    parts = parse_create_args(argv[2:])

    settings = dict(
        allow_absent_agent=modifiers.get("--force"),
        allow_invalid_operation=modifiers.get("--force"),
        allow_invalid_instance_attributes=modifiers.get("--force"),
        ensure_disabled=modifiers.get("--disabled"),
        use_default_operations=not modifiers.get("--no-default-ops"),
        wait=modifiers.get("--wait"),
    )

    if not modifiers.get("--group"):
        lib.stonith.create(stonith_id, stonith_type, parts["op"],
                           parts["meta"], parts["options"], **settings)
    else:
        adjacent_resource_id = None
        put_after_adjacent = False
        if modifiers.get("--after"):
            adjacent_resource_id = modifiers.get("--after")
            put_after_adjacent = True
        if modifiers.get("--before"):
            adjacent_resource_id = modifiers.get("--before")
            put_after_adjacent = False

        lib.stonith.create_in_group(stonith_id,
                                    stonith_type,
                                    modifiers.get("--group"),
                                    parts["op"],
                                    parts["meta"],
                                    parts["options"],
                                    adjacent_resource_id=adjacent_resource_id,
                                    put_after_adjacent=put_after_adjacent,
                                    **settings)
Esempio n. 37
0
def middleware_config(name, config_path, key_path):
    if config_path and not key_path:
        raise console_report.error(
            "With --booth-conf must be specified --booth-key as well"
        )

    if key_path and not config_path:
        raise console_report.error(
            "With --booth-key must be specified --booth-conf as well"
        )

    is_mocked_environment = config_path and key_path

    def create_booth_env():
        if not is_mocked_environment:
            return {"name": name}
        return {
            "name": name,
            "config_file": read_env_file(config_path),
            "key_file": read_env_file(key_path),
            "key_path": key_path,
        }

    def flush(modified_env):
        if not is_mocked_environment:
            return
        if not modified_env:
            #TODO now this would not happen
            #for more information see comment in
            #pcs.cli.common.lib_wrapper.lib_env_to_cli_env
            raise console_report.error("Error during library communication")

        process_no_existing_file_expectation(
            "booth config file",
            modified_env["config_file"],
            config_path
        )
        process_no_existing_file_expectation(
            "booth key file",
            modified_env["key_file"],
            key_path
        )
        write_env_file(modified_env["key_file"], key_path)
        write_env_file(modified_env["config_file"], config_path)

    def apply(next_in_line, env, *args, **kwargs):
        env.booth = create_booth_env()
        try:
            result_of_next = next_in_line(env, *args, **kwargs)
        except LibraryEnvError as e:
            for report in e.args:
                if is_missing_file_report(report, file_role_codes.BOOTH_CONFIG):
                    report_missing_file("Booth config file", config_path)
                    e.sign_processed(report)
                if is_missing_file_report(report, file_role_codes.BOOTH_KEY):
                    report_missing_file("Booth key file", key_path)
                    e.sign_processed(report)
            raise e
        flush(env.booth["modified_env"])
        return result_of_next

    return apply
Esempio n. 38
0
def location_add(lib, argv, modifiers):
    """
    Options:
      * --force - allow unknown options, allow constraint for any resource type
      * -f - CIB file
    """
    del lib
    modifiers.ensure_only_supported("--force", "-f")
    if len(argv) < 4:
        raise CmdLineInputError()

    constraint_id = argv.pop(0)
    rsc_type, rsc_value = parse_args.parse_typed_arg(
        argv.pop(0), [RESOURCE_TYPE_RESOURCE, RESOURCE_TYPE_REGEXP],
        RESOURCE_TYPE_RESOURCE)
    node = argv.pop(0)
    score = argv.pop(0)
    options = []
    # For now we only allow setting resource-discovery
    if argv:
        for arg in argv:
            if '=' in arg:
                options.append(arg.split('=', 1))
            else:
                raise CmdLineInputError(f"bad option '{arg}'")
            if (options[-1][0] != "resource-discovery"
                    and not modifiers.get("--force")):
                utils.err("bad option '%s', use --force to override" %
                          options[-1][0])

    id_valid, id_error = utils.validate_xml_id(constraint_id, 'constraint id')
    if not id_valid:
        utils.err(id_error)

    if not utils.is_score(score):
        utils.err("invalid score '%s', use integer or INFINITY or -INFINITY" %
                  score)

    required_version = None
    if [x for x in options if x[0] == "resource-discovery"]:
        required_version = 2, 2, 0
    if rsc_type == RESOURCE_TYPE_REGEXP:
        required_version = 2, 6, 0

    if required_version:
        dom = utils.cluster_upgrade_to_version(required_version)
    else:
        dom = utils.get_cib_dom()

    if rsc_type == RESOURCE_TYPE_RESOURCE:
        rsc_valid, rsc_error, dummy_correct_id = (
            utils.validate_constraint_resource(dom, rsc_value))
        if not rsc_valid:
            utils.err(rsc_error)

    # Verify that specified node exists in the cluster
    if not (modifiers.is_specified("-f") or modifiers.get("--force")):
        lib_env = utils.get_lib_env()
        existing_nodes = get_existing_nodes_names(
            corosync_conf=lib_env.get_corosync_conf(),
            cib=lib_env.get_cib(),
        )
        if node not in existing_nodes:
            raise error(f"Node '{node}' does not seem to be in the cluster"
                        ", use --force to override")
    else:
        warn(LOCATION_NODE_VALIDATION_SKIP_MSG)

    # Verify current constraint doesn't already exist
    # If it does we replace it with the new constraint
    dummy_dom, constraintsElement = getCurrentConstraints(dom)
    elementsToRemove = []
    # If the id matches, or the rsc & node match, then we replace/remove
    for rsc_loc in constraintsElement.getElementsByTagName('rsc_location'):
        # pylint: disable=too-many-boolean-expressions
        if (rsc_loc.getAttribute("id") == constraint_id
                or (rsc_loc.getAttribute("node") == node and
                    ((RESOURCE_TYPE_RESOURCE == rsc_type
                      and rsc_loc.getAttribute("rsc") == rsc_value) or
                     (RESOURCE_TYPE_REGEXP == rsc_type
                      and rsc_loc.getAttribute("rsc-pattern") == rsc_value)))):
            elementsToRemove.append(rsc_loc)
    for etr in elementsToRemove:
        constraintsElement.removeChild(etr)

    element = dom.createElement("rsc_location")
    element.setAttribute("id", constraint_id)
    if rsc_type == RESOURCE_TYPE_RESOURCE:
        element.setAttribute("rsc", rsc_value)
    elif rsc_type == RESOURCE_TYPE_REGEXP:
        element.setAttribute("rsc-pattern", rsc_value)
    element.setAttribute("node", node)
    element.setAttribute("score", score)
    for option in options:
        element.setAttribute(option[0], option[1])
    constraintsElement.appendChild(element)

    utils.replace_cib_configuration(dom)
Esempio n. 39
0
def remove(lib, argv, modifiers):
    if len(argv) != 2:
        raise CmdLineInputError()
    ticket, resource_id = argv
    if not lib.constraint_ticket.remove(ticket, resource_id):
        raise error("no matching ticket constraint found")
Esempio n. 40
0
def stonith_create(lib, argv, modifiers):
    """
    Options:
      * --before - specified resource inside a group before which new resource
        will be placed inside the group
      * --after - specified resource inside a group after which new resource
        will be placed inside the group
      * --group - specifies group in which resource will be created
      * --force - allow not existing agent, invalid operations or invalid
        instance attributes
      * --disabled - created reource will be disabled
      * --no-default-ops - do not add default operations
      * --wait
      * -f - CIB file
    """
    modifiers.ensure_only_supported(
        "--before", "--after", "--group", "--force", "--disabled",
        "--no-default-ops", "--wait", "-f",
    )
    if modifiers.is_specified("--before") and modifiers.is_specified("--after"):
        raise error("you cannot specify both --before and --after{0}".format(
            "" if modifiers.is_specified("--group")
            else " and you have to specify --group"
        ))

    if not modifiers.is_specified("--group"):
        if modifiers.is_specified("--before"):
            raise error("you cannot use --before without --group")
        if modifiers.is_specified("--after"):
            raise error("you cannot use --after without --group")

    if len(argv) < 2:
        raise CmdLineInputError()

    stonith_id = argv[0]
    stonith_type = argv[1]

    parts = parse_create_args(argv[2:])

    settings = dict(
        allow_absent_agent=modifiers.get("--force"),
        allow_invalid_operation=modifiers.get("--force"),
        allow_invalid_instance_attributes=modifiers.get("--force"),
        ensure_disabled=modifiers.get("--disabled"),
        use_default_operations=not modifiers.get("--no-default-ops"),
        wait=modifiers.get("--wait"),
    )

    if not modifiers.get("--group"):
        lib.stonith.create(
            stonith_id, stonith_type, parts["op"],
            parts["meta"],
            parts["options"],
            **settings
        )
    else:
        adjacent_resource_id = None
        put_after_adjacent = False
        if modifiers.get("--after"):
            adjacent_resource_id = modifiers.get("--after")
            put_after_adjacent = True
        if modifiers.get("--before"):
            adjacent_resource_id = modifiers.get("--before")
            put_after_adjacent = False

        lib.stonith.create_in_group(
            stonith_id, stonith_type, modifiers.get("--group"), parts["op"],
            parts["meta"],
            parts["options"],
            adjacent_resource_id=adjacent_resource_id,
            put_after_adjacent=put_after_adjacent,
            **settings
        )