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 = {} modified_argv = [] real_argv = [] try: # we change --cloneopt to "clone" for backwards compatibility new_argv = [] for arg in argv: if arg == "--cloneopt" or arg == "--clone": new_argv.append("clone") elif arg.startswith("--cloneopt="): new_argv.append("clone") new_argv.append(arg.split('=', 1)[1]) else: new_argv.append(arg) argv = new_argv # 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 # h = help, f = file, # p = password (cluster auth), u = user (cluster auth), # V = verbose (cluster verify) pcs_short_options = "hf:p:u:V" pcs_long_options = [ "debug", "version", "help", "fullhelp", "force", "skip-offline", "autocorrect", "interactive", "autodelete", "all", "full", "groups", "local", "wait", "config", "start", "enable", "disabled", "off", "pacemaker", "corosync", "no-default-ops", "defaults", "nodesc", "clone", "master", "name=", "group=", "node=", "from=", "to=", "after=", "before=", "transport=", "rrpmode=", "ipv6", "addr0=", "bcast0=", "mcast0=", "mcastport0=", "ttl0=", "broadcast0", "addr1=", "bcast1=", "mcast1=", "mcastport1=", "ttl1=", "broadcast1", "wait_for_all=", "auto_tie_breaker=", "last_man_standing=", "last_man_standing_window=", "token=", "token_coefficient=", "consensus=", "join=", "miss_count_const=", "fail_recv_const=", "corosync_conf=", "cluster_conf=", "booth-conf=", "booth-key=", "remote", "watchdog=", #in pcs status - do not display resorce status on inactive node "hide-inactive", ] # pull out negative number arguments and add them back after getopt prev_arg = "" for arg in argv: if len(arg) > 0 and arg[0] == "-": if arg[1:].isdigit() or arg[1:].startswith("INFINITY"): real_argv.append(arg) else: modified_argv.append(arg) else: # If previous argument required an argument, then this arg # should not be added back in if not prev_arg or ( not (prev_arg[0] == "-" and prev_arg[1:] in pcs_short_options) and not (prev_arg[0:2] == "--" and (prev_arg[2:] + "=") in pcs_long_options)): real_argv.append(arg) modified_argv.append(arg) prev_arg = arg pcs_options, argv = getopt.gnu_getopt(modified_argv, pcs_short_options, pcs_long_options) except getopt.GetoptError as err: print(err) usage.main() sys.exit(1) argv = real_argv for o, a in pcs_options: if not o in utils.pcs_options: if o == "--watchdog": a = [a] utils.pcs_options[o] = a else: # If any options are a list then they've been entered twice which isn't valid if o != "--watchdog": utils.err("%s can only be used once" % o) else: utils.pcs_options[o].append(a) 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 == "--cluster_conf": settings.cluster_conf_file = a elif o == "--version": print(settings.pcs_version) sys.exit() elif o == "--fullhelp": usage.full_usage() sys.exit() elif o == "--wait": utils.pcs_options[o] = waitsecs 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("old_cli") 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": lambda argv: acl.acl_cmd(utils.get_library_wrapper(), argv, utils.get_modificators()), "status": status.status_cmd, "config": config.config_cmd, "pcsd": pcsd.pcsd_cmd, "node": node.node_cmd, "quorum": lambda argv: quorum.quorum_cmd(utils.get_library_wrapper(), argv, utils.get_modificators()), "qdevice": lambda argv: qdevice.qdevice_cmd(utils.get_library_wrapper(), argv, utils.get_modificators()), "alert": lambda args: alert.alert_cmd(utils.get_library_wrapper(), args, utils.get_modificators()), "booth": lambda argv: booth.booth_cmd(utils.get_library_wrapper(), argv, utils.get_modificators()), } 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](argv) 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', 'setup', '...'], ['cluster', 'start', '...'], ['cluster', 'stop', '...'], ['cluster', 'sync', '...'], # ['config', 'restore', '...'], # handled in config.config_restore ['pcsd', 'sync-certificates'], ['status', 'nodes', 'corosync-id'], ['status', 'nodes', 'pacemaker-id'], ['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] == ["cluster", "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, True) 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](argv)
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 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 = {} modified_argv = [] real_argv = [] try: # we change --cloneopt to "clone" for backwards compatibility new_argv = [] for arg in argv: if arg == "--cloneopt" or arg == "--clone": new_argv.append("clone") elif arg.startswith("--cloneopt="): new_argv.append("clone") new_argv.append(arg.split('=',1)[1]) else: new_argv.append(arg) argv = new_argv # 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 # h = help, f = file, # p = password (cluster auth), u = user (cluster auth), # V = verbose (cluster verify) pcs_short_options = "hf:p:u:V" pcs_long_options = [ "debug", "version", "help", "fullhelp", "force", "skip-offline", "autocorrect", "interactive", "autodelete", "all", "full", "groups", "local", "wait", "config", "start", "enable", "disabled", "off", "pacemaker", "corosync", "no-default-ops", "defaults", "nodesc", "clone", "master", "name=", "group=", "node=", "from=", "to=", "after=", "before=", "transport=", "rrpmode=", "ipv6", "addr0=", "bcast0=", "mcast0=", "mcastport0=", "ttl0=", "broadcast0", "addr1=", "bcast1=", "mcast1=", "mcastport1=", "ttl1=", "broadcast1", "wait_for_all=", "auto_tie_breaker=", "last_man_standing=", "last_man_standing_window=", "token=", "token_coefficient=", "consensus=", "join=", "miss_count_const=", "fail_recv_const=", "corosync_conf=", "cluster_conf=", "remote", "watchdog=", #in pcs status - do not display resorce status on inactive node "hide-inactive", ] # pull out negative number arguments and add them back after getopt prev_arg = "" for arg in argv: if len(arg) > 0 and arg[0] == "-": if arg[1:].isdigit() or arg[1:].startswith("INFINITY"): real_argv.append(arg) else: modified_argv.append(arg) else: # If previous argument required an argument, then this arg # should not be added back in if not prev_arg or (not (prev_arg[0] == "-" and prev_arg[1:] in pcs_short_options) and not (prev_arg[0:2] == "--" and (prev_arg[2:] + "=") in pcs_long_options)): real_argv.append(arg) modified_argv.append(arg) prev_arg = arg pcs_options, argv = getopt.gnu_getopt(modified_argv, pcs_short_options, pcs_long_options) except getopt.GetoptError as err: print(err) usage.main() sys.exit(1) argv = real_argv for o, a in pcs_options: if not o in utils.pcs_options: if o == "--watchdog": a = [a] utils.pcs_options[o] = a else: # If any options are a list then they've been entered twice which isn't valid if o != "--watchdog": utils.err("%s can only be used once" % o) else: utils.pcs_options[o].append(a) 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 == "--cluster_conf": settings.cluster_conf_file = a elif o == "--version": print(settings.pcs_version) sys.exit() elif o == "--fullhelp": usage.full_usage() sys.exit() elif o == "--wait": utils.pcs_options[o] = waitsecs 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("old_cli") 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": lambda argv: quorum.quorum_cmd( utils.get_library_wrapper(), argv, utils.get_modificators() ), "qdevice": lambda argv: qdevice.qdevice_cmd( utils.get_library_wrapper(), argv, utils.get_modificators() ), "alert": lambda args: alert.alert_cmd( utils.get_library_wrapper(), args, utils.get_modificators() ), } 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](argv) 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', 'setup', '...'], ['cluster', 'start', '...'], ['cluster', 'stop', '...'], ['cluster', 'sync', '...'], # ['config', 'restore', '...'], # handled in config.config_restore ['pcsd', 'sync-certificates'], ['status', 'nodes', 'corosync-id'], ['status', 'nodes', 'pacemaker-id'], ['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] == ["cluster", "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, True ) 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](argv)
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 = {} argv = parse_args.upgrade_args(argv) # 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) for o, a in pcs_options: if not o in utils.pcs_options: if o == "--watchdog": a = [a] utils.pcs_options[o] = a else: # If any options are a list then they've been entered twice which isn't valid if o != "--watchdog": utils.err("%s can only be used once" % o) else: utils.pcs_options[o].append(a) 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 == "--cluster_conf": settings.cluster_conf_file = a elif o == "--version": print(settings.pcs_version) 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("old_cli") 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": lambda argv: acl.acl_cmd( utils.get_library_wrapper(), argv, utils.get_modificators() ), "status": status.status_cmd, "config": config.config_cmd, "pcsd": pcsd.pcsd_cmd, "node": lambda argv: node.node_cmd( utils.get_library_wrapper(), argv, utils.get_modificators() ), "quorum": lambda argv: quorum.quorum_cmd( utils.get_library_wrapper(), argv, utils.get_modificators() ), "qdevice": lambda argv: qdevice.qdevice_cmd( utils.get_library_wrapper(), argv, utils.get_modificators() ), "alert": lambda args: alert.alert_cmd( utils.get_library_wrapper(), args, utils.get_modificators() ), "booth": lambda argv: booth.booth_cmd( utils.get_library_wrapper(), argv, utils.get_modificators() ), } 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](argv) 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', 'setup', '...'], ['cluster', 'start', '...'], ['cluster', 'stop', '...'], ['cluster', 'sync', '...'], # ['config', 'restore', '...'], # handled in config.config_restore ['pcsd', 'sync-certificates'], ['status', 'nodes', 'corosync-id'], ['status', 'nodes', 'pacemaker-id'], ['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] == ["cluster", "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, True ) 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](argv)
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 = {} argv = parse_args.upgrade_args(argv) # 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: if o in ["--watchdog", "--device"]: a = [a] utils.pcs_options[o] = a else: # If any options are a list then they've been entered twice which isn't valid if o not in ["--watchdog", "--device"]: utils.err("%s can only be used once" % o) else: utils.pcs_options[o].append(a) 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 == "--cluster_conf": settings.cluster_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("old_cli") 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": lambda argv: acl.acl_cmd(utils.get_library_wrapper(), argv, utils.get_modificators()), "status": status.status_cmd, "config": config.config_cmd, "pcsd": pcsd.pcsd_cmd, "node": lambda argv: node.node_cmd(utils.get_library_wrapper(), argv, utils.get_modificators()), "quorum": lambda argv: quorum.quorum_cmd(utils.get_library_wrapper(), argv, utils.get_modificators()), "qdevice": lambda argv: qdevice.qdevice_cmd(utils.get_library_wrapper(), argv, utils.get_modificators()), "alert": lambda args: alert.alert_cmd(utils.get_library_wrapper(), args, utils.get_modificators()), "booth": lambda argv: booth.booth_cmd(utils.get_library_wrapper(), argv, utils.get_modificators()), } 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](argv) 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', 'setup', '...'], ['cluster', 'start', '...'], ['cluster', 'stop', '...'], ['cluster', 'sync', '...'], # ['config', 'restore', '...'], # handled in config.config_restore ['pcsd', 'sync-certificates'], ['status', 'nodes', 'corosync-id'], ['status', 'nodes', 'pacemaker-id'], ['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] == ["cluster", "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, True) 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](argv)