diff options
Diffstat (limited to 'agents/virsh/fence_virsh.py')
-rw-r--r-- | agents/virsh/fence_virsh.py | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/agents/virsh/fence_virsh.py b/agents/virsh/fence_virsh.py new file mode 100644 index 0000000..88cee48 --- /dev/null +++ b/agents/virsh/fence_virsh.py @@ -0,0 +1,96 @@ +#!@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 + +def get_name_or_uuid(options): + return options["--uuid"] if "--uuid" in options else options["--plug"] + +def get_outlets_status(conn, options): + if "--use-sudo" in options: + 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 "--use-sudo" in options 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 "--missing-as-off" in options: + 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 "--use-sudo" in options 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", "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() |