diff --git a/fence/agents/virsh/fence_virsh.py b/fence/agents/virsh/fence_virsh.py index 0a94136b..24d360c2 100644 --- a/fence/agents/virsh/fence_virsh.py +++ b/fence/agents/virsh/fence_virsh.py @@ -1,100 +1,102 @@ #!/usr/bin/python -tt # The Following Agent Has Been Tested On: # # Virsh 0.3.3 on RHEL 5.2 with xen-3.0.3-51 # import sys, re import time import atexit sys.path.append("@FENCEAGENTSLIBDIR@") from fencing import * from fencing import fail_usage #BEGIN_VERSION_GENERATION RELEASE_VERSION="Virsh fence agent" REDHAT_COPYRIGHT="" BUILD_DATE="" #END_VERSION_GENERATION def get_name_or_uuid(options): return options["--uuid"] if options.has_key("--uuid") else options["--plug"] def get_outlets_status(conn, options): if options.has_key("--use-sudo"): prefix = options["--sudo-path"] + " " else: prefix = "" conn.sendline(prefix + "virsh list --all") conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"])) result = {} #This is status of mini finite automata. 0 = we didn't found Id and Name, 1 = we did fa_status = 0 for line in conn.before.splitlines(): domain = re.search(r"^\s*(\S+)\s+(\S+)\s+(\S+).*$", line) if domain != None: if fa_status == 0 and domain.group(1).lower() == "id" and domain.group(2).lower() == "name": fa_status = 1 elif fa_status == 1: result[domain.group(2)] = ("", (domain.group(3).lower() in ["running", "blocked", "idle", "no state", "paused"] and "on" or "off")) return result def get_power_status(conn, options): prefix = options["--sudo-path"] + " " if options.has_key("--use-sudo") else "" conn.sendline(prefix + "virsh domstate %s" % (get_name_or_uuid(options))) conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"])) for line in conn.before.splitlines(): if line.strip() in ["running", "blocked", "idle", "no state", "paused"]: return "on" + if "error: failed to get domain" in line.strip() and options.has_key("missing_as_off"): + return "off" if "error:" in line.strip(): fail_usage("Failed: You have to enter existing name/UUID of virtual machine!") return "off" def set_power_status(conn, options): prefix = options["--sudo-path"] + " " if options.has_key("--use-sudo") else "" conn.sendline(prefix + "virsh %s " % (options["--action"] == "on" and "start" or "destroy") + get_name_or_uuid(options)) conn.log_expect(options["--command-prompt"], int(options["--power-timeout"])) time.sleep(int(options["--power-wait"])) def main(): - device_opt = ["ipaddr", "login", "passwd", "cmd_prompt", "secure", "port", "sudo"] + device_opt = ["ipaddr", "login", "passwd", "cmd_prompt", "secure", "port", "sudo", "missing_as_off"] atexit.register(atexit_handler) all_opt["secure"]["default"] = "1" all_opt["cmd_prompt"]["default"] = [r"\[EXPECT\]#\ "] all_opt["ssh_options"]["default"] = "-t '/bin/bash -c \"" + r"PS1=\\[EXPECT\\]#\ " + "/bin/bash --noprofile --norc\"'" options = check_input(device_opt, process_input(device_opt)) docs = {} docs["shortdesc"] = "Fence agent for virsh" docs["longdesc"] = "fence_virsh is an I/O Fencing agent \ which can be used with the virtual machines managed by libvirt. \ It logs via ssh to a dom0 and there run virsh command, which does \ all work. \ \n.P\n\ By default, virsh needs root account to do properly work. So you \ must allow ssh login in your sshd_config." docs["vendorurl"] = "http://libvirt.org" show_docs(options, docs) ## Operate the fencing device conn = fence_login(options) result = fence_action(conn, options, set_power_status, get_power_status, get_outlets_status) fence_logout(conn, "quit") sys.exit(result) if __name__ == "__main__": main() diff --git a/tests/data/metadata/fence_virsh.xml b/tests/data/metadata/fence_virsh.xml index 642c72e9..d664fc4c 100644 --- a/tests/data/metadata/fence_virsh.xml +++ b/tests/data/metadata/fence_virsh.xml @@ -1,155 +1,160 @@ fence_virsh is an I/O Fencing agent which can be used with the virtual machines managed by libvirt. It logs via ssh to a dom0 and there run virsh command, which does all work. .P By default, virsh needs root account to do properly work. So you must allow ssh login in your sshd_config. http://libvirt.org Fencing action Force Python regex for command prompt Identity file (private key) for SSH Forces agent to use IPv4 addresses only Forces agent to use IPv6 addresses only IP address or hostname of fencing device TCP/UDP port to use for connection with device Login name Login password or passphrase Script to run to retrieve password Physical plug number on device, UUID or identification of machine Use SSH connection SSH options to use Verbose mode Write debug information to given file Display version information and exit Display help and exit Separator for CSV created by 'list' operation Wait X seconds before fencing is started Wait X seconds for cmd prompt after login + + + + Missing port returns OFF instead of failure + Test X seconds for status change after ON/OFF Wait X seconds after issuing ON/OFF Wait X seconds for cmd prompt after issuing command Count of attempts to retry power on Use sudo (without password) when calling 3rd party software Path to ssh binary Path to sudo binary