def config_checkpoint_list(lib, argv, modifiers): """ Options: no options """ del lib modifiers.ensure_only_supported() if argv: raise CmdLineInputError() try: file_list = os.listdir(settings.cib_dir) except OSError as e: utils.err("unable to list checkpoints: %s" % e) cib_list = [] cib_name_re = re.compile(r"^cib-(\d+)\.raw$") for filename in file_list: match = cib_name_re.match(filename) if not match: continue file_path = os.path.join(settings.cib_dir, filename) try: if os.path.isfile(file_path): cib_list.append( (float(os.path.getmtime(file_path)), match.group(1))) except OSError: pass cib_list.sort() if not cib_list: print_to_stderr("No checkpoints available") return for cib_info in cib_list: print( "checkpoint %s: date %s" % (cib_info[1], datetime.datetime.fromtimestamp(round(cib_info[0]))))
def stonith_history_update_cmd(lib, argv, modifiers): """ Options: no options """ modifiers.ensure_only_supported() if argv: raise CmdLineInputError() print_to_stderr(lib.stonith.history_update())
def stonith_history_cleanup_cmd(lib, argv, modifiers): """ Options: no options """ modifiers.ensure_only_supported() if len(argv) > 1: raise CmdLineInputError() node = argv[0] if argv else None print_to_stderr(lib.stonith.history_cleanup(node))
def config_checkpoint_view(lib, argv, modifiers): """ Options: no options """ modifiers.ensure_only_supported() if len(argv) != 1: print_to_stderr(usage.config(["checkpoint view"])) sys.exit(1) loaded, lines = _checkpoint_to_lines(lib, argv[0]) if not loaded: utils.err("unable to read the checkpoint") print("\n".join(lines))
def sbd_watchdog_list(lib, argv, modifiers): """ Options: no options """ modifiers.ensure_only_supported() if argv: raise CmdLineInputError() available_watchdogs = lib.sbd.get_local_available_watchdogs() if available_watchdogs: print("Available watchdog(s):") for watchdog in sorted(available_watchdogs.keys()): print(" {}".format(watchdog)) else: print_to_stderr("No available watchdog")
def config_checkpoint_restore(lib, argv, modifiers): """ Options: * -f - CIB file, a checkpoint will be restored into a specified file """ # pylint: disable=broad-except del lib modifiers.ensure_only_supported("-f") if len(argv) != 1: print_to_stderr(usage.config(["checkpoint restore"])) sys.exit(1) cib_path = os.path.join(settings.cib_dir, "cib-%s.raw" % argv[0]) try: snapshot_dom = parse(cib_path) except Exception as e: utils.err("unable to read the checkpoint: %s" % e) utils.replace_cib_configuration(snapshot_dom)
def tag_config( lib: Any, argv: Sequence[str], modifiers: InputModifiers, ) -> None: """ Options: * -f - CIB file """ modifiers.ensure_only_supported("-f") tag_list = lib.tag.config(argv) if not tag_list: print_to_stderr(" No tags defined") return lines = [] for tag in tag_list: lines.append(tag["tag_id"]) lines.extend(indent(tag["idref_list"])) print("\n".join(lines))
def config_checkpoint_diff(lib, argv, modifiers): """ Commandline options: * -f - CIB file """ modifiers.ensure_only_supported("-f") if len(argv) != 2: print_to_stderr(usage.config(["checkpoint diff"])) sys.exit(1) if argv[0] == argv[1]: utils.err("cannot diff a checkpoint against itself") errors = [] checkpoints_lines = [] for checkpoint in argv: if checkpoint == "live": lines = _config_show_cib_lines(lib) if not lines: errors.append("unable to read live configuration") else: checkpoints_lines.append(lines) else: loaded, lines = _checkpoint_to_lines(lib, checkpoint) if not loaded: errors.append( "unable to read checkpoint '{0}'".format(checkpoint)) else: checkpoints_lines.append(lines) if errors: utils.err("\n".join(errors)) print("Differences between {0} (-) and {1} (+):".format(*[ "live configuration" if label == "live" else f"checkpoint {label}" for label in argv ])) print("\n".join([ line.rstrip() for line in difflib.Differ().compare( checkpoints_lines[0], checkpoints_lines[1]) ]))
def stonith_fence(lib, argv, modifiers): """ Options: * --off - use off action of fence agent """ del lib modifiers.ensure_only_supported("--off") if len(argv) != 1: utils.err("must specify one (and only one) node to fence") node = argv.pop(0) if modifiers.get("--off"): args = ["stonith_admin", "-F", node] else: args = ["stonith_admin", "-B", node] output, retval = utils.run(args) if retval != 0: utils.err("unable to fence '%s'\n" % node + output) else: print_to_stderr(f"Node: {node} fenced")
def pcsd_certkey_cmd(lib, argv, modifiers): """ Options: * --force - overwrite existing file """ del lib modifiers.ensure_only_supported("--force") if len(argv) != 2: raise CmdLineInputError() certfile = argv[0] keyfile = argv[1] try: with open(certfile, "rb") as myfile: cert = myfile.read() with open(keyfile, "rb") as myfile: key = myfile.read() except IOError as e: utils.err(e) errors = pcs.common.ssl.check_cert_key(certfile, keyfile) if errors: for err in errors: utils.err(err, False) sys.exit(1) if not modifiers.get("--force") and ( os.path.exists(settings.pcsd_cert_location) or os.path.exists(settings.pcsd_key_location)): utils.err( "certificate and/or key already exists, use --force to overwrite") try: try: os.chmod(settings.pcsd_cert_location, 0o600) except OSError: # If the file doesn't exist, we don't care pass try: os.chmod(settings.pcsd_key_location, 0o600) except OSError: # If the file doesn't exist, we don't care pass with os.fdopen( os.open( settings.pcsd_cert_location, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o600, ), "wb", ) as myfile: myfile.write(cert) with os.fdopen( os.open( settings.pcsd_key_location, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o600, ), "wb", ) as myfile: myfile.write(key) except IOError as e: utils.err(e) print_to_stderr( "Certificate and key updated, you may need to restart pcsd for new " "settings to take effect")
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) deprecation_warning( 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: error(str(err)) print_to_stderr(usage.main()) 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: print(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)) # initialize logger logging.getLogger("pcs") 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: print(usage.main()), } try: routing.create_router(cmd_map, [])(utils.get_library_wrapper(), argv, utils.get_input_modifiers()) except LibraryError as e: if e.output: sys.stderr.write(e.output) sys.exit(1) process_library_reports(e.args) except errors.CmdLineInputError: if argv and argv[0] in cmd_map: usage.show(argv[0], []) else: print_to_stderr(usage.main()) sys.exit(1)