def remove_constraints_containing( resource_id, output=False, constraints_element=None, passed_dom=None ): """ Commandline options: * -f - CIB file, effective only if passed_dom is None """ lib = utils.get_library_wrapper() modifiers = utils.get_input_modifiers() constraints, set_constraints = find_constraints_containing( resource_id, passed_dom ) for c in constraints: if output: print("Removing Constraint - " + c) if constraints_element is not None: constraint_rm( lib, [c], modifiers, True, constraints_element, passed_dom=passed_dom ) else: constraint_rm(lib, [c], modifiers, passed_dom=passed_dom) if set_constraints: (dom, constraintsElement) = getCurrentConstraints(passed_dom) for c in constraintsElement.getElementsByTagName("resource_ref")[:]: # If resource id is in a set, remove it from the set, if the set # is empty, then we remove the set, if the parent of the set # is empty then we remove it if c.getAttribute("id") == resource_id: pn = c.parentNode pn.removeChild(c) if output: print( "Removing %s from set %s" % (resource_id, pn.getAttribute("id")) ) if pn.getElementsByTagName("resource_ref").length == 0: print("Removing set %s" % pn.getAttribute("id")) pn2 = pn.parentNode pn2.removeChild(pn) if pn2.getElementsByTagName("resource_set").length == 0: pn2.parentNode.removeChild(pn2) print("Removing constraint %s" % pn2.getAttribute("id")) if passed_dom: return dom utils.replace_cib_configuration(dom) return None
def config_show_cib(lib): """ Commandline options: * -f - CIB file """ print("Resources:") # update of pcs_options will change output of constraint show utils.pcs_options["--full"] = 1 # get latest modifiers object after updating pcs_options modifiers = utils.get_input_modifiers() resource.resource_config(lib, [], modifiers.get_subset("-f")) print() print("Stonith Devices:") resource.resource_config( lib, [], modifiers.get_subset("-f"), stonith=True, ) print("Fencing Levels:") levels = stonith.stonith_level_config_to_str( lib.fencing_topology.get_config()) if levels: print("\n".join(indent(levels, 2))) print() constraint.location_show(lib, [], modifiers.get_subset("-f", "--full")) order_command.show(lib, [], modifiers.get_subset("-f", "--full")) colocation_command.show(lib, [], modifiers.get_subset("-f", "--full")) ticket_command.show(lib, [], modifiers.get_subset("-f", "--full")) print() alert.print_alert_config(lib, [], modifiers.get_subset("-f")) print() print("Resources Defaults:") resource.show_defaults("rsc_defaults", indent=" ") print("Operations Defaults:") resource.show_defaults("op_defaults", indent=" ") print() prop.list_property(lib, [], modifiers.get_subset("--defaults", "--all", "-f"))
def main(argv=None): # pylint: disable=global-statement # pylint: disable=too-many-branches # pylint: disable=too-many-locals # pylint: disable=too-many-statements if completion.has_applicable_environment(os.environ): print( completion.make_suggestions( os.environ, usage.generate_completion_tree_from_usage() ) ) sys.exit() argv = argv if argv else sys.argv[1:] utils.subprocess_setup() global filename, usefile utils.pcs_options = {} # we want to support optional arguments for --wait, so if an argument # is specified with --wait (ie. --wait=30) then we use them waitsecs = None new_argv = [] for arg in argv: if arg.startswith("--wait="): tempsecs = arg.replace("--wait=", "") if tempsecs: waitsecs = tempsecs arg = "--wait" new_argv.append(arg) argv = new_argv try: if "--" in argv: pcs_options, argv = getopt.gnu_getopt( argv, parse_args.PCS_SHORT_OPTIONS, parse_args.PCS_LONG_OPTIONS ) else: # DEPRECATED # TODO remove # We want to support only the -- version ( args_without_negative_nums, args_filtered_out, ) = parse_args.filter_out_non_option_negative_numbers(argv) if args_filtered_out: options_str = "', '".join(args_filtered_out) output.warn( f"Using '{options_str}' without '--' is deprecated, those " "parameters will be considered position independent " "options in future pcs versions" ) pcs_options, dummy_argv = getopt.gnu_getopt( args_without_negative_nums, parse_args.PCS_SHORT_OPTIONS, parse_args.PCS_LONG_OPTIONS, ) argv = parse_args.filter_out_options(argv) except getopt.GetoptError as err: usage.main() print(err) if err.opt in {"V", "clone", "device", "watchdog"}: # Print error messages which point users to the changes section in # pcs manpage. # TODO remove # To be removed in the next significant version. print(f"Hint: {errors.HINT_SYNTAX_CHANGE}") sys.exit(1) full = False for option, dummy_value in pcs_options: if option == "--full": full = True break for opt, val in pcs_options: if not opt in utils.pcs_options: utils.pcs_options[opt] = val else: # If any options are a list then they've been entered twice which # isn't valid utils.err("%s can only be used once" % opt) if opt in ("-h", "--help"): if not argv: usage.main() sys.exit() else: argv = [argv[0], "help"] + argv[1:] elif opt == "-f": usefile = True filename = val utils.usefile = usefile utils.filename = filename elif opt == "--corosync_conf": settings.corosync_conf_file = val elif opt == "--version": print(settings.pcs_version) if full: print( " ".join( sorted( [ feat["id"] for feat in capabilities.get_pcs_capabilities() ] ) ) ) sys.exit() elif opt == "--fullhelp": usage.full_usage() sys.exit() elif opt == "--wait": utils.pcs_options[opt] = waitsecs elif opt == "--request-timeout": request_timeout_valid = False try: timeout = int(val) if timeout > 0: utils.pcs_options[opt] = timeout request_timeout_valid = True except ValueError: pass if not request_timeout_valid: utils.err( ( "'{0}' is not a valid --request-timeout value, use " "a positive integer" ).format(val) ) logger = logging.getLogger("pcs") logger.propagate = 0 logger.handlers = [] if (os.getuid() != 0) and (argv and argv[0] != "help") and not usefile: _non_root_run(argv) cmd_map = { "resource": resource.resource_cmd, "cluster": cluster.cluster_cmd, "stonith": stonith.stonith_cmd, "property": prop.property_cmd, "constraint": constraint.constraint_cmd, "acl": acl.acl_cmd, "status": status.status_cmd, "config": config.config_cmd, "pcsd": pcsd.pcsd_cmd, "node": node.node_cmd, "quorum": quorum.quorum_cmd, "qdevice": qdevice.qdevice_cmd, "alert": alert.alert_cmd, "booth": booth.booth_cmd, "host": host.host_cmd, "client": client.client_cmd, "dr": dr.dr_cmd, "tag": tag.tag_cmd, "help": lambda lib, argv, modifiers: usage.main(), } try: routing.create_router(cmd_map, [])( utils.get_library_wrapper(), argv, utils.get_input_modifiers() ) except LibraryError as e: process_library_reports(e.args) except errors.CmdLineInputError: if argv and argv[0] in cmd_map: usage.show(argv[0], []) else: usage.main() sys.exit(1)
def main(argv=None): # pylint: disable=too-many-locals, too-many-branches, too-many-statements, global-statement if completion.has_applicable_environment(os.environ): print(completion.make_suggestions( os.environ, usage.generate_completion_tree_from_usage() )) sys.exit() argv = argv if argv else sys.argv[1:] utils.subprocess_setup() global filename, usefile utils.pcs_options = {} # we want to support optional arguments for --wait, so if an argument # is specified with --wait (ie. --wait=30) then we use them waitsecs = None new_argv = [] for arg in argv: if arg.startswith("--wait="): tempsecs = arg.replace("--wait=", "") if tempsecs: waitsecs = tempsecs arg = "--wait" new_argv.append(arg) argv = new_argv try: pcs_options, dummy_argv = getopt.gnu_getopt( parse_args.filter_out_non_option_negative_numbers(argv), parse_args.PCS_SHORT_OPTIONS, parse_args.PCS_LONG_OPTIONS, ) except getopt.GetoptError as err: print(err) usage.main() sys.exit(1) argv = parse_args.filter_out_options(argv) full = False for option, dummy_value in pcs_options: if option == "--full": full = True break for opt, val in pcs_options: if not opt in utils.pcs_options: utils.pcs_options[opt] = val else: # If any options are a list then they've been entered twice which # isn't valid utils.err("%s can only be used once" % opt) if opt in ("-h", "--help"): if not argv: usage.main() sys.exit() else: argv = [argv[0], "help"] + argv[1:] elif opt == "-f": usefile = True filename = val utils.usefile = usefile utils.filename = filename elif opt == "--corosync_conf": settings.corosync_conf_file = val elif opt == "--version": print(settings.pcs_version) if full: print(" ".join( sorted([ feat["id"] for feat in capabilities.get_pcs_capabilities() ]) )) sys.exit() elif opt == "--fullhelp": usage.full_usage() sys.exit() elif opt == "--wait": utils.pcs_options[opt] = waitsecs elif opt == "--request-timeout": request_timeout_valid = False try: timeout = int(val) if timeout > 0: utils.pcs_options[opt] = timeout request_timeout_valid = True except ValueError: pass if not request_timeout_valid: utils.err( ( "'{0}' is not a valid --request-timeout value, use " "a positive integer" ).format(val) ) logger = logging.getLogger("pcs") logger.propagate = 0 logger.handlers = [] if (os.getuid() != 0) and (argv and argv[0] != "help") and not usefile: non_root_run(argv) cmd_map = { "resource": resource.resource_cmd, "cluster": cluster.cluster_cmd, "stonith": stonith.stonith_cmd, "property": prop.property_cmd, "constraint": constraint.constraint_cmd, "acl": acl.acl_cmd, "status": status.status_cmd, "config": config.config_cmd, "pcsd": pcsd.pcsd_cmd, "node": node.node_cmd, "quorum": quorum.quorum_cmd, "qdevice": qdevice.qdevice_cmd, "alert": alert.alert_cmd, "booth": booth.booth_cmd, "host": host.host_cmd, "client": client.client_cmd, "help": lambda lib, argv, modifiers: usage.main(), } try: routing.create_router(cmd_map, [])( utils.get_library_wrapper(), argv, utils.get_input_modifiers() ) except LibraryError as e: utils.process_library_reports(e.args) except errors.CmdLineInputError: if argv and argv[0] in cmd_map: usage.show(argv[0], []) else: usage.main() sys.exit(1)
def _config_show_cib_lines(lib): """ Commandline options: * -f - CIB file """ # update of pcs_options will change output of constraint show utils.pcs_options["--full"] = 1 # get latest modifiers object after updating pcs_options modifiers = utils.get_input_modifiers() cib_xml = utils.get_cib() cib_etree = utils.get_cib_etree(cib_xml=cib_xml) cib_dom = utils.get_cib_dom(cib_xml=cib_xml) resource_lines = [] stonith_lines = [] for resource_el in cib_etree.find(".//resources"): is_stonith = ("class" in resource_el.attrib and resource_el.attrib["class"] == "stonith") resource_el_lines = resource.resource_node_lines(resource_el) if is_stonith: stonith_lines += resource_el_lines else: resource_lines += resource_el_lines all_lines = [] all_lines.append("Resources:") all_lines.extend(indent(resource_lines, indent_step=1)) all_lines.append("") all_lines.append("Stonith Devices:") all_lines.extend(indent(stonith_lines, indent_step=1)) all_lines.append("Fencing Levels:") levels_lines = stonith.stonith_level_config_to_str( lib.fencing_topology.get_config()) if levels_lines: all_lines.extend(indent(levels_lines, indent_step=2)) all_lines.append("") constraints_element = cib_dom.getElementsByTagName("constraints")[0] all_lines.extend( constraint.location_lines( constraints_element, showDetail=True, show_expired=True, verify_expiration=False, )) all_lines.extend( constraint_command.show( "Ordering Constraints:", lib.constraint_order.show, constraints_reports.order_plain, modifiers.get_subset("-f", "--full"), )) all_lines.extend( constraint_command.show( "Colocation Constraints:", lib.constraint_colocation.show, constraints_reports.colocation_plain, modifiers.get_subset("-f", "--full"), )) all_lines.extend( constraint_command.show( "Ticket Constraints:", lib.constraint_ticket.show, constraints_reports.ticket_plain, modifiers.get_subset("-f", "--full"), )) all_lines.append("") all_lines.extend(alert.alert_config_lines(lib)) all_lines.append("") all_lines.append("Resources Defaults:") all_lines.extend( indent(resource.show_defaults(cib_dom, "rsc_defaults"), indent_step=1)) all_lines.append("Operations Defaults:") all_lines.extend( indent(resource.show_defaults(cib_dom, "op_defaults"), indent_step=1)) all_lines.append("") all_lines.append("Cluster Properties:") properties = utils.get_set_properties() all_lines.extend( indent( [ "{0}: {1}".format(prop, val) for prop, val in sorted(properties.items()) ], indent_step=1, )) all_lines.append("") all_lines.append("Tags:") tags = lib.tag.config([]) if not tags: all_lines.append(" No tags defined") tag_lines = [] for tag in tags: tag_lines.append(tag["tag_id"]) tag_lines.extend(indent(tag["idref_list"])) all_lines.extend(indent(tag_lines, indent_step=1)) return all_lines
def main(argv=None): if completion.has_applicable_environment(os.environ): print(completion.make_suggestions( os.environ, usage.generate_completion_tree_from_usage() )) sys.exit() argv = argv if argv else sys.argv[1:] utils.subprocess_setup() global filename, usefile orig_argv = argv[:] utils.pcs_options = {} # we want to support optional arguments for --wait, so if an argument # is specified with --wait (ie. --wait=30) then we use them waitsecs = None new_argv = [] for arg in argv: if arg.startswith("--wait="): tempsecs = arg.replace("--wait=","") if len(tempsecs) > 0: waitsecs = tempsecs arg = "--wait" new_argv.append(arg) argv = new_argv try: pcs_options, dummy_argv = getopt.gnu_getopt( parse_args.filter_out_non_option_negative_numbers(argv), parse_args.PCS_SHORT_OPTIONS, parse_args.PCS_LONG_OPTIONS, ) except getopt.GetoptError as err: print(err) usage.main() sys.exit(1) argv = parse_args.filter_out_options(argv) full = False for option, dummy_value in pcs_options: if option == "--full": full = True break for o, a in pcs_options: if not o in utils.pcs_options: utils.pcs_options[o] = a else: # If any options are a list then they've been entered twice which # isn't valid utils.err("%s can only be used once" % o) if o == "-h" or o == "--help": if len(argv) == 0: usage.main() sys.exit() else: argv = [argv[0], "help" ] + argv[1:] elif o == "-f": usefile = True filename = a utils.usefile = usefile utils.filename = filename elif o == "--corosync_conf": settings.corosync_conf_file = a elif o == "--version": print(settings.pcs_version) if full: print(" ".join( sorted([ feat["id"] for feat in capabilities.get_pcs_capabilities() ]) )) sys.exit() elif o == "--fullhelp": usage.full_usage() sys.exit() elif o == "--wait": utils.pcs_options[o] = waitsecs elif o == "--request-timeout": request_timeout_valid = False try: timeout = int(a) if timeout > 0: utils.pcs_options[o] = timeout request_timeout_valid = True except ValueError: pass if not request_timeout_valid: utils.err( ( "'{0}' is not a valid --request-timeout value, use " "a positive integer" ).format(a) ) if len(argv) == 0: usage.main() sys.exit(1) # create a dummy logger # we do not have a log file for cli (yet), but library requires a logger logger = logging.getLogger("pcs") logger.propagate = 0 logger.handlers = [] command = argv.pop(0) if (command == "-h" or command == "help"): usage.main() return cmd_map = { "resource": resource.resource_cmd, "cluster": cluster.cluster_cmd, "stonith": stonith.stonith_cmd, "property": prop.property_cmd, "constraint": constraint.constraint_cmd, "acl": acl.acl_cmd, "status": status.status_cmd, "config": config.config_cmd, "pcsd": pcsd.pcsd_cmd, "node": node.node_cmd, "quorum": quorum.quorum_cmd, "qdevice": qdevice.qdevice_cmd, "alert": alert.alert_cmd, "booth": booth.booth_cmd, "host": host.host_cmd, "client": client.client_cmd, } if command not in cmd_map: usage.main() sys.exit(1) # root can run everything directly, also help can be displayed, # working on a local file also do not need to run under root if (os.getuid() == 0) or (argv and argv[0] == "help") or usefile: cmd_map[command]( utils.get_library_wrapper(), argv, utils.get_input_modifiers(), ) return # specific commands need to be run under root account, pass them to pcsd # don't forget to allow each command in pcsd.rb in "post /run_pcs do" root_command_list = [ ['cluster', 'auth', '...'], ['cluster', 'corosync', '...'], ['cluster', 'destroy', '...'], ['cluster', 'disable', '...'], ['cluster', 'enable', '...'], ['cluster', 'node', '...'], ['cluster', 'pcsd-status', '...'], ['cluster', 'start', '...'], ['cluster', 'stop', '...'], ['cluster', 'sync', '...'], # ['config', 'restore', '...'], # handled in config.config_restore ['host', 'auth', '...'], ['host', 'deauth', '...'], ['pcsd', 'deauth', '...'], ['pcsd', 'sync-certificates'], ['status', 'pcsd', '...'], ] argv_cmd = argv[:] argv_cmd.insert(0, command) for root_cmd in root_command_list: if ( (argv_cmd == root_cmd) or ( root_cmd[-1] == "..." and argv_cmd[:len(root_cmd)-1] == root_cmd[:-1] ) ): # handle interactivity of 'pcs cluster auth' if argv_cmd[0:2] in [["cluster", "auth"], ["host", "auth"]]: if "-u" not in utils.pcs_options: username = utils.get_terminal_input('Username: ') orig_argv.extend(["-u", username]) if "-p" not in utils.pcs_options: password = utils.get_terminal_password() orig_argv.extend(["-p", password]) # call the local pcsd err_msgs, exitcode, std_out, std_err = utils.call_local_pcsd( orig_argv ) if err_msgs: for msg in err_msgs: utils.err(msg, False) sys.exit(1) if std_out.strip(): print(std_out) if std_err.strip(): sys.stderr.write(std_err) sys.exit(exitcode) return cmd_map[command]( utils.get_library_wrapper(), argv, utils.get_input_modifiers(), )
def _config_show_cib_lines(lib): """ Commandline options: * -f - CIB file """ # update of pcs_options will change output of constraint show utils.pcs_options["--full"] = 1 # get latest modifiers object after updating pcs_options modifiers = utils.get_input_modifiers() cib_xml = utils.get_cib() cib_etree = utils.get_cib_etree(cib_xml=cib_xml) cib_dom = utils.get_cib_dom(cib_xml=cib_xml) resource_lines = [] stonith_lines = [] for resource_el in cib_etree.find(".//resources"): is_stonith = ( "class" in resource_el.attrib and resource_el.attrib["class"] == "stonith" ) resource_el_lines = resource.resource_node_lines(resource_el) if is_stonith: stonith_lines += resource_el_lines else: resource_lines += resource_el_lines all_lines = [] all_lines.append("Resources:") all_lines.extend(indent(resource_lines, indent_step=1)) all_lines.append("") all_lines.append("Stonith Devices:") all_lines.extend(indent(stonith_lines, indent_step=1)) all_lines.append("Fencing Levels:") levels_lines = stonith.stonith_level_config_to_str( lib.fencing_topology.get_config() ) if levels_lines: all_lines.extend(indent(levels_lines, indent_step=2)) all_lines.append("") constraints_element = cib_dom.getElementsByTagName('constraints')[0] all_lines.extend( constraint.location_lines(constraints_element, showDetail=True) ) all_lines.extend(constraint_command.show( "Ordering Constraints:", lib.constraint_order.show, order_console_report.constraint_plain, modifiers.get_subset("-f", "--full"), )) all_lines.extend(constraint_command.show( "Colocation Constraints:", lib.constraint_colocation.show, colocation_console_report.constraint_plain, modifiers.get_subset("-f", "--full"), )) all_lines.extend(constraint_command.show( "Ticket Constraints:", lib.constraint_ticket.show, ticket_console_report.constraint_plain, modifiers.get_subset("-f", "--full"), )) all_lines.append("") all_lines.extend(alert.alert_config_lines(lib)) all_lines.append("") all_lines.append("Resources Defaults:") all_lines.extend(indent( resource.show_defaults(cib_dom, "rsc_defaults"), indent_step=1 )) all_lines.append("Operations Defaults:") all_lines.extend(indent( resource.show_defaults(cib_dom, "op_defaults"), indent_step=1 )) all_lines.append("") all_lines.append("Cluster Properties:") properties = utils.get_set_properties() all_lines.extend(indent( [ "{0}: {1}".format(prop, val) for prop, val in sorted(properties.items()) ], indent_step=1 )) return all_lines
def _config_show_cib_lines(lib): """ Commandline options: * -f - CIB file """ # update of pcs_options will change output of constraint show and # displaying resources and operations defaults utils.pcs_options["--full"] = 1 # get latest modifiers object after updating pcs_options modifiers = utils.get_input_modifiers() cib_dom = utils.get_cib_dom() resources_facade = ResourcesConfigurationFacade.from_resources_dto( lib.resource.get_configured_resources()) all_lines = [] all_lines.append("Resources:") all_lines.extend( smart_wrap_text( indent( resources_to_text(resources_facade.filter_stonith(False)), indent_step=INDENT_STEP, ))) all_lines.append("") all_lines.append("Stonith Devices:") all_lines.extend( smart_wrap_text( indent( resources_to_text(resources_facade.filter_stonith(True)), indent_step=INDENT_STEP, ))) all_lines.append("Fencing Levels:") levels_lines = stonith.stonith_level_config_to_str( lib.fencing_topology.get_config()) if levels_lines: all_lines.extend(indent(levels_lines, indent_step=2)) all_lines.append("") constraints_element = cib_dom.getElementsByTagName("constraints")[0] all_lines.extend( constraint.location_lines( constraints_element, showDetail=True, show_expired=True, verify_expiration=False, )) all_lines.extend( constraint_command.config_cmd( "Ordering Constraints:", lib.constraint_order.config, constraints_reports.order_plain, modifiers.get_subset("-f", "--full"), )) all_lines.extend( constraint_command.config_cmd( "Colocation Constraints:", lib.constraint_colocation.config, constraints_reports.colocation_plain, modifiers.get_subset("-f", "--full"), )) all_lines.extend( constraint_command.config_cmd( "Ticket Constraints:", lib.constraint_ticket.config, constraints_reports.ticket_plain, modifiers.get_subset("-f", "--full"), )) all_lines.append("") all_lines.extend(alert.alert_config_lines(lib)) all_lines.append("") all_lines.append("Resources Defaults:") all_lines.extend( indent( nvset_dto_list_to_lines( lib.cib_options.resource_defaults_config( evaluate_expired=False).meta_attributes, nvset_label="Meta Attrs", with_ids=modifiers.get("--full"), text_if_empty="No defaults set", ))) all_lines.append("Operations Defaults:") all_lines.extend( indent( nvset_dto_list_to_lines( lib.cib_options.operation_defaults_config( evaluate_expired=False).meta_attributes, nvset_label="Meta Attrs", with_ids=modifiers.get("--full"), text_if_empty="No defaults set", ))) all_lines.append("") all_lines.append("Cluster Properties:") properties = utils.get_set_properties() all_lines.extend( indent( [ "{0}: {1}".format(prop, val) for prop, val in sorted(properties.items()) ], indent_step=1, )) all_lines.append("") all_lines.append("Tags:") tags = lib.tag.config([]) if not tags: all_lines.append(" No tags defined") tag_lines = [] for tag in tags: tag_lines.append(tag["tag_id"]) tag_lines.extend(indent(tag["idref_list"])) all_lines.extend(indent(tag_lines, indent_step=1)) return all_lines