def main(): atexit.register(atexit_handler) device_opt = ["user", "domain", "password", "tenant", "auth_url", "wf_name", "port", "mistral_url", "on_shared_storage"] define_new_opts() all_opt["shell_timeout"]["default"] = "180" options = check_input(device_opt, process_input(device_opt)) docs = {} docs["shortdesc"] = "Fence agent for nova compute nodes" docs["longdesc"] = "fence_evacuate is a Nova fencing notification agent" docs["vendorurl"] = "" show_docs(options, docs) run_delay(options) host = None # Potentially we should make this a pacemaker feature if options["--domain"] != "" and "--plug" in options: options["--plug"] = options["--plug"] + "." + options["--domain"] if "--plug" in options: host = options["--plug"] if options['--action'] in ['reboot', 'off']: if host is None: logging.error('No host specified') sys.exit(1) evacuate(host, options) sys.exit(0)
def main(argv): global options device_opt = [ "help", "version", "agent", "quiet", "verbose", "debug", "clusterconf", "test", "nodename", "simulate" ] sys.argv = argv opt = process_input(device_opt) # not to get errors that an ipadress is not set which we don't need opt["-a"] = "" # switch on simulation (only if available setSimulation(opt.has_key("-S")) setVerbose(opt.has_key("-v")) options = check_input(device_opt, opt) if options.has_key("-h"): show_docs(options) sys.exit(0) scsi_check_persist() devices = scsi_get_devices(options["-n"].strip(), None, options["-c"].strip()) if not options.has_key("-c"): options["-c"] = "/etc/cluster/cluster.conf" fence_node(options["-n"].strip(), devices, options["-c"].strip())
def main(): atexit.register(atexit_handler) all_opt["tlscert"] = { "getopt": ":", "longopt": "tlscert", "help": "--tlscert " "Path to client certificate for TLS authentication", "required": "0", "shortdesc": "Path to client certificate (PEM format) \ for TLS authentication. Required if --ssl option is used.", "order": 2 } all_opt["tlskey"] = { "getopt": ":", "longopt": "tlskey", "help": "--tlskey " "Path to client key for TLS authentication", "required": "0", "shortdesc": "Path to client key (PEM format) for TLS \ authentication. Required if --ssl option is used.", "order": 2 } all_opt["tlscacert"] = { "getopt": ":", "longopt": "tlscacert", "help": "--tlscacert " "Path to CA certificate for TLS authentication", "required": "0", "shortdesc": "Path to CA certificate (PEM format) for \ TLS authentication. Required if --ssl option is used.", "order": 2 } device_opt = [ "ipaddr", "no_password", "no_login", "port", "method", "web", "tlscert", "tlskey", "tlscacert", "ssl" ] options = check_input(device_opt, process_input(device_opt)) docs = {} docs["shortdesc"] = "Fence agent for Docker" docs["longdesc"] = "fence_docker is I/O fencing agent which \ can be used with the Docker Engine containers. You can use this \ fence-agent without any authentication, or you can use TLS authentication \ (use --ssl option, more info about TLS authentication in docker: \ http://docs.docker.com/examples/https/)." docs["vendorurl"] = "www.docker.io" show_docs(options, docs) run_delay(options) result = fence_action(None, options, set_power_status, get_power_status, get_list, reboot_cycle) sys.exit(result)
def main(): device_opt = ["help", "version", "agent", "quiet", "verbose", "debug", "action", "ipaddr", "login", "passwd", "passwd_script", "secure", "identity_file", "test", "port", "separator", "inet4_only", "inet6_only", "ipport", "power_timeout", "shell_timeout", "login_timeout", "power_wait"] atexit.register(atexit_handler) all_opt["login_timeout"]["default"] = 60 pinput = process_input(device_opt) # use ssh to manipulate node pinput["-x"] = 1 options = check_input(device_opt, pinput) if options["-o"] != "off": sys.exit(0) options["-c"] = "\[EXPECT\]#\ " # this string will be appended to the end of ssh command strict = "-t -o 'StrictHostKeyChecking=no'" serveralive = "-o 'ServerAliveInterval 2'" no_stdin = "-n" bash = "/bin/bash --noprofile --norc" options["ssh_options"] = "{0} {1} {2} '/bin/bash -c " \ "\"PS1={3} {4}\"'".format( strict, serveralive, no_stdin, options["-c"], bash) options["-X"] = "{0} {1} {2} '/bin/bash -c " \ "\"PS1={3} {4}\"'".format( strict, serveralive, no_stdin, options["-c"], bash) docs = {} docs["shortdesc"] = "Fence agent that can just reboot node via ssh" docs["longdesc"] = "fence_ssh is an I/O Fencing agent \ which can be used to reboot nodes via ssh." show_docs(options, docs) # Operate the fencing device # this method will actually launch ssh command conn = fence_login(options) result = fence_action(conn, options, set_power_status, get_power_status, None) try: conn.close() except exceptions.OSError: pass except pexpect.ExceptionPexpect: pass sys.exit(result)
def main(): device_opt = [ "help", "version", "agent", "verbose", "debug", "action", "ipaddr", "login", "passwd", "passwd_script", "secure", "identity_file", "port", "separator", "inet4_only", "inet6_only", "ipport", "power_timeout", "shell_timeout", "login_timeout", "power_wait" ] atexit.register(atexit_handler) all_opt["login_timeout"]["default"] = 60 pinput = process_input(device_opt) # use ssh to manipulate node pinput["--ssh"] = 1 pinput["--command-prompt"] = ".*" options = check_input(device_opt, pinput) if options["--action"] != "off": sys.exit(0) options["-c"] = "\[EXPECT\]#\ " # this string will be appended to the end of ssh command strict = "-t -o 'StrictHostKeyChecking=no'" serveralive = "-o 'ServerAliveInterval 2'" no_stdin = "-n" options["ssh_options"] = "{0} {1} {2} '/bin/bash -c \"PS1={3} /bin/bash " \ "--noprofile --norc\"'".format( strict, serveralive, no_stdin, options["-c"]) options["-X"] = "{0} {1} {2} '/bin/bash -c \"PS1={3} /bin/bash " \ "--noprofile --norc\"'".format( strict, serveralive, no_stdin, options["-c"]) docs = {} docs["shortdesc"] = "Fence agent that can just reboot node via ssh" docs["longdesc"] = "fence_ssh is an I/O Fencing agent " \ "which can be used to reboot nodes via ssh." show_docs(options, docs) # Operate the fencing device # this method will actually launch ssh command conn = fence_login(options) result = fence_action(conn, options, set_power_status, get_power_status, None) try: conn.close() except exceptions.OSError: pass except pexpect.ExceptionPexpect: pass sys.exit(result)
def main(): atexit.register(atexit_handler) all_opt["node_name"] = { "getopt": "N:", "longopt": "nodename", "help": "-N, --nodename " "Node on which machine is located", "required": "0", "shortdesc": "Node on which machine is located. " "(Optional, will be automatically determined)", "order": 2 } device_opt = ["ipaddr", "login", "passwd", "web", "port", "node_name"] all_opt["login"]["required"] = "0" all_opt["login"]["default"] = "root@pam" all_opt["ipport"]["default"] = "8006" all_opt["port"]["shortdesc"] = "Id of the virtual machine." all_opt["ipaddr"]["shortdesc"] = "IP Address or Hostname of a node " +\ "within the Proxmox cluster." options = check_input(device_opt, process_input(device_opt)) docs = {} docs["shortdesc"] = "Fencing agent for the Proxmox Virtual Environment" docs["longdesc"] = "The fence_pve agent can be used to fence virtual \ machines acting as nodes in a virtualized cluster." docs["vendorurl"] = "http://www.proxmox.com/" show_docs(options, docs) run_delay(options) if "--nodename" not in options or not options["--nodename"]: options["--nodename"] = None options["url"] = "https://" + options["--ip"] + ":" + str( options["--ipport"]) + "/api2/json/" options["auth"] = get_ticket(options) if options["auth"] is None: fail(EC_LOGIN_DENIED) # Workaround for unsupported API call on some Proxmox hosts outlets = get_outlet_list( None, options) # Unsupported API-Call will result in value: None if outlets is None: result = fence_action(None, options, set_power_status, get_power_status, None) sys.exit(result) result = fence_action(None, options, set_power_status, get_power_status, get_outlet_list) sys.exit(result)
def main(): atexit.register(atexit_handler) device_opt = [ "no_login", "no_password", "devices", "key", "sudo", "fabric_fencing", "on_target", "store_path", "mpathpersist_path", "force_on", ] define_new_opts() options = check_input(device_opt, process_input(device_opt), other_conditions=True) docs = {} docs["shortdesc"] = "Fence agent for multipath persistent reservation" docs[ "longdesc" ] = 'fence_mpath is an I/O fencing agent that uses SCSI-3 \ persistent reservations to control access multipath devices. Underlying \ devices must support SCSI-3 persistent reservations (SPC-3 or greater) as \ well as the "preempt-and-abort" subcommand.\nThe fence_mpath agent works by \ having a unique key for each node that has to be set in /etc/multipath.conf. \ Once registered, a single node will become the reservation holder \ by creating a "write exclusive, registrants only" reservation on the \ device(s). The result is that only registered nodes may write to the \ device(s). When a node failure occurs, the fence_mpath agent will remove the \ key belonging to the failed node from the device(s). The failed node will no \ longer be able to write to the device(s). A manual reboot is required.' docs["vendorurl"] = "https://www.sourceware.org/dm/" show_docs(options, docs) run_delay(options) # Input control BEGIN if not "--key" in options: fail_usage("Failed: key is required") if options["--action"] == "validate-all": sys.exit(0) options["devices"] = options["--devices"].split(",") if not options["devices"]: fail_usage("Failed: No devices found") # Input control END result = fence_action(None, options, set_status, get_status) sys.exit(result)
def main(): atexit.register(atexit_handler) all_opt["tlscert"] = { "getopt" : ":", "longopt" : "tlscert", "help" : "--tlscert " "Path to client certificate for TLS authentication", "required" : "0", "shortdesc" : "Path to client certificate (PEM format) \ for TLS authentication. Required if --ssl option is used.", "order": 2 } all_opt["tlskey"] = { "getopt" : ":", "longopt" : "tlskey", "help" : "--tlskey " "Path to client key for TLS authentication", "required" : "0", "shortdesc" : "Path to client key (PEM format) for TLS \ authentication. Required if --ssl option is used.", "order": 2 } all_opt["tlscacert"] = { "getopt" : ":", "longopt" : "tlscacert", "help" : "--tlscacert " "Path to CA certificate for TLS authentication", "required" : "0", "shortdesc" : "Path to CA certificate (PEM format) for \ TLS authentication. Required if --ssl option is used.", "order": 2 } device_opt = ["ipaddr", "no_password", "no_login", "port", "method", "web", "tlscert", "tlskey", "tlscacert", "ssl"] options = check_input(device_opt, process_input(device_opt)) docs = { } docs["shortdesc"] = "Fence agent for Docker" docs["longdesc"] = "fence_docker is I/O fencing agent which \ can be used with the Docker Engine containers. You can use this \ fence-agent without any authentication, or you can use TLS authentication \ (use --ssl option, more info about TLS authentication in docker: \ http://docs.docker.com/examples/https/)." docs["vendorurl"] = "www.docker.io" show_docs(options, docs) run_delay(options) result = fence_action(None, options, set_power_status, get_power_status, get_list, reboot_cycle) sys.exit(result)
def main(): atexit.register(atexit_handler) device_opt = ["no_login", "no_password", "devices", "key", "sudo", \ "fabric_fencing", "on_target", "store_path", "mpathpersist_path", "force_on"] define_new_opts() # fence_mpath_check if os.path.basename(sys.argv[0]) == "fence_mpath_check": sys.exit(mpath_check()) elif os.path.basename(sys.argv[0]) == "fence_mpath_check_hardreboot": sys.exit(mpath_check(hardreboot=True)) options = check_input(device_opt, process_input(device_opt), other_conditions=True) docs = {} docs["shortdesc"] = "Fence agent for multipath persistent reservation" docs["longdesc"] = "fence_mpath is an I/O fencing agent that uses SCSI-3 \ persistent reservations to control access multipath devices. Underlying \ devices must support SCSI-3 persistent reservations (SPC-3 or greater) as \ well as the \"preempt-and-abort\" subcommand.\nThe fence_mpath agent works by \ having a unique key for each node that has to be set in /etc/multipath.conf. \ Once registered, a single node will become the reservation holder \ by creating a \"write exclusive, registrants only\" reservation on the \ device(s). The result is that only registered nodes may write to the \ device(s). When a node failure occurs, the fence_mpath agent will remove the \ key belonging to the failed node from the device(s). The failed node will no \ longer be able to write to the device(s). A manual reboot is required." docs["vendorurl"] = "https://www.sourceware.org/dm/" show_docs(options, docs) run_delay(options) # Input control BEGIN if not "--key" in options: fail_usage("Failed: key is required") if options["--action"] == "validate-all": sys.exit(0) options["devices"] = options["--devices"].split(",") if not options["devices"]: fail_usage("Failed: No devices found") # Input control END result = fence_action(None, options, set_status, get_status) sys.exit(result)
def main(): atexit.register(atexit_handler) device_opt = ["rabbit_hosts", "rabbit_port", "user", "domain", "password", "port"] define_new_opts() all_opt["shell_timeout"]["default"] = "180" options = check_input(device_opt, process_input(device_opt)) docs = {} docs["shortdesc"] = "Fence agent for nova compute nodes" docs["longdesc"] = "fence_nova_host is a Nova fencing notification agent" docs["vendorurl"] = "" show_docs(options, docs) run_delay(options) host = None # Potentially we should make this a pacemaker feature if options["--domain"] != "" and "--plug" in options: options["--plug"] = options["--plug"] + "." + options["--domain"] if "--plug" in options: host = options["--plug"] rabbit_hosts = options["--rabbit_hosts"].split(",") port = int(options["--rabbit_port"]) user = options["--user"] password = options["--password"] routing_key = 'auto-evac' exchange = 'auto-evac' if options['--action'] in ['reboot', 'off']: if host is None: logging.error('No host specified') sys.exit(1) for rabbit_host in rabbit_hosts: try: send(user, password, rabbit_host, port, exchange, routing_key, host) sys.exit(0) except Exception: logging.warning('Cannot connect to rabbitmq on %s', rabbit_host) logging.error('Cannot connect to any of rabbitmq brokers') sys.exit(1) sys.exit(0)
def main(): atexit.register(atexit_handler) all_opt["node_name"] = { "getopt" : "N:", "longopt" : "nodename", "help" : "-N, --nodename " "Node on which machine is located", "required" : "0", "shortdesc" : "Node on which machine is located. " "(Optional, will be automatically determined)", "order": 2 } device_opt = ["ipaddr", "login", "passwd", "web", "port", "node_name"] all_opt["login"]["required"] = "0" all_opt["login"]["default"] = "root@pam" all_opt["ipport"]["default"] = "8006" all_opt["port"]["shortdesc"] = "Id of the virtual machine." all_opt["ipaddr"]["shortdesc"] = "IP Address or Hostname of a node " +\ "within the Proxmox cluster." options = check_input(device_opt, process_input(device_opt)) docs = {} docs["shortdesc"] = "Fencing agent for the Proxmox Virtual Environment" docs["longdesc"] = "The fence_pve agent can be used to fence virtual \ machines acting as nodes in a virtualized cluster." docs["vendorurl"] = "http://www.proxmox.com/" show_docs(options, docs) run_delay(options) if "--nodename" not in options or not options["--nodename"]: options["--nodename"] = None options["url"] = "https://" + options["--ip"] + ":" + str(options["--ipport"]) + "/api2/json/" options["auth"] = get_ticket(options) if options["auth"] is None: fail(EC_LOGIN_DENIED) result = fence_action(None, options, set_power_status, get_power_status, get_outlet_list) sys.exit(result)
def main(): device_opt = [ "no_status", "no_password", "ping_count", "ping_good_count", "ping_interval", "ping_timeout", "ping_maxfail", "ping_targets", "method" ] define_new_opts() atexit.register(atexit_handler) all_opt["method"]["default"] = "cycle" all_opt["method"][ "help"] = "-m, --method=[method] Method to fence (cycle|onoff) (Default: cycle)" options = check_input(device_opt, process_input(device_opt)) docs = {} docs["shortdesc"] = "Fence agent for ping-heuristic based fencing" docs[ "longdesc"] = "fence_heuristics_ping uses ping-heuristics to control execution of another fence agent on the same fencing level.\ \n.P\n\ This is not a fence agent by itself! \ Its only purpose is to enable/disable another fence agent that lives on the same fencing level but after fence_heuristics_ping." docs["vendorurl"] = "" show_docs(options, docs) # move ping-test to the end of the time-window set via --delay # as to give the network time to settle after the incident that has # caused fencing and have the results as current as possible max_pingcheck = (int(options["--ping-count"]) - 1) * \ int(options["--ping-interval"]) + int(options["--ping-timeout"]) run_delay(options, reserve=max_pingcheck) result = fence_action(\ None, \ options, \ None, \ None, \ reboot_cycle_fn = ping_test, sync_set_power_fn = ping_test) # execute the remaining delay run_delay(options, result=result) sys.exit(result)
def main(): atexit.register(atexit_handler) device_opt = ["crosscableip", "timeout", "no_password", "no_login", "port"] define_new_opts() options = check_input(device_opt, process_input(device_opt)) docs = {} docs["shortdesc"] = "Fence agent for cross-link two-node clusters" docs["longdesc"] = "This agent helps two-node clusters to tackle the " \ "situation where one node lost power, cannot be " \ "fenced by telling pacemaker that if the node is not " \ "reachable over the crosslink cable, we can assume " \ "it is dead" docs["vendorurl"] = "" show_docs(options, docs) run_delay(options) result = fence_action(None, options, set_power_status, get_power_status) sys.exit(result)
def main(argv): global options device_opt = [ "help", "version", "agent", "quiet", "verbose", "debug", "clusterconf", "test", "nodename", "simulate" ] sys.argv=argv opt=process_input(device_opt) # not to get errors that an ipadress is not set which we don't need opt["-a"]="" # switch on simulation (only if available setSimulation(opt.has_key("-S")) setVerbose(opt.has_key("-v")) options = check_input(device_opt, opt) if options.has_key("-h"): show_docs(options) sys.exit(0) scsi_check_persist() devices=scsi_get_devices(options["-n"].strip(), None, options["-c"].strip()) if not options.has_key("-c"): options["-c"]="/etc/cluster/cluster.conf" fence_node(options["-n"].strip(), devices, options["-c"].strip())
def main(): device_opt = ["no_status", "no_password", "ping_count", "ping_good_count", "ping_interval", "ping_timeout", "ping_maxfail", "ping_targets", "method"] define_new_opts() atexit.register(atexit_handler) all_opt["method"]["default"] = "cycle" all_opt["method"]["help"] = "-m, --method=[method] Method to fence (cycle|onoff) (Default: cycle)" options = check_input(device_opt, process_input(device_opt)) docs = {} docs["shortdesc"] = "Fence agent for ping-heuristic based fencing" docs["longdesc"] = "fence_heuristics_ping uses ping-heuristics to control execution of another fence agent on the same fencing level.\ \n.P\n\ This is not a fence agent by itself! \ Its only purpose is to enable/disable another fence agent that lives on the same fencing level but after fence_heuristics_ping." docs["vendorurl"] = "" show_docs(options, docs) # move ping-test to the end of the time-window set via --delay # as to give the network time to settle after the incident that has # caused fencing and have the results as current as possible max_pingcheck = (int(options["--ping-count"]) - 1) * \ int(options["--ping-interval"]) + int(options["--ping-timeout"]) run_delay(options, reserve=max_pingcheck) result = fence_action(\ None, \ options, \ None, \ None, \ reboot_cycle_fn = ping_test, sync_set_power_fn = ping_test) # execute the remaining delay run_delay(options, result=result) sys.exit(result)
def main(): conn = None device_opt = ["port", "no_password", "zone", "project"] atexit.register(atexit_handler) define_new_opts() all_opt["power_timeout"]["default"] = "60" options = check_input(device_opt, process_input(device_opt)) docs = {} docs["shortdesc"] = "Fence agent for GCE (Google Cloud Engine)" docs["longdesc"] = "fence_gce is an I/O Fencing agent for GCE (Google Cloud " \ "Engine). It uses the googleapiclient library to connect to GCE.\n" \ "googleapiclient can be configured with Google SDK CLI or by " \ "executing 'gcloud auth application-default login'.\n" \ "For instructions see: https://cloud.google.com/compute/docs/tutorials/python-guide" docs["vendorurl"] = "http://cloud.google.com" show_docs(options, docs) run_delay(options) try: credentials = None if tuple(googleapiclient.__version__) < tuple("1.6.0"): import oauth2client.client credentials = oauth2client.client.GoogleCredentials.get_application_default() conn = googleapiclient.discovery.build('compute', 'v1', credentials=credentials) except Exception as err: fail_usage("Failed: Create GCE compute v1 connection: {}".format(str(err))) # Operate the fencing device result = fence_action(conn, options, set_power_status, get_power_status, get_nodes_list) sys.exit(result)
def main(): atexit.register(atexit_handler) device_opt = [ "user", "domain", "password", "tenant", "auth_url", "wf_name", "port", "mistral_url", "on_shared_storage" ] define_new_opts() all_opt["shell_timeout"]["default"] = "180" options = check_input(device_opt, process_input(device_opt)) docs = {} docs["shortdesc"] = "Fence agent for nova compute nodes" docs["longdesc"] = "fence_evacuate is a Nova fencing notification agent" docs["vendorurl"] = "" show_docs(options, docs) run_delay(options) host = None # Potentially we should make this a pacemaker feature if options["--domain"] != "" and "--plug" in options: options["--plug"] = options["--plug"] + "." + options["--domain"] if "--plug" in options: host = options["--plug"] if options['--action'] in ['reboot', 'off']: if host is None: logging.error('No host specified') sys.exit(1) evacuate(host, options) sys.exit(0)
def main(): atexit.register(atexit_handler) device_opt = ["no_login", "no_password", "devices", "nodename", "port",\ "no_port", "key", "aptpl", "fabric_fencing", "on_target", "corosync_cmap_path",\ "sg_persist_path", "sg_turs_path", "logfile", "vgs_path", "force_on"] define_new_opts() all_opt["delay"]["getopt"] = "H:" all_opt["port"]["help"] = "-n, --plug=[nodename] Name of the node to be fenced" all_opt["port"]["shortdesc"] = "Name of the node to be fenced. The node name is used to \ generate the key value used for the current operation. This option will be \ ignored when used with the -k option." #fence_scsi_check if os.path.basename(sys.argv[0]) == "fence_scsi_check": sys.exit(scsi_check()) elif os.path.basename(sys.argv[0]) == "fence_scsi_check_hardreboot": sys.exit(scsi_check(True)) options = check_input(device_opt, process_input(device_opt), other_conditions=True) # hack to remove list/list-status actions which are not supported options["device_opt"] = [ o for o in options["device_opt"] if o != "separator" ] docs = {} docs["shortdesc"] = "Fence agent for SCSI persistent reservation" docs["longdesc"] = "fence_scsi is an I/O fencing agent that uses SCSI-3 \ persistent reservations to control access to shared storage devices. These \ devices must support SCSI-3 persistent reservations (SPC-3 or greater) as \ well as the \"preempt-and-abort\" subcommand.\nThe fence_scsi agent works by \ having each node in the cluster register a unique key with the SCSI \ device(s). Once registered, a single node will become the reservation holder \ by creating a \"write exclusive, registrants only\" reservation on the \ device(s). The result is that only registered nodes may write to the \ device(s). When a node failure occurs, the fence_scsi agent will remove the \ key belonging to the failed node from the device(s). The failed node will no \ longer be able to write to the device(s). A manual reboot is required.\ \n.P\n\ When used as a watchdog device you can define e.g. retry=1, retry-sleep=2 and \ verbose=yes parameters in /etc/sysconfig/stonith if you have issues with it \ failing." docs["vendorurl"] = "" show_docs(options, docs) run_delay(options) # backward compatibility layer BEGIN if "--logfile" in options: try: logfile = open(options["--logfile"], 'w') sys.stderr = logfile sys.stdout = logfile except IOError: fail_usage("Failed: Unable to create file " + options["--logfile"]) # backward compatibility layer END options["store_path"] = STORE_PATH # Input control BEGIN stop_after_error = False if options["--action"] == "validate-all" else True if options["--action"] == "monitor": sys.exit(do_action_monitor(options)) # workaround to avoid regressions if "--nodename" in options and options["--nodename"]: options["--plug"] = options["--nodename"] del options["--nodename"] if not (("--plug" in options and options["--plug"])\ or ("--key" in options and options["--key"])): fail_usage("Failed: nodename or key is required", stop_after_error) if not ("--key" in options and options["--key"]): options["--key"] = generate_key(options) if options["--key"] == "0" or not options["--key"]: fail_usage("Failed: key cannot be 0", stop_after_error) if options["--action"] == "validate-all": sys.exit(0) options["--key"] = options["--key"].lstrip('0') if not ("--devices" in options and options["--devices"].split(",")): options["devices"] = get_clvm_devices(options) else: options["devices"] = options["--devices"].split(",") if not options["devices"]: fail_usage("Failed: No devices found") # Input control END result = fence_action(None, options, set_status, get_status) sys.exit(result)
def main(): conn = None device_opt = [ "port", "no_password", "zone", "project", "stackdriver-logging", "method", "baremetalsolution", "apitimeout", "retries", "retrysleep", "serviceaccount", "proxyhost", "proxyport" ] atexit.register(atexit_handler) define_new_opts() all_opt["power_timeout"]["default"] = "60" options = check_input(device_opt, process_input(device_opt)) docs = {} docs["shortdesc"] = "Fence agent for GCE (Google Cloud Engine)" docs["longdesc"] = "fence_gce is an I/O Fencing agent for GCE (Google Cloud " \ "Engine). It uses the googleapiclient library to connect to GCE.\n" \ "googleapiclient can be configured with Google SDK CLI or by " \ "executing 'gcloud auth application-default login'.\n" \ "For instructions see: https://cloud.google.com/compute/docs/tutorials/python-guide" docs["vendorurl"] = "http://cloud.google.com" show_docs(options, docs) run_delay(options) # Prepare logging if options.get('--verbose') is None: logging.getLogger('googleapiclient').setLevel(logging.ERROR) logging.getLogger('oauth2client').setLevel(logging.ERROR) if options.get('--stackdriver-logging') is not None and options.get( '--plug'): try: import google.cloud.logging.handlers client = google.cloud.logging.Client() handler = google.cloud.logging.handlers.CloudLoggingHandler( client, name=options['--plug']) handler.setLevel(logging.INFO) formatter = logging.Formatter('gcp:stonith "%(message)s"') handler.setFormatter(formatter) root_logger = logging.getLogger() if options.get('--verbose') is None: root_logger.setLevel(logging.INFO) root_logger.addHandler(handler) except ImportError: logging.error('Couldn\'t import google.cloud.logging, ' 'disabling Stackdriver-logging support') # if apitimeout is defined we set the socket timeout, if not we keep the # socket default which is 60s if options.get("--apitimeout"): socket.setdefaulttimeout(options["--apitimeout"]) # Prepare cli try: if options.get("--serviceaccount"): scope = ['https://www.googleapis.com/auth/cloud-platform'] credentials = ServiceAccountCredentials.from_json_keyfile_name( options.get("--serviceaccount"), scope) logging.debug("using credentials from service account") else: credentials = GoogleCredentials.get_application_default() logging.debug("using application default credentials") if options.get("--proxyhost") and options.get("--proxyport"): proxy_info = httplib2.ProxyInfo( proxy_type=socks.PROXY_TYPE_HTTP, proxy_host=options.get("--proxyhost"), proxy_port=int(options.get("--proxyport"))) http = credentials.authorize(httplib2.Http(proxy_info=proxy_info)) conn = googleapiclient.discovery.build('compute', 'v1', http=http, cache_discovery=False) else: conn = googleapiclient.discovery.build('compute', 'v1', credentials=credentials, cache_discovery=False) except Exception as err: fail_usage("Failed: Create GCE compute v1 connection: {}".format( str(err))) # Get project and zone if not options.get("--project"): try: options["--project"] = get_metadata('project/project-id') except Exception as err: fail_usage( "Failed retrieving GCE project. Please provide --project option: {}" .format(str(err))) if "--baremetalsolution" in options: options["--zone"] = "none" if not options.get("--zone"): try: options["--zone"] = get_zone(conn, options) except Exception as err: fail_usage( "Failed retrieving GCE zone. Please provide --zone option: {}". format(str(err))) # Operate the fencing device result = fence_action(conn, options, set_power_status, get_power_status, get_nodes_list, power_cycle) sys.exit(result)
def main(): atexit.register(atexit_handler) all_opt["pve_node_auto"] = { "getopt": "A", "longopt": "pve-node-auto", "help": "-A, --pve-node-auto " "Automatically select proxmox node", "required": "0", "shortdesc": "Automatically select proxmox node. " "(This option overrides --pve-node)", "type": "boolean", "order": 2 } all_opt["pve_node"] = { "getopt": "N:", "longopt": "pve-node", "help": "-N, --pve-node=[node_name] " "Proxmox node name on which machine is located", "required": "0", "shortdesc": "Proxmox node name on which machine is located. " "(Must be specified if not using --pve-node-auto)", "order": 2 } all_opt["node_name"] = { "getopt": ":", "longopt": "nodename", "help": "--nodename " "Replaced by --pve-node", "required": "0", "shortdesc": "Replaced by --pve-node", "order": 3 } all_opt["vmtype"] = { "getopt": ":", "longopt": "vmtype", "default": "qemu", "help": "--vmtype " "Virtual machine type lxc or qemu (default: qemu)", "required": "1", "shortdesc": "Virtual machine type lxc or qemu. " "(Default: qemu)", "order": 2 } device_opt = [ "ipaddr", "login", "passwd", "web", "port", "pve_node", "pve_node_auto", "node_name", "vmtype", "method" ] all_opt["login"]["required"] = "0" all_opt["login"]["default"] = "root@pam" all_opt["ipport"]["default"] = "8006" all_opt["port"]["shortdesc"] = "Id of the virtual machine." all_opt["ipaddr"]["shortdesc"] = "IP Address or Hostname of a node " +\ "within the Proxmox cluster." options = check_input(device_opt, process_input(device_opt)) docs = {} docs["shortdesc"] = "Fencing agent for the Proxmox Virtual Environment" docs["longdesc"] = "The fence_pve agent can be used to fence virtual \ machines acting as nodes in a virtualized cluster." docs["vendorurl"] = "http://www.proxmox.com/" show_docs(options, docs) run_delay(options) if "--pve-node-auto" in options: # Force pve-node to None to allow autodiscovery options["--pve-node"] = None elif "--pve-node" in options and options["--pve-node"]: # Leave pve-node alone pass elif "--nodename" in options and options["--nodename"]: # map nodename into pve-node to support legacy implementations options["--pve-node"] = options["--nodename"] else: fail_usage( "At least one of pve-node-auto or pve-node must be supplied") if options["--vmtype"] != "qemu": # For vmtypes other than qemu, only the onoff method is valid options["--method"] = "onoff" options["url"] = "https://" + options["--ip"] + ":" + str( options["--ipport"]) + "/api2/json/" options["auth"] = get_ticket(options) if options["auth"] is None: fail(EC_LOGIN_DENIED) # Workaround for unsupported API call on some Proxmox hosts outlets = get_outlet_list( None, options) # Unsupported API-Call will result in value: None if outlets is None: result = fence_action(None, options, set_power_status, get_power_status, None, reboot_cycle) sys.exit(result) result = fence_action(None, options, set_power_status, get_power_status, get_outlet_list, reboot_cycle) sys.exit(result)
def main(): """Main function """ # We need to define "no_password" otherwise we will be ask about it if # we don't provide any password. device_opt = ["no_password", "devices", "port", "method", "sbd_path"] # close stdout if we get interrupted atexit.register(atexit_handler) define_new_opts() all_opt["method"]["default"] = "cycle" all_opt["method"]["help"] = "-m, --method=[method] Method to fence (onoff|cycle) (Default: cycle)" options = check_input(device_opt, process_input(device_opt)) # fill the needed variables to generate metadata and help text output docs = {} docs["shortdesc"] = "Fence agent for sbd" docs["longdesc"] = "fence_sbd is I/O Fencing agent \ which can be used in environments where sbd can be used (shared storage)." docs["vendorurl"] = "" show_docs(options, docs) # We need to check if --devices is given and not empty. if "--devices" not in options: fail_usage("No SBD devices specified. \ At least one SBD device is required.") run_delay(options) # We need to check if the provided sbd_devices exists. We need to do # that for every given device. for device_path in parse_sbd_devices(options): logging.debug("check device \"%s\"", device_path) return_code = check_sbd_device(options, device_path) if PATH_NOT_EXISTS == return_code: logging.error("\"%s\" does not exist", device_path) elif PATH_NOT_BLOCK == return_code: logging.error("\"%s\" is not a valid block device", device_path) elif DEVICE_NOT_INIT == return_code: logging.error("\"%s\" is not initialized", device_path) elif DEVICE_INIT != return_code: logging.error("UNKNOWN error while checking \"%s\"", device_path) # If we get any error while checking the device we need to exit at this # point. if DEVICE_INIT != return_code: exit(return_code) # we check against the defined timeouts. If the pacemaker timeout is smaller # then that defined within sbd we should report this. power_timeout = int(options["--power-timeout"]) sbd_msg_timeout = get_msg_timeout(options) if power_timeout <= sbd_msg_timeout: logging.warn("power timeout needs to be \ greater then sbd message timeout") result = fence_action(\ None, \ options, \ set_power_status, \ get_power_status, \ get_node_list, \ reboot_cycle) sys.exit(result)
def main(): atexit.register(atexit_handler) device_opt = ["no_login", "no_password", "devices", "key", "sudo", \ "fabric_fencing", "on_target", "store_path", \ "mpathpersist_path", "force_on", "port", "no_port"] define_new_opts() all_opt["port"]["required"] = "0" all_opt["port"][ "help"] = "-n, --plug=[key] Key to use for the current operation" all_opt["port"]["shortdesc"] = "Key to use for the current operation. \ This key should be unique to a node and have to be written in \ /etc/multipath.conf. For the \"on\" action, the key specifies the key use to \ register the local node. For the \"off\" action, this key specifies the key to \ be removed from the device(s)." # fence_mpath_check if os.path.basename(sys.argv[0]) == "fence_mpath_check": sys.exit(mpath_check()) elif os.path.basename(sys.argv[0]) == "fence_mpath_check_hardreboot": sys.exit(mpath_check(hardreboot=True)) options = check_input(device_opt, process_input(device_opt), other_conditions=True) # hack to remove list/list-status actions which are not supported options["device_opt"] = [ o for o in options["device_opt"] if o != "separator" ] # workaround to avoid regressions if "--key" in options: options["--plug"] = options["--key"] del options["--key"] elif "--help" not in options and options["--action"] in ["off", "on", \ "reboot", "status", "validate-all"] and "--plug" not in options: stop_after_error = False if options[ "--action"] == "validate-all" else True fail_usage( "Failed: You have to enter plug number or machine identification", stop_after_error) docs = {} docs["shortdesc"] = "Fence agent for multipath persistent reservation" docs["longdesc"] = "fence_mpath is an I/O fencing agent that uses SCSI-3 \ persistent reservations to control access multipath devices. Underlying \ devices must support SCSI-3 persistent reservations (SPC-3 or greater) as \ well as the \"preempt-and-abort\" subcommand.\nThe fence_mpath agent works by \ having a unique key for each node that has to be set in /etc/multipath.conf. \ Once registered, a single node will become the reservation holder \ by creating a \"write exclusive, registrants only\" reservation on the \ device(s). The result is that only registered nodes may write to the \ device(s). When a node failure occurs, the fence_mpath agent will remove the \ key belonging to the failed node from the device(s). The failed node will no \ longer be able to write to the device(s). A manual reboot is required.\ \n.P\n\ When used as a watchdog device you can define e.g. retry=1, retry-sleep=2 and \ verbose=yes parameters in /etc/sysconfig/stonith if you have issues with it \ failing." docs["vendorurl"] = "https://www.sourceware.org/dm/" show_docs(options, docs) run_delay(options) # Input control BEGIN if options["--action"] == "validate-all": sys.exit(0) if not ("--devices" in options and options["--devices"]): fail_usage("Failed: No devices found") options["devices"] = [ d for d in re.split("\s*,\s*|\s+", options["--devices"].strip()) if d ] # Input control END result = fence_action(None, options, set_status, get_status) sys.exit(result)
def main(): conn = None device_opt = [ "port", "no_password", "zone", "project", "stackdriver-logging", "method" ] atexit.register(atexit_handler) define_new_opts() all_opt["power_timeout"]["default"] = "60" all_opt["method"]["default"] = "cycle" all_opt["method"][ "help"] = "-m, --method=[method] Method to fence (onoff|cycle) (Default: cycle)" options = check_input(device_opt, process_input(device_opt)) docs = {} docs["shortdesc"] = "Fence agent for GCE (Google Cloud Engine)" docs["longdesc"] = "fence_gce is an I/O Fencing agent for GCE (Google Cloud " \ "Engine). It uses the googleapiclient library to connect to GCE.\n" \ "googleapiclient can be configured with Google SDK CLI or by " \ "executing 'gcloud auth application-default login'.\n" \ "For instructions see: https://cloud.google.com/compute/docs/tutorials/python-guide" docs["vendorurl"] = "http://cloud.google.com" show_docs(options, docs) run_delay(options) # Prepare logging if options.get('--verbose') is None: logging.getLogger('googleapiclient').setLevel(logging.ERROR) logging.getLogger('oauth2client').setLevel(logging.ERROR) if options.get('--stackdriver-logging') is not None and options.get( '--plug'): try: import google.cloud.logging.handlers client = google.cloud.logging.Client() handler = google.cloud.logging.handlers.CloudLoggingHandler( client, name=options['--plug']) handler.setLevel(logging.INFO) formatter = logging.Formatter('gcp:stonith "%(message)s"') handler.setFormatter(formatter) root_logger = logging.getLogger() if options.get('--verbose') is None: root_logger.setLevel(logging.INFO) root_logger.addHandler(handler) except ImportError: logging.error('Couldn\'t import google.cloud.logging, ' 'disabling Stackdriver-logging support') # Prepare cli try: credentials = None if tuple(googleapiclient.__version__) < tuple("1.6.0"): import oauth2client.client credentials = oauth2client.client.GoogleCredentials.get_application_default( ) conn = googleapiclient.discovery.build('compute', 'v1', credentials=credentials) except Exception as err: fail_usage("Failed: Create GCE compute v1 connection: {}".format( str(err))) # Get project and zone if not options.get("--project"): try: options["--project"] = get_metadata('project/project-id') except Exception as err: fail_usage( "Failed retrieving GCE project. Please provide --project option: {}" .format(str(err))) if not options.get("--zone"): try: options["--zone"] = get_zone(conn, options['--project'], options['--plug']) except Exception as err: fail_usage( "Failed retrieving GCE zone. Please provide --zone option: {}". format(str(err))) # Operate the fencing device result = fence_action(conn, options, set_power_status, get_power_status, get_nodes_list, power_cycle) sys.exit(result)
def main(): atexit.register(atexit_handler) device_opt = ["no_login", "no_password", "devices", "nodename", "key",\ "aptpl", "fabric_fencing", "on_target", "corosync-cmap_path",\ "sg_persist_path", "sg_turs_path", "logfile", "vgs_path"] define_new_opts() all_opt["delay"]["getopt"] = "H:" #fence_scsi_check if os.path.basename(sys.argv[0]) == "fence_scsi_check": sys.exit(scsi_check()) options = check_input(device_opt, process_input(device_opt), other_conditions=True) docs = {} docs["shortdesc"] = "Fence agent for SCSI persistentl reservation" docs["longdesc"] = "fence_scsi is an I/O fencing agent that uses SCSI-3 \ persistent reservations to control access to shared storage devices. These \ devices must support SCSI-3 persistent reservations (SPC-3 or greater) as \ well as the \"preempt-and-abort\" subcommand.\nThe fence_scsi agent works by \ having each node in the cluster register a unique key with the SCSI \ devive(s). Once registered, a single node will become the reservation holder \ by creating a \"write exclusive, registrants only\" reservation on the \ device(s). The result is that only registered nodes may write to the \ device(s). When a node failure occurs, the fence_scsi agent will remove the \ key belonging to the failed node from the device(s). The failed node will no \ longer be able to write to the device(s). A manual reboot is required." docs["vendorurl"] = "" show_docs(options, docs) run_delay(options) # backward compatibility layer BEGIN if "--logfile" in options: try: logfile = open(options["--logfile"], 'w') sys.stderr = logfile sys.stdout = logfile except IOError: fail_usage("Failed: Unable to create file " + options["--logfile"]) # backward compatibility layer END options["store_path"] = STORE_PATH # Input control BEGIN stop_after_error = False if options["--action"] == "validate-all" else True if options["--action"] == "monitor": sys.exit(do_action_monitor(options)) if not (("--nodename" in options and options["--nodename"])\ or ("--key" in options and options["--key"])): fail_usage("Failed: nodename or key is required", stop_after_error) if not ("--key" in options and options["--key"]): options["--key"] = generate_key(options) if options["--key"] == "0" or not options["--key"]: fail_usage("Failed: key cannot be 0", stop_after_error) if options["--action"] == "validate-all": sys.exit(0) options["--key"] = options["--key"].lstrip('0') if not ("--devices" in options and options["--devices"].split(",")): options["devices"] = get_clvm_devices(options) else: options["devices"] = options["--devices"].split(",") if not options["devices"]: fail_usage("Failed: No devices found") # Input control END result = fence_action(None, options, set_status, get_status) sys.exit(result)
def main(): atexit.register(atexit_handler) device_opt = ["no_login", "no_password", "devices", "nodename", "key",\ "aptpl", "fabric_fencing", "on_target", "corosync-cmap_path",\ "sg_persist_path", "sg_turs_path", "logfile", "vgs_path"] define_new_opts() all_opt["delay"]["getopt"] = "H:" #fence_scsi_check if os.path.basename(sys.argv[0]) == "fence_scsi_check": sys.exit(scsi_check()) options = check_input(device_opt, process_input(device_opt), other_conditions=True) docs = {} docs["shortdesc"] = "Fence agent for SCSI persistentl reservation" docs["longdesc"] = "fence_scsi is an I/O fencing agent that uses SCSI-3 \ persistent reservations to control access to shared storage devices. These \ devices must support SCSI-3 persistent reservations (SPC-3 or greater) as \ well as the \"preempt-and-abort\" subcommand.\nThe fence_scsi agent works by \ having each node in the cluster register a unique key with the SCSI \ devive(s). Once registered, a single node will become the reservation holder \ by creating a \"write exclusive, registrants only\" reservation on the \ device(s). The result is that only registered nodes may write to the \ device(s). When a node failure occurs, the fence_scsi agent will remove the \ key belonging to the failed node from the device(s). The failed node will no \ longer be able to write to the device(s). A manual reboot is required." docs["vendorurl"] = "" show_docs(options, docs) run_delay(options) # backward compatibility layer BEGIN if "--logfile" in options: try: logfile = open(options["--logfile"], 'w') sys.stderr = logfile sys.stdout = logfile except IOError: fail_usage("Failed: Unable to create file " + options["--logfile"]) # backward compatibility layer END options["store_path"] = STORE_PATH # Input control BEGIN stop_after_error = False if options["--action"] == "validate-all" else True if not (("--nodename" in options and options["--nodename"])\ or ("--key" in options and options["--key"])): fail_usage("Failed: nodename or key is required", stop_after_error) if not ("--key" in options and options["--key"]): options["--key"] = generate_key(options) if options["--key"] == "0" or not options["--key"]: fail_usage("Failed: key cannot be 0", stop_after_error) if options["--action"] == "validate-all": sys.exit(0) options["--key"] = options["--key"].lstrip('0') if not ("--devices" in options and options["--devices"].split(",")): options["devices"] = get_clvm_devices(options) else: options["devices"] = options["--devices"].split(",") if not options["devices"]: fail_usage("Failed: No devices found") # Input control END result = fence_action(None, options, set_status, get_status) sys.exit(result)
def main(): conn = None device_opt = [ "port", "no_password", "zone", "project", "stackdriver-logging", "method", "baremetalsolution", "apitimeout", "retries", "retrysleep", "serviceaccount", "plugzonemap", "proxyhost", "proxyport" ] atexit.register(atexit_handler) define_new_opts() all_opt["power_timeout"]["default"] = "60" all_opt["method"]["default"] = "cycle" all_opt["method"][ "help"] = "-m, --method=[method] Method to fence (onoff|cycle) (Default: cycle)" options = check_input(device_opt, process_input(device_opt)) docs = {} docs["shortdesc"] = "Fence agent for GCE (Google Cloud Engine)" docs["longdesc"] = "fence_gce is an I/O Fencing agent for GCE (Google Cloud " \ "Engine). It uses the googleapiclient library to connect to GCE.\n" \ "googleapiclient can be configured with Google SDK CLI or by " \ "executing 'gcloud auth application-default login'.\n" \ "For instructions see: https://cloud.google.com/compute/docs/tutorials/python-guide" docs["vendorurl"] = "http://cloud.google.com" show_docs(options, docs) run_delay(options) # Prepare logging if options.get('--verbose') is None: logging.getLogger('googleapiclient').setLevel(logging.ERROR) logging.getLogger('oauth2client').setLevel(logging.ERROR) if options.get('--stackdriver-logging') is not None and options.get( '--plug'): try: import google.cloud.logging.handlers client = google.cloud.logging.Client() handler = google.cloud.logging.handlers.CloudLoggingHandler( client, name=options['--plug']) handler.setLevel(logging.INFO) formatter = logging.Formatter('gcp:stonith "%(message)s"') handler.setFormatter(formatter) root_logger = logging.getLogger() if options.get('--verbose') is None: root_logger.setLevel(logging.INFO) root_logger.addHandler(handler) except ImportError: logging.error('Couldn\'t import google.cloud.logging, ' 'disabling Stackdriver-logging support') # if apitimeout is defined we set the socket timeout, if not we keep the # socket default which is 60s if options.get("--apitimeout"): socket.setdefaulttimeout(options["--apitimeout"]) # Prepare cli try: serviceaccount = options.get("--serviceaccount") if serviceaccount: scope = ['https://www.googleapis.com/auth/cloud-platform'] logging.debug("using credentials from service account") try: from google.oauth2.service_account import Credentials as ServiceAccountCredentials credentials = ServiceAccountCredentials.from_service_account_file( filename=serviceaccount, scopes=scope) except ImportError: from oauth2client.service_account import ServiceAccountCredentials credentials = ServiceAccountCredentials.from_json_keyfile_name( serviceaccount, scope) else: try: from googleapiclient import _auth credentials = _auth.default_credentials() except: credentials = GoogleCredentials.get_application_default() logging.debug("using application default credentials") if options.get("--proxyhost") and options.get("--proxyport"): proxy_info = httplib2.ProxyInfo( proxy_type=socks.PROXY_TYPE_HTTP, proxy_host=options.get("--proxyhost"), proxy_port=int(options.get("--proxyport"))) http = credentials.authorize(httplib2.Http(proxy_info=proxy_info)) conn = googleapiclient.discovery.build('compute', 'v1', http=http, cache_discovery=False) else: conn = googleapiclient.discovery.build('compute', 'v1', credentials=credentials, cache_discovery=False) except Exception as err: fail_usage("Failed: Create GCE compute v1 connection: {}".format( str(err))) # Get project and zone if not options.get("--project"): try: options["--project"] = get_metadata('project/project-id') except Exception as err: fail_usage( "Failed retrieving GCE project. Please provide --project option: {}" .format(str(err))) if "--baremetalsolution" in options: options["--zone"] = "none" # Populates zone automatically if missing from the command zones = [] if not "--zone" in options else options["--zone"].split(",") options["--plugzonemap"] = {} if "--plug" in options: for i, instance in enumerate(options["--plug"].split(",")): if len(zones) == 1: # If only one zone is specified, use it across all plugs options["--plugzonemap"][instance] = zones[0] continue if len(zones) - 1 >= i: # If we have enough zones specified with the --zone flag use the zone at # the same index as the plug options["--plugzonemap"][instance] = zones[i] continue try: # In this case we do not have a zone specified so we attempt to detect it options["--plugzonemap"][instance] = get_zone( conn, options, instance) except Exception as err: fail_usage( "Failed retrieving GCE zone. Please provide --zone option: {}" .format(str(err))) # Operate the fencing device result = fence_action(conn, options, set_power_status, get_power_status, get_nodes_list, power_cycle) sys.exit(result)