Thanks to Frank Brendel (author of original perl fence_pve) for help with
writing and testing this agent.
---
.gitignore| 1 +
configure.ac | 1 +
fence/agents/pve/Makefile.am | 18
fence/agents/pve/fence_pve.py | 178 ++
tests/data/metadata/fence_pve.xml | 121 ++
5 files changed, 319 insertions(+)
create mode 100644 fence/agents/pve/Makefile.am
create mode 100644 fence/agents/pve/fence_pve.py
create mode 100644 tests/data/metadata/fence_pve.xml
diff --git a/.gitignore b/.gitignore
index 74198b2..75b9aa7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -65,6 +65,7 @@ fence/agents/node_assassin/fence_na.conf
fence/agents/node_assassin/fence_na.lib
fence/agents/node_assassin/fence_na.pod
fence/agents/nss_wrapper/fence_nss_wrapper
+fence/agents/pve/fence_pve
fence/agents/rackswitch/fence_rackswitch
fence/agents/rhevm/fence_rhevm
fence/agents/raritan/fence_raritan
diff --git a/configure.ac b/configure.ac
index c24198c..5e37ee5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -283,6 +283,7 @@ AC_CONFIG_FILES([Makefile
fence/agents/netio/Makefile
fence/agents/rackswitch/Makefile
fence/agents/ovh/Makefile
+fence/agents/pve/Makefile
fence/agents/raritan/Makefile
fence/agents/rhevm/Makefile
fence/agents/rsa/Makefile
diff --git a/fence/agents/pve/Makefile.am b/fence/agents/pve/Makefile.am
new file mode 100644
index 000..9ac184e
--- /dev/null
+++ b/fence/agents/pve/Makefile.am
@@ -0,0 +1,18 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+TARGET = fence_pve
+
+SRC= $(TARGET).py
+
+EXTRA_DIST = $(SRC)
+
+sbin_SCRIPTS = $(TARGET)
+
+man_MANS = $(TARGET).8
+
+include $(top_srcdir)/make/fencebuild.mk
+include $(top_srcdir)/make/fenceman.mk
+include $(top_srcdir)/make/agentpycheck.mk
+
+clean-local: clean-man
+ rm -f $(TARGET)
diff --git a/fence/agents/pve/fence_pve.py b/fence/agents/pve/fence_pve.py
new file mode 100644
index 000..132234e
--- /dev/null
+++ b/fence/agents/pve/fence_pve.py
@@ -0,0 +1,178 @@
+#!/usr/bin/python -tt
+
+# This agent uses Proxmox VE API
+# Thanks to Frank Brendel (author of original perl fence_pve)
+# for help with writing and testing this agent.
+
+import sys
+import json
+import pycurl
+import StringIO
+import urllib
+import atexit
+import logging
+sys.path.append(@FENCEAGENTSLIBDIR@)
+from fencing import fail, EC_LOGIN_DENIED, atexit_handler, all_opt,
check_input, process_input, show_docs, fence_action, run_delay
+
+#BEGIN_VERSION_GENERATION
+RELEASE_VERSION=
+BUILD_DATE=
+REDHAT_COPYRIGHT=
+#END_VERSION_GENERATION
+
+
+def get_power_status(conn, options):
+ del conn
+ state = {running : on, stopped : off}
+ if options[--nodename] is None:
+ nodes = send_cmd(options, nodes)
+ if type(nodes) is not dict or data not in nodes or
type(nodes[data]) is not list:
+ return None
+ for node in nodes[data]: # lookup the node holding the vm
+ if type(node) is not dict or node not in node:
+ return None
+ options[--nodename] = node[node]
+ status = get_power_status(None, options)
+ if status is not None:
+ logging.info(vm found on node: +
options[--nodename])
+ break
+ else:
+ options[--nodename] = None
+ return status
+ else:
+ cmd = nodes/ + options[--nodename] + /qemu/ +
options[--plug] + /status/current
+ result = send_cmd(options, cmd)
+ if type(result) is dict and data in result:
+ if type(result[data]) is dict and status in
result[data]:
+ if result[data][status] in state:
+ return state[result[data][status]]
+ return None
+
+
+def set_power_status(conn, options):
+ del conn
+ action = {
+ 'on' : start,
+ 'off': stop
+ }[options[--action]]
+ cmd = nodes/ + options[--nodename] + /qemu/ + options[--plug] +
/status/ + action
+ send_cmd(options, cmd, post={skiplock:1})
+
+
+def get_outlet_list(conn, options):
+ del conn
+ nodes = send_cmd(options, nodes)
+ outlets = dict()
+ if type(nodes) is not dict or data not in nodes or
type(nodes[data]) is not list:
+ return None
+ for node in nodes[data]:
+ if type(node) is not dict or node not in node:
+ return None
+ vms = send_cmd(options, nodes/ + node[node] + /qemu)
+ if type(vms) is not