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)
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)
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)
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)
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
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
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)
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)
def location_prefer(lib, argv, modifiers): """ Options: * --force - allow unknown options, allow constraint for any resource type * -f - CIB file """ modifiers.ensure_only_supported("--force", "-f") rsc = argv.pop(0) prefer_option = argv.pop(0) dummy_rsc_type, rsc_value = parse_args.parse_typed_arg( rsc, [RESOURCE_TYPE_RESOURCE, RESOURCE_TYPE_REGEXP], RESOURCE_TYPE_RESOURCE) if prefer_option == "prefers": prefer = True elif prefer_option == "avoids": prefer = False else: raise CmdLineInputError() skip_node_check = False if modifiers.is_specified("-f") or modifiers.get("--force"): skip_node_check = True warn(LOCATION_NODE_VALIDATION_SKIP_MSG) else: lib_env = utils.get_lib_env() existing_nodes, report_list = get_existing_nodes_names( corosync_conf=lib_env.get_corosync_conf(), cib=lib_env.get_cib(), ) if report_list: process_library_reports(report_list) report_list = [] parameters_list = [] for nodeconf in argv: nodeconf_a = nodeconf.split("=", 1) node = nodeconf_a[0] if not skip_node_check: report_list += _verify_node_name(node, existing_nodes) if len(nodeconf_a) == 1: if prefer: score = "INFINITY" else: score = "-INFINITY" else: score = nodeconf_a[1] _verify_score(score) if not prefer: if score[0] == "-": score = score[1:] else: score = "-" + score parameters_list.append([ sanitize_id(f"location-{rsc_value}-{node}-{score}"), rsc, node, score ]) if report_list: process_library_reports(report_list) modifiers = modifiers.get_subset("--force", "-f") for parameters in parameters_list: location_add(lib, parameters, modifiers, skip_score_and_node_check=True)
def cluster_destroy(argv): if argv: raise CmdLineInputError() if "--all" in utils.pcs_options: # destroy remote and guest nodes cib = None lib_env = utils.get_lib_env() try: cib = lib_env.get_cib() except LibraryError as e: warn("Unable to load CIB to get guest and remote nodes from it, " "those nodes will not be deconfigured.") if cib is not None: try: all_remote_nodes = get_existing_nodes_names(cib=cib) if len(all_remote_nodes) > 0: _destroy_pcmk_remote_env(lib_env, all_remote_nodes, skip_offline_nodes=True, allow_fails=True) except LibraryError as e: utils.process_library_reports(e.args) # destroy full-stack nodes destroy_cluster(utils.get_corosync_conf_facade().get_nodes_names()) else: print("Shutting down pacemaker/corosync services...") for service in ["pacemaker", "corosync-qdevice", "corosync"]: # Returns an error if a service is not running. It is safe to # ignore it since we want it not to be running anyways. utils.stop_service(service) print("Killing any remaining services...") kill_local_cluster_services() try: utils.disableServices() except: # previously errors were suppressed in here, let's keep it that way # for now pass try: disable_service(utils.cmd_runner(), lib_sbd.get_sbd_service_name()) except: # it's not a big deal if sbd disable fails pass print("Removing all cluster configuration files...") dummy_output, dummy_retval = utils.run([ "rm", "-f", settings.corosync_conf_file, settings.corosync_authkey_file, settings.pacemaker_authkey_file, ]) state_files = [ "cib.xml*", "cib-*", "core.*", "hostcache", "cts.*", "pe*.bz2", "cib.*" ] for name in state_files: dummy_output, dummy_retval = utils.run([ "find", "/var/lib/pacemaker", "-name", name, "-exec", "rm", "-f", "{}", ";" ]) try: qdevice_net.client_destroy() except: # errors from deleting other files are suppressed as well # we do not want to fail if qdevice was not set up pass
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)