fence-agents: master - [cleanup] function array_to_dict() from agents to library
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=4b05b5...
Commit: 4b05b5ae21409b7c86c32062aa34b93de02c8974
Parent: 6692c808071fc1c61389277eefabde44cc31ae37
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: Wed Apr 23 17:58:03 2014 +0200
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Mon May 5 12:02:21 2014 +0200
[cleanup] function array_to_dict() from agents to library
---
fence/agents/cisco_mds/fence_cisco_mds.py | 7 +------
fence/agents/ifmib/fence_ifmib.py | 7 +------
fence/agents/lib/fencing.py.py | 5 +++++
3 files changed, 7 insertions(+), 12 deletions(-)
diff --git a/fence/agents/cisco_mds/fence_cisco_mds.py b/fence/agents/cisco_mds/fence_cisco_mds.py
index 82b28a0..22f1143 100644
--- a/fence/agents/cisco_mds/fence_cisco_mds.py
+++ b/fence/agents/cisco_mds/fence_cisco_mds.py
@@ -10,7 +10,7 @@ import sys, re
import atexit
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
-from fencing import fail_usage
+from fencing import fail_usage, array_to_dict
from fencing_snmp import FencingSnmp
#BEGIN_VERSION_GENERATION
@@ -51,11 +51,6 @@ def get_power_status(conn, options):
def set_power_status(conn, options):
conn.set(PORT_OID, (options["--action"]=="on" and 1 or 2))
-# Convert array of format [[key1, value1], [key2, value2], ... [keyN, valueN]] to dict, where key is
-# in format a.b.c.d...z and returned dict has key only z
-def array_to_dict(ar):
- return dict([[x[0].split(".")[-1], x[1]] for x in ar])
-
def get_outlets_status(conn, options):
result = {}
diff --git a/fence/agents/ifmib/fence_ifmib.py b/fence/agents/ifmib/fence_ifmib.py
index 04edbf9..e8eff1b 100644
--- a/fence/agents/ifmib/fence_ifmib.py
+++ b/fence/agents/ifmib/fence_ifmib.py
@@ -12,7 +12,7 @@ import sys
import atexit
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
-from fencing import fail_usage
+from fencing import fail_usage, array_to_dict
from fencing_snmp import FencingSnmp
#BEGIN_VERSION_GENERATION
@@ -74,11 +74,6 @@ def set_power_status(conn, options):
conn.set("%s.%d"%(STATUSES_OID, port_num), (options["--action"]=="on" and STATUS_UP or STATUS_DOWN))
-# Convert array of format [[key1, value1], [key2, value2], ... [keyN, valueN]] to dict, where key is
-# in format a.b.c.d...z and returned dict has key only z
-def array_to_dict(ar):
- return dict([[x[0].split(".")[-1], x[1]] for x in ar])
-
def get_outlets_status(conn, options):
result = {}
diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py
index c366423..3e5c788 100644
--- a/fence/agents/lib/fencing.py.py
+++ b/fence/agents/lib/fencing.py.py
@@ -1148,3 +1148,8 @@ def fence_logout(conn, logout_string, sleep=0):
pass
except pexpect.ExceptionPexpect:
pass
+
+# Convert array of format [[key1, value1], [key2, value2], ... [keyN, valueN]] to dict, where key is
+# in format a.b.c.d...z and returned dict has key only z
+def array_to_dict(ar):
+ return dict([[x[0].split(".")[-1], x[1]] for x in ar])
10 years
fence-agents: master - [cleanup] '--action' should be normalized to lowercase at one place only
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=6692c8...
Commit: 6692c808071fc1c61389277eefabde44cc31ae37
Parent: 848b801b36ccffa27fae19fe6fbcfb4a496d9d7a
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: Wed Apr 23 17:57:13 2014 +0200
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Mon May 5 12:02:15 2014 +0200
[cleanup] '--action' should be normalized to lowercase at one place only
---
fence/agents/drac5/fence_drac5.py | 2 +-
fence/agents/lib/fencing.py.py | 10 +++++-----
fence/agents/xenapi/fence_xenapi.py | 8 +++-----
3 files changed, 9 insertions(+), 11 deletions(-)
diff --git a/fence/agents/drac5/fence_drac5.py b/fence/agents/drac5/fence_drac5.py
index 845c6ac..7821f00 100644
--- a/fence/agents/drac5/fence_drac5.py
+++ b/fence/agents/drac5/fence_drac5.py
@@ -142,7 +142,7 @@ By default, the telnet interface is not enabled."
options["--drac-version"] = "DRAC 5"
if options["--drac-version"] in ["DRAC MC", "DRAC CMC"]:
- if not options.has_key("--plug") and 0 == ["monitor", "list"].count(options["--action"].lower()):
+ if not options.has_key("--plug") and 0 == ["monitor", "list"].count(options["--action"]):
fail_usage("Failed: You have to enter module name (-n)")
result = fence_action(conn, options, set_power_status, get_power_status, get_list_devices)
diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py
index b3afa0f..c366423 100644
--- a/fence/agents/lib/fencing.py.py
+++ b/fence/agents/lib/fencing.py.py
@@ -688,14 +688,14 @@ def check_input(device_opt, opt):
if not options.has_key(getopt_long):
options[getopt_long] = all_opt[opt]["default"]
+ options["--action"] = options["--action"].lower()
+
## In special cases (show help, metadata or version) we don't need to check anything
#####
if options.has_key("--help") or options.has_key("--version") or \
- options.get("--action", "").lower() == "metadata":
+ options["--action"] == "metadata":
return options
- options["--action"] = options["--action"].lower()
-
if options.has_key("--verbose"):
logging.getLogger().setLevel(logging.DEBUG)
@@ -744,7 +744,7 @@ def check_input(device_opt, opt):
if not os.path.isfile(options["--identity-file"]):
fail_usage("Failed: Identity file " + options["--identity-file"] + " does not exist")
- if (0 == ["list", "monitor"].count(options["--action"].lower())) and \
+ if (0 == ["list", "monitor"].count(options["--action"])) and \
not options.has_key("--plug") and device_opt.count("port") and device_opt.count("no_port") == 0:
fail_usage("Failed: You have to enter plug number or machine identification")
@@ -840,7 +840,7 @@ def show_docs(options, docs = None):
usage(device_opt)
sys.exit(0)
- if options.get("--action", "").lower() == "metadata":
+ if options.get("--action", "") == "metadata":
metadata(device_opt, options, docs)
sys.exit(0)
diff --git a/fence/agents/xenapi/fence_xenapi.py b/fence/agents/xenapi/fence_xenapi.py
index 25db7c7..958b006 100644
--- a/fence/agents/xenapi/fence_xenapi.py
+++ b/fence/agents/xenapi/fence_xenapi.py
@@ -79,8 +79,6 @@ def get_power_fn(session, options):
# Set the state of the port given in the -U flag of options.
def set_power_fn(session, options):
- action = options["--action"].lower()
-
try:
# Get a reference to the vm specified in the UUID or vm_name/port parameter
vm = return_vm_reference(session, options)
@@ -89,13 +87,13 @@ def set_power_fn(session, options):
# Check that we are not trying to manipulate a template or a control
# domain as they show up as VM's with specific properties.
if not record["is_a_template"] and not record["is_control_domain"]:
- if action == "on":
+ if options["--action"] == "on":
# Start the VM
session.xenapi.VM.start(vm, False, True)
- elif action == "off":
+ elif options["--action"] == "off":
# Force shutdown the VM
session.xenapi.VM.hard_shutdown(vm)
- elif action == "reboot":
+ elif options["--action"] == "reboot":
# Force reboot the VM
session.xenapi.VM.hard_reboot(vm)
except Exception, exn:
10 years
fence-agents: master - [cleanup] Simplify 'if' statements to use 'not' and 'get'
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=848b80...
Commit: 848b801b36ccffa27fae19fe6fbcfb4a496d9d7a
Parent: a252b16a2aa7a337a6f3186c72c397f6bf1d4606
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: Wed Apr 23 17:54:35 2014 +0200
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Mon May 5 12:02:08 2014 +0200
[cleanup] Simplify 'if' statements to use 'not' and 'get'
---
fence/agents/apc/fence_apc.py | 8 +++---
fence/agents/drac5/fence_drac5.py | 4 +-
fence/agents/dummy/fence_dummy.py | 6 ++--
fence/agents/ilo/fence_ilo.py | 4 +-
fence/agents/lib/fencing.py.py | 28 ++++++++++++------------
fence/agents/lpar/fence_lpar.py | 2 +-
fence/agents/netio/fence_netio.py | 2 +-
fence/agents/ovh/fence_ovh.py | 4 +-
fence/agents/rsb/fence_rsb.py | 2 +-
fence/agents/vmware_soap/fence_vmware_soap.py | 2 +-
fence/agents/wti/fence_wti.py | 2 +-
11 files changed, 32 insertions(+), 32 deletions(-)
diff --git a/fence/agents/apc/fence_apc.py b/fence/agents/apc/fence_apc.py
index c31a4b0..6047501 100644
--- a/fence/agents/apc/fence_apc.py
+++ b/fence/agents/apc/fence_apc.py
@@ -40,10 +40,10 @@ def get_power_status(conn, options):
if None != re.compile('.* MasterSwitch plus.*', re.IGNORECASE | re.S).match(conn.before):
switch = 1
if None != re.compile('.* MasterSwitch plus 2', re.IGNORECASE | re.S).match(conn.before):
- if 0 == options.has_key("--switch"):
+ if not options.has_key("--switch"):
fail_usage("Failed: You have to enter physical switch number")
else:
- if 0 == options.has_key("--switch"):
+ if not options.has_key("--switch"):
options["--switch"] = "1"
if None == re.compile('.*Outlet Management.*', re.IGNORECASE | re.S).match(conn.before):
@@ -116,10 +116,10 @@ def set_power_status(conn, options):
'off': "3"
}[options["--action"]]
if None != re.compile('.* MasterSwitch plus 2', re.IGNORECASE | re.S).match(conn.before):
- if 0 == options.has_key("--switch"):
+ if not options.has_key("--switch"):
fail_usage("Failed: You have to enter physical switch number")
else:
- if 0 == options.has_key("--switch"):
+ if not options.has_key("--switch"):
options["--switch"] = 1
if None == re.compile('.*Outlet Management.*', re.IGNORECASE | re.S).match(conn.before):
diff --git a/fence/agents/drac5/fence_drac5.py b/fence/agents/drac5/fence_drac5.py
index 7687135..845c6ac 100644
--- a/fence/agents/drac5/fence_drac5.py
+++ b/fence/agents/drac5/fence_drac5.py
@@ -129,7 +129,7 @@ By default, the telnet interface is not enabled."
######
conn = fence_login(options)
- if options.has_key("--drac-version") == False:
+ if not options.has_key("--drac-version"):
## autodetect from text issued by fence device
if conn.before.find("CMC") >= 0:
options["--drac-version"] = "DRAC CMC"
@@ -142,7 +142,7 @@ By default, the telnet interface is not enabled."
options["--drac-version"] = "DRAC 5"
if options["--drac-version"] in ["DRAC MC", "DRAC CMC"]:
- if 0 == options.has_key("--plug") and 0 == ["monitor", "list"].count(options["--action"].lower()):
+ if not options.has_key("--plug") and 0 == ["monitor", "list"].count(options["--action"].lower()):
fail_usage("Failed: You have to enter module name (-n)")
result = fence_action(conn, options, set_power_status, get_power_status, get_list_devices)
diff --git a/fence/agents/dummy/fence_dummy.py b/fence/agents/dummy/fence_dummy.py
index 5256aa8..3bd2b90 100644
--- a/fence/agents/dummy/fence_dummy.py
+++ b/fence/agents/dummy/fence_dummy.py
@@ -42,7 +42,7 @@ def set_power_status_file(conn, options):
def get_power_status_fail(conn, options):
outlets = get_outlets_fail(conn, options)
- if len(outlets) == 0 or options.has_key("--plug") == 0:
+ if len(outlets) == 0 or not options.has_key("--plug"):
fail_usage("Failed: You have to enter existing machine!")
else:
return outlets[options["--plug"]][0]
@@ -66,10 +66,10 @@ def get_outlets_fail(conn, options):
# This fake agent has no port data to list, so we have to make
# something up for the list action.
- if options.has_key("--action") and options["--action"] == "list":
+ if options.get("--action", None) == "list":
result["fake_port_1"] = [plug_status, "fake"]
result["fake_port_2"] = [plug_status, "fake"]
- elif options.has_key("--plug") == 0:
+ elif not options.has_key("--plug"):
fail_usage("Failed: You have to enter existing machine!")
else:
port = options["--plug"]
diff --git a/fence/agents/ilo/fence_ilo.py b/fence/agents/ilo/fence_ilo.py
index f45e749..766aba9 100644
--- a/fence/agents/ilo/fence_ilo.py
+++ b/fence/agents/ilo/fence_ilo.py
@@ -39,7 +39,7 @@ def set_power_status(conn, options):
" PASSWORD = " + quoteattr(options["--password"]) + ">\r\n")
conn.send("<SERVER_INFO MODE = \"write\">")
- if options.has_key("fw_processor") and options["fw_processor"] == "iLO2":
+ if options.get("fw_processor", None) == "iLO2":
if options["fw_version"] > 1.29:
conn.send("<HOLD_PWR_BTN TOGGLE=\"yes\" />\r\n")
else:
@@ -96,7 +96,7 @@ the iLO card through an XML stream."
conn.send("<?xml version=\"1.0\"?>\r\n")
conn.log_expect(options, [ "</RIBCL>", "<END_RIBCL/>" ], int(options["--login-timeout"]))
version = re.compile("<RIBCL VERSION=\"(.*?)\"", re.IGNORECASE).search(conn.before).group(1)
- if options.has_key("--ribcl-version") == 0:
+ if not options.has_key("--ribcl-version"):
options["--ribcl-version"] = float(version)
if options["--ribcl-version"] >= 2:
diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py
index 76c2cd1..b3afa0f 100644
--- a/fence/agents/lib/fencing.py.py
+++ b/fence/agents/lib/fencing.py.py
@@ -598,7 +598,7 @@ def process_input(avail_opt):
## Compatibility Layer
#####
z = dict(opt)
- if z.has_key("--plug") == 1:
+ if z.has_key("--plug"):
z["-m"] = z["--plug"]
opt = z
@@ -685,13 +685,13 @@ def check_input(device_opt, opt):
for opt in device_opt:
if all_opt[opt].has_key("default"):
getopt_long = "--" + all_opt[opt]["longopt"]
- if 0 == options.has_key(getopt_long):
+ if not options.has_key(getopt_long):
options[getopt_long] = all_opt[opt]["default"]
## In special cases (show help, metadata or version) we don't need to check anything
#####
if options.has_key("--help") or options.has_key("--version") or \
- (options.has_key("--action") and options["--action"].lower() == "metadata"):
+ options.get("--action", "").lower() == "metadata":
return options
options["--action"] = options["--action"].lower()
@@ -721,31 +721,31 @@ def check_input(device_opt, opt):
options["--action"] = "off"
## automatic detection and set of valid UUID from --plug
- if (0 == options.has_key("--username")) and \
+ if not options.has_key("--username") and \
device_opt.count("login") and (device_opt.count("no_login") == 0):
fail_usage("Failed: You have to set login name")
- if device_opt.count("ipaddr") and 0 == options.has_key("--ip") and 0 == options.has_key("--managed"):
+ if device_opt.count("ipaddr") and not options.has_key("--ip") and not options.has_key("--managed"):
fail_usage("Failed: You have to enter fence address")
if device_opt.count("no_password") == 0:
if 0 == device_opt.count("identity_file"):
- if 0 == (options.has_key("--password") or options.has_key("--password-script")):
+ if not (options.has_key("--password") or options.has_key("--password-script")):
fail_usage("Failed: You have to enter password or password script")
else:
- if 0 == (options.has_key("--password") or \
+ if not (options.has_key("--password") or \
options.has_key("--password-script") or options.has_key("--identity-file")):
fail_usage("Failed: You have to enter password, password script or identity file")
- if 0 == options.has_key("--ssh") and 1 == options.has_key("--identity-file"):
+ if not options.has_key("--ssh") and options.has_key("--identity-file"):
fail_usage("Failed: You have to use identity file together with ssh connection (-x)")
- if 1 == options.has_key("--identity-file"):
- if 0 == os.path.isfile(options["--identity-file"]):
+ if options.has_key("--identity-file"):
+ if not os.path.isfile(options["--identity-file"]):
fail_usage("Failed: Identity file " + options["--identity-file"] + " does not exist")
if (0 == ["list", "monitor"].count(options["--action"].lower())) and \
- 0 == options.has_key("--plug") and device_opt.count("port") and device_opt.count("no_port") == 0:
+ not options.has_key("--plug") and device_opt.count("port") and device_opt.count("no_port") == 0:
fail_usage("Failed: You have to enter plug number or machine identification")
if options.has_key("--password-script"):
@@ -840,7 +840,7 @@ def show_docs(options, docs = None):
usage(device_opt)
sys.exit(0)
- if options.has_key("--action") and options["--action"].lower() == "metadata":
+ if options.get("--action", "").lower() == "metadata":
metadata(device_opt, options, docs)
sys.exit(0)
@@ -910,7 +910,7 @@ def fence_action(tn, options, set_power_fn, get_power_fn, get_outlet_list = None
fail(EC_WAITING_OFF)
elif options["--action"] == "reboot":
power_on = False
- if options.has_key("--method") and options["--method"].lower() == "cycle" and reboot_cycle_fn is not None:
+ if options.get("--method", "").lower() == "cycle" and reboot_cycle_fn is not None:
for _ in range(1, 1 + int(options["--retry-on"])):
if reboot_cycle_fn(tn, options):
power_on = True
@@ -999,7 +999,7 @@ def fence_login(options, re_login_string = r"(login\s*: )|(Login Name: )|(usern
logging.error("%s\n", str(ex))
syslog.syslog(syslog.LOG_ERR, str(ex))
sys.exit(EC_GENERIC_ERROR)
- elif options.has_key("--ssh") and 0 == options.has_key("--identity-file"):
+ elif options.has_key("--ssh") and not options.has_key("--identity-file"):
command = '%s %s %s@%s -p %s -o PubkeyAuthentication=no' % \
(SSH_PATH, force_ipvx, options["--username"], options["--ip"], options["--ipport"])
if options.has_key("--ssh-options"):
diff --git a/fence/agents/lpar/fence_lpar.py b/fence/agents/lpar/fence_lpar.py
index 527b74b..da99073 100644
--- a/fence/agents/lpar/fence_lpar.py
+++ b/fence/agents/lpar/fence_lpar.py
@@ -141,7 +141,7 @@ def main():
docs["vendorurl"] = "http://www.ibm.com"
show_docs(options, docs)
- if 0 == options.has_key("--managed"):
+ if not options.has_key("--managed"):
fail_usage("Failed: You have to enter name of managed system")
##
diff --git a/fence/agents/netio/fence_netio.py b/fence/agents/netio/fence_netio.py
index 4f756f8..6e419a7 100755
--- a/fence/agents/netio/fence_netio.py
+++ b/fence/agents/netio/fence_netio.py
@@ -60,7 +60,7 @@ def main():
opt = process_input(device_opt)
# set default port for telnet only
- if 0 == opt.has_key("--ipport"):
+ if not opt.has_key("--ipport"):
opt["--ipport"] = "1234"
opt["eol"] = "\r\n"
diff --git a/fence/agents/ovh/fence_ovh.py b/fence/agents/ovh/fence_ovh.py
index 4cad818..50980f6 100644
--- a/fence/agents/ovh/fence_ovh.py
+++ b/fence/agents/ovh/fence_ovh.py
@@ -103,10 +103,10 @@ Poweroff is simulated with a reboot into rescue-pro mode."
if options["--action"] in [ "list", "status"]:
fail_usage("Action '" + options["--action"] + "' is not supported in this fence agent")
- if options["--plug"].endswith(".ovh.net") == False:
+ if not options["--plug"].endswith(".ovh.net"):
options["--plug"] += ".ovh.net"
- if options.has_key("--email") == False:
+ if not options.has_key("--email"):
fail_usage("You have to enter e-mail address which is notified by fence agent")
# Save datetime just before changing netboot
diff --git a/fence/agents/rsb/fence_rsb.py b/fence/agents/rsb/fence_rsb.py
index 32afc8f..415de10 100755
--- a/fence/agents/rsb/fence_rsb.py
+++ b/fence/agents/rsb/fence_rsb.py
@@ -47,7 +47,7 @@ def main():
opt = process_input(device_opt)
# set default port for telnet only
- if 0 == opt.has_key("--ssh") and 0 == opt.has_key("--ipport"):
+ if not opt.has_key("--ssh") and not opt.has_key("--ipport"):
opt["--ipport"] = "3172"
options = check_input(device_opt, opt)
diff --git a/fence/agents/vmware_soap/fence_vmware_soap.py b/fence/agents/vmware_soap/fence_vmware_soap.py
index 66e7eb9..d9e5ff2 100644
--- a/fence/agents/vmware_soap/fence_vmware_soap.py
+++ b/fence/agents/vmware_soap/fence_vmware_soap.py
@@ -123,7 +123,7 @@ def get_power_status(conn, options):
if ["list", "monitor"].count(options["--action"]) == 1:
return machines
else:
- if options.has_key("--uuid") == False:
+ if not options.has_key("--uuid"):
if options["--plug"].startswith('/'):
## Transform InventoryPath to UUID
mo_SearchIndex = Property(options["ServiceContent"].searchIndex.value)
diff --git a/fence/agents/wti/fence_wti.py b/fence/agents/wti/fence_wti.py
index 0280e29..de692f0 100644
--- a/fence/agents/wti/fence_wti.py
+++ b/fence/agents/wti/fence_wti.py
@@ -202,7 +202,7 @@ is running because the connection will block any necessary fencing actions."
##
## @note: if it possible that this device does not need either login, password or both of them
#####
- if 0 == options.has_key("--ssh"):
+ if not options.has_key("--ssh"):
try:
if options["--action"] in ["off", "reboot"]:
time.sleep(int(options["--delay"]))
10 years
fence-agents: master - fence_pve: new fence-agent for Proxmox VE
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=a252b1...
Commit: a252b16a2aa7a337a6f3186c72c397f6bf1d4606
Parent: b33546058c4114cf8fc65e207cf1c6e42325fd3b
Author: Ondrej Mular <omular(a)redhat.com>
AuthorDate: Fri May 2 07:16:03 2014 -0400
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Mon May 5 10:47:30 2014 +0200
fence_pve: new fence-agent for Proxmox VE
Thanks to Frank Brendel (author of original perl fence_pve) for help with writing and testing this agent.
Signed-off-by: Marek 'marx' Grac <mgrac(a)redhat.com>
---
.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(+), 0 deletions(-)
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 0000000..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 0000000..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 dict or "data" not in vms or type(vms["data"]) is not list:
+ return None
+ for vm in vms["data"]:
+ outlets[vm["vmid"]] = [vm["name"], vm["status"]]
+ return outlets
+
+
+def get_ticket(options):
+ post = {'username': options["--username"], 'password': options["--password"]}
+ result = send_cmd(options, "access/ticket", post=post)
+ if type(result) is dict and "data" in result:
+ if type(result["data"]) is dict and "ticket" in result["data"] and "CSRFPreventionToken" in result["data"]:
+ return {
+ "ticket" : str("PVEAuthCookie=" + result["data"]["ticket"] + "; " + \
+ "version=0; path=/; domain=" + options["--ip"] + \
+ "; port=" + str(options["--ipport"]) + "; path_spec=0; secure=1; " + \
+ "expires=7200; discard=0"),
+ "CSRF_token" : str("CSRFPreventionToken: " + result["data"]["CSRFPreventionToken"])
+ }
+ return None
+
+
+def send_cmd(options, cmd, post=None):
+ url = options["url"] + cmd
+ conn = pycurl.Curl()
+ output_buffer = StringIO.StringIO()
+ if logging.getLogger().getEffectiveLevel() < logging.WARNING:
+ conn.setopt(pycurl.VERBOSE, True)
+ conn.setopt(pycurl.HTTPGET, 1)
+ conn.setopt(pycurl.URL, str(url))
+ if "auth" in options and options["auth"] is not None:
+ conn.setopt(pycurl.COOKIE, options["auth"]["ticket"])
+ conn.setopt(pycurl.HTTPHEADER, [options["auth"]["CSRF_token"]])
+ if post is not None:
+ conn.setopt(pycurl.POSTFIELDS, urllib.urlencode(post))
+ conn.setopt(pycurl.WRITEFUNCTION, output_buffer.write)
+ conn.setopt(pycurl.TIMEOUT, int(options["--shell-timeout"]))
+ conn.setopt(pycurl.SSL_VERIFYPEER, 0)
+ conn.setopt(pycurl.SSL_VERIFYHOST, 0)
+
+ logging.debug("URL: " + url)
+
+ try:
+ conn.perform()
+ result = output_buffer.getvalue()
+
+ logging.debug("RESULT [" + str(conn.getinfo(pycurl.RESPONSE_CODE)) + \
+ "]: " + result)
+ conn.close()
+
+ return json.loads(result)
+ except pycurl.error:
+ logging.error("Connection failed")
+ except:
+ logging.error("Cannot parse json")
+ return None
+
+
+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)
+
+if __name__ == "__main__":
+ main()
diff --git a/tests/data/metadata/fence_pve.xml b/tests/data/metadata/fence_pve.xml
new file mode 100644
index 0000000..86c3cd7
--- /dev/null
+++ b/tests/data/metadata/fence_pve.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_pve" shortdesc="Fencing agent for the Proxmox Virtual Environment" >
+<longdesc>The fence_pve agent can be used to fence virtual machines acting as nodes in a virtualized cluster.</longdesc>
+<vendor-url>http://www.proxmox.com/</vendor-url>
+<parameters>
+ <parameter name="ipport" unique="0" required="0">
+ <getopt mixed="-u, --ipport=[port]" />
+ <content type="string" default="8006" />
+ <shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+ </parameter>
+ <parameter name="port" unique="0" required="1">
+ <getopt mixed="-n, --plug=[id]" />
+ <content type="string" />
+ <shortdesc lang="en">Id of the virtual machine.</shortdesc>
+ </parameter>
+ <parameter name="inet6_only" unique="0" required="0">
+ <getopt mixed="-6, --inet6-only" />
+ <content type="boolean" />
+ <shortdesc lang="en">Forces agent to use IPv6 addresses only</shortdesc>
+ </parameter>
+ <parameter name="ipaddr" unique="0" required="1">
+ <getopt mixed="-a, --ip=[ip]" />
+ <content type="string" />
+ <shortdesc lang="en">IP Address or Hostname of a node within the Proxmox cluster.</shortdesc>
+ </parameter>
+ <parameter name="inet4_only" unique="0" required="0">
+ <getopt mixed="-4, --inet4-only" />
+ <content type="boolean" />
+ <shortdesc lang="en">Forces agent to use IPv4 addresses only</shortdesc>
+ </parameter>
+ <parameter name="passwd_script" unique="0" required="0">
+ <getopt mixed="-S, --password-script=[script]" />
+ <content type="string" />
+ <shortdesc lang="en">Script to retrieve password</shortdesc>
+ </parameter>
+ <parameter name="passwd" unique="0" required="0">
+ <getopt mixed="-p, --password=[password]" />
+ <content type="string" />
+ <shortdesc lang="en">Login password or passphrase</shortdesc>
+ </parameter>
+ <parameter name="action" unique="0" required="1">
+ <getopt mixed="-o, --action=[action]" />
+ <content type="string" default="reboot" />
+ <shortdesc lang="en">Fencing Action</shortdesc>
+ </parameter>
+ <parameter name="login" unique="0" required="1">
+ <getopt mixed="-l, --username=[name]" />
+ <content type="string" default="root@pam" />
+ <shortdesc lang="en">Login Name</shortdesc>
+ </parameter>
+ <parameter name="node_name" unique="0" required="0">
+ <getopt mixed="-N, --nodename" />
+ <content type="string" />
+ <shortdesc lang="en">Node on which machine is located. (Optional, will be automatically determined)</shortdesc>
+ </parameter>
+ <parameter name="verbose" unique="0" required="0">
+ <getopt mixed="-v, --verbose" />
+ <content type="boolean" />
+ <shortdesc lang="en">Verbose mode</shortdesc>
+ </parameter>
+ <parameter name="debug" unique="0" required="0">
+ <getopt mixed="-D, --debug-file=[debugfile]" />
+ <content type="string" />
+ <shortdesc lang="en">Write debug information to given file</shortdesc>
+ </parameter>
+ <parameter name="version" unique="0" required="0">
+ <getopt mixed="-V, --version" />
+ <content type="boolean" />
+ <shortdesc lang="en">Display version information and exit</shortdesc>
+ </parameter>
+ <parameter name="help" unique="0" required="0">
+ <getopt mixed="-h, --help" />
+ <content type="boolean" />
+ <shortdesc lang="en">Display help and exit</shortdesc>
+ </parameter>
+ <parameter name="separator" unique="0" required="0">
+ <getopt mixed="-C, --separator=[char]" />
+ <content type="string" default="," />
+ <shortdesc lang="en">Separator for CSV created by operation list</shortdesc>
+ </parameter>
+ <parameter name="power_wait" unique="0" required="0">
+ <getopt mixed="--power-wait=[seconds]" />
+ <content type="string" default="0" />
+ <shortdesc lang="en">Wait X seconds after issuing ON/OFF</shortdesc>
+ </parameter>
+ <parameter name="login_timeout" unique="0" required="0">
+ <getopt mixed="--login-timeout=[seconds]" />
+ <content type="string" default="5" />
+ <shortdesc lang="en">Wait X seconds for cmd prompt after login</shortdesc>
+ </parameter>
+ <parameter name="power_timeout" unique="0" required="0">
+ <getopt mixed="--power-timeout=[seconds]" />
+ <content type="string" default="20" />
+ <shortdesc lang="en">Test X seconds for status change after ON/OFF</shortdesc>
+ </parameter>
+ <parameter name="delay" unique="0" required="0">
+ <getopt mixed="--delay=[seconds]" />
+ <content type="string" default="0" />
+ <shortdesc lang="en">Wait X seconds before fencing is started</shortdesc>
+ </parameter>
+ <parameter name="shell_timeout" unique="0" required="0">
+ <getopt mixed="--shell-timeout=[seconds]" />
+ <content type="string" default="3" />
+ <shortdesc lang="en">Wait X seconds for cmd prompt after issuing command</shortdesc>
+ </parameter>
+ <parameter name="retry_on" unique="0" required="0">
+ <getopt mixed="--retry-on=[attempts]" />
+ <content type="string" default="1" />
+ <shortdesc lang="en">Count of attempts to retry power on</shortdesc>
+ </parameter>
+</parameters>
+<actions>
+ <action name="on" automatic="0"/>
+ <action name="off" />
+ <action name="reboot" />
+ <action name="status" />
+ <action name="list" />
+ <action name="monitor" />
+ <action name="metadata" />
+</actions>
+</resource-agent>
10 years
fence-agents: master - fencing: added option "on_target"
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=b33546...
Commit: b33546058c4114cf8fc65e207cf1c6e42325fd3b
Parent: 96d7a8383197e3d34c201139445ff177d870ff62
Author: Ondrej Mular <omular(a)redhat.com>
AuthorDate: Fri May 2 07:15:49 2014 -0400
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Mon May 5 10:47:18 2014 +0200
fencing: added option "on_target"
added option "on_target" for agents that need attribute "on_target" in metadata
Signed-off-by: Marek 'marx' Grac <mgrac(a)redhat.com>
---
fence/agents/lib/fencing.py.py | 9 ++++++++-
1 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py
index 0539a2f..76c2cd1 100644
--- a/fence/agents/lib/fencing.py.py
+++ b/fence/agents/lib/fencing.py.py
@@ -370,6 +370,10 @@ all_opt = {
"shortdesc" : "Method to fence (onoff|cycle)",
"default" : "onoff",
"choices" : [ "onoff", "cycle" ],
+ "order" : 1},
+ "on_target": {
+ "getopt" : "",
+ "help" : "",
"order" : 1}
}
@@ -521,7 +525,10 @@ def metadata(avail_opt, options, docs):
print "<actions>"
if avail_opt.count("fabric_fencing") == 1:
## do 'unfence' at the start
- print "\t<action name=\"on\" automatic=\"1\"/>"
+ if avail_opt.count("on_target") == 1:
+ print "\t<action name=\"on\" on_target=\"1\" automatic=\"1\"/>"
+ else:
+ print "\t<action name=\"on\" automatic=\"1\"/>"
else:
print "\t<action name=\"on\" automatic=\"0\"/>"
print "\t<action name=\"off\" />"
10 years