summaryrefslogtreecommitdiffstats
path: root/agents/virsh/fence_virsh.py
diff options
context:
space:
mode:
Diffstat (limited to 'agents/virsh/fence_virsh.py')
-rw-r--r--agents/virsh/fence_virsh.py96
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()